Merged revisions 76416-76417 via svnmerge from

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
........
This commit is contained in:
Benjamin Peterson 2009-11-19 23:01:36 +00:00
parent aa4af333ec
commit 440847cf8e
4 changed files with 37 additions and 2 deletions

View File

@ -31,6 +31,18 @@ class TestPy3KWarnings(unittest.TestCase):
exec "`2`" in {} exec "`2`" in {}
self.assertWarning(None, w, expected) 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): def test_bool_assign(self):
# So we don't screw up our globals # So we don't screw up our globals
def safe_exec(expr): def safe_exec(expr):

View File

@ -447,10 +447,14 @@ class SyntaxTestCase(unittest.TestCase):
self.fail("SyntaxError is not a %s" % subclass.__name__) self.fail("SyntaxError is not a %s" % subclass.__name__)
mo = re.search(errtext, str(err)) mo = re.search(errtext, str(err))
if mo is None: if mo is None:
self.fail("SyntaxError did not contain '%r'" % (errtext,)) self.fail("%s did not contain '%r'" % (err, errtext,))
else: else:
self.fail("compile() did not raise SyntaxError") 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): def test_assign_call(self):
self._check_error("f() = 1", "assign") self._check_error("f() = 1", "assign")

View File

@ -12,6 +12,10 @@ What's New in Python 2.6.5
Core and Builtins 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 - Issue #7085: Fix crash when importing some extensions in a thread
on MacOSX 10.6. on MacOSX 10.6.

View File

@ -682,7 +682,8 @@ ast_for_arguments(struct compiling *c, const node *n)
while (i < NCH(n)) { while (i < NCH(n)) {
ch = CHILD(n, i); ch = CHILD(n, i);
switch (TYPE(ch)) { switch (TYPE(ch)) {
case fpdef: case fpdef: {
int complex_args = 0, parenthesized = 0;
handle_fpdef: handle_fpdef:
/* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is
anything other than EQUAL or a comma? */ anything other than EQUAL or a comma? */
@ -697,6 +698,12 @@ ast_for_arguments(struct compiling *c, const node *n)
found_default = 1; found_default = 1;
} }
else if (found_default) { 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, ast_error(n,
"non-default argument follows default argument"); "non-default argument follows default argument");
goto error; goto error;
@ -709,6 +716,7 @@ ast_for_arguments(struct compiling *c, const node *n)
if (Py_Py3kWarningFlag && !ast_warn(c, ch, if (Py_Py3kWarningFlag && !ast_warn(c, ch,
"tuple parameter unpacking has been removed in 3.x")) "tuple parameter unpacking has been removed in 3.x"))
goto error; goto error;
complex_args = 1;
asdl_seq_SET(args, k++, compiler_complex_args(c, ch)); asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
if (!asdl_seq_GET(args, k-1)) if (!asdl_seq_GET(args, k-1))
goto error; goto error;
@ -716,6 +724,7 @@ ast_for_arguments(struct compiling *c, const node *n)
/* def foo((x)): setup for checking NAME below. */ /* def foo((x)): setup for checking NAME below. */
/* Loop because there can be many parens and tuple /* Loop because there can be many parens and tuple
unpacking mixed in. */ unpacking mixed in. */
parenthesized = 1;
ch = CHILD(ch, 0); ch = CHILD(ch, 0);
assert(TYPE(ch) == fpdef); assert(TYPE(ch) == fpdef);
goto handle_fpdef; goto handle_fpdef;
@ -737,7 +746,13 @@ ast_for_arguments(struct compiling *c, const node *n)
} }
i += 2; /* the name and the comma */ 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; break;
}
case STAR: case STAR:
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1)))) if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
goto error; goto error;