From 0268b072d84bc4be890d1b7459815ba1cb9f9945 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 25 Sep 2024 16:30:17 -0700 Subject: [PATCH] gh-119180: Disallow instantiation of ConstEvaluator objects (#124561) --- Lib/test/test_type_params.py | 11 +++++++++++ Objects/typevarobject.c | 5 +++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py index dc0c0d0829f..8c21553e410 100644 --- a/Lib/test/test_type_params.py +++ b/Lib/test/test_type_params.py @@ -1452,3 +1452,14 @@ class TestEvaluateFunctions(unittest.TestCase): self.assertEqual(annotationlib.call_evaluate_function(case.evaluate_constraints, annotationlib.Format.VALUE), (int, str)) self.assertEqual(annotationlib.call_evaluate_function(case.evaluate_constraints, annotationlib.Format.FORWARDREF), (int, str)) self.assertEqual(annotationlib.call_evaluate_function(case.evaluate_constraints, annotationlib.Format.SOURCE), '(int, str)') + + def test_const_evaluator(self): + T = TypeVar("T", bound=int) + self.assertEqual(repr(T.evaluate_bound), ">") + + ConstEvaluator = type(T.evaluate_bound) + + with self.assertRaisesRegex(TypeError, r"cannot create '_typing\._ConstEvaluator' instances"): + ConstEvaluator() # This used to segfault. + with self.assertRaisesRegex(TypeError, r"cannot set 'attribute' attribute of immutable type '_typing\._ConstEvaluator'"): + ConstEvaluator.attribute = 1 diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index d3656155fae..09e9ab39364 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -151,7 +151,7 @@ constevaluator_clear(PyObject *self) } static PyObject * -constevaluator_repr(PyObject *self, PyObject *repr) +constevaluator_repr(PyObject *self) { PyObject *value = ((constevaluatorobject *)self)->value; return PyUnicode_FromFormat("", value); @@ -242,7 +242,8 @@ static PyType_Slot constevaluator_slots[] = { PyType_Spec constevaluator_spec = { .name = "_typing._ConstEvaluator", .basicsize = sizeof(constevaluatorobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_DISALLOW_INSTANTIATION, .slots = constevaluator_slots, };