Hello community,

here is the log from the commit of package python-jmespath for openSUSE:Factory 
checked in at 2015-04-27 13:05:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jmespath (Old)
 and      /work/SRC/openSUSE:Factory/.python-jmespath.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-jmespath"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-jmespath/python-jmespath.changes  
2015-03-27 09:41:48.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-jmespath.new/python-jmespath.changes     
2015-04-27 13:05:29.000000000 +0200
@@ -1,0 +2,14 @@
+Sun Apr 26 16:57:39 UTC 2015 - [email protected]
+
+- update to version 0.7.0:
+  * Add support for JEP-12, raw string literals
+  * Support .whl files
+- additional changes from version 0.6.2:
+  * Implement JEP-10, slice projections
+  * Fix bug with filter projection parsing
+  * Add to_array function
+  * Add merge function
+  * Fix error messages for function argument type errors
+- point source URL to pypi
+
+-------------------------------------------------------------------

Old:
----
  jmespath-0.6.1.tar.gz

New:
----
  jmespath-0.7.0.tar.gz

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

Other differences:
------------------
++++++ python-jmespath.spec ++++++
--- /var/tmp/diff_new_pack.FCyBNX/_old  2015-04-27 13:05:29.000000000 +0200
+++ /var/tmp/diff_new_pack.FCyBNX/_new  2015-04-27 13:05:29.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-jmespath
 #
-# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 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
@@ -19,13 +19,13 @@
 %define baseName jmespath
 
 Name:           python-jmespath
-Version:        0.6.1
+Version:        0.7.0
 Release:        0
 Summary:        Extract elements from JSON document
 License:        MIT
 Group:          Development/Languages/Python
 Url:            https://github.com/boto/jmespath
-Source0:        %{baseName}-%{version}.tar.gz
+Source0:        
https://pypi.python.org/packages/source/j/%{baseName}/%{baseName}-%{version}.tar.gz
 Requires:       python
 Requires:       python-ply >= 3.4
 BuildRequires:  python

++++++ jmespath-0.6.1.tar.gz -> jmespath-0.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/PKG-INFO new/jmespath-0.7.0/PKG-INFO
--- old/jmespath-0.6.1/PKG-INFO 2015-02-03 22:19:50.000000000 +0100
+++ new/jmespath-0.7.0/PKG-INFO 2015-04-21 08:34:36.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: jmespath
-Version: 0.6.1
+Version: 0.7.0
 Summary: JSON Matching Expressions
 Home-page: https://github.com/boto/jmespath
 Author: James Saryerwinnie
@@ -9,11 +9,16 @@
 Description: JMESPath
         ========
         
+        
+        .. image:: https://badges.gitter.im/Join Chat.svg
+           :target: https://gitter.im/jmespath/chat
+        
+        
         .. image:: 
https://secure.travis-ci.org/jmespath/jmespath.py.png?branch=develop
            :target: http://travis-ci.org/jmespath/jmespath.py
         
         
-        JMESPath (pronounced ``\ˈjāmz path\``) allows you to declaratively 
specify how to
+        JMESPath (pronounced "james path") allows you to declaratively specify 
how to
         extract elements from a JSON document.
         
         For example, given this document::
@@ -46,9 +51,41 @@
         The expression: ``foo.*.name`` will return ["one", "two"].
         
         
+        API
+        ===
+        
+        The ``jmespath.py`` library has two functions
+        that operate on python data structures.  You can use ``search``
+        and give it the jmespath expression and the data::
+        
+            >>> import jmespath
+            >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
+            'baz'
+        
+        Similar to the ``re`` module, you can use the ``compile`` function
+        to compile the JMESPath expression and use this parsed expression
+        to perform repeated searches::
+        
+            >>> import jmespath
+            >>> expression = jmespath.compile('foo.bar')
+            >>> expression.search({'foo': {'bar': 'baz'}})
+            'baz'
+            >>> expression.search({'foo': {'bar': 'other'}})
+            'other'
+        
+        This is useful if you're going to use the same jmespath expression to
+        search multiple documents.  This avoids having to reparse the
+        JMESPath expression each time you search a new document.
+        
+        
         Specification
         =============
         
