Skip to content

Commit 5505d97

Browse files
committed
Don't mutate globals!
1 parent 4f95b1c commit 5505d97

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

Lib/test/test_typing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4859,6 +4859,8 @@ def f(x: X): ...
48594859
)
48604860

48614861
def test_pep695_generic_with_future_annotations(self):
4862+
original_globals = dict(ann_module695.__dict__)
4863+
48624864
hints_for_A = get_type_hints(ann_module695.A)
48634865
A_type_params = ann_module695.A.__type_params__
48644866
self.assertIs(hints_for_A["x"], A_type_params[0])
@@ -4898,6 +4900,9 @@ def test_pep695_generic_with_future_annotations(self):
48984900
{"x": params["Foo"], "y": params["Bar"], "return": types.NoneType}
48994901
)
49004902

4903+
# should not have changed as a result of the get_type_hints() calls!
4904+
self.assertEqual(ann_module695.__dict__, original_globals)
4905+
49014906
def test_extended_generic_rules_subclassing(self):
49024907
class T1(Tuple[T, KT]): ...
49034908
class T2(Tuple[T, ...]): ...

Lib/typing.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,14 +1068,16 @@ def _evaluate(self, globalns, localns, type_params=_sentinel, *, recursive_guard
10681068
# names in the global scope (which here are called `localns`!),
10691069
# but should in turn be overridden by names in the class scope
10701070
# (which here are called `globalns`!)
1071-
type_params = {param.__name__: param for param in type_params}
1072-
if self.__forward_is_class__:
1073-
for name, param in type_params.items():
1074-
if name not in globalns:
1075-
globalns[name] = param
1076-
localns.pop(name, None)
1077-
else:
1078-
localns = type_params | localns
1071+
if type_params:
1072+
name_to_param_map = {param.__name__: param for param in type_params}
1073+
if self.__forward_is_class__:
1074+
globalns, localns = dict(globalns), dict(localns)
1075+
for name, param in name_to_param_map.items():
1076+
if name not in globalns:
1077+
globalns[name] = param
1078+
localns.pop(name, None)
1079+
else:
1080+
localns = name_to_param_map | localns
10791081

10801082
type_ = _type_check(
10811083
eval(self.__forward_code__, globalns, localns),

0 commit comments

Comments
 (0)