Repository: google/yapf
Pull request #672 (2019-02-08 15:38:02)

BUGFIX: Operator spacing
Fixes a bug where applying binary operators to strings would
result in the blacklist specified in
`NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS` to not take effect.


Patch:
diff --git a/CHANGELOG b/CHANGELOG
index 214f013..f9c03be 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,8 @@
   multiple lines with the opening bracket on the same line as the key.
   Therefore, we shouldn't enforce a split because of that.
 - Increase split penalty around exponent operator.
+- Correct spacing when using binary operators on strings with the
+  `NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS` option enabled.
 
 ## [0.25.0] 2018-11-25
 ### Added
diff --git a/yapf/yapflib/unwrapped_line.py b/yapf/yapflib/unwrapped_line.py
index 40f1295..6b37389 100644
--- a/yapf/yapflib/unwrapped_line.py
+++ b/yapf/yapflib/unwrapped_line.py
@@ -291,9 +291,9 @@ def _SpaceRequiredBetween(left, right):
       # If there is a type hint, then we don't want to add a space between the
       # equal sign and the hint.
       return False
-    if rval not in '[)]}.':
+    if rval not in '[)]}.' and not right.is_binary_op:
       # A string followed by something other than a subscript, closing bracket,
-      # or dot should have a space after it.
+      # dot, or a binary op should have a space after it.
       return True
   if left.is_binary_op and lval != '**' and _IsUnaryOperator(right):
     # Space between the binary operator and the unary operator.


Test patch:
diff --git a/yapftests/reformatter_basic_test.py b/yapftests/reformatter_basic_test.py
index 970c7ca..2e6fd2e 100644
--- a/yapftests/reformatter_basic_test.py
+++ b/yapftests/reformatter_basic_test.py
@@ -729,6 +729,13 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
     uwlines = yapf_test_helper.ParseAndUnwrap(code)
     self.assertCodeEqual(code, reformatter.Reformat(uwlines))
 
+  def testSpaceBetweenStringAndParentheses(self):
+    code = textwrap.dedent("""\
+        b = '0' ('hello')
+        """)
+    uwlines = yapf_test_helper.ParseAndUnwrap(code)
+    self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+
   def testMultilineString(self):
     code = textwrap.dedent("""\
         code = textwrap.dedent('''\
diff --git a/yapftests/reformatter_style_config_test.py b/yapftests/reformatter_style_config_test.py
index 5afd805..167b3d9 100644
--- a/yapftests/reformatter_style_config_test.py
+++ b/yapftests/reformatter_style_config_test.py
@@ -56,7 +56,7 @@ class TestsForStyleConfig(yapf_test_helper.YAPFTest):
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
     self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
 
-  def testOperatorStyle(self):
+  def testOperatorNoSpaceStyle(self):
     try:
       sympy_style = style.CreatePEP8Style()
       sympy_style['NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS'] = \
@@ -64,9 +64,11 @@ class TestsForStyleConfig(yapf_test_helper.YAPFTest):
       style.SetGlobalStyle(sympy_style)
       unformatted_code = textwrap.dedent("""\
           a = 1+2 * 3 - 4 / 5
+          b = '0' * 1
           """)
       expected_formatted_code = textwrap.dedent("""\
           a = 1 + 2*3 - 4/5
+          b = '0'*1
           """)
 
       uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)