diff options
author | Christian Lyder Jacobsen <christian@yocuda.com> | 2020-01-31 11:58:59 +0100 |
---|---|---|
committer | Christian Lyder Jacobsen <christian@yocuda.com> | 2020-01-31 12:05:32 +0100 |
commit | e99d178396f69f8891a62e21434c2783b76146b2 (patch) | |
tree | 86bbacebbc42cd0a4c93fa1541443dcce688d670 | |
parent | 91f61241adc9d104e1811eeaf4d9dc6518d6786e (diff) | |
download | python-json-patch-e99d178396f69f8891a62e21434c2783b76146b2.tar.gz |
Make it possible for from_diff to support custom types (issue #107)
-rw-r--r-- | jsonpatch.py | 13 | ||||
-rwxr-xr-x | tests.py | 15 |
2 files changed, 24 insertions, 4 deletions
diff --git a/jsonpatch.py b/jsonpatch.py index 7f31ce5..ebaa8e3 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -258,7 +258,7 @@ class JsonPatch(object): return cls(patch) @classmethod - def from_diff(cls, src, dst, optimization=True): + def from_diff(cls, src, dst, optimization=True, dumps=json.dumps): """Creates JsonPatch instance based on comparing of two document objects. Json patch would be created for `src` argument against `dst` one. @@ -269,6 +269,10 @@ class JsonPatch(object): :param dst: Data source document object. :type dst: dict + :param dumps: A function of one argument that produces a serialized + JSON string. + :type dumps: function + :return: :class:`JsonPatch` instance. >>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]} @@ -279,7 +283,7 @@ class JsonPatch(object): True """ - builder = DiffBuilder() + builder = DiffBuilder(dumps) builder._compare_values('', None, src, dst) ops = list(builder.execute()) return cls(ops) @@ -637,7 +641,8 @@ class CopyOperation(PatchOperation): class DiffBuilder(object): - def __init__(self): + def __init__(self, dumps): + self.dumps = dumps self.index_storage = [{}, {}] self.index_storage2 = [[], []] self.__root = root = [] @@ -832,7 +837,7 @@ class DiffBuilder(object): # and ignore those that don't. The performance of this could be # improved by doing more direct type checks, but we'd need to be # careful to accept type changes that don't matter when JSONified. - elif json.dumps(src) == json.dumps(dst): + elif self.dumps(src) == self.dumps(dst): return else: @@ -4,6 +4,7 @@ from __future__ import unicode_literals import json +import decimal import doctest import unittest import jsonpatch @@ -445,6 +446,20 @@ class MakePatchTestCase(unittest.TestCase): self.assertEqual(res, dst) self.assertIsInstance(res['A'], float) + def test_custom_types(self): + def default(obj): + if isinstance(obj, decimal.Decimal): + return str(obj) + raise TypeError('Unknown type') + + def dumps(obj): + return json.dumps(obj, default=default) + + old = {'value': decimal.Decimal('1.0')} + new = {'value': decimal.Decimal('1.00')} + patch = jsonpatch.JsonPatch.from_diff(old, new, dumps=dumps) + new_from_patch = jsonpatch.apply_patch(old, patch) + self.assertEqual(new, new_from_patch) class OptimizationTests(unittest.TestCase): |