-
-
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
Can/should marshmallow include pre-built validates_schema methods? #1988
Comments
I would consider mutually exclusive fields to be discriminators for polymorphism. As far as I can tell none of the community polymorphism libraries are quite as concise as your examples, so they are probably not going to save you any lines over just rolling schema validators as needed. Another syntax you might consider is a custom base schema with a field registry. class MySchema(MutexSchema):
foo = Mutex(fields.String())
bar = Mutex(fields.String()) A more complicated use case you might consider is supporting mutex groups: alpha = Mutex()
beta = Mutex()
# (foo XOR (bar AND baz)) AND (fizz XOR buzz)
class MySchema(MutexSchema):
foo = alpha(fields.String())
bar = alpha(fields.String())
baz = alpha(fields.String(), group='bar')
fizz = beta(fields.String())
buzz = beta(fields.String()) I generally try to build extensions as modules in my project, work out any kinks after using it a few times, then publish it as a community module once it has stabilized. That actually reminds me, I have a community module for a schema meta decorator I need to publish soon. 😄 |
Yep, I agree that it's a kind of polymorphism! It can get tricky to model with mutex, since the number of variants is equal to the product of sizes of mutex groups, which can get a bit big.
This looks very cool. I'll look into that for my own purposes for sure; thanks for sharing the idea! It could also possibly be pulled from field I don't want to focus overly much of mutex groups -- that's a motivating example, but not my only area of interest. I realized that it isn't very smooth, with the current interfaces, to share a schema-level validator as something reusable, even within my own project. To me, that looks like a gap in the API, but it might not be worth filling. I just thought of this way of adding it to the core: class MySchema(Schema, validate=MutuallyExclusive(["foo", "bar"])):
foo = fields.String()[
bar = fields.String() That has really nice symmetry with the |
That's not a pattern I have seen in other libraries, so I would probably avoid it. The schema decorator syntax would work, but you still have to make the referenced fields optional. Communicating that behavior explicitly by wrapping field attributes has the benefit of avoiding rebuilding the schema with instrumented fields. You could make a decorator for injecting schema validation methods using the same pattern I used for my meta decorator. https://github.com/deckar01/marshmallow-meta/blob/master/src/marshmallow_meta/__init__.py def schema_validator(**validators):
def wrapper(schema):
return type(schema.__name__, (schema,), validators)
return wrapper
@schema_validator(mutex=MutuallyExclusive(["foo", "bar"])
class MySchema(Schema):
... |
I have a case in which I'm looking at adding a mutually exclusive set of fields to a schema.
It would be awesome if I could define this behavior with
marshmallow.validate.MutuallyExclusive(["foo", "bar"])
, and I'd be happy to work on an implementation of that. But where would it go and how would users apply it?Unless I've missed/forgotten something, there's no way to provide pre-packaged schema validators for users to apply.
The following could work but is ugly:
What about a class decorator which adds a validator?
Is this worth pursuing? And if so, what is the correct interface to build?
The text was updated successfully, but these errors were encountered: