New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: Inaccurate Error Messages When Dict Keys Require Complex Validation #127
Comments
This also prevents errors raised by custom validators from being seen, which is not very helpful in discerning what went wrong with some data: >>> import voluptuous as v
>>> def V(s='abc'):
... def f(x):
... if x == s:
... return x
... raise v.Invalid('String "{x}" is not "{s}"'.format(x=x, s=s))
... return f
...
>>> v.Schema({V(): '123'})({'abc': '123'})
{'abc': '123'}
>>> v.Schema({V(): '123'})({'abcd': '123'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/markgollnick/.virtualenvs/py27/lib/python2.7/site-packages/voluptuous.py", line 333, in __call__
return self._compiled([], data)
File "/Users/markgollnick/.virtualenvs/py27/lib/python2.7/site-packages/voluptuous.py", line 631, in validate_dict
return base_validate(path, iteritems(data), out)
File "/Users/markgollnick/.virtualenvs/py27/lib/python2.7/site-packages/voluptuous.py", line 467, in validate_mapping
raise MultipleInvalid(errors)
voluptuous.MultipleInvalid: extra keys not allowed @ data['abcd'] It works in the values case, however: >>> v.Schema({'123': V()})({'123': 'abc'})
{'123': 'abc'}
>>> v.Schema({'123': V()})({'123': 'abcd'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/markgollnick/.virtualenvs/py27/lib/python2.7/site-packages/voluptuous.py", line 333, in __call__
return self._compiled([], data)
File "/Users/markgollnick/.virtualenvs/py27/lib/python2.7/site-packages/voluptuous.py", line 631, in validate_dict
return base_validate(path, iteritems(data), out)
File "/Users/markgollnick/.virtualenvs/py27/lib/python2.7/site-packages/voluptuous.py", line 467, in validate_mapping
raise MultipleInvalid(errors)
voluptuous.MultipleInvalid: String "abcd" is not "abc" for dictionary value @ data['123'] |
Workaround:
See |
This is not strictly speaking a bug. For a dictionary, Voluptuous will attempt to match each key against all keys in the schema. If multiple keys fail, which error should it report? For example, in the following schema, there are two possible keys that could report errors. Voluptuous does not know which one to report, so it reports the most generic error. >>> s = Schema({All(str, Coerce(int)): 1, 'bar': int})
>>> s({'foo': 1})
...
MultipleInvalid: extra keys not allowed @ data['asd'] In your specific case where there is only one key it would be possible to report a deeper error. But it's arguable whether that error is "more" correct than "extra keys not allowed". I do understand that this is perhaps not what one would expect, but if you can propose a general solution that works well in all cases I'd be happy to consider it. |
Also see #114 and probably others. |
@alecthomas, thank you for your response. Is it possible to enumerate the varying cases you have in mind? I updated your example slightly to better illustrate what kind of response is currently given versus what I would expect to be the error message. Current behavior:
Desired behavior:
Or, with the original example, which doesn't provide exactly the right message, but is closer than "extra keys not allowed", and can be enhanced with a custom message, as above:
Where "extra keys" makes sense:
Do you think this behavior could be achieved? Is there a case I'm not seeing, or something I'm misunderstanding? UPDATE:
Which error message should be raised? Expected int, or expected str? Since it doesn't match any dict keys, it makes sense for the message to read, "extra keys not allowed," since it's not known which key the user was attempting to match. I think my use case is very narrow, and only applies to dicts that have a single schema for dict keys where extra keys are not allowed, e.g. |
Yes, your update is exactly correct. It's tricky. The idea of returning the deepest error message found is what Voluptuous does actually try to do, but I think in this case it doesn't work because |
The real error is that
Coerce
fails because'abc'
isn't a validint
, but it gets clobbered by the extra keys error.The text was updated successfully, but these errors were encountered: