-
-
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
Add extra
argument to load/dump for extensions
#1725
base: dev
Are you sure you want to change the base?
Conversation
The purpose of `extra` is to allow libraries built on top of `marshmallow` to interact with one another cleanly by providing a space for additional data to be passed which `marshmallow` knows about. In particular, at present the functionality of `marshmallow-sqlalchemy` relies upon adding keyword arguments to `load`, and a proposed refactor of `marshmallow-oneofschema` would not be able to pass through these additional arguments to child schemas. At the crux of this is a desire in `marshmallow-oneofschema` to override the behavior of `_serialize` and `_deserialize` to take advantage of the hooks provided by marshmallow. This would simplify OneOfSchema and provide additional features, but cannot handle the extra arguments added by `marshmallow-sqlalchemy`. One option is for these external libraries to coordinate in order to support one another via some other (indeterminate) mechanism. However, in order for `marshmallow` to support such 3rd-party libraries, the key issue here is that there is no way to take extensible data from `load()` calls and pass it down through to the inner (de)serialization methods. `extra` could be exposed in additional contexts, for example in field loading, hook evaluation, error handling, and so forth. However, the current issue in these third party libraries only requires the addition of `extra` to be passed down to `_deserialize` and `_serialize`. Therefore, this feature addition is restricted to only this context for now. For this particular problem, this will allow a new major version of `marshmallow-oneofschema` to support usage with marshmallow-sqlalchemy something like so: load(..., extra={"child_load_kwargs": {"transient": True}}) which is then unpacked and passed to a child sqlalchemy schema as `load(..., transient=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 didn't inspect thoroughly but the rationale makes sense.
loaded = MySchema().load(data, extra={"side_effect": "foo"}) | ||
assert MySchema.last_deserialize_side_effect == "foo" | ||
assert MySchema.last_serialize_side_effect 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.
I'd clear last_deserialize_side_effect here to make next test more selective.
This seems like a problem that would benefit from opening an issue in |
I almost opened a marshmallow issue to discuss, but thought it would be better to come to the table with some concrete option for how to handle this. If you prefer to discuss in an issue to a PR, I can open one.
|
resolves #1726
I want to make some changes in
marshmallow-oneofschema
to support hooks (currently unsupported) and simplify the code.Although it's just a PR, one of the issues I see with it is that it will not play nicely with
marshmallow-sqlalchemy
and there isn't a trivial way to get the information I need in_deserialize
and_serialize
.I've been thinking about this on and off for a while and this approach is what I came up with.
It involves
marshmallow
being aware that someone might want to extendSchema
by overloading_serialize
and_deserialize
, and a single new parameter toload(s)
anddump(s)
calledextra
. (Name inspired by stdliblogging
's use ofextra
.)Although neither
marshmallow-oneofschema
normarshmallow-sqlalchemy
are part of the core project, they're both important parts of a healthy ecosystem of marshmallow extension packages. Supporting their interplay is valuable.The purpose of
extra
is to allow libraries built on top ofmarshmallow
to interact with one another cleanly by providing a space for additional data to be passed whichmarshmallow
knows about.In particular, at present the functionality of
marshmallow-sqlalchemy
relies upon adding keyword arguments toload
, and a proposed refactor ofmarshmallow-oneofschema
would not be able to pass through these additional arguments to child schemas.At the crux of this is a desire in
marshmallow-oneofschema
to override the behavior of_serialize
and_deserialize
to take advantage of the hooks provided by marshmallow. This would simplify OneOfSchema and provide additional features, but cannot handle the extra arguments added bymarshmallow-sqlalchemy
.One option is for these external libraries to coordinate in order to support one another via some other (indeterminate) mechanism. However, in order for
marshmallow
to support such 3rd-party libraries, the key issue here is that there is no way to take extensible data fromload()
calls and pass it down through to the inner (de)serialization methods.extra
could be exposed in additional contexts, for example in field loading, hook evaluation, error handling, and so forth. However, the current issue in these third party libraries only requires the addition ofextra
to be passed down to_deserialize
and_serialize
. Therefore, this feature addition is restricted to only this context for now.For this particular problem, this will allow a new major version of
marshmallow-oneofschema
to support usage with marshmallow-sqlalchemy something like so:which is then unpacked and passed to a child sqlalchemy schema as
load(..., transient=True)
.In a future version, if
marshmallow-sqlalchemy
started usingextra
instead of added keyword arguments,marshmallow-oneofschema
could pass through theextra
data it received or define other sophisticated behaviors.