[Python-ideas] Extending expressions using ellipsis

Paul Moore p.f.moore at gmail.com
Thu Sep 1 16:04:49 EDT 2016


On 1 September 2016 at 19:44, Shane Hathaway <shane at hathawaymix.org> wrote:
> Sometimes I fix unbalanced parentheses incorrectly.  Here's something I
> might type.  There should be another closing parenthesis in the middle:
>
>     def update(names, value):
>         (dbsession.query(Table1)
>          .filter(Table1.name.in_(names))
>          .update({'value': value})
>         (dbsession.query(Table2)
>          .filter(Table2.name.in_(names))
>          .update({'value': value}))
>
> Either Python or flake8 will tell me there's some kind of syntax error, so I
> might fix it by adding a closing parenthesis at the end:
>
>     def update(names, value):
>         (dbsession.query(Table1)
>          .filter(Table1.name.in_(names))
>          .update({'value': value})
>         (dbsession.query(Table2)
>          .filter(Table2.name.in_(names))
>          .update({'value': value})))
>
> This will fix the syntax error but fail at runtime.  With my proposed
> syntax, I would probably never create the error in the first place because I
> would only need to scan for balanced parentheses on each line, not over
> multiple lines:
>
>     def update(names, value):
>         dbsession.query(Table1) ...
>             .filter(Table1.name.in_(names))
>             .update({'value': value})
>         dbsession.query(Table2) ...
>             .filter(Table2.name.in_(names))
>             .update({'value': value})

Thanks. That's a nice example of how the proposal might help. But you
could of course have written your original code as

    def update(names, value):
        (dbsession.query(Table1)
            .filter(Table1.name.in_(names))
            .update({'value': value})
        (dbsession.query(Table2)
            .filter(Table2.name.in_(names))
            .update({'value': value}))

That's not going to completely alleviate the problem, but it does make
the intent clearer. And it's possible that you could propose a style
rule that a dedent in a bracketed expression is not allowed - that
might well be something that flake8 could add, and then you'd get a
much clearer error message (but only if you ran flake8 - if you just
saw a syntax error from Python, you'd probably be just as likely to
"fix" it as you said above, without even trying to run flake8). Also,
of course, most text editors would highlight matching parentheses -
which makes it much easier to spot the "correct" place for the missing
parenthesis.

One other thing, I'm not at all keen on using "..." for the syntax -
it's almost completely invisible when I read this in gmail, and as
others have pointed out, it already has a meaning, as Ellipsis. But I
don't have a better suggestion to offer, I'm afraid.

Overall, though, I'm cautiously in favour of the proposal. I'm not
convinced the benefit is huge, and I'm a little concerned that it may
be supporting a style of code that isn't ideal (the method chaining
from SQLAlchemy you use to illustrate the examples is common enough in
languages like JavaScript, but outside of SQLAlchemy I haven't seen it
used much in Python). Also, it's very definitely "yet another way to
write expressions across multiple lines". But the indented expression
format is pretty readable for cases when you *do* have a long
expression and no convenient way to bracket it.

Paul


More information about the Python-ideas mailing list