adding new stuff
This commit is contained in:
parent
f84d7183aa
commit
9ef8a96f9a
1580 changed files with 0 additions and 0 deletions
241
plugins/bundle/python-mode/pymode/libs/pylama/config.py
Normal file
241
plugins/bundle/python-mode/pymode/libs/pylama/config.py
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
""" Parse arguments from command line and configuration files. """
|
||||
import fnmatch
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
|
||||
import logging
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from . import __version__
|
||||
from .libs.inirama import Namespace
|
||||
from .lint.extensions import LINTERS
|
||||
|
||||
#: A default checkers
|
||||
DEFAULT_LINTERS = 'pep8', 'pyflakes', 'mccabe'
|
||||
|
||||
CURDIR = os.getcwd()
|
||||
CONFIG_FILES = 'pylama.ini', 'setup.cfg', 'tox.ini', 'pytest.ini'
|
||||
|
||||
#: The skip pattern
|
||||
SKIP_PATTERN = re.compile(r'# *noqa\b', re.I).search
|
||||
|
||||
# Parse a modelines
|
||||
MODELINE_RE = re.compile(r'^\s*#\s+(?:pylama:)\s*((?:[\w_]*=[^:\n\s]+:?)+)', re.I | re.M)
|
||||
|
||||
# Setup a logger
|
||||
LOGGER = logging.getLogger('pylama')
|
||||
LOGGER.propagate = False
|
||||
STREAM = logging.StreamHandler(sys.stdout)
|
||||
LOGGER.addHandler(STREAM)
|
||||
|
||||
|
||||
class _Default(object):
|
||||
|
||||
def __init__(self, value=None):
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
||||
def __repr__(self):
|
||||
return "<_Default [%s]>" % self.value
|
||||
|
||||
|
||||
def split_csp_str(s):
|
||||
""" Split commaseparated string.
|
||||
|
||||
:returns: list of splitted values
|
||||
|
||||
"""
|
||||
if isinstance(s, (list, tuple)):
|
||||
return s
|
||||
return list(set(i for i in s.strip().split(',') if i))
|
||||
|
||||
|
||||
def parse_linters(linters):
|
||||
""" Initialize choosen linters.
|
||||
|
||||
:returns: list of inited linters
|
||||
|
||||
"""
|
||||
result = list()
|
||||
for name in split_csp_str(linters):
|
||||
linter = LINTERS.get(name)
|
||||
if linter:
|
||||
result.append((name, linter))
|
||||
else:
|
||||
logging.warn("Linter `%s` not found.", name)
|
||||
return result
|
||||
|
||||
|
||||
PARSER = ArgumentParser(description="Code audit tool for python.")
|
||||
PARSER.add_argument(
|
||||
"paths", nargs='*', default=_Default([CURDIR]),
|
||||
help="Paths to files or directories for code check.")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--verbose", "-v", action='store_true', help="Verbose mode.")
|
||||
|
||||
PARSER.add_argument('--version', action='version',
|
||||
version='%(prog)s ' + __version__)
|
||||
|
||||
PARSER.add_argument(
|
||||
"--format", "-f", default=_Default('pep8'), choices=['pep8', 'pylint'],
|
||||
help="Choose errors format (pep8, pylint).")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--select", "-s", default=_Default(''), type=split_csp_str,
|
||||
help="Select errors and warnings. (comma-separated list)")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--sort", default=_Default(''), type=split_csp_str,
|
||||
help="Sort result by error types. Ex. E,W,D")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--linters", "-l", default=_Default(','.join(DEFAULT_LINTERS)),
|
||||
type=parse_linters, help=(
|
||||
"Select linters. (comma-separated). Choices are %s."
|
||||
% ','.join(s for s in LINTERS.keys())
|
||||
))
|
||||
|
||||
PARSER.add_argument(
|
||||
"--ignore", "-i", default=_Default(''), type=split_csp_str,
|
||||
help="Ignore errors and warnings. (comma-separated)")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--skip", default=_Default(''),
|
||||
type=lambda s: [re.compile(fnmatch.translate(p)) for p in s.split(',') if p],
|
||||
help="Skip files by masks (comma-separated, Ex. */messages.py)")
|
||||
|
||||
PARSER.add_argument("--report", "-r", help="Send report to file [REPORT]")
|
||||
PARSER.add_argument(
|
||||
"--hook", action="store_true", help="Install Git (Mercurial) hook.")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--async", action="store_true",
|
||||
help="Enable async mode. Usefull for checking a lot of files. "
|
||||
"Dont supported with pylint.")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--options", "-o", default="",
|
||||
help="Select configuration file. By default is '<CURDIR>/pylama.ini'")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--force", "-F", action='store_true', default=_Default(False),
|
||||
help="Force code checking (if linter doesnt allow)")
|
||||
|
||||
PARSER.add_argument(
|
||||
"--abspath", "-a", action='store_true', default=_Default(False),
|
||||
help="Use absolute paths in output.")
|
||||
|
||||
|
||||
ACTIONS = dict((a.dest, a) for a in PARSER._actions)
|
||||
|
||||
|
||||
def parse_options(args=None, config=True, rootdir=CURDIR, **overrides): # noqa
|
||||
""" Parse options from command line and configuration files.
|
||||
|
||||
:return argparse.Namespace:
|
||||
|
||||
"""
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
# Parse args from command string
|
||||
options = PARSER.parse_args(args)
|
||||
options.file_params = dict()
|
||||
options.linters_params = dict()
|
||||
|
||||
# Override options
|
||||
for k, v in overrides.items():
|
||||
passed_value = getattr(options, k, _Default())
|
||||
if isinstance(passed_value, _Default):
|
||||
setattr(options, k, _Default(v))
|
||||
|
||||
# Compile options from ini
|
||||
if config:
|
||||
cfg = get_config(str(options.options), rootdir=rootdir)
|
||||
for k, v in cfg.default.items():
|
||||
LOGGER.info('Find option %s (%s)', k, v)
|
||||
passed_value = getattr(options, k, _Default())
|
||||
if isinstance(passed_value, _Default):
|
||||
if k == 'paths':
|
||||
v = v.split()
|
||||
setattr(options, k, _Default(v))
|
||||
|
||||
# Parse file related options
|
||||
for name, opts in cfg.sections.items():
|
||||
|
||||
if not name.startswith('pylama'):
|
||||
continue
|
||||
|
||||
if name == cfg.default_section:
|
||||
continue
|
||||
|
||||
name = name[7:]
|
||||
|
||||
if name in LINTERS:
|
||||
options.linters_params[name] = dict(opts)
|
||||
continue
|
||||
|
||||
mask = re.compile(fnmatch.translate(name))
|
||||
options.file_params[mask] = dict(opts)
|
||||
|
||||
# Postprocess options
|
||||
opts = dict(options.__dict__.items())
|
||||
for name, value in opts.items():
|
||||
if isinstance(value, _Default):
|
||||
setattr(options, name, process_value(name, value.value))
|
||||
|
||||
if options.async and 'pylint' in options.linters:
|
||||
LOGGER.warn('Cant parse code asynchronously while pylint is enabled.')
|
||||
options.async = False
|
||||
|
||||
return options
|
||||
|
||||
|
||||
def process_value(name, value):
|
||||
""" Compile option value. """
|
||||
action = ACTIONS.get(name)
|
||||
if not action:
|
||||
return value
|
||||
|
||||
if callable(action.type):
|
||||
return action.type(value)
|
||||
|
||||
if action.const:
|
||||
return bool(int(value))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def get_config(ini_path=None, rootdir=CURDIR):
|
||||
""" Load configuration from INI.
|
||||
|
||||
:return Namespace:
|
||||
|
||||
"""
|
||||
config = Namespace()
|
||||
config.default_section = 'pylama'
|
||||
|
||||
if not ini_path:
|
||||
for path in CONFIG_FILES:
|
||||
path = os.path.join(rootdir, path)
|
||||
if os.path.isfile(path) and os.access(path, os.R_OK):
|
||||
config.read(path)
|
||||
else:
|
||||
config.read(ini_path)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def setup_logger(options):
|
||||
""" Setup logger with options. """
|
||||
LOGGER.setLevel(logging.INFO if options.verbose else logging.WARN)
|
||||
if options.report:
|
||||
LOGGER.removeHandler(STREAM)
|
||||
LOGGER.addHandler(logging.FileHandler(options.report, mode='w'))
|
||||
LOGGER.info('Try to read configuration from: ' + options.options)
|
||||
|
||||
# pylama:ignore=W0212,D210,F0001
|
||||
Loading…
Add table
Add a link
Reference in a new issue