Skip to main content

YAML serializable dictionary with dual item and attribute accessors

Project description

yamlns.namespace

CI Status Coverage Status PyPI PyPI - Downloads PyPI - Python Version

An extended dictionary to conveniently access your structured data with direct mapping from and to YAML and other structured formats. Besides the item like ['field'] access, an attribute like access .field is provided. And it also provides many other goodies:

  • Direct mapping to YAML using dump() and load() methods.
  • Convenient variations from the pure YAML specs on how value types are mapped between YAML and Python:
    • Inner YAML mappings (dicts) are loaded as namespaces as well instead of Python dict.
    • Namespaces preserve the insertion order, as they are based on odict. This way the insertion order and the order in the original loaded file is preserved when stored.
    • YAML floats are loaded as Decimal and Decimal objects are stored as regular YAML floats. This avoids losing precision when succesive load/store cycles are alternated.
    • YAML dates are maped to an extension of datetime.date which provides output formats as attributes which are convenient to call in format templates.
  • Tools to format templates with complex namespace structures.
    • Given the attribute like access, format templates result cleaner with multilevel dicts.
    • Function to extract an empty YAML scheletton given a template with substitutions.
    • Function to fill a format template like file with a YAML file.
    • Command line tool to run those two functions
  • unittest assertions
    • assertNsEqual to compare json like structures among them or with yaml strings and display the difference in a nice line by line diff.
    • assertNsContains to ensure that a json like structure is a superset of the expectation
  • pyunit inegration
    • pytestutils.assert_ns_equal: equivalent to assertNsEqual to be used in pytest
    • pytestutils.assert_ns_contains: equivalent to assertNsContains to be used in pytest
    • pytestutils.yaml_snapshot: fixture to detect changes estructure changes between test executions in yaml format.
    • pytestutils.text_snapshot: fixture to detect changes text changes between test executions.

Example

>>> from yamlns import namespace as ns
>>> n = ns()
>>> n.attribute1 = "value1"
>>> ns['attribute2'] = "value2"
>>> print(n.dump())
attribute1: value1
attribute2: value2

>>> n.attribute2
'value2'
>>> n['attribute1']
'value1'

>>> n.update(ns.loads("""
... attribute3: value3
... attribute4:
...   attribute5: [ 4,3,2,value5 ] 
...   attribute6: 2015-09-23
... attribute7:
... - value7.1
... - value7.2
... """))
>>> n.attribute4.attribute5
[4, 3, 2, 'value5']
>>> n.attribute4.attribute6
datetime.date(2015,9,23)
>>> n.attribute7
['value7.1', 'value7.2']

Templating example:

>>> template = (
...     "{client.name} {client.midname[0]}. {client.surname} buys {item.name} "
...     "by {item.price.amount:0.02f} {item.price.coin}."
... )
...
>>> print(ns.fromTemplate(template).dump())
client:
  name: ''
  midname: ''
  surname: ''
item:
  name: ''
  price:
    amount: ''
    coin: ''

>>> template.format(**ns.loads("""
client:
  name: 'John'
  midname: 'Archivald'
  surname: 'Doe'
item:
  name: 'Apples'
  price:
    amount: 30
    coin: 'dollars'
"""))
John A. Doe buys Apples by 30.00 dollars.

Command line tools usage

nstemplate apply <template> <yamlfile> <output>
nstemplate extract <template> <yamlskeleton>
cat file.json | json2yaml > file.yaml

Testing structure content

class MyTest(unittest.TestCase):

    from yamlns.testutils import assertNsEqual, assertNsContains

    def test(self):
        data = dict(letters = dict(
            (letter, i) for i,letter in enumerate('murcielago'))
        )
        self.assertNsEqual(data, """\
            letters:
                a: 7
                c: 3
                e: 5
                g: 8
                i: 4
                l: 6
                m: 0
                o: 9
                r: 2
                u: 1
        """)

        # Data is a superset of the expectation
        self.assertNsContains(data, """\
            letters:
                a: 7
                e: 5
                i: 4
                o: 9
                u: 1
        """)

Pytest integration

The following helper tools for pytest are provided:

  • pytestutils.assert_ns_equal: equivalent to assertNsEqual to be used in pytest
  • pytestutils.assert_ns_contains: equivalent to assertNsContains to be used in pytest
  • pytestutils.yaml_snapshot: fixture to detect changes estructure changes between test executions in yaml format.
  • pytestutils.text_snapshot: fixture to detect changes text changes between test executions.

assert_ns_equal

A custom assertion that normalizes both sides into namespaces and dumps them as yaml, which is compared side by side.

The normalization takes place, first if the data is a string, it is parsed as yaml. Then the resulting data is converted recursively into namespaces, ordering keys alfabetically. And finally the result is dumped as yaml to be compared line by line.

from yamlns.pytestutils import assert_ns_equal

def test_with_assert_ns_equal():
    data = dict(hello='world')
    assert_ns_equal(data, """\
        hello: world
    """)

assert_ns_contains

A custom assertion similar to assert_ns_equal but ignores any key not pressent in the expectation.

from yamlns.pytestutils import assert_ns_equal

def test_with_assert_ns_equal():
    data = dict(hello='world', ignored=data)
    assert_ns_equal(data, """\
        hello: world
    """)

yaml_snapshot and text_snapshot

yaml_snapshot and text_snapshot are fixtures available whenever you install yamlns. You can use it to make snapshots of data that can be compared to previous executions. Snapshots are stored into testdata/snapshots/ and are given a name that depends on the fully qualified name of the test. The ones with the .expected suffix are accepted snapshots, while the ones ending with .result are generated when the current execution does not match.

If you consider the .result is valid, just rename it as .expected. For convenience, the assert message indicates the commandline to perform the renaming.

text_snapshot just dumps verbatim text while yaml_snapshot compares the normalized dump of the data just like assert_ns_equal does.

def test_with_yaml_snapshot(yaml_snapshot):
    data = dict(hello='world')
    yaml_snapshot(data)

def test_with_text_snapshot(text_snapshot):
    who = 'world'
    text_snapshot('hello {}'.format(who))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yamlns-0.12.1.tar.gz (21.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yamlns-0.12.1-py3-none-any.whl (21.1 kB view details)

Uploaded Python 3

File details

Details for the file yamlns-0.12.1.tar.gz.

File metadata

  • Download URL: yamlns-0.12.1.tar.gz
  • Upload date:
  • Size: 21.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.9.21

File hashes

Hashes for yamlns-0.12.1.tar.gz
Algorithm Hash digest
SHA256 c3f892e6a4219b49580d477955e008e5c73cdcd561f0b110c6def34c39453741
MD5 d33191840e7ef2afe7673582a7461dcc
BLAKE2b-256 599779374c502f5c127884c375fc6ba545c6a9dc5f461b8c9981d27e77567752

See more details on using hashes here.

File details

Details for the file yamlns-0.12.1-py3-none-any.whl.

File metadata

  • Download URL: yamlns-0.12.1-py3-none-any.whl
  • Upload date:
  • Size: 21.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.9.21

File hashes

Hashes for yamlns-0.12.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c91f0eed5f0f4b069364eb2e8d3852009714976b6a78298b5d8bf196f94de813
MD5 1bc28bb25c6728f6d3448274e6a94d5a
BLAKE2b-256 802bd9da96d44e107c027c48ca6e771a8660a10f9f5dbb53635cf360992cc1a8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page