Hello community,

here is the log from the commit of package python-jmespath for openSUSE:Factory 
checked in at 2020-06-05 19:59:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jmespath (Old)
 and      /work/SRC/openSUSE:Factory/.python-jmespath.new.3606 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-jmespath"

Fri Jun  5 19:59:31 2020 rev:17 rq:810897 version:0.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-jmespath/python-jmespath.changes  
2020-03-27 00:19:50.508091608 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-jmespath.new.3606/python-jmespath.changes    
    2020-06-05 19:59:33.183801467 +0200
@@ -1,0 +2,7 @@
+Tue Jun  2 16:21:51 UTC 2020 - Dirk Mueller <[email protected]>
+
+- update to 0.10.0:
+  * Python 2.6 and 3.3 have reached end-of-life and have been deprecated. 
(issue 175)
+  * Fix race condition when clearing cached parsed expressions. (issue 197)
+
+-------------------------------------------------------------------

Old:
----
  jmespath-0.9.5.tar.gz

New:
----
  jmespath-0.10.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-jmespath.spec ++++++
--- /var/tmp/diff_new_pack.bFaErz/_old  2020-06-05 19:59:33.663803128 +0200
+++ /var/tmp/diff_new_pack.bFaErz/_new  2020-06-05 19:59:33.667803141 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-jmespath
-Version:        0.9.5
+Version:        0.10.0
 Release:        0
 Summary:        Python module for declarative JSON document element extraction
 License:        MIT

++++++ jmespath-0.9.5.tar.gz -> jmespath-0.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/PKG-INFO new/jmespath-0.10.0/PKG-INFO
--- old/jmespath-0.9.5/PKG-INFO 2020-02-24 22:43:16.000000000 +0100
+++ new/jmespath-0.10.0/PKG-INFO        2020-05-13 00:01:49.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
 Name: jmespath
-Version: 0.9.5
+Version: 0.10.0
 Summary: JSON Matching Expressions
 Home-page: https://github.com/jmespath/jmespath.py
 Author: James Saryerwinnie
@@ -55,6 +55,16 @@
         The expression: ``foo.*.name`` will return ["one", "two"].
         
         
+        Installation
+        ============
+        
+        You can install JMESPath from pypi with:
+        
+        .. code:: bash
+        
+            pip install jmespath
+        
+        
         API
         ===
         
@@ -236,3 +246,4 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/README.rst 
new/jmespath-0.10.0/README.rst
--- old/jmespath-0.9.5/README.rst       2019-02-25 00:08:17.000000000 +0100
+++ new/jmespath-0.10.0/README.rst      2020-05-13 00:01:10.000000000 +0200
@@ -47,6 +47,16 @@
 The expression: ``foo.*.name`` will return ["one", "two"].
 
 
+Installation
+============
+
+You can install JMESPath from pypi with:
+
+.. code:: bash
+
+    pip install jmespath
+
+
 API
 ===
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/bin/jp.py 
new/jmespath-0.10.0/bin/jp.py
--- old/jmespath-0.9.5/bin/jp.py        2017-05-13 19:21:34.000000000 +0200
+++ new/jmespath-0.10.0/bin/jp.py       2020-05-13 00:01:10.000000000 +0200
@@ -34,7 +34,7 @@
         data = json.loads(data)
     try:
         sys.stdout.write(json.dumps(
-            jmespath.search(expression, data), indent=4))
+            jmespath.search(expression, data), indent=4, ensure_ascii=False))
         sys.stdout.write('\n')
     except exceptions.ArityError as e:
         sys.stderr.write("invalid-arity: %s\n" % e)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/jmespath/__init__.py 
new/jmespath-0.10.0/jmespath/__init__.py
--- old/jmespath-0.9.5/jmespath/__init__.py     2020-02-24 22:43:09.000000000 
+0100
+++ new/jmespath-0.10.0/jmespath/__init__.py    2020-05-13 00:01:13.000000000 
+0200
@@ -1,7 +1,18 @@
+import warnings
+import sys
 from jmespath import parser
 from jmespath.visitor import Options
 
