Properly set Config in create_model#320
Conversation
Set the Config attribute in create_model, so it is found by the MetaModel.
Codecov Report
@@ Coverage Diff @@
## master #320 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 13 13
Lines 1761 1771 +10
Branches 340 344 +4
=====================================
+ Hits 1761 1771 +10 |
samuelcolvin
left a comment
There was a problem hiding this comment.
Thanks for the changes, overall this looks like a good idea. Thanks.
There are a few changes here that require tests:
- validator inheritance in the standard model inheritance case, with and without further subsequent validators on the same field in inheriting models
- validators in
create_model
| return validators | ||
|
|
||
|
|
||
| def inherit_validators(base_validators, validators): |
There was a problem hiding this comment.
better if this method returns validators so it's clear what's going on.
|
|
||
| def inherit_validators(base_validators, validators): | ||
| for field, field_validators in base_validators.items(): | ||
| validators.setdefault(field, []).extend(field_validators) |
There was a problem hiding this comment.
better to be explicit
if field in validators:
validators[field] += field_validators
else:
validators[field] = field_validators| annotations[f_name] = f_annotation | ||
| fields[f_name] = f_value | ||
|
|
||
| namespace = {"__annotations__": annotations, "__validators__": vg.validators} |
| namespace = {'config': config, '__fields__': fields} | ||
| # f_validators = vg.get_validators(f_name) | ||
| # if f_validators: | ||
| # setattr(f_value, "__validator_config", f_validators) |
There was a problem hiding this comment.
Is this definitely not required? if so please remove.
There was a problem hiding this comment.
I'll strip out some more incorrect validator logic.
| ignore_extra = False | ||
| allow_extra = False | ||
|
|
||
| model = create_model("FooModel", foo=(int, ...), __config__=Config) |
There was a problem hiding this comment.
I haven't got around to finding a way to lint this, but pydantic should use single quotes always unless single quotes are used in the string.
There was a problem hiding this comment.
We struggled with this with black as well. Ended up just using the Black convention.
samuelcolvin
left a comment
There was a problem hiding this comment.
Still needs the extra tests mentioned above, otherwise looking good.
|
|
||
| def inherit_validators(base_validators, validators): | ||
| for field, field_validators in base_validators.items(): | ||
| if field in validators: |
There was a problem hiding this comment.
if you want to do it this way
if field not in validators:
validators[field] = []
validators[field] += field_validatorsThere was a problem hiding this comment.
This is to avoid mutating the validators in the base classes.
a = []
b = a
b += [1]
assert a == [1]There was a problem hiding this comment.
what I've suggested has exactly the same effect as what you have now, just avoids duplicated lines.
|
|
||
| config = inherit_config(namespace.get('Config'), config) | ||
| vg = ValidatorGroup(_extract_validators(namespace)) | ||
| inherit_validators(_extract_validators(namespace), validators) |
|
@samuelcolvin I've extended the two existing validation test using inheritance. Is that sufficient or did you have something further in mind? |
|
Definitely requires more tests, from above:
|
|
I've added some tests for child classes using validators from parent classes, to complement the existing tests for adding validation in child classes.
Do you have specific test cases in mind that aren't covered by |
| Child(a='snap') | ||
|
|
||
|
|
||
| def test_validate_parent_all(): |
There was a problem hiding this comment.
looks like this test and the one at the bottom should swap name, so this becomes test_validate_child_all.
yes, a test where we have a model with validators, then us that as a base in I'm not saying it'll add any specific coverage (it can't since we have 100% coverage), but since we think that should be possible we should have a test of doing it. |
I've added some detail around the |
|
my mistake, sorry. LGTM, I'll look full and merge early next week. |
|
great, thank you very much. Will deploy in a week or two, unless you need it urgently in which case let me know and I'll deploy sooner. |
|
Thank you - the review process was definitely useful! If you could manage to release sooner it would save me the work of deploying an internal fork. |
|
Will do. |
|
done. |
* uprev pyo3 to 0.17.3 * hopefully speed up ValidationError.errors()
Change Summary
Set the Config attribute in create_model, so it is found by the
MetaModel. Pushes the field and validator configuration into the
metaclass.
Related issue number
None
Performance Changes
Not run.
Checklist
HISTORY.rsthas been updated#<number>@whatever