<div dir="ltr">Where did this PEP leave off? Anything blocking its acceptance?<br><br><div class="gmail_quote"><div dir="ltr">On Sat, 13 Feb 2016 at 00:49 Georg Brandl <<a href="mailto:g.brandl@gmx.net">g.brandl@gmx.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all,<br>
<br>
after talking to Guido and Serhiy we present the next revision<br>
of this PEP.  It is a compromise that we are all happy with,<br>
and a relatively restricted rule that makes additions to PEP 8<br>
basically unnecessary.<br>
<br>
I think the discussion has shown that supporting underscores in<br>
the from-string constructors is valuable, therefore this is now<br>
added to the specification section.<br>
<br>
The remaining open question is about the reverse direction: do<br>
we want a string formatting modifier that adds underscores as<br>
thousands separators?<br>
<br>
cheers,<br>
Georg<br>
<br>
-----------------------------------------------------------------<br>
<br>
PEP: 515<br>
Title: Underscores in Numeric Literals<br>
Version: $Revision$<br>
Last-Modified: $Date$<br>
Author: Georg Brandl, Serhiy Storchaka<br>
Status: Draft<br>
Type: Standards Track<br>
Content-Type: text/x-rst<br>
Created: 10-Feb-2016<br>
Python-Version: 3.6<br>
Post-History: 10-Feb-2016, 11-Feb-2016<br>
<br>
Abstract and Rationale<br>
======================<br>
<br>
This PEP proposes to extend Python's syntax and number-from-string<br>
constructors so that underscores can be used as visual separators for<br>
digit grouping purposes in integral, floating-point and complex number<br>
literals.<br>
<br>
This is a common feature of other modern languages, and can aid<br>
readability of long literals, or literals whose value should clearly<br>
separate into parts, such as bytes or words in hexadecimal notation.<br>
<br>
Examples::<br>
<br>
    # grouping decimal numbers by thousands<br>
    amount = 10_000_000.0<br>
<br>
    # grouping hexadecimal addresses by words<br>
    addr = 0xDEAD_BEEF<br>
<br>
    # grouping bits into nibbles in a binary literal<br>
    flags = 0b_0011_1111_0100_1110<br>
<br>
    # same, for string conversions<br>
    flags = int('0b_1111_0000', 2)<br>
<br>
<br>
Specification<br>
=============<br>
<br>
The current proposal is to allow one underscore between digits, and<br>
after base specifiers in numeric literals.  The underscores have no<br>
semantic meaning, and literals are parsed as if the underscores were<br>
absent.<br>
<br>
Literal Grammar<br>
---------------<br>
<br>
The production list for integer literals would therefore look like<br>
this::<br>
<br>
   integer: decinteger | bininteger | octinteger | hexinteger<br>
   decinteger: nonzerodigit (["_"] digit)* | "0" (["_"] "0")*<br>
   bininteger: "0" ("b" | "B") (["_"] bindigit)+<br>
   octinteger: "0" ("o" | "O") (["_"] octdigit)+<br>
   hexinteger: "0" ("x" | "X") (["_"] hexdigit)+<br>
   nonzerodigit: "1"..."9"<br>
   digit: "0"..."9"<br>
   bindigit: "0" | "1"<br>
   octdigit: "0"..."7"<br>
   hexdigit: digit | "a"..."f" | "A"..."F"<br>
<br>
For floating-point and complex literals::<br>
<br>
   floatnumber: pointfloat | exponentfloat<br>
   pointfloat: [digitpart] fraction | digitpart "."<br>
   exponentfloat: (digitpart | pointfloat) exponent<br>
   digitpart: digit (["_"] digit)*<br>
   fraction: "." digitpart<br>
   exponent: ("e" | "E") ["+" | "-"] digitpart<br>
   imagnumber: (floatnumber | digitpart) ("j" | "J")<br>
<br>
Constructors<br>
------------<br>
<br>
Following the same rules for placement, underscores will be allowed in<br>
the following constructors:<br>
<br>
- ``int()`` (with any base)<br>
- ``float()``<br>
- ``complex()``<br>
- ``Decimal()``<br>
<br>
<br>
Prior Art<br>
=========<br>
<br>
Those languages that do allow underscore grouping implement a large<br>
variety of rules for allowed placement of underscores.  In cases where<br>
the language spec contradicts the actual behavior, the actual behavior<br>
is listed.  ("single" or "multiple" refer to allowing runs of<br>
consecutive underscores.)<br>
<br>
* Ada: single, only between digits [8]_<br>
* C# (open proposal for 7.0): multiple, only between digits [6]_<br>
* C++14: single, between digits (different separator chosen) [1]_<br>
* D: multiple, anywhere, including trailing [2]_<br>
* Java: multiple, only between digits [7]_<br>
* Julia: single, only between digits (but not in float exponent parts)<br>
  [9]_<br>
