Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-87390: Add tests demonstrating current type variable substitution behaviour #32341

Merged
merged 24 commits into from
Apr 29, 2022
Merged
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f508d12
Add integration tests for type variable substitution
mrahtz Apr 5, 2022
ea104b9
Add tests for list, dict and tuple
mrahtz Apr 8, 2022
526d9e8
Add tests for Tuple
mrahtz Apr 9, 2022
0f022db
Revert "Add tests for Tuple"
mrahtz Apr 9, 2022
cc7bf8c
Make it easier to tests all tuple, list and dict types
mrahtz Apr 10, 2022
458b5dd
TypeVarSubstitutionTests -> GenericAliasSubstitutionTests
mrahtz Apr 10, 2022
0c8ba38
Remove question marks from cases I'm actually pretty sure about
mrahtz Apr 10, 2022
db24e70
Note that list[] should only take one argument
mrahtz Apr 11, 2022
15a4809
Leave unpacked tuples unsimplified
mrahtz Apr 11, 2022
0d7d2eb
Add generic[*Ts][*tuple[*Ts]]
mrahtz Apr 11, 2022
ab01c8a
Update comments based on decision to leave unpacked tuples unsimplified
mrahtz Apr 11, 2022
c4fe922
Add tests for generic[T1, bool, T2][*tuple[int, str]]
mrahtz Apr 15, 2022
d55b8fb
Update comments based on decision to unpack *some* tuples
mrahtz Apr 15, 2022
e858fc6
Note that generic[*tuple[()]] should raise TypeError
mrahtz Apr 16, 2022
3bc7d26
Note that C[T, *tuple[int, ...]][int] raises TypeError only because C…
mrahtz Apr 16, 2022
c980e4f
State that multiple unpackings should be allowed where possible
mrahtz Apr 16, 2022
95b7210
Add test for generic[T1, *tuple[int, ...], T2][str, bool, float]
mrahtz Apr 16, 2022
96394b1
Update comments according to revised tentative spec at https://github…
mrahtz Apr 16, 2022
ed9a557
Update expected comments to account for unpacked types only being val…
mrahtz Apr 18, 2022
faa9fc3
Merge branch 'main' into subst-tests
mrahtz Apr 18, 2022
9947fc0
Update to reflect results after merging latest main
mrahtz Apr 18, 2022
12496fc
Update ALL tests to reflect results after merging latest main
mrahtz Apr 18, 2022
db9af53
Remove comments saying we should get a TypeError in cases where we *d…
mrahtz Apr 18, 2022
c5b5a63
Update comments on expected results based on latest tentative spec at…
mrahtz Apr 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,83 @@ def test_bad_var_substitution(self):
list[T][arg]


class TypeVarSubstitutionTests(BaseTestCase):

