我正在尝试将自定义数据类型添加到Cerberus。UUID 类按预期工作(它是一个标准库类),但我无法使用 Cerberus 验证 UUID 类型。
其次,我无法在一个__init__
函数中注册多种类型,但这可能应该是它自己的问题。
这是我应该注册给定类型的自定义验证器。
import cerberus
class UUID:
name = "UUID"
def __init__(self, potential_uuid: str):
self.uuid = uuid.UUID(potential_uuid)
def __str__(self):
return str(self.uuid)
class Validator(cerberus.Validator):
def _register_types(self) -> cerberus.Validator.types_mapping:
types_mapping = Validator.types_mapping.copy()
for schema_type in datatypes.ALL_TYPES:
cerberus_type = cerberus.TypeDefinition(
schema_type.name,
(schema_type,),
())
types_mapping[schema_type.name] = cerberus_type
return types_mapping
cerberus_type = cerberus.TypeDefinition(
"UUID",
(datatypes.UUID,),
())
types_mapping = cerberus.Validator.types_mapping.copy()
types_mapping["UUID"] = cerberus_type
#def __init__(self, *args, **kwargs ):
# types_mapping = self._register_types()
# super().__init__(*args, **kwargs)
这是我对此代码的单元测试。
@pytest.mark.unit
def test_valid_uuid():
test_input = "35d6d5a0-6f37-4794-a493-2712eda41c1a"
actual = UUID(test_input)
assert str(actual) == "35d6d5a0-6f37-4794-a493-2712eda41c1a"
@pytest.mark.unit
def test_invalid_uuid():
test_input = "Not a Valid UUID"
with pytest.raises(ValueError):
actual = UUID(test_input)
@pytest.mark.unit
def test_uuid_type_registration():
test_schema = {"test_name": {"type": "UUID"}}
validator = Validator(test_schema)
test_record = {"test_name": "35d6d5a0-6f37-4794-a493-2712eda41c1a"}
result = validator.validate(test_record)
print(validator._errors)
assert result == True
如果我们只是给 UUID 类一个有效的 UUID,它会成功,但如果我们尝试通过 Cerberus 验证它,我们会收到BAD_TYPE
验证错误。
pytest tests/test_datatypes/test_datatypes.py
============================================================================================================================= test session starts ==============================================================================================================================
platform linux -- Python 3.7.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
benchmark: 3.2.2 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /home/vdev, inifile: setup.cfg
plugins: cov-2.6.1, benchmark-3.2.2
collected 4 items
tests/test_datatypes/test_datatypes.py ...F [100%]
=================================================================================================================================== FAILURES ===================================================================================================================================
_________________________________________________________________________________________________________________________ test_uuid_type_registration __________________________________________________________________________________________________________________________
@pytest.mark.unit
def test_uuid_type_registration():
test_schema = {"test_name": {"type": "UUID"}}
validator = Validator(test_schema)
test_record = {"test_name": "35d6d5a0-6f37-4794-a493-2712eda41c1a"}
result = validator.validate(test_record)
print(validator._errors)
> assert result == True
E assert False == True
tests/test_datatypes/test_datatypes.py:30: AssertionError
----------------------------------------------------------------------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------------------------------------------------------------------
[ValidationError @ 0x7fa477e10278 ( document_path=('test_name',),schema_path=('test_name', 'type'),code=0x24,constraint="UUID",value="35d6d5a0-6f37-4794-a493-2712eda41c1a",info=() )]
=============================================================================================================================== warnings summary ===============================================================================================================================
/usr/local/lib/python3.7/site-packages/cerberus/validator.py:14
/usr/local/lib/python3.7/site-packages/cerberus/validator.py:14
/usr/local/lib/python3.7/site-packages/cerberus/validator.py:14
/usr/local/lib/python3.7/site-packages/cerberus/validator.py:14
/usr/local/lib/python3.7/site-packages/cerberus/validator.py:14: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Hashable, Iterable, Mapping, Sequence
/usr/local/lib/python3.7/site-packages/cerberus/errors.py:6
/usr/local/lib/python3.7/site-packages/cerberus/errors.py:6: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import defaultdict, namedtuple, MutableMapping
/usr/local/lib/python3.7/site-packages/cerberus/schema.py:3
/usr/local/lib/python3.7/site-packages/cerberus/schema.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import (Callable, Hashable, Iterable, Mapping,
-- Docs: https://docs.pytest.org/en/latest/warnings.html
================================================================================================================ 1 failed, 3 passed, 6 warnings in 0.33 seconds ===============================================================================================================
编辑 1
简化的示例代码
import cerberus
import uuid
class Validator(cerberus.Validator):
types_mapping = {
**cerberus.Validator.types_mapping,
'UUID': cerberus.TypeDefinition('UUID', (uuid.UUID,), ())
}
同样的失败
@pytest.mark.unit
def test_uuid_type_registration():
test_schema = {"test_name": {"type": "UUID"}}
validator = es_client.Validator(test_schema)
test_record = {"test_name": "35d6d5a0-6f37-4794-a493-2712eda41c1a"}
result = validator.validate(test_record)
print(validator._errors)
> assert result == True
E assert False == True
tests/test_datatypes/test_datatypes.py:30: AssertionError
------------------------------------------------------------ Captured stdout call -------------------------------------------------------------
[ValidationError @ 0x7fd9cdeed0b8 ( document_path=('test_name',),schema_path=('test_name', 'type'),code=0x24,constraint="UUID",value="35d6d5a0-6f37-4794-a493-2712eda41c1a",info=() )]