Open intgr opened 1 year ago
The original example passes now with mypy 1.9.0, thanks to @cdce8p's work (https://mypy-play.net/?mypy=latest&python=3.10&gist=ca609b35e9cbf97a600343b249c6b0a9). What still needs to be done here?
One missing feature is TypeVar(default=)
referencing another TypeVar. django-stubs
has been patiently waiting for this feature, it would allow us to clean up some pretty ugly hacks.
T = TypeVar("T")
U = TypeVar("U", default=T) # If just T is specified, then U = T
class Box(Generic[T, U]): # Box[T] would be expanded to Box[T, T]
...
Right now there's no warning when using this, mypy silently does the wrong thing. Playground: https://mypy-play.net/?mypy=latest&python=3.12&gist=22121ee5ef0b55d52d651a1d8636df73
Ah yes, that doesn't quite work yet:
from typing import Generic, TypeVar
T = TypeVar("T")
U = TypeVar("U", default=T) # If just T is specified, then U = T
class Box(Generic[T, U]): # Box[T] would be expanded to Box[T, T]
...
x = Box[int]()
reveal_type(x) # E: Revealed type is "__main__.Box[builtins.int, T?]"
@cdce8p Are you interested in implementing this part of PEP 696 too -- allowing TypeVar to default to another TypeVar? Thanks for your work so far!
@cdce8p Are you interested in implementing this part of PEP 696 too -- allowing TypeVar to default to another TypeVar?
I've already started working on it. See #16878. That one didn't make in time for the 1.9.0 release though. I do plan to continue the work, just not sure when I'll get to it. It might take some time.
If I'm correct, this issue is required for Python 3.13 support right? What's needed to move it forward?
It's required to support some new syntax in Python 3.13, but mypy will type check most code in 3.13 just fine without this, so it depends on what you count as "Python 3.13 support".
As an example (probably relevant to why you're here :) ), to make Black support 3.13 mypyc compilation, this issue isn't relevant because Black doesn't use TypeVars with defaults at the moment.
However, @cdce8p implemented much of what's needed for this feature in any case (thanks!). I don't know how much is left, but most basic use cases should already work.
As an example (probably relevant to why you're here :) ), to make Black support 3.13 mypyc compilation, this issue isn't relevant because Black doesn't use TypeVars with defaults at the moment.
The issue you're looking for is probably https://github.com/mypyc/mypyc/issues/1056.
However, @cdce8p implemented much of what's needed for this feature in any case (thanks!). I don't know how much is left, but most basic use cases should already work.
The next step would be to add support for the new TypeVar defaults syntax in 3.13. I've started working on it already, just need to find some time soon to finish it and open a PR.
Besides that, the support for ParamSpec / TypeVarTuple defaults and recursive TypeVar defaults is still quite limited unfortunately. Although it would be great to fully support these, PEP 696 is already useable in the most common cases.
Examples like the following still fail:
from typing import Generic, assert_type
from typing_extensions import TypeVar
DefaultStrT = TypeVar("DefaultStrT", default=str)
DefaultIntT = TypeVar("DefaultIntT", default=int)
class NoNonDefaults(Generic[DefaultStrT, DefaultIntT]): ...
assert_type(NoNonDefaults, type[NoNonDefaults[str, int]])
assert_type(NoNonDefaults[str], type[NoNonDefaults[str, int]])
assert_type(NoNonDefaults[str, int], type[NoNonDefaults[str, int]])
It looks like this is due to the thing I find slightly confusing where mypy represents type objects as CallableType. One possible way to fix is to replace type variables with their defaults when comparing CallableType to TypeType and vice versa. Maybe there's a better way too
Feature
See PEP 696 – Type defaults for TypeVarLikes for details. The PEP has not yet been accepted though. Example from the PEP:
Since I did not find an existing tracking issue for this feature, I decided to open one.
The
default=
argument is already supported intyping_extensions
version 4.4.0+ and typeshed (https://github.com/python/typeshed/pull/8821)Edit from maintainer: mypy supports basic PEP 696 use cases, but is missing some support for less common use cases. Give it a try!