0

yaml でスキーマを定義し、それを使用して読み取り、 (または他のスキーマ検証ツールで)pyyaml検証できるようにしたいと考えています。voluptuousただし、質問のタイトルに記載されているように、組み込みクラスstrを文字列表現ではなく官能的にインスタンス化する必要があります。

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)

strただし、このスキーマは現在、 の唯一の許容値として文字列を探していますa。直接 pyyaml (例: 'a': !!python/int) を使用すると失敗します。代わりに、以下のスキーマが必要です。

schema2 = Schema({'a': str,
                 'b': int,
                 'c': {'d': float,
                       'e': str}},
                required=True)

evalこれが本番ソリューションではないことは十分承知していますが、evaler以下の関数は次のように変換schema1され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}})

また、空のクラスをインスタンス化できることも認識しています。

class foo: pass
globals()['foo']

しかし、ビルトインではこれは不可能です:

globals()['int']
# KeyError: 'int'

newおよびモジュールを調査しましたtypeが、運がありませんでした...

4

1 に答える 1