marshmallow-oneofschema
marshmallow-oneofschema copied to clipboard
Pass constructor arguments to new schema instances
Type specific schemas don't respect excludes passed to OneOfSchema
.
This adds an __init__
method to the OneOfSchema
class so the instantiation arguments can be saved and passed to the type specific schemas when they are created.
👍 Could really use this!
Closing this, as it has gone stale. Feel free to re-open if this is still relevant.
@sloria This is a PR. Rather than closing this as a stale issue, shouldn't you evaluate the PR and the corresponding test?
My availability for reviewing PRs for this project has been quite low, unfortunately. I close stale PRs to reduce the maintenance burden. My thought is that if the PRs are still relevant, the author will either re-make the PR or someone will speak up, which you've just done.. so I'll re-open 😅
Any updates on this?
I am encountering this problem because I want to do this:
from marshmallow_oneofschema import OneOfSchema
from marshmallow import Schema, fields
class BaseSchema(Schema):
type = fields.Str()
status = fields.Str()
class ChildOneSchema(BaseSchema):
child_one_attr = fields.Str()
class ChildTwoSchema(BaseSchema):
child_two_attr = fields.Str()
class ChildSchema(OneOfSchema):
type_field = "type"
type_schemas = {
"child_one": ChildOneSchema,
"child_two": ChildTwoSchema
}
ChildSchema(only=("status",)).load({"type": "child_one", "status": "updated"})
which raises ValueError: Invalid fields for <ChildSchema(many=False)>: {'status'}.
Note: The PR in its current form would still raise this ValueError because "only" would get passed to the parent Schema, where the field isn't defined.
So it might need to be updated as:
def __init__(self, *args, **kwargs):
self._schema_args = args
self._schema_kwargs = kwargs
super().__init__(
many=kwargs.get("many", False),
partial=kwargs.get("partial", False),
context=kwargs.get("context", {})
)
As a workaround I am currently using:
from marshmallow_oneofschema import OneOfSchema as _OneOfSchema
class OneOfSchema(_OneOfSchema):
def __init__(self, *args, **kwargs):
self._init_args = args
self._init_kwargs = kwargs
# Init with attrs required by OneOfSchema
super().__init__(
many=kwargs.get("many", {}),
partial=kwargs.get("partials", {}),
context=kwargs.get("context", {})
)
@property
def type_schemas(self):
_map = getattr(self, "type_schema_map")
class _Getter:
@staticmethod
def get(key):
return _map[key](*self._init_args, **self._init_kwargs)
return _Getter