Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pycodestyle.py: 68%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1367 statements  

1#!/usr/bin/env python 

2# pycodestyle.py - Check Python source code formatting, according to 

3# PEP 8 

4# 

5# Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net> 

6# Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> 

7# Copyright (C) 2014-2016 Ian Lee <ianlee1521@gmail.com> 

8# 

9# Permission is hereby granted, free of charge, to any person 

10# obtaining a copy of this software and associated documentation files 

11# (the "Software"), to deal in the Software without restriction, 

12# including without limitation the rights to use, copy, modify, merge, 

13# publish, distribute, sublicense, and/or sell copies of the Software, 

14# and to permit persons to whom the Software is furnished to do so, 

15# subject to the following conditions: 

16# 

17# The above copyright notice and this permission notice shall be 

18# included in all copies or substantial portions of the Software. 

19# 

20# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 

21# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 

22# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 

23# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 

24# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 

25# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 

26# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 

27# SOFTWARE. 

28r""" 

29Check Python source code formatting, according to PEP 8. 

30 

31For usage and a list of options, try this: 

32$ python pycodestyle.py -h 

33 

34This program and its regression test suite live here: 

35https://github.com/pycqa/pycodestyle 

36 

37Groups of errors and warnings: 

38E errors 

39W warnings 

40100 indentation 

41200 whitespace 

42300 blank lines 

43400 imports 

44500 line length 

45600 deprecation 

46700 statements 

47900 syntax error 

48""" 

49import bisect 

50import configparser 

51import inspect 

52import io 

53import keyword 

54import os 

55import re 

56import sys 

57import time 

58import tokenize 

59import warnings 

60from fnmatch import fnmatch 

61from functools import lru_cache 

62from itertools import pairwise 

63from optparse import OptionParser 

64 

65__version__ = '2.15.0' 

66 

67DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' 

68DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' 

69try: 

70 if sys.platform == 'win32': # pragma: win32 cover 

71 USER_CONFIG = os.path.expanduser(r'~\.pycodestyle') 

72 else: # pragma: win32 no cover 

73 USER_CONFIG = os.path.join( 

74 os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), 

75 'pycodestyle' 

76 ) 

77except ImportError: 

78 USER_CONFIG = None 

79 

80PROJECT_CONFIG = ('setup.cfg', 'tox.ini') 

81MAX_LINE_LENGTH = 79 

82# Number of blank lines between various code parts. 

83BLANK_LINES_CONFIG = { 

84 # Top level class and function. 

85 'top_level': 2, 

86 # Methods and nested class and function. 

87 'method': 1, 

88} 

89MAX_DOC_LENGTH = 72 

90INDENT_SIZE = 4 

91REPORT_FORMAT = { 

92 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s', 

93 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s', 

94} 

95 

96PyCF_ONLY_AST = 1024 

97SINGLETONS = frozenset(['False', 'None', 'True']) 

98KEYWORDS = frozenset(keyword.kwlist + ['print']) - SINGLETONS 

99UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) 

100ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-', '@']) 

101WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%']) 

102WS_NEEDED_OPERATORS = frozenset([ 

103 '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<', '>', 

104 '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=', 

105 'and', 'in', 'is', 'or', '->', ':=']) 

106WHITESPACE = frozenset(' \t\xa0') 

107NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) 

108SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) 

109# ERRORTOKEN is triggered by backticks in Python 3 

110SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN]) 

111BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines'] 

112 

113INDENT_REGEX = re.compile(r'([ \t]*)') 

114ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b') 

115DOCSTRING_REGEX = re.compile(r'u?r?["\']') 

116EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[\[({][ \t]|[ \t][\]}),;:](?!=)') 

117WHITESPACE_AFTER_DECORATOR_REGEX = re.compile(r'@\s') 

118WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)') 

119COMPARE_SINGLETON_REGEX = re.compile(r'(\bNone|\bFalse|\bTrue)?\s*([=!]=)' 

120 r'\s*(?(1)|(None|False|True))\b') 

121COMPARE_NEGATIVE_REGEX = re.compile(r'\b(?<!is\s)(not)\s+[^][)(}{ ]+\s+' 

122 r'(in|is)\s') 

123COMPARE_TYPE_REGEX = re.compile( 

124 r'[=!]=\s+type(?:\s*\(\s*([^)]*[^\s)])\s*\))' 

125 r'|(?<!\.)\btype(?:\s*\(\s*([^)]*[^\s)])\s*\))\s+[=!]=' 

126) 

127KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS)) 

128OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+|:=)(\s*)') 

129LAMBDA_REGEX = re.compile(r'\blambda\b') 

130HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$') 

131STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\b') 

132STARTSWITH_GENERIC_REGEX = re.compile(r'^(async\s+def|def|class|type)\s+\w+\[') 

133STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)') 

134STARTSWITH_INDENT_STATEMENT_REGEX = re.compile( 

135 r'^\s*({})\b'.format('|'.join(s.replace(' ', r'\s+') for s in ( 

136 'def', 'async def', 

137 'for', 'async for', 

138 'if', 'elif', 'else', 

139 'try', 'except', 'finally', 

140 'with', 'async with', 

141 'class', 

142 'while', 

143 ))) 

144) 

145DUNDER_REGEX = re.compile(r"^__([^\s]+)__(?::\s*[a-zA-Z.0-9_\[\]\"]+)? = ") 

146BLANK_EXCEPT_REGEX = re.compile(r"except\s*:") 

147 

148if sys.version_info >= (3, 12): # pragma: >=3.12 cover 

149 FSTRING_START = tokenize.FSTRING_START 

150 FSTRING_MIDDLE = tokenize.FSTRING_MIDDLE 

151 FSTRING_END = tokenize.FSTRING_END 

152else: # pragma: <3.12 cover 

153 FSTRING_START = FSTRING_MIDDLE = FSTRING_END = -1 

154 

155if sys.version_info >= (3, 14): # pragma: >=3.14 cover 

156 TSTRING_START = tokenize.TSTRING_START 

157 TSTRING_MIDDLE = tokenize.TSTRING_MIDDLE 

158 TSTRING_END = tokenize.TSTRING_END 

159else: # pragma: <3.14 cover 

160 TSTRING_START = TSTRING_MIDDLE = TSTRING_END = -1 

161 

162_checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}} 

163 

164 

165def _get_parameters(function): 

166 return [parameter.name 

167 for parameter 

168 in inspect.signature(function).parameters.values() 

169 if parameter.kind == parameter.POSITIONAL_OR_KEYWORD] 

170 

171 

172def register_check(check, codes=None): 

173 """Register a new check object.""" 

174 def _add_check(check, kind, codes, args): 

175 if check in _checks[kind]: 

176 _checks[kind][check][0].extend(codes or []) 

177 else: 

178 _checks[kind][check] = (codes or [''], args) 

179 if inspect.isfunction(check): 

180 args = _get_parameters(check) 

181 if args and args[0] in ('physical_line', 'logical_line'): 

182 if codes is None: 

183 codes = ERRORCODE_REGEX.findall(check.__doc__ or '') 

184 _add_check(check, args[0], codes, args) 

185 elif inspect.isclass(check): 

186 if _get_parameters(check.__init__)[:2] == ['self', 'tree']: 

187 _add_check(check, 'tree', codes, None) 

188 return check 

189 

190 

191######################################################################## 

192# Plugins (check functions) for physical lines 

193######################################################################## 

194 

195@register_check 

196def tabs_or_spaces(physical_line, indent_char): 

197 r"""Never mix tabs and spaces. 

198 

199 The most popular way of indenting Python is with spaces only. The 

200 second-most popular way is with tabs only. Code indented with a 

201 mixture of tabs and spaces should be converted to using spaces 

202 exclusively. When invoking the Python command line interpreter with 

203 the -t option, it issues warnings about code that illegally mixes 

204 tabs and spaces. When using -tt these warnings become errors. 

205 These options are highly recommended! 

206 

207 Okay: if a == 0:\n a = 1\n b = 1 

208 """ 

209 indent = INDENT_REGEX.match(physical_line).group(1) 

210 for offset, char in enumerate(indent): 

211 if char != indent_char: 

212 return offset, "E101 indentation contains mixed spaces and tabs" 

213 

214 

215@register_check 

216def tabs_obsolete(physical_line): 

217 r"""On new projects, spaces-only are strongly recommended over tabs. 

218 

219 Okay: if True:\n return 

220 W191: if True:\n\treturn 

221 """ 

222 indent = INDENT_REGEX.match(physical_line).group(1) 

223 if '\t' in indent: 

224 return indent.index('\t'), "W191 indentation contains tabs" 

225 

226 

227@register_check 

228def trailing_whitespace(physical_line): 

229 r"""Trailing whitespace is superfluous. 

230 

231 The warning returned varies on whether the line itself is blank, 

232 for easier filtering for those who want to indent their blank lines. 

233 

234 Okay: spam(1)\n# 

235 W291: spam(1) \n# 

236 W293: class Foo(object):\n \n bang = 12 

237 """ 

238 # Strip these trailing characters: 

239 # - chr(10), newline 

240 # - chr(13), carriage return 

241 # - chr(12), form feed, ^L 

242 physical_line = physical_line.rstrip('\n\r\x0c') 

243 stripped = physical_line.rstrip(' \t\v') 

244 if physical_line != stripped: 

245 if stripped: 

246 return len(stripped), "W291 trailing whitespace" 

247 else: 

248 return 0, "W293 blank line contains whitespace" 

249 

250 

251@register_check 

252def trailing_blank_lines(physical_line, lines, line_number, total_lines): 

253 r"""Trailing blank lines are superfluous. 

254 

255 Okay: spam(1) 

256 W391: spam(1)\n 

257 

258 However the last line should end with a new line (warning W292). 

259 """ 

260 if line_number == total_lines: 

261 stripped_last_line = physical_line.rstrip('\r\n') 

262 if physical_line and not stripped_last_line: 

263 return 0, "W391 blank line at end of file" 

264 if stripped_last_line == physical_line: 

265 return len(lines[-1]), "W292 no newline at end of file" 

266 

267 

268@register_check 

269def maximum_line_length(physical_line, max_line_length, multiline, 

270 line_number, noqa): 

271 r"""Limit all lines to a maximum of 79 characters. 

272 

273 There are still many devices around that are limited to 80 character 

274 lines; plus, limiting windows to 80 characters makes it possible to 

275 have several windows side-by-side. The default wrapping on such 

276 devices looks ugly. Therefore, please limit all lines to a maximum 

277 of 79 characters. For flowing long blocks of text (docstrings or 

278 comments), limiting the length to 72 characters is recommended. 

279 

280 Reports error E501. 

281 """ 

282 line = physical_line.rstrip() 

283 length = len(line) 

284 if length > max_line_length and not noqa: 

285 # Special case: ignore long shebang lines. 

286 if line_number == 1 and line.startswith('#!'): 

287 return 

288 # Special case for long URLs in multi-line docstrings or 

289 # comments, but still report the error when the 72 first chars 

290 # are whitespaces. 

291 chunks = line.split() 

292 if ((len(chunks) == 1 and multiline) or 

293 (len(chunks) == 2 and chunks[0] == '#')) and \ 

294 len(line) - len(chunks[-1]) < max_line_length - 7: 

295 return 

296 if length > max_line_length: 

297 return (max_line_length, "E501 line too long " 

298 "(%d > %d characters)" % (length, max_line_length)) 

299 

300 

301######################################################################## 

302# Plugins (check functions) for logical lines 

303######################################################################## 

304 

305 

306def _is_one_liner(logical_line, indent_level, lines, line_number): 

307 if not STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): 

308 return False 

309 

310 line_idx = line_number - 1 

311 

312 if line_idx < 1: 

313 prev_indent = 0 

314 else: 

315 prev_indent = expand_indent(lines[line_idx - 1]) 

316 

317 if prev_indent > indent_level: 

318 return False 

319 

320 while line_idx < len(lines): 

321 line = lines[line_idx].strip() 

322 if not line.startswith('@') and STARTSWITH_TOP_LEVEL_REGEX.match(line): 

323 break 

324 else: 

325 line_idx += 1 

326 else: 

327 return False # invalid syntax: EOF while searching for def/class 

328 

329 next_idx = line_idx + 1 

330 while next_idx < len(lines): 

331 if lines[next_idx].strip(): 

332 break 

333 else: 

334 next_idx += 1 

335 else: 

336 return True # line is last in the file 

337 

338 return expand_indent(lines[next_idx]) <= indent_level 

339 

340 

341@register_check 

342def blank_lines(logical_line, blank_lines, indent_level, line_number, 

343 blank_before, previous_logical, 

344 previous_unindented_logical_line, previous_indent_level, 

345 lines): 

346 r"""Separate top-level function and class definitions with two blank 

347 lines. 

348 

349 Method definitions inside a class are separated by a single blank 

350 line. 

351 

352 Extra blank lines may be used (sparingly) to separate groups of 

353 related functions. Blank lines may be omitted between a bunch of 

354 related one-liners (e.g. a set of dummy implementations). 

355 

356 Use blank lines in functions, sparingly, to indicate logical 

357 sections. 

358 

359 Okay: def a():\n pass\n\n\ndef b():\n pass 

360 Okay: def a():\n pass\n\n\nasync def b():\n pass 

361 Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass 

362 Okay: default = 1\nfoo = 1 

363 Okay: classify = 1\nfoo = 1 

364 

365 E301: class Foo:\n b = 0\n def bar():\n pass 

366 E302: def a():\n pass\n\ndef b(n):\n pass 

367 E302: def a():\n pass\n\nasync def b(n):\n pass 

368 E303: def a():\n pass\n\n\n\ndef b(n):\n pass 

369 E303: def a():\n\n\n\n pass 

370 E304: @decorator\n\ndef a():\n pass 

371 E305: def a():\n pass\na() 

372 E306: def a():\n def b():\n pass\n def c():\n pass 

373 """ # noqa 

374 top_level_lines = BLANK_LINES_CONFIG['top_level'] 

375 method_lines = BLANK_LINES_CONFIG['method'] 

376 

377 if not previous_logical and blank_before < top_level_lines: 

378 return # Don't expect blank lines before the first line 

379 if previous_logical.startswith('@'): 

380 if blank_lines: 

381 yield 0, "E304 blank lines found after function decorator" 

382 elif (blank_lines > top_level_lines or 

383 (indent_level and blank_lines == method_lines + 1) 

384 ): 

385 yield 0, "E303 too many blank lines (%d)" % blank_lines 

386 elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): 

387 # allow a group of one-liners 

388 if ( 

389 _is_one_liner(logical_line, indent_level, lines, line_number) and 

390 blank_before == 0 

391 ): 

392 return 

393 if indent_level: 

394 if not (blank_before == method_lines or 

395 previous_indent_level < indent_level or 

396 DOCSTRING_REGEX.match(previous_logical) 

397 ): 

398 ancestor_level = indent_level 

399 nested = False 

400 # Search backwards for a def ancestor or tree root 

401 # (top level). 

402 for line in lines[line_number - top_level_lines::-1]: 

403 if line.strip() and expand_indent(line) < ancestor_level: 

404 ancestor_level = expand_indent(line) 

405 nested = STARTSWITH_DEF_REGEX.match(line.lstrip()) 

406 if nested or ancestor_level == 0: 

407 break 

408 if nested: 

409 yield 0, "E306 expected %s blank line before a " \ 

410 "nested definition, found 0" % (method_lines,) 

411 else: 

412 yield 0, "E301 expected {} blank line, found 0".format( 

413 method_lines) 

414 elif blank_before != top_level_lines: 

415 yield 0, "E302 expected %s blank lines, found %d" % ( 

416 top_level_lines, blank_before) 

417 elif (logical_line and 

418 not indent_level and 

419 blank_before != top_level_lines and 

420 previous_unindented_logical_line.startswith(('def ', 'class ')) 

421 ): 

422 yield 0, "E305 expected %s blank lines after " \ 

423 "class or function definition, found %d" % ( 

424 top_level_lines, blank_before) 

425 

426 

427@register_check 

428def extraneous_whitespace(logical_line): 

429 r"""Avoid extraneous whitespace. 

430 

431 Avoid extraneous whitespace in these situations: 

432 - Immediately inside parentheses, brackets or braces. 

433 - Immediately before a comma, semicolon, or colon. 

434 

435 Okay: spam(ham[1], {eggs: 2}) 

436 E201: spam( ham[1], {eggs: 2}) 

437 E201: spam(ham[ 1], {eggs: 2}) 

438 E201: spam(ham[1], { eggs: 2}) 

439 E202: spam(ham[1], {eggs: 2} ) 

440 E202: spam(ham[1 ], {eggs: 2}) 

441 E202: spam(ham[1], {eggs: 2 }) 

442 

443 E203: if x == 4: print x, y; x, y = y , x 

444 E203: if x == 4: print x, y ; x, y = y, x 

445 E203: if x == 4 : print x, y; x, y = y, x 

446 

447 Okay: @decorator 

448 E204: @ decorator 

449 """ 

450 line = logical_line 

451 for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): 

452 text = match.group() 

453 char = text.strip() 

454 found = match.start() 

455 if text[-1].isspace(): 

456 # assert char in '([{' 

457 yield found + 1, "E201 whitespace after '%s'" % char 

458 elif line[found - 1] != ',': 

459 code = ('E202' if char in '}])' else 'E203') # if char in ',;:' 

460 yield found, f"{code} whitespace before '{char}'" 

461 

462 if WHITESPACE_AFTER_DECORATOR_REGEX.match(logical_line): 

463 yield 1, "E204 whitespace after decorator '@'" 

464 

465 

466@register_check 

467def whitespace_around_keywords(logical_line): 

468 r"""Avoid extraneous whitespace around keywords. 

469 

470 Okay: True and False 

471 E271: True and False 

472 E272: True and False 

473 E273: True and\tFalse 

474 E274: True\tand False 

475 """ 

476 for match in KEYWORD_REGEX.finditer(logical_line): 

477 before, after = match.groups() 

478 

479 if '\t' in before: 

480 yield match.start(1), "E274 tab before keyword" 

481 elif len(before) > 1: 

482 yield match.start(1), "E272 multiple spaces before keyword" 

483 

484 if '\t' in after: 

485 yield match.start(2), "E273 tab after keyword" 

486 elif len(after) > 1: 

487 yield match.start(2), "E271 multiple spaces after keyword" 

488 

489 

490@register_check 

491def missing_whitespace_after_keyword(logical_line, tokens): 

492 r"""Keywords should be followed by whitespace. 

493 

494 Okay: from foo import (bar, baz) 

495 E275: from foo import(bar, baz) 

496 E275: from importable.module import(bar, baz) 

497 E275: if(foo): bar 

498 """ 

499 for tok0, tok1 in pairwise(tokens): 

500 # This must exclude the True/False/None singletons, which can 

501 # appear e.g. as "if x is None:", and async/await, which were 

502 # valid identifier names in old Python versions. 

503 if (tok0.end == tok1.start and 

504 tok0.type == tokenize.NAME and 

505 keyword.iskeyword(tok0.string) and 

506 tok0.string not in SINGLETONS and 

507 not (tok0.string == 'except' and tok1.string == '*') and 

508 not (tok0.string == 'yield' and tok1.string == ')') and 

509 (tok1.string and tok1.string != ':' and tok1.string != '\n')): 

510 yield tok0.end, "E275 missing whitespace after keyword" 

511 

512 

513@register_check 

514def indentation(logical_line, previous_logical, indent_char, 

515 indent_level, previous_indent_level, 

516 indent_size): 

517 r"""Use indent_size (PEP8 says 4) spaces per indentation level. 

518 

519 For really old code that you don't want to mess up, you can continue 

520 to use 8-space tabs. 

521 

522 Okay: a = 1 

523 Okay: if a == 0:\n a = 1 

524 E111: a = 1 

525 E114: # a = 1 

526 

527 Okay: for item in items:\n pass 

528 E112: for item in items:\npass 

529 E115: for item in items:\n# Hi\n pass 

530 

531 Okay: a = 1\nb = 2 

532 E113: a = 1\n b = 2 

533 E116: a = 1\n # b = 2 

534 """ 

535 c = 0 if logical_line else 3 

536 tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" 

537 if indent_level % indent_size: 

538 yield 0, tmpl % ( 

539 1 + c, 

540 "indentation is not a multiple of " + str(indent_size), 

541 ) 

542 indent_expect = previous_logical.endswith(':') 

543 if indent_expect and indent_level <= previous_indent_level: 

544 yield 0, tmpl % (2 + c, "expected an indented block") 

545 elif not indent_expect and indent_level > previous_indent_level: 

546 yield 0, tmpl % (3 + c, "unexpected indentation") 

547 

548 if indent_expect: 

549 expected_indent_amount = 8 if indent_char == '\t' else 4 

550 expected_indent_level = previous_indent_level + expected_indent_amount 

551 if indent_level > expected_indent_level: 

552 yield 0, tmpl % (7, 'over-indented') 

553 

554 

555@register_check 

556def continued_indentation(logical_line, tokens, indent_level, hang_closing, 

557 indent_char, indent_size, noqa, verbose): 

558 r"""Continuation lines indentation. 

559 

560 Continuation lines should align wrapped elements either vertically 

561 using Python's implicit line joining inside parentheses, brackets 

562 and braces, or using a hanging indent. 

563 

564 When using a hanging indent these considerations should be applied: 

565 - there should be no arguments on the first line, and 

566 - further indentation should be used to clearly distinguish itself 

567 as a continuation line. 

568 

569 Okay: a = (\n) 

570 E123: a = (\n ) 

571 

572 Okay: a = (\n 42) 

573 E121: a = (\n 42) 

574 E122: a = (\n42) 

575 E123: a = (\n 42\n ) 

576 E124: a = (24,\n 42\n) 

577 E125: if (\n b):\n pass 

578 E126: a = (\n 42) 

579 E127: a = (24,\n 42) 

580 E128: a = (24,\n 42) 

581 E129: if (a or\n b):\n pass 

582 E131: a = (\n 42\n 24) 

583 """ 

584 first_row = tokens[0][2][0] 

585 nrows = 1 + tokens[-1][2][0] - first_row 

586 if noqa or nrows == 1: 

587 return 

588 

589 # indent_next tells us whether the next block is indented; assuming 

590 # that it is indented by 4 spaces, then we should not allow 4-space 

591 # indents on the final continuation line; in turn, some other 

592 # indents are allowed to have an extra 4 spaces. 

593 indent_next = logical_line.endswith(':') 

594 

595 row = depth = 0 

596 valid_hangs = (indent_size,) if indent_char != '\t' \ 

597 else (indent_size, indent_size * 2) 

598 # remember how many brackets were opened on each line 

599 parens = [0] * nrows 

600 # relative indents of physical lines 

601 rel_indent = [0] * nrows 

602 # for each depth, collect a list of opening rows 

603 open_rows = [[0]] 

604 # for each depth, memorize the hanging indentation 

605 hangs = [None] 

606 # visual indents 

607 indent_chances = {} 

608 last_indent = tokens[0][2] 

609 visual_indent = None 

610 last_token_multiline = False 

611 # for each depth, memorize the visual indent column 

612 indent = [last_indent[1]] 

613 if verbose >= 3: 

614 print(">>> " + tokens[0][4].rstrip()) 

615 

616 for token_type, text, start, end, line in tokens: 

617 

618 newline = row < start[0] - first_row 

619 if newline: 

620 row = start[0] - first_row 

621 newline = not last_token_multiline and token_type not in NEWLINE 

622 

623 if newline: 

624 # this is the beginning of a continuation line. 

625 last_indent = start 

626 if verbose >= 3: 

627 print("... " + line.rstrip()) 

628 

629 # record the initial indent. 

630 rel_indent[row] = expand_indent(line) - indent_level 

631 

632 # identify closing bracket 

633 close_bracket = (token_type == tokenize.OP and text in ']})') 

634 

635 # is the indent relative to an opening bracket line? 

636 for open_row in reversed(open_rows[depth]): 

637 hang = rel_indent[row] - rel_indent[open_row] 

638 hanging_indent = hang in valid_hangs 

639 if hanging_indent: 

640 break 

641 if hangs[depth]: 

642 hanging_indent = (hang == hangs[depth]) 

643 # is there any chance of visual indent? 

644 visual_indent = (not close_bracket and hang > 0 and 

645 indent_chances.get(start[1])) 

646 

647 if close_bracket and indent[depth]: 

648 # closing bracket for visual indent 

649 if start[1] != indent[depth]: 

650 yield (start, "E124 closing bracket does not match " 

651 "visual indentation") 

652 elif close_bracket and not hang: 

653 # closing bracket matches indentation of opening 

654 # bracket's line 

655 if hang_closing: 

656 yield start, "E133 closing bracket is missing indentation" 

657 elif indent[depth] and start[1] < indent[depth]: 

658 if visual_indent is not True: 

659 # visual indent is broken 

660 yield (start, "E128 continuation line " 

661 "under-indented for visual indent") 

662 elif hanging_indent or (indent_next and 

663 rel_indent[row] == 2 * indent_size): 

664 # hanging indent is verified 

665 if close_bracket and not hang_closing: 

666 yield (start, "E123 closing bracket does not match " 

667 "indentation of opening bracket's line") 

668 hangs[depth] = hang 

669 elif visual_indent is True: 

670 # visual indent is verified 

671 indent[depth] = start[1] 

672 elif visual_indent in (text, str): 

673 # ignore token lined up with matching one from a 

674 # previous line 

675 pass 

676 else: 

677 # indent is broken 

678 if hang <= 0: 

679 error = "E122", "missing indentation or outdented" 

680 elif indent[depth]: 

681 error = "E127", "over-indented for visual indent" 

682 elif not close_bracket and hangs[depth]: 

683 error = "E131", "unaligned for hanging indent" 

684 else: 

685 hangs[depth] = hang 

686 if hang > indent_size: 

687 error = "E126", "over-indented for hanging indent" 

688 else: 

689 error = "E121", "under-indented for hanging indent" 

690 yield start, "%s continuation line %s" % error 

691 

692 # look for visual indenting 

693 if (parens[row] and 

694 token_type not in (tokenize.NL, tokenize.COMMENT) and 

695 not indent[depth]): 

696 indent[depth] = start[1] 

697 indent_chances[start[1]] = True 

698 if verbose >= 4: 

699 print(f"bracket depth {depth} indent to {start[1]}") 

700 # deal with implicit string concatenation 

701 elif token_type in { 

702 tokenize.STRING, 

703 tokenize.COMMENT, 

704 FSTRING_START, 

705 TSTRING_START 

706 }: 

707 indent_chances[start[1]] = str 

708 # visual indent after assert/raise/with 

709 elif not row and not depth and text in ["assert", "raise", "with"]: 

710 indent_chances[end[1] + 1] = True 

711 # special case for the "if" statement because len("if (") == 4 

712 elif not indent_chances and not row and not depth and text == 'if': 

713 indent_chances[end[1] + 1] = True 

714 elif text == ':' and line[end[1]:].isspace(): 

715 open_rows[depth].append(row) 

716 

717 # keep track of bracket depth 

718 if token_type == tokenize.OP: 

719 if text in '([{': 

720 depth += 1 

721 indent.append(0) 

722 hangs.append(None) 

723 if len(open_rows) == depth: 

724 open_rows.append([]) 

725 open_rows[depth].append(row) 

726 parens[row] += 1 

727 if verbose >= 4: 

728 print("bracket depth %s seen, col %s, visual min = %s" % 

729 (depth, start[1], indent[depth])) 

730 elif text in ')]}' and depth > 0: 

731 # parent indents should not be more than this one 

732 prev_indent = indent.pop() or last_indent[1] 

733 hangs.pop() 

734 for d in range(depth): 

735 if indent[d] > prev_indent: 

736 indent[d] = 0 

737 for ind in list(indent_chances): 

738 if ind >= prev_indent: 

739 del indent_chances[ind] 

740 del open_rows[depth + 1:] 

741 depth -= 1 

742 if depth: 

743 indent_chances[indent[depth]] = True 

744 for idx in range(row, -1, -1): 

745 if parens[idx]: 

746 parens[idx] -= 1 

747 break 

748 assert len(indent) == depth + 1 

749 if start[1] not in indent_chances: 

750 # allow lining up tokens 

751 indent_chances[start[1]] = text 

752 

753 last_token_multiline = (start[0] != end[0]) 

754 if last_token_multiline: 

755 rel_indent[end[0] - first_row] = rel_indent[row] 

756 

757 if indent_next and expand_indent(line) == indent_level + indent_size: 

758 pos = (start[0], indent[0] + indent_size) 

759 if visual_indent: 

760 code = "E129 visually indented line" 

761 else: 

762 code = "E125 continuation line" 

763 yield pos, "%s with same indent as next logical line" % code 

764 

765 

766@register_check 

767def whitespace_before_parameters(logical_line, tokens): 

768 r"""Avoid extraneous whitespace. 

769 

770 Avoid extraneous whitespace in the following situations: 

771 - before the open parenthesis that starts the argument list of a 

772 function call. 

773 - before the open parenthesis that starts an indexing or slicing. 

774 

775 Okay: spam(1) 

776 E211: spam (1) 

777 

778 Okay: dict['key'] = list[index] 

779 E211: dict ['key'] = list[index] 

780 E211: dict['key'] = list [index] 

781 """ 

782 prev_type, prev_text, __, prev_end, __ = tokens[0] 

783 for index in range(1, len(tokens)): 

784 token_type, text, start, end, __ = tokens[index] 

785 if ( 

786 token_type == tokenize.OP and 

787 text in '([' and 

788 start != prev_end and 

789 (prev_type == tokenize.NAME or prev_text in '}])') and 

790 # Syntax "class A (B):" is allowed, but avoid it 

791 (index < 2 or tokens[index - 2][1] != 'class') and 

792 # Allow "return (a.foo for a in range(5))" 

793 not keyword.iskeyword(prev_text) and 

794 ( 

795 # 3.12+: type is a soft keyword but no braces after 

796 prev_text == 'type' or 

797 not keyword.issoftkeyword(prev_text) 

798 ) 

799 ): 

800 yield prev_end, "E211 whitespace before '%s'" % text 

801 prev_type = token_type 

802 prev_text = text 

803 prev_end = end 

804 

805 

806@register_check 

807def whitespace_around_operator(logical_line): 

808 r"""Avoid extraneous whitespace around an operator. 

809 

810 Okay: a = 12 + 3 

811 E221: a = 4 + 5 

812 E222: a = 4 + 5 

813 E223: a = 4\t+ 5 

814 E224: a = 4 +\t5 

815 """ 

816 for match in OPERATOR_REGEX.finditer(logical_line): 

817 before, after = match.groups() 

818 

819 if '\t' in before: 

820 yield match.start(1), "E223 tab before operator" 

821 elif len(before) > 1: 

822 yield match.start(1), "E221 multiple spaces before operator" 

823 

824 if '\t' in after: 

825 yield match.start(2), "E224 tab after operator" 

826 elif len(after) > 1: 

827 yield match.start(2), "E222 multiple spaces after operator" 

828 

829 

830@register_check 

831def missing_whitespace(logical_line, tokens): 

832 r"""Surround operators with the correct amount of whitespace. 

833 

834 - Always surround these binary operators with a single space on 

835 either side: assignment (=), augmented assignment (+=, -= etc.), 

836 comparisons (==, <, >, !=, <=, >=, in, not in, is, is not), 

837 Booleans (and, or, not). 

838 

839 - Each comma, semicolon or colon should be followed by whitespace. 

840 

841 - If operators with different priorities are used, consider adding 

842 whitespace around the operators with the lowest priorities. 

843 

844 Okay: i = i + 1 

845 Okay: submitted += 1 

846 Okay: x = x * 2 - 1 

847 Okay: hypot2 = x * x + y * y 

848 Okay: c = (a + b) * (a - b) 

849 Okay: foo(bar, key='word', *args, **kwargs) 

850 Okay: alpha[:-i] 

851 Okay: [a, b] 

852 Okay: (3,) 

853 Okay: a[3,] = 1 

854 Okay: a[1:4] 

855 Okay: a[:4] 

856 Okay: a[1:] 

857 Okay: a[1:4:2] 

858 

859 E225: i=i+1 

860 E225: submitted +=1 

861 E225: x = x /2 - 1 

862 E225: z = x **y 

863 E225: z = 1and 1 

864 E226: c = (a+b) * (a-b) 

865 E226: hypot2 = x*x + y*y 

866 E227: c = a|b 

867 E228: msg = fmt%(errno, errmsg) 

868 E231: ['a','b'] 

869 E231: foo(bar,baz) 

870 E231: [{'a':'b'}] 

871 """ 

872 need_space = False 

873 prev_type = tokenize.OP 

874 prev_text = prev_end = None 

875 operator_types = (tokenize.OP, tokenize.NAME) 

876 brace_stack = [] 

877 for token_type, text, start, end, line in tokens: 

878 if token_type == tokenize.OP and text in {'[', '(', '{'}: 

879 brace_stack.append(text) 

880 elif token_type == FSTRING_START: # pragma: >=3.12 cover 

881 brace_stack.append('f') 

882 elif token_type == TSTRING_START: # pragma: >=3.14 cover 

883 brace_stack.append('t') 

884 elif token_type == tokenize.NAME and text == 'lambda': 

885 brace_stack.append('l') 

886 elif brace_stack: 

887 if token_type == tokenize.OP and text in {']', ')', '}'}: 

888 brace_stack.pop() 

889 elif token_type == FSTRING_END: # pragma: >=3.12 cover 

890 brace_stack.pop() 

891 elif token_type == TSTRING_END: # pragma: >=3.14 cover 

892 brace_stack.pop() 

893 elif ( 

894 brace_stack[-1] == 'l' and 

895 token_type == tokenize.OP and 

896 text == ':' 

897 ): 

898 brace_stack.pop() 

899 

900 if token_type in SKIP_COMMENTS: 

901 continue 

902 

903 if token_type == tokenize.OP and text in {',', ';', ':'}: 

904 next_char = line[end[1]:end[1] + 1] 

905 if next_char not in WHITESPACE and next_char not in '\r\n': 

906 # slice 

907 if text == ':' and brace_stack[-1:] == ['[']: 

908 pass 

909 # 3.12+ fstring format specifier 

910 elif text == ':' and brace_stack[-2:] == ['f', '{']: # pragma: >=3.12 cover # noqa: E501 

911 pass 

912 # 3.14+ tstring format specifier 

913 elif text == ':' and brace_stack[-2:] == ['t', '{']: # pragma: >=3.14 cover # noqa: E501 

914 pass 

915 # tuple (and list for some reason?) 

916 elif text == ',' and next_char in ')]': 

917 pass 

918 else: 

919 yield start, f'E231 missing whitespace after {text!r}' 

920 

921 if need_space: 

922 if start != prev_end: 

923 # Found a (probably) needed space 

924 if need_space is not True and not need_space[1]: 

925 yield (need_space[0], 

926 "E225 missing whitespace around operator") 

927 need_space = False 

928 elif ( 

929 # def f(a, /, b): 

930 # ^ 

931 # def f(a, b, /): 

932 # ^ 

933 # f = lambda a, /: 

934 # ^ 

935 prev_text == '/' and text in {',', ')', ':'} or 

936 # def f(a, b, /): 

937 # ^ 

938 prev_text == ')' and text == ':' 

939 ): 

940 # Tolerate the "/" operator in function definition 

941 # For more info see PEP570 

942 pass 

943 else: 

944 if need_space is True or need_space[1]: 

945 # A needed trailing space was not found 

946 yield prev_end, "E225 missing whitespace around operator" 

947 elif prev_text != '**': 

948 code, optype = 'E226', 'arithmetic' 

949 if prev_text == '%': 

950 code, optype = 'E228', 'modulo' 

951 elif prev_text not in ARITHMETIC_OP: 

952 code, optype = 'E227', 'bitwise or shift' 

953 yield (need_space[0], "%s missing whitespace " 

954 "around %s operator" % (code, optype)) 

955 need_space = False 

956 elif token_type in operator_types and prev_end is not None: 

957 if ( 

958 text == '=' and ( 

959 # allow lambda default args: lambda x=None: None 

960 brace_stack[-1:] == ['l'] or 

961 # allow keyword args or defaults: foo(bar=None). 

962 brace_stack[-1:] == ['('] or 

963 # allow python 3.8 fstring repr specifier 

964 brace_stack[-2:] == ['f', '{'] or 

965 # allow python 3.8 fstring repr specifier 

966 brace_stack[-2:] == ['t', '{'] 

967 ) 

968 ): 

969 pass 

970 elif text in WS_NEEDED_OPERATORS: 

971 need_space = True 

972 elif text in UNARY_OPERATORS: 

973 # Check if the operator is used as a binary operator 

974 # Allow unary operators: -123, -x, +1. 

975 # Allow argument unpacking: foo(*args, **kwargs). 

976 if prev_type == tokenize.OP and prev_text in '}])' or ( 

977 prev_type != tokenize.OP and 

978 prev_text not in KEYWORDS and 

979 not keyword.issoftkeyword(prev_text) 

980 ): 

981 need_space = None 

982 elif text in WS_OPTIONAL_OPERATORS: 

983 need_space = None 

984 

985 if need_space is None: 

986 # Surrounding space is optional, but ensure that 

987 # trailing space matches opening space 

988 need_space = (prev_end, start != prev_end) 

989 elif need_space and start == prev_end: 

990 # A needed opening space was not found 

991 yield prev_end, "E225 missing whitespace around operator" 

992 need_space = False 

993 prev_type = token_type 

994 prev_text = text 

995 prev_end = end 

996 

997 

998@register_check 

999def whitespace_around_comma(logical_line): 

1000 r"""Avoid extraneous whitespace after a comma or a colon. 

1001 

1002 Note: these checks are disabled by default 

1003 

1004 Okay: a = (1, 2) 

1005 E241: a = (1, 2) 

1006 E242: a = (1,\t2) 

1007 """ 

1008 line = logical_line 

1009 for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): 

1010 found = m.start() + 1 

1011 if '\t' in m.group(): 

1012 yield found, "E242 tab after '%s'" % m.group()[0] 

1013 else: 

1014 yield found, "E241 multiple spaces after '%s'" % m.group()[0] 

1015 

1016 

1017@register_check 

1018def whitespace_around_named_parameter_equals(logical_line, tokens): 

1019 r"""Don't use spaces around the '=' sign in function arguments. 

1020 

1021 Don't use spaces around the '=' sign when used to indicate a 

1022 keyword argument or a default parameter value, except when 

1023 using a type annotation. 

1024 

1025 Okay: def complex(real, imag=0.0): 

1026 Okay: return magic(r=real, i=imag) 

1027 Okay: boolean(a == b) 

1028 Okay: boolean(a != b) 

1029 Okay: boolean(a <= b) 

1030 Okay: boolean(a >= b) 

1031 Okay: def foo(arg: int = 42): 

1032 Okay: async def foo(arg: int = 42): 

1033 

1034 E251: def complex(real, imag = 0.0): 

1035 E251: return magic(r = real, i = imag) 

1036 E252: def complex(real, image: float=0.0): 

1037 """ 

1038 paren_stack = [] 

1039 no_space = False 

1040 require_space = False 

1041 prev_end = None 

1042 annotated_func_arg = False 

1043 in_def = bool(STARTSWITH_DEF_REGEX.match(logical_line)) 

1044 in_generic = bool(STARTSWITH_GENERIC_REGEX.match(logical_line)) 

1045 

1046 message = "E251 unexpected spaces around keyword / parameter equals" 

1047 missing_message = "E252 missing whitespace around parameter equals" 

1048 

1049 for token_type, text, start, end, line in tokens: 

1050 if token_type == tokenize.NL: 

1051 continue 

1052 if no_space: 

1053 no_space = False 

1054 if start != prev_end: 

1055 yield (prev_end, message) 

1056 if require_space: 

1057 require_space = False 

1058 if start == prev_end: 

1059 yield (prev_end, missing_message) 

1060 if token_type == tokenize.OP: 

1061 if text in '([': 

1062 paren_stack.append(text) 

1063 elif text in ')]' and paren_stack: 

1064 paren_stack.pop() 

1065 # def f(arg: tp = default): ... 

1066 elif text == ':' and in_def and paren_stack == ['(']: 

1067 annotated_func_arg = True 

1068 elif len(paren_stack) == 1 and text == ',': 

1069 annotated_func_arg = False 

1070 elif paren_stack and text == '=': 

1071 if ( 

1072 # PEP 696 defaults always use spaced-style `=` 

1073 # type A[T = default] = ... 

1074 # def f[T = default](): ... 

1075 # class C[T = default](): ... 

1076 (in_generic and paren_stack == ['[']) or 

1077 (annotated_func_arg and paren_stack == ['(']) 

1078 ): 

1079 require_space = True 

1080 if start == prev_end: 

1081 yield (prev_end, missing_message) 

1082 else: 

1083 no_space = True 

1084 if start != prev_end: 

1085 yield (prev_end, message) 

1086 if not paren_stack: 

1087 annotated_func_arg = False 

1088 

1089 prev_end = end 

1090 

1091 

1092@register_check 

1093def whitespace_before_comment(logical_line, tokens): 

1094 """Separate inline comments by at least two spaces. 

1095 

1096 An inline comment is a comment on the same line as a statement. 

1097 Inline comments should be separated by at least two spaces from the 

1098 statement. They should start with a # and a single space. 

1099 

1100 Each line of a block comment starts with a # and one or multiple 

1101 spaces as there can be indented text inside the comment. 

1102 

1103 Okay: x = x + 1 # Increment x 

1104 Okay: x = x + 1 # Increment x 

1105 Okay: # Block comments: 

1106 Okay: # - Block comment list 

1107 Okay: # \xa0- Block comment list 

1108 E261: x = x + 1 # Increment x 

1109 E262: x = x + 1 #Increment x 

1110 E262: x = x + 1 # Increment x 

1111 E262: x = x + 1 # \xa0Increment x 

1112 E265: #Block comment 

1113 E266: ### Block comment 

1114 """ 

1115 prev_end = (0, 0) 

1116 for token_type, text, start, end, line in tokens: 

1117 if token_type == tokenize.COMMENT: 

1118 inline_comment = line[:start[1]].strip() 

1119 if inline_comment: 

1120 if prev_end[0] == start[0] and start[1] < prev_end[1] + 2: 

1121 yield (prev_end, 

1122 "E261 at least two spaces before inline comment") 

1123 symbol, sp, comment = text.partition(' ') 

1124 bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#') 

1125 if inline_comment: 

1126 if bad_prefix or comment[:1] in WHITESPACE: 

1127 yield start, "E262 inline comment should start with '# '" 

1128 elif bad_prefix and (bad_prefix != '!' or start[0] > 1): 

1129 if bad_prefix != '#': 

1130 yield start, "E265 block comment should start with '# '" 

1131 elif comment: 

1132 yield start, "E266 too many leading '#' for block comment" 

1133 elif token_type != tokenize.NL: 

1134 prev_end = end 

1135 

1136 

1137@register_check 

1138def imports_on_separate_lines(logical_line): 

1139 r"""Place imports on separate lines. 

1140 

1141 Okay: import os\nimport sys 

1142 E401: import sys, os 

1143 

1144 Okay: from subprocess import Popen, PIPE 

1145 Okay: from myclas import MyClass 

1146 Okay: from foo.bar.yourclass import YourClass 

1147 Okay: import myclass 

1148 Okay: import foo.bar.yourclass 

1149 """ 

1150 line = logical_line 

1151 if line.startswith('import '): 

1152 found = line.find(',') 

1153 if -1 < found and ';' not in line[:found]: 

1154 yield found, "E401 multiple imports on one line" 

1155 

1156 

1157_STRING_PREFIXES = frozenset(('u', 'U', 'b', 'B', 'r', 'R')) 

1158 

1159 

1160def _is_string_literal(line): 

1161 if line: 

1162 first_char = line[0] 

1163 if first_char in _STRING_PREFIXES: 

1164 first_char = line[1] 

1165 return first_char == '"' or first_char == "'" 

1166 return False 

1167 

1168 

1169_ALLOWED_KEYWORDS_IN_IMPORTS = ( 

1170 'try', 'except', 'else', 'finally', 'with', 'if', 'elif') 

1171 

1172 

1173@register_check 

1174def module_imports_on_top_of_file( 

1175 logical_line, indent_level, checker_state, noqa): 

1176 r"""Place imports at the top of the file. 

1177 

1178 Always put imports at the top of the file, just after any module 

1179 comments and docstrings, and before module globals and constants. 

1180 

1181 Okay: import os 

1182 Okay: # this is a comment\nimport os 

1183 Okay: '''this is a module docstring'''\nimport os 

1184 Okay: r'''this is a module docstring'''\nimport os 

1185 E402: a=1\nimport os 

1186 E402: 'One string'\n"Two string"\nimport os 

1187 E402: a=1\nfrom sys import x 

1188 

1189 Okay: if x:\n import os 

1190 """ # noqa 

1191 

1192 if indent_level: # Allow imports in conditional statement/function 

1193 return 

1194 if not logical_line: # Allow empty lines or comments 

1195 return 

1196 if noqa: 

1197 return 

1198 if logical_line.startswith(( 

1199 'import ', 'from ', 

1200 'lazy import ', 'lazy from ', 

1201 )): 

1202 if checker_state.get('seen_non_imports', False): 

1203 yield 0, "E402 module level import not at top of file" 

1204 elif not checker_state.get('seen_non_imports', False): 

1205 if DUNDER_REGEX.match(logical_line): 

1206 return 

1207 elif logical_line.startswith(_ALLOWED_KEYWORDS_IN_IMPORTS): 

1208 # Allow certain keywords intermixed with imports in order to 

1209 # support conditional or filtered importing 

1210 return 

1211 elif _is_string_literal(logical_line): 

1212 # The first literal is a docstring, allow it. Otherwise, 

1213 # report error. 

1214 if checker_state.get('seen_docstring', False): 

1215 checker_state['seen_non_imports'] = True 

1216 else: 

1217 checker_state['seen_docstring'] = True 

1218 else: 

1219 checker_state['seen_non_imports'] = True 

1220 

1221 

1222@register_check 

1223def compound_statements(logical_line): 

1224 r"""Compound statements (on the same line) are generally 

1225 discouraged. 

1226 

1227 While sometimes it's okay to put an if/for/while with a small body 

1228 on the same line, never do this for multi-clause statements. 

1229 Also avoid folding such long lines! 

1230 

1231 Always use a def statement instead of an assignment statement that 

1232 binds a lambda expression directly to a name. 

1233 

1234 Okay: if foo == 'blah':\n do_blah_thing() 

1235 Okay: do_one() 

1236 Okay: do_two() 

1237 Okay: do_three() 

1238 

1239 E701: if foo == 'blah': do_blah_thing() 

1240 E701: for x in lst: total += x 

1241 E701: while t < 10: t = delay() 

1242 E701: if foo == 'blah': do_blah_thing() 

1243 E701: else: do_non_blah_thing() 

1244 E701: try: something() 

1245 E701: finally: cleanup() 

1246 E701: if foo == 'blah': one(); two(); three() 

1247 E702: do_one(); do_two(); do_three() 

1248 E703: do_four(); # useless semicolon 

1249 E704: def f(x): return 2*x 

1250 E731: f = lambda x: 2*x 

1251 """ 

1252 line = logical_line 

1253 last_char = len(line) - 1 

1254 found = line.find(':') 

1255 prev_found = 0 

1256 counts = {char: 0 for char in '{}[]()'} 

1257 while -1 < found < last_char: 

1258 update_counts(line[prev_found:found], counts) 

1259 if ( 

1260 counts['{'] <= counts['}'] and # {'a': 1} (dict) 

1261 counts['['] <= counts[']'] and # [1:2] (slice) 

1262 counts['('] <= counts[')'] and # (annotation) 

1263 line[found + 1] != '=' # assignment expression 

1264 ): 

1265 lambda_kw = LAMBDA_REGEX.search(line, 0, found) 

1266 if lambda_kw: 

1267 before = line[:lambda_kw.start()].rstrip() 

1268 if before[-1:] == '=' and before[:-1].strip().isidentifier(): 

1269 yield 0, ("E731 do not assign a lambda expression, use a " 

1270 "def") 

1271 break 

1272 if STARTSWITH_DEF_REGEX.match(line): 

1273 yield 0, "E704 multiple statements on one line (def)" 

1274 elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line): 

1275 yield found, "E701 multiple statements on one line (colon)" 

1276 prev_found = found 

1277 found = line.find(':', found + 1) 

1278 found = line.find(';') 

1279 while -1 < found: 

1280 if found < last_char: 

1281 yield found, "E702 multiple statements on one line (semicolon)" 

1282 else: 

1283 yield found, "E703 statement ends with a semicolon" 

1284 found = line.find(';', found + 1) 

1285 

1286 

1287@register_check 

1288def explicit_line_join(logical_line, tokens): 

1289 r"""Avoid explicit line join between brackets. 

1290 

1291 The preferred way of wrapping long lines is by using Python's 

1292 implied line continuation inside parentheses, brackets and braces. 

1293 Long lines can be broken over multiple lines by wrapping expressions 

1294 in parentheses. These should be used in preference to using a 

1295 backslash for line continuation. 

1296 

1297 E502: aaa = [123, \\n 123] 

1298 E502: aaa = ("bbb " \\n "ccc") 

1299 

1300 Okay: aaa = [123,\n 123] 

1301 Okay: aaa = ("bbb "\n "ccc") 

1302 Okay: aaa = "bbb " \\n "ccc" 

1303 Okay: aaa = 123 # \\ 

1304 """ 

1305 prev_start = prev_end = parens = 0 

1306 comment = False 

1307 backslash = None 

1308 for token_type, text, start, end, line in tokens: 

1309 if token_type == tokenize.COMMENT: 

1310 comment = True 

1311 if start[0] != prev_start and parens and backslash and not comment: 

1312 yield backslash, "E502 the backslash is redundant between brackets" 

1313 if start[0] != prev_start: 

1314 comment = False # Reset comment flag on newline 

1315 if end[0] != prev_end: 

1316 if line.rstrip('\r\n').endswith('\\'): 

1317 backslash = (end[0], len(line.splitlines()[-1]) - 1) 

1318 else: 

1319 backslash = None 

1320 prev_start = prev_end = end[0] 

1321 else: 

1322 prev_start = start[0] 

1323 if token_type == tokenize.OP: 

1324 if text in '([{': 

1325 parens += 1 

1326 elif text in ')]}': 

1327 parens -= 1 

1328 

1329 

1330# The % character is strictly speaking a binary operator, but the 

1331# common usage seems to be to put it next to the format parameters, 

1332# after a line break. 

1333_SYMBOLIC_OPS = frozenset("()[]{},:.;@=%~") | frozenset(("...",)) 

1334 

1335 

1336def _is_binary_operator(token_type, text): 

1337 return ( 

1338 token_type == tokenize.OP or 

1339 text in {'and', 'or'} 

1340 ) and ( 

1341 text not in _SYMBOLIC_OPS 

1342 ) 

1343 

1344 

1345def _break_around_binary_operators(tokens): 

1346 """Private function to reduce duplication. 

1347 

1348 This factors out the shared details between 

1349 :func:`break_before_binary_operator` and 

1350 :func:`break_after_binary_operator`. 

1351 """ 

1352 line_break = False 

1353 unary_context = True 

1354 # Previous non-newline token types and text 

1355 previous_token_type = None 

1356 previous_text = None 

1357 for token_type, text, start, end, line in tokens: 

1358 if token_type == tokenize.COMMENT: 

1359 continue 

1360 if ('\n' in text or '\r' in text) and token_type != tokenize.STRING: 

1361 line_break = True 

1362 else: 

1363 yield (token_type, text, previous_token_type, previous_text, 

1364 line_break, unary_context, start) 

1365 unary_context = text in '([{,;' 

1366 line_break = False 

1367 previous_token_type = token_type 

1368 previous_text = text 

1369 

1370 

1371@register_check 

1372def break_before_binary_operator(logical_line, tokens): 

1373 r""" 

1374 Avoid breaks before binary operators. 

1375 

1376 The preferred place to break around a binary operator is after the 

1377 operator, not before it. 

1378 

1379 W503: (width == 0\n + height == 0) 

1380 W503: (width == 0\n and height == 0) 

1381 W503: var = (1\n & ~2) 

1382 W503: var = (1\n / -2) 

1383 W503: var = (1\n + -1\n + -2) 

1384 

1385 Okay: foo(\n -x) 

1386 Okay: foo(x\n []) 

1387 Okay: x = '''\n''' + '' 

1388 Okay: foo(x,\n -y) 

1389 Okay: foo(x, # comment\n -y) 

1390 """ 

1391 for context in _break_around_binary_operators(tokens): 

1392 (token_type, text, previous_token_type, previous_text, 

1393 line_break, unary_context, start) = context 

1394 if (_is_binary_operator(token_type, text) and line_break and 

1395 not unary_context and 

1396 not _is_binary_operator(previous_token_type, 

1397 previous_text)): 

1398 yield start, "W503 line break before binary operator" 

1399 

1400 

1401@register_check 

1402def break_after_binary_operator(logical_line, tokens): 

1403 r""" 

1404 Avoid breaks after binary operators. 

1405 

1406 The preferred place to break around a binary operator is before the 

1407 operator, not after it. 

1408 

1409 W504: (width == 0 +\n height == 0) 

1410 W504: (width == 0 and\n height == 0) 

1411 W504: var = (1 &\n ~2) 

1412 

1413 Okay: foo(\n -x) 

1414 Okay: foo(x\n []) 

1415 Okay: x = '''\n''' + '' 

1416 Okay: x = '' + '''\n''' 

1417 Okay: foo(x,\n -y) 

1418 Okay: foo(x, # comment\n -y) 

1419 

1420 The following should be W504 but unary_context is tricky with these 

1421 Okay: var = (1 /\n -2) 

1422 Okay: var = (1 +\n -1 +\n -2) 

1423 """ 

1424 prev_start = None 

1425 for context in _break_around_binary_operators(tokens): 

1426 (token_type, text, previous_token_type, previous_text, 

1427 line_break, unary_context, start) = context 

1428 if (_is_binary_operator(previous_token_type, previous_text) and 

1429 line_break and 

1430 not unary_context and 

1431 not _is_binary_operator(token_type, text)): 

1432 yield prev_start, "W504 line break after binary operator" 

1433 prev_start = start 

1434 

1435 

1436@register_check 

1437def comparison_to_singleton(logical_line, noqa): 

1438 r"""Comparison to singletons should use "is" or "is not". 

1439 

1440 Comparisons to singletons like None should always be done 

1441 with "is" or "is not", never the equality operators. 

1442 

1443 Okay: if arg is not None: 

1444 E711: if arg != None: 

1445 E711: if None == arg: 

1446 E712: if arg == True: 

1447 E712: if False == arg: 

1448 

1449 Also, beware of writing if x when you really mean if x is not None 

1450 -- e.g. when testing whether a variable or argument that defaults to 

1451 None was set to some other value. The other value might have a type 

1452 (such as a container) that could be false in a boolean context! 

1453 """ 

1454 if noqa: 

1455 return 

1456 

1457 for match in COMPARE_SINGLETON_REGEX.finditer(logical_line): 

1458 singleton = match.group(1) or match.group(3) 

1459 same = (match.group(2) == '==') 

1460 

1461 msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) 

1462 if singleton in ('None',): 

1463 code = 'E711' 

1464 else: 

1465 code = 'E712' 

1466 nonzero = ((singleton == 'True' and same) or 

1467 (singleton == 'False' and not same)) 

1468 msg += " or 'if %scond:'" % ('' if nonzero else 'not ') 

1469 yield match.start(2), ("%s comparison to %s should be %s" % 

1470 (code, singleton, msg)) 

1471 

1472 

1473@register_check 

1474def comparison_negative(logical_line): 

1475 r"""Negative comparison should be done using "not in" and "is not". 

1476 

1477 Okay: if x not in y:\n pass 

1478 Okay: assert (X in Y or X is Z) 

1479 Okay: if not (X in Y):\n pass 

1480 Okay: zz = x is not y 

1481 E713: Z = not X in Y 

1482 E713: if not X.B in Y:\n pass 

1483 E714: if not X is Y:\n pass 

1484 E714: Z = not X.B is Y 

1485 """ 

1486 match = COMPARE_NEGATIVE_REGEX.search(logical_line) 

1487 if match: 

1488 pos = match.start(1) 

1489 if match.group(2) == 'in': 

1490 yield pos, "E713 test for membership should be 'not in'" 

1491 else: 

1492 yield pos, "E714 test for object identity should be 'is not'" 

1493 

1494 

1495@register_check 

1496def comparison_type(logical_line, noqa): 

1497 r"""Object type comparisons should `is` / `is not` / `isinstance()`. 

1498 

1499 Do not compare types directly. 

1500 

1501 Okay: if isinstance(obj, int): 

1502 Okay: if type(obj) is int: 

1503 E721: if type(obj) == type(1): 

1504 """ 

1505 match = COMPARE_TYPE_REGEX.search(logical_line) 

1506 if match and not noqa: 

1507 inst = match.group(1) 

1508 if inst and inst.isidentifier() and inst not in SINGLETONS: 

1509 return # Allow comparison for types which are not obvious 

1510 yield ( 

1511 match.start(), 

1512 "E721 do not compare types, for exact checks use `is` / `is not`, " 

1513 "for instance checks use `isinstance()`", 

1514 ) 

1515 

1516 

1517@register_check 

1518def bare_except(logical_line, noqa): 

1519 r"""When catching exceptions, mention specific exceptions when 

1520 possible. 

1521 

1522 Okay: except Exception: 

1523 Okay: except BaseException: 

1524 E722: except: 

1525 """ 

1526 if noqa: 

1527 return 

1528 

1529 match = BLANK_EXCEPT_REGEX.match(logical_line) 

1530 if match: 

1531 yield match.start(), "E722 do not use bare 'except'" 

1532 

1533 

1534@register_check 

1535def ambiguous_identifier(logical_line, tokens): 

1536 r"""Never use the characters 'l', 'O', or 'I' as variable names. 

1537 

1538 In some fonts, these characters are indistinguishable from the 

1539 numerals one and zero. When tempted to use 'l', use 'L' instead. 

1540 

1541 Okay: L = 0 

1542 Okay: o = 123 

1543 Okay: i = 42 

1544 E741: l = 0 

1545 E741: O = 123 

1546 E741: I = 42 

1547 

1548 Variables can be bound in several other contexts, including class 

1549 and function definitions, lambda functions, 'global' and 'nonlocal' 

1550 statements, exception handlers, and 'with' and 'for' statements. 

1551 In addition, we have a special handling for function parameters. 

1552 

1553 Okay: except AttributeError as o: 

1554 Okay: with lock as L: 

1555 Okay: foo(l=12) 

1556 Okay: foo(l=I) 

1557 Okay: for a in foo(l=12): 

1558 Okay: lambda arg: arg * l 

1559 Okay: lambda a=l[I:5]: None 

1560 Okay: lambda x=a.I: None 

1561 Okay: if l >= 12: 

1562 E741: except AttributeError as O: 

1563 E741: with lock as l: 

1564 E741: global I 

1565 E741: nonlocal l 

1566 E741: def foo(l): 

1567 E741: def foo(l=12): 

1568 E741: l = foo(l=12) 

1569 E741: for l in range(10): 

1570 E741: [l for l in lines if l] 

1571 E741: lambda l: None 

1572 E741: lambda a=x[1:5], l: None 

1573 E741: lambda **l: 

1574 E741: def f(**l): 

1575 E742: class I(object): 

1576 E743: def l(x): 

1577 """ 

1578 func_depth = None # set to brace depth if 'def' or 'lambda' is found 

1579 seen_colon = False # set to true if we're done with function parameters 

1580 brace_depth = 0 

1581 idents_to_avoid = ('l', 'O', 'I') 

1582 prev_type, prev_text, prev_start, prev_end, __ = tokens[0] 

1583 for index in range(1, len(tokens)): 

1584 token_type, text, start, end, line = tokens[index] 

1585 ident = pos = None 

1586 # find function definitions 

1587 if prev_text in {'def', 'lambda'}: 

1588 func_depth = brace_depth 

1589 seen_colon = False 

1590 elif ( 

1591 func_depth is not None and 

1592 text == ':' and 

1593 brace_depth == func_depth 

1594 ): 

1595 seen_colon = True 

1596 # update parameter parentheses level 

1597 if text in '([{': 

1598 brace_depth += 1 

1599 elif text in ')]}': 

1600 brace_depth -= 1 

1601 # identifiers on the lhs of an assignment operator 

1602 if text == ':=' or (text == '=' and brace_depth == 0): 

1603 if prev_text in idents_to_avoid: 

1604 ident = prev_text 

1605 pos = prev_start 

1606 # identifiers bound to values with 'as', 'for', 

1607 # 'global', or 'nonlocal' 

1608 if prev_text in ('as', 'for', 'global', 'nonlocal'): 

1609 if text in idents_to_avoid: 

1610 ident = text 

1611 pos = start 

1612 # function / lambda parameter definitions 

1613 if ( 

1614 func_depth is not None and 

1615 not seen_colon and 

1616 index < len(tokens) - 1 and tokens[index + 1][1] in ':,=)' and 

1617 prev_text in {'lambda', ',', '*', '**', '('} and 

1618 text in idents_to_avoid 

1619 ): 

1620 ident = text 

1621 pos = start 

1622 if prev_text == 'class': 

1623 if text in idents_to_avoid: 

1624 yield start, "E742 ambiguous class definition '%s'" % text 

1625 if prev_text == 'def': 

1626 if text in idents_to_avoid: 

1627 yield start, "E743 ambiguous function definition '%s'" % text 

1628 if ident: 

1629 yield pos, "E741 ambiguous variable name '%s'" % ident 

1630 prev_text = text 

1631 prev_start = start 

1632 

1633 

1634# https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals 

1635_PYTHON_3000_VALID_ESC = frozenset([ 

1636 '\n', 

1637 '\\', 

1638 '\'', 

1639 '"', 

1640 'a', 

1641 'b', 

1642 'f', 

1643 'n', 

1644 'r', 

1645 't', 

1646 'v', 

1647 '0', '1', '2', '3', '4', '5', '6', '7', 

1648 'x', 

1649 

1650 # Escape sequences only recognized in string literals 

1651 'N', 

1652 'u', 

1653 'U', 

1654]) 

1655 

1656 

1657@register_check 

1658def python_3000_invalid_escape_sequence(logical_line, tokens, noqa): 

1659 r"""Invalid escape sequences are deprecated in Python 3.6. 

1660 

1661 Okay: regex = r'\.png$' 

1662 W605: regex = '\.png$' 

1663 """ 

1664 if noqa: 

1665 return 

1666 

1667 prefixes = [] 

1668 for token_type, text, start, _, _ in tokens: 

1669 if ( 

1670 token_type == tokenize.STRING or 

1671 token_type == FSTRING_START or 

1672 token_type == TSTRING_START 

1673 ): 

1674 # Extract string modifiers (e.g. u or r) 

1675 prefixes.append(text[:text.index(text[-1])].lower()) 

1676 

1677 if ( 

1678 token_type == tokenize.STRING or 

1679 token_type == FSTRING_MIDDLE or 

1680 token_type == TSTRING_MIDDLE 

1681 ): 

1682 if 'r' not in prefixes[-1]: 

1683 start_line, start_col = start 

1684 pos = text.find('\\') 

1685 while pos >= 0: 

1686 pos += 1 

1687 if text[pos] not in _PYTHON_3000_VALID_ESC: 

1688 line = start_line + text.count('\n', 0, pos) 

1689 if line == start_line: 

1690 col = start_col + pos 

1691 else: 

1692 col = pos - text.rfind('\n', 0, pos) - 1 

1693 yield ( 

1694 (line, col - 1), 

1695 f"W605 invalid escape sequence '\\{text[pos]}'" 

1696 ) 

1697 pos = text.find('\\', pos + 1) 

1698 

1699 if ( 

1700 token_type == tokenize.STRING or 

1701 token_type == FSTRING_END or 

1702 token_type == TSTRING_END 

1703 ): 

1704 prefixes.pop() 

1705 

1706 

1707######################################################################## 

1708@register_check 

1709def maximum_doc_length(logical_line, max_doc_length, noqa, tokens): 

1710 r"""Limit all doc lines to a maximum of 72 characters. 

1711 

1712 For flowing long blocks of text (docstrings or comments), limiting 

1713 the length to 72 characters is recommended. 

1714 

1715 Reports warning W505 

1716 """ 

1717 if max_doc_length is None or noqa: 

1718 return 

