change some numeric behavior (#469)

This commit is contained in:
Jelle Zijlstra 2018-08-23 11:55:29 -07:00 committed by GitHub
parent c67feaf04f
commit a37abdcbc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 16 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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