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