为密钥类型验证获取更好的 Voluptuous Schema 错误消息?
Getting a better Voluptuous Schema error message for key type validation?
我有一个如下所示的架构(示例):
Schema({
Any(str, unicode): [{
Required('first_name'): [Any(str, unicode)],
Required('age'): Any('int32', 'double'),
Required('something'): Any(int, long, float, str, unicode)
}]
})
如果我传递一个 int(比方说 42
)作为键(Any(str, unicode)
),我得到:
<class 'voluptuous.error.Invalid'> : extra keys not allowed @ data[42]. Got ["my_value"]
这并不能很好地代表我的错误,因为它甚至没有告诉我们问题实际上是密钥的类型。值类型的错误是完美的,像这样:expected str for dictionary value @ data[0]["my_key"]. Got 42
有没有办法像这样使用 voluptuous' Schema
获得更清晰的密钥类型验证消息?
expected str for dictionary key type. Got 42
PS: 还是我的Schema
不对?我的目标是拥有一个字典,其中的键是字符串或 unicode(这是一个示例),值是具有特定值类型的特定键的字典列表。
更新
我尝试将密钥验证放在另一个架构中,以获得正确的错误消息,如下所示:
KEY_SCHEMA = Schema(Any(str, unicode))
def validate_key(my_key):
KEY_SCHEMA (my_key) # Here the correct error/message is raised
Schema({
validate_key: [{
Required('first_name'): [Any(str, unicode)],
Required('age'): Any('int32', 'double'),
Required('something'): Any(int, long, float, str, unicode)
}]
})
我从 KEY_SCHEMA
得到的错误信息是 "ok" 我可以做一个 try/except raise
来输出一个更好的错误信息,但是它被主 Schema
并再次返回与之前相同的错误。
我运行遇到了完全相同的问题。这不是关于你的模式,而是关于性感的工作方式。
因为您为字典键而不是静态值定义了架构,所以它允许字典包含与该架构匹配的多个键。你的父模式的额外参数是 False (默认),这意味着任何额外的元素(任何与你的内部模式不匹配的键)都不会被接受(这很好,否则你无法确保所有键根据您的内部架构进行验证)。这就是问题所在, extra=False 条件优先于内部模式的非验证。然后整数键被视为额外键,因为它在被视为无效之前不匹配模式。在 voluptuous 中验证具有相同模式的多个键不如值验证有效和明确。
话虽如此,我最终得到了一个(肮脏的)解决方案。在作为额外参数打印之前,我只想输出一条消息,说明密钥架构与给定密钥不匹配。通过为密钥验证定义一个函数,我做了和你一样的事情。此函数会自行验证密钥,如果没有验证则打印一条错误消息。引发 Invalid 将触发额外的参数错误消息,所以我之前退出了我的程序(它符合我的需要,但这对其他人来说不是必需的)。
在你的情况下可能是这样的:
KEY_SCHEMA = Schema(Any(str, unicode))
def validate_key(my_key):
if type(my_key) is not str and type(my_key) is not unicode:
logger.error("{} is not a str or unicode. Aborting.") # if you use the logger library
sys.exit(1) # need to import sys
return KEY_SCHEMA (my_key)
Schema({
validate_key: [{
Required('first_name'): [Any(str, unicode)],
Required('age'): Any('int32', 'double'),
Required('something'): Any(int, long, float, str, unicode)
}]
})
我有一个如下所示的架构(示例):
Schema({
Any(str, unicode): [{
Required('first_name'): [Any(str, unicode)],
Required('age'): Any('int32', 'double'),
Required('something'): Any(int, long, float, str, unicode)
}]
})
如果我传递一个 int(比方说 42
)作为键(Any(str, unicode)
),我得到:
<class 'voluptuous.error.Invalid'> : extra keys not allowed @ data[42]. Got ["my_value"]
这并不能很好地代表我的错误,因为它甚至没有告诉我们问题实际上是密钥的类型。值类型的错误是完美的,像这样:expected str for dictionary value @ data[0]["my_key"]. Got 42
有没有办法像这样使用 voluptuous' Schema
获得更清晰的密钥类型验证消息?
expected str for dictionary key type. Got 42
PS: 还是我的Schema
不对?我的目标是拥有一个字典,其中的键是字符串或 unicode(这是一个示例),值是具有特定值类型的特定键的字典列表。
更新
我尝试将密钥验证放在另一个架构中,以获得正确的错误消息,如下所示:
KEY_SCHEMA = Schema(Any(str, unicode))
def validate_key(my_key):
KEY_SCHEMA (my_key) # Here the correct error/message is raised
Schema({
validate_key: [{
Required('first_name'): [Any(str, unicode)],
Required('age'): Any('int32', 'double'),
Required('something'): Any(int, long, float, str, unicode)
}]
})
我从 KEY_SCHEMA
得到的错误信息是 "ok" 我可以做一个 try/except raise
来输出一个更好的错误信息,但是它被主 Schema
并再次返回与之前相同的错误。
我运行遇到了完全相同的问题。这不是关于你的模式,而是关于性感的工作方式。
因为您为字典键而不是静态值定义了架构,所以它允许字典包含与该架构匹配的多个键。你的父模式的额外参数是 False (默认),这意味着任何额外的元素(任何与你的内部模式不匹配的键)都不会被接受(这很好,否则你无法确保所有键根据您的内部架构进行验证)。这就是问题所在, extra=False 条件优先于内部模式的非验证。然后整数键被视为额外键,因为它在被视为无效之前不匹配模式。在 voluptuous 中验证具有相同模式的多个键不如值验证有效和明确。
话虽如此,我最终得到了一个(肮脏的)解决方案。在作为额外参数打印之前,我只想输出一条消息,说明密钥架构与给定密钥不匹配。通过为密钥验证定义一个函数,我做了和你一样的事情。此函数会自行验证密钥,如果没有验证则打印一条错误消息。引发 Invalid 将触发额外的参数错误消息,所以我之前退出了我的程序(它符合我的需要,但这对其他人来说不是必需的)。
在你的情况下可能是这样的:
KEY_SCHEMA = Schema(Any(str, unicode))
def validate_key(my_key):
if type(my_key) is not str and type(my_key) is not unicode:
logger.error("{} is not a str or unicode. Aborting.") # if you use the logger library
sys.exit(1) # need to import sys
return KEY_SCHEMA (my_key)
Schema({
validate_key: [{
Required('first_name'): [Any(str, unicode)],
Required('age'): Any('int32', 'double'),
Required('something'): Any(int, long, float, str, unicode)
}]
})