Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-32012: Disallow trailing comma after genexpr without parenthesis. #4382

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Nov 12, 2017

@serhiy-storchaka serhiy-storchaka force-pushed the gen-expr-argument-and-trailing-comma branch from b0bfcb7 to db4aafc Compare November 12, 2017 22:44
Copy link
Contributor

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test and compiler updates look good to me, just some minor grammar suggestions for the NEWS entry.

@@ -0,0 +1,4 @@
SyntaxError now is raised when a generator expression without parenthesis is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor grammar fix: "now is" -> "is now"

@@ -0,0 +1,4 @@
SyntaxError now is raised when a generator expression without parenthesis is
passed as argument but followed by trailing comma. A generator expression
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"... as an argument, but followed by a trailing ..."

@serhiy-storchaka
Copy link
Member Author

Thank you @ncoghlan for your fixes.

Copy link
Contributor

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this version goes too far - decorator factories that accept generator expressions don't break any syntactic design principles, and we don't check for any other "definitely not a valid base class" expressions in base class lists.

(The latter change might be an interesting one to make, but it should be a separate enhancement request that checks for all the constructs with a guaranteed non-class return type, and explicitly considers the question of metaclasses that might be doing something unusual with the base class list)

@@ -638,10 +638,18 @@ Changes in Python behavior

f(1 for x in [1],)

@deco(1 for x in [1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's wrong with this one? While we've restricted the form that decorator expressions take to being a name (dotted or otherwise) plus an optional function call, we've never restricted the arguments passed to that function call.

At the generator expression level, it also still meets the "must be surrounded by parentheses rule".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as with

@deco[0](1)

or

@deco(0)(1)

or

@(a+b*c)

This looks like valid Python expression syntax, but the syntax of decorator expression is intentionally more limited.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This aspect of the change is more akin to prohibiting @deco(a+b*c) - once the top level expression is in the form of a function call, the fact that it's part of a decorator expression shouldn't be altering what's permitted in the argument list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case these syntax changes should be discussed and officially approved. Could you please open a topic on Python-Dev about omitting parenthesis in a generator expression in these two cases? I have arguments for these changes and against them, but I think you will formulate them better. I'll add my comments.

Despite the fact that currently the CPython parser allows such syntax, it is illegal, and allowing it officially is a changing of Python language specification.

def f():
pass

class C(1 for x in [1]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one seems a bit odd to me as well, as we don't disallow other expressions in base class lists at compile time just because we know they can't produce a valid base class:

>>> class C([]): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list() takes at most 1 argument (3 given)
>>> class C({}): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: dict expected at most 1 arguments, got 3

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still can use

>>> class C((1 for x in [1])): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot create 'generator' instances

Omitting parenthesis in a generator expression is a special case for improving readability when pass a sole generator expression argument. The syntax of class definition doesn't have such special case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think there's merit to that argument, I don't think it belongs in the same PR (or issue) as the one that addresses the problem with mishandling trailing commas in function calls. Unlike the trailing comma case, there's no syntactic ambiguity being addressed.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Copy link
Contributor

@benjaminp benjaminp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to disallow a lot more than trailing commas in call genexps.

Python/ast.c Outdated
@@ -2705,14 +2705,14 @@ ast_for_expr(struct compiling *c, const node *n)
}

static expr_ty
ast_for_call(struct compiling *c, const node *n, expr_ty func)
ast_for_call(struct compiling *c, const node *n, expr_ty func, int allowgen)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allowgen should be bool parameter and the callers should pass true or false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python/ast.c:614:72: error: unknown type name ‘bool’; did you mean ‘_Bool’?
Python/ast.c:1548:53: error: ‘false’ undeclared (first use in this function); did you mean ‘fabsl’?
Python/ast.c:2371:60: error: ‘true’ undeclared (first use in this function); did you mean ‘time’?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to #include <stdbool.h>

@serhiy-storchaka
Copy link
Member Author

This seems to disallow a lot more than trailing commas in call genexps.

Only makes the implementation more conforming to the specification.

@serhiy-storchaka
Copy link
Member Author

I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@ncoghlan: please review the changes made to this pull request.

Copy link
Contributor

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! We can follow up on the others on the issue tracker, and potentially take them to python-dev if Guido thinks that's appropriate.

@serhiy-storchaka
Copy link
Member Author

Thank you for your review @ncoghlan and @benjaminp!

@serhiy-storchaka
Copy link
Member Author

Created #4400 for fixing class definitions.

tacaswell added a commit to tacaswell/toolz that referenced this pull request Nov 16, 2017
This expression is broken by:

bpo-32012: Disallow trailing comma after genexpr without
parenthesis.

python/cpython#4382
python/cpython@9165f77
tacaswell added a commit to tacaswell/toolz that referenced this pull request Nov 16, 2017
This expression is broken by:

bpo-32012: Disallow trailing comma after genexpr without
parenthesis.

python/cpython#4382
python/cpython@9165f77
@serhiy-storchaka serhiy-storchaka deleted the gen-expr-argument-and-trailing-comma branch September 22, 2018 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants