Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add a python tuple to a YAML file using pyYAML?

Tags:

python

pyyaml

The title is fairly self-explanatory.

When I save a tuple to a YAML file, I get something that looks like this:

ambient:  !!python/tuple [0.3, 0.3 ,0.3]

When I try to load it with yaml.safe_load(file_object), I keep getting an error that reads:

yaml.constructor.ConstructorError:  could not determine a constructor for the tag 'tag:yaml.org,2002:python/tuple'

What needs to be done?

like image 880
Louis Thibault Avatar asked Feb 06 '12 23:02

Louis Thibault


1 Answers

In pyyaml, the SafeLoader does not include a loader for the python native types, only the types defined in the yaml spec. You can see the types for the SafeLoader and the Loader here in the interaction sample below.

You can define a new Loader class that adds in the python tuple, but not other types, so it should still be pretty safe:

import yaml

class PrettySafeLoader(yaml.SafeLoader):
    def construct_python_tuple(self, node):
        return tuple(self.construct_sequence(node))

PrettySafeLoader.add_constructor(
    u'tag:yaml.org,2002:python/tuple',
    PrettySafeLoader.construct_python_tuple)

doc = yaml.dump(tuple("foo bar baaz".split()))
print repr(doc)
thing = yaml.load(doc, Loader=PrettySafeLoader)
print thing

resulting in:

'!!python/tuple [foo, bar, baaz]\n'
('foo', 'bar', 'baaz')

See below for the constructors associated with the SafeLoader and the Loader classes.

>>> yaml.SafeLoader.yaml_constructors
{None: <unbound method SafeConstructor.construct_undefined>,
 u'tag:yaml.org,2002:binary': <unbound method SafeConstructor.construct_yaml_binary>,
 u'tag:yaml.org,2002:bool': <unbound method SafeConstructor.construct_yaml_bool>,
 u'tag:yaml.org,2002:float': <unbound method SafeConstructor.construct_yaml_float>,
 u'tag:yaml.org,2002:int': <unbound method SafeConstructor.construct_yaml_int>,
 u'tag:yaml.org,2002:map': <unbound method SafeConstructor.construct_yaml_map>,
 u'tag:yaml.org,2002:null': <unbound method SafeConstructor.construct_yaml_null>,
 u'tag:yaml.org,2002:omap': <unbound method SafeConstructor.construct_yaml_omap>,
 u'tag:yaml.org,2002:pairs': <unbound method SafeConstructor.construct_yaml_pairs>,
 u'tag:yaml.org,2002:seq': <unbound method SafeConstructor.construct_yaml_seq>,
 u'tag:yaml.org,2002:set': <unbound method SafeConstructor.construct_yaml_set>,
 u'tag:yaml.org,2002:str': <unbound method SafeConstructor.construct_yaml_str>,
 u'tag:yaml.org,2002:timestamp': <unbound method SafeConstructor.construct_yaml_timestamp>}

>>> yaml.Loader.yaml_constructors
{None: <unbound method SafeConstructor.construct_undefined>,
 u'tag:yaml.org,2002:binary': <unbound method SafeConstructor.construct_yaml_binary>,
 u'tag:yaml.org,2002:bool': <unbound method SafeConstructor.construct_yaml_bool>,
 u'tag:yaml.org,2002:float': <unbound method SafeConstructor.construct_yaml_float>,
 u'tag:yaml.org,2002:int': <unbound method SafeConstructor.construct_yaml_int>,
 u'tag:yaml.org,2002:map': <unbound method SafeConstructor.construct_yaml_map>,
 u'tag:yaml.org,2002:null': <unbound method SafeConstructor.construct_yaml_null>,
 u'tag:yaml.org,2002:omap': <unbound method SafeConstructor.construct_yaml_omap>,
 u'tag:yaml.org,2002:pairs': <unbound method SafeConstructor.construct_yaml_pairs>,
 u'tag:yaml.org,2002:python/bool': <unbound method Constructor.construct_yaml_bool>,
 u'tag:yaml.org,2002:python/complex': <unbound method Constructor.construct_python_complex>,
 u'tag:yaml.org,2002:python/dict': <unbound method Constructor.construct_yaml_map>,
 u'tag:yaml.org,2002:python/float': <unbound method Constructor.construct_yaml_float>,
 u'tag:yaml.org,2002:python/int': <unbound method Constructor.construct_yaml_int>,
 u'tag:yaml.org,2002:python/list': <unbound method Constructor.construct_yaml_seq>,
 u'tag:yaml.org,2002:python/long': <unbound method Constructor.construct_python_long>,
 u'tag:yaml.org,2002:python/none': <unbound method Constructor.construct_yaml_null>,
 u'tag:yaml.org,2002:python/str': <unbound method Constructor.construct_python_str>,
 u'tag:yaml.org,2002:python/tuple': <unbound method Constructor.construct_python_tuple>,
 u'tag:yaml.org,2002:python/unicode': <unbound method Constructor.construct_python_unicode>,
 u'tag:yaml.org,2002:seq': <unbound method SafeConstructor.construct_yaml_seq>,
 u'tag:yaml.org,2002:set': <unbound method SafeConstructor.construct_yaml_set>,
 u'tag:yaml.org,2002:str': <unbound method SafeConstructor.construct_yaml_str>,
 u'tag:yaml.org,2002:timestamp': <unbound method SafeConstructor.construct_yaml_timestamp>}
like image 74
Matt Anderson Avatar answered Sep 21 '22 11:09

Matt Anderson