diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-02-01 20:53:03 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2017-02-01 20:53:03 (GMT) |
commit | 3b23004112aefffa72a3763916d78f12b9e056fe (patch) | |
tree | 5b7a93c73b9f632ddea44d4989e3850e2c7a421c | |
parent | 8e21cc3ce010990b043068f0fab13e71c827341f (diff) | |
download | cpython-3b23004112aefffa72a3763916d78f12b9e056fe.zip cpython-3b23004112aefffa72a3763916d78f12b9e056fe.tar.gz cpython-3b23004112aefffa72a3763916d78f12b9e056fe.tar.bz2 |
Issue #29354: Fixed inspect.getargs() for parameters which are cell
variables.
-rw-r--r-- | Lib/inspect.py | 7 | ||||
-rw-r--r-- | Lib/test/test_inspect.py | 36 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 42 insertions, 4 deletions
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 @@ def getargs(co): 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 @@ class TestClassesAndFunctions(unittest.TestCase): '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 @@ class TestClassesAndFunctions(unittest.TestCase): 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 @@ class TestGetcallargsFunctions(unittest.TestCase): 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 @@ def test_main(): run_unittest( TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates, - TestGetcallargsFunctions, TestGetcallargsMethods, - TestGetcallargsUnboundMethods) + TestGetcallargsFunctions, TestGetcallargsFunctionsCellVars, + TestGetcallargsMethods, TestGetcallargsUnboundMethods) if __name__ == "__main__": test_main() @@ -26,6 +26,9 @@ Extension Modules 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). |