summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lee <IanLee1521@gmail.com>2015-02-08 15:00:18 -0800
committerIan Lee <IanLee1521@gmail.com>2015-02-08 15:00:18 -0800
commitbcbd486eb4c698bc4008f3b38fae0370dce62748 (patch)
tree5266bf10f770a5f732a98d7acc3a0f871e73080f
parent1f4227b3735333d7a2fdb197eb049850961e3977 (diff)
parent7f2a185aba1a0e5ab796b66230c67af2ff2be380 (diff)
downloadpep8-bcbd486eb4c698bc4008f3b38fae0370dce62748.tar.gz
Merge pull request #305 from yole/break-around-binary-operator
Thanks for the patch!
-rwxr-xr-xpep8.py48
-rw-r--r--testsuite/E12.py6
2 files changed, 47 insertions, 7 deletions
diff --git a/pep8.py b/pep8.py
index bc6a659..d80b313 100755
--- a/pep8.py
+++ b/pep8.py
@@ -515,8 +515,9 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
yield start, "%s continuation line %s" % error
# look for visual indenting
- if (parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT)
- and not indent[depth]):
+ if (parens[row] and
+ token_type not in (tokenize.NL, tokenize.COMMENT) and
+ not indent[depth]):
indent[depth] = start[1]
indent_chances[start[1]] = True
if verbose >= 4:
@@ -1000,6 +1001,45 @@ def explicit_line_join(logical_line, tokens):
parens -= 1
+def break_around_binary_operator(logical_line, tokens):
+ r"""
+ Avoid breaks before binary operators.
+
+ The preferred place to break around a binary operator is after the
+ operator, not before it.
+
+ W503: (width == 0\n + height == 0)
+ W503: (width == 0\n and height == 0)
+
+ Okay: (width == 0 +\n height == 0)
+ Okay: foo(\n -x)
+ Okay: foo(x\n [])
+ Okay: x = '''\n''' + ''
+ Okay: foo(x,\n -y)
+ Okay: foo(x, # comment\n -y)
+ """
+ def is_binary_operator(token_type, text):
+ # The % character is strictly speaking a binary operator, but the
+ # common usage seems to be to put it next to the format parameters,
+ # after a line break.
+ return ((token_type == tokenize.OP or text in ['and', 'or']) and
+ text not in "()[]{},:.;@=%")
+
+ line_break = False
+ unary_context = True
+ for token_type, text, start, end, line in tokens:
+ if token_type == tokenize.COMMENT:
+ continue
+ if ('\n' in text or '\r' in text) and token_type != tokenize.STRING:
+ line_break = True
+ else:
+ if (is_binary_operator(token_type, text) and line_break and
+ not unary_context):
+ yield start, "W503 line break before binary operator"
+ unary_context = text in '([{,;'
+ line_break = False
+
+
def comparison_to_singleton(logical_line, noqa):
r"""Comparison to singletons should use "is" or "is not".
@@ -1415,8 +1455,8 @@ class Checker(object):
(start_row, start_col) = start
if prev_row != start_row: # different row
prev_text = self.lines[prev_row - 1][prev_col - 1]
- if prev_text == ',' or (prev_text not in '{[('
- and text not in '}])'):
+ if prev_text == ',' or (prev_text not in '{[(' and
+ text not in '}])'):
text = ' ' + text
elif prev_col != start_col: # different column
text = line[prev_col:start_col] + text
diff --git a/testsuite/E12.py b/testsuite/E12.py
index 6ebd44e..a995c95 100644
--- a/testsuite/E12.py
+++ b/testsuite/E12.py
@@ -323,14 +323,14 @@ if line_removed:
rv.update(d=('a', 'b', 'c'),
e=42)
#
-#: E127
+#: E127 W503
rv.update(d=('a' + 'b', 'c'),
e=42, f=42
+ 42)
-#: E127
+#: E127 W503
input1 = {'a': {'calc': 1 + 2}, 'b': 1
+ 42}
-#: E128
+#: E128 W503
rv.update(d=('a' + 'b', 'c'),
e=42, f=(42
+ 42))