[Python-modules-commits] [python-jmespath] 01/06: Import python-jmespath_0.9.0.orig.tar.gz
Takaki Taniguchi
takaki at moszumanska.debian.org
Tue Nov 24 13:17:46 UTC 2015
This is an automated email from the git hooks/post-receive script.
takaki pushed a commit to branch master
in repository python-jmespath.
commit 475be3837428024b98ceb30539ccc1b9c1b4d173
Author: TANIGUCHI Takaki <takaki at asis.media-as.org>
Date: Tue Nov 24 22:05:33 2015 +0900
Import python-jmespath_0.9.0.orig.tar.gz
---
PKG-INFO | 106 +++++--
README.rst | 101 ++++--
bin/{jp => jp.py} | 15 +-
jmespath.egg-info/PKG-INFO | 106 +++++--
jmespath.egg-info/SOURCES.txt | 7 +-
jmespath.egg-info/pbr.json | 1 +
jmespath/__init__.py | 7 +-
jmespath/ast.py | 713 +++---------------------------------------
jmespath/compat.py | 23 +-
jmespath/exceptions.py | 44 ++-
jmespath/functions.py | 364 +++++++++++++++++++++
jmespath/lexer.py | 279 ++++++++++-------
jmespath/parser.py | 240 +++++++++-----
jmespath/visitor.py | 286 +++++++++++++++++
setup.cfg | 3 +
setup.py | 24 +-
tests/test_ast.py | 407 ------------------------
tests/test_compliance.py | 20 +-
tests/test_parser.py | 138 +++++---
19 files changed, 1409 insertions(+), 1475 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index 7bfe79a..418337f 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,15 +1,24 @@
Metadata-Version: 1.1
Name: jmespath
-Version: 0.4.1
+Version: 0.9.0
Summary: JSON Matching Expressions
-Home-page: https://github.com/boto/jmespath
+Home-page: https://github.com/jmespath/jmespath.py
Author: James Saryerwinnie
Author-email: js at jamesls.com
License: UNKNOWN
Description: JMESPath
========
- JMESPath (pronounced ``\ˈjāmz path\``) allows you to declaratively specify how to
+
+ .. 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 "james path") allows you to declaratively specify how to
extract elements from a JSON document.
For example, given this document::
@@ -41,20 +50,69 @@ Description: JMESPath
The expression: ``foo.*.name`` will return ["one", "two"].
- **NOTE: jmespath is being actively developed. There are a number
- of features it does not currently support that may be added in the
- future.**
+
+ 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.
+
+ Options
+ -------
+
+ You can provide an instance of ``jmespath.Options`` to control how
+ a JMESPath expression is evaluated. The most common scenario for
+ using an ``Options`` instance is if you want to have ordered output
+ of your dict keys. To do this you can use either of these options::
+
+ >>> import jmespath
+ >>> jmespath.search('{a: a, b: b},
+ ... mydata,
+ ... jmespath.Options(dict_cls=collections.OrderedDict))
+
+
+ >>> import jmespath
+ >>> parsed = jmespath.compile('{a: a, b: b}')
+ >>> parsed.search('{a: a, b: b},
+ ... mydata,
+ ... jmespath.Options(dict_cls=collections.OrderedDict))
Specification
=============
- The grammar is specified using ABNF, as described in `RFC4234`_.
- You can find the most up to date grammar for JMESPath
- `here <http://jmespath.readthedocs.org/en/latest/specification.html#grammar>`__.
+ 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
+ `grammar for JMESPath here <http://jmespath.org/specification.html#grammar>`__.
- You can read the full JMESPath specification
- `here http://jmespath.readthedocs.org/en/latest/specification.html`__.
+ You can read the full
+ `JMESPath specification here <http://jmespath.org/specification.html>`__.
Testing
@@ -66,29 +124,12 @@ Description: JMESPath
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
@@ -100,3 +141,4 @@ Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
diff --git a/README.rst b/README.rst
index 144b88e..76844bd 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,16 @@
JMESPath
========
-JMESPath (pronounced ``\ˈjāmz path\``) allows you to declaratively specify how to
+
+.. 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 "james path") allows you to declaratively specify how to
extract elements from a JSON document.
For example, given this document::
@@ -33,20 +42,69 @@ The ``*`` can also be used for hash types::
The expression: ``foo.*.name`` will return ["one", "two"].
-**NOTE: jmespath is being actively developed. There are a number
-of features it does not currently support that may be added in the
-future.**
+
+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.
+
+Options
+-------
+
+You can provide an instance of ``jmespath.Options`` to control how
+a JMESPath expression is evaluated. The most common scenario for
+using an ``Options`` instance is if you want to have ordered output
+of your dict keys. To do this you can use either of these options::
+
+ >>> import jmespath
+ >>> jmespath.search('{a: a, b: b},
+ ... mydata,
+ ... jmespath.Options(dict_cls=collections.OrderedDict))
+
+
+ >>> import jmespath
+ >>> parsed = jmespath.compile('{a: a, b: b}')
+ >>> parsed.search('{a: a, b: b},
+ ... mydata,
+ ... jmespath.Options(dict_cls=collections.OrderedDict))
Specification
=============
-The grammar is specified using ABNF, as described in `RFC4234`_.
-You can find the most up to date grammar for JMESPath
-`here <http://jmespath.readthedocs.org/en/latest/specification.html#grammar>`__.
+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
+`grammar for JMESPath here <http://jmespath.org/specification.html#grammar>`__.
-You can read the full JMESPath specification
-`here http://jmespath.readthedocs.org/en/latest/specification.html`__.
+You can read the full
+`JMESPath specification here <http://jmespath.org/specification.html>`__.
Testing
@@ -58,26 +116,9 @@ there is a ``tests/compliance`` directory that contains
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 --git a/bin/jp b/bin/jp.py
similarity index 75%
rename from bin/jp
rename to bin/jp.py
index ebc8b86..91b5ca9 100755
--- a/bin/jp
+++ b/bin/jp.py
@@ -3,18 +3,15 @@
import sys
import json
import argparse
+from pprint import pformat
import jmespath
from jmespath import exceptions
-from jmespath.compat import OrderedDict
def main():
parser = argparse.ArgumentParser()
parser.add_argument('expression')
- parser.add_argument('-o', '--ordered', action='store_true',
- help='Preserve the order of hash keys, which '
- 'are normally unordered.')
parser.add_argument('-f', '--filename',
help=('The filename containing the input data. '
'If a filename is not given then data is '
@@ -26,7 +23,7 @@ def main():
if args.ast:
# Only print the AST
expression = jmespath.compile(args.expression)
- sys.stdout.write(str(expression))
+ sys.stdout.write(pformat(expression.parsed))
sys.stdout.write('\n')
return 0
if args.filename:
@@ -34,10 +31,7 @@ def main():
data = json.load(f)
else:
data = sys.stdin.read()
- if args.ordered:
- data = json.loads(data, object_pairs_hook=OrderedDict)
- else:
- data = json.loads(data)
+ data = json.loads(data)
try:
sys.stdout.write(json.dumps(
jmespath.search(expression, data), indent=4))
@@ -51,9 +45,6 @@ def main():
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 --git a/jmespath.egg-info/PKG-INFO b/jmespath.egg-info/PKG-INFO
index 7bfe79a..418337f 100644
--- a/jmespath.egg-info/PKG-INFO
+++ b/jmespath.egg-info/PKG-INFO
@@ -1,15 +1,24 @@
Metadata-Version: 1.1
Name: jmespath
-Version: 0.4.1
+Version: 0.9.0
Summary: JSON Matching Expressions
-Home-page: https://github.com/boto/jmespath
+Home-page: https://github.com/jmespath/jmespath.py
Author: James Saryerwinnie
Author-email: js at jamesls.com
License: UNKNOWN
Description: JMESPath
========
- JMESPath (pronounced ``\ˈjāmz path\``) allows you to declaratively specify how to
+
+ .. 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 "james path") allows you to declaratively specify how to
extract elements from a JSON document.
For example, given this document::
@@ -41,20 +50,69 @@ Description: JMESPath
The expression: ``foo.*.name`` will return ["one", "two"].
- **NOTE: jmespath is being actively developed. There are a number
- of features it does not currently support that may be added in the
- future.**
+
+ 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.
+
+ Options
+ -------
+
+ You can provide an instance of ``jmespath.Options`` to control how
+ a JMESPath expression is evaluated. The most common scenario for
+ using an ``Options`` instance is if you want to have ordered output
+ of your dict keys. To do this you can use either of these options::
+
+ >>> import jmespath
+ >>> jmespath.search('{a: a, b: b},
+ ... mydata,
+ ... jmespath.Options(dict_cls=collections.OrderedDict))
+
+
+ >>> import jmespath
+ >>> parsed = jmespath.compile('{a: a, b: b}')
+ >>> parsed.search('{a: a, b: b},
+ ... mydata,
+ ... jmespath.Options(dict_cls=collections.OrderedDict))
Specification
=============
- The grammar is specified using ABNF, as described in `RFC4234`_.
- You can find the most up to date grammar for JMESPath
- `here <http://jmespath.readthedocs.org/en/latest/specification.html#grammar>`__.
+ 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
+ `grammar for JMESPath here <http://jmespath.org/specification.html#grammar>`__.
- You can read the full JMESPath specification
- `here http://jmespath.readthedocs.org/en/latest/specification.html`__.
+ You can read the full
+ `JMESPath specification here <http://jmespath.org/specification.html>`__.
Testing
@@ -66,29 +124,12 @@ Description: JMESPath
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
@@ -100,3 +141,4 @@ Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
diff --git a/jmespath.egg-info/SOURCES.txt b/jmespath.egg-info/SOURCES.txt
index b32cbc1..7e92b55 100644
--- a/jmespath.egg-info/SOURCES.txt
+++ b/jmespath.egg-info/SOURCES.txt
@@ -1,19 +1,22 @@
LICENSE.txt
MANIFEST.in
README.rst
+setup.cfg
setup.py
-bin/jp
+bin/jp.py
jmespath/__init__.py
jmespath/ast.py
jmespath/compat.py
jmespath/exceptions.py
+jmespath/functions.py
jmespath/lexer.py
jmespath/parser.py
+jmespath/visitor.py
jmespath.egg-info/PKG-INFO
jmespath.egg-info/SOURCES.txt
jmespath.egg-info/dependency_links.txt
+jmespath.egg-info/pbr.json
jmespath.egg-info/top_level.txt
tests/__init__.py
-tests/test_ast.py
tests/test_compliance.py
tests/test_parser.py
\ No newline at end of file
diff --git a/jmespath.egg-info/pbr.json b/jmespath.egg-info/pbr.json
new file mode 100644
index 0000000..961baf5
--- /dev/null
+++ b/jmespath.egg-info/pbr.json
@@ -0,0 +1 @@
+{"is_release": true, "git_version": "0466cc1"}
\ No newline at end of file
diff --git a/jmespath/__init__.py b/jmespath/__init__.py
index 9847342..fdd3c79 100644
--- a/jmespath/__init__.py
+++ b/jmespath/__init__.py
@@ -1,11 +1,12 @@
from jmespath import parser
+from jmespath.visitor import Options
-__version__ = '0.4.1'
+__version__ = '0.9.0'
def compile(expression):
return parser.Parser().parse(expression)
-def search(expression, data):
- return parser.Parser().parse(expression).search(data)
+def search(expression, data, options=None):
+ return parser.Parser().parse(expression).search(data, options=options)
diff --git a/jmespath/ast.py b/jmespath/ast.py
index 64d4ed3..dd56c6e 100644
--- a/jmespath/ast.py
+++ b/jmespath/ast.py
@@ -1,711 +1,90 @@
-import operator
-import math
-import json
+# AST nodes have this structure:
+# {"type": <node type>", children: [], "value": ""}
-from jmespath.compat import with_repr_method
-from jmespath.compat import string_type as STRING_TYPE
-from jmespath.compat import zip_longest
-from jmespath.exceptions import JMESPathTypeError, UnknownFunctionError
+def comparator(name, first, second):
+ return {'type': 'comparator', 'children': [first, second], 'value': name}
-NUMBER_TYPE = (float, int)
-_VARIADIC = object()
+def current_node():
+ return {'type': 'current', 'children': []}
-# python types -> jmespath types
-TYPES_MAP = {
- 'bool': 'boolean',
- 'list': 'array',
- 'dict': 'object',
- 'NoneType': 'null',
- 'unicode': 'string',
- 'str': 'string',
- 'float': 'number',
- 'int': 'number',
- 'OrderedDict': 'object',
- '_Projection': 'array',
- '_Expression': 'expref',
-}
+def expref(expression):
+ return {'type': 'expref', 'children': [expression]}
-# jmespath types -> python types
-REVERSE_TYPES_MAP = {
- 'boolean': ('bool',),
- 'array': ('list', '_Projection'),
- 'object': ('dict', 'OrderedDict',),
- 'null': ('None',),
- 'string': ('unicode', 'str'),
- 'number': ('float', 'int'),
- 'expref': ('_Expression',),
-}
+def function_expression(name, args):
+ return {'type': 'function_expression', 'children': args, 'value': name}
-class _Arg(object):
- __slots__ = ('types',)
- def __init__(self, types=None):
- self.types = types
+def field(name):
+ return {"type": "field", "children": [], "value": name}
- at with_repr_method
-class AST(object):
+def filter_projection(left, right, comparator):
+ return {'type': 'filter_projection', 'children': [left, right, comparator]}
- def __init__(self):
- self.children = []
- def search(self, value):
- pass
+def flatten(node):
+ return {'type': 'flatten', 'children': [node]}
- def pretty_print(self, indent=''):
- return super(AST, self).__repr__()
- def __repr__(self):
- return self.pretty_print()
+def identity():
+ return {"type": "identity", 'children': []}
-class Identity(AST):
- def search(self, value):
- return value
+def index(index):
+ return {"type": "index", "value": index, "children": []}
- def pretty_print(self, indent=''):
- return "%sIdentity()" % indent
+def index_expression(children):
+ return {"type": "index_expression", 'children': children}
-class SubExpression(AST):
- """Represents a subexpression match.
- A subexpression match has a parent and a child node. A simple example
- would be something like 'foo.bar' which is represented as::
+def key_val_pair(key_name, node):
+ return {"type": "key_val_pair", 'children': [node], "value": key_name}
- SubExpression(Field(foo), Field(bar))
- """
- def __init__(self, parent, child):
- self.children = [parent, child]
+def literal(literal_value):
+ return {'type': 'literal', 'value': literal_value, 'children': []}
- def search(self, value):
- # To evaluate a subexpression we first evaluate the parent object
- # and then feed the match of the parent node into the child node.
- sub_value = self.children[0].search(value)
- found = self.children[1].search(sub_value)
- return found
- def pretty_print(self, indent=''):
- sub_indent = indent + ' ' * 4
- return "%s%s(\n%s%s,\n%s%s)" % (
- indent, self.__class__.__name__,
- sub_indent, self.children[0].pretty_print(sub_indent),
- sub_indent, self.children[1].pretty_print(sub_indent))
+def multi_select_dict(nodes):
+ return {"type": "multi_select_dict", "children": nodes}
-# This is used just to differentiate between
-# subexpressions and indexexpressions (wildcards can hang
-# off of an indexexpression).
-class IndexExpression(SubExpression):
- pass
+def multi_select_list(nodes):
+ return {"type": "multi_select_list", "children": nodes}
-class Field(AST):
+def or_expression(left, right):
+ return {"type": "or_expression", "children": [left, right]}
- def __init__(self, name):
- self.name = name
- self.children = []
- def pretty_print(self, indent=''):
- return "%sField(%s)" % (indent, self.name)
+def and_expression(left, right):
+ return {"type": "and_expression", "children": [left, right]}
- def search(self, value):
- if value is not None:
- try:
- return value.get(self.name)
- except AttributeError:
- return None
+def not_expression(expr):
+ return {"type": "not_expression", "children": [expr]}
-class BaseMultiField(AST):
- def __init__(self, nodes):
- self.children = list(nodes)
- def search(self, value):
- if value is None:
- return None
- return self._multi_get(value)
+def pipe(left, right):
+ return {'type': 'pipe', 'children': [left, right]}
- def _multi_get(self, value):
- # Subclasses must define this method.
- raise NotImplementedError("_multi_get")
- def pretty_print(self, indent=''):
- return "%s%s(%s)" % (indent, self.__class__.__name__, self.children)
+def projection(left, right):
+ return {'type': 'projection', 'children': [left, right]}
-class MultiFieldDict(BaseMultiField):
+def subexpression(children):
+ return {"type": "subexpression", 'children': children}
- def _multi_get(self, value):
- collected = {}
- for node in self.children:
- collected[node.key_name] = node.search(value)
- return collected
+def slice(start, end, step):
+ return {"type": "slice", "children": [start, end, step]}
-class MultiFieldList(BaseMultiField):
- def _multi_get(self, value):
- collected = []
- for node in self.children:
- collected.append(node.search(value))
- return collected
-
-
-class KeyValPair(AST):
- def __init__(self, key_name, node):
- self.key_name = key_name
- self.children = [node]
-
- def search(self, value):
- return self.children[0].search(value)
-
- def pretty_print(self, indent=''):
- return "%sKeyValPair(key_name=%s, node=%s)" % (
- indent, self.key_name, self.children[0])
-
-
-class Index(AST):
-
- def __init__(self, index):
- super(Index, self).__init__()
- self.index = index
-
- def pretty_print(self, indent=''):
- return "%sIndex(%s)" % (indent, self.index)
-
- def search(self, value):
- # Even though we can index strings, we don't
- # want to support that.
- if not isinstance(value, list):
- return None
- try:
- return value[self.index]
- except IndexError:
- return None
-
-
-class ORExpression(AST):
- def __init__(self, first, remaining):
- self.children = [first, remaining]
-
- def search(self, value):
- matched = self.children[0].search(value)
- if self._is_false(matched):
- matched = self.children[1].search(value)
- return matched
-
- def _is_false(self, value):
- # This looks weird, but we're explicitly using equality checks
- # because the truth/false values are different between
- # python and jmespath.
- return (value == '' or value == [] or value == {} or value is None or
- value == False)
-
- def pretty_print(self, indent=''):
- return "%sORExpression(%s, %s)" % (indent, self.children[0],
- self.children[1])
-
-
-class FilterExpression(AST):
-
- def __init__(self, expression):
- self.children = [expression]
-
- def search(self, value):
- if not isinstance(value, list):
- return None
- result = []
- for element in value:
- if self.children[0].search(element):
- result.append(element)
- return result
-
- def pretty_print(self, indent=''):
- return '%sFilterExpression(%s)' % (indent, self.children[0])
-
-
-class Literal(AST):
-
- def __init__(self, literal_value):
- super(Literal, self).__init__()
- self.literal_value = literal_value
-
- def search(self, value):
- return self.literal_value
-
- def pretty_print(self, indent=''):
- return '%sLiteral(%s)' % (indent, self.literal_value)
-
-
-class Comparator(AST):
- # Subclasses must define the operation function.
- operation = None
-
- def __init__(self, first, second):
- self.children = [first, second]
-
- def search(self, data):
- return self.operation(self.children[0].search(data),
- self.children[1].search(data))
-
- def pretty_print(self, indent=''):
- return '%s%s(%s, %s)' % (indent, self.__class__.__name__,
- self.children[0], self.children[1])
-
-
-class OPEquals(Comparator):
- def _equals(self, first, second):
- if self._is_special_integer_case(first, second):
- return False
- else:
- return first == second
-
- def _is_special_integer_case(self, first, second):
- # We need to special case comparing 0 or 1 to
- # True/False. While normally comparing any
- # integer other than 0/1 to True/False will always
- # return False. However 0/1 have this:
- # >>> 0 == True
- # False
- # >>> 0 == False
- # True
- # >>> 1 == True
- # True
- # >>> 1 == False
- # False
- #
- # Also need to consider that:
- # >>> 0 in [True, False]
- # True
- if first is 0 or first is 1:
- return second is True or second is False
- elif second is 0 or second is 1:
- return first is True or first is False
-
- operation = _equals
-
-
-class OPNotEquals(OPEquals):
- def _not_equals(self, first, second):
- return not super(OPNotEquals, self)._equals(first, second)
-
- operation = _not_equals
-
-
-class OPLessThan(Comparator):
- operation = operator.lt
-
-
-class OPLessThanEquals(Comparator):
- operation = operator.le
-
-
-class OPGreaterThan(Comparator):
- operation = operator.gt
-
-
-class OPGreaterThanEquals(Comparator):
- operation = operator.ge
-
-
-class CurrentNode(AST):
- def search(self, value):
- return value
-
-
-class FunctionExpression(AST):
-
- def __init__(self, name, args):
- self.name = name
- # The .children attribute is to support homogeneous
- # children nodes, but .args is a better name for all the
- # code that uses the children, so we support both.
- self.children = args
- self.args = args
- try:
- self.function = getattr(self, '_func_%s' % name)
- except AttributeError:
- raise UnknownFunctionError("Unknown function: %s" % self.name)
- self.arity = self.function.arity
- self.variadic = self.function.variadic
- self.function = self._resolve_arguments_wrapper(self.function)
-
- def pretty_print(self, indent=''):
- return "%sFunctionExpression(name=%s, args=%s)" % (
- indent, self.name, self.args)
-
- def search(self, value):
- return self.function(value)
-
- def _resolve_arguments_wrapper(self, function):
- def _call_with_resolved_args(value):
- # Before calling the function, we have two things to do:
- # 1. Resolve the arguments (evaluate the arg expressions
- # against the passed in input.
- # 2. Type check the arguments
- resolved_args = []
- for arg_expression, arg_spec in zip_longest(
- self.args, function.argspec,
- fillvalue=function.argspec[-1]):
- # 1. Resolve the arguments.
- current = arg_expression.search(value)
- # 2. Type check (provided we have type information).
- if arg_spec.types is not None:
- _type_check(arg_spec.types, current)
- resolved_args.append(current)
- return function(*resolved_args)
-
- def _get_allowed_pytypes(types):
- allowed_types = []
- allowed_subtypes = []
- for t in types:
- type_ = t.split('-', 1)
- if len(type_) == 2:
- type_, subtype = type_
- allowed_subtypes.append(REVERSE_TYPES_MAP[subtype])
- else:
- type_ = type_[0]
- allowed_types.extend(REVERSE_TYPES_MAP[type_])
- return allowed_types, allowed_subtypes
-
- def _type_check(types, current):
- # Type checking involves checking the top level type,
- # and in the case of arrays, potentially checking the types
... 2639 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-jmespath.git
More information about the Python-modules-commits
mailing list