Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update typing from v3.14.3
  • Loading branch information
CPython Developers authored and youknowone committed Feb 10, 2026
commit 8d16007ffbbbc49a0c82a92c6de9e8d9e8830eea
158 changes: 147 additions & 11 deletions Lib/test/test_genericalias.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
from weakref import WeakSet, ReferenceType, ref
import typing
from typing import Unpack
try:
from tkinter import Event
except ImportError:
Event = None
from string.templatelib import Template, Interpolation

from typing import TypeVar
T = TypeVar('T')
Expand Down Expand Up @@ -96,7 +101,7 @@

class BaseTest(unittest.TestCase):
"""Test basics."""
generic_types = [type, tuple, list, dict, set, frozenset, enumerate,
generic_types = [type, tuple, list, dict, set, frozenset, enumerate, memoryview,
defaultdict, deque,
SequenceMatcher,
dircmp,
Expand Down Expand Up @@ -133,13 +138,21 @@ class BaseTest(unittest.TestCase):
Future, _WorkItem,
Morsel,
DictReader, DictWriter,
array]
array,
staticmethod,
classmethod,
Template,
Interpolation,
]
if ctypes is not None:
generic_types.extend((ctypes.Array, ctypes.LibraryLoader))
generic_types.extend((ctypes.Array, ctypes.LibraryLoader, ctypes.py_object))
if ValueProxy is not None:
generic_types.extend((ValueProxy, DictProxy, ListProxy, ApplyResult,
MPSimpleQueue, MPQueue, MPJoinableQueue))
if Event is not None:
generic_types.append(Event)

@unittest.expectedFailure # TODO: RUSTPYTHON; memoryview, Template, Interpolation, py_object not subscriptable
def test_subscriptable(self):
for t in self.generic_types:
if t is None:
Expand Down Expand Up @@ -209,7 +222,6 @@ class MyList(list):
self.assertEqual(t.__args__, (int,))
self.assertEqual(t.__parameters__, ())

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_repr(self):
class MyList(list):
pass
Expand All @@ -225,13 +237,64 @@ class MyGeneric:
self.assertEqual(repr(x2), 'tuple[*tuple[int, str]]')
x3 = tuple[*tuple[int, ...]]
self.assertEqual(repr(x3), 'tuple[*tuple[int, ...]]')
self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]'))
self.assertEndsWith(repr(MyList[int]), '.BaseTest.test_repr.<locals>.MyList[int]')
self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr

# gh-105488
self.assertTrue(repr(MyGeneric[int]).endswith('MyGeneric[int]'))
self.assertTrue(repr(MyGeneric[[]]).endswith('MyGeneric[[]]'))
self.assertTrue(repr(MyGeneric[[int, str]]).endswith('MyGeneric[[int, str]]'))
self.assertEndsWith(repr(MyGeneric[int]), 'MyGeneric[int]')
self.assertEndsWith(repr(MyGeneric[[]]), 'MyGeneric[[]]')
self.assertEndsWith(repr(MyGeneric[[int, str]]), 'MyGeneric[[int, str]]')

def test_evil_repr1(self):
# gh-143635
class Zap:
def __init__(self, container):
self.container = container
def __getattr__(self, name):
if name == "__origin__":
self.container.clear()
return None
if name == "__args__":
return ()
raise AttributeError

params = []
params.append(Zap(params))
alias = GenericAlias(list, (params,))
repr_str = repr(alias)
self.assertTrue(repr_str.startswith("list[["), repr_str)

def test_evil_repr2(self):
class Zap:
def __init__(self, container):
self.container = container
def __getattr__(self, name):
if name == "__qualname__":
self.container.clear()
return "abcd"
if name == "__module__":
return None
raise AttributeError

params = []
params.append(Zap(params))
alias = GenericAlias(list, (params,))
repr_str = repr(alias)
self.assertTrue(repr_str.startswith("list[["), repr_str)

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: IndexError not raised
def test_evil_repr3(self):
# gh-143823
lst = []
class X:
def __repr__(self):
lst.clear()
return "x"

lst += [X(), 1]
ga = GenericAlias(int, lst)
with self.assertRaises(IndexError):
repr(ga)

def test_exposed_type(self):
import types
Expand Down Expand Up @@ -333,7 +396,7 @@ def test_parameter_chaining(self):
with self.assertRaises(TypeError):
dict[T, T][str, int]

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: *tuple[int] == tuple[int]
def test_equality(self):
self.assertEqual(list[int], list[int])
self.assertEqual(dict[str, int], dict[str, int])
Expand All @@ -352,7 +415,7 @@ def test_isinstance(self):