def test(self):
T = TypeVar('T')
T1 = TypeVar('T1')
T2 = TypeVar('T2')
Ts = TypeVarTuple('Ts')
class A(Generic[T]): pass
class B(Generic[T1, T2]): pass
mrahtz marked this conversation as resolved.
Show resolved Hide resolved
class C(Generic[*Ts]): pass
tests = [
('A[T]', '[()]', TypeError),
('A[T]', '[int]', A[int]),
('A[T]', '[int, str]', TypeError),
('A[T]', '[tuple[int, ...]]', A[tuple[int, ...]]),
('A[T]', '[*tuple[()]]', A[*tuple[()]]), # Should raise TypeError?
('A[T]', '[*tuple[int]]', A[*tuple[int]]), # Should be A[int]?
('A[T]', '[*tuple[int, str]]', A[*tuple[int, str]]), # Should raise TypeError?
('A[T]', '[*tuple[int, ...]]', A[*tuple[int, ...]]), # Should raise TypeError?
('A[T]', '[*Ts]', A[T][*Ts]), # Should raise TypeError?
('A[T]', '[T, *Ts]', TypeError),
('A[T]', '[*Ts, T]', TypeError),
('A[T, *tuple[int, ...]]', '[int]', TypeError),

('B[T1, T2]', '[()]', TypeError),
('B[T1, T2]', '[int]', TypeError),
('B[T1, T2]', '[int, str]', B[int, str]),
('B[T1, T2]', '[int, str, bool]', TypeError),
('B[T1, T2]', '[*tuple[int]]', TypeError),
('B[T1, T2]', '[*tuple[int, str]]', TypeError), # Should be B[int, str]?
('B[T1, T2]', '[*tuple[int, str, bool]]', TypeError),
('B[T1, T2]', '[*tuple[int, str], *tuple[float, bool]]', B[*tuple[int, str], *tuple[float, bool]]), # Should raise TypeError?
('B[T1, T2]', '[tuple[int, ...]]', TypeError),
('B[T1, T2]', '[tuple[int, ...], tuple[str, ...]]', B[tuple[int, ...], tuple[str, ...]]),
('B[T1, T2]', '[*tuple[int, ...]]', TypeError),
('B[T1, T2]', '[*tuple[int, ...], *tuple[str, ...]]', B[*tuple[int, ...], *tuple[str, ...]]), # Should raise TypeError?
('B[T1, T2]', '[*Ts]', TypeError),
('B[T1, T2]', '[T, *Ts]', B[T, *Ts]), # Should raise TypeError?
('B[T1, T2]', '[*Ts, T]', B[*Ts, T]), # Should raise TypeError?
('B[T1, *tuple[int, ...]]', '[str]', B[str, *tuple[int, ...]]), # Should raise TypeError?
('B[T1, T2, *tuple[int, ...]]', '[int, str]', TypeError),

('C[*Ts]', '[()]', C[()]),
('C[*Ts]', '[int]', C[int]),
('C[*Ts]', '[int, str]', C[int, str]),
('C[*Ts]', '[*tuple[int]]', C[*tuple[int]]), # Should be C[int]?
('C[*Ts]', '[*tuple[int, str]]', C[*tuple[int, str]]), # Should be C[int, str]?
('C[*Ts]', '[tuple[int, ...]]', C[tuple[int, ...]]),
('C[*Ts]', '[tuple[int, ...], tuple[str, ...]]', C[tuple[int, ...], tuple[str, ...]]),
('C[*Ts]', '[*tuple[int, ...]]', C[*tuple[int, ...]]),
('C[*Ts]', '[*tuple[int, ...], *tuple[str, ...]]', C[*tuple[int, ...], *tuple[str, ...]]),
('C[*Ts]', '[*Ts]', C[*Ts]),
('C[*Ts]', '[T, *Ts]', C[T, *Ts]),
('C[*Ts]', '[*Ts, T]', C[*Ts, T]),
('C[T, *Ts]', '[int]', C[int]),
('C[T, *Ts]', '[int, str]', C[int, str]),
('C[T, *Ts]', '[int, str, bool]', C[int, str, bool]),
('C[*Ts, T]', '[int]', C[int]),
('C[*Ts, T]', '[int, str]', C[int, str]),
('C[*Ts, T]', '[int, str, bool]', C[int, str, bool]),
('C[T, *Ts]', '[*tuple[int, ...]]', C[*tuple[int, ...]]), # Should be C[int, *tuple[int, ...]]?
('C[T, *tuple[int, ...]]', '[str]', C[str, *tuple[int, ...]]),
('C[T1, T2, *tuple[int, ...]]', '[str, bool]', C[str, bool, *tuple[int, ...]]),
('C[T1, *tuple[int, ...], T2]', '[str, bool]', C[str, *tuple[int, ...], bool]),
]
for alias, args, expected in tests:
with self.subTest(alias=alias, args=args, expected=expected):
if inspect.isclass(expected) and issubclass(expected, Exception):
with self.assertRaises(expected):
eval(alias + args)
else:
self.assertEqual(
eval(alias + args),
expected,
)


class UnpackTests(BaseTestCase):

def test_accepts_single_type(self):
Expand Down