fune/tools/lint/python/pylint.py
Alex Lopez 56dc4c7787 Bug 1682959 - Update pylint dependencies to ensure compatibility. r=mhentges
Conflicting pylint requirements were causing the new pip dependency resolver
to report an error. This updates the dependencies for pylint (using the hashin package)
so that the conflict is resolved.

Differential Revision: https://phabricator.services.mozilla.com/D106154
2021-02-25 18:36:59 +00:00

134 lines
3.6 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import json
import os
import subprocess
import signal
from mozprocess import ProcessHandler
from mozlint import result
from mozlint.pathutils import expand_exclusions
here = os.path.abspath(os.path.dirname(__file__))
PYLINT_REQUIREMENTS_PATH = os.path.join(here, "pylint_requirements.txt")
PYLINT_NOT_FOUND = """
Could not find pylint! Install pylint and try again.
$ pip install -U --require-hashes -r {}
""".strip().format(
PYLINT_REQUIREMENTS_PATH
)
PYLINT_INSTALL_ERROR = """
Unable to install correct version of pylint
Try to install it manually with:
$ pip install -U --require-hashes -r {}
""".strip().format(
PYLINT_REQUIREMENTS_PATH
)
class PylintProcess(ProcessHandler):
def __init__(self, config, *args, **kwargs):
self.config = config
kwargs["stream"] = False
kwargs["universal_newlines"] = True
ProcessHandler.__init__(self, *args, **kwargs)
def run(self, *args, **kwargs):
orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
ProcessHandler.run(self, *args, **kwargs)
signal.signal(signal.SIGINT, orig)
def setup(root, **lintargs):
virtualenv_manager = lintargs["virtualenv_manager"]
try:
virtualenv_manager.install_pip_requirements(
PYLINT_REQUIREMENTS_PATH,
quiet=True,
)
except subprocess.CalledProcessError:
print(PYLINT_INSTALL_ERROR)
return 1
def get_pylint_binary():
return "pylint"
def run_process(config, cmd):
proc = PylintProcess(config, cmd)
proc.run()
try:
proc.wait()
except KeyboardInterrupt:
proc.kill()
return proc.output
def parse_issues(log, config, issues_json, path):
results = []
try:
issues = json.loads(issues_json)
except json.decoder.JSONDecodeError:
log.debug("Could not parse the output:")
log.debug("pylint output: {}".format(issues_json))
return []
for issue in issues:
res = {
"path": issue["path"],
"level": issue["type"],
"lineno": issue["line"],
"column": issue["column"],
"message": issue["message"],
"rule": issue["message-id"],
}
results.append(result.from_config(config, **res))
return results
def get_pylint_version(binary):
return subprocess.check_output(
[binary, "--version"],
universal_newlines=True,
stderr=subprocess.STDOUT,
)
def lint(paths, config, **lintargs):
log = lintargs["log"]
binary = get_pylint_binary()
log = lintargs["log"]
paths = list(expand_exclusions(paths, config, lintargs["root"]))
cmd_args = [binary]
results = []
# list from https://code.visualstudio.com/docs/python/linting#_pylint
# And ignore a bit more elements
cmd_args += [
"-fjson",
"--disable=all",
"--enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode,no-else-return", # NOQA: E501
"--disable=import-error,no-member",
]
base_command = cmd_args + paths
log.debug("Command: {}".format(" ".join(cmd_args)))
log.debug("pylint version: {}".format(get_pylint_version(binary)))
output = " ".join(run_process(config, base_command))
results = parse_issues(log, config, str(output), [])
return results