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

1343 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:57 +0000

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 optparse import OptionParser 

63 

64# this is a performance hack. see https://bugs.python.org/issue43014 

65if ( 

66 sys.version_info < (3, 10) and 

67 callable(getattr(tokenize, '_compile', None)) 

68): # pragma: no cover (<py310) 

69 tokenize._compile = lru_cache(tokenize._compile) # type: ignore 

70 

71__version__ = '2.11.1' 

72 

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

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

75try: 

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

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

78 else: # pragma: win32 no cover 

79 USER_CONFIG = os.path.join( 

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

81 'pycodestyle' 

82 ) 

83except ImportError: 

84 USER_CONFIG = None 

85 

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

87MAX_LINE_LENGTH = 79 

88# Number of blank lines between various code parts. 

89BLANK_LINES_CONFIG = { 

90 # Top level class and function. 

91 'top_level': 2, 

92 # Methods and nested class and function. 

93 'method': 1, 

94} 

95MAX_DOC_LENGTH = 72 

96INDENT_SIZE = 4 

97REPORT_FORMAT = { 

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

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

100} 

101 

102PyCF_ONLY_AST = 1024 

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

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

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

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

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

108WS_NEEDED_OPERATORS = frozenset([ 

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

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

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

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

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

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

115# ERRORTOKEN is triggered by backticks in Python 3 

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

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

118 

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

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

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

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

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

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

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

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

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

128COMPARE_TYPE_REGEX = re.compile( 

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

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

131) 

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

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

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

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

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

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

138STARTSWITH_INDENT_STATEMENT_REGEX = re.compile( 

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

140 'def', 'async def', 

141 'for', 'async for', 

142 'if', 'elif', 'else', 

143 'try', 'except', 'finally', 

144 'with', 'async with', 

145 'class', 

146 'while', 

147 ))) 

148) 

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

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

151 

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

153 FSTRING_START = tokenize.FSTRING_START 

154 FSTRING_MIDDLE = tokenize.FSTRING_MIDDLE 

155 FSTRING_END = tokenize.FSTRING_END 

156else: # pragma: <3.12 cover 

157 FSTRING_START = FSTRING_MIDDLE = FSTRING_END = -1 

158 

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

160 

161 

162def _get_parameters(function): 

163 return [parameter.name 

164 for parameter 

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

166 if parameter.kind == parameter.POSITIONAL_OR_KEYWORD] 

167 

168 

169def register_check(check, codes=None): 

170 """Register a new check object.""" 

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

172 if check in _checks[kind]: 

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

174 else: 

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

176 if inspect.isfunction(check): 

177 args = _get_parameters(check) 

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

179 if codes is None: 

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

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

182 elif inspect.isclass(check): 

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

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

185 return check 

186 

187 

188######################################################################## 

189# Plugins (check functions) for physical lines 

190######################################################################## 

191 

192@register_check 

193def tabs_or_spaces(physical_line, indent_char): 

194 r"""Never mix tabs and spaces. 

195 

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

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

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

199 exclusively. When invoking the Python command line interpreter with 

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

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

202 These options are highly recommended! 

203 

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

205 """ 

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

207 for offset, char in enumerate(indent): 

208 if char != indent_char: 

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

210 

211 

212@register_check 

213def tabs_obsolete(physical_line): 

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

215 

216 Okay: if True:\n return 

217 W191: if True:\n\treturn 

218 """ 

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

220 if '\t' in indent: 

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

222 

223 

224@register_check 

225def trailing_whitespace(physical_line): 

226 r"""Trailing whitespace is superfluous. 

227 

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

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

230 

231 Okay: spam(1)\n# 

232 W291: spam(1) \n# 

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

234 """ 

235 physical_line = physical_line.rstrip('\n') # chr(10), newline 

236 physical_line = physical_line.rstrip('\r') # chr(13), carriage return 

237 physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L 

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

239 if physical_line != stripped: 

240 if stripped: 

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

242 else: 

243 return 0, "W293 blank line contains whitespace" 

244 

245 

246@register_check 

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

248 r"""Trailing blank lines are superfluous. 

249 

250 Okay: spam(1) 

251 W391: spam(1)\n 

252 

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

254 """ 

255 if line_number == total_lines: 

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

257 if physical_line and not stripped_last_line: 

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

259 if stripped_last_line == physical_line: 

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

261 

262 

263@register_check 

264def maximum_line_length(physical_line, max_line_length, multiline, 

265 line_number, noqa): 

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

267 

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

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

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

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

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

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

274 

275 Reports error E501. 

276 """ 

277 line = physical_line.rstrip() 

278 length = len(line) 

279 if length > max_line_length and not noqa: 

280 # Special case: ignore long shebang lines. 

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

282 return 

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

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

285 # are whitespaces. 

286 chunks = line.split() 

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

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

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

290 return 

291 if length > max_line_length: 

292 return (max_line_length, "E501 line too long " 

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

294 

295 

296######################################################################## 

297# Plugins (check functions) for logical lines 

298######################################################################## 

299 

300 

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

302 if not STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): 

303 return False 

304 

305 line_idx = line_number - 1 

306 

307 if line_idx < 1: 

308 prev_indent = 0 

309 else: 

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

311 

312 if prev_indent > indent_level: 

313 return False 

314 

315 while line_idx < len(lines): 

316 line = lines[line_idx].strip() 

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

318 break 

319 else: 

320 line_idx += 1 

321 else: 

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

323 

324 next_idx = line_idx + 1 

325 while next_idx < len(lines): 

326 if lines[next_idx].strip(): 

327 break 

328 else: 

329 next_idx += 1 

330 else: 

331 return True # line is last in the file 

332 

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

334 

335 

336@register_check 

337def blank_lines(logical_line, blank_lines, indent_level, line_number, 

338 blank_before, previous_logical, 

339 previous_unindented_logical_line, previous_indent_level, 

340 lines): 

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

342 lines. 

343 

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

345 line. 

346 

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

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

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

350 

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

352 sections. 

353 

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

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

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

357 Okay: default = 1\nfoo = 1 

358 Okay: classify = 1\nfoo = 1 

359 

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

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

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

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

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

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

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

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

368 """ # noqa 

369 top_level_lines = BLANK_LINES_CONFIG['top_level'] 

370 method_lines = BLANK_LINES_CONFIG['method'] 

371 

372 if not previous_logical and blank_before < top_level_lines: 

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

374 if previous_logical.startswith('@'): 

375 if blank_lines: 

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

377 elif (blank_lines > top_level_lines or 

378 (indent_level and blank_lines == method_lines + 1) 

379 ): 

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

381 elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): 

382 # allow a group of one-liners 

383 if ( 

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

385 blank_before == 0 

386 ): 

387 return 

388 if indent_level: 

389 if not (blank_before == method_lines or 

390 previous_indent_level < indent_level or 

391 DOCSTRING_REGEX.match(previous_logical) 

392 ): 

393 ancestor_level = indent_level 

394 nested = False 

395 # Search backwards for a def ancestor or tree root 

396 # (top level). 

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

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

399 ancestor_level = expand_indent(line) 

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

401 if nested or ancestor_level == 0: 

402 break 

403 if nested: 

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

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

406 else: 

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

408 method_lines) 

409 elif blank_before != top_level_lines: 

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

411 top_level_lines, blank_before) 

412 elif (logical_line and 

413 not indent_level and 

414 blank_before != top_level_lines and 

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

416 ): 

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

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

419 top_level_lines, blank_before) 

420 

421 

422@register_check 

423def extraneous_whitespace(logical_line): 

424 r"""Avoid extraneous whitespace. 

425 

426 Avoid extraneous whitespace in these situations: 

427 - Immediately inside parentheses, brackets or braces. 

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

429 

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

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

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

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

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

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

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

437 

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

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

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

441 """ 

442 line = logical_line 

443 for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): 

444 text = match.group() 

445 char = text.strip() 

446 found = match.start() 

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

448 # assert char in '([{' 

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

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

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

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

453 

454 

455@register_check 

456def whitespace_around_keywords(logical_line): 

457 r"""Avoid extraneous whitespace around keywords. 

458 

459 Okay: True and False 

460 E271: True and False 

461 E272: True and False 

462 E273: True and\tFalse 

463 E274: True\tand False 

464 """ 

465 for match in KEYWORD_REGEX.finditer(logical_line): 

466 before, after = match.groups() 

467 

468 if '\t' in before: 

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

470 elif len(before) > 1: 

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

472 

473 if '\t' in after: 

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

475 elif len(after) > 1: 

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

477 

478 

479@register_check 

480def missing_whitespace_after_keyword(logical_line, tokens): 

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

482 

483 Okay: from foo import (bar, baz) 

484 E275: from foo import(bar, baz) 

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

486 E275: if(foo): bar 

487 """ 

488 for tok0, tok1 in zip(tokens, tokens[1:]): 

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

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

491 # valid identifier names in old Python versions. 

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

493 tok0.type == tokenize.NAME and 

494 keyword.iskeyword(tok0.string) and 

495 tok0.string not in SINGLETONS and 

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

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

498 tok1.string not in ':\n'): 

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

500 

501 

502@register_check 

503def indentation(logical_line, previous_logical, indent_char, 

504 indent_level, previous_indent_level, 

505 indent_size): 

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

507 

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

509 to use 8-space tabs. 

510 

511 Okay: a = 1 

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

513 E111: a = 1 

514 E114: # a = 1 

515 

516 Okay: for item in items:\n pass 

517 E112: for item in items:\npass 

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

519 

520 Okay: a = 1\nb = 2 

521 E113: a = 1\n b = 2 

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

523 """ 

524 c = 0 if logical_line else 3 

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

526 if indent_level % indent_size: 

527 yield 0, tmpl % ( 

528 1 + c, 

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

530 ) 

531 indent_expect = previous_logical.endswith(':') 

532 if indent_expect and indent_level <= previous_indent_level: 

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

534 elif not indent_expect and indent_level > previous_indent_level: 

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

536 

537 if indent_expect: 

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

539 expected_indent_level = previous_indent_level + expected_indent_amount 

540 if indent_level > expected_indent_level: 

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

542 

543 

544@register_check 

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

546 indent_char, indent_size, noqa, verbose): 

547 r"""Continuation lines indentation. 

548 

549 Continuation lines should align wrapped elements either vertically 

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

551 and braces, or using a hanging indent. 

552 

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

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

555 - further indentation should be used to clearly distinguish itself 

556 as a continuation line. 

557 

558 Okay: a = (\n) 

559 E123: a = (\n ) 

560 

561 Okay: a = (\n 42) 

562 E121: a = (\n 42) 

563 E122: a = (\n42) 

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

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

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

567 E126: a = (\n 42) 

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

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

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

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

572 """ 

573 first_row = tokens[0][2][0] 

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

575 if noqa or nrows == 1: 

576 return 

577 

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

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

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

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

582 indent_next = logical_line.endswith(':') 

583 

584 row = depth = 0 

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

586 else (indent_size, indent_size * 2) 

587 # remember how many brackets were opened on each line 

588 parens = [0] * nrows 

589 # relative indents of physical lines 

590 rel_indent = [0] * nrows 

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

592 open_rows = [[0]] 

593 # for each depth, memorize the hanging indentation 

594 hangs = [None] 

595 # visual indents 

596 indent_chances = {} 

597 last_indent = tokens[0][2] 

598 visual_indent = None 

599 last_token_multiline = False 

600 # for each depth, memorize the visual indent column 

601 indent = [last_indent[1]] 

602 if verbose >= 3: 

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

604 

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

606 

607 newline = row < start[0] - first_row 

608 if newline: 

609 row = start[0] - first_row 

610 newline = not last_token_multiline and token_type not in NEWLINE 

611 

612 if newline: 

613 # this is the beginning of a continuation line. 

614 last_indent = start 

615 if verbose >= 3: 

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

617 

618 # record the initial indent. 

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

620 

621 # identify closing bracket 

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

623 

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

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

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

627 hanging_indent = hang in valid_hangs 

628 if hanging_indent: 

629 break 

630 if hangs[depth]: 

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

632 # is there any chance of visual indent? 

633 visual_indent = (not close_bracket and hang > 0 and 

634 indent_chances.get(start[1])) 

635 

636 if close_bracket and indent[depth]: 

637 # closing bracket for visual indent 

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

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

640 "visual indentation") 

641 elif close_bracket and not hang: 

642 # closing bracket matches indentation of opening 

643 # bracket's line 

644 if hang_closing: 

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

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

647 if visual_indent is not True: 

648 # visual indent is broken 

649 yield (start, "E128 continuation line " 

650 "under-indented for visual indent") 

651 elif hanging_indent or (indent_next and 

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

653 # hanging indent is verified 

654 if close_bracket and not hang_closing: 

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

656 "indentation of opening bracket's line") 

657 hangs[depth] = hang 

658 elif visual_indent is True: 

659 # visual indent is verified 

660 indent[depth] = start[1] 

661 elif visual_indent in (text, str): 

662 # ignore token lined up with matching one from a 

663 # previous line 

664 pass 

665 else: 

666 # indent is broken 

667 if hang <= 0: 

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

669 elif indent[depth]: 

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

671 elif not close_bracket and hangs[depth]: 

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

673 else: 

674 hangs[depth] = hang 

675 if hang > indent_size: 

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

677 else: 

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

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

680 

681 # look for visual indenting 

682 if (parens[row] and 

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

684 not indent[depth]): 

685 indent[depth] = start[1] 

686 indent_chances[start[1]] = True 

687 if verbose >= 4: 

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

689 # deal with implicit string concatenation 

690 elif token_type in (tokenize.STRING, tokenize.COMMENT, FSTRING_START): 

691 indent_chances[start[1]] = str 

692 # visual indent after assert/raise/with 

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

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

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

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

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

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

699 open_rows[depth].append(row) 

700 

701 # keep track of bracket depth 

702 if token_type == tokenize.OP: 

703 if text in '([{': 

704 depth += 1 

705 indent.append(0) 

706 hangs.append(None) 

707 if len(open_rows) == depth: 

708 open_rows.append([]) 

709 open_rows[depth].append(row) 

710 parens[row] += 1 

711 if verbose >= 4: 

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

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

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

715 # parent indents should not be more than this one 

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

717 hangs.pop() 

718 for d in range(depth): 

719 if indent[d] > prev_indent: 

720 indent[d] = 0 

721 for ind in list(indent_chances): 

722 if ind >= prev_indent: 

723 del indent_chances[ind] 

724 del open_rows[depth + 1:] 

725 depth -= 1 

726 if depth: 

727 indent_chances[indent[depth]] = True 

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

729 if parens[idx]: 

730 parens[idx] -= 1 

731 break 

732 assert len(indent) == depth + 1 

733 if start[1] not in indent_chances: 

734 # allow lining up tokens 

735 indent_chances[start[1]] = text 

736 

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

738 if last_token_multiline: 

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

740 

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

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

743 if visual_indent: 

744 code = "E129 visually indented line" 

745 else: 

746 code = "E125 continuation line" 

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

748 

749 

750@register_check 

751def whitespace_before_parameters(logical_line, tokens): 

752 r"""Avoid extraneous whitespace. 

753 

754 Avoid extraneous whitespace in the following situations: 

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

756 function call. 

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

758 

759 Okay: spam(1) 

760 E211: spam (1) 

761 

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

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

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

