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
Raise ValidationError
for unhashable discriminator values
#5132
Raise ValidationError
for unhashable discriminator values
#5132
Conversation
a7e96d3
to
221f9ed
Compare
The GitHub workflow failed to start for this. If it's not possible to re-run the failed jobs, let me know and I'll push an update to re-trigger the workflow. |
Thanks @kurtmckee for this. The fix LGTM. The only concern is that it is a change in old behavior(raising
I think it's not needed. @samuelcolvin, @dmontagu what do you think? |
I think this is a very good point. I'm definitely keen to make sure this doesn't happen in v2, but I'd be a bit nervous to change the error handling in older versions unless this was causing issues that couldn't be properly handled by catching a ConfigError in the right place. |
Agree! |
It's my understanding that This appears to be a |
@kurtmckee I agree that what you are describing is better behavior, the main point is that if someone is already handling it as a ConfigError, it could end up breaking their code if they upgrade. If we were still planning additional releases to pydantic v1 this would definitely make sense as an addition to a 1.11.0 release, but we aren't planning to do that now (instead, doing a 2.0.0). That said, I recognize that this is arguably a bugfix worthy of inclusion in a 1.10.X release; I'll defer to @samuelcolvin's opinion on what's the best path forward. |
Thought about this more and I think you are right about everything @kurtmckee. Going to merge this then do a new release. |
Thank you @dmontagu, and thank you all for reviewing and discussing! |
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [pydantic](https://togithub.com/pydantic/pydantic) | `==1.10.5` -> `==1.10.6` | [![age](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/compatibility-slim/1.10.5)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/confidence-slim/1.10.5)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>pydantic/pydantic</summary> ### [`v1.10.6`](https://togithub.com/pydantic/pydantic/releases/tag/v1.10.6): 2023-03-02 [Compare Source](https://togithub.com/pydantic/pydantic/compare/v1.10.5...v1.10.6) #### What's Changed - Implement logic to support creating validators from non standard callables by using defaults to identify them and unwrapping `functools.partial` and `functools.partialmethod` when checking the signature, [#​5126](https://togithub.com/pydantic/pydantic/issues/5126) by [@​JensHeinrich](https://togithub.com/JensHeinrich) - Fix mypy plugin for v1.1.1, and fix `dataclass_transform` decorator for pydantic dataclasses, [#​5111](https://togithub.com/pydantic/pydantic/issues/5111) by [@​cdce8p](https://togithub.com/cdce8p) - Raise `ValidationError`, not `ConfigError`, when a discriminator value is unhashable, [#​4773](https://togithub.com/pydantic/pydantic/issues/4773) by [@​kurtmckee](https://togithub.com/kurtmckee) #### New Contributors - [@​mrmammadov](https://togithub.com/mrmammadov) made their first contribution in [pydantic/pydantic#5074 - [@​JensHeinrich](https://togithub.com/JensHeinrich) made their first contribution in [pydantic/pydantic#5127 - [@​kurtmckee](https://togithub.com/kurtmckee) made their first contribution in [pydantic/pydantic#5132 **Full Changelog**: pydantic/pydantic@v1.10.5...v1.10.6 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/allenporter/pyrainbird). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjM0LjE1OS4yIn0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [pydantic](https://togithub.com/pydantic/pydantic) | `==1.10.5` -> `==1.10.6` | [![age](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/compatibility-slim/1.10.5)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.6/confidence-slim/1.10.5)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>pydantic/pydantic</summary> ### [`v1.10.6`](https://togithub.com/pydantic/pydantic/releases/tag/v1.10.6): 2023-03-02 [Compare Source](https://togithub.com/pydantic/pydantic/compare/v1.10.5...v1.10.6) ##### What's Changed - Implement logic to support creating validators from non standard callables by using defaults to identify them and unwrapping `functools.partial` and `functools.partialmethod` when checking the signature, [#​5126](https://togithub.com/pydantic/pydantic/issues/5126) by [@​JensHeinrich](https://togithub.com/JensHeinrich) - Fix mypy plugin for v1.1.1, and fix `dataclass_transform` decorator for pydantic dataclasses, [#​5111](https://togithub.com/pydantic/pydantic/issues/5111) by [@​cdce8p](https://togithub.com/cdce8p) - Raise `ValidationError`, not `ConfigError`, when a discriminator value is unhashable, [#​4773](https://togithub.com/pydantic/pydantic/issues/4773) by [@​kurtmckee](https://togithub.com/kurtmckee) ##### New Contributors - [@​mrmammadov](https://togithub.com/mrmammadov) made their first contribution in [pydantic/pydantic#5074 - [@​JensHeinrich](https://togithub.com/JensHeinrich) made their first contribution in [pydantic/pydantic#5127 - [@​kurtmckee](https://togithub.com/kurtmckee) made their first contribution in [pydantic/pydantic#5132 **Full Changelog**: pydantic/pydantic@v1.10.5...v1.10.6 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/allenporter/flux-local). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xNjAuMCIsInVwZGF0ZWRJblZlciI6IjM0LjE2MC4wIn0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
As reported in #4773, unhashable discriminator values are incorrectly rejected with a
ConfigError
, rather than aValidationError
.The bug
The current code catches a
TypeError
at line 1121 and converts it to aConfigError
:pydantic/pydantic/fields.py
Lines 1120 to 1127 in 7f3b754
This can happen when
self.sub_fields_mapping
isNone
, in which case theConfigError
correctly suggests calling.update_forward_refs()
. For reference, the exact error is:However, a
TypeError
can also be raised whenself.sub_fields_mapping
is a dictionary butdiscriminator_value
is an unhashable type. For reference, the exact error is:The fix
This PR addresses the bug by first checking whether
self.sub_fields_mapping
is None. If it is, then aConfigError
is raised as expected. Then, bothKeyError
andTypeError
are interpreted as an invalid discriminator value.Please let me know if this needs to be separately forward-ported to
main
.Thanks for your work on pydantic!
Fixes #4773