The safest, simplest, clearest solution is a mapping explicitly listing the types you care about:
TYPES = {
'str': str,
'int': int,
...
}
You can eliminate the repetition (at the cost of some flexibility) by creating this dict from a list of types:
TYPES = {cls.__name__: cls for cls in [str, int, ...]}
Then you can recursively walk the document (as you do in evaler
) and replace each string s with TYPES[s]
.
If you insist on supporting all built-in types by their name, without listing them separately, you can use the builtins
module (called __builtin__
in Python 2).
getattr
is your friend here. You should probably check whether it's a type -- there are a lot of built in names that aren't.
You need to walk the document in any case. From PyYAML's perspective, the string "str" used as mapping value has the same tag as the string "a" used as mapping key, so you can't do anything by specifying a different class for that tag. While you could perhaps dive into its guts and introduce a hack that treats scalar mapping values differently, this would be just that: A hack. And a huge amount of additional work to boot. Not worth it.