Skip to content

Commit dcaaaaa

Browse files
authored
Merge pull request #151 from dpath-maintainers/version/2.x
Version/2.x
2 parents ec052aa + f39e91e commit dcaaaaa

4 files changed

Lines changed: 82 additions & 4 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/MANIFEST
22
/.tox
3-
/.hypothesis
43
/build
54
/env
5+
.hypothesis
66
*.pyc
77
.vscode
88
venv_39

dpath/segments.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ def kvs(node):
1313
try:
1414
return iter(node.items())
1515
except AttributeError:
16-
return zip(range(len(node)), node)
16+
try:
17+
return zip(range(len(node)), node)
18+
except TypeError:
19+
# This can happen in cases where the node isn't leaf(node) == True,
20+
# but also isn't actually iterable. Instead of this being an error
21+
# we will treat this node as if it has no children.
22+
return enumerate([])
1723

1824

1925
def leaf(thing):
@@ -34,7 +40,12 @@ def leafy(thing):
3440
3541
leafy(thing) -> bool
3642
'''
37-
return leaf(thing) or len(thing) == 0
43+
44+
try:
45+
return leaf(thing) or len(thing) == 0
46+
except TypeError:
47+
# In case thing has no len()
48+
return False
3849

3950

4051
def walk(obj, location=()):

dpath/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = "2.0.1"
1+
VERSION = "2.0.2"

tests/test_util_get_values.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from nose.tools import assert_raises
2+
3+
import datetime
4+
import decimal
25
import dpath.util
36
import mock
7+
import time
48

59

610
def test_util_get_root():
@@ -140,3 +144,66 @@ def test_values_list():
140144
ret = dpath.util.values(a, 'actions/*')
141145
assert(isinstance(ret, list))
142146
assert(len(ret) == 2)
147+
148+
149+
def test_non_leaf_leaf():
150+
# The leaves in this test aren't leaf(thing) == True, but we should still
151+
# be able to get them. They should also not prevent fetching other values.
152+
153+
def func(x):
154+
return x
155+
156+
testdict = {
157+
'a': func,
158+
'b': lambda x: x,
159+
'c': [
160+
{
161+
'a',
162+
'b',
163+
},
164+
],
165+
'd': [
166+
decimal.Decimal(1.5),
167+
decimal.Decimal(2.25),
168+
],
169+
'e': datetime.datetime(2020, 1, 1),
170+
'f': {
171+
'config': 'something',
172+
},
173+
}
174+
175+
# It should be possible to get the callables:
176+
assert dpath.util.get(testdict, 'a') == func
177+
assert dpath.util.get(testdict, 'b')(42) == 42
178+
179+
# It should be possible to get other values:
180+
assert dpath.util.get(testdict, 'c/0') == testdict['c'][0]
181+
assert dpath.util.get(testdict, 'd')[0] == testdict['d'][0]
182+
assert dpath.util.get(testdict, 'd/0') == testdict['d'][0]
183+
assert dpath.util.get(testdict, 'd/1') == testdict['d'][1]
184+
assert dpath.util.get(testdict, 'e') == testdict['e']
185+
186+
# Values should also still work:
187+
assert dpath.util.values(testdict, 'f/config') == ['something']
188+
189+
# Data classes should also be retrievable:
190+
try:
191+
import dataclasses
192+
except:
193+
return
194+
195+
@dataclasses.dataclass
196+
class Connection:
197+
group_name: str
198+
channel_name: str
199+
last_seen: float
200+
201+
testdict['g'] = {
202+
'my-key': Connection(
203+
group_name='foo',
204+
channel_name='bar',
205+
last_seen=time.time(),
206+
),
207+
}
208+
209+
assert dpath.util.search(testdict, 'g/my*')['g']['my-key'] == testdict['g']['my-key']

0 commit comments

Comments
 (0)