From c0444a77f1601f2b5fe265ecedf1cef2156c7756 Mon Sep 17 00:00:00 2001 From: youben11 Date: Sun, 13 Oct 2019 19:07:15 +0100 Subject: [PATCH 1/3] Add support for pylint config files --- pyls/config/config.py | 7 ++++- pyls/config/pylint_conf.py | 54 +++++++++++++++++++++++++++++++++++++ pyls/plugins/pylint_lint.py | 24 +++++++++++++++-- vscode-client/package.json | 2 +- 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 pyls/config/pylint_conf.py diff --git a/pyls/config/config.py b/pyls/config/config.py index 65696d81..3425703c 100644 --- a/pyls/config/config.py +++ b/pyls/config/config.py @@ -13,7 +13,7 @@ log = logging.getLogger(__name__) # Sources of config, first source overrides next source -DEFAULT_CONFIG_SOURCES = ['pycodestyle'] +DEFAULT_CONFIG_SOURCES = ['pycodestyle', 'pylint'] class Config(object): @@ -39,6 +39,11 @@ def __init__(self, root_uri, init_opts, process_id, capabilities): self._config_sources['pycodestyle'] = PyCodeStyleConfig(self._root_path) except ImportError: pass + try: + from .pylint_conf import PylintConfig + self._config_sources['pylint'] = PylintConfig(self._root_path) + except ImportError: + pass self._pm = pluggy.PluginManager(PYLS) self._pm.trace.root.setwriter(log.debug) diff --git a/pyls/config/pylint_conf.py b/pyls/config/pylint_conf.py new file mode 100644 index 00000000..711cb994 --- /dev/null +++ b/pyls/config/pylint_conf.py @@ -0,0 +1,54 @@ +# Copyright 2019 Palantir Technologies, Inc. +import logging +import os +from pyls._utils import find_parents +from .source import ConfigSource, _get_opt, _set_opt + +log = logging.getLogger(__name__) + +PROJECT_CONFIGS = ['.pylintrc', 'pylintrc'] + +CONFIG_KEYS = { # 'option': 'section key' + 'disable': 'MESSAGES CONTROL', + 'ignore': 'MASTER', + 'max-line-length': 'FORMAT', +} + +OPTIONS = [ + ('disable', 'plugins.pylint.disable', list), + ('ignore', 'plugins.pylint.ignore', list), + ('max-line-length', 'plugins.pylint.maxLineLength', int), +] + + +class PylintConfig(ConfigSource): + """Parse pylint configurations.""" + + def user_config(self): + config_file = self._user_config_file() + config = self.read_config_from_files([config_file]) + return self.parse_config(config, CONFIG_KEYS, OPTIONS) + + def _user_config_file(self): + if self.is_windows: + return os.path.expanduser('~\\.pylintrc') + return os.path.expanduser('~/.pylintrc') + + def project_config(self, document_path): + files = find_parents(self.root_path, document_path, PROJECT_CONFIGS) + config = self.read_config_from_files(files) + return self.parse_config(config, CONFIG_KEYS, OPTIONS) + + @staticmethod + def parse_config(config, keys, options): + """Parse the config with the given options. + This method override its parent to use multiple keys depending + on the value we want to get. + """ + conf = {} + for source, destination, opt_type in options: + key = keys[source] + opt_value = _get_opt(config, key, source, opt_type) + if opt_value is not None: + _set_opt(conf, destination, opt_value) + return conf diff --git a/pyls/plugins/pylint_lint.py b/pyls/plugins/pylint_lint.py index c07ade55..a4e8c965 100644 --- a/pyls/plugins/pylint_lint.py +++ b/pyls/plugins/pylint_lint.py @@ -11,6 +11,12 @@ log = logging.getLogger(__name__) +ARGS = { # 'argument_name': 'name_under_plugin_conf' + 'disable': 'disable', + 'ignore': 'ignore', + 'max-line-length': 'maxLineLength', +} + class PylintLinter(object): last_diags = collections.defaultdict(list) @@ -140,10 +146,24 @@ def lint(cls, document, is_saved, flags=''): def _build_pylint_flags(settings): - """Build arguments for calling pylint.""" + """Build arguments for calling pylint. + If args is found then it's the arguments used, otherwise, + we build arguments from the plugin config. + """ pylint_args = settings.get('args') if pylint_args is None: - return '' + # Build args from plugin config + pylint_args = list() + for arg_name in ARGS: + arg_val = settings.get(ARGS[arg_name]) + arg = None + if isinstance(arg_val, list): + arg = '--{}={}'.format(arg_name, ','.join(arg_val)) + elif isinstance(arg_val, int): + arg = '--{}={}'.format(arg_name, arg_val) + if arg: + pylint_args.append(arg) + return ' '.join(pylint_args) diff --git a/vscode-client/package.json b/vscode-client/package.json index a5798ec2..ca9584ed 100644 --- a/vscode-client/package.json +++ b/vscode-client/package.json @@ -27,7 +27,7 @@ }, "pyls.configurationSources": { "type": "array", - "default": ["pycodestyle"], + "default": ["pycodestyle", "pylint"], "description": "List of configuration sources to use.", "items": { "type": "string", From 0a767a3623745c22e223ae227d338cad629ff1a0 Mon Sep 17 00:00:00 2001 From: youben11 Date: Sun, 13 Oct 2019 19:52:44 +0100 Subject: [PATCH 2/3] parse_config using multiple keys --- pyls/config/pylint_conf.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pyls/config/pylint_conf.py b/pyls/config/pylint_conf.py index 711cb994..7583e040 100644 --- a/pyls/config/pylint_conf.py +++ b/pyls/config/pylint_conf.py @@ -27,7 +27,7 @@ class PylintConfig(ConfigSource): def user_config(self): config_file = self._user_config_file() config = self.read_config_from_files([config_file]) - return self.parse_config(config, CONFIG_KEYS, OPTIONS) + return self.parse_config_multi_keys(config, CONFIG_KEYS, OPTIONS) def _user_config_file(self): if self.is_windows: @@ -37,13 +37,12 @@ def _user_config_file(self): def project_config(self, document_path): files = find_parents(self.root_path, document_path, PROJECT_CONFIGS) config = self.read_config_from_files(files) - return self.parse_config(config, CONFIG_KEYS, OPTIONS) + return self.parse_config_multi_keys(config, CONFIG_KEYS, OPTIONS) @staticmethod - def parse_config(config, keys, options): + def parse_config_multi_keys(config, keys, options): """Parse the config with the given options. - This method override its parent to use multiple keys depending - on the value we want to get. + This method use multiple keys depending on the value we want to get. """ conf = {} for source, destination, opt_type in options: From 4bd3aab45fc9d89f9f50335e6335fa84a2adb3ee Mon Sep 17 00:00:00 2001 From: youben11 Date: Sun, 13 Oct 2019 19:57:31 +0100 Subject: [PATCH 3/3] two space inline comment --- pyls/config/pylint_conf.py | 2 +- pyls/plugins/pylint_lint.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyls/config/pylint_conf.py b/pyls/config/pylint_conf.py index 7583e040..2c918b64 100644 --- a/pyls/config/pylint_conf.py +++ b/pyls/config/pylint_conf.py @@ -8,7 +8,7 @@ PROJECT_CONFIGS = ['.pylintrc', 'pylintrc'] -CONFIG_KEYS = { # 'option': 'section key' +CONFIG_KEYS = { # 'option': 'section key' 'disable': 'MESSAGES CONTROL', 'ignore': 'MASTER', 'max-line-length': 'FORMAT', diff --git a/pyls/plugins/pylint_lint.py b/pyls/plugins/pylint_lint.py index a4e8c965..d1fa0948 100644 --- a/pyls/plugins/pylint_lint.py +++ b/pyls/plugins/pylint_lint.py @@ -11,7 +11,7 @@ log = logging.getLogger(__name__) -ARGS = { # 'argument_name': 'name_under_plugin_conf' +ARGS = { # 'argument_name': 'name_under_plugin_conf' 'disable': 'disable', 'ignore': 'ignore', 'max-line-length': 'maxLineLength',