+        If you'd like to learn more about the JMESPath language, you can check 
out
+        the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.  Also 
check
+        out the `JMESPath examples page <http://jmespath.org/examples.html>`__ 
for
+        examples of more complex jmespath queries.
+        
         The grammar is specified using ABNF, as described in
         `RFC4234 <http://www.ietf.org/rfc/rfc4234.txt>`_.
         You can find the most up to date
@@ -57,9 +94,6 @@
         You can read the full
         `JMESPath specification here 
<http://jmespath.org/specification.html>`__.
         
-        If you'd like to learn more about the JMESPath language, you can check 
out
-        the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.
-        
         
         Testing
         =======
@@ -70,29 +104,12 @@
         to verify they are producing the correct output.  Each json
         file is grouped by feature.
         
-        Python Library
-        ==============
         
-        The included python implementation has two convenience functions
-        that operate on python data structures.  You can use ``search``
-        and give it the jmespath expression and the data::
-        
-            >>> import jmespath
-            >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
-            'baz'
-        
-        Similar to the ``re`` module, you can store the compiled expressions
-        and reuse them to perform repeated searches::
-        
-            >>> import jmespath
-            >>> path = jmespath.compile('foo.bar')
-            >>> path.search({'foo': {'bar': 'baz'}})
-            'baz'
-            >>> path.search({'foo': {'bar': 'other'}})
-            'other'
+        Discuss
+        =======
         
-        You can also use the ``jmespath.parser.Parser`` class directly
-        if you want more control.
+        Join us on our `Gitter channel <https://gitter.im/jmespath/chat>`__
+        if you want to chat or if you have any questions.
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/README.rst 
new/jmespath-0.7.0/README.rst
--- old/jmespath-0.6.1/README.rst       2015-02-03 22:19:02.000000000 +0100
+++ new/jmespath-0.7.0/README.rst       2015-03-20 03:58:23.000000000 +0100
@@ -1,11 +1,16 @@
 JMESPath
 ========
 
+
+.. image:: https://badges.gitter.im/Join Chat.svg
+   :target: https://gitter.im/jmespath/chat
+
+
 .. image:: https://secure.travis-ci.org/jmespath/jmespath.py.png?branch=develop
    :target: http://travis-ci.org/jmespath/jmespath.py
 
 
-JMESPath (pronounced ``\ˈjāmz path\``) allows you to declaratively specify how 
to
+JMESPath (pronounced "james path") allows you to declaratively specify how to
 extract elements from a JSON document.
 
 For example, given this document::
@@ -38,9 +43,41 @@
 The expression: ``foo.*.name`` will return ["one", "two"].
 
 
+API
+===
+
+The ``jmespath.py`` library has two functions
+that operate on python data structures.  You can use ``search``
+and give it the jmespath expression and the data::
+
+    >>> import jmespath
+    >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
+    'baz'
+
+Similar to the ``re`` module, you can use the ``compile`` function
+to compile the JMESPath expression and use this parsed expression
+to perform repeated searches::
+
+    >>> import jmespath
+    >>> expression = jmespath.compile('foo.bar')
+    >>> expression.search({'foo': {'bar': 'baz'}})
+    'baz'
+    >>> expression.search({'foo': {'bar': 'other'}})
+    'other'
+
+This is useful if you're going to use the same jmespath expression to
+search multiple documents.  This avoids having to reparse the
+JMESPath expression each time you search a new document.
+
+
 Specification
 =============
 
+If you'd like to learn more about the JMESPath language, you can check out
+the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.  Also check
+out the `JMESPath examples page <http://jmespath.org/examples.html>`__ for
+examples of more complex jmespath queries.
+
 The grammar is specified using ABNF, as described in
 `RFC4234 <http://www.ietf.org/rfc/rfc4234.txt>`_.
 You can find the most up to date
@@ -49,9 +86,6 @@
 You can read the full
 `JMESPath specification here <http://jmespath.org/specification.html>`__.
 
-If you'd like to learn more about the JMESPath language, you can check out
-the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.
-
 
 Testing
 =======
@@ -62,26 +96,9 @@
 to verify they are producing the correct output.  Each json
 file is grouped by feature.
 
-Python Library
-==============
 
-The included python implementation has two convenience functions
-that operate on python data structures.  You can use ``search``
-and give it the jmespath expression and the data::
-
-    >>> import jmespath
-    >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
-    'baz'
-
-Similar to the ``re`` module, you can store the compiled expressions
-and reuse them to perform repeated searches::
-
-    >>> import jmespath
-    >>> path = jmespath.compile('foo.bar')
-    >>> path.search({'foo': {'bar': 'baz'}})
-    'baz'
-    >>> path.search({'foo': {'bar': 'other'}})
-    'other'
+Discuss
+=======
 
-You can also use the ``jmespath.parser.Parser`` class directly
-if you want more control.
+Join us on our `Gitter channel <https://gitter.im/jmespath/chat>`__
+if you want to chat or if you have any questions.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/bin/jp new/jmespath-0.7.0/bin/jp
--- old/jmespath-0.6.1/bin/jp   2014-04-23 21:00:09.000000000 +0200
+++ new/jmespath-0.7.0/bin/jp   2015-04-18 20:54:14.000000000 +0200
@@ -51,9 +51,6 @@
     except exceptions.UnknownFunctionError as e:
         sys.stderr.write("unknown-function: %s\n" % e)
         return 1
-    except exceptions.LexerError as e:
-        sys.stderr.write("syntax-error: %s\n" % e)
-        return 1
     except exceptions.ParseError as e:
         sys.stderr.write("syntax-error: %s\n" % e)
         return 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath/__init__.py 
new/jmespath-0.7.0/jmespath/__init__.py
--- old/jmespath-0.6.1/jmespath/__init__.py     2015-02-03 22:19:10.000000000 
+0100
+++ new/jmespath-0.7.0/jmespath/__init__.py     2015-04-21 08:29:17.000000000 
+0200
@@ -1,6 +1,6 @@
 from jmespath import parser
 
-__version__ = '0.6.1'
+__version__ = '0.7.0'
 
 
 def compile(expression):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath/exceptions.py 
new/jmespath-0.7.0/jmespath/exceptions.py
--- old/jmespath-0.6.1/jmespath/exceptions.py   2015-01-29 20:42:34.000000000 
+0100
+++ new/jmespath-0.7.0/jmespath/exceptions.py   2015-04-18 20:54:14.000000000 
+0200
@@ -22,8 +22,8 @@
         # self.lex_position +1 to account for the starting double quote char.
         underline = ' ' * (self.lex_position + 1) + '^'
         return (
-            '%s: Parse error at column %s near '
-            'token "%s" (%s) for expression:\n"%s"\n%s' % (
+            '%s: Parse error at column %s, '
+            'token "%s" (%s), for expression:\n"%s"\n%s' % (
                 self.msg, self.lex_position, self.token_value, self.token_type,
                 self.expression, underline))
 
@@ -71,19 +71,29 @@
         self.expression = None
 
     def __str__(self):
-        return ("Expected %s arguments for function %s(), "
-                "received %s" % (self.expected_arity,
-                                 self.function_name,
-                                 self.actual_arity))
+        return ("Expected %s %s for function %s(), "
+                "received %s" % (
+                    self.expected_arity,
+                    self._pluralize('argument', self.expected_arity),
+                    self.function_name,
+                    self.actual_arity))
+
+    def _pluralize(self, word, count):
+        if count == 1:
+            return word
+        else:
+            return word + 's'
 
 
 @with_str_method
 class VariadictArityError(ArityError):
     def __str__(self):
-        return ("Expected at least %s arguments for function %s, "
-                "received %s" % (self.expected_arity,
-                                 self.function_name,
-                                 self.actual_arity))
+        return ("Expected at least %s %s for function %s(), "
+                "received %s" % (
+                    self.expected_arity,
+                    self._pluralize('argument', self.expected_arity),
+                    self.function_name,
+                    self.actual_arity))
 
 
 @with_str_method
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath/functions.py 
new/jmespath-0.7.0/jmespath/functions.py
--- old/jmespath-0.6.1/jmespath/functions.py    2015-01-31 22:18:30.000000000 
+0100
+++ new/jmespath-0.7.0/jmespath/functions.py    2015-04-18 20:54:14.000000000 
+0200
@@ -186,6 +186,13 @@
                 return argument
 
     @builtin_function({'types': []})
+    def _func_to_array(self, arg):
+        if isinstance(arg, list):
+            return arg
+        else:
+            return [arg]
+
+    @builtin_function({'types': []})
     def _func_to_string(self, arg):
         if isinstance(arg, STRING_TYPE):
             return arg
@@ -252,6 +259,13 @@
         else:
             return None
 
+    @builtin_function({"types": ["object"], "variadic": True})
+    def _func_merge(self, *arguments):
+        merged = {}
+        for arg in arguments:
+            merged.update(arg)
+        return merged
+
     @builtin_function({"types": ['array-number', 'array-string']})
     def _func_min(self, arg):
         if arg:
@@ -303,7 +317,7 @@
         # that validates that type, which requires that remaining array
         # elements resolve to the same type as the first element.
         required_type = self._convert_to_jmespath_type(
-            self.interpreter.visit(expref.expression, array[0]))
+            type(self.interpreter.visit(expref.expression, array[0])).__name__)
         if required_type not in ['number', 'string']:
             raise exceptions.JMESPathTypeError(
                 'sort_by', array[0], required_type, ['string', 'number'])
