Hello community, here is the log from the commit of package python-jsonpointer for openSUSE:Factory checked in at 2014-09-17 17:25:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jsonpointer (Old) and /work/SRC/openSUSE:Factory/.python-jsonpointer.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jsonpointer" Changes: -------- --- /work/SRC/openSUSE:Factory/python-jsonpointer/python-jsonpointer.changes 2013-05-02 11:41:55.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-jsonpointer.new/python-jsonpointer.changes 2014-09-17 17:25:26.000000000 +0200 @@ -1,0 +2,47 @@ +Mon Sep 15 09:45:48 UTC 2014 - tbecht...@suse.com + +- update to version 1.4: + * bump version to 1.4 + * [Setup] use utf-8 explicitly in setup.py, fixes #8 + * Merge pull request #7 from alexsdutton/patch-1 + * Calculate path properly when self.parts == []. + * Added tests for round-tripping pointers from paths to parts + * JsonPointer.from_parts should handle the empty path + * fix doctest for Python 3 + * bump version to 1.3 + * add JsonPointer.path and JsonPointer.from_parts + * bump version to 1.2 + * add trove classifiers (fixes #6) + * fix string formatting in assert statement + * fix typo in setup.py + * add links to README.md + * add MANIFEST.in + * add comments to commandline doc + * add "jsonpointer" commandline utility + * add missing AUTHORS + * Support for set_pointer and indexing arbitrary objects via __getitem__/__setitem__ + * refactor type check + * add tests for JsonPointer.to_last() + * remove unused param of to_last() + * add test for out-of-bounds error + * add test for JsonPointer.contains(other) + * add test for invalid list index + * add test for pointer string not starting with / + * add test for comparing a pointer to another object + * show pypi information in README + * show coverage status in README + * remove some code from coverage calculation + * move coverage code from tests.py to makefile + * add coveralls support to .travis.yml + * add doctests for pairwise(iter) + * mention supported Python versions in docs + * Drop support for Python 2.5 + * also target Python 3.3 and PyPy + * fix unicode literal quirks in Python 3.2 + * let sphinx extract version, author from source + * README: add link to docs + * add some documentation + * ignore *.swp and files generated during packaging +- Install /usr/bin/jsonpointer with update-alternatives + +------------------------------------------------------------------- Old: ---- jsonpointer-1.0.tar.gz New: ---- jsonpointer-1.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jsonpointer.spec ++++++ --- /var/tmp/diff_new_pack.U3osSa/_old 2014-09-17 17:25:27.000000000 +0200 +++ /var/tmp/diff_new_pack.U3osSa/_new 2014-09-17 17:25:27.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-jsonpointer # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-jsonpointer -Version: 1.0 +Version: 1.4 Release: 0 Summary: Identify specific nodes in a JSON document (according to draft 08) License: BSD-3-Clause @@ -25,6 +25,8 @@ Url: https://github.com/stefankoegl/python-json-pointer Source: http://pypi.python.org/packages/source/j/jsonpointer/jsonpointer-%{version}.tar.gz BuildRequires: python-devel +Requires(post): update-alternatives +Requires(postun): 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()")} @@ -43,9 +45,25 @@ %install python setup.py install --prefix=%{_prefix} --root=%{buildroot} +mv %{buildroot}%{_bindir}/jsonpointer %{buildroot}%{_bindir}/jsonpointer-%{py_ver} +ln -s %{_bindir}/jsonpointer-%{py_ver} %{buildroot}%{_bindir}/jsonpointer + +%pre +[[ ! -L %{_bindir}/jsonpointer ]] && rm -f %{_bindir}/jsonpointer || : + +%post +update-alternatives --install \ + %{_bindir}/jsonpointer jsonpointer %{_bindir}/jsonpointer-%{py_ver} 20 + +%preun +if [ $1 -eq 0 ] ; then + update-alternatives --remove jsonpointer %{_bindir}/jsonpointer-%{py_ver} +fi %files %defattr(-,root,root,-) +%ghost %{_bindir}/jsonpointer +%{_bindir}/jsonpointer-%{py_ver} %{python_sitelib}/* %changelog ++++++ jsonpointer-1.0.tar.gz -> jsonpointer-1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/AUTHORS new/jsonpointer-1.4/AUTHORS --- old/jsonpointer-1.0/AUTHORS 1970-01-01 01:00:00.000000000 +0100 +++ new/jsonpointer-1.4/AUTHORS 2013-11-22 16:20:03.000000000 +0100 @@ -0,0 +1,3 @@ +Stefan Kögl <ste...@skoegl.net> +Alexander Shorin <kxe...@gmail.com> +Christopher J. White <ch...@grierwhite.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/COPYING new/jsonpointer-1.4/COPYING --- old/jsonpointer-1.0/COPYING 1970-01-01 01:00:00.000000000 +0100 +++ new/jsonpointer-1.4/COPYING 2013-11-22 16:20:03.000000000 +0100 @@ -0,0 +1,26 @@ +Copyright (c) 2011 Stefan Kögl <ste...@skoegl.net> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/PKG-INFO new/jsonpointer-1.4/PKG-INFO --- old/jsonpointer-1.0/PKG-INFO 2013-04-03 17:07:28.000000000 +0200 +++ new/jsonpointer-1.4/PKG-INFO 2014-07-03 22:01:21.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: jsonpointer -Version: 1.0 +Version: 1.4 Summary: Identify specific nodes in a JSON document (RFC 6901) Home-page: https://github.com/stefankoegl/python-json-pointer Author: Stefan Kögl @@ -8,3 +8,20 @@ License: Modified BSD License Description: UNKNOWN Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/README.md new/jsonpointer-1.4/README.md --- old/jsonpointer-1.0/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/jsonpointer-1.4/README.md 2013-11-22 16:20:03.000000000 +0100 @@ -0,0 +1,16 @@ +python-json-pointer [![Build Status](https://secure.travis-ci.org/stefankoegl/python-json-pointer.png?branch=master)](https://travis-ci.org/stefankoegl/python-json-pointer) [![Coverage Status](https://coveralls.io/repos/stefankoegl/python-json-pointer/badge.png?branch=master)](https://coveralls.io/r/stefankoegl/python-json-pointer?branch=master) ![Downloads](https://pypip.in/d/jsonpointer/badge.png) ![Version](https://pypip.in/v/jsonpointer/badge.png) +=================== + +Resolve JSON Pointers in Python +------------------------------- + +Library to resolve JSON Pointers according to +[RFC 6901](http://tools.ietf.org/html/rfc6901) + +See Sourcecode for Examples +* Website: https://github.com/stefankoegl/python-json-pointer +* Repository: https://github.com/stefankoegl/python-json-pointer.git +* Documentation: https://python-json-pointer.readthedocs.org/ +* PyPI: https://pypi.python.org/pypi/jsonpointer +* Travis-CI: https://travis-ci.org/stefankoegl/python-json-pointer +* Coveralls: https://coveralls.io/r/stefankoegl/python-json-pointer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/bin/jsonpointer new/jsonpointer-1.4/bin/jsonpointer --- old/jsonpointer-1.0/bin/jsonpointer 1970-01-01 01:00:00.000000000 +0100 +++ new/jsonpointer-1.4/bin/jsonpointer 2013-11-22 16:20:03.000000000 +0100 @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from __future__ import print_function + +import sys +import os.path +import json +import jsonpointer +import argparse + + +parser = argparse.ArgumentParser( + description='Resolve a JSON pointer on JSON files') +parser.add_argument('POINTER', type=argparse.FileType('r'), + help='File containing a JSON pointer expression') +parser.add_argument('FILE', type=argparse.FileType('r'), nargs='+', + help='Files for which the pointer should be resolved') +parser.add_argument('--indent', type=int, default=None, + help='Indent output by n spaces') +parser.add_argument('-v', '--version', action='version', + version='%(prog)s ' + jsonpointer.__version__) + + +def main(): + try: + resolve_files() + except KeyboardInterrupt: + sys.exit(1) + + +def resolve_files(): + """ Resolve a JSON pointer on JSON files """ + args = parser.parse_args() + ptr = json.load(args.POINTER) + for f in args.FILE: + doc = json.load(f) + try: + result = jsonpointer.resolve_pointer(doc, ptr) + print(json.dumps(result, indent=args.indent)) + except jsonpointer.JsonPointerException as e: + print('Could not resolve pointer: %s' % str(e), file=sys.stderr) + + +if __name__ == "__main__": + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/jsonpointer.py new/jsonpointer-1.4/jsonpointer.py --- old/jsonpointer-1.0/jsonpointer.py 2013-04-03 15:41:18.000000000 +0200 +++ new/jsonpointer-1.4/jsonpointer.py 2014-07-03 21:58:11.000000000 +0200 @@ -30,11 +30,13 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +from __future__ import unicode_literals + """ Identify specific nodes in a JSON document (RFC 6901) """ # Will be parsed by setup.py to determine package metadata __author__ = 'Stefan Kögl <ste...@skoegl.net>' -__version__ = '1.0' +__version__ = '1.4' __website__ = 'https://github.com/stefankoegl/python-json-pointer' __license__ = 'Modified BSD License' @@ -48,6 +50,7 @@ from itertools import tee import re +import copy # array indices must not contain leading zeros, signs, spaces, decimals, etc @@ -102,6 +105,28 @@ pointer = JsonPointer(pointer) return pointer.resolve(doc, default) +def set_pointer(doc, pointer, value, inplace=True): + """ + Resolves pointer against doc and sets the value of the target within doc. + + With inplace set to true, doc is modified as long as pointer is not the + root. + + >>> obj = {"foo": {"anArray": [ {"prop": 44}], "another prop": {"baz": "A string" }}} + + >>> set_pointer(obj, '/foo/anArray/0/prop', 55) == \ + {'foo': {'another prop': {'baz': 'A string'}, 'anArray': [{'prop': 55}]}} + True + + >>> set_pointer(obj, '/foo/yet%20another%20prop', 'added prop') == \ + {'foo': {'another prop': {'baz': 'A string'}, 'yet another prop': 'added prop', 'anArray': [{'prop': 55}]}} + True + + """ + + pointer = JsonPointer(pointer) + return pointer.set(doc, value, inplace) + class JsonPointer(object): """ A JSON Pointer that can reference parts of an JSON document """ @@ -117,7 +142,7 @@ self.parts = parts - def to_last(self, doc, default=_nothing): + def to_last(self, doc): """ Resolves ptr until the last step, returns (sub-doc, last-step) """ if not self.parts: @@ -147,6 +172,21 @@ get = resolve + def set(self, doc, value, inplace=True): + """ Resolve the pointer against the doc and replace the target with value. """ + + if len(self.parts) == 0: + if inplace: + raise JsonPointerException('cannot set root in place') + return value + + if not inplace: + doc = copy.deepcopy(doc) + + (parent, part) = self.to_last(doc) + + parent[part] = value + return doc def get_part(self, doc, part): """ Returns the next step in the correct type """ @@ -164,8 +204,13 @@ return int(part) + elif hasattr(doc, '__getitem__'): + # Allow indexing via ducktyping if the target has defined __getitem__ + return part + else: - raise JsonPointerException("Unknown document type '%s'" % (doc.__class__,)) + raise JsonPointerException("Document '%s' does not support indexing, " + "must be dict/list or support __getitem__" % type(doc)) def walk(self, doc, part): @@ -173,6 +218,8 @@ part = self.get_part(doc, part) + assert (type(doc) in (dict, list) or hasattr(doc, '__getitem__')), "invalid document type %s" % (type(doc),) + if isinstance(doc, dict): try: return doc[part] @@ -191,17 +238,24 @@ except IndexError: raise JsonPointerException("index '%s' is out of bounds" % (part, )) - else: - raise JsonPointerException("can not go beyond '%s' (type '%s')" % (part, doc.__class__)) - - + # Object supports __getitem__, assume custom indexing + return doc[part] def contains(self, ptr): - """" Returns True if self contains the given ptr """ + """ Returns True if self contains the given ptr """ return len(self.parts) > len(ptr.parts) and \ self.parts[:len(ptr.parts)] == ptr.parts + @property + def path(self): + """ Returns the string representation of the pointer + + >>> ptr = JsonPointer('/~0/0/~1').path == '/~0/0/~1' + """ + parts = [part.replace('~', '~0') for part in self.parts] + parts = [part.replace('/', '~1') for part in parts] + return ''.join('/' + part for part in parts) def __eq__(self, other): """ compares a pointer to another object @@ -219,9 +273,33 @@ def __hash__(self): return hash(tuple(self.parts)) + @classmethod + def from_parts(cls, parts): + """ Constructs a JsonPointer from a list of (unescaped) paths + + >>> JsonPointer.from_parts(['a', '~', '/', 0]).path == '/a/~0/~1/0' + True + """ + parts = [str(part) for part in parts] + parts = [part.replace('~', '~0') for part in parts] + parts = [part.replace('/', '~1') for part in parts] + ptr = cls(''.join('/' + part for part in parts)) + return ptr + + def pairwise(iterable): - "s -> (s0,s1), (s1,s2), (s2, s3), ..." + """ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/setup.py new/jsonpointer-1.4/setup.py --- old/jsonpointer-1.0/setup.py 2012-12-20 18:54:49.000000000 +0100 +++ new/jsonpointer-1.4/setup.py 2014-06-30 22:35:12.000000000 +0200 @@ -2,11 +2,12 @@ from distutils.core import setup import re +import io import os.path dirname = os.path.dirname(os.path.abspath(__file__)) filename = os.path.join(dirname, 'jsonpointer.py') -src = open(filename).read() +src = io.open(filename, encoding='utf-8').read() metadata = dict(re.findall("__([a-z]+)__ = '([^']+)'", src)) docstrings = re.findall('"""(.*)"""', src) @@ -25,6 +26,26 @@ # Extract name and e-mail ("Firstname Lastname <m...@example.org>") AUTHOR, EMAIL = re.match(r'(.*) <(.*)>', AUTHOR_EMAIL).groups() +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: Implementation :: CPython', + 'Programming Language :: Python :: Implementation :: PyPy', + 'Topic :: Software Development :: Libraries', + 'Topic :: Utilities', +] + setup(name=PACKAGE, version=VERSION, description=DESCRIPTION, @@ -33,4 +54,10 @@ license=LICENSE, url=WEBSITE, py_modules=MODULES, + scripts=['bin/jsonpointer'], + entry_points = { + 'console_scripts': [ + 'jsonpointer = jsonpointer:main', + ]}, + classifiers=CLASSIFIERS, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jsonpointer-1.0/tests.py new/jsonpointer-1.4/tests.py --- old/jsonpointer-1.0/tests.py 1970-01-01 01:00:00.000000000 +0100 +++ new/jsonpointer-1.4/tests.py 2014-03-30 10:45:48.000000000 +0200 @@ -0,0 +1,259 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import doctest +import unittest +import sys +import copy +from jsonpointer import resolve_pointer, EndOfList, JsonPointerException, \ + JsonPointer, set_pointer + +class SpecificationTests(unittest.TestCase): + """ Tests all examples from the JSON Pointer specification """ + + def test_example(self): + doc = { + "foo": ["bar", "baz"], + "": 0, + "a/b": 1, + "c%d": 2, + "e^f": 3, + "g|h": 4, + "i\\j": 5, + "k\"l": 6, + " ": 7, + "m~n": 8 + } + + self.assertEqual(resolve_pointer(doc, ""), doc) + self.assertEqual(resolve_pointer(doc, "/foo"), ["bar", "baz"]) + self.assertEqual(resolve_pointer(doc, "/foo/0"), "bar") + self.assertEqual(resolve_pointer(doc, "/"), 0) + self.assertEqual(resolve_pointer(doc, "/a~1b"), 1) + self.assertEqual(resolve_pointer(doc, "/c%d"), 2) + self.assertEqual(resolve_pointer(doc, "/e^f"), 3) + self.assertEqual(resolve_pointer(doc, "/g|h"), 4) + self.assertEqual(resolve_pointer(doc, "/i\\j"), 5) + self.assertEqual(resolve_pointer(doc, "/k\"l"), 6) + self.assertEqual(resolve_pointer(doc, "/ "), 7) + self.assertEqual(resolve_pointer(doc, "/m~0n"), 8) + + + def test_eol(self): + doc = { + "foo": ["bar", "baz"] + } + + self.assertTrue(isinstance(resolve_pointer(doc, "/foo/-"), EndOfList)) + self.assertRaises(JsonPointerException, resolve_pointer, doc, "/foo/-/1") + + def test_round_trip(self): + paths = [ + "", + "/foo", + "/foo/0", + "/", + "/a~1b", + "/c%d", + "/e^f", + "/g|h", + "/i\\j", + "/k\"l", + "/ ", + "/m~0n", + ] + for path in paths: + ptr = JsonPointer(path) + self.assertEqual(path, ptr.path) + + parts = ptr.parts + new_ptr = JsonPointer.from_parts(parts) + self.assertEqual(ptr, new_ptr) + +class ComparisonTests(unittest.TestCase): + + def test_eq_hash(self): + p1 = JsonPointer("/something/1/b") + p2 = JsonPointer("/something/1/b") + p3 = JsonPointer("/something/1.0/b") + + self.assertEqual(p1, p2) + self.assertNotEqual(p1, p3) + self.assertNotEqual(p2, p3) + + self.assertEqual(hash(p1), hash(p2)) + self.assertNotEqual(hash(p1), hash(p3)) + self.assertNotEqual(hash(p2), hash(p3)) + + # a pointer compares not-equal to objects of other types + self.assertFalse(p1 == "/something/1/b") + + def test_contains(self): + p1 = JsonPointer("/a/b/c") + p2 = JsonPointer("/a/b") + p3 = JsonPointer("/b/c") + + self.assertTrue(p1.contains(p2)) + self.assertFalse(p1.contains(p3)) + + + +class WrongInputTests(unittest.TestCase): + + def test_no_start_slash(self): + # an exception is raised when the pointer string does not start with / + self.assertRaises(JsonPointerException, JsonPointer, 'some/thing') + + def test_invalid_index(self): + # 'a' is not a valid list index + doc = [0, 1, 2] + self.assertRaises(JsonPointerException, resolve_pointer, doc, '/a') + + def test_oob(self): + # this list does not have 10 members + doc = [0, 1, 2] + self.assertRaises(JsonPointerException, resolve_pointer, doc, '/10') + + +class ToLastTests(unittest.TestCase): + + def test_empty_path(self): + doc = {'a': [1, 2, 3]} + ptr = JsonPointer('') + last, nxt = ptr.to_last(doc) + self.assertEqual(doc, last) + self.assertTrue(nxt is None) + + + def test_path(self): + doc = {'a': [{'b': 1, 'c': 2}, 5]} + ptr = JsonPointer('/a/0/b') + last, nxt = ptr.to_last(doc) + self.assertEqual(last, {'b': 1, 'c': 2}) + self.assertEqual(nxt, 'b') + + +class SetTests(unittest.TestCase): + + def test_set(self): + doc = { + "foo": ["bar", "baz"], + "": 0, + "a/b": 1, + "c%d": 2, + "e^f": 3, + "g|h": 4, + "i\\j": 5, + "k\"l": 6, + " ": 7, + "m~n": 8 + } + origdoc = copy.deepcopy(doc) + + # inplace=False + newdoc = set_pointer(doc, "/foo/1", "cod", inplace=False) + self.assertEqual(resolve_pointer(newdoc, "/foo/1"), "cod") + + newdoc = set_pointer(doc, "/", 9, inplace=False) + self.assertEqual(resolve_pointer(newdoc, "/"), 9) + + newdoc = set_pointer(doc, "/fud", {}, inplace=False) + newdoc = set_pointer(newdoc, "/fud/gaw", [1, 2, 3], inplace=False) + self.assertEqual(resolve_pointer(newdoc, "/fud"), {'gaw' : [1, 2, 3]}) + + newdoc = set_pointer(doc, "", 9, inplace=False) + self.assertEqual(newdoc, 9) + + self.assertEqual(doc, origdoc) + + # inplace=True + set_pointer(doc, "/foo/1", "cod") + self.assertEqual(resolve_pointer(doc, "/foo/1"), "cod") + + set_pointer(doc, "/", 9) + self.assertEqual(resolve_pointer(doc, "/"), 9) + + self.assertRaises(JsonPointerException, set_pointer, doc, "/fud/gaw", 9) + + set_pointer(doc, "/fud", {}) + set_pointer(doc, "/fud/gaw", [1, 2, 3] ) + self.assertEqual(resolve_pointer(doc, "/fud"), {'gaw' : [1, 2, 3]}) + + self.assertRaises(JsonPointerException, set_pointer, doc, "", 9) + +class AltTypesTests(unittest.TestCase): + + def test_alttypes(self): + JsonPointer.alttypes = True + + class Node(object): + def __init__(self, name, parent=None): + self.name = name + self.parent = parent + self.left = None + self.right = None + + def set_left(self, node): + node.parent = self + self.left = node + + def set_right(self, node): + node.parent = self + self.right = node + + def __getitem__(self, key): + if key == 'left': + return self.left + if key == 'right': + return self.right + + raise KeyError("Only left and right supported") + + def __setitem__(self, key, val): + if key == 'left': + return self.set_left(val) + if key == 'right': + return self.set_right(val) + + raise KeyError("Only left and right supported: %s" % key) + + + root = Node('root') + root.set_left(Node('a')) + root.left.set_left(Node('aa')) + root.left.set_right(Node('ab')) + root.set_right(Node('b')) + root.right.set_left(Node('ba')) + root.right.set_right(Node('bb')) + + self.assertEqual(resolve_pointer(root, '/left').name, 'a') + self.assertEqual(resolve_pointer(root, '/left/right').name, 'ab') + self.assertEqual(resolve_pointer(root, '/right').name, 'b') + self.assertEqual(resolve_pointer(root, '/right/left').name, 'ba') + + newroot = set_pointer(root, '/left/right', Node('AB'), inplace=False) + self.assertEqual(resolve_pointer(root, '/left/right').name, 'ab') + self.assertEqual(resolve_pointer(newroot, '/left/right').name, 'AB') + + set_pointer(root, '/left/right', Node('AB')) + self.assertEqual(resolve_pointer(root, '/left/right').name, 'AB') + +suite = unittest.TestSuite() +suite.addTest(unittest.makeSuite(SpecificationTests)) +suite.addTest(unittest.makeSuite(ComparisonTests)) +suite.addTest(unittest.makeSuite(WrongInputTests)) +suite.addTest(unittest.makeSuite(ToLastTests)) +suite.addTest(unittest.makeSuite(SetTests)) +suite.addTest(unittest.makeSuite(AltTypesTests)) + +modules = ['jsonpointer'] + +for module in modules: + m = __import__(module, fromlist=[module]) + suite.addTest(doctest.DocTestSuite(m)) + +runner = unittest.TextTestRunner(verbosity=1) +result = runner.run(suite) + +if not result.wasSuccessful(): + sys.exit(1) -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org