blob: 196b059dfa0dd09b7f3bd81979b1304ff554dfa3 [file] [log] [blame]
Guido van Rossum48b069a2020-04-07 09:50:06 -07001"""Tests for C-implemented GenericAlias."""
2
3import unittest
4import pickle
5from collections import (
6 defaultdict, deque, OrderedDict, Counter, UserDict, UserList
7)
8from collections.abc import *
9from contextlib import AbstractContextManager, AbstractAsyncContextManager
Ethan Smith7c4185d2020-04-09 21:25:53 -070010from mmap import mmap
Batuhan Taşkaya2fa67df2020-04-10 07:04:54 +030011from ipaddress import IPv4Network, IPv4Interface, IPv6Network, IPv6Interface
Ethan Smitha8403d02020-04-09 20:28:08 -070012from itertools import chain
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013from os import DirEntry
Guido van Rossum48b069a2020-04-07 09:50:06 -070014from re import Pattern, Match
Ethan Smith7c4185d2020-04-09 21:25:53 -070015from types import GenericAlias, MappingProxyType, AsyncGeneratorType
Guido van Rossum48b069a2020-04-07 09:50:06 -070016import typing
17
18from typing import TypeVar
19T = TypeVar('T')
20
21class BaseTest(unittest.TestCase):
22 """Test basics."""
23
24 def test_subscriptable(self):
Ethan Smith7c4185d2020-04-09 21:25:53 -070025 for t in (type, tuple, list, dict, set, frozenset, enumerate,
26 mmap,
Guido van Rossum48b069a2020-04-07 09:50:06 -070027 defaultdict, deque,
28 OrderedDict, Counter, UserDict, UserList,
29 Pattern, Match,
30 AbstractContextManager, AbstractAsyncContextManager,
31 Awaitable, Coroutine,
32 AsyncIterable, AsyncIterator,
33 AsyncGenerator, Generator,
34 Iterable, Iterator,
35 Reversible,
36 Container, Collection,
37 Callable,
38 Set, MutableSet,
39 Mapping, MutableMapping, MappingView,
40 KeysView, ItemsView, ValuesView,
41 Sequence, MutableSequence,
Ethan Smith7c4185d2020-04-09 21:25:53 -070042 MappingProxyType, AsyncGeneratorType,
Batuhan Taşkaya2fa67df2020-04-10 07:04:54 +030043 DirEntry,
44 IPv4Network, IPv4Interface, IPv6Network, IPv6Interface,
Ethan Smitha8403d02020-04-09 20:28:08 -070045 chain,
Guido van Rossum48b069a2020-04-07 09:50:06 -070046 ):
47 tname = t.__name__
48 with self.subTest(f"Testing {tname}"):
49 alias = t[int]
50 self.assertIs(alias.__origin__, t)
51 self.assertEqual(alias.__args__, (int,))
52 self.assertEqual(alias.__parameters__, ())
53
54 def test_unsubscriptable(self):
55 for t in int, str, float, Sized, Hashable:
56 tname = t.__name__
57 with self.subTest(f"Testing {tname}"):
58 with self.assertRaises(TypeError):
59 t[int]
60
61 def test_instantiate(self):
62 for t in tuple, list, dict, set, frozenset, defaultdict, deque:
63 tname = t.__name__
64 with self.subTest(f"Testing {tname}"):
65 alias = t[int]
66 self.assertEqual(alias(), t())
67 if t is dict:
68 self.assertEqual(alias(iter([('a', 1), ('b', 2)])), dict(a=1, b=2))
69 self.assertEqual(alias(a=1, b=2), dict(a=1, b=2))
70 elif t is defaultdict:
71 def default():
72 return 'value'
73 a = alias(default)
74 d = defaultdict(default)
75 self.assertEqual(a['test'], d['test'])
76 else:
77 self.assertEqual(alias(iter((1, 2, 3))), t((1, 2, 3)))
78
79 def test_unbound_methods(self):
80 t = list[int]
81 a = t()
82 t.append(a, 'foo')
83 self.assertEqual(a, ['foo'])
84 x = t.__getitem__(a, 0)
85 self.assertEqual(x, 'foo')
86 self.assertEqual(t.__len__(a), 1)
87
88 def test_subclassing(self):
89 class C(list[int]):
90 pass
91 self.assertEqual(C.__bases__, (list,))
92 self.assertEqual(C.__class__, type)
93
94 def test_class_methods(self):
95 t = dict[int, None]
96 self.assertEqual(dict.fromkeys(range(2)), {0: None, 1: None}) # This works
97 self.assertEqual(t.fromkeys(range(2)), {0: None, 1: None}) # Should be equivalent
98
99 def test_no_chaining(self):
100 t = list[int]
101 with self.assertRaises(TypeError):
102 t[int]
103
104 def test_generic_subclass(self):
105 class MyList(list):
106 pass
107 t = MyList[int]
108 self.assertIs(t.__origin__, MyList)
109 self.assertEqual(t.__args__, (int,))
110 self.assertEqual(t.__parameters__, ())
111
112 def test_repr(self):
113 class MyList(list):
114 pass
115 self.assertEqual(repr(list[str]), 'list[str]')
116 self.assertEqual(repr(list[()]), 'list[()]')
117 self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]')
118 self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]'))
119 self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr
120
121 def test_exposed_type(self):
122 import types
123 a = types.GenericAlias(list, int)
124 self.assertEqual(str(a), 'list[int]')
125 self.assertIs(a.__origin__, list)
126 self.assertEqual(a.__args__, (int,))
127 self.assertEqual(a.__parameters__, ())
128
129 def test_parameters(self):
130 from typing import TypeVar
131 T = TypeVar('T')
132 K = TypeVar('K')
133 V = TypeVar('V')
134 D0 = dict[str, int]
135 self.assertEqual(D0.__args__, (str, int))
136 self.assertEqual(D0.__parameters__, ())
137 D1a = dict[str, V]
138 self.assertEqual(D1a.__args__, (str, V))
139 self.assertEqual(D1a.__parameters__, (V,))
140 D1b = dict[K, int]
141 self.assertEqual(D1b.__args__, (K, int))
142 self.assertEqual(D1b.__parameters__, (K,))
143 D2a = dict[K, V]
144 self.assertEqual(D2a.__args__, (K, V))
145 self.assertEqual(D2a.__parameters__, (K, V))
146 D2b = dict[T, T]
147 self.assertEqual(D2b.__args__, (T, T))
148 self.assertEqual(D2b.__parameters__, (T,))
149 L0 = list[str]
150 self.assertEqual(L0.__args__, (str,))
151 self.assertEqual(L0.__parameters__, ())
152 L1 = list[T]
153 self.assertEqual(L1.__args__, (T,))
154 self.assertEqual(L1.__parameters__, (T,))
155
156 def test_parameter_chaining(self):
157 from typing import TypeVar
158 T = TypeVar('T')
159 self.assertEqual(list[T][int], list[int])
160 self.assertEqual(dict[str, T][int], dict[str, int])
161 self.assertEqual(dict[T, int][str], dict[str, int])
162 self.assertEqual(dict[T, T][int], dict[int, int])
163 with self.assertRaises(TypeError):
164 list[int][int]
165 dict[T, int][str, int]
166 dict[str, T][str, int]
167 dict[T, T][str, int]
168
169 def test_equality(self):
170 self.assertEqual(list[int], list[int])
171 self.assertEqual(dict[str, int], dict[str, int])
172 self.assertNotEqual(dict[str, int], dict[str, str])
173 self.assertNotEqual(list, list[int])
174 self.assertNotEqual(list[int], list)
175
176 def test_isinstance(self):
177 self.assertTrue(isinstance([], list))
178 with self.assertRaises(TypeError):
179 isinstance([], list[str])
180
181 def test_issubclass(self):
182 class L(list): ...
183 self.assertTrue(issubclass(L, list))
184 with self.assertRaises(TypeError):
185 issubclass(L, list[str])
186
187 def test_type_generic(self):
188 t = type[int]
189 Test = t('Test', (), {})
190 self.assertTrue(isinstance(Test, type))
191 test = Test()
192 self.assertEqual(t(test), Test)
193 self.assertEqual(t(0), int)
194
195 def test_type_subclass_generic(self):
196 class MyType(type):
197 pass
198 with self.assertRaises(TypeError):
199 MyType[int]
200
201 def test_pickle(self):
202 alias = GenericAlias(list, T)
203 s = pickle.dumps(alias)
204 loaded = pickle.loads(s)
205 self.assertEqual(alias.__origin__, loaded.__origin__)
206 self.assertEqual(alias.__args__, loaded.__args__)
207 self.assertEqual(alias.__parameters__, loaded.__parameters__)
208
209 def test_union(self):
210 a = typing.Union[list[int], list[str]]
211 self.assertEqual(a.__args__, (list[int], list[str]))
212 self.assertEqual(a.__parameters__, ())
213
214 def test_union_generic(self):
215 T = typing.TypeVar('T')
216 a = typing.Union[list[T], tuple[T, ...]]
217 self.assertEqual(a.__args__, (list[T], tuple[T, ...]))
218 self.assertEqual(a.__parameters__, (T,))
219
220
221if __name__ == "__main__":
222 unittest.main()