Hello community, here is the log from the commit of package python-jsonpatch for openSUSE:Factory checked in at 2017-08-16 16:12:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jsonpatch (Old) and /work/SRC/openSUSE:Factory/.python-jsonpatch.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jsonpatch" Wed Aug 16 16:12:42 2017 rev:15 rq:515124 version:1.16 Changes: -------- --- /work/SRC/openSUSE:Factory/python-jsonpatch/python-jsonpatch.changes 2016-12-08 00:29:54.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python-jsonpatch.new/python-jsonpatch.changes 2017-08-16 16:12:48.541002757 +0200 @@ -1,0 +2,11 @@ +Tue Aug 8 06:27:14 UTC 2017 - [email protected] + +- Fix Requires + +------------------------------------------------------------------- +Fri Jul 28 14:43:04 UTC 2017 - [email protected] + +- Convert packaging to Singlespec +- update to 1.16 + +------------------------------------------------------------------- Old: ---- jsonpatch-1.14.tar.gz New: ---- jsonpatch-1.16.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jsonpatch.spec ++++++ --- /var/tmp/diff_new_pack.36LIu1/_old 2017-08-16 16:12:50.100783813 +0200 +++ /var/tmp/diff_new_pack.36LIu1/_new 2017-08-16 16:12:50.104783252 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-jsonpatch # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,64 +16,58 @@ # +%{?!python_module:%define python_module() python-%{**} python3-%{**}} +%bcond_without test Name: python-jsonpatch -Version: 1.14 +Version: 1.16 Release: 0 Summary: Python - JSON-Patches License: BSD-3-Clause Group: Development/Languages/Python Url: https://github.com/stefankoegl/python-json-patch Source: https://pypi.io/packages/source/j/jsonpatch/jsonpatch-%{version}.tar.gz -BuildRequires: python-devel -BuildRequires: python-jsonpointer +BuildRequires: %{python_module devel} +BuildRequires: %{python_module setuptools} +BuildRequires: python-rpm-macros +%if %{with test} +BuildRequires: %{python_module jsonpointer >= 1.9} +%endif Requires: python-jsonpointer >= 1.9 Requires(post): update-alternatives Requires(preun): update-alternatives BuildRoot: %{_tmppath}/%{name}-%{version}-build -%if 0%{?suse_version} && 0%{?suse_version} <= 1110 -%{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} -%else BuildArch: noarch -%endif + +%python_subpackages %description Python module to apply JSON-Patches (according to RFC 6902). %prep %setup -q -n jsonpatch-%{version} -sed -i "s|entry_poimts|entry_points|" setup.py # Typo fix already in upstream git.. %build -python setup.py build +%python_build %install -python setup.py install --prefix=%{_prefix} --root=%{buildroot} +%python_install # Prepare for update-alternatives usage -mkdir -p %{buildroot}%{_sysconfdir}/alternatives for p in jsonpatch jsondiff ; do - mv %{buildroot}%{_bindir}/$p %{buildroot}%{_bindir}/$p-%{py_ver} - ln -s -f %{_sysconfdir}/alternatives/$p %{buildroot}%{_bindir}/$p + %python_clone -a %{buildroot}%{_bindir}/$p done %post -%_sbindir/update-alternatives \ - --install %{_bindir}/jsonpatch jsonpatch %{_bindir}/jsonpatch-%{py_ver} 20 \ - --slave %{_bindir}/jsondiff jsondiff %{_bindir}/jsondiff-%{py_ver} +%python_install_alternative jsonpatch jsondiff %preun -if [ $1 -eq 0 ] ; then - %_sbindir/update-alternatives --remove jsonpatch %{_bindir}/jsonpatch-%{py_ver} -fi +%python_uninstall_alternative jsonpatch jsondiff -%files +%files %{python_files} %defattr(-,root,root,-) -%{_bindir}/jsondiff -%{_bindir}/jsonpatch -%{_bindir}/jsondiff-%{py_ver} -%{_bindir}/jsonpatch-%{py_ver} -%ghost %{_sysconfdir}/alternatives/jsondiff -%ghost %{_sysconfdir}/alternatives/jsonpatch -%{python_sitelib}/jsonpatch* +%doc AUTHORS COPYING README.md +%python_alternative %{_bindir}/jsonpatch +%python_alternative %{_bindir}/jsondiff +%{python_sitelib}/* %changelog ++++++ jsonpatch-1.14.tar.gz -> jsonpatch-1.16.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/PKG-INFO new/jsonpatch-1.16/PKG-INFO --- old/jsonpatch-1.14/PKG-INFO 2016-05-31 20:24:55.000000000 +0200 +++ new/jsonpatch-1.16/PKG-INFO 2017-06-15 17:42:22.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: jsonpatch -Version: 1.14 +Version: 1.16 Summary: Apply JSON-Patches (RFC 6902) Home-page: https://github.com/stefankoegl/python-json-patch Author: Stefan Kögl @@ -41,6 +41,7 @@ .. |Downloads| image:: https://pypip.in/d/jsonpatch/badge.png .. |Version| image:: https://pypip.in/v/jsonpatch/badge.png + Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console @@ -56,6 +57,7 @@ Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/bin/jsondiff new/jsonpatch-1.16/bin/jsondiff --- old/jsonpatch-1.14/bin/jsondiff 2015-10-28 20:19:28.000000000 +0100 +++ new/jsonpatch-1.16/bin/jsondiff 2017-01-12 22:23:15.000000000 +0100 @@ -32,8 +32,9 @@ doc1 = json.load(args.FILE1) doc2 = json.load(args.FILE2) patch = jsonpatch.make_patch(doc1, doc2) - print(json.dumps(patch.patch, indent=args.indent)) - + if patch.patch: + print(json.dumps(patch.patch, indent=args.indent)) + sys.exit(1) if __name__ == "__main__": main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/jsonpatch.egg-info/PKG-INFO new/jsonpatch-1.16/jsonpatch.egg-info/PKG-INFO --- old/jsonpatch-1.14/jsonpatch.egg-info/PKG-INFO 2016-05-31 20:24:55.000000000 +0200 +++ new/jsonpatch-1.16/jsonpatch.egg-info/PKG-INFO 2017-06-15 17:42:22.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: jsonpatch -Version: 1.14 +Version: 1.16 Summary: Apply JSON-Patches (RFC 6902) Home-page: https://github.com/stefankoegl/python-json-patch Author: Stefan Kögl @@ -41,6 +41,7 @@ .. |Downloads| image:: https://pypip.in/d/jsonpatch/badge.png .. |Version| image:: https://pypip.in/v/jsonpatch/badge.png + Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console @@ -56,6 +57,7 @@ Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/jsonpatch.egg-info/requires.txt new/jsonpatch-1.16/jsonpatch.egg-info/requires.txt --- old/jsonpatch-1.14/jsonpatch.egg-info/requires.txt 2016-05-31 20:24:55.000000000 +0200 +++ new/jsonpatch-1.16/jsonpatch.egg-info/requires.txt 2017-06-15 17:42:22.000000000 +0200 @@ -1 +1 @@ -jsonpointer>=1.9 \ No newline at end of file +jsonpointer>=1.9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/jsonpatch.py new/jsonpatch-1.16/jsonpatch.py --- old/jsonpatch-1.14/jsonpatch.py 2016-05-31 18:51:21.000000000 +0200 +++ new/jsonpatch-1.16/jsonpatch.py 2017-06-15 17:41:02.000000000 +0200 @@ -51,7 +51,7 @@ # Will be parsed by setup.py to determine package metadata __author__ = 'Stefan Kögl <[email protected]>' -__version__ = '1.14' +__version__ = '1.16' __website__ = 'https://github.com/stefankoegl/python-json-patch' __license__ = 'Modified BSD License' @@ -105,8 +105,11 @@ function with object_pairs_hook set to multidict for Python versions that support the parameter. """ - argspec = inspect.getargspec(json.load) - if 'object_pairs_hook' not in argspec.args: + if sys.version_info >= (3, 3): + args = inspect.signature(json.load).parameters + else: + args = inspect.getargspec(json.load).args + if 'object_pairs_hook' not in args: return json.load return functools.partial(json.load, object_pairs_hook=multidict) @@ -168,6 +171,14 @@ >>> new == dst True """ + + # TODO: fix patch optimiztion and remove the following check + # fix when patch with optimization is incorrect + patch = JsonPatch.from_diff(src, dst) + new = patch.apply(src) + if new != dst: + return JsonPatch.from_diff(src, dst, False) + return JsonPatch.from_diff(src, dst) @@ -265,7 +276,7 @@ return cls(patch) @classmethod - def from_diff(cls, src, dst): + def from_diff(cls, src, dst, optimization=True): """Creates JsonPatch instance based on comparing of two document objects. Json patch would be created for `src` argument against `dst` one. @@ -317,7 +328,7 @@ 'value': dst[key]} def compare_lists(path, src, dst): - return _compare_lists(path, src, dst) + return _compare_lists(path, src, dst, optimization=optimization) return cls(list(compare_values([], src, dst))) @@ -558,9 +569,12 @@ return obj -def _compare_lists(path, src, dst): +def _compare_lists(path, src, dst, optimization=True): """Compares two lists objects and return JSON patch about.""" - return _optimize(_compare(path, src, dst, *_split_by_common_seq(src, dst))) + patch = list(_compare(path, src, dst, *_split_by_common_seq(src, dst))) + if optimization: + return list(_optimize(patch)) + return patch def _longest_common_subseq(src, dst): @@ -767,7 +781,16 @@ if cur['op'] == 'add': # make recursive patch patch = make_patch(prev['value'], cur['value']) - if len(patch.patch) == 1 and patch.patch[0]['op'] != 'remove': + # check case when dict "remove" is less than "add" and has a same key + if isinstance(prev['value'], dict) and isinstance(cur['value'], dict) and len(prev['value'].keys()) == 1: + prev_set = set(prev['value'].keys()) + cur_set = set(cur['value'].keys()) + if prev_set & cur_set == prev_set: + patch = make_patch(cur['value'], prev['value']) + + if len(patch.patch) == 1 and \ + patch.patch[0]['op'] != 'remove' and \ + patch.patch[0]['path'] and patch.patch[0]['path'].split('/')[1] in prev['value']: prev['path'] = prev['path'] + patch.patch[0]['path'] prev['value'] = patch.patch[0]['value'] else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/setup.cfg new/jsonpatch-1.16/setup.cfg --- old/jsonpatch-1.14/setup.cfg 2016-05-31 20:24:55.000000000 +0200 +++ new/jsonpatch-1.16/setup.cfg 2017-06-15 17:42:22.000000000 +0200 @@ -2,7 +2,7 @@ universal = 1 [egg_info] -tag_svn_revision = 0 -tag_date = 0 tag_build = +tag_date = 0 +tag_svn_revision = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/setup.py new/jsonpatch-1.16/setup.py --- old/jsonpatch-1.14/setup.py 2016-02-13 19:04:52.000000000 +0100 +++ new/jsonpatch-1.16/setup.py 2017-01-12 22:23:48.000000000 +0100 @@ -68,6 +68,7 @@ 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpatch-1.14/tests.py new/jsonpatch-1.16/tests.py --- old/jsonpatch-1.14/tests.py 2016-05-31 18:46:45.000000000 +0200 +++ new/jsonpatch-1.16/tests.py 2017-06-15 17:34:43.000000000 +0200 @@ -13,6 +13,34 @@ class ApplyPatchTestCase(unittest.TestCase): + def test_js_file(self): + with open('./tests.js', 'r') as f: + tests = json.load(f) + for test in tests: + try: + if 'expected' not in test: + continue + result = jsonpatch.apply_patch(test['doc'], test['patch']) + self.assertEqual(result, test['expected']) + except Exception: + if test.get('error'): + continue + else: + raise + + def test_success_if_replaced_dict(self): + src = [{'a': 1}, {'b': 2}] + dst = [{'a': 1, 'b': 2}] + patch = jsonpatch.make_patch(src, dst) + self.assertEqual(patch.apply(src), dst) + + def test_success_if_raise_no_error(self): + src = [{}] + dst = [{'key': ''}] + patch = jsonpatch.make_patch(src, dst) + patch.apply(src) + self.assertTrue(True) + def test_apply_patch_from_string(self): obj = {'foo': 'bar'} patch = '[{"op": "add", "path": "/baz", "value": "qux"}]' @@ -239,7 +267,6 @@ self.assertEqual(json.dumps(patch_obj), patch.to_string()) - class MakePatchTestCase(unittest.TestCase): def test_apply_patch_to_copy(self): @@ -308,6 +335,50 @@ res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst) + def test_escape(self): + src = {"x/y": 1} + dst = {"x/y": 2} + patch = jsonpatch.make_patch(src, dst) + self.assertEqual([{"path": "/x~1y", "value": 2, "op": "replace"}], patch.patch) + res = patch.apply(src) + self.assertEqual(res, dst) + + def test_root_list(self): + """ Test making and applying a patch of the root is a list """ + src = [{'foo': 'bar', 'boo': 'qux'}] + dst = [{'baz': 'qux', 'foo': 'boo'}] + patch = jsonpatch.make_patch(src, dst) + res = patch.apply(src) + self.assertEqual(res, dst) + + def test_make_patch_unicode(self): + """ Test if unicode keys and values are handled correctly """ + src = {} + dst = {'\xee': '\xee'} + patch = jsonpatch.make_patch(src, dst) + res = patch.apply(src) + self.assertEqual(res, dst) + + def test_issue40(self): + """ Tests an issue in _split_by_common_seq reported in #40 """ + + src = [8, 7, 2, 1, 0, 9, 4, 3, 5, 6] + dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8] + patch = jsonpatch.make_patch(src, dest) + + def test_json_patch(self): + old = { + 'queue': {'teams_out': [{'id': 3, 'reason': 'If tied'}, {'id': 5, 'reason': 'If tied'}]}, + } + new = { + 'queue': {'teams_out': [{'id': 5, 'reason': 'If lose'}]} + } + patch = jsonpatch.make_patch(old, new) + new_from_patch = jsonpatch.apply_patch(old, patch) + self.assertEqual(new, new_from_patch) + + +class OptimizationTests(unittest.TestCase): def test_use_replace_instead_of_remove_add(self): src = {'foo': [1, 2, 3]} dst = {'foo': [3, 2, 3]} @@ -344,41 +415,42 @@ res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst) - def test_escape(self): - src = {"x/y": 1} - dst = {"x/y": 2} + def test_success_if_replace_inside_dict(self): + src = [{'a': 1, 'foo': {'b': 2, 'd': 5}}] + dst = [{'a': 1, 'foo': {'b': 3, 'd': 6}}] patch = jsonpatch.make_patch(src, dst) - self.assertEqual([{"path": "/x~1y", "value": 2, "op": "replace"}], patch.patch) - res = patch.apply(src) - self.assertEqual(res, dst) + self.assertEqual(patch.apply(src), dst) - def test_root_list(self): - """ Test making and applying a patch of the root is a list """ - src = [{'foo': 'bar', 'boo': 'qux'}] - dst = [{'baz': 'qux', 'foo': 'boo'}] + def test_success_if_replace_single_value(self): + src = [{'a': 1, 'b': 2, 'd': 5}] + dst = [{'a': 1, 'c': 3, 'd': 5}] patch = jsonpatch.make_patch(src, dst) - res = patch.apply(src) - self.assertEqual(res, dst) + self.assertEqual(patch.apply(src), dst) - def test_make_patch_unicode(self): - """ Test if unicode keys and values are handled correctly """ - src = {} - dst = {'\xee': '\xee'} + def test_success_if_replaced_by_object(self): + src = [{'a': 1, 'b': 2, 'd': 5}] + dst = [{'d': 6}] patch = jsonpatch.make_patch(src, dst) - res = patch.apply(src) - self.assertEqual(res, dst) + self.assertEqual(patch.apply(src), dst) - def test_issue40(self): - """ Tests an issue in _split_by_common_seq reported in #40 """ + def test_success_if_correct_patch_appied(self): + src = [{'a': 1}, {'b': 2}] + dst = [{'a': 1, 'b': 2}] + patch = jsonpatch.make_patch(src, dst) + self.assertEqual(patch.apply(src), dst) - src = [8, 7, 2, 1, 0, 9, 4, 3, 5, 6] - dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8] - patch = jsonpatch.make_patch(src, dest) + def test_success_if_correct_expected_patch_appied(self): + src = [{"a": 1, "b": 2}] + dst = [{"b": 2, "c": 2}] + exp = [{'path': '/0', 'value': {'c': 2, 'b': 2}, 'op': 'replace'}] + patch = jsonpatch.make_patch(src, dst) + self.assertEqual(patch.patch, exp) def test_minimal_patch(self): """ Test whether a minimal patch is created, see #36 """ src = [{"foo": 1, "bar": 2}] dst = [{"foo": 2, "bar": 2}] + patch = jsonpatch.make_patch(src, dst) exp = [ @@ -458,6 +530,7 @@ suite.addTest(unittest.makeSuite(MakePatchTestCase)) suite.addTest(unittest.makeSuite(InvalidInputTests)) suite.addTest(unittest.makeSuite(ConflictTests)) + suite.addTest(unittest.makeSuite(OptimizationTests)) return suite