@@ -331,7 +345,9 @@
 
         def keyfunc(x):
             result = interpreter.visit(expr_node, x)
-            jmespath_type = self._convert_to_jmespath_type(result)
+            actual_typename = type(result).__name__
+            jmespath_type = self._convert_to_jmespath_type(actual_typename)
+            # allowed_types is in term of jmespath types, not python types.
             if jmespath_type not in allowed_types:
                 raise exceptions.JMESPathTypeError(
                     function_name, result, jmespath_type, allowed_types)
@@ -339,4 +355,4 @@
         return keyfunc
 
     def _convert_to_jmespath_type(self, pyobject):
-        return TYPES_MAP.get(type(pyobject).__name__, 'unknown')
+        return TYPES_MAP.get(pyobject, 'unknown')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath/lexer.py 
new/jmespath-0.7.0/jmespath/lexer.py
--- old/jmespath-0.6.1/jmespath/lexer.py        2015-01-29 20:42:34.000000000 
+0100
+++ new/jmespath-0.7.0/jmespath/lexer.py        2015-04-21 08:28:55.000000000 
+0200
@@ -1,4 +1,5 @@
 import re
+import warnings
 from json import loads
 
 from jmespath.exceptions import LexerError, EmptyExpressionError
@@ -9,6 +10,7 @@
         r'(?P<number>-?\d+)|'
         r'(?P<unquoted_identifier>([a-zA-Z_][a-zA-Z_0-9]*))|'
         r'(?P<quoted_identifier>("(?:\\\\|\\"|[^"])*"))|'
+        r'(?P<string_literal>(\'(?:\\\\|\\\'|[^\'])*\'))|'
         r'(?P<literal>(`(?:\\\\|\\`|[^`])*`))|'
         r'(?P<filter>\[\?)|'
         r'(?P<or>\|\|)|'
@@ -93,6 +95,9 @@
                              lexer_value=value,
                              message=error_message)
 
+    def _token_string_literal(self, value, start, end):
+        return value[1:-1]
+
     def _token_literal(self, value, start, end):
         actual_value = value[1:-1]
         actual_value = actual_value.replace('\\`', '`').lstrip()
@@ -113,7 +118,10 @@
                 # don't have to be quoted.  This is only true if the
                 # string doesn't start with chars that could start a valid
                 # JSON value.
