PEP 8 updated on whether to break before or after a binary update
After a fruitful discussion on python-ideas I've decided that it's fine to break lines *before* a binary operator. It looks better and Knuth recommends it. The head of the python-ideas discussion: https://mail.python.org/pipermail/python-ideas/2016-April/039752.html See also the discussion in the tracker: http://bugs.python.org/issue26763 Here's the diff I applied: https://hg.python.org/peps/rev/3857909d7956 The talk by Brandon Rhodes where Knuth is referenced ([3] below): http://rhodesmill.org/brandon/slides/2012-11-pyconca/#laying-down-the-law The key section in PEP 8 that was updated (apart from fixing up references): Should a line break before or after a binary operator? ------------------------------------------------------ For decades the recommended style has been to break after binary operators. However, recent reseach unearthed recommendations by Donald Knuth to break *before* binary operators, in his writings about typesetting [3]_. Therefore it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested. Some examples of code breaking before binary Boolean operators:: class Rectangle(Blob): def __init__(self, width, height, color='black', emphasis=None, highlight=0): if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") if (width == 0 and height == 0 and (color == 'red' or emphasis is None)): raise ValueError("I don't think so -- values are %s, %s" % (width, height)) Blob.__init__(self, width, height, color, emphasis, highlight) -- --Guido van Rossum (python.org/~guido)
[Guido]
After a fruitful discussion on python-ideas I've decided that it's fine to break lines *before* a binary operator. It looks better and Knuth recommends it. ... Therefore it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested.
Some examples of code breaking before binary Boolean operators::
class Rectangle(Blob):
def __init__(self, width, height, color='black', emphasis=None, highlight=0): if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") if (width == 0 and height == 0 and (color == 'red' or emphasis is None)): raise ValueError("I don't think so -- values are %s, %s" % (width, height)) Blob.__init__(self, width, height, color, emphasis, highlight)
Note that this code still breaks a line after a binary operator (the string formatting "%" operator in the 2nd ValueError call). But it's perfectly clear the way it is. Good taste can't be reduced to rules ;-)
Hum. if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") Please remove one space to vertically align "and" operators with the opening parenthesis: if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") (I'm not sure that the difference is obvious in a mail client, you need a fixed width font which is not the case in my Gmail editor.) It helps to visually see that the multiline test and the raise instruction are in two different blocks. (Moreover, the pep8 checks of OpenStack simply reject such syntax, but I cannot use this syntax anymore :-)) Victor
On Fri, Apr 15, 2016 at 10:03 AM, Victor Stinner
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
(I'm not sure that the difference is obvious in a mail client, you need a fixed width font which is not the case in my Gmail editor.)
I can see it perfectly fin and I disagree.
It helps to visually see that the multiline test and the raise instruction are in two different blocks.
(Moreover, the pep8 checks of OpenStack simply reject such syntax, but I cannot use this syntax anymore :-))
That's why that tool shouldn't be named after the PEP. See https://github.com/PyCQA/pycodestyle/issues/466 -- --Guido van Rossum (python.org/~guido)
On 15 April 2016 at 18:03, Victor Stinner
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Personally, I think what you propose looks ugly. The first version looks so much better. It helps to visually see that the multiline test and the raise
instruction are in two different blocks.
The only thing I would add would be an empty line to help distinguish the if expression block from the "then" code block: if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") -- Gustavo J. A. M. Carneiro Gambit Research "The universe is always one step beyond logic." -- Frank Herbert
On 15.04.16 20:03, Victor Stinner wrote:
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
I would rather *add* spaces to wrapped condition lines. if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
The update is already serving its real purpose: showing that style is
debatable and cannot always easily be reduced to fixed rules.
On Fri, Apr 15, 2016 at 10:24 AM, Serhiy Storchaka
On 15.04.16 20:03, Victor Stinner wrote:
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
I would rather *add* spaces to wrapped condition lines.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
_______________________________________________ Python-Dev mailing list Python-Dev@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)
Hi, On 04/15/2016 07:43 PM, Guido van Rossum wrote:
The update is already serving its real purpose: showing that style is debatable and cannot always easily be reduced to fixed rules.
As you said, there will be always some kind personal preferences or style taste and one can see on the debate that the current rules are context dependent. But I wonder how far that style context/rule (function) evaluation/application issue could be solved in a machine learning context. Regards, francis
On 2016-04-15 18:03, Victor Stinner wrote:
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
(I'm not sure that the difference is obvious in a mail client, you need a fixed width font which is not the case in my Gmail editor.)
It helps to visually see that the multiline test and the raise instruction are in two different blocks.
(Moreover, the pep8 checks of OpenStack simply reject such syntax, but I cannot use this syntax anymore :-))
I always half-indent continuation lines: if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Cross posting the comment I’d left on the issue [1].
My preference is to actually break that logic up and avoid the wrapping in the first place, as in [2]. Which in this particular class has the side benefit of that value being used again in the same function anyways.
I'm starting to realize that Brandon Rhodes really had a big impact on my ideas of styling as I've been learning Python these past few years, as this was another one style I'm stealing from that same talk [3].
[1] http://bugs.python.org/msg263509 http://bugs.python.org/msg263509 [2] https://github.com/python/peps/commit/0c790e7b721bd13ad12ab9e6f6206836f398f9... ~ Ian Lee | IanLee1521@gmail.com mailto:IanLee1521@gmail.com
On Apr 15, 2016, at 10:49, MRAB
wrote: On 2016-04-15 18:03, Victor Stinner wrote:
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
(I'm not sure that the difference is obvious in a mail client, you need a fixed width font which is not the case in my Gmail editor.)
It helps to visually see that the multiline test and the raise instruction are in two different blocks.
(Moreover, the pep8 checks of OpenStack simply reject such syntax, but I cannot use this syntax anymore :-))
I always half-indent continuation lines:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") _______________________________________________ Python-Dev mailing list Python-Dev@python.org mailto:Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ianlee1521%40gmail.com https://mail.python.org/mailman/options/python-dev/ianlee1521%40gmail.com
If Python ever adopts the BCPL rule for implicit line continuation if the
last thing on a line is an operator (or if there's an open parentheses),
then the break-after-an-operator rule would be more persuasive.
;)
[IIRC, the BCPL rule was that there was an implicit continuation if the
grammar would not allow inserting a semicolon at the end of the line, which
covered both the open-parens and last-item-is-operator cases, and probably
a few others.] But I should shut up and leave shut discussions to
python-ideas.
On 15 April 2016 at 13:48, Ian Lee
Cross posting the comment I’d left on the issue [1].
My preference is to actually break that logic up and avoid the wrapping in the first place, as in [2]. Which in this particular class has the side benefit of that value being used again in the same function anyways.
I'm starting to realize that Brandon Rhodes really had a big impact on my ideas of styling as I've been learning Python these past few years, as this was another one style I'm stealing from that same talk [3].
[1] http://bugs.python.org/msg263509 [2] https://github.com/python/peps/commit/0c790e7b721bd13ad12ab9e6f6206836f398f9...
~ Ian Lee | IanLee1521@gmail.com
On Apr 15, 2016, at 10:49, MRAB
wrote: On 2016-04-15 18:03, Victor Stinner wrote:
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
(I'm not sure that the difference is obvious in a mail client, you need a fixed width font which is not the case in my Gmail editor.)
It helps to visually see that the multiline test and the raise instruction are in two different blocks.
(Moreover, the pep8 checks of OpenStack simply reject such syntax, but I cannot use this syntax anymore :-))
I always half-indent continuation lines:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ianlee1521%40gmail.com
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/pludemann%40google.com
On Fri, Apr 15, 2016, at 23:46, Peter Ludemann via Python-Dev wrote:
If Python ever adopts the BCPL rule for implicit line continuation if the last thing on a line is an operator (or if there's an open parentheses), then the break-after-an-operator rule would be more persuasive. ;)
[IIRC, the BCPL rule was that there was an implicit continuation if the grammar would not allow inserting a semicolon at the end of the line, which covered both the open-parens and last-item-is-operator cases, and probably a few others.] But I should shut up and leave shut discussions to python-ideas.
Sounds like Visual Basic. Meanwhile, Javascript's rule is that there's an implicit semicolon if and only if the grammar would not allow the two lines to be considered as a single statement. Insanity comes in all flavors.
Victor Stinner writes:
Hum.
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
Please remove one space to vertically align "and" operators with the opening parenthesis:
if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose")
The RightThang[tm] is to remove "if" and replace it with the Japanese "moshi": moshi (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") It-works-for-me-ly y'rs,
participants (12)
-
Barry Warsaw
-
francismb
-
Guido van Rossum
-
Gustavo Carneiro
-
Ian Lee
-
MRAB
-
Peter Ludemann
-
Random832
-
Serhiy Storchaka
-
Stephen J. Turnbull
-
Tim Peters
-
Victor Stinner