diff options
-rw-r--r-- | jsonpointer.py | 49 | ||||
-rwxr-xr-x | tests.py | 10 |
2 files changed, 43 insertions, 16 deletions
diff --git a/jsonpointer.py b/jsonpointer.py index 0736014..9897858 100644 --- a/jsonpointer.py +++ b/jsonpointer.py @@ -31,7 +31,7 @@ # """ Identify specific nodes in a JSON document according to -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-04 """ +http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-05 """ # Will be parsed by setup.py to determine package metadata __author__ = 'Stefan Kögl <stefan@skoegl.net>' @@ -54,6 +54,18 @@ class JsonPointerException(Exception): pass +class EndOfList(object): + """ Result of accessing element "-" of a list """ + + def __init__(self, list_): + self.list_ = list_ + + + def __repr__(self): + return '{cls}({lst})'.format(cls=self.__class__.__name__, + lst=repr(self.list_)) + + _nothing = object() @@ -198,25 +210,32 @@ class JsonPointer(object): def walk(self, doc, part): """ Walks one step in doc and returns the referenced part """ - # Its not clear if a location "1" should be considered as 1 or "1" - # We prefer the integer-variant if possible - part_variants = self._try_parse(part) + [part] + if isinstance(doc, dict): + try: + return doc[part] + + except KeyError: + raise JsonPointerException("member '%s' not found in %s" % (part, doc)) + + elif isinstance(doc, list): + + if part == '-': + return EndOfList(doc) - for variant in part_variants: try: - return doc[variant] - except: - continue + part = int(part) + except ValueError: + raise JsonPointerException("'%s' is not a valid list index" % (part, )) - raise JsonPointerException("'%s' not found in %s" % (part, doc)) + try: + return doc[part] + except IndexError: + raise JsonPointerException("index '%s' is out of bounds" % (part, )) - @staticmethod - def _try_parse(val, cls=int): - try: - return [cls(val)] - except: - return [] + + else: + raise JsonPointerException("can not go beyond '%s' (type '%s')" % (part, doc.__class__)) @@ -4,7 +4,7 @@ import doctest import unittest import sys -from jsonpointer import resolve_pointer +from jsonpointer import resolve_pointer, EndOfList, JsonPointerException class SpecificationTests(unittest.TestCase): """ Tests all examples from the JSON Pointer specification """ @@ -37,6 +37,14 @@ class SpecificationTests(unittest.TestCase): self.assertEqual(resolve_pointer(doc, "/m~0n"), 8) + def test_eol(self): + doc = { + "foo": ["bar", "baz"] + } + + self.assertTrue(isinstance(resolve_pointer(doc, "/foo/-"), EndOfList)) + self.assertRaises(JsonPointerException, resolve_pointer, doc, "/foo/-/1") + modules = ['jsonpointer'] |