hoodmane
(Hood Chatham)
November 29, 2023, 2:52am
1
How do I make a type IdentityType so that IdentityType[T] is synonymous with T?
Jelle
(Jelle Zijlstra)
November 29, 2023, 3:28am
2
Like this:
from typing import TypeAlias, TypeVar, reveal_type
type IdentityType[T] = T # Python 3.12 only
T = TypeVar("T")
IdentityType2: TypeAlias = T # works on older versions
def f(x: IdentityType[int], y: IdentityType2[int]):
reveal_type(x) # int
reveal_type(y) # int
(Pyright playground )
2 Likes
hoodmane
(Hood Chatham)
November 29, 2023, 4:35am
3
Thanks!
I have a second question while I’m at it: how do I make TakeFirst[S, T] which is synonymous with S?
hoodmane
(Hood Chatham)
November 29, 2023, 4:37am
4
I guess it’s clear how to do it in Python 3.12: type X[S, T] = S. But what about in Python 3.11?
Jelle
(Jelle Zijlstra)
November 29, 2023, 5:01am
5
I can’t think of a way to do it without the type statement.
hoodmane
(Hood Chatham)
November 29, 2023, 5:09am
6
Yeah I was looking for ways to use T in an expression but in a way that T doesn’t actually matter but I couldn’t see a way to do this. The type keyword seems pretty great.
Maybe there could be some trick with metaclasses? Something like:
class Test(type, Generic[S]):
def __new__(cls, name, bases, classdict) -> S:
...
class A(metaclass=Test[S], Generic[S, T]):
...
hoodmane
(Hood Chatham)
November 29, 2023, 5:12am
7
But mypy is not happy with this unreasonable hack…
Incompatible return type for "__new__" (returns "int", but must return a subtype of "type")
For instance even in the following it doesn’t realize that A is 5:
class Test(type):
def __new__(cls: Any, name: Any, bases: Any, classdict: Any) -> int:
return 5
class A(metaclass=Test):
...
hoodmane
(Hood Chatham)
November 29, 2023, 5:13am
8
Thanks again for your help @Jelle !
mdrissi
(Mehdi Drissi)
November 29, 2023, 10:00am
9
Here’s a way to do it in 3.11,
from typing import TypeVar
from typing_extensions import TypeAliasType
S = TypeVar('S')
T = TypeVar('T')
X = TypeAliasType("X", S, (S, T))
Same idea as type statement just using backport.
hoodmane
(Hood Chatham)
November 30, 2023, 11:36pm
10
Thanks @mdrissi that’s exactly what I was looking for!
hoodmane
(Hood Chatham)
November 30, 2023, 11:49pm
11
I’m having trouble getting TypeAliasType to work with mypy. I have the following source code:
from typing import TypeVar
from typing_extensions import TypeAliasType
S = TypeVar("S")
Identity = TypeAliasType("Identity", S, type_params=(S,))
mypy gives:
file.pyi:7: error: Argument "type_params" to "TypeAliasType" has incompatible type "tuple[object]"; expected "tuple[typing_extensions.TypeVar | ParamSpec | TypeVarTuple, ...]" [arg-type]
With the following versions:
$ mypy --version
mypy 1.7.1 (compiled: yes)
$ python -c 'from importlib.metadata import version; print(version("typing-extensions"))'
4.8.0
$ python --version
Python 3.11.6
hoodmane
(Hood Chatham)
November 30, 2023, 11:52pm
12
Oh I see, this is a mypy TODO:
PEP 695 was accepted, and it looks like it will make it into Python 3.12. This PEP adds support for a new type parameter syntax for generic classes and methods. It also adds a new syntax for type aliases (both generic and not).
…
Here is a rough task list associated with this work:
…
Add support for functional form of TypeAliasType, supported for backward compatibility; see this section of PEP for details
opened 03:24AM - 14 May 23 UTC
feature
topic-type-variables
[PEP 695](https://peps.python.org/pep-0695/) was accepted, and it looks like it … will make it into Python 3.12. This PEP adds support for a new type parameter syntax for generic classes and methods. It also adds a new syntax for type aliases (both generic and not).
PEP 695 functionality is implemented in pyright today. It would be great to see it also implemented in mypy and the other major type checkers so we could start to use the new features in type stubs.
Here is a rough task list associated with this work:
- [ ] Add support for `infer_variance` keyword parameter in `TypeVar`; see [this section of PEP](https://peps.python.org/pep-0695/#auto-variance-for-typevar) for details
- [ ] Add support for variance inference (similar to variance enforcement in Protocol classes today); see [this section of PEP](https://peps.python.org/pep-0695/#variance-inference) for details
- [ ] Add support for new AST nodes for `type` statement; see [this section of PEP](https://peps.python.org/pep-0695/#grammar-changes) for details
- [ ] Add support for new AST nodes for generic classes and functions; see [this section of PEP](https://peps.python.org/pep-0695/#grammar-changes) for details
- [ ] Add support for evaluating type parameters using the new syntax (including TypeVar bounds and constraints, TypeVarTuple and ParamSpec); see [this section of PEP](https://peps.python.org/pep-0695/#type-parameter-declarations) for details
- [ ] Add support for defining type aliases using the new `type` statement (including generic and recursive type definitions); see [this section of PEP](https://peps.python.org/pep-0695/#generic-type-alias) for details
- [ ] Add support for defining generic classes and functions with explicit type parameter lists using new syntax
- [ ] Add support for functional form of `TypeAliasType`, supported for backward compatibility; see [this section of PEP](https://peps.python.org/pep-0695/#runtime-type-alias-class) for details
- [ ] Add detection and error reporting for use of traditional TypeVar, TypeVarTuple, or ParamSpec in conjunction with new syntax; see [this section of PEP](https://peps.python.org/pep-0695/#compatibility-with-traditional-typevars) for details
- [ ] Add detection and error reporting for use of assignment expressions, yield, yield from, and await expressions within the type parameter scope; see [this section of PEP](https://peps.python.org/pep-0695/#type-parameter-scopes) for details
erictraut
(Eric Traut)
December 1, 2023, 12:00am
13
Yeah, to my knowledge, mypy hasn’t started to add support for PEP 695 yet. If you want to use the PEP 695 functionality, it’s fully supported in pyright.
Code sample in pyright playground