765 """ 

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

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

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

769 if ( 

770 token_type == tokenize.OP and 

771 text in '([' and 

772 start != prev_end and 

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

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

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

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

777 not keyword.iskeyword(prev_text) and 

778 ( 

779 sys.version_info < (3, 9) or 

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

781 prev_text == 'type' or 

782 not keyword.issoftkeyword(prev_text) 

783 ) 

784 ): 

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

786 prev_type = token_type 

787 prev_text = text 

788 prev_end = end 

789 

790 

791@register_check 

792def whitespace_around_operator(logical_line): 

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

794 

795 Okay: a = 12 + 3 

796 E221: a = 4 + 5 

797 E222: a = 4 + 5 

798 E223: a = 4\t+ 5 

799 E224: a = 4 +\t5 

800 """ 

801 for match in OPERATOR_REGEX.finditer(logical_line): 

802 before, after = match.groups() 

803 

804 if '\t' in before: 

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

806 elif len(before) > 1: 

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

808 

809 if '\t' in after: 

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

811 elif len(after) > 1: 

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

813 

814 

815@register_check 

816def missing_whitespace(logical_line, tokens): 

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

818 

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

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

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

822 Booleans (and, or, not). 

823 

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

825 

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

827 whitespace around the operators with the lowest priorities. 

828 

829 Okay: i = i + 1 

830 Okay: submitted += 1 

831 Okay: x = x * 2 - 1 

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

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

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

835 Okay: alpha[:-i] 

836 Okay: [a, b] 

837 Okay: (3,) 

838 Okay: a[3,] = 1 

839 Okay: a[1:4] 

840 Okay: a[:4] 

841 Okay: a[1:] 

842 Okay: a[1:4:2] 

843 

844 E225: i=i+1 

845 E225: submitted +=1 

846 E225: x = x /2 - 1 

847 E225: z = x **y 

848 E225: z = 1and 1 

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

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

851 E227: c = a|b 

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

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

854 E231: foo(bar,baz) 

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

856 """ 

857 need_space = False 

858 prev_type = tokenize.OP 

859 prev_text = prev_end = None 

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

861 brace_stack = [] 

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

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

864 brace_stack.append(text) 

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

866 brace_stack.append('f') 

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

868 brace_stack.append('l') 

869 elif brace_stack: 

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

871 brace_stack.pop() 

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

873 brace_stack.pop() 

874 elif ( 

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

876 token_type == tokenize.OP and 

877 text == ':' 

878 ): 

879 brace_stack.pop() 

880 

881 if token_type in SKIP_COMMENTS: 

882 continue 

883 

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

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

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

887 # slice 

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

889 pass 

890 # 3.12+ fstring format specifier 

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

892 pass 

893 # tuple (and list for some reason?) 

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

895 pass 

896 else: 

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

898 

899 if need_space: 

900 if start != prev_end: 

901 # Found a (probably) needed space 

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

903 yield (need_space[0], 

904 "E225 missing whitespace around operator") 

905 need_space = False 

906 elif ( 

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

908 # ^ 

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

910 # ^ 

911 # f = lambda a, /: 

912 # ^ 

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

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

915 # ^ 

916 prev_text == ')' and text == ':' 

917 ): 

918 # Tolerate the "/" operator in function definition 

919 # For more info see PEP570 

920 pass 

921 else: 

922 if need_space is True or need_space[1]: 

923 # A needed trailing space was not found 

924 yield prev_end, "E225 missing whitespace around operator" 

925 elif prev_text != '**': 

926 code, optype = 'E226', 'arithmetic' 

927 if prev_text == '%': 

928 code, optype = 'E228', 'modulo' 

929 elif prev_text not in ARITHMETIC_OP: 

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

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

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

933 need_space = False 

934 elif token_type in operator_types and prev_end is not None: 

935 if ( 

936 text == '=' and ( 

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

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

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

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

941 # allow python 3.8 fstring repr specifier 

942 brace_stack[-2:] == ['f', '{'] 

943 ) 

944 ): 

945 pass 

946 elif text in WS_NEEDED_OPERATORS: 

947 need_space = True 

948 elif text in UNARY_OPERATORS: 

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

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

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

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

953 prev_type != tokenize.OP and 

954 prev_text not in KEYWORDS and ( 

955 sys.version_info < (3, 9) or 

956 not keyword.issoftkeyword(prev_text) 

957 ) 

958 ): 

959 need_space = None 

960 elif text in WS_OPTIONAL_OPERATORS: 

961 need_space = None 

962 

963 if need_space is None: 

964 # Surrounding space is optional, but ensure that 

965 # trailing space matches opening space 

966 need_space = (prev_end, start != prev_end) 

967 elif need_space and start == prev_end: 

968 # A needed opening space was not found 

969 yield prev_end, "E225 missing whitespace around operator" 

970 need_space = False 

971 prev_type = token_type 

972 prev_text = text 

973 prev_end = end 

974 

975 

976@register_check 

977def whitespace_around_comma(logical_line): 

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

979 

980 Note: these checks are disabled by default 

981 

982 Okay: a = (1, 2) 

983 E241: a = (1, 2) 

984 E242: a = (1,\t2) 

985 """ 

986 line = logical_line 

987 for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): 

988 found = m.start() + 1 

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

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

991 else: 

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

993 

994 

995@register_check 

996def whitespace_around_named_parameter_equals(logical_line, tokens): 

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

998 

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

1000 keyword argument or a default parameter value, except when 

1001 using a type annotation. 

1002 

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

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

1005 Okay: boolean(a == b) 

1006 Okay: boolean(a != b) 

1007 Okay: boolean(a <= b) 

1008 Okay: boolean(a >= b) 

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

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

1011 

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

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

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

1015 """ 

1016 parens = 0 

1017 no_space = False 

1018 require_space = False 

1019 prev_end = None 

1020 annotated_func_arg = False 

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

1022 

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

1024 missing_message = "E252 missing whitespace around parameter equals" 

1025 

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

1027 if token_type == tokenize.NL: 

1028 continue 

1029 if no_space: 

1030 no_space = False 

1031 if start != prev_end: 

1032 yield (prev_end, message) 

1033 if require_space: 

1034 require_space = False 

1035 if start == prev_end: 

1036 yield (prev_end, missing_message) 

1037 if token_type == tokenize.OP: 

1038 if text in '([': 

1039 parens += 1 

1040 elif text in ')]': 

1041 parens -= 1 

1042 elif in_def and text == ':' and parens == 1: 

1043 annotated_func_arg = True 

1044 elif parens == 1 and text == ',': 

1045 annotated_func_arg = False 

1046 elif parens and text == '=': 

1047 if annotated_func_arg and parens == 1: 

1048 require_space = True 

1049 if start == prev_end: 

1050 yield (prev_end, missing_message) 

1051 else: 

1052 no_space = True 

1053 if start != prev_end: 

1054 yield (prev_end, message) 

1055 if not parens: 

1056 annotated_func_arg = False 

1057 

1058 prev_end = end 

1059 

1060 

1061@register_check 

1062def whitespace_before_comment(logical_line, tokens): 

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

1064 

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

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

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

1068 

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

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

1071 

1072 Okay: x = x + 1 # Increment x 

1073 Okay: x = x + 1 # Increment x 

1074 Okay: # Block comments: 

1075 Okay: # - Block comment list 

1076 Okay: # \xa0- Block comment list 

1077 E261: x = x + 1 # Increment x 

1078 E262: x = x + 1 #Increment x 

1079 E262: x = x + 1 # Increment x 

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

1081 E265: #Block comment 

1082 E266: ### Block comment 

1083 """ 

1084 prev_end = (0, 0) 

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

1086 if token_type == tokenize.COMMENT: 

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

1088 if inline_comment: 

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

