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
Handle X | Y union in GenericModel #4977
Handle X | Y union in GenericModel #4977
Conversation
please review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a good start.
@dmontagu what do you think?
tests/test_generics.py
Outdated
@@ -853,6 +853,17 @@ class Model(GenericModel, Generic[T]): | |||
# example) | |||
assert replace_types(list[Union[str, list, T]], {T: int}) == list[Union[str, list, int]] | |||
|
|||
if sys.version_info >= (3, 10): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
separate test with skipif
please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, please can you add a standalone test for unions on a generic model.
There should be examples elsewhere of testing |
style unions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
separate test with
skipif
please.
done
also, please can you add a standalone test for unions on a generic model.
There should be examples elsewhere of testing
|
style unions.
kinda done though i don't have a feeling that that's enough and might add some more later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good, let me know when it's done.
pydantic/generics.py
Outdated
# PEP-604 syntax (Ex.: list | str) is represented with a types.UnionType object that does not have __getitem__. | ||
# We also cannot use isinstance() since we have to compare types. | ||
if sys.version_info >= (3, 10) and origin_type is types.UnionType: # noqa: E721 | ||
return functools.reduce(operator.or_, resolved_type_args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems like a slightly weird approach, could we use pydantic.typing.convert_generics
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a closer look at convert_generics, not sure how it fits, but i guess at least it can be recreated with typing._UnionGenericAlias
as it's done in convert_generics
.
Co-authored-by: ⬢ Samuel Colvin <s@muelcolvin.com>
please update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, @dmontagu would appreciate if you could confirm you're happy with this as "king of generics".
please review.
@thenx Looks great. The only one thing I'd like to request: could we add a test that there are no issues with order-of-arguments caching? My main concern is that since Basically just copying this test but using the pydantic/tests/test_generics.py Lines 718 to 735 in 0bc7cd3
No need to copy the (currently skipped) test below. |
LGTM, @thenx the PR is still in draft, if you think it's ready to be merged, please mark it as "ready for review". |
[![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.4` -> `==1.10.5` | [![age](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/compatibility-slim/1.10.4)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/confidence-slim/1.10.4)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>pydantic/pydantic</summary> ### [`v1.10.5`](https://togithub.com/pydantic/pydantic/releases/tag/v1.10.5): (2023-02-15) [Compare Source](https://togithub.com/pydantic/pydantic/compare/v1.10.4...v1.10.5) - Fix broken parametrized bases handling with `GenericModel`s with complex sets of models, [#​5052](https://togithub.com/pydantic/pydantic/issues/5052) by [@​MarkusSintonen](https://togithub.com/MarkusSintonen) - Invalidate mypy cache if plugin config changes, [#​5007](https://togithub.com/pydantic/pydantic/issues/5007) by [@​cdce8p](https://togithub.com/cdce8p) - Fix `RecursionError` when deep-copying dataclass types wrapped by pydantic, [#​4949](https://togithub.com/pydantic/pydantic/issues/4949) by [@​mbillingr](https://togithub.com/mbillingr) - Fix `X | Y` union syntax breaking `GenericModel`, [#​4146](https://togithub.com/pydantic/pydantic/issues/4146) by [@​thenx](https://togithub.com/thenx) - Switch coverage badge to show coverage for this branch/release, [#​5060](https://togithub.com/pydantic/pydantic/issues/5060) by [@​samuelcolvin](https://togithub.com/samuelcolvin) #### New Contributors - [@​thenx](https://togithub.com/thenx) made their first contribution in [pydantic/pydantic#4977 - [@​mbillingr](https://togithub.com/mbillingr) made their first contribution in [pydantic/pydantic#4963 - [@​MarkusSintonen](https://togithub.com/MarkusSintonen) made their first contribution in [pydantic/pydantic#5052 **Full Changelog**: pydantic/pydantic@v1.10.4...v1.10.5 </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:eyJjcmVhdGVkSW5WZXIiOiIzNC4xNDMuMSIsInVwZGF0ZWRJblZlciI6IjM0LjE0My4xIn0=--> 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.4` -> `==1.10.5` | [![age](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/compatibility-slim/1.10.4)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/pydantic/1.10.5/confidence-slim/1.10.4)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>pydantic/pydantic</summary> ### [`v1.10.5`](https://togithub.com/pydantic/pydantic/releases/tag/v1.10.5): (2023-02-15) [Compare Source](https://togithub.com/pydantic/pydantic/compare/v1.10.4...v1.10.5) - Fix broken parametrized bases handling with `GenericModel`s with complex sets of models, [#​5052](https://togithub.com/pydantic/pydantic/issues/5052) by [@​MarkusSintonen](https://togithub.com/MarkusSintonen) - Invalidate mypy cache if plugin config changes, [#​5007](https://togithub.com/pydantic/pydantic/issues/5007) by [@​cdce8p](https://togithub.com/cdce8p) - Fix `RecursionError` when deep-copying dataclass types wrapped by pydantic, [#​4949](https://togithub.com/pydantic/pydantic/issues/4949) by [@​mbillingr](https://togithub.com/mbillingr) - Fix `X | Y` union syntax breaking `GenericModel`, [#​4146](https://togithub.com/pydantic/pydantic/issues/4146) by [@​thenx](https://togithub.com/thenx) - Switch coverage badge to show coverage for this branch/release, [#​5060](https://togithub.com/pydantic/pydantic/issues/5060) by [@​samuelcolvin](https://togithub.com/samuelcolvin) #### New Contributors - [@​thenx](https://togithub.com/thenx) made their first contribution in [pydantic/pydantic#4977 - [@​mbillingr](https://togithub.com/mbillingr) made their first contribution in [pydantic/pydantic#4963 - [@​MarkusSintonen](https://togithub.com/MarkusSintonen) made their first contribution in [pydantic/pydantic#5052 **Full Changelog**: pydantic/pydantic@v1.10.4...v1.10.5 </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:eyJjcmVhdGVkSW5WZXIiOiIzNC4xNDMuMSIsInVwZGF0ZWRJblZlciI6IjM0LjE0My4xIn0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Change Summary
The root cause of the issue is that X | Y has type types.UnionType which does not have __getitem__. This makes
pydantic.generics.replace_types
to fail withTypeError: 'type' object is not subscriptable
.In this PR we handle types.UnionType separately.
Related issue number
fix #4146
Peculiarities
Do not compare types, use 'isinstance()' (E721)
Checklist
changes/<pull request or issue id>-<github username>.md
file added describing change(see changes/README.md for details)