Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ of your dict keys. To do this you can use either of these options:
... jmespath.Options(dict_cls=collections.OrderedDict))


Options can also be supplied when compiling an expression, so repeated
searches use the same defaults:

.. code:: python

>>> parsed = jmespath.compile('{a: a, b: b}',
... options=jmespath.Options(dict_cls=collections.OrderedDict))
>>> parsed.search(mydata)

Passing ``options`` to ``parsed.search()`` overrides the compiled defaults
for that search only. Other compiled expressions and ``jmespath.search()``
are unaffected.

Custom Functions
~~~~~~~~~~~~~~~~

Expand Down
7 changes: 5 additions & 2 deletions jmespath/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
__version__ = '1.1.0'


def compile(expression):
return parser.Parser().parse(expression)
def compile(expression, options=None):
parsed = parser.Parser().parse(expression)
if options is None:
return parsed
return parser.ParsedResult(parsed.expression, parsed.parsed, options=options)


def search(expression, data, options=None):
Expand Down
5 changes: 4 additions & 1 deletion jmespath/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,14 @@ def purge(cls):

@with_repr_method
class ParsedResult(object):
def __init__(self, expression, parsed):
def __init__(self, expression, parsed, options=None):
self.expression = expression
self.parsed = parsed
self._options = options

def search(self, value, options=None):
if options is None:
options = self._options
interpreter = visitor.TreeInterpreter(options)
result = interpreter.visit(self.parsed, value)
return result
Expand Down
45 changes: 45 additions & 0 deletions tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,51 @@


class TestSearchOptions(unittest.TestCase):
def test_compile_uses_default_options(self):
expression = jmespath.compile(
'{a: a, b: b}',
options=jmespath.Options(dict_cls=OrderedDict))
result = expression.search({'a': 1, 'b': 2})
self.assertIsInstance(result, OrderedDict)
self.assertEqual(list(result.items()), [('a', 1), ('b', 2)])

def test_search_options_override_compiled_defaults(self):
expression = jmespath.compile(
'{a: a}', options=jmespath.Options(dict_cls=OrderedDict))
result = expression.search(
{'a': 1}, options=jmespath.Options(dict_cls=dict))
self.assertIs(type(result), dict)
self.assertIsInstance(expression.search({'a': 2}), OrderedDict)

def test_compiled_defaults_do_not_leak_between_expressions(self):
class OtherDict(dict):
pass

plain = jmespath.compile('{a: a}')
ordered = jmespath.compile(
'{a: a}', options=jmespath.Options(dict_cls=OrderedDict))
other = jmespath.compile(
'{a: a}', options=jmespath.Options(dict_cls=OtherDict))
self.assertIsInstance(ordered.search({'a': 1}), OrderedDict)
self.assertIsInstance(other.search({'a': 1}), OtherDict)
self.assertIs(type(plain.search({'a': 1})), dict)
self.assertIs(type(jmespath.compile('{a: a}').search({'a': 1})), dict)
self.assertIs(type(jmespath.search('{a: a}', {'a': 1})), dict)

def test_compile_with_custom_functions(self):
class CustomFunctions(jmespath.functions.Functions):
@jmespath.functions.signature({'types': ['number']})
def _func_double(self, number):
return number * 2

expression = jmespath.compile(
'double(value)',
options=jmespath.Options(custom_functions=CustomFunctions()))
self.assertEqual(expression.search({'value': 3}), 6)
self.assertEqual(expression.search({'value': 5}), 10)
with self.assertRaises(jmespath.exceptions.UnknownFunctionError):
jmespath.search('double(value)', {'value': 3})

def test_can_provide_dict_cls(self):
result = jmespath.search(
'{a: a, b: b, c: c}.*',
Expand Down