Use lowercase hex numbers fixes #1692 (#1775)

* Made hex lower case

* Refactored numeric formatting section

* Redid some refactoring and removed bloat

* Removed additions from test_requirements.txt

* Primer now expects expected changes

* Undid some refactoring

* added to changelog

* Update src/black/__init__.py

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
Co-authored-by: Cooper Lees <me@cooperlees.com>
This commit is contained in:
Casper Weiss Bang 2020-11-13 16:25:17 +01:00 committed by GitHub
parent 1d8b4d766d
commit 7d032fa848
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 57 additions and 33 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
.venv
.coverage
_build
.DS_Store
@ -15,4 +16,4 @@ src/_black_version.py
.dmypy.json
*.swp
.hypothesis/
venv/
venv/

View File

@ -21,6 +21,8 @@
- Added support for PEP 614 relaxed decorator syntax on python 3.9 (#1711)
- use lowercase hex strings (#1692)
#### _Packaging_
- Self-contained native _Black_ binaries are now provided for releases via GitHub

View File

@ -5192,31 +5192,52 @@ def normalize_numeric_literal(leaf: Leaf) -> None:
# Leave octal and binary literals alone.
pass
elif text.startswith("0x"):
# Change hex literals to upper case.
before, after = text[:2], text[2:]
text = f"{before}{after.upper()}"
text = format_hex(text)
elif "e" in text:
before, after = text.split("e")
sign = ""
if after.startswith("-"):
after = after[1:]
sign = "-"
elif after.startswith("+"):
after = after[1:]
before = format_float_or_int_string(before)
text = f"{before}e{sign}{after}"
text = format_scientific_notation(text)
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)}{suffix}"
text = format_long_or_complex_number(text)
else:
text = format_float_or_int_string(text)
leaf.value = text
def format_hex(text: str) -> str:
"""
Formats a hexadecimal string like "0x12b3"
Uses lowercase because of similarity between "B" and "8", which
can cause security issues.
see: https://github.com/psf/black/issues/1692
"""
before, after = text[:2], text[2:]
return f"{before}{after.lower()}"
def format_scientific_notation(text: str) -> str:
"""Formats a numeric string utilizing scentific notation"""
before, after = text.split("e")
sign = ""
if after.startswith("-"):
after = after[1:]
sign = "-"
elif after.startswith("+"):
after = after[1:]
before = format_float_or_int_string(before)
return f"{before}e{sign}{after}"
def format_long_or_complex_number(text: str) -> str:
"""Formats a long or complex string like `10L` or `10j`"""
number = text[:-1]
suffix = text[-1]
# Capitalize in "2L" because "l" looks too similar to "1".
if suffix == "l":
suffix = "L"
return f"{format_float_or_int_string(number)}{suffix}"
def format_float_or_int_string(text: str) -> str:
"""Formats a float string like "1.0"."""
if "." not in text:

View File

@ -10,7 +10,7 @@
},
"attrs": {
"cli_arguments": [],
"expect_formatting_changes": false,
"expect_formatting_changes": true,
"git_clone_url": "https://github.com/python-attrs/attrs.git",
"long_checkout": false,
"py_versions": ["all"]
@ -47,7 +47,7 @@
},
"hypothesis": {
"cli_arguments": [],
"expect_formatting_changes": false,
"expect_formatting_changes": true,
"git_clone_url": "https://github.com/HypothesisWorks/hypothesis.git",
"long_checkout": false,
"py_versions": ["all"]
@ -63,7 +63,7 @@
},
"pillow": {
"cli_arguments": [],
"expect_formatting_changes": false,
"expect_formatting_changes": true,
"git_clone_url": "https://github.com/python-pillow/Pillow.git",
"long_checkout": false,
"py_versions": ["all"]
@ -77,7 +77,7 @@
},
"pyramid": {
"cli_arguments": [],
"expect_formatting_changes": false,
"expect_formatting_changes": true,
"git_clone_url": "https://github.com/Pylons/pyramid.git",
"long_checkout": false,
"py_versions": ["all"]
@ -112,7 +112,7 @@
},
"virtualenv": {
"cli_arguments": [],
"expect_formatting_changes": false,
"expect_formatting_changes": true,
"git_clone_url": "https://github.com/pypa/virtualenv.git",
"long_checkout": false,
"py_versions": ["all"]

View File

@ -34,7 +34,7 @@
import sys
from io import StringIO
HUGE: int = 0x7FFFFFFF # maximum repeat count, default max
HUGE: int = 0x7fffffff # maximum repeat count, default max
_type_reprs: Dict[int, Union[Text, int]] = {}

View File

@ -2,4 +2,4 @@ pytest >= 6.1.1
pytest-mock >= 3.3.1
pytest-cases >= 2.3.0
coverage >= 5.3
parameterized >= 0.7.4
parameterized >= 0.7.4

View File

@ -12,7 +12,7 @@
x = 123456789E123456789
x = 123456789J
x = 123456789.123456789J
x = 0XB1ACC
x = 0Xb1aCc
x = 0B1011
x = 0O777
x = 0.000000006
@ -36,7 +36,7 @@
x = 123456789e123456789
x = 123456789j
x = 123456789.123456789j
x = 0xB1ACC
x = 0xb1acc
x = 0b1011
x = 0o777
x = 0.000000006

View File

@ -3,7 +3,7 @@
x = 123456789L
x = 123456789l
x = 123456789
x = 0xb1acc
x = 0xB1aCc
# output
@ -13,4 +13,4 @@
x = 123456789L
x = 123456789L
x = 123456789
x = 0xB1ACC
x = 0xb1acc

View File

@ -3,7 +3,7 @@
x = 123456789
x = 1_2_3_4_5_6_7
x = 1E+1
x = 0xb1acc
x = 0xb1AcC
x = 0.00_00_006
x = 12_34_567J
x = .1_2
@ -16,8 +16,8 @@
x = 123456789
x = 1_2_3_4_5_6_7
x = 1e1
x = 0xB1ACC
x = 0xb1acc
x = 0.00_00_006
x = 12_34_567j
x = 0.1_2
x = 1_2.0
x = 1_2.0