1090 yield (prev_end, 

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

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

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

1094 if inline_comment: 

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

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

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

1098 if bad_prefix != '#': 

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

1100 elif comment: 

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

1102 elif token_type != tokenize.NL: 

1103 prev_end = end 

1104 

1105 

1106@register_check 

1107def imports_on_separate_lines(logical_line): 

1108 r"""Place imports on separate lines. 

1109 

1110 Okay: import os\nimport sys 

1111 E401: import sys, os 

1112 

1113 Okay: from subprocess import Popen, PIPE 

1114 Okay: from myclas import MyClass 

1115 Okay: from foo.bar.yourclass import YourClass 

1116 Okay: import myclass 

1117 Okay: import foo.bar.yourclass 

1118 """ 

1119 line = logical_line 

1120 if line.startswith('import '): 

1121 found = line.find(',') 

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

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

1124 

1125 

1126@register_check 

1127def module_imports_on_top_of_file( 

1128 logical_line, indent_level, checker_state, noqa): 

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

1130 

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

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

1133 

1134 Okay: import os 

1135 Okay: # this is a comment\nimport os 

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

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

1138 E402: a=1\nimport os 

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

1140 E402: a=1\nfrom sys import x 

1141 

1142 Okay: if x:\n import os 

1143 """ # noqa 

1144 def is_string_literal(line): 

1145 if line[0] in 'uUbB': 

1146 line = line[1:] 

1147 if line and line[0] in 'rR': 

1148 line = line[1:] 

1149 return line and (line[0] == '"' or line[0] == "'") 

1150 

1151 allowed_keywords = ( 

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

1153 

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

1155 return 

1156 if not logical_line: # Allow empty lines or comments 

1157 return 

1158 if noqa: 

1159 return 

1160 line = logical_line 

1161 if line.startswith('import ') or line.startswith('from '): 

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

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

1164 elif re.match(DUNDER_REGEX, line): 

1165 return 

1166 elif any(line.startswith(kw) for kw in allowed_keywords): 

1167 # Allow certain keywords intermixed with imports in order to 

1168 # support conditional or filtered importing 

1169 return 

1170 elif is_string_literal(line): 

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

1172 # error. 

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

1174 checker_state['seen_non_imports'] = True 

1175 else: 

1176 checker_state['seen_docstring'] = True 

1177 else: 

1178 checker_state['seen_non_imports'] = True 

1179 

1180 

1181@register_check 

1182def compound_statements(logical_line): 

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

1184 discouraged. 

1185 

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

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

1188 Also avoid folding such long lines! 

1189 

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

1191 binds a lambda expression directly to a name. 

1192 

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

1194 Okay: do_one() 

1195 Okay: do_two() 

1196 Okay: do_three() 

1197 

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

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

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

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

1202 E701: else: do_non_blah_thing() 

1203 E701: try: something() 

1204 E701: finally: cleanup() 

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

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

1207 E703: do_four(); # useless semicolon 

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

1209 E731: f = lambda x: 2*x 

1210 """ 

1211 line = logical_line 

1212 last_char = len(line) - 1 

1213 found = line.find(':') 

1214 prev_found = 0 

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

1216 while -1 < found < last_char: 

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

1218 if ( 

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

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

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

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

1223 ): 

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

1225 if lambda_kw: 

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

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

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

1229 "def") 

1230 break 

1231 if STARTSWITH_DEF_REGEX.match(line): 

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

1233 elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line): 

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

1235 prev_found = found 

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

1237 found = line.find(';') 

1238 while -1 < found: 

1239 if found < last_char: 

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

1241 else: 

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

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

1244 

1245 

1246@register_check 

1247def explicit_line_join(logical_line, tokens): 

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

1249 

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

1251 implied line continuation inside parentheses, brackets and braces. 

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

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

1254 backslash for line continuation. 

1255 

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

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

1258 

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

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

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

1262 Okay: aaa = 123 # \\ 

1263 """ 

1264 prev_start = prev_end = parens = 0 

1265 comment = False 

1266 backslash = None 

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

1268 if token_type == tokenize.COMMENT: 

1269 comment = True 

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

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

1272 if end[0] != prev_end: 

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

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

1275 else: 

1276 backslash = None 

1277 prev_start = prev_end = end[0] 

1278 else: 

1279 prev_start = start[0] 

1280 if token_type == tokenize.OP: 

1281 if text in '([{': 

1282 parens += 1 

1283 elif text in ')]}': 

1284 parens -= 1 

1285 

1286 

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

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

1289# after a line break. 

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

1291 

1292 

1293def _is_binary_operator(token_type, text): 

1294 return ( 

1295 token_type == tokenize.OP or 

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

1297 ) and ( 

1298 text not in _SYMBOLIC_OPS 

1299 ) 

1300 

1301 

1302def _break_around_binary_operators(tokens): 

1303 """Private function to reduce duplication. 

1304 

1305 This factors out the shared details between 

1306 :func:`break_before_binary_operator` and 

1307 :func:`break_after_binary_operator`. 

1308 """ 

1309 line_break = False 

1310 unary_context = True 

1311 # Previous non-newline token types and text 

1312 previous_token_type = None 

1313 previous_text = None 

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

1315 if token_type == tokenize.COMMENT: 

1316 continue 

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

1318 line_break = True 

1319 else: 

1320 yield (token_type, text, previous_token_type, previous_text, 

1321 line_break, unary_context, start) 

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

1323 line_break = False 

1324 previous_token_type = token_type 

1325 previous_text = text 

1326 

1327 

1328@register_check 

1329def break_before_binary_operator(logical_line, tokens): 

1330 r""" 

1331 Avoid breaks before binary operators. 

1332 

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

1334 operator, not before it. 

1335 

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

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

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

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

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

1341 

1342 Okay: foo(\n -x) 

1343 Okay: foo(x\n []) 

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

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

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

1347 """ 

1348 for context in _break_around_binary_operators(tokens): 

1349 (token_type, text, previous_token_type, previous_text, 

1350 line_break, unary_context, start) = context 

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

1352 not unary_context and 

1353 not _is_binary_operator(previous_token_type, 

1354 previous_text)): 

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

1356 

1357 

1358@register_check 

1359def break_after_binary_operator(logical_line, tokens): 

1360 r""" 

1361 Avoid breaks after binary operators. 

1362 

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

1364 operator, not after it. 

1365 

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

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

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

1369 

1370 Okay: foo(\n -x) 

1371 Okay: foo(x\n []) 

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

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

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

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

1376 

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

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

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

1380 """ 

1381 prev_start = None 

1382 for context in _break_around_binary_operators(tokens): 

1383 (token_type, text, previous_token_type, previous_text, 

1384 line_break, unary_context, start) = context 

1385 if (_is_binary_operator(previous_token_type, previous_text) and 

1386 line_break and 

1387 not unary_context and 

1388 not _is_binary_operator(token_type, text)): 

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

1390 prev_start = start 

1391 

1392 

1393@register_check 

1394def comparison_to_singleton(logical_line, noqa): 

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

1396 

1397 Comparisons to singletons like None should always be done 

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

1399 

1400 Okay: if arg is not None: 

1401 E711: if arg != None: 

1402 E711: if None == arg: 

1403 E712: if arg == True: 

1404 E712: if False == arg: 

1405 

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

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

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

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

1410 """ 

1411 if noqa: 

1412 return 

1413 

1414 for match in COMPARE_SINGLETON_REGEX.finditer(logical_line): 

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

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

1417 

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

1419 if singleton in ('None',): 

1420 code = 'E711' 

1421 else: 

1422 code = 'E712' 

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

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

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

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

1427 (code, singleton, msg)) 

1428 

1429 

1430@register_check 

1431def comparison_negative(logical_line): 

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

1433 

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

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

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

1437 Okay: zz = x is not y 

1438 E713: Z = not X in Y 

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

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

