For the first time ever, I think I'm actually able to use Python to
reliably load *typed* YAML objects. This is just wonderful. The need
for this emerged since I needed to distinguish between two keys that
might possibly have the same "value".
%YAML 1.1
%TAG !! tag:example.com,2006:
---
!!bing rowid: bing
rowid: womble
...
This can be loaded, using the following:
import yaml
class Bing(object):
def __init__(self, value):
self.value = value
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, repr(self.value))
def bing_representer(dumper,data):
return dumper.represent_scalar('tag:example.com,2006:bing', data.value)
yaml.add_representer(Bing, bing_representer)
def bing_constructor(loader,node):
return Bing(loader.construct_scalar(node))
yaml.add_constructor('tag:example.com,2006:bing', bing_constructor)
output = """\
{rowid: womble, !<tag:example.com,2006:bing> 'rowid': bing}
"""
assert output == yaml.dump(yaml.load(input))
I am absolutely happy. But I have a few suggestions:
1. First, I'd like to use ``save_load``, rather than just ``load``,
so I was wondering if there is a way I can *only* load standard
YAML types *and* my Bing class, but not allow for arbitrary Python
object construction.
-> Actually, I'd make ``load()`` by default be ``safe_load()``,
and rename what is currently ``load()`` to ``unsafe_load()``.
The regular load would construct standard YAML data types, plus
any that are _explicitly_ registered via the mechanism above.
2. I'd like to see if we can modify the specifcation to permit
!! all by itself: !!bing is quite arbitrary in this use case,
what would be nicer to read is:
%YAML 1.1
%TAG !! tag:example.com,2006:bing
---
!! rowid: bing
rowid: womble
...
Especially since I have *alot* of these alternate tags.
Oh, we need to update the specification to reflect the current usage
of "!" causing implicit typing. This was the old behavior, it works,
but the current 1.1 specification doesn't reflect this notion.
Best,
Clark
|