Repository navigation
Bug or new behavior of generics parameterization? #98852
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Oct 29, 2022 - addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory3.11only security fixesonly security fixes3.12only security fixesonly security fixes
on Oct 29, 2022 This is how it used to work in
3.10: https://github.com/python/cpython/blame/85f88f63d96b07208c98a725391af7cb710fe06b/Lib/typing.py#L1060-L1081>>> from typing import TypeVar, Generic, Callable >>> >>> >>> T = TypeVar("T") >>> P = TypeVar("P") >>> >>> class Test(Generic[T]): ... ... >>> >>> S = Callable[[Test], P] >>> >>> def test(arg: S[T]): ... ... >>> test.__annotations__ {'arg': typing.Callable[[__main__.Test], ~T]}
Clearly looks like a bug to me. I am investigating what is going on :)
I know about how it works in 3.10 =)
My simple solution:... if substfunc: new_arg = substfunc(new_arg_by_param[old_arg]) elif not isinstance(old_arg, (_GenericAlias, GenericAlias, types.UnionType)): new_arg = old_arg else: ...With that, code above works fine.
>>> test.__annotations__ {'arg': typing.Callable[[__main__.Test], ~T]}
What you think about this?
Yes, looks like it might work. Previously the same logic was guarded by this check: https://github.com/python/cpython/blame/85f88f63d96b07208c98a725391af7cb710fe06b/Lib/typing.py#L1071
Would you like to send a PR with this proposal? :)
Could we first find which PR introduced the bug?
Also, @JelleZijlstra ^^
Reacted by Alex WaygoodIndeed, there is a bug in
_collect_parameterswhich causes to skipping generic types.Yet one interesting example:
>>> class Test(Generic[T]): ... ... >>> Test.__parameters__ (~T,) >>> class Test2(Test): ... ... >>> Test2.__parameters__ ()
But after fixing this code I got other test failure. And it seems that we have contradictory tests. Test in
test_complex_subclassesexpects that we can successfully create a class inheriting from generic base andGeneric[].
cpython/Lib/test/test_typing.py
Lines 3898 to 3900 in 018b248
# see gh-94607: this fails in that bug class Sub(Base, Generic[T]): ... But tests in
test_generic_errorsandtest_generic_inheritanceexpect thatGeneric[]should include all typing variables, otherwise the class creation should fail.
cpython/Lib/test/test_typing.py
Lines 3047 to 3048 in 018b248
with self.assertRaises(TypeError): class MyGeneric(List[T], Generic[S]): ...
cpython/Lib/test/test_typing.py
Lines 6492 to 6494 in 018b248
with self.assertRaises(TypeError): class Point3D(Point2DGeneric[T], Generic[KT]): c: KT The only difference between these examples is that in the former case the generic base is a generic class, and in the latter cases it is a generic alias. I do not think that there should be difference between them in this context. We should either require
Generic[]containing all typing variables or allow it only containing some of them.See also #94607.
I don't see a contradiction. In
class Sub(Base, Generic[T]):,Baseshould be equivalent toBase[Any], which is the general behavior for generics missing a subscription.It makes sense if you look at it this way. The problem is with distinguishing free and bound variables. Both are represented in
__parameters__.- added a commit that references this issue
on Oct 31, 2022 - addedtype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
on Oct 31, 2022 The issue is more serious and is not completely new.
In the following code:
from typing import * T = TypeVar("T") T2 = TypeVar("T2") class A(Generic[T2]): ... Tuple[A, T][int] tuple[A, T][int] Tuple[TypeVar, T][int] tuple[TypeVar, T][int]
3.11 raises exception for the 1st and 3rd examples, produces incorrect result for the 2nd example, and crashes on the last example.
3.10 raises exception for the 2nd examples.
Reacted by Paul FidikaIs there anything left to do here?
It is completed.
Reacted by Paul Fidika
On python3.11 i can't run this code. Code falls on an attempt to parameterize
STraceback:
How i understand, in 3.11, an attempt is being made to parameterize
TestinS, but in 3.10 - notIs it new behavior or a bug?