-
Notifications
You must be signed in to change notification settings - Fork 44
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
Fix cases where validator use isn't robust to model changes #392
Comments
Default values:User wants to specify Old way:field: Tuple[float, float, float] = None
@pd.validator('field')
def set_field(cls, val, values):
if field is not None:
return field
return fn(values.get('something_else')) Issues:
Solutions:
field: Tuple[float, float, float] = None
@property
def _field(self):
if self.field is not None:
return self.field
return fn(self.something_else) However, this will require replacing all instances of
field: Tuple[float, float, float] = None
@pd.root_validator
def set_field(cls, values):
if values.get('field') is not None:
return values
values['field'] = fn(values.get('something_else'))
return values However, there is a fundamental problem here in that My opinionWe should do property approach, since the 2nd option means that |
Stale ValidatorsOften times, we want to validate a Old wayfield: Tuple[float, float, float] = None
# just check if passes validation
@validator
def validate_field(cls, val, values):
if fn(values.get('something_else')):
raise SetupError
return val
# set a new value for val
@validator
def validate_field(cls, val, values):
return fn(values.get('something_else')): Issues
Solutions
field: Tuple[float, float, float] = None
# just check if passes validation
@root_validator
def validate_field(cls, values):
if fn(values.get('something_else')):
raise SetupError
return values
# set a new value for val
@root_validator
def validate_field(cls, values):
values['field'] = fn(values.get('something_else')): my opinionI see no problem with this except:
|
Fields dont pass initial type validationAn annoying thing about pydantic is that the validators are run even if the initial type validation fails. In this case, the field: Tuple[float, float, float] = None
# just check if passes validation
@root_validator
def validate_field(cls, values):
field = values.get('field')
values['field2'] = field[0]**2 + field[1]**2 + field[2]**2
return values If I try to construct Model(field='blah') I’ll get one validation error because Old WayWe simply dont handle this, therefore users might get this obscure error if one of their fields is entered incorrectly. SolutionsAdd a field: Tuple[float, float, float] = None
@root_validator(pre=True)
def check_field_not_none(cls, values):
for field in cls.__fields__:
if field not in values:
raise ValidationError(f'field {field} didnt pass initial validation.')
# this wont be run because the above validator failed first
@root_validator
def validate_field(cls, values):
field = values.get('field')
values['field2'] = field[0]**2 + field[1]**2 + field[2]**2
return values IssuesWe’ll still get two validation errors. One for the type check and one for the |
I think you could try |
One thing that worries me about this is if all validators will be run when any value is changed. For example I change |
This seems like a twist to the more usual use of properties, where the private value is the stored one and the property is exposed.
I don't know if there's any known issues with that just apart from the fact that it looks a bit weird, but one thing that comes to mind is that the user will have a hard time knowing what the default value is. Instead of being able to check |
Validators used to set unspecified fields
Near2Far.origin
Near2Far.medium
Near2Far.currents
App.app
Port.mode_indices
Monitor.colocate
Planar.length
,PolySlab.slab_bounds
,PolySlab.set_center
,PolySlab.set_length
Validators aren't triggered when all dependencies change (make root validators?)
ModeSpec.bend_axis_given
doesn't get called ifbend_radius
changes.TimeMonitor.stop_greater_than_start
doesn't get called ifstart
changes.validators.validate_mode_objects_symmetry
validators.assert_unique_names
validators.assert_objects_in_sim_bounds
Simulation
validators?The text was updated successfully, but these errors were encountered: