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
|
### Numeric literals
|
||||||
|
|
||||||
*Black* standardizes all numeric literals to use lowercase letters: `0xab`
|
*Black* standardizes most numeric literals to use lowercase letters: `0xab`
|
||||||
instead of `0XAB` and `1e10` instead of `1E10`. In Python 3.6+, *Black*
|
instead of `0XAB` and `1e10` instead of `1E10`. Python 2 long literals are
|
||||||
adds underscores to long numeric literals to aid readability: `100000000`
|
styled as `2L` instead of `2l` to avoid confusion between `l` and `1`. In
|
||||||
becomes `100_000_000`.
|
Python 3.6+, *Black* adds underscores to long numeric literals to aid
|
||||||
|
readability: `100000000` becomes `100_000_000`.
|
||||||
|
|
||||||
### Line breaks & binary operators
|
### 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)
|
* 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
|
* numeric literals are normalized to include `_` separators on Python 3.6+ code
|
||||||
(#452)
|
|
||||||
|
* 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
|
* cache is now populated when `--check` is successful for a file which speeds up
|
||||||
consecutive checks of properly formatted unmodified files (#448)
|
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:
|
def normalize_numeric_literal(leaf: Leaf, allow_underscores: bool) -> None:
|
||||||
"""Normalizes numeric (float, int, and complex) literals.
|
"""Normalizes numeric (float, int, and complex) literals.
|
||||||
|
|
||||||
All letters used in the representation are normalized to lowercase, long number
|
All letters used in the representation are normalized to lowercase (except
|
||||||
literals are split using underscores.
|
in Python 2 long literals), and long number literals are split using underscores.
|
||||||
"""
|
"""
|
||||||
text = leaf.value.lower()
|
text = leaf.value.lower()
|
||||||
if text.startswith(("0o", "0x", "0b")):
|
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")):
|
elif text.endswith(("j", "l")):
|
||||||
number = text[:-1]
|
number = text[:-1]
|
||||||
suffix = 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}"
|
text = f"{format_float_or_int_string(number, allow_underscores)}{suffix}"
|
||||||
else:
|
else:
|
||||||
text = format_float_or_int_string(text, allow_underscores)
|
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, after = text.split(".")
|
||||||
before = format_int_string(before, allow_underscores) if before else "0"
|
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}"
|
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.
|
"""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:
|
if not allow_underscores:
|
||||||
return text
|
return text
|
||||||
@ -2573,9 +2584,12 @@ def format_int_string(text: str, allow_underscores: bool) -> str:
|
|||||||
# No underscores for numbers <= 6 digits long.
|
# No underscores for numbers <= 6 digits long.
|
||||||
return text
|
return text
|
||||||
|
|
||||||
# Avoid removing leading zeros, which are important if we're formatting
|
if count_from_end:
|
||||||
# part of a number like "0.001".
|
# Avoid removing leading zeros, which are important if we're formatting
|
||||||
return format(int("1" + text), "3_")[1:].lstrip("_")
|
# 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:
|
def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
x = 1.
|
x = 1.
|
||||||
x = 1E+1
|
x = 1E+1
|
||||||
x = 1E-1
|
x = 1E-1
|
||||||
|
x = 1.00000001
|
||||||
x = 123456789.123456789
|
x = 123456789.123456789
|
||||||
x = 123456789.123456789E123456789
|
x = 123456789.123456789E123456789
|
||||||
x = 123456789E123456789
|
x = 123456789E123456789
|
||||||
@ -27,6 +28,7 @@
|
|||||||
x = 1.0
|
x = 1.0
|
||||||
x = 1e1
|
x = 1e1
|
||||||
x = 1e-1
|
x = 1e-1
|
||||||
|
x = 1.000_000_01
|
||||||
x = 123_456_789.123_456_789
|
x = 123_456_789.123_456_789
|
||||||
x = 123_456_789.123_456_789e123_456_789
|
x = 123_456_789.123_456_789e123_456_789
|
||||||
x = 123_456_789e123_456_789
|
x = 123_456_789e123_456_789
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python2.7
|
#!/usr/bin/env python2.7
|
||||||
|
|
||||||
x = 123456789L
|
x = 123456789L
|
||||||
|
x = 123456789l
|
||||||
x = 123456789
|
x = 123456789
|
||||||
|
|
||||||
# output
|
# output
|
||||||
@ -8,5 +9,6 @@
|
|||||||
|
|
||||||
#!/usr/bin/env python2.7
|
#!/usr/bin/env python2.7
|
||||||
|
|
||||||
x = 123456789l
|
x = 123456789L
|
||||||
|
x = 123456789L
|
||||||
x = 123456789
|
x = 123456789
|
||||||
|
Loading…
Reference in New Issue
Block a user