Skip to content

PYD-137: Implement PydanticUseDefault error #714

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

Merged
merged 5 commits into from
Jun 29, 2023
Merged

Conversation

adriangb
Copy link
Member

@adriangb adriangb commented Jun 28, 2023

Closes pydantic/pydantic#6268

Selected Reviewer: @dmontagu

@adriangb
Copy link
Member Author

please review

@adriangb
Copy link
Member Author

@davidhewitt any idea why the PyPy jobs are failing? It doesn't seem like it's related to this PR

@codecov-commenter
Copy link

codecov-commenter commented Jun 28, 2023

Codecov Report

Merging #714 (eb673f2) into main (12073b8) will decrease coverage by 0.07%.
The diff coverage is 67.74%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #714      +/-   ##
==========================================
- Coverage   93.71%   93.65%   -0.07%     
==========================================
  Files          99       99              
  Lines       13838    13864      +26     
  Branches       25       25              
==========================================
+ Hits        12968    12984      +16     
- Misses        864      874      +10     
  Partials        6        6              
Impacted Files Coverage Δ
python/pydantic_core/__init__.py 88.57% <ø> (ø)
src/build_tools.rs 81.63% <0.00%> (-0.85%) ⬇️
src/errors/line_error.rs 91.95% <0.00%> (-1.07%) ⬇️
src/errors/mod.rs 92.30% <ø> (ø)
src/validators/mod.rs 97.79% <0.00%> (-0.25%) ⬇️
src/errors/value_exception.rs 88.99% <41.66%> (-5.86%) ⬇️
src/errors/validation_exception.rs 93.92% <100.00%> (+0.07%) ⬆️
src/lib.rs 100.00% <100.00%> (ø)
src/validators/function.rs 91.41% <100.00%> (+0.04%) ⬆️
src/validators/with_default.rs 99.13% <100.00%> (+0.03%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 12073b8...eb673f2. Read the comment docs.

@adriangb adriangb changed the title Implement PydanticUseDefault error PYD-137: Implement PydanticUseDefault error Jun 28, 2023
@linear
Copy link

linear bot commented Jun 28, 2023

PYD-137 v1 -> v2 - Getting default value during validation

If you check this example in v1 there was a way to get default value of the in validation function

basically the goal is if data that is passed equals to empty string - just change it to default value:

class MyModel(BaseModel)
    price: EmptyStrToDefault[int] = 10


obj = MyModel(price="")
assert obj.price == 10

obj = MyModel(price=20)
assert obj.price == 20

what's the way to get this default value in v2 ?

Python, Pydantic & OS Version

pydantic version: 2.0b3
        pydantic-core version: 0.39.0 release build profile
                 install path: .venv2/lib/python3.9/site-packages/pydantic
               python version: 3.9.15 (main, Dec  6 2022, 21:16:57)  [Clang 14.0.0 (clang-1400.0.29.202)]
                     platform: macOS-13.4.1-arm64-arm-64bit
     optional deps. installed: ['typing-extensions']

Selected Assignee: samuelcolvin

@codspeed-hq
Copy link

codspeed-hq bot commented Jun 28, 2023

CodSpeed Performance Report

Merging #714 will degrade performances by 10.88%

Comparing use-default-error (f102425) with main (081cf31)

Summary

❌ 1 regressions
✅ 124 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark main use-default-error Change
test_set_of_ints_core_json_duplicates 4.8 ms 5.4 ms -10.88%

@dmontagu
Copy link
Collaborator

I haven't reviewed this yet, but my understanding is that the purpose here is to provide a way to escape hatch out of a validator of a field with a default value and pass that default value up the validation chain.

I understand that this makes sense in the context of pydantic-core where there is a clear DefaultValidator and we can do exception handling inside it, and it seems reasonable to provide a way to escape-hatch out of that validation in pydantic-core and pretend like you wanted the default all along.

However, I don't think this does a great job of addressing the shortcoming of not having access to FieldInfo in an annotation-based validator — in the context of usage-in-pydantic, it feels weirdly restrictive; while I think this implementation choice makes sense with knowledge of pydantic-core, I worry that that may end up frustrating/unsatisfying to users who really do need access to the FieldInfo (specifically the default) in their validator.

Of course, we can try to solve the have-access-to-field-info problem in a different way later on. But my main concern is if this functionality would be rendered unnecessary when we do that, and we end up stuck with the backwards-compatibility maintenance burden.

But if we want/need this to get v2 released and @samuelcolvin is okay with it .. then I guess I'm fine with the approach.

(I haven't actually read the code yet, just wanted to voice my concern up front.)

Copy link
Collaborator

@dmontagu dmontagu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easy to review, code looks good, but my objections to this as a solution still stand. Given how little code there is though, maybe it's not likely to pose a serious maintenance burden

@adriangb
Copy link
Member Author

adriangb commented Jun 29, 2023

I don't think this does a great job of addressing the shortcoming of not having access to FieldInfo in an annotation-based validator

Just to clarify (you mentioned it but maybe it wasn't clear to others) you can already access cls.model_fields from an @field_validator we are talking exclusively about Annotated-based validators.

That is by design. It's unclear what the semantics are for accessing a FieldInfo: at what point of nesting does it stop being the "current thing". Until we can answer that, I don't think we should make it accessible in function validators that are not directly attached via @field_validator. The reason this is different is that it doesn't introduce any references to the "last field", instead it raises an exception and lets that last field handle it (if it exists). We also already have PydanticOmit and it already interacts with WithDefault validators (hence why this PR is relatively simple).

@samuelcolvin
Copy link
Member

we can do exception handling inside it, and it seems reasonable to provide a way to escape-hatch out of that validation in pydantic-core and pretend like you wanted the default all along.

I think this is a good feature either way, it doesn't preclude adding field info to other validations somehow in the future.

@samuelcolvin samuelcolvin enabled auto-merge (squash) June 29, 2023 14:57
@samuelcolvin samuelcolvin merged commit 16ef703 into main Jun 29, 2023
@samuelcolvin samuelcolvin deleted the use-default-error branch June 29, 2023 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[PYD-137] v1 -> v2 - Getting default value during validation
4 participants