Major rewrite by Jim Jewett.
The inside-a-string continuation is separated from the general continuation. The alternatives section is expaned to als list Andrew Koenig's improved inside-expressions variant, since that is a real contender.
This commit is contained in:
parent
ea766d6a3d
commit
3e0cd27724
256
pep-3125.txt
256
pep-3125.txt
|
@ -13,208 +13,209 @@ Post-History: 29-Apr-2007, 30-Apr-2007, 04-May-2007
|
|||
Abstract
|
||||
========
|
||||
|
||||
Python initially inherited its parsing from C. While this has been
|
||||
generally useful, there are some remnants which have been less useful
|
||||
for Python, and should be eliminated.
|
||||
Python initially inherited its parsing from C. While this has
|
||||
been generally useful, there are some remnants which have been
|
||||
less useful for python, and should be eliminated.
|
||||
|
||||
This PEP proposes elimination of terminal ``\`` as a marker for line
|
||||
continuation.
|
||||
This PEP proposes elimination of terminal ``\`` as a marker for
|
||||
line continuation.
|
||||
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
||||
One goal for Python 3000 should be to simplify the language by
|
||||
removing unnecessary or duplicated features. There are currently
|
||||
several ways to indicate that a logical line is continued on the
|
||||
following physical line.
|
||||
One goal for Python 3000 should be to simplify the language by
|
||||
removing unnecessary or duplicated features. There are currently
|
||||
several ways to indicate that a logical line is continued on the
|
||||
following physical line.
|
||||
|
||||
The other continuation methods are easily explained as a logical
|
||||
consequence of the semantics they provide; ``\`` is simply an escape
|
||||
character that needs to be memorized.
|
||||
The other continuation methods are easily explained as a logical
|
||||
consequence of the semantics they provide; ``\`` is simply an escape
|
||||
character that needs to be memorized.
|
||||
|
||||
|
||||
Existing Line Continuation Methods
|
||||
==================================
|
||||
|
||||
|
||||
Parenthetical Expression - ``([{}])``
|
||||
-------------------------------------
|
||||
Parenthetical Expression - ([{}])
|
||||
---------------------------------
|
||||
|
||||
Open a parenthetical expression. It doesn't matter whether people
|
||||
view the "line" as continuing; they do immediately recognize that the
|
||||
expression needs to be closed before the statement can end.
|
||||
Open a parenthetical expression. It doesn't matter whether people
|
||||
view the "line" as continuing; they do immediately recognize that
|
||||
the expression needs to be closed before the statement can end.
|
||||
|
||||
Examples using each of ``()``, ``[]``, and ``{}``::
|
||||
An examples using each of (), [], and {}::
|
||||
|
||||
def fn(long_argname1,
|
||||
long_argname2):
|
||||
settings = {"background": "random noise",
|
||||
"volume": "barely audible"}
|
||||
restrictions = ["Warrantee void if used",
|
||||
"Notice must be received by yesterday",
|
||||
"Not responsible for sales pitch"]
|
||||
def fn(long_argname1,
|
||||
long_argname2):
|
||||
settings = {"background": "random noise"
|
||||
"volume": "barely audible"}
|
||||
restrictions = ["Warrantee void if used",
|
||||
"Notice must be recieved by yesterday"
|
||||
"Not responsible for sales pitch"]
|
||||
|
||||
Note that it is always possible to parenthesize an expression, but it
|
||||
can seem odd to parenthesize an expression that needs parentheses only
|
||||
for the line break::
|
||||
Note that it is always possible to parenthesize an expression,
|
||||
but it can seem odd to parenthesize an expression that needs
|
||||
them only for the line break::
|
||||
|
||||
assert val>4, (
|
||||
"val is too small")
|
||||
assert val>4, (
|
||||
"val is too small")
|
||||
|
||||
|
||||
Triple-Quoted Strings
|
||||
---------------------
|
||||
|
||||
Open a triple-quoted string; again, people recognize that the string
|
||||
needs to finish before the next statement starts. ::
|
||||
Open a triple-quoted string; again, people recognize that the
|
||||
string needs to finish before the next statement starts.
|
||||
|
||||
banner_message = """
|
||||
Satisfaction Guaranteed,
|
||||
or DOUBLE YOUR MONEY BACK!!!
|
||||
banner_message = """
|
||||
Satisfaction Guaranteed,
|
||||
or DOUBLE YOUR MONEY BACK!!!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
some minor restrictions apply"""
|
||||
some minor restrictions apply"""
|
||||
|
||||
|
||||
Terminal ``\`` in the general case
|
||||
----------------------------------
|
||||
|
||||
A terminal ``\`` indicates that the logical line is continued on the
|
||||
following physical line (after whitespace). There are no particular
|
||||
semantics associated with this. This form is never required, although
|
||||
it may look better (particularly for people with a C language
|
||||
background) in some cases::
|
||||
A terminal ``\`` indicates that the logical line is continued on the
|
||||
following physical line (after whitespace). There are no
|
||||
particular semantics associated with this. This form is never
|
||||
required, although it may look better (particularly for people
|
||||
with a C language background) in some cases::
|
||||
|
||||
>>> assert val>4, \
|
||||
"val is too small"
|
||||
>>> assert val>4, \
|
||||
"val is too small"
|
||||
|
||||
Also note that the ``\`` must be the final character in the line. If
|
||||
your editor navigation can add whitespace to the end of a line, that
|
||||
invisible change will alter the semantics of the program.
|
||||
Fortunately, the typical result is only a syntax error, rather than a
|
||||
runtime bug::
|
||||
Also note that the ``\`` must be the final character in the line.
|
||||
If your editor navigation can add whitespace to the end of a line,
|
||||
that invisible change will alter the semantics of the program.
|
||||
Fortunately, the typical result is only a syntax error, rather
|
||||
than a runtime bug::
|
||||
|
||||
>>> assert val>4, \
|
||||
"val is too small"
|
||||
>>> assert val>4, \
|
||||
"val is too small"
|
||||
|
||||
SyntaxError: unexpected character after line continuation character
|
||||
SyntaxError: unexpected character after line continuation character
|
||||
|
||||
This PEP proposes to eliminate this redundant and potentially
|
||||
confusing alternative.
|
||||
This PEP proposes to eliminate this redundant and potentially
|
||||
confusing alternative.
|
||||
|
||||
|
||||
Terminal ``\`` within a string
|
||||
------------------------------
|
||||
|
||||
A terminal ``\`` within a single-quoted string, at the end of the
|
||||
line. This is arguably a special case of the terminal ``\``, but it
|
||||
is a special case that may be worth keeping. ::
|
||||
|
||||
>>> "abd\
|
||||
def"
|
||||
'abd def'
|
||||
A terminal ``\`` within a single-quoted string, at the end of the
|
||||
line. This is arguably a special case of the terminal ``\``, but
|
||||
it is a special case that may be worth keeping.
|
||||
|
||||
* Pro: Many of the objections to removing ``\`` termination were
|
||||
really just objections to removing it within literal strings;
|
||||
several people clarified that they want to keep this literal-string
|
||||
usage, but don't mind losing the general case.
|
||||
>>> "abd\
|
||||
def"
|
||||
'abd def'
|
||||
|
||||
* Pro: The use of ``\`` for an escape character within strings is well
|
||||
known.
|
||||
+ Many of the objections to removing ``\`` termination were really
|
||||
just objections to removing it within literal strings; several
|
||||
people clarified that they want to keep this literal-string
|
||||
usage, but don't mind losing the general case.
|
||||
|
||||
* Contra: But note that this particular usage is odd, because the
|
||||
escaped character (the newline) is invisible, and the special
|
||||
treatment is to delete the character. That said, the ``\`` of
|
||||
``\(newline)`` is still an escape which changes the meaning of the
|
||||
following character.
|
||||
+ The use of ``\`` for an escape character within strings is well
|
||||
known.
|
||||
|
||||
- But note that this particular usage is odd, because the escaped
|
||||
character (the newline) is invisible, and the special treatment
|
||||
is to delete the character. That said, the ``\`` of
|
||||
``\(newline)`` is still an escape which changes the meaning of
|
||||
the following character.
|
||||
|
||||
|
||||
Alternate Proposals
|
||||
===================
|
||||
|
||||
Several people have suggested alternative ways of marking the line
|
||||
end. Most of these were rejected for not actually simplifying things.
|
||||
Several people have suggested alternative ways of marking the line
|
||||
end. Most of these were rejected for not actually simplifying things.
|
||||
|
||||
The one exception was to let any unfinished expression signify a line
|
||||
continuation, possibly in conjunction with increased indentation.
|
||||
The one exception was to let any unfished expression signify a line
|
||||
continuation, possibly in conjunction with increased indentation.
|
||||
|
||||
This is attractive because it is a generalization of the rule for
|
||||
parentheses.
|
||||
This is attractive because it is a generalization of the rule for
|
||||
parentheses.
|
||||
|
||||
The initial objections to this were:
|
||||
The initial objections to this were:
|
||||
|
||||
- The amount of whitespace may be contentious; expression continuation
|
||||
should not be confused with opening a new suite.
|
||||
- The amount of whitespace may be contentious; expression
|
||||
continuation should not be confused with opening a new
|
||||
suite.
|
||||
|
||||
- The "expression continuation" markers are not as clearly marked in
|
||||
Python as the grouping punctuation "(), [], {}" marks are::
|
||||
- The "expression continuation" markers are not as clearly marked
|
||||
in Python as the grouping punctuation "(), [], {}" marks are::
|
||||
|
||||
# Plus needs another operand, so the line continues
|
||||
"abc" +
|
||||
"def"
|
||||
# Plus needs another operand, so the line continues
|
||||
"abc" +
|
||||
"def"
|
||||
|
||||
# String ends an expression, so the line does not
|
||||
# not continue. The next line is a syntax error because
|
||||
# unary plus does not apply to strings.
|
||||
"abc"
|
||||
+ "def"
|
||||
# String ends an expression, so the line does not
|
||||
# not continue. The next line is a syntax error because
|
||||
# unary plus does not apply to strings.
|
||||
"abc"
|
||||
+ "def"
|
||||
|
||||
- Guido objected for technical reasons. [#dedent]_ The most obvious
|
||||
implementation would require allowing INDENT or DEDENT tokens
|
||||
anywhere, or at least in a widely expanded (and ill-defined) set of
|
||||
locations. While this is of concern only for the internal parsing
|
||||
mechanism (rather than for users), it would be a major new source of
|
||||
complexity.
|
||||
- Guido objected for technical reasons. [#dedent]_ The most
|
||||
obvious implementation would require allowing INDENT or
|
||||
DEDENT tokens anywhere, or at least in a widely expanded
|
||||
(and ill-defined) set of locations. While this is concern
|
||||
only for the internal parsing mechanism (rather than for
|
||||
users), it would be a major new source of complexity.
|
||||
|
||||
Andrew Koenig then pointed out [#lexical]_ a better implementation
|
||||
strategy, and said that it had worked quite well in other
|
||||
languages. [#snocone]_ The improved suggestion boiled down to:
|
||||
Andrew Koenig then pointed out [#lexical]_ a better implementation
|
||||
strategy, and said that it had worked quite well in other
|
||||
languages. [#snocone]_ The improved suggestion boiled down to::
|
||||
|
||||
The whitespace that follows an (operator or) open bracket or
|
||||
parenthesis can include newline characters.
|
||||
The whitespace that follows an (operator or) open bracket or
|
||||
parenthesis can include newline characters.
|
||||
|
||||
It would be implemented at a very low lexical level -- even before
|
||||
the decision is made to turn a newline followed by spaces into an
|
||||
INDENT or DEDENT token.
|
||||
It would be implemented at a very low lexical level -- even
|
||||
before the decision is made to turn a newline followed by
|
||||
spaces into an INDENT or DEDENT token.
|
||||
|
||||
There is still some concern that it could mask bugs, as in this
|
||||
example [#guidobughide]_::
|
||||
There is still some concern that it could mask bugs, as in this
|
||||
example [#guidobughide]_::
|
||||
|
||||
# Used to be y+1, the 1 got dropped. Syntax Error (today)
|
||||
# would become nonsense.
|
||||
x = y+
|
||||
f(x)
|
||||
# Used to be y+1, the 1 got dropped. Syntax Error (today)
|
||||
# would become nonsense.
|
||||
x = y+
|
||||
f(x)
|
||||
|
||||
Requiring that the continuation be indented more than the initial line
|
||||
would add both safety and complexity.
|
||||
Requiring that the continuation be indented more than the initial
|
||||
line would add both safety and complexity.
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
|
||||
* Should ``\``-continuation be removed even inside strings?
|
||||
+ Should ``\``-continuation be removed even inside strings?
|
||||
|
||||
* Should the continuation markers be expanded from just ([{}]) to
|
||||
include lines ending with an operator?
|
||||
+ Should the continuation markers be expanced from just ([{}])
|
||||
to include lines ending with an operator?
|
||||
|
||||
* As a safety measure, should the continuation line be required to be
|
||||
more indented than the initial line?
|
||||
+ As a safety measure, should the continuation line be required
|
||||
to be more indented than the initial line?
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
|
||||
.. [#dedent] (email subject) PEP 30XZ: Simplified Parsing, van Rossum
|
||||
http://mail.python.org/pipermail/python-3000/2007-April/007063.html
|
||||
|
||||
.. [#lexical] (email subject) PEP-3125 -- remove backslash
|
||||
continuation, Koenig
|
||||
http://mail.python.org/pipermail/python-3000/2007-May/007237.html
|
||||
|
||||
|
||||
.. [#snocone] The Snocone Programming Language, Koenig
|
||||
http://www.snobol4.com/report.htm
|
||||
|
||||
|
@ -226,15 +227,14 @@ References
|
|||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
||||
|
|
Loading…
Reference in New Issue