diff options
author | Stefan Kögl <stefan@skoegl.net> | 2017-09-10 16:25:27 +0200 |
---|---|---|
committer | Stefan Kögl <stefan@skoegl.net> | 2017-09-10 19:24:48 +0200 |
commit | 03aa14e8209d59522476726d55bfabf86a28929e (patch) | |
tree | d82e26beab6199fc25cff1bd12cbf18264cf0b51 /jsonpatch.py | |
parent | 2f45e50b8a3139e56e359d6b8d56227c5680ca8f (diff) | |
download | python-json-patch-03aa14e8209d59522476726d55bfabf86a28929e.tar.gz |
Merge _op_base classes into PatchOperation classes
Diffstat (limited to 'jsonpatch.py')
-rw-r--r-- | jsonpatch.py | 225 |
1 files changed, 113 insertions, 112 deletions
diff --git a/jsonpatch.py b/jsonpatch.py index 8db0b7f..72fa52f 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -379,6 +379,23 @@ class PatchOperation(object): def __ne__(self, other): return not(self == other) + @property + def path(self): + return '/'.join(self.pointer.parts[:-1]) + + @property + def key(self): + try: + return int(self.pointer.parts[-1]) + except ValueError: + return self.pointer.parts[-1] + + @key.setter + def key(self, value): + self.pointer.parts[-1] = str(value) + self.location = self.pointer.path + self.operation['path'] = self.location + class RemoveOperation(PatchOperation): """Removes an object property or an array element.""" @@ -393,6 +410,22 @@ class RemoveOperation(PatchOperation): return obj + def _on_undo_remove(self, path, key): + if self.path == path: + if self.key >= key: + self.key += 1 + else: + key -= 1 + return key + + def _on_undo_add(self, path, key): + if self.path == path: + if self.key > key: + self.key -= 1 + else: + key -= 1 + return key + class AddOperation(PatchOperation): """Adds an object property or an array element.""" @@ -427,6 +460,22 @@ class AddOperation(PatchOperation): return obj + def _on_undo_remove(self, path, key): + if self.path == path: + if self.key > key: + self.key += 1 + else: + key += 1 + return key + + def _on_undo_add(self, path, key): + if self.path == path: + if self.key > key: + self.key -= 1 + else: + key += 1 + return key + class ReplaceOperation(PatchOperation): """Replaces an object property or an array element by new value.""" @@ -457,6 +506,12 @@ class ReplaceOperation(PatchOperation): subobj[part] = value return obj + def _on_undo_remove(self, path, key): + return key + + def _on_undo_add(self, path, key): + return key + class MoveOperation(PatchOperation): """Moves an object property or an array element to new location.""" @@ -495,6 +550,51 @@ class MoveOperation(PatchOperation): return obj + @property + def oldpath(self): + oldptr = JsonPointer(self.operation['from']) + return '/'.join(oldptr.parts[:-1]) + + @property + def oldkey(self): + oldptr = JsonPointer(self.operation['from']) + try: + return int(oldptr.parts[-1]) + except TypeError: + return oldptr.parts[-1] + + @oldkey.setter + def oldkey(self, value): + oldptr = JsonPointer(self.operation['from']) + oldptr.parts[-1] = str(value) + self.operation['from'] = oldptr.path + + def _on_undo_remove(self, path, key): + if self.oldpath == path: + if self.oldkey >= key: + self.oldkey += 1 + else: + key -= 1 + if self.path == path: + if self.key > key: + self.key += 1 + else: + key += 1 + return key + + def _on_undo_add(self, path, key): + if self.oldpath == path: + if self.oldkey > key: + self.oldkey -= 1 + else: + key -= 1 + if self.path == path: + if self.key > key: + self.key -= 1 + else: + key += 1 + return key + class TestOperation(PatchOperation): """Test value by specified location.""" @@ -610,115 +710,16 @@ class _compare_info(object): while curr is not root: if curr[1] is not root: op_first, op_second = curr[2], curr[1][2] - if op_first.key == op_second.key and \ - op_first.path == op_second.path and \ - type(op_first) == _op_remove and \ - type(op_second) == _op_add: - yield _op_replace(op_second.path, op_second.key, op_second.value).get() + if ( #op_first.key == op_second.key and \ + op_first.location == op_second.location and \ + type(op_first) == RemoveOperation and \ + type(op_second) == AddOperation): + yield ReplaceOperation({'op': 'replace', 'path': op_second.location, 'value': op_second.operation['value']}).operation curr = curr[1][1] continue - yield curr[2].get() + yield curr[2].operation curr = curr[1] -class _op_base(object): - def __init__(self, path, key, value): - self.path = path - self.key = key - self.value = value - - def __repr__(self): - return str(self.get()) - -class _op_add(_op_base): - def _on_undo_remove(self, path, key): - if self.path == path: - if self.key > key: - self.key += 1 - else: - key += 1 - return key - - def _on_undo_add(self, path, key): - if self.path == path: - if self.key > key: - self.key -= 1 - else: - key += 1 - return key - - def get(self): - return {'op': 'add', 'path': _path_join(self.path, self.key), 'value': self.value} - -class _op_remove(_op_base): - def _on_undo_remove(self, path, key): - if self.path == path: - if self.key >= key: - self.key += 1 - else: - key -= 1 - return key - - def _on_undo_add(self, path, key): - if self.path == path: - if self.key > key: - self.key -= 1 - else: - key -= 1 - return key - - def get(self): - return {'op': 'remove', 'path': _path_join(self.path, self.key)} - -class _op_replace(_op_base): - def _on_undo_remove(self, path, key): - return key - - def _on_undo_add(self, path, key): - return key - - def get(self): - return {'op': 'replace', 'path': _path_join(self.path, self.key), 'value': self.value} - - -class _op_move(object): - def __init__(self, oldpath, oldkey, path, key): - self.oldpath = oldpath - self.oldkey = oldkey - self.path = path - self.key = key - - def _on_undo_remove(self, path, key): - if self.oldpath == path: - if self.oldkey >= key: - self.oldkey += 1 - else: - key -= 1 - if self.path == path: - if self.key > key: - self.key += 1 - else: - key += 1 - return key - - def _on_undo_add(self, path, key): - if self.oldpath == path: - if self.oldkey > key: - self.oldkey -= 1 - else: - key -= 1 - if self.path == path: - if self.key > key: - self.key -= 1 - else: - key += 1 - return key - - def get(self): - return {'op': 'move', 'path': _path_join(self.path, self.key), 'from': _path_join(self.oldpath, self.oldkey)} - - def __repr__(self): - return str(self.get()) - def _path_join(path, key): if key != None: return path + '/' + str(key).replace('~', '~0').replace('/', '~1') @@ -732,16 +733,16 @@ def _item_added(path, key, info, item): for v in info.iter_from(index): op.key = v._on_undo_remove(op.path, op.key) info.remove(index) - if op.path != path or op.key != key: - new_op = _op_move(op.path, op.key, path, key) + if op.location != _path_join(path, key): + new_op = MoveOperation({'op': 'move', 'from': op.location, 'path': _path_join(path, key)}) info.insert(new_op) else: - new_op = _op_add(path, key, item) + new_op = AddOperation({'op': 'add', 'path': _path_join(path, key), 'value': item}) new_index = info.insert(new_op) info.store_index(item, new_index, _ST_ADD) def _item_removed(path, key, info, item): - new_op = _op_remove(path, key, item) + new_op = RemoveOperation({'op': 'remove', 'path': _path_join(path, key), 'value': item}) index = info.take_index(item, _ST_ADD) new_index = info.insert(new_op) if index != None: @@ -750,8 +751,8 @@ def _item_removed(path, key, info, item): for v in info.iter_from(index): op.key = v._on_undo_add(op.path, op.key) info.remove(index) - if new_op.path != op.path or new_op.key != op.key: - new_op = _op_move(new_op.path, new_op.key, op.path, op.key) + if new_op.location != op.location: + new_op = MoveOperation({'op': 'move', 'from': new_op.location, 'path': op.location}) new_index[2] = new_op else: info.remove(new_index) @@ -759,7 +760,7 @@ def _item_removed(path, key, info, item): info.store_index(item, new_index, _ST_REMOVE) def _item_replaced(path, key, info, item): - info.insert(_op_replace(path, key, item)) + info.insert(ReplaceOperation({'op': 'replace', 'path': _path_join(path, key), 'value': item})) def _compare_dicts(path, info, src, dst): src_keys = _viewkeys(src) |