1441 E714: Z = not X.B is Y 

1442 """ 

1443 match = COMPARE_NEGATIVE_REGEX.search(logical_line) 

1444 if match: 

1445 pos = match.start(1) 

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

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

1448 else: 

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

1450 

1451 

1452@register_check 

1453def comparison_type(logical_line, noqa): 

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

1455 

1456 Do not compare types directly. 

1457 

1458 Okay: if isinstance(obj, int): 

1459 Okay: if type(obj) is int: 

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

1461 """ 

1462 match = COMPARE_TYPE_REGEX.search(logical_line) 

1463 if match and not noqa: 

1464 inst = match.group(1) 

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

1466 return # Allow comparison for types which are not obvious 

1467 yield ( 

1468 match.start(), 

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

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

1471 ) 

1472 

1473 

1474@register_check 

1475def bare_except(logical_line, noqa): 

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

1477 possible. 

1478 

1479 Okay: except Exception: 

1480 Okay: except BaseException: 

1481 E722: except: 

1482 """ 

1483 if noqa: 

1484 return 

1485 

1486 match = BLANK_EXCEPT_REGEX.match(logical_line) 

1487 if match: 

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

1489 

1490 

1491@register_check 

1492def ambiguous_identifier(logical_line, tokens): 

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

1494 

1495 In some fonts, these characters are indistinguishable from the 

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

1497 

1498 Okay: L = 0 

1499 Okay: o = 123 

1500 Okay: i = 42 

1501 E741: l = 0 

1502 E741: O = 123 

1503 E741: I = 42 

1504 

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

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

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

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

1509 

1510 Okay: except AttributeError as o: 

1511 Okay: with lock as L: 

1512 Okay: foo(l=12) 

1513 Okay: foo(l=I) 

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

1515 Okay: lambda arg: arg * l 

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

1517 Okay: lambda x=a.I: None 

1518 Okay: if l >= 12: 

1519 E741: except AttributeError as O: 

1520 E741: with lock as l: 

1521 E741: global I 

1522 E741: nonlocal l 

1523 E741: def foo(l): 

1524 E741: def foo(l=12): 

1525 E741: l = foo(l=12) 

1526 E741: for l in range(10): 

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

1528 E741: lambda l: None 

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

1530 E741: lambda **l: 

1531 E741: def f(**l): 

1532 E742: class I(object): 

1533 E743: def l(x): 

1534 """ 

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

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

1537 brace_depth = 0 

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

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

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

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

1542 ident = pos = None 

1543 # find function definitions 

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

1545 func_depth = brace_depth 

1546 seen_colon = False 

1547 elif ( 

1548 func_depth is not None and 

1549 text == ':' and 

1550 brace_depth == func_depth 

1551 ): 

1552 seen_colon = True 

1553 # update parameter parentheses level 

1554 if text in '([{': 

1555 brace_depth += 1 

1556 elif text in ')]}': 

1557 brace_depth -= 1 

1558 # identifiers on the lhs of an assignment operator 

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

1560 if prev_text in idents_to_avoid: 

1561 ident = prev_text 

1562 pos = prev_start 

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

1564 # 'global', or 'nonlocal' 

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

1566 if text in idents_to_avoid: 

1567 ident = text 

1568 pos = start 

1569 # function / lambda parameter definitions 

1570 if ( 

1571 func_depth is not None and 

1572 not seen_colon and 

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

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

1575 text in idents_to_avoid 

1576 ): 

1577 ident = text 

1578 pos = start 

1579 if prev_text == 'class': 

1580 if text in idents_to_avoid: 

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

1582 if prev_text == 'def': 

1583 if text in idents_to_avoid: 

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

1585 if ident: 

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

1587 prev_text = text 

1588 prev_start = start 

1589 

1590 

1591@register_check 

1592def python_3000_invalid_escape_sequence(logical_line, tokens, noqa): 

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

1594 

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

1596 W605: regex = '\.png$' 

1597 """ 

1598 if noqa: 

1599 return 

1600 

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

1602 valid = [ 

1603 '\n', 

1604 '\\', 

1605 '\'', 

1606 '"', 

1607 'a', 

1608 'b', 

1609 'f', 

1610 'n', 

1611 'r', 

1612 't', 

1613 'v', 

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

1615 'x', 

1616 

1617 # Escape sequences only recognized in string literals 

1618 'N', 

1619 'u', 

1620 'U', 

1621 ] 

1622 

1623 prefixes = [] 

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

1625 if token_type in {tokenize.STRING, FSTRING_START}: 

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

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

1628 

1629 if token_type in {tokenize.STRING, FSTRING_MIDDLE}: 

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

1631 start_line, start_col = start 

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

1633 while pos >= 0: 

1634 pos += 1 

1635 if text[pos] not in valid: 

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

1637 if line == start_line: 

1638 col = start_col + pos 

1639 else: 

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

1641 yield ( 

1642 (line, col - 1), 

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

1644 ) 

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

1646 

1647 if token_type in {tokenize.STRING, FSTRING_END}: 

1648 prefixes.pop() 

1649 

1650 

1651######################################################################## 

1652@register_check 

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

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

1655 

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

1657 the length to 72 characters is recommended. 

1658 

1659 Reports warning W505 

1660 """ 

1661 if max_doc_length is None or noqa: 

1662 return 

1663 

1664 prev_token = None 

1665 skip_lines = set() 

1666 # Skip lines that 

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

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

1669 skip_lines.add(line) 

1670 

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

1672 # Skip lines that aren't pure strings 

1673 if token_type == tokenize.STRING and skip_lines: 

1674 continue 

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

1676 # Only check comment-only lines 

1677 if prev_token is None or prev_token in SKIP_TOKENS: 

1678 lines = line.splitlines() 

1679 for line_num, physical_line in enumerate(lines): 

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

1681 return 

1682 length = len(physical_line) 

1683 chunks = physical_line.split() 

1684 if token_type == tokenize.COMMENT: 

