Skip to content

Commit

Permalink
Merge 9653d1b into af04ec0
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Dutton committed Feb 19, 2015
2 parents af04ec0 + 9653d1b commit e43762e
Showing 1 changed file with 59 additions and 53 deletions.
112 changes: 59 additions & 53 deletions jsonpointer.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,28 +153,53 @@ def to_last(self, doc):
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])


def resolve(self, doc, default=_nothing):
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, parts=None):
"""Resolves the pointer against doc and returns the referenced object"""

for part in self.parts:

try:
doc = self.walk(doc, part)
except JsonPointerException:
if default is _nothing:
raise
if parts is None:
parts = self.parts

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):
Expand All @@ -196,56 +221,37 @@ def set(self, doc, value, inplace=True):
def get_part(self, doc, part):
""" Returns the next step in the correct type """

if isinstance(doc, Mapping):
# Optimize for common cases of doc being a dict or list, but not a
# sub-class (because isinstance() is far slower)
ptype = type(doc)
if ptype == dict:
return part

elif isinstance(doc, Sequence):

if ptype == list or isinstance(doc, Sequence):
if part == '-':
return part

if not RE_ARRAY_INDEX.match(str(part)):
raise JsonPointerException("'%s' is not a valid list index" % (part, ))

return int(part)

elif hasattr(doc, '__getitem__'):
# Allow indexing via ducktyping if the target has defined __getitem__
return part

else:
raise JsonPointerException("Document '%s' does not support indexing, "
"must be dict/list or support __getitem__" % type(doc))

return part

def walk(self, doc, part):
""" Walks one step in doc and returns the referenced part """

part = self.get_part(doc, part)

assert (type(doc) in (dict, list) or hasattr(doc, '__getitem__')), "invalid document type %s" % (type(doc),)

if isinstance(doc, Mapping):
try:
return doc[part]

except KeyError:
raise JsonPointerException("member '%s' not found in %s" % (part, doc))

elif isinstance(doc, Sequence):

if part == '-':
return EndOfList(doc)

try:
return doc[part]

except IndexError:
raise JsonPointerException("index '%s' is out of bounds" % (part, ))

else:
# Object supports __getitem__, assume custom indexing
if part == '-' and isinstance(doc, Sequence):
return EndOfList(doc)
try:
return doc[part]
except KeyError:
raise JsonPointerException("member '%s' not found in %s" % (part, doc))
except IndexError:
raise JsonPointerException("index '%s' is out of bounds" % (part, ))
except TypeError:
raise JsonPointerException("Document '%s' does not support indexing, "
"must be dict/list or support __getitem__" % type(doc))


def contains(self, ptr):
"""Returns True if self contains the given ptr"""
Expand Down

0 comments on commit e43762e

Please sign in to comment.