-                return loads(potential_value)
+                value = loads(potential_value)
+                warnings.warn("deprecated string literal syntax",
+                              PendingDeprecationWarning)
+                return value
             except ValueError:
                 raise LexerError(lexer_position=start,
                                  lexer_value=value,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath/parser.py 
new/jmespath-0.7.0/jmespath/parser.py
--- old/jmespath-0.6.1/jmespath/parser.py       2015-02-03 22:19:02.000000000 
+0100
+++ new/jmespath-0.7.0/jmespath/parser.py       2015-04-21 08:28:55.000000000 
+0200
@@ -46,6 +46,7 @@
         'number': 0,
         'current': 0,
         'expref': 0,
+        'colon': 0,
         'pipe': 1,
         'eq': 2,
         'gt': 2,
@@ -56,9 +57,9 @@
         'or': 5,
         'flatten': 6,
         'star': 20,
+        'filter': 20,
         'dot': 40,
         'lbrace': 50,
-        'filter': 50,
         'lbracket': 55,
         'lparen': 60,
     }
@@ -126,6 +127,9 @@
                 current_token = self._current_token()
         return left
 
+    def _token_nud_string_literal(self, token):
+        return ast.literal(token['value'])
+
     def _token_nud_literal(self, token):
         return ast.literal(token['value'])
 
@@ -165,7 +169,12 @@
 
     def _token_nud_lbracket(self, token):
         if self._current_token() in ['number', 'colon']:
-            return self._parse_index_expression()
+            right = self._parse_index_expression()
+            # We could optimize this and remove the identity() node.
+            # We don't really need an index_expression node, we can
+            # just use emit an index node here if we're not dealing
+            # with a slice.
+            return self._project_if_slice(ast.identity(), right)
         elif self._current_token() == 'star' and \
                 self._lookahead(1) == 'rbracket':
             self._advance()
@@ -300,10 +309,13 @@
         if token['type'] in ['number', 'colon']:
             right = self._parse_index_expression()
             if left['type'] == 'index_expression':
+                # Optimization: if the left node is an index expr,
+                # we can avoid creating another node and instead just add
+                # the right node as a child of the left.
                 left['children'].append(right)
                 return left
             else:
-                return ast.index_expression([left, right])
+                return self._project_if_slice(left, right)
         else:
             # We have a projection
             self._match('star')
@@ -311,6 +323,15 @@
             right = self._parse_projection_rhs(self.BINDING_POWER['star'])
             return ast.projection(left, right)
 
+    def _project_if_slice(self, left, right):
+        index_expr = ast.index_expression([left, right])
+        if right['type'] == 'slice':
+            return ast.projection(
+                index_expr,
+                self._parse_projection_rhs(self.BINDING_POWER['star']))
+        else:
+            return index_expr
+
     def _parse_comparator(self, left, comparator):
         right = self._expression(self.BINDING_POWER[comparator])
         return ast.comparator(comparator, left, right)
@@ -409,6 +430,9 @@
                 "Token %s not allowed to be: %s" % (actual_type, token_types))
 
     def _error_nud_token(self, token):
+        if token['type'] == 'eof':
+            raise exceptions.IncompleteExpressionError(
+                token['start'], token['value'], token['type'])
         raise exceptions.ParseError(token['start'], token['value'],
                                     token['type'], 'Invalid token.')
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath.egg-info/PKG-INFO 
new/jmespath-0.7.0/jmespath.egg-info/PKG-INFO
--- old/jmespath-0.6.1/jmespath.egg-info/PKG-INFO       2015-02-03 
22:19:49.000000000 +0100
+++ new/jmespath-0.7.0/jmespath.egg-info/PKG-INFO       2015-04-21 
08:34:35.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: jmespath
-Version: 0.6.1
+Version: 0.7.0
 Summary: JSON Matching Expressions
 Home-page: https://github.com/boto/jmespath
 Author: James Saryerwinnie
@@ -9,11 +9,16 @@
 Description: JMESPath
         ========
         
+        
+        .. image:: https://badges.gitter.im/Join Chat.svg
+           :target: https://gitter.im/jmespath/chat
+        
+        
         .. image:: 
