diff options
author | Alexander Dutton <alexander.dutton@it.ox.ac.uk> | 2015-02-19 00:22:03 +0000 |
---|---|---|
committer | Alexander Dutton <alexander.dutton@it.ox.ac.uk> | 2015-02-19 00:22:03 +0000 |
commit | 9653d1be314e14ae00d86b13807d2d22c0d55e98 (patch) | |
tree | ca1cf0b06209160a39eab2fb9fb077a2bb298f21 /jsonpointer.py | |
parent | c4372cdb3829138a1e5287e1c4ef8dc9c6c5b5a5 (diff) | |
download | python-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)
Diffstat (limited to 'jsonpointer.py')
-rw-r--r-- | jsonpointer.py | 53 |
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): |