def test_issubclass(self):
class L(list): ...
self.assertTrue(issubclass(L, list))
self.assertIsSubclass(L, list)
with self.assertRaises(TypeError):
issubclass(L, list[str])

Expand Down Expand Up @@ -424,7 +487,7 @@ def test_union_generic(self):
self.assertEqual(a.__args__, (list[T], tuple[T, ...]))
self.assertEqual(a.__parameters__, (T,))

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_dir(self):
ga = list[int]
dir_of_gen_alias = set(dir(ga))
Expand All @@ -447,6 +510,7 @@ def test_dir(self):
with self.subTest(entry=entry):
getattr(ga, entry) # must not raise `AttributeError`

@unittest.expectedFailure # TODO: RUSTPYTHON; memoryview, Template, Interpolation, py_object not subscriptable
def test_weakref(self):
for t in self.generic_types:
if t is None:
Expand Down Expand Up @@ -490,6 +554,78 @@ def test_del_iter(self):
iter_x = iter(t)
del iter_x

@unittest.expectedFailure # TODO: RUSTPYTHON; + (~T,)
def test_paramspec_specialization(self):
# gh-124445
T = TypeVar("T")
U = TypeVar("U")
type X[**P] = Callable[P, int]

generic = X[[T]]
self.assertEqual(generic.__args__, ([T],))
self.assertEqual(generic.__parameters__, (T,))
specialized = generic[str]
self.assertEqual(specialized.__args__, ([str],))
self.assertEqual(specialized.__parameters__, ())

generic = X[(T,)]
self.assertEqual(generic.__args__, (T,))
self.assertEqual(generic.__parameters__, (T,))
specialized = generic[str]
self.assertEqual(specialized.__args__, (str,))
self.assertEqual(specialized.__parameters__, ())

generic = X[[T, U]]
self.assertEqual(generic.__args__, ([T, U],))
self.assertEqual(generic.__parameters__, (T, U))
specialized = generic[str, int]
self.assertEqual(specialized.__args__, ([str, int],))
self.assertEqual(specialized.__parameters__, ())

generic = X[(T, U)]
self.assertEqual(generic.__args__, (T, U))
self.assertEqual(generic.__parameters__, (T, U))
specialized = generic[str, int]
self.assertEqual(specialized.__args__, (str, int))
self.assertEqual(specialized.__parameters__, ())

@unittest.expectedFailure # TODO: RUSTPYTHON; + (~U, ~V)
def test_nested_paramspec_specialization(self):
# gh-124445
type X[**P, T] = Callable[P, T]

x_list = X[[int, str], float]
self.assertEqual(x_list.__args__, ([int, str], float))
self.assertEqual(x_list.__parameters__, ())

x_tuple = X[(int, str), float]
self.assertEqual(x_tuple.__args__, ((int, str), float))
self.assertEqual(x_tuple.__parameters__, ())

U = TypeVar("U")
V = TypeVar("V")

multiple_params_list = X[[int, U], V]
self.assertEqual(multiple_params_list.__args__, ([int, U], V))
self.assertEqual(multiple_params_list.__parameters__, (U, V))
multiple_params_list_specialized = multiple_params_list[str, float]
self.assertEqual(multiple_params_list_specialized.__args__, ([int, str], float))
self.assertEqual(multiple_params_list_specialized.__parameters__, ())

multiple_params_tuple = X[(int, U), V]
self.assertEqual(multiple_params_tuple.__args__, ((int, U), V))
self.assertEqual(multiple_params_tuple.__parameters__, (U, V))
multiple_params_tuple_specialized = multiple_params_tuple[str, float]
self.assertEqual(multiple_params_tuple_specialized.__args__, ((int, str), float))
self.assertEqual(multiple_params_tuple_specialized.__parameters__, ())

deeply_nested = X[[U, [V], int], V]
self.assertEqual(deeply_nested.__args__, ([U, [V], int], V))
self.assertEqual(deeply_nested.__parameters__, (U, V))
deeply_nested_specialized = deeply_nested[str, float]
self.assertEqual(deeply_nested_specialized.__args__, ([str, [float], int], float))
self.assertEqual(deeply_nested_specialized.__parameters__, ())


class TypeIterationTests(unittest.TestCase):
_UNITERABLE_TYPES = (list, tuple)
Expand Down
Loading