Skip to content

Commit f1e127c

Browse files
committed
Rework set to allow for custom creator function.
Fixes issue #91.
1 parent 33ef899 commit f1e127c

2 files changed

Lines changed: 38 additions & 24 deletions

File tree

dpath/segments.py

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,41 @@ def extend(thing, index, value=None):
279279
return thing
280280

281281

282-
def set(obj, segments, value, create_missing=True, hints=()):
282+
def __default_creator__(current, segments, i, hints=()):
283283
'''
284-
Set the value in obj at the place indicated by segments. If
285-
create_missing is True (default), then create any missing path
286-
components (dict or list as appropriate).
284+
Create missing path components. If the segment is an int or long, then it
285+
will create a list. Otherwise a dictionary is created.
286+
287+
set(obj, segments, value) -> obj
288+
'''
289+
segment = segments[i]
290+
length = len(segments)
291+
292+
if isinstance(segment, (int, long)):
293+
extend(current, segment)
294+
295+
# Infer the type from the hints provided.
296+
if i < len(hints):
297+
current[segment] = hints[i][1]()
298+
else:
299+
# Peek at the next segment to determine if we should be
300+
# creating an array for it to access or dictionary.
301+
if i + 1 < length:
302+
segment_next = segments[i + 1]
303+
else:
304+
segment_next = None
305+
306+
if isinstance(segment_next, (int, long)):
307+
current[segment] = []
308+
else:
309+
current[segment] = {}
310+
311+
312+
def set(obj, segments, value, creator=__default_creator__, hints=()):
313+
'''
314+
Set the value in obj at the place indicated by segments. If creator is not
315+
None (default __default_creator__), then call the creator function to
316+
create any missing path components.
287317
288318
set(obj, segments, value) -> obj
289319
'''
@@ -300,27 +330,11 @@ def set(obj, segments, value, create_missing=True, hints=()):
300330
# values, not keys whereas dicts check keys.
301331
current[segment]
302332
except:
303-
if create_missing:
304-
if isinstance(segment, (int, long)):
305-
extend(current, segment)
306-
307-
# Infer the type from the hints provided.
308-
if i < len(hints):
309-
current[segment] = hints[i][1]()
310-
else:
311-
# Peek at the next segment to determine if we should be
312-
# creating an array for it to access or dictionary.
313-
if i + 1 < length:
314-
segment_next = segments[i + 1]
315-
else:
316-
segment_next = None
317-
318-
if isinstance(segment_next, (int, long)):
319-
current[segment] = []
320-
else:
321-
current[segment] = {}
333+
if creator != None:
334+
creator(current, segments, i, hints=hints)
322335
else:
323336
raise
337+
324338
current = current[segment]
325339
if i != length - 1 and leaf(current):
326340
raise PathNotFound('Path: {}[{}]'.format(segments, i))

dpath/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def f(obj, pair, counter):
131131
selected = afilter and dpath.segments.leaf(found) and afilter(found)
132132

133133
if (matched and not afilter) or (matched and selected):
134-
dpath.segments.set(obj, segments, value, create_missing=False)
134+
dpath.segments.set(obj, segments, value, creator=None)
135135
counter[0] += 1
136136

137137
[changed] = dpath.segments.foldm(obj, f, [0])

0 commit comments

Comments
 (0)