|
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,63 @@ 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) |
|
|
|
|
|
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 +395,6 @@ def test_parameter_chaining(self): |
|
|
with self.assertRaises(TypeError): |
|
|
dict[T, T][str, int] |
|
|
|
|
|
@unittest.expectedFailure # TODO: RUSTPYTHON |
|
|
def test_equality(self): |
|
|
self.assertEqual(list[int], list[int]) |
|
|
self.assertEqual(dict[str, int], dict[str, int]) |
|
Expand All
|
@@ -352,7 +413,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 +485,6 @@ def test_union_generic(self): |
|
|
self.assertEqual(a.__args__, (list[T], tuple[T, ...])) |
|
|
self.assertEqual(a.__parameters__, (T,)) |
|
|
|
|
|
@unittest.expectedFailure # TODO: RUSTPYTHON |
|
|
def test_dir(self): |
|
|
ga = list[int] |
|
|
dir_of_gen_alias = set(dir(ga)) |
|
Expand All
|
@@ -447,6 +507,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 +551,76 @@ def test_del_iter(self): |
|
|
iter_x = iter(t) |
|
|
del iter_x |
|
|
|
|
|
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__, ()) |
|
|
|
|
|
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
|
|