Skip to content

Commit 9653d1b

Browse files
committed
Re-factor resolve and to_last to not make lots of function calls.
Also means that isinstance(..., Sequence) doesn't get called twice for non-list sequences (once in walk, and one in get_part)
1 parent c4372cd commit 9653d1b

File tree

1 file changed

+39
-14
lines changed

1 file changed

+39
-14
lines changed

jsonpointer.py

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,28 +153,53 @@ def to_last(self, doc):
153153
if not self.parts:
154154
return doc, None
155155

156-
for part in self.parts[:-1]:
157-
doc = self.walk(doc, part)
158-
159-
return doc, self.get_part(doc, self.parts[-1])
156+
doc = self.resolve(doc, parts=self.parts[:-1])
157+
last = self.parts[-1]
158+
ptype = type(doc)
159+
if ptype == dict:
160+
pass
161+
elif ptype == list or isinstance(doc, Sequence):
162+
if not RE_ARRAY_INDEX.match(str(last)):
163+
raise JsonPointerException("'%s' is not a valid list index" % (last, ))
164+
last = int(last)
160165

166+
return doc, last
161167

162-
def resolve(self, doc, default=_nothing):
168+
def resolve(self, doc, default=_nothing, parts=None):
163169
"""Resolves the pointer against doc and returns the referenced object"""
170+
if parts is None:
171+
parts = self.parts
164172

165-
for part in self.parts:
166-
167-
try:
168-
doc = self.walk(doc, part)
169-
except JsonPointerException:
170-
if default is _nothing:
171-
raise
173+
try:
174+
for part in parts:
175+
ptype = type(doc)
176+
if ptype == dict:
177+
doc = doc[part]
178+
elif ptype == list or isinstance(doc, Sequence):
179+
if part == '-':
180+
doc = EndOfList(doc)
181+
else:
182+
if not RE_ARRAY_INDEX.match(str(part)):
183+
raise JsonPointerException("'%s' is not a valid list index" % (part, ))
184+
doc = doc[int(part)]
172185
else:
173-
return default
186+
doc = doc[part]
187+
except KeyError:
188+
if default is not _nothing:
189+
return default
190+
raise JsonPointerException("member '%s' not found in %s" % (part, doc))
191+
except IndexError:
192+
if default is not _nothing:
193+
return default
194+
raise JsonPointerException("index '%s' is out of bounds" % (part, ))
195+
except TypeError:
196+
if default is not _nothing:
197+
return default
198+
raise JsonPointerException("Document '%s' does not support indexing, "
199+
"must be dict/list or support __getitem__" % type(doc))
174200

175201
return doc
176202

177-
178203
get = resolve
179204

180205
def set(self, doc, value, inplace=True):

0 commit comments

Comments
 (0)