From dc90d4951f66ac665582159537b902017d9a0361 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Thu, 16 Dec 2021 03:17:33 +0300 Subject: [PATCH] Unpacking on flow constructs (return/yield) now implies 3.8+ (#2700) --- CHANGES.md | 1 + src/black/__init__.py | 8 ++++++++ src/black/mode.py | 4 ++++ tests/test_black.py | 8 ++++++++ 4 files changed, 21 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 9208be7cd96..ae0bf80da48 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ (#2686) - No longer color diff headers white as it's unreadable in light themed terminals (#2691) +- Tuple unpacking on `return` and `yield` constructs now implies 3.8+ (#2700) ## 21.12b0 diff --git a/src/black/__init__.py b/src/black/__init__.py index f2efdec83b2..08c239dc155 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -1210,6 +1210,14 @@ def get_features_used( # noqa: C901 if argch.type in STARS: features.add(feature) + elif ( + n.type in {syms.return_stmt, syms.yield_expr} + and len(n.children) >= 2 + and n.children[1].type == syms.testlist_star_expr + and any(child.type == syms.star_expr for child in n.children[1].children) + ): + features.add(Feature.UNPACKING_ON_FLOW) + # Python 2 only features (for its deprecation) except for integers, see above elif n.type == syms.print_stmt: features.add(Feature.PRINT_STMT) diff --git a/src/black/mode.py b/src/black/mode.py index a2b7d9e9e2d..b28dcd8d149 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -49,6 +49,7 @@ class Feature(Enum): POS_ONLY_ARGUMENTS = 9 RELAXED_DECORATORS = 10 PATTERN_MATCHING = 11 + UNPACKING_ON_FLOW = 12 FORCE_OPTIONAL_PARENTHESES = 50 # __future__ flags @@ -116,6 +117,7 @@ class Feature(Enum): Feature.FUTURE_ANNOTATIONS, Feature.ASSIGNMENT_EXPRESSIONS, Feature.POS_ONLY_ARGUMENTS, + Feature.UNPACKING_ON_FLOW, }, TargetVersion.PY39: { Feature.UNICODE_LITERALS, @@ -128,6 +130,7 @@ class Feature(Enum): Feature.ASSIGNMENT_EXPRESSIONS, Feature.RELAXED_DECORATORS, Feature.POS_ONLY_ARGUMENTS, + Feature.UNPACKING_ON_FLOW, }, TargetVersion.PY310: { Feature.UNICODE_LITERALS, @@ -140,6 +143,7 @@ class Feature(Enum): Feature.ASSIGNMENT_EXPRESSIONS, Feature.RELAXED_DECORATORS, Feature.POS_ONLY_ARGUMENTS, + Feature.UNPACKING_ON_FLOW, Feature.PATTERN_MATCHING, }, } diff --git a/tests/test_black.py b/tests/test_black.py index 63cd716c0bb..8726cc10ddc 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -810,6 +810,14 @@ def test_get_features_used(self) -> None: self.assertEqual(black.get_features_used(node), {Feature.POS_ONLY_ARGUMENTS}) node = black.lib2to3_parse("def fn(a, /, b): ...") self.assertEqual(black.get_features_used(node), {Feature.POS_ONLY_ARGUMENTS}) + node = black.lib2to3_parse("def fn(): yield a, b") + self.assertEqual(black.get_features_used(node), set()) + node = black.lib2to3_parse("def fn(): return a, b") + self.assertEqual(black.get_features_used(node), set()) + node = black.lib2to3_parse("def fn(): yield *b, c") + self.assertEqual(black.get_features_used(node), {Feature.UNPACKING_ON_FLOW}) + node = black.lib2to3_parse("def fn(): return a, *b, c") + self.assertEqual(black.get_features_used(node), {Feature.UNPACKING_ON_FLOW}) def test_get_features_used_for_future_flags(self) -> None: for src, features in [