From a3f7db7f943ac5898518f7f79896677e9301a065 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 16 May 2023 18:41:12 -0700 Subject: [PATCH 1/2] 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. --- Lib/test/test_typing.py | 42 +++++++++++++++++++++++++++++++++++++++++ Objects/typevarobject.c | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 0cd67c51e50838..045f2a3b4dfe18 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -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') @@ -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__ @@ -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') diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index b0578756f7dfcc..4464e7a9da89db 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -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); From 254e1cf8451b03647fc9d7cacf83508b96da8f99 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 16 May 2023 19:14:34 -0700 Subject: [PATCH 2/2] Fix test_type_params --- Lib/test/test_type_params.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py index 3ca13c21c61a12..96bd1fa0bab990 100644 --- a/Lib/test/test_type_params.py +++ b/Lib/test/test_type_params.py @@ -425,11 +425,11 @@ class Foo[T: Foo, U: (Foo, Foo)]: type_params = Foo.__type_params__ self.assertEqual(len(type_params), 2) self.assertEqual(type_params[0].__name__, "T") - self.assertEqual(type_params[0].__bound__, Foo) - self.assertEqual(type_params[0].__constraints__, None) + self.assertIs(type_params[0].__bound__, Foo) + self.assertEqual(type_params[0].__constraints__, ()) self.assertEqual(type_params[1].__name__, "U") - self.assertEqual(type_params[1].__bound__, None) + self.assertIs(type_params[1].__bound__, None) self.assertEqual(type_params[1].__constraints__, (Foo, Foo)) def test_evaluation_error(self): @@ -439,16 +439,16 @@ class Foo[T: Undefined, U: (Undefined,)]: type_params = Foo.__type_params__ with self.assertRaises(NameError): type_params[0].__bound__ - self.assertEqual(type_params[0].__constraints__, None) - self.assertEqual(type_params[1].__bound__, None) + self.assertEqual(type_params[0].__constraints__, ()) + self.assertIs(type_params[1].__bound__, None) with self.assertRaises(NameError): type_params[1].__constraints__ Undefined = "defined" self.assertEqual(type_params[0].__bound__, "defined") - self.assertEqual(type_params[0].__constraints__, None) + self.assertEqual(type_params[0].__constraints__, ()) - self.assertEqual(type_params[1].__bound__, None) + self.assertIs(type_params[1].__bound__, None) self.assertEqual(type_params[1].__constraints__, ("defined",)) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy