From 7d032fa848c8910007a0a41c1ba61d70d2846f48 Mon Sep 17 00:00:00 2001 From: Casper Weiss Bang Date: Fri, 13 Nov 2020 16:25:17 +0100 Subject: [PATCH] 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 Co-authored-by: Zsolt Dollenstein Co-authored-by: Cooper Lees --- .gitignore | 3 +- CHANGES.md | 2 + src/black/__init__.py | 57 +++++++++++++------ src/black_primer/primer.json | 10 ++-- src/blib2to3/pytree.py | 2 +- test_requirements.txt | 2 +- tests/data/numeric_literals.py | 4 +- tests/data/numeric_literals_py2.py | 4 +- .../data/numeric_literals_skip_underscores.py | 6 +- 9 files changed, 57 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 3207e72..30225ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.venv .coverage _build .DS_Store @@ -15,4 +16,4 @@ src/_black_version.py .dmypy.json *.swp .hypothesis/ -venv/ \ No newline at end of file +venv/ diff --git a/CHANGES.md b/CHANGES.md index 240abe3..67697bd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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 diff --git a/src/black/__init__.py b/src/black/__init__.py index 7e13a5d..44edeb0 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -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: diff --git a/src/black_primer/primer.json b/src/black_primer/primer.json index cdc863c..32df015 100644 --- a/src/black_primer/primer.json +++ b/src/black_primer/primer.json @@ -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"] diff --git a/src/blib2to3/pytree.py b/src/blib2to3/pytree.py index 4b841b7..6dba3c7 100644 --- a/src/blib2to3/pytree.py +++ b/src/blib2to3/pytree.py @@ -34,7 +34,7 @@ __author__ = "Guido van Rossum " 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]] = {} diff --git a/test_requirements.txt b/test_requirements.txt index 3e65cdb..9f69b8e 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -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 \ No newline at end of file +parameterized >= 0.7.4 diff --git a/tests/data/numeric_literals.py b/tests/data/numeric_literals.py index 254da68..06b7f77 100644 --- a/tests/data/numeric_literals.py +++ b/tests/data/numeric_literals.py @@ -12,7 +12,7 @@ x = 123456789.123456789E123456789 x = 123456789E123456789 x = 123456789J x = 123456789.123456789J -x = 0XB1ACC +x = 0Xb1aCc x = 0B1011 x = 0O777 x = 0.000000006 @@ -36,7 +36,7 @@ x = 123456789.123456789e123456789 x = 123456789e123456789 x = 123456789j x = 123456789.123456789j -x = 0xB1ACC +x = 0xb1acc x = 0b1011 x = 0o777 x = 0.000000006 diff --git a/tests/data/numeric_literals_py2.py b/tests/data/numeric_literals_py2.py index 8f85c43..8b2c7fa 100644 --- a/tests/data/numeric_literals_py2.py +++ b/tests/data/numeric_literals_py2.py @@ -3,7 +3,7 @@ x = 123456789L x = 123456789l x = 123456789 -x = 0xb1acc +x = 0xB1aCc # output @@ -13,4 +13,4 @@ x = 0xb1acc x = 123456789L x = 123456789L x = 123456789 -x = 0xB1ACC +x = 0xb1acc diff --git a/tests/data/numeric_literals_skip_underscores.py b/tests/data/numeric_literals_skip_underscores.py index e345bb9..f83e233 100644 --- a/tests/data/numeric_literals_skip_underscores.py +++ b/tests/data/numeric_literals_skip_underscores.py @@ -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 = 1_2. 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 \ No newline at end of file +x = 1_2.0 -- 2.39.5