blob: 4f3798e8f87d8ffee21590438cafda4e5dcf4f7d [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 *
Batuhan Taşkaya03615562020-04-10 17:46:36 +03009from concurrent.futures import Future
10from concurrent.futures.thread import _WorkItem
Guido van Rossum48b069a2020-04-07 09:50:06 -070011from contextlib import AbstractContextManager, AbstractAsyncContextManager
Ethan Smithd01628e2020-04-14 16:14:15 -070012from contextvars import ContextVar, Token
13from dataclasses import Field
14from functools import partial, partialmethod, cached_property
15from mailbox import Mailbox, _PartialFile
Batuhan Taşkaya03615562020-04-10 17:46:36 +030016from ctypes import Array, LibraryLoader
Ethan Smithe3ec44d2020-04-09 21:47:31 -070017from difflib import SequenceMatcher
18from filecmp import dircmp
19from fileinput import FileInput
Ethan Smitha8403d02020-04-09 20:28:08 -070020from itertools import chain
Batuhan Taşkaya03615562020-04-10 17:46:36 +030021from http.cookies import Morsel
22from multiprocessing.managers import ValueProxy
23from multiprocessing.pool import ApplyResult
Chih-Hsuan Yen25a68332020-04-14 06:00:16 +080024try:
25 from multiprocessing.shared_memory import ShareableList
26except ImportError:
27 # multiprocessing.shared_memory is not available on e.g. Android
28 ShareableList = None
Batuhan Taşkaya03615562020-04-10 17:46:36 +030029from multiprocessing.queues import SimpleQueue
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030030from os import DirEntry
Guido van Rossum48b069a2020-04-07 09:50:06 -070031from re import Pattern, Match
Ethan Smith7c4185d2020-04-09 21:25:53 -070032from types import GenericAlias, MappingProxyType, AsyncGeneratorType
Batuhan Taşkaya03615562020-04-10 17:46:36 +030033from tempfile import TemporaryDirectory, SpooledTemporaryFile
34from urllib.parse import SplitResult, ParseResult
35from unittest.case import _AssertRaisesContext
36from queue import Queue, SimpleQueue
Ethan Smith8ef87502020-04-13 21:54:40 -070037from weakref import WeakSet, ReferenceType, ref
Guido van Rossum48b069a2020-04-07 09:50:06 -070038import typing
39
40from typing import TypeVar
41T = TypeVar('T')
Serhiy Storchaka41a64582020-05-04 10:56:05 +030042K = TypeVar('K')
43V = TypeVar('V')
Guido van Rossum48b069a2020-04-07 09:50:06 -070044
45class BaseTest(unittest.TestCase):
46 """Test basics."""
47
48 def test_subscriptable(self):
Ethan Smith7c4185d2020-04-09 21:25:53 -070049 for t in (type, tuple, list, dict, set, frozenset, enumerate,
Guido van Rossum48b069a2020-04-07 09:50:06 -070050 defaultdict, deque,
Ethan Smithe3ec44d2020-04-09 21:47:31 -070051 SequenceMatcher,
52 dircmp,
53 FileInput,
Guido van Rossum48b069a2020-04-07 09:50:06 -070054 OrderedDict, Counter, UserDict, UserList,
55 Pattern, Match,
Ethan Smithcecf0492020-04-13 21:53:04 -070056 partial, partialmethod, cached_property,
Guido van Rossum48b069a2020-04-07 09:50:06 -070057 AbstractContextManager, AbstractAsyncContextManager,
58 Awaitable, Coroutine,
59 AsyncIterable, AsyncIterator,
60 AsyncGenerator, Generator,
61 Iterable, Iterator,
62 Reversible,
63 Container, Collection,
64 Callable,
Ethan Smithd01628e2020-04-14 16:14:15 -070065 Mailbox, _PartialFile,
66 ContextVar, Token,
67 Field,
Guido van Rossum48b069a2020-04-07 09:50:06 -070068 Set, MutableSet,
69 Mapping, MutableMapping, MappingView,
70 KeysView, ItemsView, ValuesView,
71 Sequence, MutableSequence,
Ethan Smith7c4185d2020-04-09 21:25:53 -070072 MappingProxyType, AsyncGeneratorType,
Batuhan Taşkaya2fa67df2020-04-10 07:04:54 +030073 DirEntry,
Ethan Smitha8403d02020-04-09 20:28:08 -070074 chain,
Batuhan Taşkaya03615562020-04-10 17:46:36 +030075 TemporaryDirectory, SpooledTemporaryFile,
76 Queue, SimpleQueue,
77 _AssertRaisesContext,
78 Array, LibraryLoader,
79 SplitResult, ParseResult,
80 ValueProxy, ApplyResult,
Ethan Smith8ef87502020-04-13 21:54:40 -070081 WeakSet, ReferenceType, ref,
Batuhan Taşkaya03615562020-04-10 17:46:36 +030082 ShareableList, SimpleQueue,
83 Future, _WorkItem,
84 Morsel,
Guido van Rossum48b069a2020-04-07 09:50:06 -070085 ):
Chih-Hsuan Yen25a68332020-04-14 06:00:16 +080086 if t is None:
87 continue
Guido van Rossum48b069a2020-04-07 09:50:06 -070088 tname = t.__name__
89 with self.subTest(f"Testing {tname}"):
90 alias = t[int]
91 self.assertIs(alias.__origin__, t)
92 self.assertEqual(alias.__args__, (int,))
93 self.assertEqual(alias.__parameters__, ())
94
95 def test_unsubscriptable(self):
96 for t in int, str, float, Sized, Hashable:
97 tname = t.__name__
98 with self.subTest(f"Testing {tname}"):
99 with self.assertRaises(TypeError):
100 t[int]
101
102 def test_instantiate(self):
103 for t in tuple, list, dict, set, frozenset, defaultdict, deque:
104 tname = t.__name__
105 with self.subTest(f"Testing {tname}"):
106 alias = t[int]
107 self.assertEqual(alias(), t())
108 if t is dict:
109 self.assertEqual(alias(iter([('a', 1), ('b', 2)])), dict(a=1, b=2))
110 self.assertEqual(alias(a=1, b=2), dict(a=1, b=2))
111 elif t is defaultdict:
112 def default():
113 return 'value'
114 a = alias(default)
115 d = defaultdict(default)
116 self.assertEqual(a['test'], d['test'])
117 else:
118 self.assertEqual(alias(iter((1, 2, 3))), t((1, 2, 3)))
119
120 def test_unbound_methods(self):
121 t = list[int]
122 a = t()
123 t.append(a, 'foo')
124 self.assertEqual(a, ['foo'])
125 x = t.__getitem__(a, 0)
126 self.assertEqual(x, 'foo')
127 self.assertEqual(t.__len__(a), 1)
128
129 def test_subclassing(self):
130 class C(list[int]):
131 pass
132 self.assertEqual(C.__bases__, (list,))
133 self.assertEqual(C.__class__, type)
134
135 def test_class_methods(self):
136 t = dict[int, None]
137 self.assertEqual(dict.fromkeys(range(2)), {0: None, 1: None}) # This works
138 self.assertEqual(t.fromkeys(range(2)), {0: None, 1: None}) # Should be equivalent
139
140 def test_no_chaining(self):
141 t = list[int]
142 with self.assertRaises(TypeError):
143 t[int]
144
145 def test_generic_subclass(self):
146 class MyList(list):
147 pass
148 t = MyList[int]
149 self.assertIs(t.__origin__, MyList)
150 self.assertEqual(t.__args__, (int,))
151 self.assertEqual(t.__parameters__, ())
152
153 def test_repr(self):
154 class MyList(list):
155 pass
156 self.assertEqual(repr(list[str]), 'list[str]')
157 self.assertEqual(repr(list[()]), 'list[()]')
158 self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]')
159 self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]'))
160 self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr
161
162 def test_exposed_type(self):
163 import types
164 a = types.GenericAlias(list, int)
165 self.assertEqual(str(a), 'list[int]')
166 self.assertIs(a.__origin__, list)
167 self.assertEqual(a.__args__, (int,))
168 self.assertEqual(a.__parameters__, ())
169
170 def test_parameters(self):
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300171 from typing import List, Dict, Callable
Guido van Rossum48b069a2020-04-07 09:50:06 -0700172 D0 = dict[str, int]
173 self.assertEqual(D0.__args__, (str, int))
174 self.assertEqual(D0.__parameters__, ())
175 D1a = dict[str, V]
176 self.assertEqual(D1a.__args__, (str, V))
177 self.assertEqual(D1a.__parameters__, (V,))
178 D1b = dict[K, int]
179 self.assertEqual(D1b.__args__, (K, int))
180 self.assertEqual(D1b.__parameters__, (K,))
181 D2a = dict[K, V]
182 self.assertEqual(D2a.__args__, (K, V))
183 self.assertEqual(D2a.__parameters__, (K, V))
184 D2b = dict[T, T]
185 self.assertEqual(D2b.__args__, (T, T))
186 self.assertEqual(D2b.__parameters__, (T,))
187 L0 = list[str]
188 self.assertEqual(L0.__args__, (str,))
189 self.assertEqual(L0.__parameters__, ())
190 L1 = list[T]
191 self.assertEqual(L1.__args__, (T,))
192 self.assertEqual(L1.__parameters__, (T,))
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300193 L2 = list[list[T]]
194 self.assertEqual(L2.__args__, (list[T],))
195 self.assertEqual(L2.__parameters__, (T,))
196 L3 = list[List[T]]
197 self.assertEqual(L3.__args__, (List[T],))
198 self.assertEqual(L3.__parameters__, (T,))
199 L4a = list[Dict[K, V]]
200 self.assertEqual(L4a.__args__, (Dict[K, V],))
201 self.assertEqual(L4a.__parameters__, (K, V))
202 L4b = list[Dict[T, int]]
203 self.assertEqual(L4b.__args__, (Dict[T, int],))
204 self.assertEqual(L4b.__parameters__, (T,))
205 L5 = list[Callable[[K, V], K]]
206 self.assertEqual(L5.__args__, (Callable[[K, V], K],))
207 self.assertEqual(L5.__parameters__, (K, V))
Guido van Rossum48b069a2020-04-07 09:50:06 -0700208
209 def test_parameter_chaining(self):
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300210 from typing import List, Dict, Union, Callable
Guido van Rossum48b069a2020-04-07 09:50:06 -0700211 self.assertEqual(list[T][int], list[int])
212 self.assertEqual(dict[str, T][int], dict[str, int])
213 self.assertEqual(dict[T, int][str], dict[str, int])
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300214 self.assertEqual(dict[K, V][str, int], dict[str, int])
Guido van Rossum48b069a2020-04-07 09:50:06 -0700215 self.assertEqual(dict[T, T][int], dict[int, int])
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300216
217 self.assertEqual(list[list[T]][int], list[list[int]])
218 self.assertEqual(list[dict[T, int]][str], list[dict[str, int]])
219 self.assertEqual(list[dict[str, T]][int], list[dict[str, int]])
220 self.assertEqual(list[dict[K, V]][str, int], list[dict[str, int]])
221 self.assertEqual(dict[T, list[int]][str], dict[str, list[int]])
222
223 self.assertEqual(list[List[T]][int], list[List[int]])
224 self.assertEqual(list[Dict[K, V]][str, int], list[Dict[str, int]])
225 self.assertEqual(list[Union[K, V]][str, int], list[Union[str, int]])
226 self.assertEqual(list[Callable[[K, V], K]][str, int],
227 list[Callable[[str, int], str]])
228 self.assertEqual(dict[T, List[int]][str], dict[str, List[int]])
229
Guido van Rossum48b069a2020-04-07 09:50:06 -0700230 with self.assertRaises(TypeError):
231 list[int][int]
232 dict[T, int][str, int]
233 dict[str, T][str, int]
234 dict[T, T][str, int]
235
236 def test_equality(self):
237 self.assertEqual(list[int], list[int])
238 self.assertEqual(dict[str, int], dict[str, int])
239 self.assertNotEqual(dict[str, int], dict[str, str])
240 self.assertNotEqual(list, list[int])
241 self.assertNotEqual(list[int], list)
242
243 def test_isinstance(self):
244 self.assertTrue(isinstance([], list))
245 with self.assertRaises(TypeError):
246 isinstance([], list[str])
247
248 def test_issubclass(self):
249 class L(list): ...
250 self.assertTrue(issubclass(L, list))
251 with self.assertRaises(TypeError):
252 issubclass(L, list[str])
253
254 def test_type_generic(self):
255 t = type[int]
256 Test = t('Test', (), {})
257 self.assertTrue(isinstance(Test, type))
258 test = Test()
259 self.assertEqual(t(test), Test)
260 self.assertEqual(t(0), int)
261
262 def test_type_subclass_generic(self):
263 class MyType(type):
264 pass
265 with self.assertRaises(TypeError):
266 MyType[int]
267
268 def test_pickle(self):
269 alias = GenericAlias(list, T)
270 s = pickle.dumps(alias)
271 loaded = pickle.loads(s)
272 self.assertEqual(alias.__origin__, loaded.__origin__)
273 self.assertEqual(alias.__args__, loaded.__args__)
274 self.assertEqual(alias.__parameters__, loaded.__parameters__)
275
276 def test_union(self):
277 a = typing.Union[list[int], list[str]]
278 self.assertEqual(a.__args__, (list[int], list[str]))
279 self.assertEqual(a.__parameters__, ())
280
281 def test_union_generic(self):
Guido van Rossum48b069a2020-04-07 09:50:06 -0700282 a = typing.Union[list[T], tuple[T, ...]]
283 self.assertEqual(a.__args__, (list[T], tuple[T, ...]))
284 self.assertEqual(a.__parameters__, (T,))
285
286
287if __name__ == "__main__":
288 unittest.main()