Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
typing: Add more tests for TypeVar
During the PEP 695 implementation at one point I made
TypeVar.__name__ return garbage, and all of test_typing passed.
So I decided to add a few more tests. In the process I discovered
a minor incompatibility from the C implementation of TypeVar:
empty constraints were returned as None instead of an empty tuple.
  • Loading branch information
JelleZijlstra committed May 17, 2023
commit a3f7db7f943ac5898518f7f79896677e9301a065
42 changes: 42 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,41 @@ def test_basic_plain(self):
self.assertEqual(T, T)
# T is an instance of TypeVar
self.assertIsInstance(T, TypeVar)
self.assertEqual(T.__name__, 'T')
self.assertEqual(T.__constraints__, ())
self.assertIs(T.__bound__, None)
self.assertIs(T.__covariant__, False)
self.assertIs(T.__contravariant__, False)
self.assertIs(T.__infer_variance__, False)

def test_attributes(self):
T_bound = TypeVar('T_bound', bound=int)
self.assertEqual(T_bound.__name__, 'T_bound')
self.assertEqual(T_bound.__constraints__, ())
self.assertIs(T_bound.__bound__, int)

T_constraints = TypeVar('T_constraints', int, str)
self.assertEqual(T_constraints.__name__, 'T_constraints')
self.assertEqual(T_constraints.__constraints__, (int, str))
self.assertIs(T_constraints.__bound__, None)

T_co = TypeVar('T_co', covariant=True)
self.assertEqual(T_co.__name__, 'T_co')
self.assertIs(T_co.__covariant__, True)
self.assertIs(T_co.__contravariant__, False)
self.assertIs(T_co.__infer_variance__, False)

T_contra = TypeVar('T_contra', contravariant=True)
self.assertEqual(T_contra.__name__, 'T_contra')
self.assertIs(T_contra.__covariant__, False)
self.assertIs(T_contra.__contravariant__, True)
self.assertIs(T_contra.__infer_variance__, False)

T_infer = TypeVar('T_infer', infer_variance=True)
self.assertEqual(T_infer.__name__, 'T_infer')
self.assertIs(T_infer.__covariant__, False)
self.assertIs(T_infer.__contravariant__, False)
self.assertIs(T_infer.__infer_variance__, True)

def test_typevar_instance_type_error(self):
T = TypeVar('T')
Expand Down Expand Up @@ -458,6 +493,12 @@ def test_no_bivariant(self):
with self.assertRaises(ValueError):
TypeVar('T', covariant=True, contravariant=True)

def test_cannot_combine_explicit_and_infer(self):
with self.assertRaises(ValueError):
TypeVar('T', covariant=True, infer_variance=True)
with self.assertRaises(ValueError):
TypeVar('T', contravariant=True, infer_variance=True)

def test_var_substitution(self):
T = TypeVar('T')
subst = T.__typing_subst__
Expand Down Expand Up @@ -7812,6 +7853,7 @@ def test_basic_plain(self):
P = ParamSpec('P')
self.assertEqual(P, P)
self.assertIsInstance(P, ParamSpec)
self.assertEqual(P.__name__, 'P')

def test_valid_uses(self):
P = ParamSpec('P')
Expand Down
2 changes: 1 addition & 1 deletion Objects/typevarobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored))
return Py_NewRef(self->constraints);
}
if (self->evaluate_constraints == NULL) {
Py_RETURN_NONE;
return PyTuple_New(0);
}
PyObject *constraints = PyObject_CallNoArgs(self->evaluate_constraints);
self->constraints = Py_XNewRef(constraints);
Expand Down