-
Notifications
You must be signed in to change notification settings - Fork 130
Support constrained type validations #176
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
Conversation
- Switches to using a uint64_t for a bitmask. On 64bit platforms this shouldn't result in increased memory usage, since these types already had to be 64 bit aligned anyway. - Moves to using a union to contain type details, instead of a `void *`. With these changes the TypeNode structure is now able to contain all the constraint information we'll eventually want to encode in it.
Adds a `Meta` object for holding extra metadata for a specific TypeNode.
Also sets up framework for other constraints.
Instead of having a single callback after decoding, this moves the type-specific checks to be called directly from the type-specific decoding routines. This mainly speeds up numeric constraint checking, and also allows msgpack length constraints to happen _before_ the object is decoded. Also fixes a bug in constraints on dict keys.
|
cc @adriangb. This is part of what you asked for. We still don't integrate with the |
|
First thing I'll say is that this is amazing. The C part is way over my head. But it's really cool that that you got so much of this working at once. w.r.t. annotated-types, I'm curious to hear the cons to integrating with it. I can imagine several, but I want to make sure we're on the same page as to which before I try to think of ways to mitigate them.
From the developers perspective or the user's? I definitely understand from a developers perspective, but I think it'd be transparent for a user's perspective. Also were you thinking of having msgspec understand annotated-types annotations, having it create annotated-types annotations (via |
Thanks! It's been fun to work on. There's some nuance to making these validations fast, but I'm really happy with how this has turned out.
I'd be open to making
There are two main concerns: Multiple ways of spelling the same thing.I want
There's also some incompatibilities in meaning that might trip a user up ( These are surmountable issues given proper documentation, but it'd require some work to present in a clear and concise way. Complicated implementationI want Neither of these issues is a for-sure "no", but I'm hesitant to spend time on this for now until more users ask for it. |
|
Not sure why coverage is failing, if you look at the diff, all of this patch is covered 🤷. Merging! |
This adds support for constrained types, implementing the following constraints from json-schema:
ge,gt,le,lt, andmultiple_ofcorrespond tominimum,exclusiveMinimum,maximum,exclusiveMaximum, andmultipleOfrespectivelypatterncorresponds topatternmin_lengthandmax_lengthcorrespond tominLength/maxLengthorminItems/maxItemsorminProperties/maxPropertiesdepending on if the annotated type is a string, sequence, or mapping.Constraints are added by wrapping a type with
Annotated, and the specialmsgspec.Metaannotation. This is nice, since it works natively withmypyorpyright, and can be applied anywhere in the type hierarchy, not just on a struct field. These can be used to build up some fairly complicated validations.For example, here we define a type with:
xthat takes a list of at least 3 integers greater than or equal to 0ythat takes a string matching a regex for a valid unix usernameValidation happens during decoding, and except for the
patternvalidation has negligible overhead. Users should feel comfortable adding constraints to types as needed without worrying about performance impacts.Errors are raised for values not matching the specified constraints, just as they are for value not matching the specified types:
The
Metaobjects also contain support for json-schema metadata annotations (title,description, ...), but currently nothing is done with it. Generation of a json-schema spec from a type (#125) will happen in a follow-up PR.Fixes #154 (kind of). I'm reading the bulk of that issue as "support value constraints", which this adds. The remaining bit of supporting the annotated-types library isn't done, and I'm not 100% sure I want to support it yet. I'll open a follow-up issue. to address that, rather than continuing discussion in #154.
Still needs docs, but otherwise this should be done.