-
-
Notifications
You must be signed in to change notification settings - Fork 629
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
Remove strict parameter and return [de|]serialiazed data or raise ValidationError #711
Conversation
@sloria, any idea why the tests fail for P2.7 and Pypy? It fails with invoke but I can't reproduce when calling pytest directly in a P2.7 virtualenv. I copied the mechanism used for json module deprecation. |
I'm tackling #598 in the same branch as those two issues are related. Feedback welcome. The docs should be updated. Not sure about |
Thanks so much for tackling this @lafrech ! This is looking great. The failure in Python 2 is due to an existing bug in pytest: pytest-dev/pytest#2917 . I was able to work around it by upgrading pytest to the latest version and using def test_strict_is_deprecated():
with pytest.deprecated_call():
class StrictUserSchema(Schema):
name = fields.String()
class Meta:
strict = False
class UserSchema(Schema):
name = fields.String()
with pytest.deprecated_call():
UserSchema(strict=True) I just enabled pyup.io so that we can automate dependency upgrades. Once I have the initial update passing on Travis, pytest will be updated. Feel free to just do the update in this branch though if it's blocking you. |
OK, pytest is now updated on |
Branch rebased and workaround applied. |
docs/upgrading.rst
Outdated
errors = err.messages | ||
valid_data = err.valid_data | ||
|
||
:meth:`Schema.validate` now always returns a dictionary of validation errors (same as before with ``strict=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.
Wouldn't it be the same as before with strict=False
?
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.
Oops. You're right. Let me fix this now.
This is fantastic. Special thanks for updating the docs! This doesn't deprecate |
By the way, I've given you write access to this repo. Thanks again for all your hard work. |
Also, the code in the |
If errors are detected, ValidationError is raised which contains errors in its 'messages' attribute. Remove MarshalResult and UnmarshalResult Closes #598
Done.
Yes, I totally realize that. You're right about the fact that it is not a "deprecation". Since this is a major release, let's remove
Thanks. I don't think I'll be pushing stuff in |
Fine by me! |
Great! Thanks for reviewing and merging.
Actually, they are not only strict by default, they can only be strict, the option has been removed. |
Fair point; I've tweaked the wording a bit. |
raise ValidationError(errors, data=obj, valid_data=ret) | ||
except ValidationError as exc: | ||
raise ValidationError(exc.messages, data=obj, valid_data=exc.valid_data) | ||
finally: |
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 causes a NameError
to be raised instead of the ValueError
when using the string version of only
, because ret
will always be undefined if an exception is raised. This shouldn't have been wrapped in a finally
block.
try:
raise ValueError()
a = 1
except ValueError as e:
raise ValueError()
finally:
print(a)
# Traceback (most recent call last):
# line 7, in <module>
# NameError: name 'a' is not defined
The should get fixed as part of #800.
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.
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 have a fix in a WIP PR. #823
@sloria, I think you should reconsider keeping the strict field, although I agree it should be the default. Consider the case of a third party dependency that adds an additional field to a response from an API call. It's common practice to add additional json fields without considering this to be a breaking change. Alternatively, consider two microservices that communicate over json. By forcing "strict", we make it difficult to deploy or rollback these microservices independently. Even the JSON Schema spec itself allows for additional fields:
|
It is about raising an exception in case of error vs. returning a data + errors tuple. |
See marshmallow-code/marshmallow#711 Our attempt to make it strict is obsolete, and was raising this error on all the generic leaderboards pages: ``` TypeError TypeError: __init__() got an unexpected keyword argument 'strict' Traceback (most recent call last) File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__ return self.wsgi_app(environ, start_response) File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app response = self.handle_exception(e) File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app response = self.full_dispatch_request() File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request rv = self.dispatch_request() File "/Users/rbulling/Documents/src/freezingsaddles/.venv/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/Users/rbulling/Documents/src/freezingsaddles/freezing-web/freezing/web/views/pointless.py", line 22, in generic board, data = load_board_and_data(leaderboard) File "/Users/rbulling/Documents/src/freezingsaddles/freezing-web/freezing/web/utils/genericboard.py", line 93, in load_board_and_data board = load_board(leaderboard) File "/Users/rbulling/Documents/src/freezingsaddles/freezing-web/freezing/web/utils/genericboard.py", line 116, in load_board schema = GenericBoardSchema() File "/Users/rbulling/Documents/src/freezingsaddles/.venv/src/freezing-model/freezing/model/msg/__init__.py", line 24, in __init__ super().__init__(*args, **kwargs) TypeError: __init__() got an unexpected keyword argument 'strict' ```
I started to work on #377 (Strict Schema Validation should be enabled by default).
This deprecates
strict
. AValidationError
is raised every time an error is encountered.Note that this does not implement #598 (Return deserialized data when strict=True), and dump/load still returns data and errors.
The error in the tests is due to #710. I'll rebase this branch when this issue is fixed in
dev
branch.Feedback welcome.