-
Notifications
You must be signed in to change notification settings - Fork 240
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
Don't ignore all exceptions during coercions for nullable fields #490
Conversation
The Travis failure for |
f5ece6b
to
7921688
Compare
The same test passed on the second try, so just appears to be flaky. The failure was https://travis-ci.org/pyeve/cerberus/jobs/527412260 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for bringing this up. could you please also update the CHANGES.rst
and add yourself to the AUTHORS
file?
@@ -170,6 +170,15 @@ def test_nullables_dont_fail_coerce(): | |||
assert_normalized(document, document, schema) | |||
|
|||
|
|||
def test_nullables_fail_coerce_on_non_null_values(validator): | |||
schema = {'foo': {'coerce': lambda x: 1 / 0, 'nullable': True, 'type': 'integer'}} | |||
document = {'foo': None} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is already covered in the previous test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but I feel the repetition is a good idea here because the new behavior is about the difference between these two cases (the value is None
or not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not saying you're wrong, but we don't do that elsewhere (oh dear, formulating this makes me feel old). i'm gonna amend this when merging.
cerberus/validator.py
Outdated
@@ -723,7 +723,7 @@ def __normalize_coerce(self, processor, field, value, nullable, error): | |||
try: | |||
return processor(value) | |||
except Exception as e: | |||
if not nullable and e is not TypeError: | |||
if not nullable or value is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i find this term more obvious: not (nullable and value is None)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
second thought: should the coercion get tried at all when the part in brackets is true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the condition.
Not sure there's an obvious answer to whether the coercion should be tried or not. Somebody might want to coerce None
to something else? Or would the validation in that case fail at a later stage anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that NOT trying the coercion for nullable fields when the value is None would fix this issue: #427
To be honest, I don't feel I'm in a position to make the right call here. So happy to make this change or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for digging this out. that issue concluded to postpone changes until the 2.0 release; and i think i shall document that this still needs to be layed out design-wise.
please don't mark this conversation as resolved for visibility.
yes, Python 2.7 and 3.5 sort errors kind of erraticly. no worries. |
7921688
to
2797119
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick review! I updated AUTHORS and CHANGES too
@@ -170,6 +170,15 @@ def test_nullables_dont_fail_coerce(): | |||
assert_normalized(document, document, schema) | |||
|
|||
|
|||
def test_nullables_fail_coerce_on_non_null_values(validator): | |||
schema = {'foo': {'coerce': lambda x: 1 / 0, 'nullable': True, 'type': 'integer'}} | |||
document = {'foo': None} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but I feel the repetition is a good idea here because the new behavior is about the difference between these two cases (the value is None
or not).
cerberus/validator.py
Outdated
@@ -723,7 +723,7 @@ def __normalize_coerce(self, processor, field, value, nullable, error): | |||
try: | |||
return processor(value) | |||
except Exception as e: | |||
if not nullable and e is not TypeError: | |||
if not nullable or value is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the condition.
Not sure there's an obvious answer to whether the coercion should be tried or not. Somebody might want to coerce None
to something else? Or would the validation in that case fail at a later stage anyway?
2797119
to
299bd92
Compare
Only ignore exceptions if a value for a nullable field is not null. Previously all exceptions during custom coerction were ignored with nullable fields. The developer and/or user most likely wants to know about exceptions that happen during coercion - this leads to hard to debug problems otherwise. The purpose of the `e is not TypeError` condition was unclear. As far as I know this condition can never be false (`e` is an instance of an exception, not an exception class). I think this is still in line with the original intent of this code, which was to make common coercions like `float` work with nullable fields out of the box: pyeve#269
299bd92
to
c51059d
Compare
Side note, |
now, that's bad luck. but just ignore it. |
Only ignore exceptions if a value for a nullable field is not null.
Previously all exceptions during custom coerction were ignored with nullable
fields. The developer and/or user most likely wants to know about
exceptions that happen during coercion - this leads to hard to debug
problems otherwise.
The purpose of the
e is not TypeError
condition was unclear. As far as Iknow this condition can never be false (
e
is an instance of an exception,not an exception class).
I think this is still in line with the original intent of this code, which
was to make common coercions like
float
work with nullable fields outof the box: #269