1719 

1720 prev_token = None 

1721 skip_lines = set() 

1722 # Skip lines that 

1723 for token_type, text, start, end, line in tokens: 

1724 if token_type not in SKIP_COMMENTS.union([tokenize.STRING]): 

1725 skip_lines.add(line) 

1726 

1727 for token_type, text, start, end, line in tokens: 

1728 # Skip lines that aren't pure strings 

1729 if token_type == tokenize.STRING and skip_lines: 

1730 continue 

1731 if token_type in (tokenize.STRING, tokenize.COMMENT): 

1732 # Only check comment-only lines 

1733 if prev_token is None or prev_token in SKIP_TOKENS: 

1734 lines = line.splitlines() 

1735 for line_num, physical_line in enumerate(lines): 

1736 if start[0] + line_num == 1 and line.startswith('#!'): 

1737 return 

1738 length = len(physical_line) 

1739 chunks = physical_line.split() 

1740 if token_type == tokenize.COMMENT: 

1741 if (len(chunks) == 2 and 

1742 length - len(chunks[-1]) < MAX_DOC_LENGTH): 

1743 continue 

1744 if len(chunks) == 1 and line_num + 1 < len(lines): 

1745 if (len(chunks) == 1 and 

1746 length - len(chunks[-1]) < MAX_DOC_LENGTH): 

1747 continue 

1748 if length > max_doc_length: 

1749 doc_error = (start[0] + line_num, max_doc_length) 

1750 yield (doc_error, "W505 doc line too long " 

1751 "(%d > %d characters)" 

1752 % (length, max_doc_length)) 

1753 prev_token = token_type 

1754 

1755 

1756######################################################################## 

1757# Helper functions 

1758######################################################################## 

1759 

1760 

1761def readlines(filename): 

1762 """Read the source code.""" 

1763 try: 

1764 with tokenize.open(filename) as f: 

1765 return f.readlines() 

1766 except (LookupError, SyntaxError, UnicodeError): 

1767 # Fall back if file encoding is improperly declared 

1768 with open(filename, encoding='latin-1') as f: 

1769 return f.readlines() 

1770 

1771 

1772def stdin_get_value(): 

1773 """Read the value from stdin.""" 

1774 return io.TextIOWrapper(sys.stdin.buffer, errors='ignore').read() 

1775 

1776 

1777noqa = lru_cache(512)(re.compile(r'# no(?:qa|pep8)\b', re.I).search) 

1778 

1779 

1780def expand_indent(line): 

1781 r"""Return the amount of indentation. 

1782 

1783 Tabs are expanded to the next multiple of 8. 

1784 """ 

1785 line = line.rstrip('\n\r') 

1786 if '\t' not in line: 

1787 return len(line) - len(line.lstrip()) 

1788 result = 0 

1789 for char in line: 

1790 if char == '\t': 

1791 result = result // 8 * 8 + 8 

1792 elif char == ' ': 

1793 result += 1 

1794 else: 

1795 break 

1796 return result 

1797 

1798 

1799def mute_string(text): 

1800 """Replace contents with 'xxx' to prevent syntax matching.""" 

1801 # String modifiers (e.g. u or r) 

1802 start = text.index(text[-1]) + 1 

1803 end = len(text) - 1 

1804 # Triple quotes 

1805 if text[-3:] in ('"""', "'''"): 

1806 start += 2 

1807 end -= 2 

1808 return text[:start] + 'x' * (end - start) + text[end:] 

1809 

1810 

1811def parse_udiff(diff, patterns=None, parent='.'): 

1812 """Return a dictionary of matching lines.""" 

1813 # For each file of the diff, the entry key is the filename, 

1814 # and the value is a set of row numbers to consider. 

1815 rv = {} 

1816 path = nrows = None 

1817 for line in diff.splitlines(): 

1818 if nrows: 

1819 if line[:1] != '-': 

1820 nrows -= 1 

1821 continue 

1822 if line[:3] == '@@ ': 

1823 hunk_match = HUNK_REGEX.match(line) 

1824 (row, nrows) = (int(g or '1') for g in hunk_match.groups()) 

1825 rv[path].update(range(row, row + nrows)) 

1826 elif line[:3] == '+++': 

1827 path = line[4:].split('\t', 1)[0] 

1828 # Git diff will use (i)ndex, (w)ork tree, (c)ommit and 

1829 # (o)bject instead of a/b/c/d as prefixes for patches 

1830 if path[:2] in ('b/', 'w/', 'i/'): 

1831 path = path[2:] 

1832 rv[path] = set() 

1833 return { 

1834 os.path.join(parent, filepath): rows 

1835 for (filepath, rows) in rv.items() 

1836 if rows and filename_match(filepath, patterns) 

1837 } 

1838 

1839 

1840def normalize_paths(value, parent=os.curdir): 

1841 """Parse a comma-separated list of paths. 

1842 

1843 Return a list of absolute paths. 

1844 """ 

1845 if not value: 

1846 return [] 

1847 if isinstance(value, list): 

1848 return value 

1849 paths = [] 

1850 for path in value.split(','): 

1851 path = path.strip() 

1852 if '/' in path: 

1853 path = os.path.abspath(os.path.join(parent, path)) 

1854 paths.append(path.rstrip('/')) 

1855 return paths 

1856 

1857 

1858def filename_match(filename, patterns, default=True): 

1859 """Check if patterns contains a pattern that matches filename. 

1860 

1861 If patterns is unspecified, this always returns True. 

1862 """ 

1863 if not patterns: 

1864 return default 

1865 return any(fnmatch(filename, pattern) for pattern in patterns) 

1866 

1867 

1868def update_counts(s, counts): 

1869 r"""Adds one to the counts of each appearance of characters in s, 

1870 for characters in counts""" 

1871 for char in s: 

1872 if char in counts: 

1873 counts[char] += 1 

1874 

1875 

1876def _is_eol_token(token): 

1877 return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n' 

1878 

1879 

1880######################################################################## 

1881# Framework to run all checks 

1882######################################################################## 

1883 

1884 

1885class Checker: 

1886 """Load a Python source file, tokenize it, check coding style.""" 

1887 

1888 def __init__(self, filename=None, lines=None, 

1889 options=None, report=None, **kwargs): 

1890 if options is None: 

1891 options = StyleGuide(kwargs).options 

1892 else: 

1893 assert not kwargs 

1894 self._io_error = None 

1895 self._physical_checks = options.physical_checks 

1896 self._logical_checks = options.logical_checks 

1897 self._ast_checks = options.ast_checks 

1898 self.max_line_length = options.max_line_length 

1899 self.max_doc_length = options.max_doc_length 

1900 self.indent_size = options.indent_size 

1901 self.fstring_start = self.tstring_start = 0 

1902 self.multiline = False # in a multiline string? 

1903 self.hang_closing = options.hang_closing 

1904 self.indent_size = options.indent_size 

1905 self.verbose = options.verbose 

1906 self.filename = filename 

1907 # Dictionary where a checker can store its custom state. 

1908 self._checker_states = {} 

1909 if filename is None: 

1910 self.filename = 'stdin' 

1911 self.lines = lines or [] 

1912 elif filename == '-': 

1913 self.filename = 'stdin' 

1914 self.lines = stdin_get_value().splitlines(True) 

1915 elif lines is None: 

1916 try: 

1917 self.lines = readlines(filename) 

1918 except OSError: 

1919 (exc_type, exc) = sys.exc_info()[:2] 

1920 self._io_error = f'{exc_type.__name__}: {exc}' 

1921 self.lines = [] 

1922 else: 

1923 self.lines = lines 

1924 if self.lines: 

1925 ord0 = ord(self.lines[0][0]) 

1926 if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM 

1927 if ord0 == 0xfeff: 

1928 self.lines[0] = self.lines[0][1:] 

1929 elif self.lines[0][:3] == '\xef\xbb\xbf': 

1930 self.lines[0] = self.lines[0][3:] 

1931 self.report = report or options.report 

1932 self.report_error = self.report.error 

1933 self.noqa = False 

1934 

1935 def report_invalid_syntax(self): 

1936 """Check if the syntax is valid.""" 

1937 (exc_type, exc) = sys.exc_info()[:2] 

1938 if len(exc.args) > 1: 

1939 offset = exc.args[1] 

1940 if len(offset) > 2: 

1941 offset = offset[1:3] 

1942 else: 

1943 offset = (1, 0) 

1944 self.report_error(offset[0], offset[1] or 0, 

1945 f'E901 {exc_type.__name__}: {exc.args[0]}', 

1946 self.report_invalid_syntax) 

1947 

1948 def readline(self): 

1949 """Get the next line from the input buffer.""" 

1950 if self.line_number >= self.total_lines: 

1951 return '' 

1952 line = self.lines[self.line_number] 

1953 self.line_number += 1 

1954 if self.indent_char is None and line[:1] in WHITESPACE: 

1955 self.indent_char = line[0] 

1956 return line 

1957 

1958 def run_check(self, check, argument_names): 

1959 """Run a check plugin.""" 

1960 arguments = [getattr(self, name) for name in argument_names] 

1961 return check(*arguments) 

1962 

1963 def init_checker_state(self, name, argument_names): 

1964 """Prepare custom state for the specific checker plugin.""" 

1965 if 'checker_state' in argument_names: 

1966 self.checker_state = self._checker_states.setdefault(name, {}) 

1967 

1968 def check_physical(self, line): 

1969 """Run all physical checks on a raw input line.""" 

1970 self.physical_line = line 

1971 for name, check, argument_names in self._physical_checks: 

1972 self.init_checker_state(name, argument_names) 

1973 result = self.run_check(check, argument_names) 

1974 if result is not None: 

1975 (offset, text) = result 

1976 self.report_error(self.line_number, offset, text, check) 

1977 if text[:4] == 'E101': 

1978 self.indent_char = line[0] 

1979 

1980 def build_tokens_line(self): 

1981 """Build a logical line from tokens.""" 

1982 logical = [] 

1983 comments = [] 

1984 length = 0 

1985 prev_row = prev_col = mapping = None 

1986 for token_type, text, start, end, line in self.tokens: 

1987 if token_type in SKIP_TOKENS: 

1988 continue 

1989 if not mapping: 

1990 mapping = [(0, start)] 

1991 if token_type == tokenize.COMMENT: 

1992 comments.append(text) 

1993 continue 

1994 if token_type == tokenize.STRING: 

1995 text = mute_string(text) 

1996 elif token_type in {FSTRING_MIDDLE, TSTRING_MIDDLE}: # pragma: >=3.12 cover # noqa: E501 

1997 # fstring tokens are "unescaped" braces -- re-escape! 

1998 brace_count = text.count('{') + text.count('}') 

1999 text = 'x' * (len(text) + brace_count) 

2000 end = (end[0], end[1] + brace_count) 

2001 if prev_row: 

2002 (start_row, start_col) = start 

2003 if prev_row != start_row: # different row 

2004 prev_text = self.lines[prev_row - 1][prev_col - 1] 

2005 if prev_text == ',' or (prev_text not in '{[(' and 

2006 text not in '}])'): 

2007 text = ' ' + text 

2008 elif prev_col != start_col: # different column 

2009 text = line[prev_col:start_col] + text 

2010 logical.append(text) 

2011 length += len(text) 

2012 mapping.append((length, end)) 

2013 (prev_row, prev_col) = end 

2014 self.logical_line = ''.join(logical) 

2015 self.noqa = comments and noqa(''.join(comments)) 

2016 return mapping 

2017 

2018 def check_logical(self): 

2019 """Build a line from tokens and run all logical checks on it.""" 

2020 self.report.increment_logical_line() 

2021 mapping = self.build_tokens_line() 

2022 if not mapping: 

2023 return 

2024 

2025 mapping_offsets = [offset for offset, _ in mapping] 

2026 (start_row, start_col) = mapping[0][1] 

2027 start_line = self.lines[start_row - 1] 

2028 self.indent_level = expand_indent(start_line[:start_col]) 

2029 if self.blank_before < self.blank_lines: 

2030 self.blank_before = self.blank_lines 

2031 if self.verbose >= 2: 

2032 print(self.logical_line[:80].rstrip()) 

2033 for name, check, argument_names in self._logical_checks: 

2034 if self.verbose >= 4: 

2035 print(' ' + name) 

2036 self.init_checker_state(name, argument_names) 

2037 for offset, text in self.run_check(check, argument_names) or (): 

2038 if not isinstance(offset, tuple): 

2039 # As mappings are ordered, bisecting is a fast way 

2040 # to find a given offset in them. 

2041 token_offset, pos = mapping[bisect.bisect_left( 

2042 mapping_offsets, offset)] 

2043 offset = (pos[0], pos[1] + offset - token_offset) 

2044 self.report_error(offset[0], offset[1], text, check) 

2045 if self.logical_line: 

2046 self.previous_indent_level = self.indent_level 

2047 self.previous_logical = self.logical_line 

2048 if not self.indent_level: 

2049 self.previous_unindented_logical_line = self.logical_line 

2050 self.blank_lines = 0 

2051 self.tokens = [] 

2052 

2053 def check_ast(self): 

2054 """Build the file's AST and run all AST checks.""" 