https://secure.travis-ci.org/jmespath/jmespath.py.png?branch=develop
            :target: http://travis-ci.org/jmespath/jmespath.py
         
         
-        JMESPath (pronounced ``\ˈjāmz path\``) allows you to declaratively 
specify how to
+        JMESPath (pronounced "james path") allows you to declaratively specify 
how to
         extract elements from a JSON document.
         
         For example, given this document::
@@ -46,9 +51,41 @@
         The expression: ``foo.*.name`` will return ["one", "two"].
         
         
+        API
+        ===
+        
+        The ``jmespath.py`` library has two functions
+        that operate on python data structures.  You can use ``search``
+        and give it the jmespath expression and the data::
+        
+            >>> import jmespath
+            >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
+            'baz'
+        
+        Similar to the ``re`` module, you can use the ``compile`` function
+        to compile the JMESPath expression and use this parsed expression
+        to perform repeated searches::
+        
+            >>> import jmespath
+            >>> expression = jmespath.compile('foo.bar')
+            >>> expression.search({'foo': {'bar': 'baz'}})
+            'baz'
+            >>> expression.search({'foo': {'bar': 'other'}})
+            'other'
+        
+        This is useful if you're going to use the same jmespath expression to
+        search multiple documents.  This avoids having to reparse the
+        JMESPath expression each time you search a new document.
+        
+        
         Specification
         =============
         
+        If you'd like to learn more about the JMESPath language, you can check 
out
+        the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.  Also 
check
+        out the `JMESPath examples page <http://jmespath.org/examples.html>`__ 
for
+        examples of more complex jmespath queries.
+        
         The grammar is specified using ABNF, as described in
         `RFC4234 <http://www.ietf.org/rfc/rfc4234.txt>`_.
         You can find the most up to date
@@ -57,9 +94,6 @@
         You can read the full
         `JMESPath specification here 
<http://jmespath.org/specification.html>`__.
         
-        If you'd like to learn more about the JMESPath language, you can check 
out
-        the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.
-        
         
         Testing
         =======
@@ -70,29 +104,12 @@
         to verify they are producing the correct output.  Each json
         file is grouped by feature.
         
-        Python Library
-        ==============
         
-        The included python implementation has two convenience functions
-        that operate on python data structures.  You can use ``search``
-        and give it the jmespath expression and the data::
-        
-            >>> import jmespath
-            >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
-            'baz'
-        
-        Similar to the ``re`` module, you can store the compiled expressions
-        and reuse them to perform repeated searches::
-        
-            >>> import jmespath
-            >>> path = jmespath.compile('foo.bar')
-            >>> path.search({'foo': {'bar': 'baz'}})
-            'baz'
-            >>> path.search({'foo': {'bar': 'other'}})
-            'other'
+        Discuss
+        =======
         
-        You can also use the ``jmespath.parser.Parser`` class directly
-        if you want more control.
+        Join us on our `Gitter channel <https://gitter.im/jmespath/chat>`__
+        if you want to chat or if you have any questions.
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/jmespath.egg-info/SOURCES.txt 
new/jmespath-0.7.0/jmespath.egg-info/SOURCES.txt
--- old/jmespath-0.6.1/jmespath.egg-info/SOURCES.txt    2015-02-03 
22:19:50.000000000 +0100
+++ new/jmespath-0.7.0/jmespath.egg-info/SOURCES.txt    2015-04-21 
08:34:36.000000000 +0200
@@ -1,6 +1,7 @@
 LICENSE.txt
 MANIFEST.in
 README.rst
+setup.cfg
 setup.py
 bin/jp
 jmespath/__init__.py
@@ -14,7 +15,5 @@
 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/pbr.json
