[Python-Dev] Assignment expression and coding style: the while True case

Tim Peters tim.peters at gmail.com
Thu Jul 5 13:41:07 EDT 2018

[Victor Stinner]

> FYI I'm trying to use assignment expressions on the stdlib because
> *all* examples of the PEP 572 look artificial to me.

All the examples in my Appendix A were derived from real. pre-existing code
(although mostly my own).  It's turned out that several others with your
complaint above never read the PEP after that Appendix was added, so it's
possible that applies to you too.

> Like "group = re.match(data).group(1) if re.match(data) else None"
> which is followed by "(TODO: Include Guido's evidence, and do a more
> systematic search.)" I cannot find such inefficient code in the
> stdlib. I'm not saying that nobody writes code like that, just that
> developers with a good Python expertise would avoid to write such
> code.

Sure.  It happens, but it's rare.  As I've said many times already, I was
slightly surprised to conclude that the PEP was a win, but very surprised
to conclude it was the frequent dead- obvious little wins that added up to
its strongest case.

But that's mostly from staring at my code, and there's really nobody on
Earth better qualified to make my tradeoffs than I am ;-)

I don't discount Guido's impressions either.  While it's unlikely you're
going to find needlessly inefficient code in my Python, or the std lib, to
save a line, I'm not surprised at all that he found people writing worse
(on several counts - readability, maintainability, and speed) code _ just_
to save a line in "industrial Python".  Rather than dismiss the value for
them because they're not as expert as I am, or as our std lib authors have
been, I take it as evidence that the PEP provides value to others in ways
that don't really apply to bona-fide-Python-expert code.  I suspect, but
don't know, Guido is more moved by _that_ factor than by the dead obvious
little wins in experts' code.

 "filtered_data = [y for x in data if (y := f(x)) is not None]" also

seems artificial. In the 711,617 lines of Python code of the stdlib, I
> only found *one* example:

Well, you can't have it both ways.  That is, you can't fret that the
feature will be massively used while simultaneously claiming there are
almost no plausible uses at all ;-)

>    ...

And I also only found a single for loop which can be converted to a
> list comprehension thanks to assignement expression.

>     lines = []
>     for raw_line in raw_lines:
>         match = line_pat.search(raw_line.strip())
>         if match:
>             lines.append(match.group(1, 2))

And I don't see it as "an obvious win" _to_ change it, so wouldn't rewrite
it anyway.  Then again, my bar for "obvious win" may be higher than others'.


> > Wholesale changes to the std lib are unlikely to happen regardless.
> Broad
> > patches just to spell things differently without _need_ are discouraged.

> So PEP 572 is purely syntax sugar? It doesn't bring anything to the
> stdlib for example?

Insert the standard tedious observation about "Turing complete" here.  I'm
too old to bear it again ;-)

Patches to make widespread more-or-less mindless changes are _always_
frowned on, unless it's truly necessary (because, e.g., a language change
means the existing idiom will no longer work in the next release, or the
existing idiom is known to be 10x slower than a new alternative, or ...).
It clutters the history, greatly obscures who is "really responsible" for
the line that just showed up in a critical-failure traceback, and any code
churn risks introducing bugs.  Especially when people with little knowledge
of a module are changing it.  No matter how careful they are, they suffer
brain farts when making widespread changes to code they've basically never
seen before, and do introduce errors.  That's empirical historic fact.

Instead module experts introduce such changes incrementally while going
about their regular business, if they so choose.  If, for example, Raymond
despises assignment expressions. it's fine by me if itertools and random.py
(two modules for which he's the primary maintainer) never use them - and
it's a Bad Thing if someone else forces them on him without his approval.

In any case, I'd be -1 on your current approach regardless, until you drop
the outer parens in

    if (name := f()):

etc.  It reads better as the intended:

    if name := f():

and that can matter.  There _is_ a side effect going on here, and on
general principle it's better to avoid "hiding it" inside parentheses
unless there's a need to.  There's no possible way to misread the
unparenthesized form in this context, so there's no point at all to adding
redundant parens.  "But some earlier version of the PEP may or may not have
required them - I don't recall" is no longer a real point ;-)

My current 3 pull requests showing how assignment expressions can be
> used in the stdlib:
> while True: https://github.com/python/cpython/pull/8095/files
> match/group: https://github.com/python/cpython/pull/8097/files
> list comp: https://github.com/python/cpython/pull/8098/files

And again I'm very happy you're doing this!  Just drop the uselessly
distracting parens cluttering the dead obvious little wins ;-)

> Right now, I'm still not really excited by the new code.

Me neiither - but I'm not looking for excitement here, and never was.
There's nothing exciting about little wins.  They're ...  little ;-)

I'm more _intrigued_ by the possibilities created by assignment expression
targets living in the scope enclosing the outermost comprehension/genexp,
but I don't expect to find existing code just waiting to be slightly
rewritten to take advantage of that.  Although I certainly have "search
loop" code that could be rewritten with some real effort to exploit the
possibility of "exporting" the value that causes an `any(genexp)` or
`all(genexp)` to terminate early.  If assignment expressions had been
there, I would have written them with any/all from the start (even in
Python 2, for-target names are "hidden" in genexps).

> If you spotted other parts of the stdlib where assignment expressions
> would be appropriate, please tell me and I will try to write more pull
> requests :-)

I will if it comes up, but don't expect that.  I did my code spelunking
already, and stopped when I ceased learning anything new from it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180705/65828612/attachment.html>

More information about the Python-Dev mailing list