]> granicus.if.org Git - python/commitdiff
Merged revisions 76416-76417 via svnmerge from
authorBenjamin Peterson <benjamin@python.org>
Thu, 19 Nov 2009 23:01:36 +0000 (23:01 +0000)
committerBenjamin Peterson <benjamin@python.org>
Thu, 19 Nov 2009 23:01:36 +0000 (23:01 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r76416 | benjamin.peterson | 2009-11-19 16:54:57 -0600 (Thu, 19 Nov 2009) | 10 lines

  improve several corner cases related with argument names in parenthesis

  - Fix #7362: give a good error message for parenthesized arguments with
    defaults.

  - Add a py3k warning for any parenthesized arguments since those are not allowed
    in Py3.  This warning is not given in tuple unpacking, since that incurs the
    tuple unpacking warning.
........
  r76417 | benjamin.peterson | 2009-11-19 16:58:01 -0600 (Thu, 19 Nov 2009) | 1 line

  add news notes for r76416
........

Lib/test/test_py3kwarn.py
Lib/test/test_syntax.py
Misc/NEWS
Python/ast.c

index 6d8863ad7b50faa15e0c952f5b22fc1d62fe562a..55b327eaa9b0572604abc2ac80d6ab2564380671 100644 (file)
@@ -31,6 +31,18 @@ class TestPy3KWarnings(unittest.TestCase):
             exec "`2`" in {}
         self.assertWarning(None, w, expected)
 
+    def test_paren_arg_names(self):
+        expected = 'parenthesized argument names are invalid in 3.x'
+        def check(s):
+            exec s in {}
+            self.assertWarning(None, w, expected)
+        with check_warnings() as w:
+            check("def f((x)): pass")
+            check("def f((((x))), (y)): pass")
+            check("def f((x), (((y))), m=32): pass")
+            # Something like def f((a, (b))): pass will raise the tuple
+            # unpacking warning.
+
     def test_bool_assign(self):
         # So we don't screw up our globals
         def safe_exec(expr):
index e978a6ec7a8fd59743182a8e3e7b40e8a8d06ad2..366c1e80b20b0eb9b3d4364d187a2ef48ec8fe39 100644 (file)
@@ -447,10 +447,14 @@ class SyntaxTestCase(unittest.TestCase):
                 self.fail("SyntaxError is not a %s" % subclass.__name__)
             mo = re.search(errtext, str(err))
             if mo is None:
-                self.fail("SyntaxError did not contain '%r'" % (errtext,))
+                self.fail("%s did not contain '%r'" % (err, errtext,))
         else:
             self.fail("compile() did not raise SyntaxError")
 
+    def test_paren_arg_with_default(self):
+        self._check_error("def f((x)=23): pass",
+                          "parenthesized arg with default")
+
     def test_assign_call(self):
         self._check_error("f() = 1", "assign")
 
index 8c09401f1f2696022097ca8629f081088f3f8bcc..277b892f9173445b4f63c324da1dd389e0b9a955 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.6.5
 Core and Builtins
 -----------------
 
+- Add Py3k warnings for parameter names in parenthesis.
+
+- Issue #7362: Give a propery error message for def f((x)=3): pass.
+
 - Issue #7085: Fix crash when importing some extensions in a thread
   on MacOSX 10.6.
 
index b89e29c55cc98df9a902449e4ebc1f0a2e5862ca..574a3d817cebedbc6285e476e28c2d7ad82ef8b0 100644 (file)
@@ -682,7 +682,8 @@ ast_for_arguments(struct compiling *c, const node *n)
     while (i < NCH(n)) {
         ch = CHILD(n, i);
         switch (TYPE(ch)) {
-            case fpdef:
+            case fpdef: {
+                int complex_args = 0, parenthesized = 0;
             handle_fpdef:
                 /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is
                    anything other than EQUAL or a comma? */
@@ -697,6 +698,12 @@ ast_for_arguments(struct compiling *c, const node *n)
                     found_default = 1;
                 }
                 else if (found_default) {
+                    /* def f((x)=4): pass should raise an error.
+                       def f((x, (y))): pass will just incur the tuple unpacking warning. */
+                    if (parenthesized && !complex_args) {
+                        ast_error(n, "parenthesized arg with default");
+                        goto error;
+                    }
                     ast_error(n, 
                              "non-default argument follows default argument");
                     goto error;
@@ -709,6 +716,7 @@ ast_for_arguments(struct compiling *c, const node *n)
                         if (Py_Py3kWarningFlag && !ast_warn(c, ch,
                             "tuple parameter unpacking has been removed in 3.x"))
                             goto error;
+                        complex_args = 1;
                         asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
                         if (!asdl_seq_GET(args, k-1))
                                 goto error;
@@ -716,6 +724,7 @@ ast_for_arguments(struct compiling *c, const node *n)
                         /* def foo((x)): setup for checking NAME below. */
                         /* Loop because there can be many parens and tuple
                            unpacking mixed in. */
+                        parenthesized = 1;
                         ch = CHILD(ch, 0);
                         assert(TYPE(ch) == fpdef);
                         goto handle_fpdef;
@@ -737,7 +746,13 @@ ast_for_arguments(struct compiling *c, const node *n)
                                          
                 }
                 i += 2; /* the name and the comma */
+                if (parenthesized && Py_Py3kWarningFlag &&
+                    !ast_warn(c, ch, "parenthesized argument names "
+                              "are invalid in 3.x"))
+                    goto error;
+
                 break;
+            }
             case STAR:
                 if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
                     goto error;