Skip to content

Commit 83ba8c2

Browse files
authored
gh-70764: inspect.getclosurevars now identifies global variables with LOAD_GLOBAL (#120143)
1 parent fc233f4 commit 83ba8c2

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

Lib/inspect.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,11 +1507,15 @@ def getclosurevars(func):
15071507
global_vars = {}
15081508
builtin_vars = {}
15091509
unbound_names = set()
1510-
for name in code.co_names:
1511-
if name in ("None", "True", "False"):
1512-
# Because these used to be builtins instead of keywords, they
1513-
# may still show up as name references. We ignore them.
1514-
continue
1510+
global_names = set()
1511+
for instruction in dis.get_instructions(code):
1512+
opname = instruction.opname
1513+
name = instruction.argval
1514+
if opname == "LOAD_ATTR":
1515+
unbound_names.add(name)
1516+
elif opname == "LOAD_GLOBAL":
1517+
global_names.add(name)
1518+
for name in global_names:
15151519
try:
15161520
global_vars[name] = global_ns[name]
15171521
except KeyError:

Lib/test/test_inspect/test_inspect.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,19 @@ def g(local_ref):
19601960
builtin_vars, unbound_names)
19611961
self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
19621962

1963+
def test_attribute_same_name_as_global_var(self):
1964+
class C:
1965+
_global_ref = object()
1966+
def f():
1967+
print(C._global_ref, _global_ref)
1968+
nonlocal_vars = {"C": C}
1969+
global_vars = {"_global_ref": _global_ref}
1970+
builtin_vars = {"print": print}
1971+
unbound_names = {"_global_ref"}
1972+
expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1973+
builtin_vars, unbound_names)
1974+
self.assertEqual(inspect.getclosurevars(f), expected)
1975+
19631976
def test_nonlocal_vars(self):
19641977
# More complex tests of nonlocal resolution
19651978
def _nonlocal_vars(f):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed an issue where :func:`inspect.getclosurevars` would incorrectly classify an attribute name as a global variable when the name exists both as an attribute name and a global variable.

0 commit comments

Comments
 (0)
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