Skip to content

Commit 61a1f6d

Browse files
committed
Merge branch 'master' of https://github.com/gward/pep8 into gward-master
2 parents dd06247 + 9ab266d commit 61a1f6d

5 files changed

Lines changed: 98 additions & 14 deletions

File tree

pep8.py

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ def missing_newline(physical_line):
200200
return len(physical_line), "W292 no newline at end of file"
201201

202202

203-
def maximum_line_length(physical_line, max_line_length):
203+
def maximum_line_length(physical_line, max_line_length, multiline):
204204
"""
205205
Limit all lines to a maximum of 79 characters.
206206
@@ -216,6 +216,10 @@ def maximum_line_length(physical_line, max_line_length):
216216
line = physical_line.rstrip()
217217
length = len(line)
218218
if length > max_line_length and not noqa(line):
219+
# Sometimes, long lines in docstrings are hard to avoid -- like,
220+
# a long URL that can't be wrapped because it has no whitespace.
221+
if multiline and re.match(r'^\s*\S+$', line):
222+
return
219223
if hasattr(line, 'decode'): # Python 2
220224
# The line could contain multi-byte characters
221225
try:
@@ -1189,6 +1193,7 @@ def __init__(self, filename=None, lines=None,
11891193
self._logical_checks = options.logical_checks
11901194
self._ast_checks = options.ast_checks
11911195
self.max_line_length = options.max_line_length
1196+
self.multiline = False # in a multiline string?
11921197
self.hang_closing = options.hang_closing
11931198
self.verbose = options.verbose
11941199
self.filename = filename
@@ -1237,16 +1242,9 @@ def readline(self):
12371242
self.line_number += 1
12381243
if self.line_number > len(self.lines):
12391244
return ''
1240-
return self.lines[self.line_number - 1]
1241-
1242-
def readline_check_physical(self):
1243-
"""
1244-
Check and return the next physical line. This method can be
1245-
used to feed tokenize.generate_tokens.
1246-
"""
1247-
line = self.readline()
1248-
if line:
1249-
self.check_physical(line)
1245+
line = self.lines[self.line_number - 1]
1246+
if self.indent_char is None and line[:1] in WHITESPACE:
1247+
self.indent_char = line[0]
12501248
return line
12511249

12521250
def run_check(self, check, argument_names):
@@ -1263,8 +1261,6 @@ def check_physical(self, line):
12631261
Run all physical checks on a raw input line.
12641262
"""
12651263
self.physical_line = line
1266-
if self.indent_char is None and line[:1] in WHITESPACE:
1267-
self.indent_char = line[0]
12681264
for name, check, argument_names in self._physical_checks:
12691265
result = self.run_check(check, argument_names)
12701266
if result is not None:
@@ -1352,13 +1348,47 @@ def check_ast(self):
13521348
def generate_tokens(self):
13531349
if self._io_error:
13541350
self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
1355-
tokengen = tokenize.generate_tokens(self.readline_check_physical)
1351+
tokengen = tokenize.generate_tokens(self.readline)
13561352
try:
13571353
for token in tokengen:
13581354
yield token
1355+
self.maybe_check_physical(token)
13591356
except (SyntaxError, tokenize.TokenError):
13601357
self.report_invalid_syntax()
13611358

1359+
def maybe_check_physical(self, token):
1360+
"""
1361+
If appropriate (based on token), check current physical line(s).
1362+
"""
1363+
# This is called after every token, but we only want to take action
1364+
# after a token that ends a line.
1365+
if token[0] in (tokenize.NEWLINE, tokenize.NL):
1366+
# Obviously, a newline token ends a single physical line.
1367+
self.check_physical(token[4])
1368+
elif token[0] == tokenize.STRING and token[1].count('\n'):
1369+
# Less obviously, a string that contains newlines is a
1370+
# multiline string, either triple-quoted or with internal
1371+
# newlines backslash-escaped. Check every physical line in the
1372+
# string *except* for the last one: its newline is outside of
1373+
# the multiline string, so we consider it a regular physical
1374+
# line, and will check it like any other physical line.
1375+
#
1376+
# Subtleties:
1377+
# - we don't *completely* ignore the last line; if it contains
1378+
# the magical "# noqa" comment, we disable all physical
1379+
# checks for the entire multiline string
1380+
# - have to wind self.line_number back because initially it
1381+
# points to the last line of the string, and we want
1382+
# check_physical() to give accurate feedback
1383+
if noqa(token[4]):
1384+
return
1385+
self.multiline = True
1386+
self.line_number = token[2][0]
1387+
for line in token[1].split('\n')[:-1]:
1388+
self.check_physical(line + '\n')
1389+
self.line_number += 1
1390+
self.multiline = False
1391+
13621392
def check_all(self, expected=None, line_offset=0):
13631393
"""
13641394
Run all checks on the input file.

testsuite/E50.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,26 @@
4545
('''
4646
''' + ' \
4747
')
48+
#: E501 E225 E226
49+
very_long_identifiers=and_terrible_whitespace_habits(are_no_excuse+for_long_lines)
50+
#
51+
#: E501
52+
'''multiline string
53+
with a long long long long long long long long long long long long long long long long line
54+
'''
55+
#: E501
56+
'''same thing, but this time without a terminal newline in the string
57+
long long long long long long long long long long long long long long long long line'''
58+
#
59+
# issue 224 (unavoidable long lines in docstrings)
60+
#: Okay
61+
"""
62+
I'm some great documentation. Because I'm some great documentation, I'm
63+
going to give you a reference to some valuable information about some API
64+
that I'm calling:
65+
66+
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
67+
"""
68+
#: E501
69+
"""
70+
longnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaces"""

testsuite/W19.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,28 @@ def long_function_name(
9797
if os.path.exists(os.path.join(path, PEP8_BIN)):
9898
cmd = ([os.path.join(path, PEP8_BIN)] +
9999
self._pep8_options(targetfile))
100+
#: W191
101+
'''
102+
multiline string with tab in it'''
103+
#: E101 W191
104+
'''multiline string
105+
with tabs
106+
and spaces
107+
'''
108+
#: Okay
109+
'''sometimes, you just need to go nuts in a multiline string
110+
and allow all sorts of crap
111+
like mixed tabs and spaces
112+
113+
or trailing whitespace
114+
or long long long long long long long long long long long long long long long long long lines
115+
''' # nopep8
116+
#: Okay
117+
'''this one
118+
will get no warning
119+
even though the noqa comment is not immediately after the string
120+
''' + foo # noqa
121+
#
100122
#: E101 W191
101123
if foo is None and bar is "frop" and \
102124
blah == 'yeah':

testsuite/W29.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@
66
class Foo(object):
77

88
bang = 12
9+
#: W291
10+
'''multiline
11+
string with trailing whitespace'''
912
#: W292
1013
# This line doesn't have a linefeed

testsuite/W39no.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#: Okay
2+
'''there is nothing wrong
3+
with a multiline string at EOF
4+
5+
that happens to have a blank line in it
6+
'''

0 commit comments

Comments
 (0)