change some numeric behavior (#469)
This commit is contained in:
parent
c67feaf04f
commit
a37abdcbc5
18
README.md
18
README.md
@ -373,10 +373,11 @@ an adoption helper, avoid using this for new projects.
|
||||
|
||||
### Numeric literals
|
||||
|
||||
*Black* standardizes all numeric literals to use lowercase letters: `0xab`
|
||||
instead of `0XAB` and `1e10` instead of `1E10`. In Python 3.6+, *Black*
|
||||
adds underscores to long numeric literals to aid readability: `100000000`
|
||||
becomes `100_000_000`.
|
||||
*Black* standardizes most numeric literals to use lowercase letters: `0xab`
|
||||
instead of `0XAB` and `1e10` instead of `1E10`. Python 2 long literals are
|
||||
styled as `2L` instead of `2l` to avoid confusion between `l` and `1`. In
|
||||
Python 3.6+, *Black* adds underscores to long numeric literals to aid
|
||||
readability: `100000000` becomes `100_000_000`.
|
||||
|
||||
### Line breaks & binary operators
|
||||
|
||||
@ -851,10 +852,13 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
|
||||
|
||||
* adjacent string literals are now correctly split into multiple lines (#463)
|
||||
|
||||
* code with `_` in numeric literals is recognized as Python 3.6+ (#461)
|
||||
* numeric literals are now formatted by *Black* (#452, #461, #464, #469):
|
||||
|
||||
* numeric literals are now normalized to include `_` separators on Python 3.6+ code
|
||||
(#452)
|
||||
* numeric literals are normalized to include `_` separators on Python 3.6+ code
|
||||
|
||||
* code with `_` in numeric literals is recognized as Python 3.6+
|
||||
|
||||
* most letters in numeric literals are lowercased (e.g., in `1e10` or `0xab`)
|
||||
|
||||
* cache is now populated when `--check` is successful for a file which speeds up
|
||||
consecutive checks of properly formatted unmodified files (#448)
|
||||
|
30
black.py
30
black.py
@ -2522,8 +2522,8 @@ def normalize_string_quotes(leaf: Leaf) -> None:
|
||||
def normalize_numeric_literal(leaf: Leaf, allow_underscores: bool) -> None:
|
||||
"""Normalizes numeric (float, int, and complex) literals.
|
||||
|
||||
All letters used in the representation are normalized to lowercase, long number
|
||||
literals are split using underscores.
|
||||
All letters used in the representation are normalized to lowercase (except
|
||||
in Python 2 long literals), and long number literals are split using underscores.
|
||||
"""
|
||||
text = leaf.value.lower()
|
||||
if text.startswith(("0o", "0x", "0b")):
|
||||
@ -2543,6 +2543,9 @@ def normalize_numeric_literal(leaf: Leaf, allow_underscores: bool) -> None:
|
||||
elif text.endswith(("j", "l")):
|
||||
number = text[:-1]
|
||||
suffix = text[-1]
|
||||
# Capitalize in "2L" because "l" looks too similar to "1".
|
||||
if suffix == "l":
|
||||
suffix = "L"
|
||||
text = f"{format_float_or_int_string(number, allow_underscores)}{suffix}"
|
||||
else:
|
||||
text = format_float_or_int_string(text, allow_underscores)
|
||||
@ -2556,14 +2559,22 @@ def format_float_or_int_string(text: str, allow_underscores: bool) -> str:
|
||||
|
||||
before, after = text.split(".")
|
||||
before = format_int_string(before, allow_underscores) if before else "0"
|
||||
after = format_int_string(after, allow_underscores) if after else "0"
|
||||
if after:
|
||||
after = format_int_string(after, allow_underscores, count_from_end=False)
|
||||
else:
|
||||
after = "0"
|
||||
return f"{before}.{after}"
|
||||
|
||||
|
||||
def format_int_string(text: str, allow_underscores: bool) -> str:
|
||||
def format_int_string(
|
||||
text: str, allow_underscores: bool, count_from_end: bool = True
|
||||
) -> str:
|
||||
"""Normalizes underscores in a string to e.g. 1_000_000.
|
||||
|
||||
Input must be a string of at least six digits and optional underscores.
|
||||
Input must be a string of digits and optional underscores.
|
||||
If count_from_end is False, we add underscores after groups of three digits
|
||||
counting from the beginning instead of the end of the strings. This is used
|
||||
for the fractional part of float literals.
|
||||
"""
|
||||
if not allow_underscores:
|
||||
return text
|
||||
@ -2573,9 +2584,12 @@ def format_int_string(text: str, allow_underscores: bool) -> str:
|
||||
# No underscores for numbers <= 6 digits long.
|
||||
return text
|
||||
|
||||
# Avoid removing leading zeros, which are important if we're formatting
|
||||
# part of a number like "0.001".
|
||||
return format(int("1" + text), "3_")[1:].lstrip("_")
|
||||
if count_from_end:
|
||||
# Avoid removing leading zeros, which are important if we're formatting
|
||||
# part of a number like "0.001".
|
||||
return format(int("1" + text), "3_")[1:].lstrip("_")
|
||||
else:
|
||||
return "_".join(text[i : i + 3] for i in range(0, len(text), 3))
|
||||
|
||||
|
||||
def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
|
||||
|
@ -6,6 +6,7 @@
|
||||
x = 1.
|
||||
x = 1E+1
|
||||
x = 1E-1
|
||||
x = 1.00000001
|
||||
x = 123456789.123456789
|
||||
x = 123456789.123456789E123456789
|
||||
x = 123456789E123456789
|
||||
@ -27,6 +28,7 @@
|
||||
x = 1.0
|
||||
x = 1e1
|
||||
x = 1e-1
|
||||
x = 1.000_000_01
|
||||
x = 123_456_789.123_456_789
|
||||
x = 123_456_789.123_456_789e123_456_789
|
||||
x = 123_456_789e123_456_789
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python2.7
|
||||
|
||||
x = 123456789L
|
||||
x = 123456789l
|
||||
x = 123456789
|
||||
|
||||
# output
|
||||
@ -8,5 +9,6 @@
|
||||
|
||||
#!/usr/bin/env python2.7
|
||||
|
||||
x = 123456789l
|
||||
x = 123456789L
|
||||
x = 123456789L
|
||||
x = 123456789
|
||||
|
Loading…
Reference in New Issue
Block a user