Commit 909569c2 authored by nimrod's avatar nimrod
Browse files

Merge branch 'master' into feature/toml

# Conflicts:
#	README.rst
#	setup.py
#	template/filters.py
#	tests.sh
parents 1f42a863 00a42412
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -6,7 +6,10 @@ sudo: false
cache:
  - pip
matrix:
  allow_failure:
  include:
    - python: "3.5"
      env: TOXENV=docs
  allow_failures:
    - python: "3.2"

install:
+6 −6
Original line number Diff line number Diff line
@@ -47,8 +47,11 @@ The following Jinja filters were added:
- :code:`combine`: Combine 2 dictionaries.
- :code:`to_toml`: Convert to toml.
- :code:`from_toml`: Convert from toml.
- :code:`jmespath`: Queries data using the `JMESPath <http://jmespath.org/>`_
  query language.

Example usage can be seen in :code:`tests.sh`.
Example usage can be seen in :code:`tests.sh` and for specific filters in the
docstrings in :code:`template/filters.py`.

Testing
-------
@@ -81,11 +84,8 @@ at: https://www.shore.co.il/git/.
TODO
----

- Add unit tests of filters using doctest.
- Fix combining dictionaries test.
- Fix Travis CI test on Python 3.2 (https://travis-ci.org/adarnimrod/template/jobs/187388235).
- Fix test failure on Python 3.2
  (https://travis-ci.org/adarnimrod/template/jobs/194581463).
- Release on tagged commits to PyPI in Travis CI
  (https://docs.travis-ci.com/user/deployment/pypi/ and
  https://docs.travis-ci.com/user/encryption-keys/).
- Add JMESPath support.
- Add TOML support?
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ setup(
    ],
    keywords='config configuration jinja template environment',
    packages=find_packages(),
    install_requires=['Jinja2', 'PyYAML', 'toml'],
    install_requires=['Jinja2', 'PyYAML', 'jmespath', 'toml'],
    extras_require={
        'dev': ['tox'], },
    entry_points={
+107 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)


def to_yaml(value):
    '''
    Converts given data structure to YAML form.
    Examples:

    >>> to_yaml([1,2,3])
    '[1, 2, 3]\\n'
    >>> to_yaml({'a': 1, 'b': 2})
    '{a: 1, b: 2}\\n'
    >>> to_yaml({1: {'a': [1,2,3]}})
    '1:\\n  a: [1, 2, 3]\\n'
    >>> to_yaml("abc")
    'abc\\n...\\n'
    '''
    from yaml import safe_dump
    return safe_dump(value)


def to_json(value):
    '''
    Converts given data structure to JSON form.
    Examples:

    >>> to_json([1,2,3])
    '[1, 2, 3]'
    >>> to_json({'b':2})
    '{"b": 2}'
    >>> to_json(2)
    '2'
    >>> to_json({1: {'a': [1,2,3]}})
    '{"1": {"a": [1, 2, 3]}}'
    '''
    from json import dumps
    return dumps(value)


def from_json(value):
    '''
    Returns native data structure from the given JSON string.
    Examples:

    >>> import six
    >>> from_json('[1, 2, 3]')
    [1, 2, 3]
    >>> from_json('"a"') == six.text_type('a')
    True
    >>> from_json('{"1": {"a": [1, 2, 3]}}') == {'1': {'a': [1, 2, 3]}}
    True
    '''
    from json import loads
    return loads(value)


def from_yaml(value):
    '''
    Returns native data structure from the given YAML string.
    Examples:

    >>> from_yaml('a')
    'a'
    >>> from_yaml('[1, 2, 3]')
    [1, 2, 3]
    >>> from_yaml('{"1": {"a": [1, 2, 3]}}')
    {'1': {'a': [1, 2, 3]}}
    '''
    from yaml import safe_load
    return safe_load(value)


def pprint(value):
    '''
    Returns a pretty string representation of the data structure given.
    Examples:
    >>> pprint(1)
    '1'
    >>> import six
    >>> output = pprint([{'first_name': 'John', 'last_name': 'Doe'}, {'first_name': 'Jane', 'last_name': 'Doe'}])  # noqa: E501
    >>> if six.PY3:
    ...  output == "[{'first_name': 'John', 'last_name': 'Doe'},\\n {'first_name': 'Jane', 'last_name': 'Doe'}]"
    ... elif six.PY2:
    ...  output == "[{u'first_name': u'John', u'last_name': u'Doe'},\\n {u'first_name': u'Jane', u'last_name': u'Doe'}]"
    ...
    True
    '''
    from pprint import pformat
    return pformat(value)


def combine(default, override):
    '''
    Returns a combined dictionary of the 2 dictionaries given (with the 2nd
    overriding the 1st).
    Examples:
    >>> combine({'a': 1, 'b': 2}, {'b': 3, 'c': 4}) == {'a': 1, 'b': 3, 'c': 4}
    True
    '''
    combined = default.copy()
    combined.update(override)
    return combined


def from_toml(value):
    '''
    Returns a data structure from the TOML string given.
    Examples:
    >>> from_toml('[table]\\nkey = "value"\\n') == {'table': {'key': 'value'}}
    True
    '''
    from toml import loads
    return loads(value)


def to_toml(value):
    '''
    Returns a string of the TOML representation for the data structure given.
    Examples:
    >>> import six
    >>> to_toml({'key': [1, 2]}) == six.text_type("key = [ 1, 2,]\\n")
    True
    '''
    from toml import dumps
    return dumps(value)


def jmespath(value, query):
    '''
    Queries the data using the JMESPath query language.
    Examples:
    >>> import six
    >>> locations = [{'name': 'Seattle', 'state': 'WA'},
    ... {"name": "New York", "state": "NY"},
    ... {"name": "Bellevue", "state": "WA"},
    ... {"name": "Olympia", "state": "WA"}]
    >>> query = "[?state == 'WA'].name | sort(@) | {WashingtonCities: join(', ', @)}"  # noqa: E501
    >>> WACities = jmespath(locations, query)
    >>> if six.PY2:
    ...  WACities == {u'WashingtonCities': u'Bellevue, Olympia, Seattle'}
    ... elif six.PY3:
    ...  WACities == {'WashingtonCities': 'Bellevue, Olympia, Seattle'}
    ...
    True
    '''
    import jmespath
    return jmespath.search(query, value)
+0 −35
Original line number Diff line number Diff line
@@ -14,39 +14,4 @@ export name='John'
template --output "$outfile" "$infile"
test "$(cat $outfile)" = "$name"

echo Testing JSON parsing.
export json='{"a": 1, "b": 2}'
echo '{{ (json|from_json)["a"] }}' > "$infile"
test "$(template $infile)" = "1"

echo Testing JSON output.
echo '{{ [1, 1+2, 3] | to_json }}' > "$infile"
test "$(template $infile)" = '[1, 3, 3]'

echo Testing YAML parsing.
export yaml='a: 1
b: 2'
echo '{{ (yaml|from_yaml)["a"] }}' > "$infile"
test "$(template $infile)" = "1"

echo Testing YAML output.
echo '{{ [1, 1+2, 3] | to_yaml }}' > "$infile"
test "$(template $infile)" = '[1, 3, 3]'

echo Testing pprint.
echo '{{ [1, ] + [2, ] }}' > "$infile"
test "$(template $infile)" = "[1, 2]"

# echo Testing combining dictionaries.
# echo '{{ {"a": 1, "b": 2}|combine({"a": 11, "c": 33}) }}' > "$infile"
# test "$(template $infile)" = "{'a': 11, 'c': 33, 'b': 2}"

echo Testing TOML parsing.
echo '{{ "[table]\n key = value" | from_toml }}' > "$infile"
test "$(template $infile)" = "table = {'key': 'value'}"

echo Testing TOML output.
echo "{{ {'key': [1, 2]} | to_toml }}" > "$infile"
test "$(template $infile)" = "key = [ 1, 2,]"

rm "$infile" "$outfile"
Loading