Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pycqa/pycodestyle
1 result
Show changes
Commits on Source (6)
Loading
Loading
@@ -6,6 +6,8 @@ UNRELEASED
 
New checks:
 
* Add W504 warning for checking that a break doesn't happen after a binary
operator. This check is ignored by default
* Add W605 warning for invalid escape sequences in string literals
 
2.3.1 (2017-01-31)
Loading
Loading
Loading
Loading
@@ -80,7 +80,7 @@ except ImportError:
__version__ = '2.3.1'
 
DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox'
DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503'
DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504'
try:
if sys.platform == 'win32':
USER_CONFIG = os.path.expanduser(r'~\.pycodestyle')
Loading
Loading
@@ -1135,34 +1135,26 @@ def explicit_line_join(logical_line, tokens):
parens -= 1
 
 
@register_check
def break_around_binary_operator(logical_line, tokens):
r"""
Avoid breaks before binary operators.
def _is_binary_operator(token_type, text):
is_op_token = token_type == tokenize.OP
is_conjunction = text in ['and', 'or']
# NOTE(sigmavirus24): Previously the not_a_symbol check was executed
# conditionally. Since it is now *always* executed, text may be None.
# In that case we get a TypeError for `text not in str`.
not_a_symbol = text and text not in "()[]{},:.;@=%~"
# 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 ((is_op_token or is_conjunction) and not_a_symbol)
 
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)
def _break_around_binary_operators(tokens):
"""Private function to reduce duplication.
 
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)
Okay: var = (1 &\n ~2)
Okay: var = (1 /\n -2)
Okay: var = (1 +\n -1 +\n -2)
This factors out the shared details between
:func:`break_before_binary_operator` and
:func:`break_after_binary_operator`.
"""
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
# Previous non-newline token types and text
Loading
Loading
@@ -1174,17 +1166,78 @@ def break_around_binary_operator(logical_line, tokens):
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 and
not is_binary_operator(previous_token_type,
previous_text)):
yield start, "W503 line break before binary operator"
yield (token_type, text, previous_token_type, previous_text,
line_break, unary_context, start)
unary_context = text in '([{,;'
line_break = False
previous_token_type = token_type
previous_text = text
 
 
@register_check
def break_before_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)
W503: var = (1\n & ~2)
W503: var = (1\n / -2)
W503: var = (1\n + -1\n + -2)
Okay: foo(\n -x)
Okay: foo(x\n [])
Okay: x = '''\n''' + ''
Okay: foo(x,\n -y)
Okay: foo(x, # comment\n -y)
"""
for context in _break_around_binary_operators(tokens):
(token_type, text, previous_token_type, previous_text,
line_break, unary_context, start) = context
if (_is_binary_operator(token_type, text) and line_break and
not unary_context and
not _is_binary_operator(previous_token_type,
previous_text)):
yield start, "W503 line break before binary operator"
@register_check
def break_after_binary_operator(logical_line, tokens):
r"""
Avoid breaks after binary operators.
The preferred place to break around a binary operator is before the
operator, not after it.
W504: (width == 0 +\n height == 0)
W504: (width == 0 and\n height == 0)
W504: var = (1 &\n ~2)
Okay: foo(\n -x)
Okay: foo(x\n [])
Okay: x = '''\n''' + ''
Okay: x = '' + '''\n'''
Okay: foo(x,\n -y)
Okay: foo(x, # comment\n -y)
The following should be W504 but unary_context is tricky with these
Okay: var = (1 /\n -2)
Okay: var = (1 +\n -1 +\n -2)
"""
for context in _break_around_binary_operators(tokens):
(token_type, text, previous_token_type, previous_text,
line_break, unary_context, start) = context
if (_is_binary_operator(previous_token_type, previous_text) and
line_break and
not unary_context and
not _is_binary_operator(token_type, text)):
error_pos = (start[0] - 1, start[1])
yield error_pos, "W504 line break after binary operator"
@register_check
def comparison_to_singleton(logical_line, noqa):
r"""Comparison to singletons should use "is" or "is not".
Loading
Loading
Loading
Loading
@@ -6,5 +6,5 @@ license_file = LICENSE
 
[pycodestyle]
select =
ignore = E226,E24
ignore = E226,E24,W504
max_line_length = 79
Loading
Loading
@@ -20,9 +20,9 @@ print "E124", ("visual",
#: E124
a = (123,
)
#: E129
if (row < 0 or self.moduleCount <= row or
col < 0 or self.moduleCount <= col):
#: E129 W503
if (row < 0 or self.moduleCount <= row
or col < 0 or self.moduleCount <= col):
raise Exception("%s,%s - %s" % (row, col, self.moduleCount))
#: E126
print "E126", (
Loading
Loading
@@ -195,9 +195,9 @@ def qualify_by_address(
self, cr, uid, ids, context=None,
params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)):
""" This gets called by the web server """
#: E129
if (a == 2 or
b == "abc def ghi"
#: E129 W503
if (a == 2
or b == "abc def ghi"
"jkl mno"):
return True
#:
Loading
Loading
@@ -225,22 +225,21 @@ rv.update(dict.fromkeys((
eat_a_dict_a_day({
"foo": "bar",
})
#: E126
#: E126 W503
if (
x == (
3
) or
y == 4):
)
or y == 4):
pass
#: E126
#: E126 W503 W503
if (
x == (
3
) or
x == (
3
) or
y == 4):
)
or x == (
3)
or y == 4):
pass
#: E131
troublesome_hash = {
Loading
Loading
if (
x == (
3
) or
y == 4):
) or y == 4):
pass
 
y = x == 2 \
Loading
Loading
@@ -17,15 +16,14 @@ if x == 2 \
or y > 1 \
or x == 3:
pass
if (foo == bar and
baz == frop):
#: W503
if (foo == bar
and baz == frop):
pass
#: W503
if (
foo == bar and
baz == frop
foo == bar
and baz == frop
):
pass
 
Loading
Loading
@@ -109,7 +107,7 @@ sat = 'AAA' \
'BBB' \
'iii' \
'CCC'
#: W504 W504
abricot = (3 +
4 +
5 + 6)
Loading
Loading
@@ -138,8 +136,7 @@ def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
#: W504
if ((row < 0 or self.moduleCount <= row or
col < 0 or self.moduleCount <= col)):
raise Exception("%s,%s - %s" % (row, col, self.moduleCount))
Loading
Loading
@@ -184,23 +181,23 @@ if bar:
"to match that of the opening "
"bracket's line"
)
#
#: W504
# you want vertical alignment, so use a parens
if ((foo.bar("baz") and
foo.bar("frop")
)):
print "yes"
#: W504
# also ok, but starting to look like LISP
if ((foo.bar("baz") and
foo.bar("frop"))):
print "yes"
#: W504
if (a == 2 or
b == "abc def ghi"
"jkl mno"):
return True
#: W504
if (a == 2 or
b == """abc def ghi
jkl mno"""):
Loading
Loading
@@ -224,22 +221,19 @@ print 'l.{line}\t{pos}\t{name}\t{text}'.format(
print('%-7d %s per second (%d total)' % (
options.counters[key] / elapsed, key,
options.counters[key]))
#: W504
if os.path.exists(os.path.join(path, PEP8_BIN)):
cmd = ([os.path.join(path, PEP8_BIN)] +
self._pep8_options(targetfile))
#: W504
fixed = (re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] +
target[c + 1:])
#: W504
fixed = (
re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] +
target[c + 1:]
)
#: W504
if foo is None and bar is "frop" and \
blah == 'yeah':
blah = 'yeahnah'
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ if False:
#: W191
y = x == 2 \
or x == 3
#: E101 W191
#: E101 W191 W504
if (
x == (
3
Loading
Loading
@@ -26,11 +26,11 @@ if x == 2 \
pass
#:
 
#: E101 W191
#: E101 W191 W504
if (foo == bar and
baz == frop):
pass
#: E101 W191
#: E101 W191 W504
if (
foo == bar and
baz == frop
Loading
Loading
@@ -52,7 +52,7 @@ def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
#: E101 W191
#: E101 W191 W504
if ((row < 0 or self.moduleCount <= row or
col < 0 or self.moduleCount <= col)):
raise Exception("%s,%s - %s" % (row, col, self.moduleCount))
Loading
Loading
@@ -65,23 +65,23 @@ if bar:
"bracket's line"
)
#
#: E101 W191
#: E101 W191 W504
# you want vertical alignment, so use a parens
if ((foo.bar("baz") and
foo.bar("frop")
)):
print "yes"
#: E101 W191
#: E101 W191 W504
# also ok, but starting to look like LISP
if ((foo.bar("baz") and
foo.bar("frop"))):
print "yes"
#: E101 W191
#: E101 W191 W504
if (a == 2 or
b == "abc def ghi"
"jkl mno"):
return True
#: E101 W191
#: E101 W191 W504
if (a == 2 or
b == """abc def ghi
jkl mno"""):
Loading
Loading
@@ -93,7 +93,7 @@ if length > options.max_line_length:
 
 
#
#: E101 W191 W191
#: E101 W191 W191 W504
if os.path.exists(os.path.join(path, PEP8_BIN)):
cmd = ([os.path.join(path, PEP8_BIN)] +
self._pep8_options(targetfile))
Loading
Loading
Loading
Loading
@@ -43,7 +43,7 @@ class PycodestyleTestCase(unittest.TestCase):
os.path.join(ROOT_DIR, 'setup.py')]
report = self._style.init_report(pycodestyle.StandardReport)
report = self._style.check_files(files)
self.assertFalse(report.total_errors,
self.assertEqual(list(report.messages.keys()), ['W504'],
msg='Failures: %s' % report.messages)
 
 
Loading
Loading
Loading
Loading
@@ -166,7 +166,7 @@ class APITestCase(unittest.TestCase):
self.assertEqual(pep8style.options.filename, ['*.py'])
self.assertEqual(pep8style.options.format, 'default')
self.assertEqual(pep8style.options.select, ())
self.assertEqual(pep8style.options.ignore, ('E226', 'E24'))
self.assertEqual(pep8style.options.ignore, ('E226', 'E24', 'W504'))
self.assertEqual(pep8style.options.max_line_length, 79)
 
def test_styleguide_ignore_code(self):
Loading
Loading
@@ -182,7 +182,7 @@ class APITestCase(unittest.TestCase):
self.assertEqual(options.select, ())
self.assertEqual(
options.ignore,
('E121', 'E123', 'E126', 'E226', 'E24', 'E704', 'W503')
('E121', 'E123', 'E126', 'E226', 'E24', 'E704', 'W503', 'W504')
)
 
options = parse_argv('--doctest').options
Loading
Loading