Issue #29354: Fixed inspect.getargs() for parameters which are cell
variables.
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 6d645bd..0a6cfd7 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -769,8 +769,11 @@
if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
remain.append(value)
count.append(value)
- elif opname == 'STORE_FAST':
- stack.append(names[value])
+ elif opname in ('STORE_FAST', 'STORE_DEREF'):
+ if opname == 'STORE_FAST':
+ stack.append(names[value])
+ else:
+ stack.append(co.co_cellvars[value])
# Special case for sublists of length 1: def foo((bar))
# doesn't generate the UNPACK_TUPLE bytecode, so if
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index ecc04cb..3d9c3b1 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -502,6 +502,15 @@
'g', 'h', (3, (4, (5,))),
'(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
+ def spam_deref(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
+ def eggs():
+ return a + b + c + d + e + f + g + h
+ return eggs
+ self.assertArgSpecEquals(spam_deref,
+ ['a', 'b', 'c', 'd', ['e', ['f']]],
+ 'g', 'h', (3, (4, (5,))),
+ '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
+
def test_getargspec_method(self):
class A(object):
def m(self):
@@ -515,9 +524,15 @@
exec 'def sublistOfOne((foo,)): return 1'
self.assertArgSpecEquals(sublistOfOne, [['foo']])
+ exec 'def sublistOfOne((foo,)): return (lambda: foo)'
+ self.assertArgSpecEquals(sublistOfOne, [['foo']])
+
exec 'def fakeSublistOfOne((foo)): return 1'
self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
+ exec 'def sublistOfOne((foo)): return (lambda: foo)'
+ self.assertArgSpecEquals(sublistOfOne, ['foo'])
+
def _classify_test(self, newstyle):
"""Helper for testing that classify_class_attrs finds a bunch of
@@ -820,6 +835,23 @@
self.assertEqualException(f3, '1, 2')
self.assertEqualException(f3, '1, 2, a=1, b=2')
+
+class TestGetcallargsFunctionsCellVars(TestGetcallargsFunctions):
+
+ def makeCallable(self, signature):
+ """Create a function that returns its locals(), excluding the
+ autogenerated '.1', '.2', etc. tuple param names (if any)."""
+ with check_py3k_warnings(
+ ("tuple parameter unpacking has been removed", SyntaxWarning),
+ quiet=True):
+ code = """lambda %s: (
+ (lambda: a+b+c+d+d+e+f+g+h), # make parameters cell vars
+ dict(i for i in locals().items()
+ if not is_tuplename(i[0]))
+ )[1]"""
+ return eval(code % signature, {'is_tuplename' : self.is_tuplename})
+
+
class TestGetcallargsMethods(TestGetcallargsFunctions):
def setUp(self):
@@ -857,8 +889,8 @@
run_unittest(
TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
- TestGetcallargsFunctions, TestGetcallargsMethods,
- TestGetcallargsUnboundMethods)
+ TestGetcallargsFunctions, TestGetcallargsFunctionsCellVars,
+ TestGetcallargsMethods, TestGetcallargsUnboundMethods)
if __name__ == "__main__":
test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
index a3f6aa1..0e4921c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -26,6 +26,9 @@
Library
-------
+- Issue #29354: Fixed inspect.getargs() for parameters which are cell
+ variables.
+
- Issue #29335: Fix subprocess.Popen.wait() when the child process has
exited to a stopped instead of terminated state (ex: when under ptrace).