-__version__ = '0.9.5'
+__version__ = '0.10.0'
+
+
+if sys.version_info[:2] <= (2, 6) or ((3, 0) <= sys.version_info[:2] <= (3, 
3)):
+    python_ver = '.'.join(str(x) for x in sys.version_info[:3])
+
+    warnings.warn(
+        'You are using Python {0}, which will no longer be supported in '
+        'version 0.11.0'.format(python_ver),
+        DeprecationWarning)
 
 
 def compile(expression):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/jmespath/parser.py 
new/jmespath-0.10.0/jmespath/parser.py
--- old/jmespath-0.9.5/jmespath/parser.py       2017-05-14 00:44:33.000000000 
+0200
+++ new/jmespath-0.10.0/jmespath/parser.py      2020-05-13 00:01:10.000000000 
+0200
@@ -490,7 +490,7 @@
 
     def _free_cache_entries(self):
         for key in random.sample(self._CACHE.keys(), int(self._MAX_SIZE / 2)):
-            del self._CACHE[key]
+            self._CACHE.pop(key, None)
 
     @classmethod
     def purge(cls):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/jmespath.egg-info/PKG-INFO 
new/jmespath-0.10.0/jmespath.egg-info/PKG-INFO
--- old/jmespath-0.9.5/jmespath.egg-info/PKG-INFO       2020-02-24 
22:43:16.000000000 +0100
+++ new/jmespath-0.10.0/jmespath.egg-info/PKG-INFO      2020-05-13 
00:01:49.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
 Name: jmespath
-Version: 0.9.5
+Version: 0.10.0
 Summary: JSON Matching Expressions
 Home-page: https://github.com/jmespath/jmespath.py
 Author: James Saryerwinnie
@@ -55,6 +55,16 @@
         The expression: ``foo.*.name`` will return ["one", "two"].
         
         
+        Installation
+        ============
+        
+        You can install JMESPath from pypi with:
+        
+        .. code:: bash
+        
+            pip install jmespath
+        
+        
         API
         ===
         
@@ -236,3 +246,4 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/jmespath.egg-info/SOURCES.txt 
new/jmespath-0.10.0/jmespath.egg-info/SOURCES.txt
--- old/jmespath-0.9.5/jmespath.egg-info/SOURCES.txt    2020-02-24 
22:43:16.000000000 +0100
+++ new/jmespath-0.10.0/jmespath.egg-info/SOURCES.txt   2020-05-13 
00:01:49.000000000 +0200
@@ -15,7 +15,4 @@
 jmespath.egg-info/PKG-INFO
 jmespath.egg-info/SOURCES.txt
 jmespath.egg-info/dependency_links.txt
-jmespath.egg-info/top_level.txt
-tests/__init__.py
-tests/test_compliance.py
-tests/test_parser.py
\ No newline at end of file
+jmespath.egg-info/top_level.txt
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/setup.py new/jmespath-0.10.0/setup.py
--- old/jmespath-0.9.5/setup.py 2020-02-24 22:43:09.000000000 +0100
+++ new/jmespath-0.10.0/setup.py        2020-05-13 00:01:13.000000000 +0200
@@ -1,13 +1,24 @@
 #!/usr/bin/env python
 
 import io
+import sys
+import warnings
 
 from setuptools import setup, find_packages
 
 