2055 try: 

2056 tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) 

2057 except (ValueError, SyntaxError, TypeError): 

2058 return self.report_invalid_syntax() 

2059 for name, cls, __ in self._ast_checks: 

2060 checker = cls(tree, self.filename) 

2061 for lineno, offset, text, check in checker.run(): 

2062 if not self.lines or not noqa(self.lines[lineno - 1]): 

2063 self.report_error(lineno, offset, text, check) 

2064 

2065 def generate_tokens(self): 

2066 """Tokenize file, run physical line checks and yield tokens.""" 

2067 if self._io_error: 

2068 self.report_error(1, 0, 'E902 %s' % self._io_error, readlines) 

2069 tokengen = tokenize.generate_tokens(self.readline) 

2070 try: 

2071 prev_physical = '' 

2072 for token in tokengen: 

2073 if token[2][0] > self.total_lines: 

2074 return 

2075 self.noqa = token[4] and noqa(token[4]) 

2076 self.maybe_check_physical(token, prev_physical) 

2077 yield token 

2078 prev_physical = token[4] 

2079 except (SyntaxError, tokenize.TokenError): 

2080 self.report_invalid_syntax() 

2081 

2082 def maybe_check_physical(self, token, prev_physical): 

2083 """If appropriate for token, check current physical line(s).""" 

2084 # Called after every token, but act only on end of line. 

2085 

2086 if token.type == FSTRING_START: # pragma: >=3.12 cover 

2087 self.fstring_start = token.start[0] 

2088 elif token.type == TSTRING_START: # pragma: >=3.14 cover 

2089 self.tstring_start = token.start[0] 

2090 # a newline token ends a single physical line. 

2091 elif _is_eol_token(token): 

2092 # if the file does not end with a newline, the NEWLINE 

2093 # token is inserted by the parser, but it does not contain 

2094 # the previous physical line in `token[4]` 

2095 if token.line == '': 

2096 self.check_physical(prev_physical) 

2097 else: 

2098 self.check_physical(token.line) 

2099 elif ( 

2100 token.type == tokenize.STRING and '\n' in token.string or 

2101 token.type == FSTRING_END or 

2102 token.type == TSTRING_END 

2103 ): 

2104 # Less obviously, a string that contains newlines is a 

2105 # multiline string, either triple-quoted or with internal 

2106 # newlines backslash-escaped. Check every physical line in 

2107 # the string *except* for the last one: its newline is 

2108 # outside of the multiline string, so we consider it a 

2109 # regular physical line, and will check it like any other 

2110 # physical line. 

2111 # 

2112 # Subtleties: 

2113 # - we don't *completely* ignore the last line; if it 

2114 # contains the magical "# noqa" comment, we disable all 

2115 # physical checks for the entire multiline string 

2116 # - have to wind self.line_number back because initially it 

2117 # points to the last line of the string, and we want 

2118 # check_physical() to give accurate feedback 

2119 if noqa(token.line): 

2120 return 

2121 if token.type == FSTRING_END: # pragma: >=3.12 cover 

2122 start = self.fstring_start 

2123 elif token.type == TSTRING_END: # pragma: >=3.12 cover 

2124 start = self.tstring_start 

2125 else: 

2126 start = token.start[0] 

2127 end = token.end[0] 

2128 

2129 self.multiline = True 

2130 self.line_number = start 

2131 for line_number in range(start, end): 

2132 self.check_physical(self.lines[line_number - 1] + '\n') 

2133 self.line_number += 1 

2134 self.multiline = False 

2135 

2136 def check_all(self, expected=None, line_offset=0): 

2137 """Run all checks on the input file.""" 

2138 self.report.init_file(self.filename, self.lines, expected, line_offset) 

2139 self.total_lines = len(self.lines) 

2140 if self._ast_checks: 

2141 self.check_ast() 

2142 self.line_number = 0 

2143 self.indent_char = None 

2144 self.indent_level = self.previous_indent_level = 0 

2145 self.previous_logical = '' 

2146 self.previous_unindented_logical_line = '' 

2147 self.tokens = [] 

2148 self.blank_lines = self.blank_before = 0 

2149 parens = 0 

2150 for token in self.generate_tokens(): 

2151 self.tokens.append(token) 

2152 token_type, text = token[0:2] 

2153 if self.verbose >= 3: 

2154 if token[2][0] == token[3][0]: 

2155 pos = '[{}:{}]'.format(token[2][1] or '', token[3][1]) 

2156 else: 

2157 pos = 'l.%s' % token[3][0] 

2158 print('l.%s\t%s\t%s\t%r' % 

2159 (token[2][0], pos, tokenize.tok_name[token[0]], text)) 

2160 if token_type == tokenize.OP: 

2161 if text in '([{': 

2162 parens += 1 

2163 elif text in '}])': 

2164 parens -= 1 

2165 elif not parens: 

2166 if token_type in NEWLINE: 

2167 if token_type == tokenize.NEWLINE: 

2168 self.check_logical() 

2169 self.blank_before = 0 

2170 elif len(self.tokens) == 1: 

2171 # The physical line contains only this token. 

2172 self.blank_lines += 1 

2173 del self.tokens[0] 

2174 else: 

2175 self.check_logical() 

2176 if self.tokens: 

2177 self.check_physical(self.lines[-1]) 

2178 self.check_logical() 

2179 return self.report.get_file_results() 

2180 

2181 

2182class BaseReport: 

2183 """Collect the results of the checks.""" 

2184 

2185 print_filename = False 

2186 

2187 def __init__(self, options): 

2188 self._benchmark_keys = options.benchmark_keys 

2189 self._ignore_code = options.ignore_code 

2190 # Results 

2191 self.elapsed = 0 

2192 self.total_errors = 0 

2193 self.counters = dict.fromkeys(self._benchmark_keys, 0) 

2194 self.messages = {} 

2195 

2196 def start(self): 

2197 """Start the timer.""" 

2198 self._start_time = time.time() 

2199 

2200 def stop(self): 

2201 """Stop the timer.""" 

2202 self.elapsed = time.time() - self._start_time 

2203 

2204 def init_file(self, filename, lines, expected, line_offset): 

2205 """Signal a new file.""" 

2206 self.filename = filename 

2207 self.lines = lines 

2208 self.expected = expected or () 

2209 self.line_offset = line_offset 

2210 self.file_errors = 0 

2211 self.counters['files'] += 1 

2212 self.counters['physical lines'] += len(lines) 

2213 

2214 def increment_logical_line(self): 

2215 """Signal a new logical line.""" 

2216 self.counters['logical lines'] += 1 

2217 

2218 def error(self, line_number, offset, text, check): 

2219 """Report an error, according to options.""" 

2220 code = text[:4] 

2221 if self._ignore_code(code): 

2222 return 

2223 if code in self.counters: 

2224 self.counters[code] += 1 

2225 else: 

2226 self.counters[code] = 1 

2227 self.messages[code] = text[5:] 

2228 # Don't care about expected errors or warnings 

2229 if code in self.expected: 

2230 return 

2231 if self.print_filename and not self.file_errors: 

2232 print(self.filename) 

2233 self.file_errors += 1 

2234 self.total_errors += 1 

2235 return code 

2236 

2237 def get_file_results(self): 

2238 """Return the count of errors and warnings for this file.""" 

2239 return self.file_errors 

2240 

2241 def get_count(self, prefix=''): 

2242 """Return the total count of errors and warnings.""" 

2243 return sum(self.counters[key] 

2244 for key in self.messages if key.startswith(prefix)) 

2245 

2246 def get_statistics(self, prefix=''): 

2247 """Get statistics for message codes that start with the prefix. 

2248 

2249 prefix='' matches all errors and warnings 

2250 prefix='E' matches all errors 

2251 prefix='W' matches all warnings 

2252 prefix='E4' matches all errors that have to do with imports 

2253 """ 

2254 return ['%-7s %s %s' % (self.counters[key], key, self.messages[key]) 

2255 for key in sorted(self.messages) if key.startswith(prefix)] 

2256 

2257 def print_statistics(self, prefix=''): 

2258 """Print overall statistics (number of errors and warnings).""" 

2259 for line in self.get_statistics(prefix): 

2260 print(line) 

2261 

2262 def print_benchmark(self): 

2263 """Print benchmark numbers.""" 

2264 print('{:<7.2f} {}'.format(self.elapsed, 'seconds elapsed')) 

2265 if self.elapsed: 

2266 for key in self._benchmark_keys: 

2267 print('%-7d %s per second (%d total)' % 

2268 (self.counters[key] / self.elapsed, key, 

2269 self.counters[key])) 

2270 

2271 

2272class FileReport(BaseReport): 

2273 """Collect the results of the checks and print the filenames.""" 

2274 

2275 print_filename = True 

2276 

2277 

2278class StandardReport(BaseReport): 

2279 """Collect and print the results of the checks.""" 

2280 

2281 def __init__(self, options): 

2282 super().__init__(options) 

2283 self._fmt = REPORT_FORMAT.get(options.format.lower(), 

2284 options.format) 

2285 self._repeat = options.repeat 

2286 self._show_source = options.show_source 

2287 self._show_pep8 = options.show_pep8 

2288 

2289 def init_file(self, filename, lines, expected, line_offset): 

2290 """Signal a new file.""" 

2291 self._deferred_print = [] 

2292 return super().init_file( 

2293 filename, lines, expected, line_offset) 

2294 

2295 def error(self, line_number, offset, text, check): 

2296 """Report an error, according to options.""" 

2297 code = super().error(line_number, offset, text, check) 

2298 if code and (self.counters[code] == 1 or self._repeat): 

2299 self._deferred_print.append( 

2300 (line_number, offset, code, text[5:], check.__doc__)) 

2301 return code 

2302 

2303 def get_file_results(self): 

2304 """Print results and return the overall count for this file.""" 

2305 self._deferred_print.sort() 

2306 for line_number, offset, code, text, doc in self._deferred_print: 

2307 print(self._fmt % { 

2308 'path': self.filename, 

2309 'row': self.line_offset + line_number, 'col': offset + 1, 

2310 'code': code, 'text': text, 

2311 }) 

2312 if self._show_source: 

2313 if line_number > len(self.lines): 

2314 line = '' 

2315 else: 

2316 line = self.lines[line_number - 1] 

2317 print(line.rstrip()) 

2318 print(re.sub(r'\S', ' ', line[:offset]) + '^') 

2319 if self._show_pep8 and doc: 

2320 print(' ' + doc.strip()) 

2321 

2322 # stdout is block buffered when not stdout.isatty(). 

2323 # line can be broken where buffer boundary since other 

2324 # processes write to same file. 

2325 # flush() after print() to avoid buffer boundary. 

2326 # Typical buffer size is 8192. line written safely when 

2327 # len(line) < 8192. 

2328 sys.stdout.flush() 

2329 return self.file_errors 

2330 

2331 

2332class DiffReport(StandardReport): 

2333 """Collect and print the results for the changed lines only.""" 

2334 

2335 def __init__(self, options): 

2336 super().__init__(options) 

2337 self._selected = options.selected_lines 

2338 

2339 def error(self, line_number, offset, text, check): 

2340 if line_number not in self._selected[self.filename]: 

2341 return 

2342 return super().error(line_number, offset, text, check) 

2343 

2344 

2345class StyleGuide: 

2346 """Initialize a PEP-8 instance with few options.""" 

2347 

2348 def __init__(self, *args, **kwargs): 

2349 # build options from the command line 

2350 self.checker_class = kwargs.pop('checker_class', Checker) 

2351 parse_argv = kwargs.pop('parse_argv', False) 

2352 config_file = kwargs.pop('config_file', False) 

2353 parser = kwargs.pop('parser', None) 

2354 # build options from dict 

2355 options_dict = dict(*args, **kwargs) 

2356 arglist = None if parse_argv else options_dict.get('paths', None) 

2357 verbose = options_dict.get('verbose', None) 

2358 options, self.paths = process_options( 

2359 arglist, parse_argv, config_file, parser, verbose) 

2360 if options_dict: 

2361 options.__dict__.update(options_dict) 

2362 if 'paths' in options_dict: 

2363 self.paths = options_dict['paths'] 

2364 

2365 self.runner = self.input_file 

2366 self.options = options 

2367 

2368 if not options.reporter: 

2369 options.reporter = BaseReport if options.quiet else StandardReport 

2370 

2371 options.select = tuple(options.select or ()) 

2372 if not (options.select or options.ignore) and DEFAULT_IGNORE: 

2373 # The default choice: ignore controversial checks 

2374 options.ignore = tuple(DEFAULT_IGNORE.split(',')) 

2375 else: 

2376 # Ignore all checks which are not explicitly selected 

2377 options.ignore = ('',) if options.select else tuple(options.ignore) 

2378 options.benchmark_keys = BENCHMARK_KEYS[:] 

2379 options.ignore_code = self.ignore_code 

2380 options.physical_checks = self.get_checks('physical_line') 

2381 options.logical_checks = self.get_checks('logical_line') 

2382 options.ast_checks = self.get_checks('tree') 

2383 self.init_report() 

2384 

2385 def init_report(self, reporter=None): 

