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.""" |
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 |