-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Simplify setting dynamic default values #866
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
Comments
I'm hesitant about pseudo types, without reading the docs it's not clear what this does. What we could do is just is the function as the default/initial value? Then unless the type of the field was This would not be completely backwards, but I think it would be more intuitive. |
This would work as well! The main idea would be to reduce the amount of boilerplate code required for this type of usage. |
I think this might be better suited as a keyword argument to Schema (or Field now), or similar. That’s how this functionality is handled by both attrs and dataclasses. |
agreed. |
#1210 will implement For use of |
Since the documentation still points here as the place to comment on the design of the I would like to suggest permitting the argument name |
The name |
I didn't ask why it is the way it is. I didn't argue against having I suggested also having |
Ok sure, I'm still 👎🏽 on adding aliases for arguments/keywords, no good reason to add the additional complexity and documentation. from pydantic import Field
class ErgonomicField(Field):
def __init__(*args, **kwargs):
kwargs['default_factory'] = kwargs.pop('factory', None)
super().__init__(*args, **kwargs) |
Yeah I don't love aliases either, but aliases are a good solution for backwards-compatibly migrating to a better name, and this is right in that middle ground of very minor but permeating improvement that is rarely worth doing on a case-by-case basis in a project, but would gradually ripple a slight benefit across many projects if done upstream. |
I do totally sympathize with the resistance. I do the same thing when people bring suggested changes to any of my repos - I don't like messing up and growing my public interfaces with changes unless they seem like clear strict improvements, especially if it doesn't feel like an extremely clear win, especially if it feels like it can be trivially layered on by the user. But I do think |
Let me know if I am in the wrong place, I came across this thread posing this question and have a question about v2 Is there a way to allow a default_factory to access other values so the field can be derived from other values? Or is this the sort of thing that a process working with a pydantic class is supposed to handle (eg, we dont want to support derived data in the interest of keeping the class less complex) What I have now works as intended (see the SO question), but I am wondering if there is or should be a more idiomatic/explicit way to do this? In my mind it would look something like class DynamicValueModel(BaseModel):
field_1: str
assigned_id: str
@validator('assigned_id', derived=True)
def hash(val, values):
return hash(values['field_1'])
DynamicValueModel(assigned_id='oops_lol')
# raises ValidationException or ValueError
# 'Cannot assign value to derived field!
|
Is the default_factory expected to be triggered for None, empty("") values of string? If the field doesn't come in data then the default_facotry gets invoked, I was expecting to do the same in cases of None and empty string (explicitly) as the construct of Python variable foo or 'bar' would yield 'bar' in cases of foo being None or empty string variable. |
Is there any way to provide an argument to default_factory callable object?
|
use |
I was going to suggest partial as well, but I think, the real question from @personage-hub lies in his example: "Is there a way to provide model field as an argument to Quick answer: no. You can achieve the effect you're looking for via |
field-with-dynamic-default-value Hi, I wonder if relevant: default_factory of pydantic's Field not used when included in response_model |
is it correctly conceived that the value in default_factory generates once when importing the model? Then how is this different from just default=func()? |
Not quite. You can quickly test this by using functions that return different value: from datetime import datetime
from pydantic import BaseModel
from pydantic import Field
_counter = 0
def factory():
global _counter
try:
return _counter
finally:
_counter += 1
class Model(BaseModel):
counter: int = Field(default_factory=factory)
timestamp: datetime = Field(default_factory=datetime.utcnow)
for i in range(3):
print(Model()) |
Uh oh!
There was an error while loading. Please reload this page.
Feature Request
Please complete:
Feature Request
Currently, if I want to have a dynamic default value, it has to be done the following way:
This is fine for cases where actual validation has to be provided, however, in many cases like the one portrayed below, this leads to unnecessary code, especially if there are multiple dynamically set values. For instance, a timestamp and an id.
It would be great to be able to replace this usage pattern by a pydantic field called
Dynamic
for instance such that one can pass a callable as a default value. This would look like this:I don't expect that this would need to modify any existing functionalities. Probably just a need to create some sort of wrapper.
The text was updated successfully, but these errors were encountered: