@@ -80,7 +80,7 @@ def lru_cache(maxsize=128): # noqa as it's a fake implementation.
8080__version__ = '2.3.1'
8181
8282DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox'
83- DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503'
83+ DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504 '
8484try :
8585 if sys .platform == 'win32' :
8686 USER_CONFIG = os .path .expanduser (r'~\.pycodestyle' )
@@ -1135,34 +1135,26 @@ def explicit_line_join(logical_line, tokens):
11351135 parens -= 1
11361136
11371137
1138- @register_check
1139- def break_around_binary_operator (logical_line , tokens ):
1140- r"""
1141- Avoid breaks before binary operators.
1138+ def _is_binary_operator (token_type , text ):
1139+ is_op_token = token_type == tokenize .OP
1140+ is_conjunction = text in ['and' , 'or' ]
1141+ # NOTE(sigmavirus24): Previously the not_a_symbol check was executed
1142+ # conditionally. Since it is now *always* executed, text may be None.
1143+ # In that case we get a TypeError for `text not in str`.
1144+ not_a_symbol = text and text not in "()[]{},:.;@=%~"
1145+ # The % character is strictly speaking a binary operator, but the
1146+ # common usage seems to be to put it next to the format parameters,
1147+ # after a line break.
1148+ return ((is_op_token or is_conjunction ) and not_a_symbol )
11421149
1143- The preferred place to break around a binary operator is after the
1144- operator, not before it.
11451150
1146- W503: (width == 0\n + height == 0)
1147- W503: (width == 0\n and height == 0)
1151+ def _break_around_binary_operators ( tokens ):
1152+ """Private function to reduce duplication.
11481153
1149- Okay: (width == 0 +\n height == 0)
1150- Okay: foo(\n -x)
1151- Okay: foo(x\n [])
1152- Okay: x = '''\n''' + ''
1153- Okay: foo(x,\n -y)
1154- Okay: foo(x, # comment\n -y)
1155- Okay: var = (1 &\n ~2)
1156- Okay: var = (1 /\n -2)
1157- Okay: var = (1 +\n -1 +\n -2)
1154+ This factors out the shared details between
1155+ :func:`break_before_binary_operator` and
1156+ :func:`break_after_binary_operator`.
11581157 """
1159- def is_binary_operator (token_type , text ):
1160- # The % character is strictly speaking a binary operator, but the
1161- # common usage seems to be to put it next to the format parameters,
1162- # after a line break.
1163- return ((token_type == tokenize .OP or text in ['and' , 'or' ]) and
1164- text not in "()[]{},:.;@=%~" )
1165-
11661158 line_break = False
11671159 unary_context = True
11681160 # Previous non-newline token types and text
@@ -1174,17 +1166,78 @@ def is_binary_operator(token_type, text):
11741166 if ('\n ' in text or '\r ' in text ) and token_type != tokenize .STRING :
11751167 line_break = True
11761168 else :
1177- if (is_binary_operator (token_type , text ) and line_break and
1178- not unary_context and
1179- not is_binary_operator (previous_token_type ,
1180- previous_text )):
1181- yield start , "W503 line break before binary operator"
1169+ yield (token_type , text , previous_token_type , previous_text ,
1170+ line_break , unary_context , start )
11821171 unary_context = text in '([{,;'
11831172 line_break = False
11841173 previous_token_type = token_type
11851174 previous_text = text
11861175
11871176
1177+ @register_check
1178+ def break_before_binary_operator (logical_line , tokens ):
1179+ r"""
1180+ Avoid breaks before binary operators.
1181+
1182+ The preferred place to break around a binary operator is after the
1183+ operator, not before it.
1184+
1185+ W503: (width == 0\n + height == 0)
1186+ W503: (width == 0\n and height == 0)
1187+ W503: var = (1\n & ~2)
1188+ W503: var = (1\n / -2)
1189+ W503: var = (1\n + -1\n + -2)
1190+
1191+ Okay: foo(\n -x)
1192+ Okay: foo(x\n [])
1193+ Okay: x = '''\n''' + ''
1194+ Okay: foo(x,\n -y)
1195+ Okay: foo(x, # comment\n -y)
1196+ """
1197+ for context in _break_around_binary_operators (tokens ):
1198+ (token_type , text , previous_token_type , previous_text ,
1199+ line_break , unary_context , start ) = context
1200+ if (_is_binary_operator (token_type , text ) and line_break and
1201+ not unary_context and
1202+ not _is_binary_operator (previous_token_type ,
1203+ previous_text )):
1204+ yield start , "W503 line break before binary operator"
1205+
1206+
1207+ @register_check
1208+ def break_after_binary_operator (logical_line , tokens ):
1209+ r"""
1210+ Avoid breaks after binary operators.
1211+
1212+ The preferred place to break around a binary operator is before the
1213+ operator, not after it.
1214+
1215+ W504: (width == 0 +\n height == 0)
1216+ W504: (width == 0 and\n height == 0)
1217+ W504: var = (1 &\n ~2)
1218+
1219+ Okay: foo(\n -x)
1220+ Okay: foo(x\n [])
1221+ Okay: x = '''\n''' + ''
1222+ Okay: x = '' + '''\n'''
1223+ Okay: foo(x,\n -y)
1224+ Okay: foo(x, # comment\n -y)
1225+
1226+ The following should be W504 but unary_context is tricky with these
1227+ Okay: var = (1 /\n -2)
1228+ Okay: var = (1 +\n -1 +\n -2)
1229+ """
1230+ for context in _break_around_binary_operators (tokens ):
1231+ (token_type , text , previous_token_type , previous_text ,
1232+ line_break , unary_context , start ) = context
1233+ if (_is_binary_operator (previous_token_type , previous_text ) and
1234+ line_break and
1235+ not unary_context and
1236+ not _is_binary_operator (token_type , text )):
1237+ error_pos = (start [0 ] - 1 , start [1 ])
1238+ yield error_pos , "W504 line break after binary operator"
1239+
1240+
11881241@register_check
11891242def comparison_to_singleton (logical_line , noqa ):
11901243 r"""Comparison to singletons should use "is" or "is not".
0 commit comments