summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Dutton <alexander.dutton@it.ox.ac.uk>2015-02-19 00:22:03 +0000
committerAlexander Dutton <alexander.dutton@it.ox.ac.uk>2015-02-19 00:22:03 +0000
commit9653d1be314e14ae00d86b13807d2d22c0d55e98 (patch)
treeca1cf0b06209160a39eab2fb9fb077a2bb298f21
parentc4372cdb3829138a1e5287e1c4ef8dc9c6c5b5a5 (diff)
downloadpython-json-pointer-9653d1be314e14ae00d86b13807d2d22c0d55e98.tar.gz
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)
-rw-r--r--jsonpointer.py53
1 files changed, 39 insertions, 14 deletions
diff --git a/jsonpointer.py b/jsonpointer.py
index 3e8b31c..72e5f93 100644
--- a/jsonpointer.py
+++ b/jsonpointer.py
@@ -153,28 +153,53 @@ class JsonPointer(object):
if not self.parts:
return doc, None
- for part in self.parts[:-1]:
- doc = self.walk(doc, part)
-
- return doc, self.get_part(doc, self.parts[-1])
+ doc = self.resolve(doc, parts=self.parts[:-1])
+ last = self.parts[-1]
+ ptype = type(doc)
+ if ptype == dict:
+ pass
+ elif ptype == list or isinstance(doc, Sequence):
+ if not RE_ARRAY_INDEX.match(str(last)):
+ raise JsonPointerException("'%s' is not a valid list index" % (last, ))
+ last = int(last)
+ return doc, last
- def resolve(self, doc, default=_nothing):
+ def resolve(self, doc, default=_nothing, parts=None):
"""Resolves the pointer against doc and returns the referenced object"""
+ if parts is None:
+ parts = self.parts
- for part in self.parts:
-
- try:
- doc = self.walk(doc, part)
- except JsonPointerException:
- if default is _nothing:
- raise
+ try:
+ for part in parts:
+ ptype = type(doc)
+ if ptype == dict:
+ doc = doc[part]
+ elif ptype == list or isinstance(doc, Sequence):
+ if part == '-':
+ doc = EndOfList(doc)
+ else:
+ if not RE_ARRAY_INDEX.match(str(part)):
+ raise JsonPointerException("'%s' is not a valid list index" % (part, ))
+ doc = doc[int(part)]
else:
- return default
+ doc = doc[part]
+ except KeyError:
+ if default is not _nothing:
+ return default
+ raise JsonPointerException("member '%s' not found in %s" % (part, doc))
+ except IndexError:
+ if default is not _nothing:
+ return default
+ raise JsonPointerException("index '%s' is out of bounds" % (part, ))
+ except TypeError:
+ if default is not _nothing:
+ return default
+ raise JsonPointerException("Document '%s' does not support indexing, "
+ "must be dict/list or support __getitem__" % type(doc))
return doc
-
get = resolve
def set(self, doc, value, inplace=True):