]> granicus.if.org Git - python/commitdiff
Issue #29354: Fixed inspect.getargs() for parameters which are cell
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 1 Feb 2017 20:53:03 +0000 (22:53 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Wed, 1 Feb 2017 20:53:03 +0000 (22:53 +0200)
variables.

Lib/inspect.py
Lib/test/test_inspect.py
Misc/NEWS

index 6d645bd04653141993157554e7ff2fcdfdb6edb3..0a6cfd795184d507548ad89ccfb72bb0f3904093 100644 (file)
@@ -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
index ecc04cb75d59b128b13e1cb10078e725ba3a87ef..3d9c3b119e9fc53d1d3152636d49fb73d45ed711 100644 (file)
@@ -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()
index a3f6aa160994d7ea197e001c943be0e360deb8b3..0e4921c09fa3712ccdebfea9656fc377d1f8f6a0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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).