+if sys.version_info[:2] <= (2, 6) or ((3, 0) <= sys.version_info[:2] <= (3, 
3)):
+    python_ver = '.'.join(str(x) for x in sys.version_info[:3])
+
+    warnings.warn(
+        'You are using Python {0}, which will no longer be supported in '
+        'version 0.11.0'.format(python_ver),
+        DeprecationWarning)
+
+
 setup(
     name='jmespath',
-    version='0.9.5',
+    version='0.10.0',
     description='JSON Matching Expressions',
     long_description=io.open('README.rst', encoding='utf-8').read(),
     author='James Saryerwinnie',
@@ -16,6 +27,7 @@
     scripts=['bin/jp.py'],
     packages=find_packages(exclude=['tests']),
     license='MIT',
+    python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*',
     classifiers=[
         'Development Status :: 5 - Production/Stable',
         'Intended Audience :: Developers',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/tests/__init__.py 
new/jmespath-0.10.0/tests/__init__.py
--- old/jmespath-0.9.5/tests/__init__.py        2017-03-10 01:45:59.000000000 
+0100
+++ new/jmespath-0.10.0/tests/__init__.py       1970-01-01 01:00:00.000000000 
+0100
@@ -1,40 +0,0 @@
-import sys
-from jmespath import ast
-
-
-# The unittest module got a significant overhaul
-# in 2.7, so if we're in 2.6 we can use the backported
-# version unittest2.
-if sys.version_info[:2] == (2, 6):
-    import unittest2 as unittest
-    import simplejson as json
-    from ordereddict import OrderedDict
-else:
-    import unittest
-    import json
-    from collections import OrderedDict
-
-
-# Helper method used to create an s-expression
-# of the AST to make unit test assertions easier.
-# You get a nice string diff on assert failures.
-def as_s_expression(node):
-    parts = []
-    _as_s_expression(node, parts)
-    return ''.join(parts)
-
-
-def _as_s_expression(node, parts):
-    parts.append("(%s" % (node.__class__.__name__.lower()))
-    if isinstance(node, ast.Field):
-        parts.append(" %s" % node.name)
-    elif isinstance(node, ast.FunctionExpression):
-        parts.append(" %s" % node.name)
-    elif isinstance(node, ast.KeyValPair):
-        parts.append(" %s" % node.key_name)
-    for child in node.children:
-        parts.append(" ")
-        _as_s_expression(child, parts)
-    parts.append(")")
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/tests/test_compliance.py 
new/jmespath-0.10.0/tests/test_compliance.py
--- old/jmespath-0.9.5/tests/test_compliance.py 2017-05-13 19:21:34.000000000 
+0200
+++ new/jmespath-0.10.0/tests/test_compliance.py        1970-01-01 
01:00:00.000000000 +0100
@@ -1,109 +0,0 @@
-import os
-from pprint import pformat
-from tests import OrderedDict
-from tests import json
-
-from nose.tools import assert_equal
-
-from jmespath.visitor import Options
-
-
-TEST_DIR = os.path.dirname(os.path.abspath(__file__))
-COMPLIANCE_DIR = os.path.join(TEST_DIR, 'compliance')
-LEGACY_DIR = os.path.join(TEST_DIR, 'legacy')
-NOT_SPECIFIED = object()
-OPTIONS = Options(dict_cls=OrderedDict)
-
-
-def test_compliance():
-    for full_path in _walk_files():
-        if full_path.endswith('.json'):
-            for given, test_type, test_data in load_cases(full_path):
-                t = test_data
-                # Benchmark tests aren't run as part of the normal
-                # test suite, so we only care about 'result' and
-                # 'error' test_types.
-                if test_type == 'result':
-                    yield (_test_expression, given, t['expression'],
-                           t['result'], os.path.basename(full_path))
-                elif test_type == 'error':
-                    yield (_test_error_expression, given, t['expression'],
-                           t['error'], os.path.basename(full_path))
-
-
-def _walk_files():
-    # Check for a shortcut when running the tests interactively.
-    # If a JMESPATH_TEST is defined, that file is used as the
-    # only test to run.  Useful when doing feature development.
-    single_file = os.environ.get('JMESPATH_TEST')
-    if single_file is not None:
-        yield os.path.abspath(single_file)
-    else:
-        for root, dirnames, filenames in os.walk(TEST_DIR):
-            for filename in filenames:
-                yield os.path.join(root, filename)
-        for root, dirnames, filenames in os.walk(LEGACY_DIR):
-            for filename in filenames:
-                yield os.path.join(root, filename)
-
-
-def load_cases(full_path):
-    all_test_data = json.load(open(full_path), object_pairs_hook=OrderedDict)
-    for test_data in all_test_data:
-        given = test_data['given']
-        for case in test_data['cases']:
-            if 'result' in case:
-                test_type = 'result'
-            elif 'error' in case:
-                test_type = 'error'
-            elif 'bench' in case:
-                test_type = 'bench'
-            else:
-                raise RuntimeError("Unknown test type: %s" % json.dumps(case))
-            yield (given, test_type, case)
-
-
-def _test_expression(given, expression, expected, filename):
-    import jmespath.parser
-    try:
-        parsed = jmespath.compile(expression)
-    except ValueError as e:
-        raise AssertionError(
-            'jmespath expression failed to compile: "%s", error: %s"' %
-            (expression, e))
-    actual = parsed.search(given, options=OPTIONS)
-    expected_repr = json.dumps(expected, indent=4)
-    actual_repr = json.dumps(actual, indent=4)
-    error_msg = ("\n\n  (%s) The expression '%s' was suppose to give:\n%s\n"
-                 "Instead it matched:\n%s\nparsed as:\n%s\ngiven:\n%s" % (
-                     filename, expression, expected_repr,
-                     actual_repr, pformat(parsed.parsed),
-                     json.dumps(given, indent=4)))
-    error_msg = error_msg.replace(r'\n', '\n')
-    assert_equal(actual, expected, error_msg)
-
-
-def _test_error_expression(given, expression, error, filename):
-    import jmespath.parser
-    if error not in ('syntax', 'invalid-type',
-                     'unknown-function', 'invalid-arity', 'invalid-value'):
-        raise RuntimeError("Unknown error type '%s'" % error)
-    try:
-        parsed = jmespath.compile(expression)
-        parsed.search(given)
-    except ValueError:
-        # Test passes, it raised a parse error as expected.
-        pass
-    except Exception as e:
-        # Failure because an unexpected exception was raised.
-        error_msg = ("\n\n  (%s) The expression '%s' was suppose to be a "
-                     "syntax error, but it raised an unexpected error:\n\n%s" 
% (
-                         filename, expression, e))
-        error_msg = error_msg.replace(r'\n', '\n')
-        raise AssertionError(error_msg)
-    else:
-        error_msg = ("\n\n  (%s) The expression '%s' was suppose to be a "
-                     "syntax error, but it successfully parsed as:\n\n%s" % (
-                         filename, expression, pformat(parsed.parsed)))
-        error_msg = error_msg.replace(r'\n', '\n')
-        raise AssertionError(error_msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.9.5/tests/test_parser.py 
new/jmespath-0.10.0/tests/test_parser.py
--- old/jmespath-0.9.5/tests/test_parser.py     2017-05-13 19:21:34.000000000 
+0200
+++ new/jmespath-0.10.0/tests/test_parser.py    1970-01-01 01:00:00.000000000 
+0100
@@ -1,368 +0,0 @@
-#!/usr/bin/env python
-
-import re
-from tests import unittest, OrderedDict
-
-from jmespath import parser
-from jmespath import visitor
-from jmespath import ast
-from jmespath import exceptions
-
-
-class TestParser(unittest.TestCase):
-    def setUp(self):
-        self.parser = parser.Parser()
-
-    def assert_parsed_ast(self, expression, expected_ast):
-        parsed = self.parser.parse(expression)
-        self.assertEqual(parsed.parsed, expected_ast)
-
-    def test_parse_empty_string_raises_exception(self):
-        with self.assertRaises(exceptions.EmptyExpressionError):
-            self.parser.parse('')
-
-    def test_field(self):
-        self.assert_parsed_ast('foo', ast.field('foo'))
-
-    def test_dot_syntax(self):
-        self.assert_parsed_ast('foo.bar',
-                               ast.subexpression([ast.field('foo'),
-                                                  ast.field('bar')]))
-
-    def test_multiple_dots(self):
-        parsed = self.parser.parse('foo.bar.baz')
-        self.assertEqual(
-            parsed.search({'foo': {'bar': {'baz': 'correct'}}}), 'correct')
-
-    def test_index(self):
-        parsed = self.parser.parse('foo[1]')
-        self.assertEqual(
-            parsed.search({'foo': ['zero', 'one', 'two']}),
-            'one')
-
-    def test_quoted_subexpression(self):
-        self.assert_parsed_ast('"foo"."bar"',
-                               ast.subexpression([
-                                   ast.field('foo'),
-                                   ast.field('bar')]))
-
-    def test_wildcard(self):
-        parsed = self.parser.parse('foo[*]')
-        self.assertEqual(
-            parsed.search({'foo': ['zero', 'one', 'two']}),
-            ['zero', 'one', 'two'])
-
-    def test_wildcard_with_children(self):
-        parsed = self.parser.parse('foo[*].bar')
-        self.assertEqual(
-            parsed.search({'foo': [{'bar': 'one'}, {'bar': 'two'}]}),
-            ['one', 'two'])
-
-    def test_or_expression(self):
-        parsed = self.parser.parse('foo || bar')
-        self.assertEqual(parsed.search({'foo': 'foo'}), 'foo')
-        self.assertEqual(parsed.search({'bar': 'bar'}), 'bar')
-        self.assertEqual(parsed.search({'foo': 'foo', 'bar': 'bar'}), 'foo')
-        self.assertEqual(parsed.search({'bad': 'bad'}), None)
-
-    def test_complex_or_expression(self):
-        parsed = self.parser.parse('foo.foo || foo.bar')
-        self.assertEqual(parsed.search({'foo': {'foo': 'foo'}}), 'foo')
-        self.assertEqual(parsed.search({'foo': {'bar': 'bar'}}), 'bar')
-        self.assertEqual(parsed.search({'foo': {'baz': 'baz'}}), None)
-
-    def test_or_repr(self):
-        self.assert_parsed_ast('foo || bar', 
ast.or_expression(ast.field('foo'),
-                                                               
ast.field('bar')))
-
-    def test_unicode_literals_escaped(self):
-        self.assert_parsed_ast(r'`"\u2713"`', ast.literal(u'\u2713'))
-
-    def test_multiselect(self):
-        parsed = self.parser.parse('foo.{bar: bar,baz: baz}')
-        self.assertEqual(
-            parsed.search({'foo': {'bar': 'bar', 'baz': 'baz', 'qux': 'qux'}}),
-            {'bar': 'bar', 'baz': 'baz'})
-
-    def test_multiselect_subexpressions(self):
-        parsed = self.parser.parse('foo.{"bar.baz": bar.baz, qux: qux}')
-        self.assertEqual(
-            parsed.search({'foo': {'bar': {'baz': 'CORRECT'}, 'qux': 'qux'}}),
-            {'bar.baz': 'CORRECT', 'qux': 'qux'})
-
-    def test_multiselect_with_all_quoted_keys(self):
-        parsed = self.parser.parse('foo.{"bar": bar.baz, "qux": qux}')
-        result = parsed.search({'foo': {'bar': {'baz': 'CORRECT'}, 'qux': 
'qux'}})
-        self.assertEqual(result, {"bar": "CORRECT", "qux": "qux"})
-
-    def test_function_call_with_and_statement(self):
-        self.assert_parsed_ast(
-            'f(@ && @)',
-            {'children': [{'children': [{'children': [], 'type': 'current'},
-                                        {'children': [], 'type': 'current'}],
-                           'type': 'and_expression'}],
-             'type': 'function_expression',
-             'value': 'f'})
-
-
-class TestErrorMessages(unittest.TestCase):
-
-    def setUp(self):
-        self.parser = parser.Parser()
-
-    def assert_error_message(self, expression, error_message,
-                             exception=exceptions.ParseError):
-        try:
-            self.parser.parse(expression)
-        except exception as e:
-            self.assertEqual(error_message, str(e))
-            return
-        except Exception as e:
-            self.fail(
-                "Unexpected error raised (%s: %s) for bad expression: %s" %
-                (e.__class__.__name__, e, expression))
-        else:
-            self.fail(
-                "ParseError not raised for bad expression: %s" % expression)
-
-    def test_bad_parse(self):
-        with self.assertRaises(exceptions.ParseError):
-            self.parser.parse('foo]baz')
-
-    def test_bad_parse_error_message(self):
-        error_message = (
-            'Unexpected token: ]: Parse error at column 3, '
-            'token "]" (RBRACKET), for expression:\n'
-            '"foo]baz"\n'
-            '    ^')
-        self.assert_error_message('foo]baz', error_message)
-
-    def test_bad_parse_error_message_with_multiselect(self):
-        error_message = (
-            'Invalid jmespath expression: Incomplete expression:\n'
-            '"foo.{bar: baz,bar: bar"\n'
-            '                       ^')
-        self.assert_error_message('foo.{bar: baz,bar: bar', error_message)
-
-    def test_incomplete_expression_with_missing_paren(self):
-        error_message = (
-            'Invalid jmespath expression: Incomplete expression:\n'
-            '"length(@,"\n'
-            '          ^')
-        self.assert_error_message('length(@,', error_message)
-
-    def test_bad_lexer_values(self):
-        error_message = (
-            'Bad jmespath expression: '
-            'Unclosed " delimiter:\n'
-            'foo."bar\n'
-            '    ^')
-        self.assert_error_message('foo."bar', error_message,
-                                  exception=exceptions.LexerError)
-
-    def test_bad_unicode_string(self):
-        # This error message is straight from the JSON parser
-        # and pypy has a slightly different error message,
-        # so we're not using assert_error_message.
-        error_message = re.compile(
-            r'Bad jmespath expression: '
-            r'Invalid \\uXXXX escape.*\\uAZ12', re.DOTALL)
-        with self.assertRaisesRegexp(exceptions.LexerError, error_message):
-            self.parser.parse(r'"\uAZ12"')
-
-
-class TestParserWildcards(unittest.TestCase):
-    def setUp(self):
-        self.parser = parser.Parser()
-        self.data = {
-            'foo': [
-                {'bar': [{'baz': 'one'}, {'baz': 'two'}]},
-                {'bar': [{'baz': 'three'}, {'baz': 'four'}, {'baz': 'five'}]},
-            ]
-        }
-
-    def test_multiple_index_wildcards(self):
-        parsed = self.parser.parse('foo[*].bar[*].baz')
-        self.assertEqual(parsed.search(self.data),
-                         [['one', 'two'], ['three', 'four', 'five']])
-
-    def test_wildcard_mix_with_indices(self):
-        parsed = self.parser.parse('foo[*].bar[0].baz')
-        self.assertEqual(parsed.search(self.data),
-                         ['one', 'three'])
-
-    def test_wildcard_mix_last(self):
-        parsed = self.parser.parse('foo[0].bar[*].baz')
-        self.assertEqual(parsed.search(self.data),
-                         ['one', 'two'])
-
-    def test_indices_out_of_bounds(self):
-        parsed = self.parser.parse('foo[*].bar[2].baz')
-        self.assertEqual(parsed.search(self.data),
-                         ['five'])
-
-    def test_root_indices(self):
-        parsed = self.parser.parse('[0]')
-        self.assertEqual(parsed.search(['one', 'two']), 'one')
-
-    def test_root_wildcard(self):
-        parsed = self.parser.parse('*.foo')
-        data = {'top1': {'foo': 'bar'}, 'top2': {'foo': 'baz'},
-                'top3': {'notfoo': 'notfoo'}}
-        # Sorted is being used because the order of the keys are not
-        # required to be in any specific order.
-        self.assertEqual(sorted(parsed.search(data)), sorted(['bar', 'baz']))
-        self.assertEqual(sorted(self.parser.parse('*.notfoo').search(data)),
-                         sorted(['notfoo']))
-
-    def test_only_wildcard(self):
-        parsed = self.parser.parse('*')
-        data = {'foo': 'a', 'bar': 'b', 'baz': 'c'}
-        self.assertEqual(sorted(parsed.search(data)), sorted(['a', 'b', 'c']))
-
-    def test_escape_sequences(self):
-        self.assertEqual(self.parser.parse(r'"foo\tbar"').search(
-            {'foo\tbar': 'baz'}), 'baz')
-        self.assertEqual(self.parser.parse(r'"foo\nbar"').search(
-            {'foo\nbar': 'baz'}), 'baz')
-        self.assertEqual(self.parser.parse(r'"foo\bbar"').search(
-            {'foo\bbar': 'baz'}), 'baz')
-        self.assertEqual(self.parser.parse(r'"foo\fbar"').search(
-            {'foo\fbar': 'baz'}), 'baz')
-        self.assertEqual(self.parser.parse(r'"foo\rbar"').search(
-            {'foo\rbar': 'baz'}), 'baz')
-
-    def test_consecutive_escape_sequences(self):
-        parsed = self.parser.parse(r'"foo\\nbar"')
-        self.assertEqual(parsed.search({'foo\\nbar': 'baz'}), 'baz')
-
-        parsed = self.parser.parse(r'"foo\n\t\rbar"')
-        self.assertEqual(parsed.search({'foo\n\t\rbar': 'baz'}), 'baz')
-
-    def test_escape_sequence_at_end_of_string_not_allowed(self):
-        with self.assertRaises(ValueError):
-            self.parser.parse('foobar\\')
-
-    def test_wildcard_with_multiselect(self):
-        parsed = self.parser.parse('foo.*.{a: a, b: b}')
-        data = {
-            'foo': {
-                'one': {
-                    'a': {'c': 'CORRECT', 'd': 'other'},
-                    'b': {'c': 'ALSOCORRECT', 'd': 'other'},
-                },
-                'two': {
-                    'a': {'c': 'CORRECT', 'd': 'other'},
-                    'c': {'c': 'WRONG', 'd': 'other'},
-                },
-            }
-        }
-        match = parsed.search(data)
-        self.assertEqual(len(match), 2)
-        self.assertIn('a', match[0])
-        self.assertIn('b', match[0])
-        self.assertIn('a', match[1])
-        self.assertIn('b', match[1])
-
-
-class TestMergedLists(unittest.TestCase):
-    def setUp(self):
-        self.parser = parser.Parser()
-        self.data = {
-            "foo": [
-                [["one", "two"], ["three", "four"]],
-                [["five", "six"], ["seven", "eight"]],
-                [["nine"], ["ten"]]
-            ]
-        }
-
-    def test_merge_with_indices(self):
-        parsed = self.parser.parse('foo[][0]')
-        match = parsed.search(self.data)
-        self.assertEqual(match, ["one", "three", "five", "seven",
-                                 "nine", "ten"])
-
-    def test_trailing_merged_operator(self):
-        parsed = self.parser.parse('foo[]')
-        match = parsed.search(self.data)
-        self.assertEqual(
-            match,
-            [["one", "two"], ["three", "four"],
-             ["five", "six"], ["seven", "eight"],
-             ["nine"], ["ten"]])
-
-
-class TestParserCaching(unittest.TestCase):
-    def test_compile_lots_of_expressions(self):
-        # We have to be careful here because this is an implementation detail
-        # that should be abstracted from the user, but we need to make sure we
-        # exercise the code and that it doesn't blow up.
-        p = parser.Parser()
-        compiled = []
-        compiled2 = []
-        for i in range(parser.Parser._MAX_SIZE + 1):
-            compiled.append(p.parse('foo%s' % i))
-        # Rerun the test and half of these entries should be from the
-        # cache but they should still be equal to compiled.
-        for i in range(parser.Parser._MAX_SIZE + 1):
-            compiled2.append(p.parse('foo%s' % i))
-        self.assertEqual(len(compiled), len(compiled2))
-        self.assertEqual(
-            [expr.parsed for expr in compiled],
-            [expr.parsed for expr in compiled2])
-
-    def test_cache_purge(self):
-        p = parser.Parser()
-        first = p.parse('foo')
-        cached = p.parse('foo')
-        p.purge()
-        second = p.parse('foo')
-        self.assertEqual(first.parsed,
-                         second.parsed)
-        self.assertEqual(first.parsed,
-                         cached.parsed)
-
-
-class TestParserAddsExpressionAttribute(unittest.TestCase):
-    def test_expression_available_from_parser(self):
-        p = parser.Parser()
-        parsed = p.parse('foo.bar')
-        self.assertEqual(parsed.expression, 'foo.bar')
-
-
-class TestParsedResultAddsOptions(unittest.TestCase):
-    def test_can_have_ordered_dict(self):
-        p = parser.Parser()
-        parsed = p.parse('{a: a, b: b, c: c}')
-        options = visitor.Options(dict_cls=OrderedDict)
-        result = parsed.search(
-            {"c": "c", "b": "b", "a": "a"}, options=options)
-        # The order should be 'a', 'b' because we're using an
-        # OrderedDict
-        self.assertEqual(list(result), ['a', 'b', 'c'])
-
-
-class TestRenderGraphvizFile(unittest.TestCase):
-    def test_dot_file_rendered(self):
-        p = parser.Parser()
-        result = p.parse('foo')
-        dot_contents = result._render_dot_file()
-        self.assertEqual(dot_contents,
-                         'digraph AST {\nfield1 [label="field(foo)"]\n}')
-
-    def test_dot_file_subexpr(self):
-        p = parser.Parser()
-        result = p.parse('foo.bar')
-        dot_contents = result._render_dot_file()
-        self.assertEqual(
-            dot_contents,
-            'digraph AST {\n'
-            'subexpression1 [label="subexpression()"]\n'
-            '  subexpression1 -> field2\n'
-            'field2 [label="field(foo)"]\n'
-            '  subexpression1 -> field3\n'
-            'field3 [label="field(bar)"]\n}')
-
-
-if __name__ == '__main__':
-    unittest.main()


Reply via email to