mirror of https://github.com/python/cpython
gh-104879: Fix TypeAliasType.__module__ in exec() (#104881)
This commit is contained in:
parent
1497607a8e
commit
fe77a99fc8
|
@ -159,6 +159,15 @@ class TypeAliasConstructorTest(unittest.TestCase):
|
||||||
self.assertEqual(TA.__type_params__, ())
|
self.assertEqual(TA.__type_params__, ())
|
||||||
self.assertEqual(TA.__module__, __name__)
|
self.assertEqual(TA.__module__, __name__)
|
||||||
|
|
||||||
|
def test_attributes_with_exec(self):
|
||||||
|
ns = {}
|
||||||
|
exec("type TA = int", ns, ns)
|
||||||
|
TA = ns["TA"]
|
||||||
|
self.assertEqual(TA.__name__, "TA")
|
||||||
|
self.assertIs(TA.__value__, int)
|
||||||
|
self.assertEqual(TA.__type_params__, ())
|
||||||
|
self.assertIs(TA.__module__, None)
|
||||||
|
|
||||||
def test_generic(self):
|
def test_generic(self):
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
TA = TypeAliasType("TA", list[T], type_params=(T,))
|
TA = TypeAliasType("TA", list[T], type_params=(T,))
|
||||||
|
|
|
@ -373,6 +373,20 @@ class TypeVarTests(BaseTestCase):
|
||||||
self.assertIs(T.__covariant__, False)
|
self.assertIs(T.__covariant__, False)
|
||||||
self.assertIs(T.__contravariant__, False)
|
self.assertIs(T.__contravariant__, False)
|
||||||
self.assertIs(T.__infer_variance__, False)
|
self.assertIs(T.__infer_variance__, False)
|
||||||
|
self.assertEqual(T.__module__, __name__)
|
||||||
|
|
||||||
|
def test_basic_with_exec(self):
|
||||||
|
ns = {}
|
||||||
|
exec('from typing import TypeVar; T = TypeVar("T", bound=float)', ns, ns)
|
||||||
|
T = ns['T']
|
||||||
|
self.assertIsInstance(T, TypeVar)
|
||||||
|
self.assertEqual(T.__name__, 'T')
|
||||||
|
self.assertEqual(T.__constraints__, ())
|
||||||
|
self.assertIs(T.__bound__, float)
|
||||||
|
self.assertIs(T.__covariant__, False)
|
||||||
|
self.assertIs(T.__contravariant__, False)
|
||||||
|
self.assertIs(T.__infer_variance__, False)
|
||||||
|
self.assertIs(T.__module__, None)
|
||||||
|
|
||||||
def test_attributes(self):
|
def test_attributes(self):
|
||||||
T_bound = TypeVar('T_bound', bound=int)
|
T_bound = TypeVar('T_bound', bound=int)
|
||||||
|
@ -939,6 +953,17 @@ class TypeVarTupleTests(BaseTestCase):
|
||||||
Ts2 = TypeVarTuple('Ts2')
|
Ts2 = TypeVarTuple('Ts2')
|
||||||
self.assertEqual(Ts2.__name__, 'Ts2')
|
self.assertEqual(Ts2.__name__, 'Ts2')
|
||||||
|
|
||||||
|
def test_module(self):
|
||||||
|
Ts = TypeVarTuple('Ts')
|
||||||
|
self.assertEqual(Ts.__module__, __name__)
|
||||||
|
|
||||||
|
def test_exec(self):
|
||||||
|
ns = {}
|
||||||
|
exec('from typing import TypeVarTuple; Ts = TypeVarTuple("Ts")', ns)
|
||||||
|
Ts = ns['Ts']
|
||||||
|
self.assertEqual(Ts.__name__, 'Ts')
|
||||||
|
self.assertIs(Ts.__module__, None)
|
||||||
|
|
||||||
def test_instance_is_equal_to_itself(self):
|
def test_instance_is_equal_to_itself(self):
|
||||||
Ts = TypeVarTuple('Ts')
|
Ts = TypeVarTuple('Ts')
|
||||||
self.assertEqual(Ts, Ts)
|
self.assertEqual(Ts, Ts)
|
||||||
|
@ -7985,6 +8010,15 @@ class ParamSpecTests(BaseTestCase):
|
||||||
self.assertEqual(P, P)
|
self.assertEqual(P, P)
|
||||||
self.assertIsInstance(P, ParamSpec)
|
self.assertIsInstance(P, ParamSpec)
|
||||||
self.assertEqual(P.__name__, 'P')
|
self.assertEqual(P.__name__, 'P')
|
||||||
|
self.assertEqual(P.__module__, __name__)
|
||||||
|
|
||||||
|
def test_basic_with_exec(self):
|
||||||
|
ns = {}
|
||||||
|
exec('from typing import ParamSpec; P = ParamSpec("P")', ns, ns)
|
||||||
|
P = ns['P']
|
||||||
|
self.assertIsInstance(P, ParamSpec)
|
||||||
|
self.assertEqual(P.__name__, 'P')
|
||||||
|
self.assertIs(P.__module__, None)
|
||||||
|
|
||||||
def test_valid_uses(self):
|
def test_valid_uses(self):
|
||||||
P = ParamSpec('P')
|
P = ParamSpec('P')
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crash when accessing the ``__module__`` attribute of type aliases
|
||||||
|
defined outside a module. Patch by Jelle Zijlstra.
|
|
@ -1319,8 +1319,13 @@ typealias_module(PyObject *self, void *unused)
|
||||||
return Py_NewRef(ta->module);
|
return Py_NewRef(ta->module);
|
||||||
}
|
}
|
||||||
if (ta->compute_value != NULL) {
|
if (ta->compute_value != NULL) {
|
||||||
// PyFunction_GetModule() returns a borrowed reference
|
PyObject* mod = PyFunction_GetModule(ta->compute_value);
|
||||||
return Py_NewRef(PyFunction_GetModule(ta->compute_value));
|
if (mod != NULL) {
|
||||||
|
// PyFunction_GetModule() returns a borrowed reference,
|
||||||
|
// and it may return NULL (e.g., for functions defined
|
||||||
|
// in an exec()'ed block).
|
||||||
|
return Py_NewRef(mod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue