Plugins/CheckerPlugins/CodeStyleChecker/pycodestyle.py

changeset 5288
ff831e3e383e
parent 5147
d39dd5cee0c8
child 5290
174dae2b91c3
equal deleted inserted replaced
5287:971f24c89e6b 5288:ff831e3e383e
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # pycodestyle.py - Check Python source code formatting, according to PEP 8 4 # pycodestyle.py - Check Python source code formatting, according to PEP 8
5 #
5 # Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net> 6 # Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net>
6 # Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> 7 # Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
7 # Copyright (C) 2014-2016 Ian Lee <ianlee1521@gmail.com> 8 # Copyright (C) 2014-2016 Ian Lee <ianlee1521@gmail.com>
8 # 9 #
9 # Permission is hereby granted, free of charge, to any person 10 # Permission is hereby granted, free of charge, to any person
65 import os 66 import os
66 import re 67 import re
67 import sys 68 import sys
68 import time 69 import time
69 import tokenize 70 import tokenize
70 ##import ast 71 import warnings
72
71 from fnmatch import fnmatch 73 from fnmatch import fnmatch
72 from optparse import OptionParser 74 from optparse import OptionParser
75
73 try: 76 try:
74 from configparser import RawConfigParser 77 from configparser import RawConfigParser
75 from io import TextIOWrapper 78 from io import TextIOWrapper
76 except ImportError: 79 except ImportError:
77 from ConfigParser import RawConfigParser # __IGNORE_WARNING__ 80 from ConfigParser import RawConfigParser # __IGNORE_WARNING__
78 81
79 __version__ = '2.1.0.dev0' 82 __version__ = '2.1.0'
80 83
81 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' 84 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox'
82 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503' 85 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503'
83 try: 86 try:
84 if sys.platform == 'win32': 87 if sys.platform == 'win32':
279 if previous_logical.startswith('@'): 282 if previous_logical.startswith('@'):
280 if blank_lines: 283 if blank_lines:
281 yield 0, "E304 blank lines found after function decorator" 284 yield 0, "E304 blank lines found after function decorator"
282 elif blank_lines > 2 or (indent_level and blank_lines == 2): 285 elif blank_lines > 2 or (indent_level and blank_lines == 2):
283 yield 0, "E303 too many blank lines (%d)", blank_lines 286 yield 0, "E303 too many blank lines (%d)", blank_lines
284 elif logical_line.startswith(('def ', 'async def ', 'class ', '@')): 287 elif logical_line.startswith(('def ', 'async def', 'class ', '@')):
285 if indent_level: 288 if indent_level:
286 if not (blank_before or previous_indent_level < indent_level or 289 if not (blank_before or previous_indent_level < indent_level or
287 DOCSTRING_REGEX.match(previous_logical)): 290 DOCSTRING_REGEX.match(previous_logical)):
288 ancestor_level = indent_level 291 ancestor_level = indent_level
289 nested = False 292 nested = False
986 E701: finally: cleanup() 989 E701: finally: cleanup()
987 E701: if foo == 'blah': one(); two(); three() 990 E701: if foo == 'blah': one(); two(); three()
988 E702: do_one(); do_two(); do_three() 991 E702: do_one(); do_two(); do_three()
989 E703: do_four(); # useless semicolon 992 E703: do_four(); # useless semicolon
990 E704: def f(x): return 2*x 993 E704: def f(x): return 2*x
991 E705: async def f(x): return 2*x
992 E731: f = lambda x: 2*x 994 E731: f = lambda x: 2*x
993 """ 995 """
994 line = logical_line 996 line = logical_line
995 last_char = len(line) - 1 997 last_char = len(line) - 1
996 found = line.find(':') 998 found = line.find(':')
1008 yield 0, ("E731 do not assign a lambda expression, use a " 1010 yield 0, ("E731 do not assign a lambda expression, use a "
1009 "def") 1011 "def")
1010 break 1012 break
1011 if line.startswith('def '): 1013 if line.startswith('def '):
1012 yield 0, "E704 multiple statements on one line (def)" 1014 yield 0, "E704 multiple statements on one line (def)"
1013 elif line.startswith('async def '):
1014 yield 0, "E705 multiple statements on one line (async def)"
1015 else: 1015 else:
1016 yield found, "E701 multiple statements on one line (colon)" 1016 yield found, "E701 multiple statements on one line (colon)"
1017 prev_found = found 1017 prev_found = found
1018 found = line.find(':', found + 1) 1018 found = line.find(':', found + 1)
1019 found = line.find(';') 1019 found = line.find(';')
1571 for name in argument_names: 1571 for name in argument_names:
1572 arguments.append(getattr(self, name)) 1572 arguments.append(getattr(self, name))
1573 return check(*arguments) 1573 return check(*arguments)
1574 1574
1575 def init_checker_state(self, name, argument_names): 1575 def init_checker_state(self, name, argument_names):
1576 """ Prepare custom state for the specific checker plugin.""" 1576 """Prepare custom state for the specific checker plugin."""
1577 if 'checker_state' in argument_names: 1577 if 'checker_state' in argument_names:
1578 self.checker_state = self._checker_states.setdefault(name, {}) 1578 self.checker_state = self._checker_states.setdefault(name, {})
1579 1579
1580 def check_physical(self, line): 1580 def check_physical(self, line):
1581 """Run all physical checks on a raw input line.""" 1581 """Run all physical checks on a raw input line."""
1883 self.counters[key])) 1883 self.counters[key]))
1884 1884
1885 1885
1886 class FileReport(BaseReport): 1886 class FileReport(BaseReport):
1887 """Collect the results of the checks and print only the filenames.""" 1887 """Collect the results of the checks and print only the filenames."""
1888
1888 print_filename = True 1889 print_filename = True
1889 1890
1890 1891
1891 class StandardReport(BaseReport): 1892 class StandardReport(BaseReport):
1892 """Collect and print the results of the checks.""" 1893 """Collect and print the results of the checks."""
2164 help="measure processing speed") 2165 help="measure processing speed")
2165 return parser 2166 return parser
2166 2167
2167 2168
2168 def read_config(options, args, arglist, parser): 2169 def read_config(options, args, arglist, parser):
2169 """Read and parse configurations 2170 """Read and parse configurations.
2170 2171
2171 If a config file is specified on the command line with the "--config" 2172 If a config file is specified on the command line with the "--config"
2172 option, then only it is used for configuration. 2173 option, then only it is used for configuration.
2173 2174
2174 Otherwise, the user configuration (~/.config/pycodestyle) and any local 2175 Otherwise, the user configuration (~/.config/pycodestyle) and any local
2198 if cli_conf and os.path.isfile(cli_conf): 2199 if cli_conf and os.path.isfile(cli_conf):
2199 if options.verbose: 2200 if options.verbose:
2200 print('cli configuration: %s' % cli_conf) 2201 print('cli configuration: %s' % cli_conf)
2201 config.read(cli_conf) 2202 config.read(cli_conf)
2202 2203
2203 pep8_section = parser.prog 2204 pycodestyle_section = None
2204 if config.has_section(pep8_section): 2205 if config.has_section(parser.prog):
2206 pycodestyle_section = parser.prog
2207 elif config.has_section('pep8'):
2208 pycodestyle_section = 'pep8' # Deprecated
2209 warnings.warn('[pep8] section is deprecated. Use [pycodestyle].')
2210
2211 if pycodestyle_section:
2205 option_list = dict([(o.dest, o.type or o.action) 2212 option_list = dict([(o.dest, o.type or o.action)
2206 for o in parser.option_list]) 2213 for o in parser.option_list])
2207 2214
2208 # First, read the default values 2215 # First, read the default values
2209 (new_options, __) = parser.parse_args([]) 2216 (new_options, __) = parser.parse_args([])
2210 2217
2211 # Second, parse the configuration 2218 # Second, parse the configuration
2212 for opt in config.options(pep8_section): 2219 for opt in config.options(pycodestyle_section):
2213 if opt.replace('_', '-') not in parser.config_options: 2220 if opt.replace('_', '-') not in parser.config_options:
2214 print(" unknown option '%s' ignored" % opt) 2221 print(" unknown option '%s' ignored" % opt)
2215 continue 2222 continue
2216 if options.verbose > 1: 2223 if options.verbose > 1:
2217 print(" %s = %s" % (opt, config.get(pep8_section, opt))) 2224 print(" %s = %s" % (opt,
2225 config.get(pycodestyle_section, opt)))
2218 normalized_opt = opt.replace('-', '_') 2226 normalized_opt = opt.replace('-', '_')
2219 opt_type = option_list[normalized_opt] 2227 opt_type = option_list[normalized_opt]
2220 if opt_type in ('int', 'count'): 2228 if opt_type in ('int', 'count'):
2221 value = config.getint(pep8_section, opt) 2229 value = config.getint(pycodestyle_section, opt)
2222 elif opt_type in ('store_true', 'store_false'): 2230 elif opt_type in ('store_true', 'store_false'):
2223 value = config.getboolean(pep8_section, opt) 2231 value = config.getboolean(pycodestyle_section, opt)
2224 else: 2232 else:
2225 value = config.get(pep8_section, opt) 2233 value = config.get(pycodestyle_section, opt)
2226 if normalized_opt == 'exclude': 2234 if normalized_opt == 'exclude':
2227 value = normalize_paths(value, local_dir) 2235 value = normalize_paths(value, local_dir)
2228 setattr(new_options, normalized_opt, value) 2236 setattr(new_options, normalized_opt, value)
2229 2237
2230 # Third, overwrite with the command-line options 2238 # Third, overwrite with the command-line options
2331 if report.total_errors: 2339 if report.total_errors:
2332 if options.count: 2340 if options.count:
2333 sys.stderr.write(str(report.total_errors) + '\n') 2341 sys.stderr.write(str(report.total_errors) + '\n')
2334 sys.exit(1) 2342 sys.exit(1)
2335 2343
2344
2336 if __name__ == '__main__': 2345 if __name__ == '__main__':
2337 _main() 2346 _main()
2338 # 2347 #
2339 # eflag: noqa = M702 2348 # eflag: noqa = D2, M601, M701, M702, M801

eric ide

mercurial