1685 if (len(chunks) == 2 and 

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

1687 continue 

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

1689 if (len(chunks) == 1 and 

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

1691 continue 

1692 if length > max_doc_length: 

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

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

1695 "(%d > %d characters)" 

1696 % (length, max_doc_length)) 

1697 prev_token = token_type 

1698 

1699 

1700######################################################################## 

1701# Helper functions 

1702######################################################################## 

1703 

1704 

1705def readlines(filename): 

1706 """Read the source code.""" 

1707 try: 

1708 with tokenize.open(filename) as f: 

1709 return f.readlines() 

1710 except (LookupError, SyntaxError, UnicodeError): 

1711 # Fall back if file encoding is improperly declared 

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

1713 return f.readlines() 

1714 

1715 

1716def stdin_get_value(): 

1717 """Read the value from stdin.""" 

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

1719 

1720 

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

1722 

1723 

1724def expand_indent(line): 

1725 r"""Return the amount of indentation. 

1726 

1727 Tabs are expanded to the next multiple of 8. 

1728 """ 

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

1730 if '\t' not in line: 

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

1732 result = 0 

1733 for char in line: 

1734 if char == '\t': 

1735 result = result // 8 * 8 + 8 

1736 elif char == ' ': 

1737 result += 1 

1738 else: 

1739 break 

1740 return result 

1741 

1742 

1743def mute_string(text): 

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

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

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

1747 end = len(text) - 1 

1748 # Triple quotes 

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

1750 start += 2 

1751 end -= 2 

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

1753 

1754 

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

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

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

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

1759 rv = {} 

1760 path = nrows = None 

1761 for line in diff.splitlines(): 

1762 if nrows: 

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

1764 nrows -= 1 

1765 continue 

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

1767 hunk_match = HUNK_REGEX.match(line) 

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

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

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

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

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

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

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

1775 path = path[2:] 

1776 rv[path] = set() 

1777 return { 

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

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

1780 if rows and filename_match(filepath, patterns) 

1781 } 

1782 

1783 

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

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

1786 

1787 Return a list of absolute paths. 

1788 """ 

1789 if not value: 

1790 return [] 

1791 if isinstance(value, list): 

1792 return value 

1793 paths = [] 

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

1795 path = path.strip() 

1796 if '/' in path: 

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

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

1799 return paths 

1800 

1801 

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

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

1804 

1805 If patterns is unspecified, this always returns True. 

1806 """ 

1807 if not patterns: 

1808 return default 

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

1810 

1811 

1812def update_counts(s, counts): 

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

1814 for characters in counts""" 

1815 for char in s: 

1816 if char in counts: 

1817 counts[char] += 1 

1818 

1819 

1820def _is_eol_token(token): 

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

1822 

1823 

1824######################################################################## 

1825# Framework to run all checks 

1826######################################################################## 

1827 

1828 

1829class Checker: 

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

1831 

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

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

1834 if options is None: 

1835 options = StyleGuide(kwargs).options 

1836 else: 

1837 assert not kwargs 

1838 self._io_error = None 

1839 self._physical_checks = options.physical_checks 

1840 self._logical_checks = options.logical_checks 

1841 self._ast_checks = options.ast_checks 

1842 self.max_line_length = options.max_line_length 

1843 self.max_doc_length = options.max_doc_length 

1844 self.indent_size = options.indent_size 

1845 self.fstring_start = 0 

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

1847 self.hang_closing = options.hang_closing 

1848 self.indent_size = options.indent_size 

1849 self.verbose = options.verbose 

1850 self.filename = filename 

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

1852 self._checker_states = {} 

1853 if filename is None: 

1854 self.filename = 'stdin' 

1855 self.lines = lines or [] 

1856 elif filename == '-': 

1857 self.filename = 'stdin' 

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

1859 elif lines is None: 

1860 try: 

1861 self.lines = readlines(filename) 

1862 except OSError: 

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

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

1865 self.lines = [] 

1866 else: 

1867 self.lines = lines 

1868 if self.lines: 

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

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

1871 if ord0 == 0xfeff: 

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

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

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

1875 self.report = report or options.report 

1876 self.report_error = self.report.error 

1877 self.noqa = False 

1878 

1879 def report_invalid_syntax(self): 

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

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

1882 if len(exc.args) > 1: 

1883 offset = exc.args[1] 

1884 if len(offset) > 2: 

1885 offset = offset[1:3] 

1886 else: 

1887 offset = (1, 0) 

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

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

1890 self.report_invalid_syntax) 

1891 

1892 def readline(self): 

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

1894 if self.line_number >= self.total_lines: 

1895 return '' 

1896 line = self.lines[self.line_number] 

1897 self.line_number += 1 

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

1899 self.indent_char = line[0] 

1900 return line 

1901 

1902 def run_check(self, check, argument_names): 

1903 """Run a check plugin.""" 

1904 arguments = [] 

1905 for name in argument_names: 

1906 arguments.append(getattr(self, name)) 

1907 return check(*arguments) 

1908 

1909 def init_checker_state(self, name, argument_names): 

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

1911 if 'checker_state' in argument_names: 

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

1913 

1914 def check_physical(self, line): 

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

1916 self.physical_line = line 

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

1918 self.init_checker_state(name, argument_names) 

1919 result = self.run_check(check, argument_names) 

1920 if result is not None: 

1921 (offset, text) = result 

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

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

1924 self.indent_char = line[0] 

1925 

1926 def build_tokens_line(self): 

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

1928 logical = [] 

1929 comments = [] 

1930 length = 0 

1931 prev_row = prev_col = mapping = None 

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

1933 if token_type in SKIP_TOKENS: 

1934 continue 

1935 if not mapping: 

1936 mapping = [(0, start)] 

1937 if token_type == tokenize.COMMENT: 

1938 comments.append(text) 

1939 continue 

1940 if token_type == tokenize.STRING: 

1941 text = mute_string(text) 

1942 elif token_type == FSTRING_MIDDLE: # pragma: >=3.12 cover 

1943 text = 'x' * len(text) 

1944 if prev_row: 

1945 (start_row, start_col) = start 

1946 if prev_row != start_row: # different row 

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

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

1949 text not in '}])'): 

1950 text = ' ' + text 

1951 elif prev_col != start_col: # different column 

1952 text = line[prev_col:start_col] + text 

1953 logical.append(text) 

1954 length += len(text) 

1955 mapping.append((length, end)) 

1956 (prev_row, prev_col) = end 

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

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

1959 return mapping 

1960 

1961 def check_logical(self): 

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

1963 self.report.increment_logical_line() 

1964 mapping = self.build_tokens_line() 

1965 if not mapping: 

1966 return 

1967 

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

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

1970 start_line = self.lines[start_row - 1] 

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

1972 if self.blank_before < self.blank_lines: 

1973 self.blank_before = self.blank_lines 

1974 if self.verbose >= 2: 

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

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

1977 if self.verbose >= 4: 

1978 print(' ' + name) 

1979 self.init_checker_state(name, argument_names) 

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

1981 if not isinstance(offset, tuple): 

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

1983 # to find a given offset in them. 

1984 token_offset, pos = mapping[bisect.bisect_left( 

1985 mapping_offsets, offset)] 

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

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

1988 if self.logical_line: 

1989 self.previous_indent_level = self.indent_level 

1990 self.previous_logical = self.logical_line 

1991 if not self.indent_level: 

1992 self.previous_unindented_logical_line = self.logical_line 

1993 self.blank_lines = 0 

1994 self.tokens = [] 

1995 

1996 def check_ast(self): 

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

1998 try: 

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

2000 except (ValueError, SyntaxError, TypeError): 

2001 return self.report_invalid_syntax() 

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

2003 checker = cls(tree, self.filename) 

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

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

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

2007 

2008 def generate_tokens(self): 

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

2010 if self._io_error: 

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

2012 tokengen = tokenize.generate_tokens(self.readline) 

2013 try: 

2014 prev_physical = '' 

2015 for token in tokengen: 

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

2017 return 

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

2019 self.maybe_check_physical(token, prev_physical) 

2020 yield token 

2021 prev_physical = token[4] 

2022 except (SyntaxError, tokenize.TokenError): 

2023 self.report_invalid_syntax() 

2024 

2025 def maybe_check_physical(self, token, prev_physical): 

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

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

2028 

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

2030 self.fstring_start = token.start[0] 

2031 # a newline token ends a single physical line. 

2032 elif _is_eol_token(token): 

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

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

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

2036 if token.line == '': 

2037 self.check_physical(prev_physical) 

2038 else: 

2039 self.check_physical(token.line) 

2040 elif ( 

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

2042 token.type == FSTRING_END 

2043 ): 

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

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

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

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

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

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

2050 # physical line. 

2051 # 

2052 # Subtleties: 

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

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

2055 # physical checks for the entire multiline string 

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

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

2058 # check_physical() to give accurate feedback 

2059 if noqa(token.line): 

2060 return 

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

2062 start = self.fstring_start 

2063 else: 

2064 start = token.start[0] 

2065 end = token.end[0] 

2066 

2067 self.multiline = True 

2068 self.line_number = start 

2069 for line_number in range(start, end): 

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

2071 self.line_number += 1 

2072 self.multiline = False 

2073 

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

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

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

2077 self.total_lines = len(self.lines) 

2078 if self._ast_checks: 

2079 self.check_ast() 

2080 self.line_number = 0 

2081 self.indent_char = None 

2082 self.indent_level = self.previous_indent_level = 0 

2083 self.previous_logical = '' 

2084 self.previous_unindented_logical_line = '' 

2085 self.tokens = [] 

2086 self.blank_lines = self.blank_before = 0 

2087 parens = 0 

2088 for token in self.generate_tokens(): 

2089 self.tokens.append(token) 

2090 token_type, text = token[0:2] 

2091 if self.verbose >= 3: 

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

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

2094 else: 

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

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

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

2098 if token_type == tokenize.OP: 

2099 if text in '([{': 

2100 parens += 1 

2101 elif text in '}])': 

2102 parens -= 1 

2103 elif not parens: 

2104 if token_type in NEWLINE: 

2105 if token_type == tokenize.NEWLINE: 

2106 self.check_logical() 

2107 self.blank_before = 0 

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

2109 # The physical line contains only this token. 

2110 self.blank_lines += 1 

2111 del self.tokens[0] 

2112 else: 

2113 self.check_logical() 

2114 if self.tokens: 

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

2116 self.check_logical() 

2117 return self.report.get_file_results() 

2118 

2119 

2120class BaseReport: 

2121 """Collect the results of the checks.""" 

2122 

2123 print_filename = False 

2124 

2125 def __init__(self, options): 

2126 self._benchmark_keys = options.benchmark_keys 

2127 self._ignore_code = options.ignore_code 

2128 # Results 

2129 self.elapsed = 0 

2130 self.total_errors = 0 

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

2132 self.messages = {} 

2133 

2134 def start(self): 

2135 """Start the timer.""" 

2136 self._start_time = time.time() 

2137 

2138 def stop(self): 

2139 """Stop the timer.""" 

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

2141 

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

2143 """Signal a new file.""" 

2144 self.filename = filename 

2145 self.lines = lines 

2146 self.expected = expected or () 

2147 self.line_offset = line_offset 

2148 self.file_errors = 0 

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

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

2151 

2152 def increment_logical_line(self): 

2153 """Signal a new logical line.""" 

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

2155 

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

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

2158 code = text[:4] 

2159 if self._ignore_code(code): 

2160 return 

2161 if code in self.counters: 

2162 self.counters[code] += 1 

2163 else: 

2164 self.counters[code] = 1 

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

2166 # Don't care about expected errors or warnings 

2167 if code in self.expected: 

2168 return 

2169 if self.print_filename and not self.file_errors: 

2170 print(self.filename) 

2171 self.file_errors += 1 

2172 self.total_errors += 1 

2173 return code 

2174 

2175 def get_file_results(self): 

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

2177 return self.file_errors 

2178 

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

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

2181 return sum(self.counters[key] 

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

2183 

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

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

2186 

2187 prefix='' matches all errors and warnings 

2188 prefix='E' matches all errors 

2189 prefix='W' matches all warnings 

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

2191 """ 

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

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

2194 

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

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

2197 for line in self.get_statistics(prefix): 

2198 print(line) 

2199 

2200 def print_benchmark(self): 

2201 """Print benchmark numbers.""" 

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

2203 if self.elapsed: 

2204 for key in self._benchmark_keys: 

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

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

2207 self.counters[key])) 

