Skip to content
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

Use ParamSpec for classmethod and staticmethod #9771

Merged
merged 3 commits into from
Mar 14, 2023

Conversation

AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Feb 20, 2023

Fixes #7689. Fixes #7134 (as much as we're ever going to fix, anyway). Cc. @NeilGirdhar.

@github-actions

This comment has been minimized.

@AlexWaygood AlexWaygood marked this pull request as ready for review February 20, 2023 16:11
@AlexWaygood
Copy link
Member Author

Links to the primer hits:

These are all somewhat atypical use cases. pydantic is using classmethod directly as an annotation, so will just have to change the number of parameters it has in its classmethod annotations. The sympy error is sort-of a false positive, but can also be worked around.

Pytype crashes on this PR because they don't use typeshed's builtins stub, but I don't think it's worth bugging the pytype maintainers about unless we agree that this is worth doing.

stdlib/builtins.pyi Outdated Show resolved Hide resolved
@github-actions

This comment has been minimized.

Copy link
Contributor

@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

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

lgtm

@AlexWaygood
Copy link
Member Author

AlexWaygood commented Mar 9, 2023

@rchen152, how difficult would the pytype crash be to fix? :)

(There's no particular rush here on this one!)

@rchen152
Copy link
Collaborator

I believe all we need to do is copy the changes to builtins.pyi over to pytype's copy of the stub. I'll give it a try and let you know how it goes.

rchen152 added a commit to google/pytype that referenced this pull request Mar 11, 2023
See python/typeshed#9771 for context.

PiperOrigin-RevId: 515480379
@rchen152
Copy link
Collaborator

The builtins.pyi changes from this PR have been copied to pytype and released in version 2023.03.13.

@AlexWaygood
Copy link
Member Author

The builtins.pyi changes from this PR have been copied to pytype and released in version 2023.03.13.

That seems to have done the trick — thank you very much!

@github-actions
Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

pydantic (https://github.com/samuelcolvin/pydantic)
+ pydantic/_internal/_decorators.py:195: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/_internal/_decorators.py:202: error: Need type annotation for "f_cls"  [var-annotated]
+ pydantic/decorators.py:26: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:48: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:64: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:73: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:82: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:92: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:107: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/decorators.py:131: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]
+ pydantic/main.py:44: error: "classmethod" expects 3 type arguments, but 1 given  [type-arg]

sympy (https://github.com/sympy/sympy)
+ sympy/polys/solvers.py:34: error: Cannot infer type of lambda  [misc]
+ sympy/polys/solvers.py:34: error: Argument 1 to "staticmethod" has incompatible type "Callable[[Any], Any]"; expected "Callable[[Any, Any, Any, Any, Any, Any], Any]"  [arg-type]

discord.py (https://github.com/Rapptz/discord.py)
- discord/ext/commands/cog.py:500: error: Incompatible types in assignment (expression has type "Callable[..., Any]", variable has type "FuncT")  [assignment]
+ discord/ext/commands/cog.py:500: error: Incompatible types in assignment (expression has type "Callable[[VarArg(Any), KwArg(Any)], Any]", variable has type "FuncT")  [assignment]

@AlexWaygood AlexWaygood merged commit 28dd6c1 into main Mar 14, 2023
@AlexWaygood AlexWaygood deleted the staticmethod-paramspec branch March 14, 2023 09:59
@AlexWaygood
Copy link
Member Author

AlexWaygood commented Mar 14, 2023

@samuelcolvin, just to give you a heads-up about this — this changes the stub for classmethod so that it is now generic over two TypeVars and a ParamSpec, whereas previously it was only generic over a single TypeVar. This makes the stub much more precise, but it means you'll probably have to update a few annotations in pydantic with the next mypy release (see the mypy_primer diff just above for details).

@samuelcolvin
Copy link
Contributor

Thanks @AlexWaygood for pinging me.

What's the time frame for this being released?

Also, what's your recommendation for supporting this while keeping support for older versions? I'm a bit confused about where typeshed fits in to mypy, cpython, pyright etc.

cc @dmontagu and @adriangb

@AlexWaygood
Copy link
Member Author

AlexWaygood commented Mar 15, 2023

Most of CPython has no type annotations. Even for the parts of CPython that do have type annotations, type checkers ignore the type annotations in CPython, and only look to typeshed's stubs when it comes to type hints in the stdlib.

Typeshed's stdlib stubs are vendored by mypy; mypy updates its vendored stdlib stubs to sync with typeshed's main branch about once every two weeks. As such, you won't see any change in mypy's behaviour until the next mypy release (mypy 1.2). There's no tracking issue for planning mypy 1.2 yet over at the mypy repo, so I can't tell you when mypy 1.2 will be released. I would guess it won't be released for a few weeks at least.

All other major type checkers also vendor typeshed's stdlib stubs in a very similar way. You may see pyright start to emit errors sooner than mypy, due to the fact that pyright has a much more frequent release schedule than mypy. (Again, I have no control over the mypy release process, I'm afraid! I'm not a mypy core dev.)

When mypy 1.2 comes out, supporting the latest mypy version while maintaining support for older mypy versions might, admittedly, be a little tricky here. If that's something you want to do, I'd probably advise not parameterising classmethod at all in your annotations, e.g.:

- foo: classmethod[Any]`
+ foo: classmethod

If you have --disallow-any-generics enabled in your mypy config (this setting is enabled by default if you use mypy --strict), you may need to add a type: ignore or two to silence some mypy complaints, so that mypy is happy with you using classmethod as an annotation without parameterising it.

I hope that's helpful, and sorry for the disruption caused!

@samuelcolvin
Copy link
Contributor

That's really helpful, it was the vendoring that was confusing me, since I couldn't remember seeing typeshed in installed dependencies.

@srittau
Copy link
Collaborator

srittau commented Mar 15, 2023

@samuelcolvin Also, as far as I can see, pydantic already pins mypy to a specific version. This is good. When you decide to update mypy, you will surely run it and fix all type annotations at that point. So, this should not break CI at unexpected times.

@samuelcolvin
Copy link
Contributor

Sadly not. We pin it in our tests, but we can't stop users from installing newer versions - hence lots of problems at the moment with mypy v1.1.1.

There's no wayin packaging to say "X isn't required, but if is installed, it must be Y version".

In v2 we might add an optional dependency group just to constrain the mypy version, e.g. pydantic[mypy].

@AlexWaygood
Copy link
Member Author

What's the time frame for this being released?

The tracking issue for the mypy 1.2 release has just been opened:

samuelcolvin pushed a commit to pydantic/pydantic that referenced this pull request Apr 24, 2023
* update `AnyClassMethod` for change in python/typeshed#9771

* update mypy to use recent version of typeshed

* Add comment to try to trigger CI

* revert mypy version, add condition around AnyClassMethod

---------

Co-authored-by: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>
clrpackages pushed a commit to clearlinux-pkgs/pypi-pydantic that referenced this pull request May 25, 2023
…rsion 1.10.8

Adrian Garcia Badaracco (1):
      Support for email-validator>=2.0.0.post2 (#5627)

Amin Alaee (1):
      Remove pkg_resources test (#5508)

Benoit C. Sirois (1):
      Fixes discriminated unions not working on aliased literal fields. Issue #3849. (#5736)

David Montague (1):
      Fix internal error with mypy (#5449)

Dimitri Papadopoulos Orfanos (1):
      Fix typos found by codespell (#5375)

Hasan Ramezani (2):
      Fix Literal bug with typing-extension==4.6.0 (#5826)
      Prepare for 1.10.8 (#5830)

Jens Heinrich (1):
      tweak type annotations (#5499)

Kyle Finley (1):
      update `AnyClassMethod` for change in python/typeshed#9771 (#5505)

Samuel Colvin (6):
      [ALPHA] V2 Alpha Blog Post (#5343)
      fix link in alpha release to v2 blog
      Add mike to V1 docs (#5628)
      enable fastapi testing on 1.10 (#5635)
      V1 add `build-docs.sh` (#5832)
      remove sponsors from docs (#5833)
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this pull request May 26, 2023
https://build.opensuse.org/request/show/1088976
by user dgarcia + dimstar_suse
- Update to v1.10.8
  * Fix a bug in `Literal` usage with `typing-extension==4.6.0`, #5826
    by @hramezani
  * This solves the (closed) issue #3849 where aliased fields that use
    discriminated union fail to validate when the data contains the
    non-aliased field name, #5736 by @benwah
  * Update email-validator dependency to >=2.0.0post2, #5627 by
    @adriangb
  * update `AnyClassMethod` for changes in
    [python/typeshed#9771](python/typeshed#9771),
    #5505 by @ITProKyle
clrpackages pushed a commit to clearlinux-pkgs/pypi-pydantic that referenced this pull request Oct 26, 2023
…sion 1.10.10

Adrian Garcia Badaracco (1):
      Support for email-validator>=2.0.0.post2 (#5627)

Amin Alaee (1):
      Remove pkg_resources test (#5508)

Arseny Boykov (1):
      [1.10.x] Properly encode model and dataclass default for schema (#4781)

Bas Schoenmaeckers (1):
      Add future and past date hypothesis strategies (#5850)

Benoit C. Sirois (1):
      Fixes discriminated unions not working on aliased literal fields. Issue #3849. (#5736)

David Montague (7):
      Disable Google analytics (#5059)
      prepare for v1.10.6 (#5157)
      Fix mypy plugin misbehavior with from_orm for user classes (#5193)
      Mypy plugin: Add implicit defaults for Field with no default argument (#5207)
      Fix mypy plugin crash (1.10.X-fixes) (#5208)
      prepare for 1.10.7 (#5248)
      Fix internal error with mypy (#5449)

Dimitri Papadopoulos Orfanos (1):
      Fix typos found by codespell (#5375)

Eric Jolibois (3):
      fix: support assignment on DataclassProxy (#4880)
      fix: avoid multiple calls of `__post_init__` when dataclasses are inherited (#4493)
      fix: use dataclasses proxy for frozen or empty dataclasses (#4878)

Gulu Mammadli (1):
      fix: Fix broken link in the docs (Pydantic Models - Data Binding) (#5074)

Hasan Ramezani (11):
      fix: missing file extension in model_config.md link (#4512) (#4513)
      Update mkdocs.yml (#4524) (#4532)
      v2 docs broken link fix (#4533) (#4550)
      Replace deprecated `get_event_loop` with `asyncio.run` (#4859) (#4860)
      Fix Literal bug with typing-extension==4.6.0 (#5826)
      Prepare for 1.10.8 (#5830)
      Add Pydantic classifier (#5847)
      [Backport] Fix Decimal trailing zero handling (#5968)
      Prepare for 1.10.9 (#6034)
      Add Pydantic `Json` field support to settings management (#6250)
      Prepare for 1.10.10 (#6308)

Jens Heinrich (4):
      Fix wrong type for parameter (#5127)
      Mark optional params as Optional (#5128)
      Use getattr and default for qualname (#5126)
      tweak type annotations (#5499)

Jon Parise (1):
      Allow dicts to have both patternProperties and additionalProperties (#4641)

K900 (1):
      Fix racy doctests (#6103)

Kurt McKee (1):
      Raise `ValidationError` for unhashable discriminator values (#5132)

Kyle Finley (1):
      update `AnyClassMethod` for change in python/typeshed#9771 (#5505)

Marc Mueller (3):
      [cherry-pick] Fix mypy plugin for 1.1.0 (#5077) (#5111)
      Don't apply dataclass transform twice with plugin + mypy 1.1.1 (#5162)
      [cherry-pick] Fix mypy plugin for 1.4.0 (#5927) (#5928)

Marcelo Trylesinski (1):
      ✅ Update FastAPI test script (#6117)

Markus Scheidgen (1):
      Fixed literal validator errors for unhashable values (#6194)

MarkusSintonen (1):
      fix: Fix broken parametrized bases with GenericModels (#5052)

Matt Fulgo (2):
      Allows Optional lists with unique_items check (#4568)
      Fix TypeError for GenericModel with Callable param (#4653)

Mòrian (1):
      Add postgresql+psycopg as allowed scheme for PostgreDsn (#4689) (#4690)

Samuel Colvin (26):
      test on the 1.10.X-fixes branch
      fix copy_on_model_validation type hint (#4491)
      use "field_specifiers", fix #4500 (#4501)
      add hooky config
      uprev 3.11, add check job (#4662)
      Add Jina AI to sponsors (#4767)
      bust CI cache, fix docs-build
      bust CI test cache (#4786)
      Moving docs to `docs.pydantic.dev` (#4818)
      Reduce binary sizes (#4862)
      fix history links (#4866)
      prepare for v1.10.3, fix #4552
      Typing extensions min version (#4886)
      prepare for v1.10.4 release
      add dependencies-check to 1.10.X-fixes
      fix install step for dependencies check
      fix coverage badge to use correct branch (#5060)
      prepare for v1.10.5
      Announcement (#5069)
      [ALPHA] V2 Alpha Blog Post (#5343)
      fix link in alpha release to v2 blog
      Add mike to V1 docs (#5628)
      enable fastapi testing on 1.10 (#5635)
      V1 add `build-docs.sh` (#5832)
      remove sponsors from docs (#5833)
      add roadmap to announcement (#6120)

Serge Matveenko (1):
      📌 Use Cython < v3 (#5845)

Sigurd Spieckermann (1):
      [1.10.X] Fix field regex with StrictStr type annotation (#4538)

Simon Matejetz (1):
      Fix creating schema from model using ConstrainedStr with regex str as dict key (#5223)

Slava (1):
      Handle X | Y union in GenericModel (#4977)

Volker Hilsenstein (1):
      Fix broken cross-references (#4743)

github-actions[bot] (12):
      Fix "trough" typo in Model Config docs (#4593) (#4594)
      Add missing typing to example (#4596) (#4605)
      Fix improper parsing of Enum document (#4736)
      Renaming BaseModel (#4766)
      fix typo in docs (#4765)
      Remove trailing "```" (#4799) (#4800)
      Add newline before `Outputs:` when printing json output in docs (#4802) (#4848)
      Fix typo in types usage documentation. (#4825) (#4849)
      fixed documentation typo (#4855) (#4858)
      Fixed datetime format specifier in docs (#4876) (#4879)
      Fix typo in Field function docstring (#4931) (#4932)
      Invalidate mypy cache if config changes (#5007) (#5023)

gou177 (1):
      fix: Parsing of custom root models (#4883) (#4884)

javibookline (1):
      Discriminated union literal enum values (#5188)

kgolawski (1):
      Fix code typo in docs (#4775)

mark-todd (1):
      Bug fix for forward refs in generics (#6157)

mbillingr (1):
      Dataclass deepcopy 1.10 (#4963)

⬢ Samuel Colvin (3):
      remove remains of ads, add custom analytics (#4927)
      simplify analytics more (#4930)
      uprev mkdocs-material, fix maxcdn errors (#4954)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants