summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kögl <stefan@skoegl.net>2017-09-10 19:40:12 +0200
committerStefan Kögl <stefan@skoegl.net>2017-09-10 19:40:12 +0200
commit244bed3e827166dcffaf5fec5abb16736fe9d8c5 (patch)
tree1b2c3597848061219b202af8bb444987f18551c3
parent85ff9a1b2165edce7baae2ddbf60a2a7f2557ce5 (diff)
downloadpython-json-pointer-244bed3e827166dcffaf5fec5abb16736fe9d8c5.tar.gz
Revert optimizations due to compatibility issues with jsonpatch
-rw-r--r--.travis.yml34
-rw-r--r--jsonpointer.py148
-rw-r--r--requirements-dev.txt2
3 files changed, 77 insertions, 107 deletions
diff --git a/.travis.yml b/.travis.yml
index 7c737e4..389dc95 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,25 +1,21 @@
language: python
python:
-- '2.6'
-- '2.7'
-- '3.3'
-- '3.4'
-- '3.5'
-- '3.6'
-- pypy
-- pypy3
+ - "2.6"
+ - "2.7"
+ - "3.3"
+ - "3.4"
+ - "3.5"
+ - "3.6"
+ - "pypy"
+ - "pypy3"
+
install:
-- travis_retry pip install coveralls
+ - travis_retry pip install coveralls
+
script:
-- coverage run --source=jsonpointer tests.py
+ - coverage run --source=jsonpointer tests.py
+
after_script:
-- coveralls
+ - coveralls
+
sudo: false
-deploy:
- provider: pypi
- user: skoegl
- password:
- secure: g+81X6n8etmQQ9ZbxoSx/OoXsDHBwgoBlesnrYP4RBHLoez3wBbI2w1tu7Uce2irWMmkoFIpQHguXxOqHVoGzx18s1njp9/1fyrJ3f6gYbcQrUnwRFjYGcIc0TUSTI9dLpnRKCp9glNwIvPx7n6/5avZIaXveLU9j4DIm1xA1ZM=
- on:
- tags: true
- distributions: sdist bdist_wheel
diff --git a/jsonpointer.py b/jsonpointer.py
index 5d41b58..9a6a613 100644
--- a/jsonpointer.py
+++ b/jsonpointer.py
@@ -36,22 +36,25 @@ from __future__ import unicode_literals
# Will be parsed by setup.py to determine package metadata
__author__ = 'Stefan Kögl <stefan@skoegl.net>'
-__version__ = '1.11'
+__version__ = '1.10'
__website__ = 'https://github.com/stefankoegl/python-json-pointer'
__license__ = 'Modified BSD License'
try:
from urllib import unquote
+ from itertools import izip
str = unicode
except ImportError: # Python 3
from urllib.parse import unquote
+ izip = zip
try:
from collections.abc import Mapping, Sequence
except ImportError: # Python 3
from collections import Mapping, Sequence
+from itertools import tee
import re
import copy
@@ -108,6 +111,26 @@ def resolve_pointer(doc, pointer, default=_nothing):
return pointer.resolve(doc, default)
+def pairwise(iterable):
+ """ Transforms a list to a list of tuples of adjacent items
+
+ s -> (s0,s1), (s1,s2), (s2, s3), ...
+
+ >>> list(pairwise([]))
+ []
+
+ >>> list(pairwise([1]))
+ []
+
+ >>> list(pairwise([1, 2, 3, 4]))
+ [(1, 2), (2, 3), (3, 4)]
+ """
+ a, b = tee(iterable)
+ for _ in b:
+ break
+ return izip(a, b)
+
+
class JsonPointerException(Exception):
pass
@@ -145,62 +168,23 @@ class JsonPointer(object):
if not self.parts:
return doc, None
- 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 self._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, returns the referenced object """
- if parts is None:
- parts = self.parts
+ for part in self.parts[:-1]:
+ doc = self.walk(doc, part)
- 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 self._RE_ARRAY_INDEX.match(str(part)):
- raise JsonPointerException(
- "'%s' is not a valid list index" % (part, )
- )
- doc = doc[int(part)]
+ return doc, self.get_part(doc, self.parts[-1])
+
+ def resolve(self, doc, default=_nothing):
+ """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
else:
- 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 default
return doc
@@ -225,19 +209,17 @@ class JsonPointer(object):
def get_part(self, doc, part):
"""Returns the next step in the correct type"""
- # 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:
+ if isinstance(doc, Mapping):
return part
- if ptype == list or isinstance(doc, Sequence):
+
+ elif isinstance(doc, Sequence):
+
if part == '-':
return part
if not self._RE_ARRAY_INDEX.match(str(part)):
- raise JsonPointerException(
- "'%s' is not a valid list index" % (part, )
- )
+ raise JsonPointerException("'%s' is not a valid sequence index" % part)
+
return int(part)
elif hasattr(doc, '__getitem__'):
@@ -246,42 +228,34 @@ class JsonPointer(object):
return part
else:
- raise JsonPointerException(
- "Document '%s' does not support indexing, must be "
- "mapping/sequence or support __getitem__" % type(doc)
- )
+ raise JsonPointerException("Document '%s' does not support indexing, "
+ "must be mapping/sequence or support __getitem__" % type(doc))
+
def walk(self, doc, part):
""" Walks one step in doc and returns the referenced part """
part = self.get_part(doc, part)
- if part == '-' and isinstance(doc, Sequence):
- return EndOfList(doc)
+ assert hasattr(doc, '__getitem__'), "invalid document type %s" % (type(doc),)
- try:
- return doc[part]
+ if isinstance(doc, Sequence):
+ if part == '-':
+ return EndOfList(doc)
- except KeyError:
- raise JsonPointerException(
- "member '%s' not found in %s" % (part, doc)
- )
+ try:
+ return doc[part]
- except IndexError:
- raise JsonPointerException(
- "index '%s' is out of bounds" % (part, )
- )
+ 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)
- )
+ # Else the object is a mapping or supports __getitem__(so assume custom indexing)
+ try:
+ return doc[part]
except KeyError:
- raise JsonPointerException(
- "member '%s' not found in %s" % (part, doc)
- )
+ raise JsonPointerException("member '%s' not found in %s" % (part, doc))
+
def contains(self, ptr):
""" Returns True if self contains the given ptr """
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 51e335b..fd0fd6c 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,2 +1,2 @@
wheel
-pandoc==1.0.0b2
+pandoc==1.0.0-alpha.3