* Perl 5: multiple, basically anywhere, although docs say it's<br>
  restricted to one underscore between digits [3]_<br>
* Ruby: single, only between digits (although docs say "anywhere")<br>
  [10]_<br>
* Rust: multiple, anywhere, except for between exponent "e" and digits<br>
  [4]_<br>
* Swift: multiple, between digits and trailing (although textual<br>
  description says only "between digits") [5]_<br>
<br>
<br>
Alternative Syntax<br>
==================<br>
<br>
Underscore Placement Rules<br>
--------------------------<br>
<br>
Instead of the relatively strict rule specified above, the use of<br>
underscores could be limited.  As we seen from other languages, common<br>
rules include:<br>
<br>
* Only one consecutive underscore allowed, and only between digits.<br>
* Multiple consecutive underscores allowed, but only between digits.<br>
* Multiple consecutive underscores allowed, in most positions except<br>
  for the start of the literal, or special positions like after a<br>
  decimal point.<br>
<br>
The syntax in this PEP has ultimately been selected because it covers<br>
the common use cases, and does not allow for syntax that would have to<br>
be discouraged in style guides anyway.<br>
<br>
A less common rule would be to allow underscores only every N digits<br>
(where N could be 3 for decimal literals, or 4 for hexadecimal ones).<br>
This is unnecessarily restrictive, especially considering the<br>
separator placement is different in different cultures.<br>
<br>
Different Separators<br>
--------------------<br>
<br>
A proposed alternate syntax was to use whitespace for grouping.<br>
Although strings are a precedent for combining adjoining literals, the<br>
behavior can lead to unexpected effects which are not possible with<br>
underscores.  Also, no other language is known to use this rule,<br>
except for languages that generally disregard any whitespace.<br>
<br>
C++14 introduces apostrophes for grouping (because underscores<br>
introduce ambiguity with user-defined literals), which is not<br>
considered because of the use in Python's string literals. [1]_<br>
<br>
<br>
Open Proposals<br>
==============<br>
<br>
It has been proposed [11]_ to extend the number-to-string formatting<br>
language to allow ``_`` as a thousans separator, where currently only<br>
``,`` is supported.  This could be used to easily generate code with<br>
more readable literals.<br>
<br>
<br>
Implementation<br>
==============<br>
<br>
A preliminary patch that implements the specification given above has<br>
been posted to the issue tracker. [12]_<br>
<br>
<br>
References<br>
==========<br>
<br>
.. [1] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3499.html" rel="noreferrer" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3499.html</a><br>
<br>
.. [2] <a href="http://dlang.org/spec/lex.html#integerliteral" rel="noreferrer" target="_blank">http://dlang.org/spec/lex.html#integerliteral</a><br>
<br>
.. [3] <a href="http://perldoc.perl.org/perldata.html#Scalar-value-constructors" rel="noreferrer" target="_blank">http://perldoc.perl.org/perldata.html#Scalar-value-constructors</a><br>
<br>
.. [4] <a href="http://doc.rust-lang.org/reference.html#number-literals" rel="noreferrer" target="_blank">http://doc.rust-lang.org/reference.html#number-literals</a><br>
<br>
.. [5]<br>
<a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html" rel="noreferrer" target="_blank">https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html</a><br>
<br>
.. [6] <a href="https://github.com/dotnet/roslyn/issues/216" rel="noreferrer" target="_blank">https://github.com/dotnet/roslyn/issues/216</a><br>
<br>
.. [7]<br>
<a href="https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html" rel="noreferrer" target="_blank">https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html</a><br>
<br>
.. [8] <a href="http://archive.adaic.com/standards/83lrm/html/lrm-02-04.html#2.4" rel="noreferrer" target="_blank">http://archive.adaic.com/standards/83lrm/html/lrm-02-04.html#2.4</a><br>
<br>
.. [9]<br>
<a href="http://docs.julialang.org/en/release-0.4/manual/integers-and-floating-point-numbers/" rel="noreferrer" target="_blank">http://docs.julialang.org/en/release-0.4/manual/integers-and-floating-point-numbers/</a><br>
<br>
.. [10] <a href="http://ruby-doc.org/core-2.3.0/doc/syntax/literals_rdoc.html#label-Numbers" rel="noreferrer" target="_blank">http://ruby-doc.org/core-2.3.0/doc/syntax/literals_rdoc.html#label-Numbers</a><br>
<br>
.. [11] <a href="https://mail.python.org/pipermail/python-dev/2016-February/143283.html" rel="noreferrer" target="_blank">https://mail.python.org/pipermail/python-dev/2016-February/143283.html</a><br>
<br>
.. [12] <a href="http://bugs.python.org/issue26331" rel="noreferrer" target="_blank">http://bugs.python.org/issue26331</a><br>
<br>
<br>
Copyright<br>
=========<br>
<br>
This document has been placed in the public domain.<br>
<br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/brett%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/brett%40python.org</a><br>
</blockquote></div></div>