-
-
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
@validates accepts multiple field names #1965
base: dev
Are you sure you want to change the base?
@validates accepts multiple field names #1965
Conversation
apologies for the long delay on this. i hesitated initially because i had the same concern as @deckar01 about this being a breaking change. now that we're closing to releasing the next major, i think this is one that we can get merged. i'll update this when i have some time |
should validator methods receive from marshmallow import Schema, fields, validates, ValidationError
class UserSchema(Schema):
name = fields.Str(required=True)
nickname = fields.Str(required=True)
@validates("name", "nickname")
def validate_names(self, value: str, field_name: str) -> str:
if len(value) < 3:
raise ValidationError(f"{field_name} too short")
return value |
looks like SQLAlchemy does pass a from sqlalchemy.orm import validates
class EmailAddress(Base):
__tablename__ = "address"
id = mapped_column(Integer, primary_key=True)
email = mapped_column(String)
@validates("email")
def validate_email(self, key, address):
if "@" not in address:
raise ValueError("failed simple email validation")
return address |
Updated to pass |
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.
No strong opinion about this. It adds a bit of API surface for a case that may not be so frequent, but addressing it with validates_schema
is less convenient so this makes sense.
I'm not a fan of the "string or list of strings" pattern. In fact I didn't see where the magic operates but I suppose it does, otherwise all tests would be broken. And expecting a list of strings for a single field (99% case) would be a pity.
@validates("name", "nickname") | ||
def validate_names(self, value: str, data_key: str) -> None: | ||
if len(value) < 3: | ||
raise ValidationError("Too short") |
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 would be the right place to show the use of data_key
like in the upgrading guide.
there's actually no special-casing here because def validates(*field_names: str) allows one or more field names to be passed positionally. |
But then in (I'm not talking about mypy / type checking but about runtime.) |
>>> def validates(*field_names: str):
... print(type(field_names))
...
>>> validates("foo")
<class 'tuple'> |
Oh sorry, I missed the obvious. The user never passes a tuple or list, just N positional args. |
Fix for #1960