2208 

2209 

2210class FileReport(BaseReport): 

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

2212 

2213 print_filename = True 

2214 

2215 

2216class StandardReport(BaseReport): 

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

2218 

2219 def __init__(self, options): 

2220 super().__init__(options) 

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

2222 options.format) 

2223 self._repeat = options.repeat 

2224 self._show_source = options.show_source 

2225 self._show_pep8 = options.show_pep8 

2226 

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

2228 """Signal a new file.""" 

2229 self._deferred_print = [] 

2230 return super().init_file( 

2231 filename, lines, expected, line_offset) 

2232 

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

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

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

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

2237 self._deferred_print.append( 

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

2239 return code 

2240 

2241 def get_file_results(self): 

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

2243 self._deferred_print.sort() 

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

2245 print(self._fmt % { 

2246 'path': self.filename, 

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

2248 'code': code, 'text': text, 

2249 }) 

2250 if self._show_source: 

2251 if line_number > len(self.lines): 

2252 line = '' 

2253 else: 

2254 line = self.lines[line_number - 1] 

2255 print(line.rstrip()) 

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

2257 if self._show_pep8 and doc: 

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

2259 

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

2261 # line can be broken where buffer boundary since other 

2262 # processes write to same file. 

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

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

2265 # len(line) < 8192. 

2266 sys.stdout.flush() 

2267 return self.file_errors 

2268 

2269 

2270class DiffReport(StandardReport): 

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

2272 

2273 def __init__(self, options): 

2274 super().__init__(options) 

2275 self._selected = options.selected_lines 

2276 

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

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

2279 return 

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

2281 

2282 

2283class StyleGuide: 

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

2285 

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

2287 # build options from the command line 

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

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

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

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

2292 # build options from dict 

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

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

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

2296 options, self.paths = process_options( 

2297 arglist, parse_argv, config_file, parser, verbose) 

2298 if options_dict: 

2299 options.__dict__.update(options_dict) 

2300 if 'paths' in options_dict: 

2301 self.paths = options_dict['paths'] 

2302 

2303 self.runner = self.input_file 

2304 self.options = options 

2305 

2306 if not options.reporter: 

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

2308 

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

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

2311 # The default choice: ignore controversial checks 

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

2313 else: 

2314 # Ignore all checks which are not explicitly selected 

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

2316 options.benchmark_keys = BENCHMARK_KEYS[:] 

2317 options.ignore_code = self.ignore_code 

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

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

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

2321 self.init_report() 

2322 

2323 def init_report(self, reporter=None): 

2324 """Initialize the report instance.""" 

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

2326 return self.options.report 

2327 

2328 def check_files(self, paths=None): 

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

2330 if paths is None: 

2331 paths = self.paths 

2332 report = self.options.report 

2333 runner = self.runner 

2334 report.start() 

2335 try: 

2336 for path in paths: 

2337 if os.path.isdir(path): 

2338 self.input_dir(path) 

2339 elif not self.excluded(path): 

2340 runner(path) 

2341 except KeyboardInterrupt: 

2342 print('... stopped') 

2343 report.stop() 

2344 return report 

2345 

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

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

2348 if self.options.verbose: 

2349 print('checking %s' % filename) 

2350 fchecker = self.checker_class( 

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

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

2353 

2354 def input_dir(self, dirname): 

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

2356 dirname = dirname.rstrip('/') 

2357 if self.excluded(dirname): 

2358 return 0 

2359 counters = self.options.report.counters 

2360 verbose = self.options.verbose 

2361 filepatterns = self.options.filename 

2362 runner = self.runner 

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

2364 if verbose: 

2365 print('directory ' + root) 

2366 counters['directories'] += 1 

2367 for subdir in sorted(dirs): 

2368 if self.excluded(subdir, root): 

2369 dirs.remove(subdir) 

2370 for filename in sorted(files): 

2371 # contain a pattern that matches? 

2372 if ( 

2373 filename_match(filename, filepatterns) and 

2374 not self.excluded(filename, root) 

2375 ): 

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

2377 

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

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

2380 

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

2382 """ 

2383 if not self.options.exclude: 

2384 return False 

2385 basename = os.path.basename(filename) 

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

2387 return True 

2388 if parent: 

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

2390 filename = os.path.abspath(filename) 

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

2392 

2393 def ignore_code(self, code): 

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

2395 

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

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

2398 the error code, return True. 

2399 """ 

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

2401 for s in self.options.select): 

2402 return False 

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

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

2405 

2406 def get_checks(self, argument_name): 

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

2408 

2409 Find all globally visible functions where the first argument 

2410 name starts with argument_name and which contain selected tests. 

2411 """ 

2412 checks = [] 

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

2414 (codes, args) = attrs 

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

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

2417 return sorted(checks) 

2418 

2419 

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

2421 """Create the parser for the program.""" 

2422 parser = OptionParser(prog=prog, version=version, 

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

2424 parser.config_options = [ 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2441 "matching these comma separated patterns " 

2442 "(default: %default)") 

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

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

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

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

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

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

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

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

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

2452 "(implies --first)") 

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

2454 help="count errors and warnings") 

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

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

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

2458 "total is not null") 

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

2460 default=MAX_LINE_LENGTH, 

2461 help="set maximum allowed line length " 

2462 "(default: %default)") 

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

2464 default=None, 

2465 help="set maximum allowed doc line length and perform " 

2466 "these checks (unchecked if not set)") 

2467 parser.add_option('--indent-size', type='int', metavar='n', 

2468 default=INDENT_SIZE, 

2469 help="set how many spaces make up an indent " 

2470 "(default: %default)") 

2471 parser.add_option('--hang-closing', action='store_true', 

2472 help="hang closing bracket instead of matching " 

2473 "indentation of opening bracket's line") 

2474 parser.add_option('--format', metavar='format', default='default', 

2475 help="set the error format [default|pylint|<custom>]") 

2476 parser.add_option('--diff', action='store_true', 

2477 help="report changes only within line number ranges in " 

2478 "the unified diff received on STDIN") 

2479 group = parser.add_option_group("Testing Options") 

2480 group.add_option('--benchmark', action='store_true', 

2481 help="measure processing speed") 

2482 return parser 

2483 

2484 

2485def read_config(options, args, arglist, parser): 

2486 """Read and parse configurations. 

2487 

2488 If a config file is specified on the command line with the 

2489 "--config" option, then only it is used for configuration. 

2490 

2491 Otherwise, the user configuration (~/.config/pycodestyle) and any 

2492 local configurations in the current directory or above will be 

2493 merged together (in that order) using the read method of 

2494 ConfigParser. 

2495 """ 

2496 config = configparser.RawConfigParser() 

2497 

2498 cli_conf = options.config 

2499 

2500 local_dir = os.curdir 

2501 

2502 if USER_CONFIG and os.path.isfile(USER_CONFIG): 

2503 if options.verbose: 

2504 print('user configuration: %s' % USER_CONFIG) 

2505 config.read(USER_CONFIG) 

2506 

2507 parent = tail = args and os.path.abspath(os.path.commonprefix(args)) 

2508 while tail: 

2509 if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): 

2510 local_dir = parent 

2511 if options.verbose: 

2512 print('local configuration: in %s' % parent) 

2513 break 

2514 (parent, tail) = os.path.split(parent) 

2515 

2516 if cli_conf and os.path.isfile(cli_conf): 

2517 if options.verbose: 

2518 print('cli configuration: %s' % cli_conf) 

2519 config.read(cli_conf) 

2520 

2521 pycodestyle_section = None 

2522 if config.has_section(parser.prog): 

2523 pycodestyle_section = parser.prog 

2524 elif config.has_section('pep8'): 

2525 pycodestyle_section = 'pep8' # Deprecated 

2526 warnings.warn('[pep8] section is deprecated. Use [pycodestyle].') 

2527 

2528 if pycodestyle_section: 

2529 option_list = {o.dest: o.type or o.action for o in parser.option_list} 

2530 

2531 # First, read the default values 

2532 (new_options, __) = parser.parse_args([]) 

2533 

2534 # Second, parse the configuration 

2535 for opt in config.options(pycodestyle_section): 

2536 if opt.replace('_', '-') not in parser.config_options: 

2537 print(" unknown option '%s' ignored" % opt) 

2538 continue 

2539 if options.verbose > 1: 

2540 print(" {} = {}".format(opt, 

2541 config.get(pycodestyle_section, opt))) 

2542 normalized_opt = opt.replace('-', '_') 

2543 opt_type = option_list[normalized_opt] 

2544 if opt_type in ('int', 'count'): 

2545 value = config.getint(pycodestyle_section, opt) 

2546 elif opt_type in ('store_true', 'store_false'): 

2547 value = config.getboolean(pycodestyle_section, opt) 

2548 else: 

2549 value = config.get(pycodestyle_section, opt) 

2550 if normalized_opt == 'exclude': 

2551 value = normalize_paths(value, local_dir) 

2552 setattr(new_options, normalized_opt, value) 

2553 

2554 # Third, overwrite with the command-line options 

2555 (options, __) = parser.parse_args(arglist, values=new_options) 

2556 return options 

2557 

2558 

2559def process_options(arglist=None, parse_argv=False, config_file=None, 

2560 parser=None, verbose=None): 

2561 """Process options passed either via arglist or command line args. 

2562 

2563 Passing in the ``config_file`` parameter allows other tools, such as 

2564 flake8 to specify their own options to be processed in pycodestyle. 

2565 """ 

2566 if not parser: 

2567 parser = get_parser() 

2568 if not parser.has_option('--config'): 

2569 group = parser.add_option_group("Configuration", description=( 

2570 "The project options are read from the [%s] section of the " 

2571 "tox.ini file or the setup.cfg file located in any parent folder " 

2572 "of the path(s) being processed. Allowed options are: %s." % 

2573 (parser.prog, ', '.join(parser.config_options)))) 

2574 group.add_option('--config', metavar='path', default=config_file, 

2575 help="user config file location") 

2576 # Don't read the command line if the module is used as a library. 

2577 if not arglist and not parse_argv: 

2578 arglist = [] 

2579 # If parse_argv is True and arglist is None, arguments are 

2580 # parsed from the command line (sys.argv) 

2581 (options, args) = parser.parse_args(arglist) 

2582 options.reporter = None 

2583 

2584 # If explicitly specified verbosity, override any `-v` CLI flag 

2585 if verbose is not None: 

2586 options.verbose = verbose 

2587 

2588 if parse_argv and not args: 

2589 if options.diff or any(os.path.exists(name) 

2590 for name in PROJECT_CONFIG): 

2591 args = ['.'] 

2592 else: 

2593 parser.error('input not specified') 

2594 options = read_config(options, args, arglist, parser) 

2595 options.reporter = parse_argv and options.quiet == 1 and FileReport 

2596 

2597 options.filename = _parse_multi_options(options.filename) 

2598 options.exclude = normalize_paths(options.exclude) 

2599 options.select = _parse_multi_options(options.select) 

2600 options.ignore = _parse_multi_options(options.ignore) 

2601 

2602 if options.diff: 

2603 options.reporter = DiffReport 

2604 stdin = stdin_get_value() 

2605 options.selected_lines = parse_udiff(stdin, options.filename, args[0]) 

2606 args = sorted(options.selected_lines) 

2607 

2608 return options, args 

2609 

2610 

2611def _parse_multi_options(options, split_token=','): 

2612 r"""Split and strip and discard empties. 

2613 

2614 Turns the following: 

2615 

2616 A, 

2617 B, 

2618 

2619 into ["A", "B"] 

2620 """ 

2621 if options: 

2622 return [o.strip() for o in options.split(split_token) if o.strip()] 

2623 else: 

2624 return options 

2625 

2626 

2627def _main(): 

2628 """Parse options and run checks on Python source.""" 

2629 import signal 

2630 

2631 # Handle "Broken pipe" gracefully 

2632 try: 

2633 signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1)) 

2634 except AttributeError: 

2635 pass # not supported on Windows 

2636 

2637 style_guide = StyleGuide(parse_argv=True) 

2638 options = style_guide.options 

2639 

2640 report = style_guide.check_files() 

2641 

2642 if options.statistics: 

2643 report.print_statistics() 

2644 

2645 if options.benchmark: 

2646 report.print_benchmark() 

2647 

2648 if report.total_errors: 

2649 if options.count: 

2650 sys.stderr.write(str(report.total_errors) + '\n') 

2651 sys.exit(1) 

2652 

2653 

2654if __name__ == '__main__': 

2655 _main()