blob: a00899f5267d724cba1d301d6f84e08211a65d14 [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
Batuhan Taşkaya03615562020-04-10 17:46:36 +030012from ctypes import Array, LibraryLoader
Ethan Smithe3ec44d2020-04-09 21:47:31 -070013from difflib import SequenceMatcher
14from filecmp import dircmp
15from fileinput import FileInput
Ethan Smith7c4185d2020-04-09 21:25:53 -070016from mmap import mmap
Batuhan Taşkaya2fa67df2020-04-10 07:04:54 +030017from ipaddress import IPv4Network, IPv4Interface, IPv6Network, IPv6Interface
Ethan Smitha8403d02020-04-09 20:28:08 -070018from itertools import chain
Batuhan Taşkaya03615562020-04-10 17:46:36 +030019from http.cookies import Morsel
20from multiprocessing.managers import ValueProxy
21from multiprocessing.pool import ApplyResult
22from multiprocessing.shared_memory import ShareableList
23from multiprocessing.queues import SimpleQueue
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030024from os import DirEntry
Guido van Rossum48b069a2020-04-07 09:50:06 -070025from re import Pattern, Match
Ethan Smith7c4185d2020-04-09 21:25:53 -070026from types import GenericAlias, MappingProxyType, AsyncGeneratorType
Batuhan Taşkaya03615562020-04-10 17:46:36 +030027from tempfile import TemporaryDirectory, SpooledTemporaryFile
28from urllib.parse import SplitResult, ParseResult
29from unittest.case import _AssertRaisesContext
30from queue import Queue, SimpleQueue
Guido van Rossum48b069a2020-04-07 09:50:06 -070031import typing
32
33from typing import TypeVar
34T = TypeVar('T')
35
36class BaseTest(unittest.TestCase):
37 """Test basics."""
38
39 def test_subscriptable(self):
Ethan Smith7c4185d2020-04-09 21:25:53 -070040 for t in (type, tuple, list, dict, set, frozenset, enumerate,
41 mmap,
Guido van Rossum48b069a2020-04-07 09:50:06 -070042 defaultdict, deque,
Ethan Smithe3ec44d2020-04-09 21:47:31 -070043 SequenceMatcher,
44 dircmp,
45 FileInput,
Guido van Rossum48b069a2020-04-07 09:50:06 -070046 OrderedDict, Counter, UserDict, UserList,
47 Pattern, Match,
48 AbstractContextManager, AbstractAsyncContextManager,
49 Awaitable, Coroutine,
50 AsyncIterable, AsyncIterator,
51 AsyncGenerator, Generator,
52 Iterable, Iterator,
53 Reversible,
54 Container, Collection,
55 Callable,
56 Set, MutableSet,
57 Mapping, MutableMapping, MappingView,
58 KeysView, ItemsView, ValuesView,
59 Sequence, MutableSequence,
Ethan Smith7c4185d2020-04-09 21:25:53 -070060 MappingProxyType, AsyncGeneratorType,
Batuhan Taşkaya2fa67df2020-04-10 07:04:54 +030061 DirEntry,
62 IPv4Network, IPv4Interface, IPv6Network, IPv6Interface,
Ethan Smitha8403d02020-04-09 20:28:08 -070063 chain,
Batuhan Taşkaya03615562020-04-10 17:46:36 +030064 TemporaryDirectory, SpooledTemporaryFile,
65 Queue, SimpleQueue,
66 _AssertRaisesContext,
67 Array, LibraryLoader,
68 SplitResult, ParseResult,
69 ValueProxy, ApplyResult,
70 ShareableList, SimpleQueue,
71 Future, _WorkItem,
72 Morsel,
Guido van Rossum48b069a2020-04-07 09:50:06 -070073 ):
74 tname = t.__name__
75 with self.subTest(f"Testing {tname}"):
76 alias = t[int]
77 self.assertIs(alias.__origin__, t)
78 self.assertEqual(alias.__args__, (int,))
79 self.assertEqual(alias.__parameters__, ())
80
81 def test_unsubscriptable(self):
82 for t in int, str, float, Sized, Hashable:
83 tname = t.__name__
84 with self.subTest(f"Testing {tname}"):
85 with self.assertRaises(TypeError):
86 t[int]
87
88 def test_instantiate(self):
89 for t in tuple, list, dict, set, frozenset, defaultdict, deque:
90 tname = t.__name__
91 with self.subTest(f"Testing {tname}"):
92 alias = t[int]
93 self.assertEqual(alias(), t())
94 if t is dict:
95 self.assertEqual(alias(iter([('a', 1), ('b', 2)])), dict(a=1, b=2))
96 self.assertEqual(alias(a=1, b=2), dict(a=1, b=2))
97 elif t is defaultdict:
98 def default():
99 return 'value'
100 a = alias(default)
101 d = defaultdict(default)
102 self.assertEqual(a['test'], d['test'])
103 else:
104 self.assertEqual(alias(iter((1, 2, 3))), t((1, 2, 3)))
105
106 def test_unbound_methods(self):
107 t = list[int]
108 a = t()
109 t.append(a, 'foo')
110 self.assertEqual(a, ['foo'])
111 x = t.__getitem__(a, 0)
112 self.assertEqual(x, 'foo')
113 self.assertEqual(t.__len__(a), 1)
114
115 def test_subclassing(self):
116 class C(list[int]):
117 pass
118 self.assertEqual(C.__bases__, (list,))
119 self.assertEqual(C.__class__, type)
120
121 def test_class_methods(self):
122 t = dict[int, None]
123 self.assertEqual(dict.fromkeys(range(2)), {0: None, 1: None}) # This works
124 self.assertEqual(t.fromkeys(range(2)), {0: None, 1: None}) # Should be equivalent
125
126 def test_no_chaining(self):
127 t = list[int]
128 with self.assertRaises(TypeError):
129 t[int]
130
131 def test_generic_subclass(self):
132 class MyList(list):
133 pass
134 t = MyList[int]
135 self.assertIs(t.__origin__, MyList)
136 self.assertEqual(t.__args__, (int,))
137 self.assertEqual(t.__parameters__, ())
138
139 def test_repr(self):
140 class MyList(list):
141 pass
142 self.assertEqual(repr(list[str]), 'list[str]')
143 self.assertEqual(repr(list[()]), 'list[()]')
144 self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]')
145 self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]'))
146 self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr
147
148 def test_exposed_type(self):
149 import types
150 a = types.GenericAlias(list, int)
151 self.assertEqual(str(a), 'list[int]')
152 self.assertIs(a.__origin__, list)
153 self.assertEqual(a.__args__, (int,))
154 self.assertEqual(a.__parameters__, ())
155
156 def test_parameters(self):
157 from typing import TypeVar
158 T = TypeVar('T')
159 K = TypeVar('K')
160 V = TypeVar('V')
161 D0 = dict[str, int]
162 self.assertEqual(D0.__args__, (str, int))
163 self.assertEqual(D0.__parameters__, ())
164 D1a = dict[str, V]
165 self.assertEqual(D1a.__args__, (str, V))
166 self.assertEqual(D1a.__parameters__, (V,))
167 D1b = dict[K, int]
168 self.assertEqual(D1b.__args__, (K, int))
169 self.assertEqual(D1b.__parameters__, (K,))
170 D2a = dict[K, V]
171 self.assertEqual(D2a.__args__, (K, V))
172 self.assertEqual(D2a.__parameters__, (K, V))
173 D2b = dict[T, T]
174 self.assertEqual(D2b.__args__, (T, T))
175 self.assertEqual(D2b.__parameters__, (T,))
176 L0 = list[str]
177 self.assertEqual(L0.__args__, (str,))
178 self.assertEqual(L0.__parameters__, ())
179 L1 = list[T]
180 self.assertEqual(L1.__args__, (T,))
181 self.assertEqual(L1.__parameters__, (T,))
182
183 def test_parameter_chaining(self):
184 from typing import TypeVar
185 T = TypeVar('T')
186 self.assertEqual(list[T][int], list[int])
187 self.assertEqual(dict[str, T][int], dict[str, int])
188 self.assertEqual(dict[T, int][str], dict[str, int])
189 self.assertEqual(dict[T, T][int], dict[int, int])
190 with self.assertRaises(TypeError):
191 list[int][int]
192 dict[T, int][str, int]
193 dict[str, T][str, int]
194 dict[T, T][str, int]
195
196 def test_equality(self):
197 self.assertEqual(list[int], list[int])
198 self.assertEqual(dict[str, int], dict[str, int])
199 self.assertNotEqual(dict[str, int], dict[str, str])
200 self.assertNotEqual(list, list[int])
201 self.assertNotEqual(list[int], list)
202
203 def test_isinstance(self):
204 self.assertTrue(isinstance([], list))
205 with self.assertRaises(TypeError):
206 isinstance([], list[str])
207
208 def test_issubclass(self):
209 class L(list): ...
210 self.assertTrue(issubclass(L, list))
211 with self.assertRaises(TypeError):
212 issubclass(L, list[str])
213
214 def test_type_generic(self):
215 t = type[int]
216 Test = t('Test', (), {})
217 self.assertTrue(isinstance(Test, type))
218 test = Test()
219 self.assertEqual(t(test), Test)
220 self.assertEqual(t(0), int)
221
222 def test_type_subclass_generic(self):
223 class MyType(type):
224 pass
225 with self.assertRaises(TypeError):
226 MyType[int]
227
228 def test_pickle(self):
229 alias = GenericAlias(list, T)
230 s = pickle.dumps(alias)
231 loaded = pickle.loads(s)
232 self.assertEqual(alias.__origin__, loaded.__origin__)
233 self.assertEqual(alias.__args__, loaded.__args__)
234 self.assertEqual(alias.__parameters__, loaded.__parameters__)
235
236 def test_union(self):
237 a = typing.Union[list[int], list[str]]
238 self.assertEqual(a.__args__, (list[int], list[str]))
239 self.assertEqual(a.__parameters__, ())
240
241 def test_union_generic(self):
242 T = typing.TypeVar('T')
243 a = typing.Union[list[T], tuple[T, ...]]
244 self.assertEqual(a.__args__, (list[T], tuple[T, ...]))
245 self.assertEqual(a.__parameters__, (T,))
246
247
248if __name__ == "__main__":
249 unittest.main()