Skip to content

Commit 4026247

Browse files
committed
join support for ranges
1 parent 488f009 commit 4026247

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

datapath/_base.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,24 @@ def _split_match(match: re.Match, iterable: bool) -> SplitPath:
133133
return tuple(split_path)
134134

135135

136+
def _format_range(range_obj: range) -> str:
137+
start = range_obj.start
138+
stop = range_obj.stop
139+
step = range_obj.step
140+
if range_obj.start == 0:
141+
start = ''
142+
if range_obj.stop == sys.maxsize:
143+
stop = ''
144+
if range_obj.step == 1:
145+
step = ''
146+
if not any((start, stop, step)):
147+
return '[]'
148+
slice_str = f'{start}:{stop}'
149+
if step:
150+
slice_str += f':{step}'
151+
return f'[{slice_str}]'
152+
153+
136154
def join(split_path: Iterable[Key]) -> str:
137155
"""inverse of split() -- combine an iterable of keys/indexes into a dotted-path format
138156
@@ -160,8 +178,13 @@ def join(split_path: Iterable[Key]) -> str:
160178
path = f'{path}[]'
161179
else:
162180
path = '[]'
181+
elif isinstance(part, range):
182+
if path:
183+
path = f'{path}{_format_range(part)}'
184+
else:
185+
path = _format_range(part)
163186
else:
164-
raise ValidationError(f'index {i} is invalid, must be str/int, '
187+
raise ValidationError(f'index {i} is invalid, must be str/int/range/ITERATION_POINT, '
165188
f'got {type(part).__name__}')
166189
return path
167190

@@ -171,7 +194,7 @@ def _validate_key_collection_type(obj: Collection, key: Key) -> None:
171194
validate a collection object and key are valid and corresponding types
172195
raise a ValidationError if they are not
173196
"""
174-
if key is ITERATION_POINT:
197+
if key is ITERATION_POINT or isinstance(key, range):
175198
raise TypeError('bug: iteration not supported here')
176199
if not isinstance(obj, _collection_types):
177200
raise TypeValidationError('object must be list/dict')

test/test_datapath.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ def test_split_path_invalid_iteration(self):
123123
datapath.split(path, iterable=False)
124124

125125
def test_split_join(self):
126-
for path in valid_paths:
126+
for path in valid_paths + valid_iterable_paths:
127127
with self.subTest(msg=path):
128128
try:
129-
self.assertEqual(datapath.join(datapath.split(path)), path)
129+
self.assertEqual(datapath.join(datapath.split(path, iterable=True)), path)
130130
except datapath.ValidationError:
131131
self.fail(f'path `{path}` was found invalid')
132132

0 commit comments

Comments
 (0)