Description
As suggested by @lafrech in #2786 (review), we can enable pre/post-load on fields to address use cases like whitespace trimming (#1391) via an API similar to the schema-level pre/post_load/dump API.
Something like:
from marshmallow import Schema, fields
class ArtistSchema(Schema):
name = fields.Str(post_load=(str.strip, str.upper))
email = fields.Str(post_load=(str.strip, str.upper))
- pro: allows field-specific transformations without having to implement a custom field
- pro: non-breaking change
- con: overlaps with existing functionality provided by custom fields and the schema-level
@pre/post_load
Alternatives considered
Allow validators to transform values
- same as pydantic and [sqlalchemy](https://docs.sqlalchemy.org/en/20/orm/mapped_attributes.html#simple-validators and Add field-level pre/post-load API #2787 (comment))
- pro: minimal API surface added
- pro: minimal internal code changes
- con: it's not intuitive that validators can mutate values
- con: doesn't solve for pre-validation transformations or dumping/serialization
- con: breaking change
Decorator API
update: this was considered as part of the original proposal but rejected/tabled (#2787 (comment) and #2787 (comment))
from marshmallow import Schema, fields, field_post_load
class ArtistSchema(Schema):
name = fields.Str()
email = fields.Str()
@field_post_load("name", "email")
def strip_whitespace(self, field_name: str, value: str) -> str:
return value.strip()