[Python-Dev] Call for prudence about PEP-572

Guido van Rossum guido at python.org
Sat Jul 7 11:48:45 EDT 2018


This seems more suitable for a style guide.

Enforcing such restrictions in the grammar would actually be complicated,
due to nesting -- but even if it wasn't, I wouldn't want to, as I don't
want to limit future generations to only the benefits of the new construct
that we can now come up with. Orthogonality is a good thing in my mind,
else we might never have had nested functions or conditional imports.

As to why you might want to use := in a function call, I could imagine
writing

    if validate(name := re.search(pattern, line).group(1)):
        return name

The benefit of combining the assignment with the if would be more apparent
if there was an if-elif...elif-else pattern, like here:
https://github.com/python/peps/pull/695/files#diff-09a4f112ea673a2339f0bec6014ff47fR409
(click off the comments to see it better).



On Sat, Jul 7, 2018 at 6:12 AM Giampaolo Rodola' <g.rodola at gmail.com> wrote:

> Sorry in advance for opening yet another topic about PEP-572. With PEP-572
> being officially accepted I know debating its inclusion in the language is
> a useless exercise at this point, but since it's still in "draft" status I
> would like to express my opinion as I think this is a feature which can
> potentially be abused fairly easily. FWIW I initially found myself
> disliking the idea as a whole but
> https://github.com/python/cpython/pull/8122 made me (and others)
> reconsider it quite a bit (see:
> https://twitter.com/grodola/status/1015251302350245888). PR-8122 clearly
> shows an improvement in expressiveness and compactness (many folks argue
> this is too much) but PEP-572 as it currently stands is too permissive
> IMHO. My concern about "easily abusable ugly cases" still remains, and I
> think they should be banned instead of just discouraged in the PEP or in
> the doc. Since we spend way more time *reading* code rather than writing
> it, as a "reader" I would expect a more prudent approach to the problem.
>
> Proposal
> ========
>
> 1) allow only one := assignment per line in "if" statements:
>     >>> if x := val1 and y := val2:   # SyntaxError or SyntaxWarning
>     >>> if x == val1 and y := val2:   # SyntaxError or SyntaxWarning
>     >>> if x := val1 and y == val2:   # SyntaxError or SyntaxWarning
>     >>> if x := val1:  # OK
>     >>> if (x := val1):  # OK
>
> 2) allow := in "while" statements, "if" statements and comprehensions only:
>     >>> foo(x := 0)  # SyntaxError
>     >>> yield x := 3  # SyntaxError
>     >>> assert y := 3  # SyntaxError
>
> 3) (debatable) disallow := if the variable is already defined:
>     >>> x = 5
>     >>> if (x := val):  # SyntaxError or SyntaxWarning
>
> 4) ban "a = (b := c)", "x = a := (b := (c := d))" and similar (they're
> just too ugly IMHO)
>
> Rationale 1
> ===========
>
> In visual terms assignments in Python have always occurred at the
> BEGINNING of the line and always on the most LEFT side:
>
>     >>> foo = fun1()
>     >>> bar = fun2()
>     >>> baz = fun3()
>
> That is where I naturally expect an assignment to be when reading code. My
> main concern with PEP-572 is that an assignments can now occur at *any
> point* in the line:
>
>     >>> foo = fun1()
>     >>> bar = fun2()
>     >>> if foo == val1 and bar == val2 and baz := fun3():
>     ...    ...
>
> That forces me to visually scan the whole line horizontally from left to
> right 'till its end, looking for possible variables being set. I'm
> concerned that I will miss := occurrences because visually they are very
> similar to == unless parentheses are made mandatory:
>
>     >>> if foo == val1 and bar == val2 and (baz := fun3()):
>     ...    ...
>
> Also, in case of multi-line conditionals I have to visually scan the
> construct both horizontally AND vertically:
>
>     >>> if (foo == val1 and \
>     ...        bar == val2 and \
>     ...        baz := val3):
>     ...     ...
>
> Again, that is not a place where I would expect to find or look for a
> variable assignment. I know I wouldn't like to read or review a code which
> does that and I suspect linters will likely end up wanting to emit a
> warning in that case (see: https://github.com/PyCQA/pylint/issues/2246).
> https://github.com/python/cpython/pull/8116/files avoids using multiple
> := per line and that's why the result appears readable enough IMO.
>
> Rationale 2
> ===========
>
> PEP-572 states:
>
>     > The := operator may be used directly in a positional function call
> argument
>
> That means allowing:
>
>     >>> foo(x := 0)
>
> I honestly don't see why anyone would want to call a function AND assign a
> variable value at the same time (except in comprehensions). With this in
> place I not only have to guard against "if" statements assigning values at
> any point in the code, but also function calls, both horizontally and
> vertically e.g.:
>
>     >>> foo(some_long_var_name, another_one, x := bar(),
>             y := fun())
>
> To me this looks like the perfect example of where this functionality can
> be abused. Also, I'm not clear what PEP-572 intend to do about "all other
> places". E.g. should these cases be allowed? (IMO no)
>
>     >>> yield x := 3
>     >>> assert y := 3
>
> --
> Giampaolo - http://grodola.blogspot.com
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org
>


-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180707/8f5ea19c/attachment.html>


More information about the Python-Dev mailing list