Repository: ambv/black
Pull request #461 (2018-08-19 03:51:10)

autodetect Python 3.6 on the basis of underscores

coveralls: ## Pull Request Test Coverage Report for [Build 625](https://coveralls.io/builds/18555258)

* **7** of **7**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.01%**) to **96.056%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/18555258/badge)](https://coveralls.io/builds/18555258) |
| :-- | --: |
| Change from base [Build 624](https://coveralls.io/builds/18553557): |  0.01% |
| Covered Lines: | 2679 |
| Relevant Lines: | 2789 |

---
##### 💛  - [Coveralls](https://coveralls.io)

zsol: Can you mention this in the README and Changelog?

Patch:
diff --git a/README.md b/README.md
index 96a24a1..9cb4f18 100644
--- a/README.md
+++ b/README.md
@@ -371,6 +371,12 @@ human-readable strings"](https://stackoverflow.com/a/56190)), you can
 pass `--skip-string-normalization` on the command line.  This is meant as
 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`.
 
 ### Line breaks & binary operators
 
@@ -843,6 +849,8 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
 
 ### 18.8b0
 
+* code with `_` in numeric literals is recognized as Python 3.6+ (#461)
+
 * numeric literals are now normalized to include `_` separators on Python 3.6+ code
   (#452)
 
diff --git a/black.py b/black.py
index d688748..b65693e 100644
--- a/black.py
+++ b/black.py
@@ -170,7 +170,7 @@ def read_pyproject_toml(
     "--line-length",
     type=int,
     default=DEFAULT_LINE_LENGTH,
-    help="How many character per line to allow.",
+    help="How many characters per line to allow.",
     show_default=True,
 )
 @click.option(
@@ -1164,7 +1164,7 @@ def maybe_remove_trailing_comma(self, closing: Leaf) -> bool:
             self.remove_trailing_comma()
             return True
 
-        # Otheriwsse, if the trailing one is the only one, we might mistakenly
+        # Otherwise, if the trailing one is the only one, we might mistakenly
         # change a tuple into a different type by removing the comma.
         depth = closing.bracket_depth + 1
         commas = 0
@@ -1377,7 +1377,7 @@ def _maybe_empty_lines_for_class_or_def(
                 newlines = 1
             elif current_line.is_class or self.previous_line.is_class:
                 if current_line.is_stub_class and self.previous_line.is_stub_class:
-                    # No blank line between classes with an emty body
+                    # No blank line between classes with an empty body
                     newlines = 0
                 else:
                     newlines = 1
@@ -2891,7 +2891,8 @@ def is_python36(node: Node) -> bool:
     """Return True if the current file is using Python 3.6+ features.
 
     Currently looking for:
-    - f-strings; and
+    - f-strings;
+    - underscores in numeric literals; and
     - trailing commas after * or ** in function signatures and calls.
     """
     for n in node.pre_order():
@@ -2900,6 +2901,10 @@ def is_python36(node: Node) -> bool:
             if value_head in {'f"', 'F"', "f'", "F'", "rf", "fr", "RF", "FR"}:
                 return True
 
+        elif n.type == token.NUMBER:
+            if "_" in n.value:  # type: ignore
+                return True
+
         elif (
             n.type in {syms.typedargslist, syms.arglist}
             and n.children
@@ -3133,7 +3138,7 @@ def return_code(self) -> int:
         - otherwise return 0.
         """
         # According to http://tldp.org/LDP/abs/html/exitcodes.html starting with
-        # 126 we have special returncodes reserved by the shell.
+        # 126 we have special return codes reserved by the shell.
         if self.failure_count:
             return 123
 


Test patch:
diff --git a/tests/test_black.py b/tests/test_black.py
index 884d046..10d7f28 100644
--- a/tests/test_black.py
+++ b/tests/test_black.py
@@ -722,6 +722,10 @@ def test_is_python36(self) -> None:
         self.assertTrue(black.is_python36(node))
         node = black.lib2to3_parse("def f(*, arg): f'string'\n")
         self.assertTrue(black.is_python36(node))
+        node = black.lib2to3_parse("123_456\n")
+        self.assertTrue(black.is_python36(node))
+        node = black.lib2to3_parse("123456\n")
+        self.assertFalse(black.is_python36(node))
         source, expected = read_data("function")
         node = black.lib2to3_parse(source)
         self.assertTrue(black.is_python36(node))