-
Notifications
You must be signed in to change notification settings - Fork 252
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 support for unpacked TypedDict
to type hint variadic keyword arguments in ArgumentsValidator
#1451
Conversation
CodSpeed Performance ReportMerging #1451 will not alter performanceComparing Summary
|
None => None, | ||
}; | ||
|
||
if var_kwargs_mode == VarKwargsMode::UnpackedTypedDict && var_kwargs_validator.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'm wondering if we should also check that var_kwargs_validator
is a TypedDictValidator
?
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 don't think you need to, given that you have the conditional checks in pydantic
.
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.
Making it a TypedDictValdiator
statically (at build time) would allow for efficiency gains (by avoiding the dispatch via CombinedValidator
).
But I wonder, are there cases where it can be wrapped in a function-after validator (e.g. model_validator
)?
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.
Making it a
TypedDictValdiator
statically (at build time) would allow for efficiency gains (by avoiding the dispatch viaCombinedValidator
).
The thing is (as described here) var_kwargs_validator
is used for both uniform
and unpacked-typed-dict
modes.
But I wonder, are there cases where it can be wrapped in a function-after validator (e.g.
model_validator
)?
only config can be attached to typed dicts iirc, and it still results in a typed dict schema.
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.
You could have
#[derive(Debug, PartialEq)]
enum VarKwargsMode {
Uniform(CombinedValidator),
UnpackedTypedDict(TypedDictValidator),
}
... and replace the FromStr
implementation with a bespoke function like from_string_and_validator
or similar.
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.
Will leave this as an optimization for later, going to approve for now 👍
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.
See #1457
TypedDict
for **kwargs
TypedDict
to type hint variadic keyword arguments with @validate_call
TypedDict
to type hint variadic keyword arguments with @validate_call
TypedDict
to type hint variadic keyword arguments in the ArgumentsValidator
TypedDict
to type hint variadic keyword arguments in the ArgumentsValidator
TypedDict
to type hint variadic keyword arguments in ArgumentsValidator
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.
Looking great thus far! A couple of rust syntax suggestions + potentially one constant change.
python/pydantic_core/core_schema.py
Outdated
var_kwargs_mode: The validation mode to use for variadic keyword arguments. If `'single'`, every value of the | ||
keyword arguments will be validated against the `var_kwargs_schema` schema. If `'unpacked-typed-dict'`, | ||
the `schema` argument must be a [`typed_dict_schema`][pydantic_core.core_schema.typed_dict_schema] |
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.
What if instead of single we did uniform? Don't want to bikeshed here too much, but I was a bit confused by single on its own.
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.
Yes I'm not too happy with name either. uniform seems better, although there might be an even more explicit name, I'll think about it.
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.
uniform
seems good to me 👍
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 wonder about whether to handle uniform
via the "extras" of the typed dict schema (if such a thing exists) and have simpler code here (i.e. no need for mode, just always require typed dict schema). Maybe a little breaking, though?
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.
There's a extras_schema
key in the TypedDictSchema
, but it is not used currently. For Pydantic models, we support:
class Model(BaseModel):
__pydantic_extra__: dict[str, int]
But we don't for typed dicts. I believe it's best to wait for https://peps.python.org/pep-0728/, this will probably completely change how we handle extra keys for typed dicts currently.
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.
Sounds good. We should probably start validating extra keys as well, just a side note :).
None => None, | ||
}; | ||
|
||
if var_kwargs_mode == VarKwargsMode::UnpackedTypedDict && var_kwargs_validator.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 don't think you need to, given that you have the conditional checks in pydantic
.
Co-authored-by: Sydney Runkle <[email protected]>
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.
Overall LGTM with some brief thoughts...
python/pydantic_core/core_schema.py
Outdated
var_kwargs_mode: The validation mode to use for variadic keyword arguments. If `'single'`, every value of the | ||
keyword arguments will be validated against the `var_kwargs_schema` schema. If `'unpacked-typed-dict'`, | ||
the `schema` argument must be a [`typed_dict_schema`][pydantic_core.core_schema.typed_dict_schema] |
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.
uniform
seems good to me 👍
None => None, | ||
}; | ||
|
||
if var_kwargs_mode == VarKwargsMode::UnpackedTypedDict && var_kwargs_validator.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.
Making it a TypedDictValdiator
statically (at build time) would allow for efficiency gains (by avoiding the dispatch via CombinedValidator
).
But I wonder, are there cases where it can be wrapped in a function-after validator (e.g. model_validator
)?
python/pydantic_core/core_schema.py
Outdated
var_kwargs_mode: The validation mode to use for variadic keyword arguments. If `'single'`, every value of the | ||
keyword arguments will be validated against the `var_kwargs_schema` schema. If `'unpacked-typed-dict'`, | ||
the `schema` argument must be a [`typed_dict_schema`][pydantic_core.core_schema.typed_dict_schema] |
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 wonder about whether to handle uniform
via the "extras" of the typed dict schema (if such a thing exists) and have simpler code here (i.e. no need for mode, just always require typed dict schema). Maybe a little breaking, though?
Co-authored-by: David Hewitt <[email protected]>
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.
Great work @Viicos, looking forward to having this feature!
None => None, | ||
}; | ||
|
||
if var_kwargs_mode == VarKwargsMode::UnpackedTypedDict && var_kwargs_validator.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.
Will leave this as an optimization for later, going to approve for now 👍
Change Summary
Part of pydantic/pydantic#9619.
Related issue number
Checklist
pydantic-core
(except for expected changes)