Yaco

Yaco provides a dict like structure that can be serialized to & from yaml. Yaco objects behave as dictionaries but also allow attribute access (loosely based on this `recipe < http://code.activestate.com/recipes/473786/>`_). Sublevel dictionaries are automatically converted to Yaco objects, allowing sublevel attribute access, for example:

>>> x = Yaco()
>>> x.test = 1
>>> x.sub.test = 2
>>> x.sub.test
2

Note that sub-dictionaries do not need to be initialized. This has as a consequence that requesting uninitialized items automatically return an empty Yaco object (inherited from a dictionary).

Yaco can be found in the Python package index and is also part of the Moa source distribution

Autogenerating keys

An important feature (or annoyance) of Yaco is the auto generation of keys that are not present (yet). For example:

>>> x = Yaco()
>>> x.a.b.c.d = 1
>>> assert(x.a.b.c.d == 1)

works - a, b and c are assumed to be Yaco dictionaries and d is give value 1. This makes populating data structures easy.

It might also generate some confusion when querying for keys in the Yaco structure - if a key does not exists, it automatically comes back as an empy dict or Yaco object (renders as {}). This means that if it is easy to check if a certain ‘branch’ of a Yaco datastructure exists:

>>> x = Yaco()
>>> assert (not x.a.b)

but now the following works as well:

>>> assert(x.has_key('a'))
>>> assert(x.a.has_key('b'))

So, a safe way to test a data structure, without introducing extra branches is:

>>> x = Yaco()
>>> assert(not x.has_key('a'))

Todo: Need to find a more elegant way of testing without introducing data structures

class Yaco.Yaco(data={})

Rather loosely based on http://code.activestate.com/recipes/473786/ (r1)

>>> v= Yaco()
>>> v.a = 1
>>> assert(v.a == 1)
>>> assert(v['a'] == 1)
>>> v= Yaco({'a':1})
>>> assert(v.a == 1)
>>> assert(v['a'] == 1)
get_data()

Prepare & parse data for export

>>> y = Yaco()
>>> y.a = 1
>>> y.b = 2
>>> y._c = 3
>>> assert(y._c == 3)
>>> d = y.get_data()
>>> assert(d.has_key('a') == True)
>>> assert(d.has_key('b') == True)
>>> assert(d.has_key('_c') == False)
>>> y._private = ['b']
>>> d = y.get_data()
>>> assert(d.has_key('a') == True)
>>> assert(d.has_key('b') == False)
>>> assert(d.has_key('_c') == False)
load(from_file)

Load this dict from_file

>>> import yaml
>>> import tempfile
>>> tf = tempfile.NamedTemporaryFile(delete=False)
>>> tf.write(yaml.dump({'a' : [1,2,3, [1,2,3, {'d' : 4}]], 'b': 4, 'c': '5'}))
>>> tf.close()
>>> y = Yaco()
>>> y.load(tf.name)
>>> assert(y.a[3][3].d == 4)
pretty()

Return data as a pprint.pformatted string

save(to_file, doNotSave=[])
simple()

return a simplified representation of this Yaco struct - remove Yaco from the equation - and all object reference. Leave only bool, float, str, lists, tuples and dicts

>>> x = Yaco()
>>> x.y.z = 1
>>> assert(isinstance(x.y, Yaco))
>>> s = x.simple()
>>> assert(s['y']['z'] == 1)
>>> assert(isinstance(s['y'], dict))
>>> assert(not isinstance(s['y'], Yaco))
update(data)
>>> v = Yaco({'a' : [1,2,3,{'b' : 12}]})
>>> assert(v.a[3].b == 12)
>>> v = Yaco({'a' : [1,2,3,[1,{'b' : 12}]]})
>>> assert(v.a[3][1].b == 12)