Package: yamlns
yamlns.namespaceAn 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.fieldis provided.
And it also provides many other goodies:Direct mapping to YAML usingdump()andload()methods.Convenient variations from the pure YAML specs on how value types are mapped between YAML and Python:Inner YAML mappings (dicts) are loaded asnamespaces as well instead of Pythondict.Namespaces preserve the insertion order, as they are based onodict.
This way the insertion order and the order in the original loaded file is preserved when stored.YAML floats are loaded asDecimalandDecimalobjects are stored as regular YAML floats.
This avoids losing precision when succesive load/store cycles are alternated.YAML dates are maped to an extension ofdatetime.datewhich provides output formats as attributes
which are convenient to call informattemplates.Tools toformattemplates with complex namespace structures.Given the attribute like access,formattemplates result cleaner with multilevel dicts.Function to extract an empty YAML scheletton given a template with substitutions.Function to fill aformattemplate like file with a YAML file.Command line tool to run those two functionsunittestassertionsassertNsEqualto compare json like structures among them or with yaml strings and display the difference in a nice line by line diff.assertNsContainsto ensure that a json like structure is a superset of the expectationpyunitinegrationpytestutils.assert_ns_equal: equivalent toassertNsEqualto be used in pytestpytestutils.assert_ns_contains: equivalent toassertNsContainsto be used in pytestpytestutils.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>>>fromyamlnsimportnamespaceasns>>>n=ns()>>>n.attribute1="value1">>>ns['attribute2']="value2">>>print(n.dump())attribute1:value1attribute2: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.attribute6datetime.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: 30coin: 'dollars'"""))JohnA.DoebuysApplesby30.00dollars.Command line tools usagenstemplateapply<template><yamlfile><output>
nstemplateextract<template><yamlskeleton>
catfile.json|json2yaml>file.yamlTesting structure contentclassMyTest(unittest.TestCase):fromyamlns.testutilsimportassertNsEqual,assertNsContainsdeftest(self):data=dict(letters=dict((letter,i)fori,letterinenumerate('murcielago')))self.assertNsEqual(data,"""\letters:a: 7c: 3e: 5g: 8i: 4l: 6m: 0o: 9r: 2u: 1""")# Data is a superset of the expectationself.assertNsContains(data,"""\letters:a: 7e: 5i: 4o: 9u: 1""")Pytest integrationThe following helper tools for pytest are provided:pytestutils.assert_ns_equal: equivalent toassertNsEqualto be used in pytestpytestutils.assert_ns_contains: equivalent toassertNsContainsto be used in pytestpytestutils.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_equalA 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.fromyamlns.pytestutilsimportassert_ns_equaldeftest_with_assert_ns_equal():data=dict(hello='world')assert_ns_equal(data,"""\hello: world""")assert_ns_containsA custom assertion similar toassert_ns_equalbut ignores any key not pressent in the expectation.fromyamlns.pytestutilsimportassert_ns_equaldeftest_with_assert_ns_equal():data=dict(hello='world',ignored=data)assert_ns_equal(data,"""\hello: world""")yaml_snapshotandtext_snapshotyaml_snapshotandtext_snapshotare 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 intotestdata/snapshots/and are given a name that depends on the fully qualified name of the test.
The ones with the.expectedsuffix are accepted snapshots,
while the ones ending with.resultare generated
when the current execution does not match.If you consider the.resultis valid, just rename it as.expected.
For convenience, the assert message indicates the commandline to perform the renaming.text_snapshotjust dumps verbatim text whileyaml_snapshotcompares the normalized dump of the data
just likeassert_ns_equaldoes.deftest_with_yaml_snapshot(yaml_snapshot):data=dict(hello='world')yaml_snapshot(data)deftest_with_text_snapshot(text_snapshot):who='world'text_snapshot('hello{}'.format(who))