summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shorin <kxepal@apache.org>2013-10-28 06:10:38 +0400
committerAlexander Shorin <kxepal@apache.org>2013-10-28 06:10:38 +0400
commita46fad1ee1deea872347a28329236bb1af467ff4 (patch)
tree56cbd7e88841acb80cf150eab69a9860c9aea3be
parent07667c6d0d582d9f11a6e0779fbab25db0417614 (diff)
downloadpython-json-patch-a46fad1ee1deea872347a28329236bb1af467ff4.tar.gz
Raise pylint score from 6.87 to 9.10
-rw-r--r--jsonpatch.py113
1 files changed, 62 insertions, 51 deletions
diff --git a/jsonpatch.py b/jsonpatch.py
index aec583b..5f82c23 100644
--- a/jsonpatch.py
+++ b/jsonpatch.py
@@ -30,9 +30,19 @@
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
+""" Apply JSON-Patches (RFC 6902) """
+
from __future__ import unicode_literals
-""" Apply JSON-Patches (RFC 6902) """
+import collections
+import copy
+import functools
+import inspect
+import json
+import operator
+import sys
+
+from jsonpointer import JsonPointer, JsonPointerException
# Will be parsed by setup.py to determine package metadata
__author__ = 'Stefan Kögl <stefan@skoegl.net>'
@@ -40,21 +50,10 @@ __version__ = '1.3'
__website__ = 'https://github.com/stefankoegl/python-json-patch'
__license__ = 'Modified BSD License'
-import copy
-import sys
-import operator
-import collections
-
-import json
-
-import jsonpointer
-
if sys.version_info >= (3, 0):
- basestring = (bytes, str)
+ basestring = (bytes, str) # pylint: disable=C0103
-JsonPointerException = jsonpointer.JsonPointerException
-
class JsonPatchException(Exception):
"""Base Json Patch exception"""
@@ -67,6 +66,7 @@ class JsonPatchConflict(JsonPatchException):
- etc.
"""
+
class JsonPatchTestFailed(JsonPatchException, AssertionError):
""" A Test operation failed """
@@ -74,15 +74,15 @@ class JsonPatchTestFailed(JsonPatchException, AssertionError):
def multidict(ordered_pairs):
"""Convert duplicate keys values to lists."""
# read all values into lists
- d = collections.defaultdict(list)
- for k, v in ordered_pairs:
- d[k].append(v)
+ mdict = collections.defaultdict(list)
+ for key, value in ordered_pairs:
+ mdict[key].append(value)
# unpack lists that have only 1 item
- for k, v in d.items():
- if len(v) == 1:
- d[k] = v[0]
- return dict(d)
+ for key, values in mdict.items():
+ if len(values) == 1:
+ mdict[key] = values[0]
+ return dict(mdict)
def get_loadjson():
@@ -94,9 +94,6 @@ def get_loadjson():
function with object_pairs_hook set to multidict for Python versions that
support the parameter. """
- import inspect
- import functools
-
argspec = inspect.getargspec(json.load)
if 'object_pairs_hook' not in argspec.args:
return json.load
@@ -123,12 +120,14 @@ def apply_patch(doc, patch, in_place=False):
:rtype: dict
>>> doc = {'foo': 'bar'}
- >>> other = apply_patch(doc, [{'op': 'add', 'path': '/baz', 'value': 'qux'}])
+ >>> patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}]
+ >>> other = apply_patch(doc, patch)
>>> doc is not other
True
>>> other == {'foo': 'bar', 'baz': 'qux'}
True
- >>> apply_patch(doc, [{'op': 'add', 'path': '/baz', 'value': 'qux'}], in_place=True) == {'foo': 'bar', 'baz': 'qux'}
+ >>> patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}]
+ >>> apply_patch(doc, patch, in_place=True) == {'foo': 'bar', 'baz': 'qux'}
True
>>> doc == other
True
@@ -140,6 +139,7 @@ def apply_patch(doc, patch, in_place=False):
patch = JsonPatch(patch)
return patch.apply(doc, in_place)
+
def make_patch(src, dst):
"""Generates patch by comparing of two document objects. Actually is
a proxy to :meth:`JsonPatch.from_diff` method.
@@ -230,11 +230,9 @@ class JsonPatch(object):
def __iter__(self):
return iter(self.patch)
-
def __hash__(self):
return hash(tuple(self._ops))
-
def __eq__(self, other):
if not isinstance(other, JsonPatch):
return False
@@ -242,7 +240,6 @@ class JsonPatch(object):
return len(list(self._ops)) == len(list(other._ops)) and \
all(map(operator.eq, self._ops, other._ops))
-
@classmethod
def from_string(cls, patch_str):
"""Creates JsonPatch instance from string source.
@@ -298,7 +295,9 @@ class JsonPatch(object):
yield operation
for key in dst:
if key not in src:
- yield {'op': 'add', 'path': '/'.join(path + [key]), 'value': dst[key]}
+ yield {'op': 'add',
+ 'path': '/'.join(path + [key]),
+ 'value': dst[key]}
def compare_list(path, src, dst):
lsrc, ldst = len(src), len(dst)
@@ -309,7 +308,9 @@ class JsonPatch(object):
if lsrc < ldst:
for idx in range(lsrc, ldst):
current = path + [str(idx)]
- yield {'op': 'add', 'path': '/'.join(current), 'value': dst[idx]}
+ yield {'op': 'add',
+ 'path': '/'.join(current),
+ 'value': dst[idx]}
elif lsrc > ldst:
for idx in reversed(range(ldst, lsrc)):
yield {'op': 'remove', 'path': '/'.join(path + [str(idx)])}
@@ -361,28 +362,24 @@ class JsonPatch(object):
return cls(operation)
-
class PatchOperation(object):
"""A single operation inside a JSON Patch."""
def __init__(self, operation):
self.location = operation['path']
- self.pointer = jsonpointer.JsonPointer(self.location)
+ self.pointer = JsonPointer(self.location)
self.operation = operation
def apply(self, obj):
"""Abstract method that applies patch operation to specified object."""
raise NotImplementedError('should implement patch operation.')
-
def __hash__(self):
return hash(frozenset(self.operation.items()))
-
def __eq__(self, other):
if not isinstance(other, PatchOperation):
return False
-
return self.operation == other.operation
@@ -409,24 +406,22 @@ class AddOperation(PatchOperation):
# type is already checked in to_last(), so we assert here
# for consistency
assert isinstance(subobj, list) or isinstance(subobj, dict), \
- "invalid document type %s" (type(doc),)
+ "invalid document type %s" % type(subobj)
if isinstance(subobj, list):
if part == '-':
- subobj.append(value)
+ subobj.append(value) # pylint: disable=E1103
elif part > len(subobj) or part < 0:
raise JsonPatchConflict("can't insert outside of list")
else:
- subobj.insert(part, value)
+ subobj.insert(part, value) # pylint: disable=E1103
elif isinstance(subobj, dict):
if part is None:
- # we're replacing the root
- obj = value
-
+ obj = value # we're replacing the root
else:
subobj[part] = value
@@ -443,7 +438,7 @@ class ReplaceOperation(PatchOperation):
# type is already checked in to_last(), so we assert here
# for consistency
assert isinstance(subobj, list) or isinstance(subobj, dict), \
- "invalid document type %s" (type(doc),)
+ "invalid document type %s" % subobj
if part is None:
return value
@@ -454,8 +449,8 @@ class ReplaceOperation(PatchOperation):
elif isinstance(subobj, dict):
if not part in subobj:
- raise JsonPatchConflict("can't replace non-existant object '%s'"
- "" % part)
+ raise JsonPatchConflict("can't replace non-existent object '%s'"
+ % part)
subobj[part] = value
return obj
@@ -465,15 +460,24 @@ class MoveOperation(PatchOperation):
"""Moves an object property or an array element to new location."""
def apply(self, obj):
- from_ptr = jsonpointer.JsonPointer(self.operation['from'])
+ from_ptr = JsonPointer(self.operation['from'])
subobj, part = from_ptr.to_last(obj)
value = subobj[part]
if self.pointer.contains(from_ptr):
raise JsonPatchException('Cannot move values into its own children')
- obj = RemoveOperation({'op': 'remove', 'path': self.operation['from']}).apply(obj)
- obj = AddOperation({'op': 'add', 'path': self.location, 'value': value}).apply(obj)
+ obj = RemoveOperation({
+ 'op': 'remove',
+ 'path': self.operation['from']
+ }).apply(obj)
+
+ obj = AddOperation({
+ 'op': 'add',
+ 'path': self.location,
+ 'value': value
+ }).apply(obj)
+
return obj
@@ -487,14 +491,15 @@ class TestOperation(PatchOperation):
val = subobj
else:
val = self.pointer.walk(subobj, part)
-
except JsonPointerException as ex:
raise JsonPatchTestFailed(str(ex))
if 'value' in self.operation:
value = self.operation['value']
if val != value:
- raise JsonPatchTestFailed('%s is not equal to tested value %s (types %s and %s)' % (val, value, type(val), type(value)))
+ raise JsonPatchTestFailed(
+ '%s is not equal to tested value %s (types %s and %s)'
+ % (val, value, type(val), type(value)))
return obj
@@ -503,8 +508,14 @@ class CopyOperation(PatchOperation):
""" Copies an object property or an array element to a new location """
def apply(self, obj):
- from_ptr = jsonpointer.JsonPointer(self.operation['from'])
+ from_ptr = JsonPointer(self.operation['from'])
subobj, part = from_ptr.to_last(obj)
value = copy.deepcopy(subobj[part])
- obj = AddOperation({'op': 'add', 'path': self.location, 'value': value}).apply(obj)
+
+ obj = AddOperation({
+ 'op': 'add',
+ 'path': self.location,
+ 'value': value
+ }).apply(obj)
+
return obj