https://github.com/python/cpython/commit/83ba8c2bba834c0b92de669cac16fcda17485e0e
commit: 83ba8c2bba834c0b92de669cac16fcda17485e0e
branch: main
author: blhsing <[email protected]>
committer: carljm <[email protected]>
date: 2024-11-05T15:53:54-08:00
summary:
gh-70764: inspect.getclosurevars now identifies global variables with
LOAD_GLOBAL (#120143)
files:
A Misc/NEWS.d/next/Library/2024-06-06-04-06-05.gh-issue-70764.6511hw.rst
M Lib/inspect.py
M Lib/test/test_inspect/test_inspect.py
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 08718d82e91582..e3f74e9f047eaf 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1507,11 +1507,15 @@ def getclosurevars(func):
global_vars = {}
builtin_vars = {}
unbound_names = set()
- for name in code.co_names:
- if name in ("None", "True", "False"):
- # Because these used to be builtins instead of keywords, they
- # may still show up as name references. We ignore them.
- continue
+ global_names = set()
+ for instruction in dis.get_instructions(code):
+ opname = instruction.opname
+ name = instruction.argval
+ if opname == "LOAD_ATTR":
+ unbound_names.add(name)
+ elif opname == "LOAD_GLOBAL":
+ global_names.add(name)
+ for name in global_names:
try:
global_vars[name] = global_ns[name]
except KeyError:
diff --git a/Lib/test/test_inspect/test_inspect.py
b/Lib/test/test_inspect/test_inspect.py
index a4430a868676e2..a92627a4d60f68 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -1960,6 +1960,19 @@ def g(local_ref):
builtin_vars, unbound_names)
self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
+ def test_attribute_same_name_as_global_var(self):
+ class C:
+ _global_ref = object()
+ def f():
+ print(C._global_ref, _global_ref)
+ nonlocal_vars = {"C": C}
+ global_vars = {"_global_ref": _global_ref}
+ builtin_vars = {"print": print}
+ unbound_names = {"_global_ref"}
+ expected = inspect.ClosureVars(nonlocal_vars, global_vars,
+ builtin_vars, unbound_names)
+ self.assertEqual(inspect.getclosurevars(f), expected)
+
def test_nonlocal_vars(self):
# More complex tests of nonlocal resolution
def _nonlocal_vars(f):
diff --git
a/Misc/NEWS.d/next/Library/2024-06-06-04-06-05.gh-issue-70764.6511hw.rst
b/Misc/NEWS.d/next/Library/2024-06-06-04-06-05.gh-issue-70764.6511hw.rst
new file mode 100644
index 00000000000000..4cfb66a6ccc6ee
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-06-04-06-05.gh-issue-70764.6511hw.rst
@@ -0,0 +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.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]