summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kögl <stefan@skoegl.net>2012-11-08 15:55:45 +0100
committerStefan Kögl <stefan@skoegl.net>2012-11-08 15:55:45 +0100
commit16d29f8fa10664a92f27b47d617260f0e5d13b9a (patch)
tree90aa95a21273e2d669a931130232f1f2e655f935
parent97a06ecb9dde82bd54dc269052841035ca2a1390 (diff)
downloadpython-json-pointer-16d29f8fa10664a92f27b47d617260f0e5d13b9a.tar.gz
update jsonpointer to current spec
http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-05
-rw-r--r--jsonpointer.py49
-rwxr-xr-xtests.py10
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__))
diff --git a/tests.py b/tests.py
index 57a4818..a0a2c79 100755
--- a/tests.py
+++ b/tests.py
@@ -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']