I'd like to be able to define a schema in yaml, read it in using pyyaml
and then validate with voluptuous
(or other schema validator!). However, as stated in the question title, I run into the need to have the builtin class str
instantiated for voluptuous rather than the string representation of it.
from voluptuous import Schema
import yaml
y = '''
a: str
b: int
c:
d: float
e: str
'''
yaml_schema = yaml.load(y,
Loader=yaml.CLoader)
schema1 = Schema(yaml_schema, required=True)
However, this schema is now looking for the string str
as the only acceptable value of a
. Using the direct pyyaml (e.g. 'a': !!python/int) fails. Instead, I want the schema below:
schema2 = Schema({'a': str,
'b': int,
'c': {'d': float,
'e': str}},
required=True)
I am well aware that eval
is not a production solution, but the function evaler
below will convert schema1
to schema2
...
def evaler(d):
out = {}
for k, v in d.items():
if isinstance(v, dict):
out[k] = evaler(v)
else:
out[k] = eval(v)
return out
## Tests:
## passing
v.Schema(evaler(yaml_schema),
required=True)({'a': 'foo',
'b': 2,
'c': {'d': 2.0,
'e': 'bar'}})
## failling
v.Schema(evaler(yaml_schema),
required=True)({'a': 3,
'b': 2,
'c': {'d': 2.0,
'e': 1}})
I'm also aware that you can instantiate an empty class:
class foo: pass
globals()['foo']
But with builtins this is not possible:
globals()['int']
# KeyError: 'int'
I explored the new
and type
modules, but didn't have any luck...