2386 """Initialize the report instance.""" 

2387 self.options.report = (reporter or self.options.reporter)(self.options) 

2388 return self.options.report 

2389 

2390 def check_files(self, paths=None): 

2391 """Run all checks on the paths.""" 

2392 if paths is None: 

2393 paths = self.paths 

2394 report = self.options.report 

2395 runner = self.runner 

2396 report.start() 

2397 try: 

2398 for path in paths: 

2399 if os.path.isdir(path): 

2400 self.input_dir(path) 

2401 elif not self.excluded(path): 

2402 runner(path) 

2403 except KeyboardInterrupt: 

2404 print('... stopped') 

2405 report.stop() 

2406 return report 

2407 

2408 def input_file(self, filename, lines=None, expected=None, line_offset=0): 

2409 """Run all checks on a Python source file.""" 

2410 if self.options.verbose: 

2411 print('checking %s' % filename) 

2412 fchecker = self.checker_class( 

2413 filename, lines=lines, options=self.options) 

2414 return fchecker.check_all(expected=expected, line_offset=line_offset) 

2415 

2416 def input_dir(self, dirname): 

2417 """Check all files in this directory and all subdirectories.""" 

2418 dirname = dirname.rstrip('/') 

2419 if self.excluded(dirname): 

2420 return 0 

2421 counters = self.options.report.counters 

2422 verbose = self.options.verbose 

2423 filepatterns = self.options.filename 

2424 runner = self.runner 

2425 for root, dirs, files in os.walk(dirname): 

2426 if verbose: 

2427 print('directory ' + root) 

2428 counters['directories'] += 1 

2429 for subdir in sorted(dirs): 

2430 if self.excluded(subdir, root): 

2431 dirs.remove(subdir) 

2432 for filename in sorted(files): 

2433 # contain a pattern that matches? 

2434 if ( 

2435 filename_match(filename, filepatterns) and 

2436 not self.excluded(filename, root) 

2437 ): 

2438 runner(os.path.join(root, filename)) 

2439 

2440 def excluded(self, filename, parent=None): 

2441 """Check if the file should be excluded. 

2442 

2443 Check if 'options.exclude' contains a pattern matching filename. 

2444 """ 

2445 if not self.options.exclude: 

2446 return False 

2447 basename = os.path.basename(filename) 

2448 if filename_match(basename, self.options.exclude): 

2449 return True 

2450 if parent: 

2451 filename = os.path.join(parent, filename) 

2452 filename = os.path.abspath(filename) 

2453 return filename_match(filename, self.options.exclude) 

2454 

2455 def ignore_code(self, code): 

2456 """Check if the error code should be ignored. 

2457 

2458 If 'options.select' contains a prefix of the error code, 

2459 return False. Else, if 'options.ignore' contains a prefix of 

2460 the error code, return True. 

2461 """ 

2462 if len(code) < 4 and any(s.startswith(code) 

2463 for s in self.options.select): 

2464 return False 

2465 return (code.startswith(self.options.ignore) and 

2466 not code.startswith(self.options.select)) 

2467 

2468 def get_checks(self, argument_name): 

2469 """Get all the checks for this category. 

2470 

2471 Find all globally visible functions where the first argument 

2472 name starts with argument_name and which contain selected tests. 

2473 """ 

2474 checks = [] 

2475 for check, attrs in _checks[argument_name].items(): 

2476 (codes, args) = attrs 

2477 if any(not (code and self.ignore_code(code)) for code in codes): 

2478 checks.append((check.__name__, check, args)) 

2479 return sorted(checks) 

2480 

2481 

2482def get_parser(prog='pycodestyle', version=__version__): 

2483 """Create the parser for the program.""" 

2484 parser = OptionParser(prog=prog, version=version, 

2485 usage="%prog [options] input ...") 

2486 parser.config_options = [ 

2487 'exclude', 'filename', 'select', 'ignore', 'max-line-length', 

2488 'max-doc-length', 'indent-size', 'hang-closing', 'count', 'format', 

2489 'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose'] 

2490 parser.add_option('-v', '--verbose', default=0, action='count', 

2491 help="print status messages, or debug with -vv") 

2492 parser.add_option('-q', '--quiet', default=0, action='count', 

2493 help="report only file names, or nothing with -qq") 

2494 parser.add_option('-r', '--repeat', default=True, action='store_true', 

2495 help="(obsolete) show all occurrences of the same error") 

2496 parser.add_option('--first', action='store_false', dest='repeat', 

2497 help="show first occurrence of each error") 

2498 parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, 

2499 help="exclude files or directories which match these " 

2500 "comma separated patterns (default: %default)") 

2501 parser.add_option('--filename', metavar='patterns', default='*.py', 

2502 help="when parsing directories, only check filenames " 

2503 "matching these comma separated patterns " 

2504 "(default: %default)") 

2505 parser.add_option('--select', metavar='errors', default='', 

2506 help="select errors and warnings (e.g. E,W6)") 

2507 parser.add_option('--ignore', metavar='errors', default='', 

2508 help="skip errors and warnings (e.g. E4,W) " 

2509 "(default: %s)" % DEFAULT_IGNORE) 

2510 parser.add_option('--show-source', action='store_true', 

2511 help="show source code for each error") 

2512 parser.add_option('--show-pep8', action='store_true', 

2513 help="show text of PEP 8 for each error " 

2514 "(implies --first)") 

2515 parser.add_option('--statistics', action='store_true', 

2516 help="count errors and warnings") 

2517 parser.add_option('--count', action='store_true', 

2518 help="print total number of errors and warnings " 

2519 "to standard error and set exit code to 1 if " 

2520 "total is not null") 

2521 parser.add_option('--max-line-length', type='int', metavar='n', 

2522 default=MAX_LINE_LENGTH, 

2523 help="set maximum allowed line length " 

2524 "(default: %default)") 

2525 parser.add_option('--max-doc-length', type='int', metavar='n', 

2526 default=None, 

2527 help="set maximum allowed doc line length and perform " 

2528 "these checks (unchecked if not set)") 

2529 parser.add_option('--indent-size', type='int', metavar='n', 

2530 default=INDENT_SIZE, 

2531 help="set how many spaces make up an indent " 

2532 "(default: %default)") 

2533 parser.add_option('--hang-closing', action='store_true', 

2534 help="hang closing bracket instead of matching " 

2535 "indentation of opening bracket's line") 

2536 parser.add_option('--format', metavar='format', default='default', 

2537 help="set the error format [default|pylint|<custom>]") 

2538 parser.add_option('--diff', action='store_true', 

2539 help="report changes only within line number ranges in " 

2540 "the unified diff received on STDIN") 

2541 group = parser.add_option_group("Testing Options") 

2542 group.add_option('--benchmark', action='store_true', 

2543 help="measure processing speed") 

2544 return parser 

2545 

2546 

2547def read_config(options, args, arglist, parser): 

2548 """Read and parse configurations. 

2549 

2550 If a config file is specified on the command line with the 

2551 "--config" option, then only it is used for configuration. 

2552 

2553 Otherwise, the user configuration (~/.config/pycodestyle) and any 

2554 local configurations in the current directory or above will be 

2555 merged together (in that order) using the read method of 

2556 ConfigParser. 

2557 """ 

2558 config = configparser.RawConfigParser() 

2559 

2560 cli_conf = options.config 

2561 

2562 local_dir = os.curdir 

2563 

2564 if USER_CONFIG and os.path.isfile(USER_CONFIG): 

2565 if options.verbose: 

2566 print('user configuration: %s' % USER_CONFIG) 

2567 config.read(USER_CONFIG) 

2568 

2569 parent = tail = args and os.path.abspath(os.path.commonpath(args)) 

2570 while tail: 

2571 if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): 

2572 local_dir = parent 

2573 if options.verbose: 

2574 print('local configuration: in %s' % parent) 

2575 break 

2576 (parent, tail) = os.path.split(parent) 

2577 

2578 if cli_conf and os.path.isfile(cli_conf): 

2579 if options.verbose: 

2580 print('cli configuration: %s' % cli_conf) 

2581 config.read(cli_conf) 

2582 

2583 pycodestyle_section = None 

2584 if config.has_section(parser.prog): 

2585 pycodestyle_section = parser.prog 

2586 elif config.has_section('pep8'): 

2587 pycodestyle_section = 'pep8' # Deprecated 

2588 warnings.warn('[pep8] section is deprecated. Use [pycodestyle].') 

2589 

2590 if pycodestyle_section: 

2591 option_list = {o.dest: o.type or o.action for o in parser.option_list} 

2592 

2593 # First, read the default values 

2594 (new_options, __) = parser.parse_args([]) 

2595 

2596 # Second, parse the configuration 

2597 for opt in config.options(pycodestyle_section): 

2598 if opt.replace('_', '-') not in parser.config_options: 

2599 print(" unknown option '%s' ignored" % opt) 

2600 continue 

2601 if options.verbose > 1: 

2602 print(" {} = {}".format(opt, 

2603 config.get(pycodestyle_section, opt))) 

2604 normalized_opt = opt.replace('-', '_') 

2605 opt_type = option_list[normalized_opt] 

2606 if opt_type in ('int', 'count'): 

2607 value = config.getint(pycodestyle_section, opt) 

2608 elif opt_type in ('store_true', 'store_false'): 

2609 value = config.getboolean(pycodestyle_section, opt) 

2610 else: 

2611 value = config.get(pycodestyle_section, opt) 

2612 if normalized_opt == 'exclude': 

2613 value = normalize_paths(value, local_dir) 

2614 setattr(new_options, normalized_opt, value) 

2615 

2616 # Third, overwrite with the command-line options 

2617 (options, __) = parser.parse_args(arglist, values=new_options) 

2618 return options 

2619 

2620 

2621def process_options(arglist=None, parse_argv=False, config_file=None, 

2622 parser=None, verbose=None): 

2623 """Process options passed either via arglist or command line args. 

2624 

2625 Passing in the ``config_file`` parameter allows other tools, such as 

2626 flake8 to specify their own options to be processed in pycodestyle. 

2627 """ 

2628 if not parser: 

2629 parser = get_parser() 

2630 if not parser.has_option('--config'): 

2631 group = parser.add_option_group("Configuration", description=( 

2632 "The project options are read from the [%s] section of the " 

2633 "tox.ini file or the setup.cfg file located in any parent folder " 

2634 "of the path(s) being processed. Allowed options are: %s." % 

2635 (parser.prog, ', '.join(parser.config_options)))) 

2636 group.add_option('--config', metavar='path', default=config_file, 

2637 help="user config file location") 

2638 # Don't read the command line if the module is used as a library. 

2639 if not arglist and not parse_argv: 

2640 arglist = [] 

2641 # If parse_argv is True and arglist is None, arguments are 

2642 # parsed from the command line (sys.argv) 

2643 (options, args) = parser.parse_args(arglist) 

2644 options.reporter = None 

2645 

2646 # If explicitly specified verbosity, override any `-v` CLI flag 

2647 if verbose is not None: 

2648 options.verbose = verbose 

2649 

2650 if parse_argv and not args: 

2651 if options.diff or any(os.path.exists(name) 

2652 for name in PROJECT_CONFIG): 

2653 args = ['.'] 

2654 else: 

2655 parser.error('input not specified') 

2656 options = read_config(options, args, arglist, parser) 

2657 options.reporter = parse_argv and options.quiet == 1 and FileReport 

2658 

2659 options.filename = _parse_multi_options(options.filename) 

2660 options.exclude = normalize_paths(options.exclude) 

2661 options.select = _parse_multi_options(options.select) 

2662 options.ignore = _parse_multi_options(options.ignore) 

2663 

2664 if options.diff: 

2665 options.reporter = DiffReport 

2666 stdin = stdin_get_value() 

2667 options.selected_lines = parse_udiff(stdin, options.filename, args[0]) 

2668 args = sorted(options.selected_lines) 

2669 

2670 return options, args 

2671 

2672 

2673def _parse_multi_options(options, split_token=','): 

2674 r"""Split and strip and discard empties. 

2675 

2676 Turns the following: 

2677 

2678 A, 

2679 B, 

2680 

2681 into ["A", "B"] 

2682 """ 

2683 if options: 

2684 return [o.strip() for o in options.split(split_token) if o.strip()] 

2685 else: 

2686 return options 

2687 

2688 

2689def _main(): 

2690 """Parse options and run checks on Python source.""" 

2691 import signal 

2692 

2693 # Handle "Broken pipe" gracefully 

2694 try: 

2695 signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1)) 

2696 except AttributeError: 

2697 pass # not supported on Windows 

2698 

2699 style_guide = StyleGuide(parse_argv=True) 

2700 options = style_guide.options 

2701 

2702 report = style_guide.check_files() 

2703 

2704 if options.statistics: 

2705 report.print_statistics() 

2706 

2707 if options.benchmark: 

2708 report.print_benchmark() 

2709 

2710 if report.total_errors: 

2711 if options.count: 

2712 sys.stderr.write(str(report.total_errors) + '\n') 

2713 sys.exit(1) 

2714 

2715 

2716if __name__ == '__main__': 

2717 _main()