+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.6.1/jmespath.egg-info/pbr.json 
new/jmespath-0.7.0/jmespath.egg-info/pbr.json
--- old/jmespath-0.6.1/jmespath.egg-info/pbr.json       1970-01-01 
01:00:00.000000000 +0100
+++ new/jmespath-0.7.0/jmespath.egg-info/pbr.json       2015-04-21 
08:34:36.000000000 +0200
@@ -0,0 +1 @@
+{"is_release": true, "git_version": "0466cc1"}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/setup.cfg new/jmespath-0.7.0/setup.cfg
--- old/jmespath-0.6.1/setup.cfg        2015-02-03 22:19:50.000000000 +0100
+++ new/jmespath-0.7.0/setup.cfg        2015-04-21 08:34:36.000000000 +0200
@@ -1,3 +1,6 @@
+[bdist_wheel]
+universal = 1
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/setup.py new/jmespath-0.7.0/setup.py
--- old/jmespath-0.6.1/setup.py 2015-02-03 22:19:10.000000000 +0100
+++ new/jmespath-0.7.0/setup.py 2015-04-21 08:29:17.000000000 +0200
@@ -25,7 +25,7 @@
 
 setup(
     name='jmespath',
-    version='0.6.1',
+    version='0.7.0',
     description='JSON Matching Expressions',
     long_description=io.open('README.rst', encoding='utf-8').read(),
     author='James Saryerwinnie',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jmespath-0.6.1/tests/__init__.py 
new/jmespath-0.7.0/tests/__init__.py
--- old/jmespath-0.6.1/tests/__init__.py        2014-04-23 21:00:09.000000000 
+0200
+++ new/jmespath-0.7.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.6.1/tests/test_compliance.py 
new/jmespath-0.7.0/tests/test_compliance.py
--- old/jmespath-0.6.1/tests/test_compliance.py 2015-01-31 22:18:30.000000000 
+0100
+++ new/jmespath-0.7.0/tests/test_compliance.py 1970-01-01 01:00:00.000000000 
+0100
@@ -1,93 +0,0 @@
-import os
-from pprint import pformat
-from tests import OrderedDict
-from tests import json
-
-from nose.tools import assert_equal
-
-import jmespath
-from jmespath.visitor import TreeInterpreter
-
-
-TEST_DIR = os.path.join(
-    os.path.dirname(os.path.abspath(__file__)),
-    'compliance')
-NOT_SPECIFIED = object()
-TreeInterpreter.MAP_TYPE = OrderedDict
-
-
-def test_compliance():
-    for full_path in _walk_files():
-        if full_path.endswith('.json'):
-            for given, expression, result, error in _load_cases(full_path):
-                if error is NOT_SPECIFIED and result is not NOT_SPECIFIED:
-                    yield (_test_expression, given, expression,
-                        result, os.path.basename(full_path))
-                elif result is NOT_SPECIFIED and error is not NOT_SPECIFIED:
-                    yield (_test_error_expression, given, expression,
-                           error, os.path.basename(full_path))
-                else:
-                    parts = (given, expression, result, error)
-                    raise RuntimeError("Invalid test description: %s" % parts)
-
-
-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)
-
-
-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']:
-            yield (given, case['expression'],
-                   case.get('result', NOT_SPECIFIED),
-                   case.get('error', NOT_SPECIFIED))
-
-
-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)
-    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, 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 as e:
-        # Test passes, it raised a parse error as expected.
-        pass
-    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, 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.6.1/tests/test_parser.py 
new/jmespath-0.7.0/tests/test_parser.py
--- old/jmespath-0.6.1/tests/test_parser.py     2015-01-31 22:18:30.000000000 
+0100
+++ new/jmespath-0.7.0/tests/test_parser.py     1970-01-01 01:00:00.000000000 
+0100
@@ -1,345 +0,0 @@
-#!/usr/bin/env python
-
-import re
-from tests import unittest
-
-from jmespath import parser
-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"})
-
-
-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 '
-            'near 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_bad_lexer_values(self):
-        error_message = (
-            'Bad jmespath expression: '
-            'Starting quote is missing the ending quote:\n'
-            'foo."bar\n'
-            '    ^')
-        self.assert_error_message('foo."bar', error_message,
-                                  exception=exceptions.LexerError)
-
-    def test_bad_lexer_literal_value_with_json_object(self):
-        error_message = ('Bad jmespath expression: '
-                         'Bad token `{{}`:\n`{{}`\n^')
-        self.assert_error_message('`{{}`', 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 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