Odoo18-Base/odoo/addons/test_lint/tests/test_pylint.py

110 lines
3.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import os
import platform
import sys
from os.path import join
try:
import pylint
except ImportError:
pylint = None
import subprocess
from odoo.tests.common import TransactionCase
from odoo import tools
from odoo.modules import get_modules, get_module_path
HERE = os.path.dirname(os.path.realpath(__file__))
_logger = logging.getLogger(__name__)
class TestPyLint(TransactionCase):
def _skip_test(self, reason):
_logger.warning(reason)
self.skipTest(reason)
def test_pylint(self):
if pylint is None:
self._skip_test('please install pylint')
required_pylint_version = tools.parse_version('1.6.4')
if self._python_version >= (3, 6):
required_pylint_version = tools.parse_version('1.7.0')
pylint_version = getattr(pylint, '__version__', '0.0.1')
_logger.runbot("pylint version: %s", pylint_version)
if tools.parse_version(pylint_version) < required_pylint_version:
self._skip_test('please upgrade pylint to >= %s' % required_pylint_version)
paths = {tools.config['root_path']}
for module in get_modules():
module_path = get_module_path(module)
if module_path.startswith(join(tools.config['root_path'], 'addons')):
continue
paths.add(module_path)
options = [
'--rcfile=%s' % os.devnull,
'--disable=all,useless-option-value',
'--enable=' + ','.join([
'used-before-assignment',
'undefined-variable',
'eval-used',
'unreachable',
'function-redefined',
# custom checkers
'sql-injection',
'gettext-variable',
'raise-unlink-override',
]),
'--reports=n',
"--msg-template='{msg} ({msg_id}) at {path}:{line}'",
'--load-plugins=' + ','.join([
"_pylint_path_setup",
"pylint.extensions.bad_builtin",
"_odoo_checker_sql_injection",
"_odoo_checker_gettext",
"_odoo_checker_unlink_override",
]),
'--bad-functions=input',
'--deprecated-modules=' + ','.join([
'csv',
'urllib',
'cgi',
*tools.constants.SUPPORTED_DEBUGGER,
]),
]
stdlib_prefixes = tuple({sys.prefix, sys.base_prefix, sys.exec_prefix, sys.base_exec_prefix})
pypath = os.pathsep.join([HERE, *(p for p in sys.path if not p.startswith(stdlib_prefixes))])
env = {
**os.environ,
"PYTHONPATH": pypath,
"ADDONS_PATH": os.pathsep.join(tools.config['addons_path']),
}
if os.name == 'posix' and platform.system() != 'Darwin':
# Pylint started failing at ~2.4g from time to time.
# Removing the memory limit will solve this issue for a while (runbot limit is arroung 5g)
def preexec():
import resource
resource.setrlimit(resource.RLIMIT_AS, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
else:
preexec = None
try:
r = subprocess.run(
[tools.which('pylint'), *options, *paths],
capture_output=True, text=True, env=env,
preexec_fn=preexec,
)
except (OSError, IOError):
self._skip_test('pylint executable not found in the path')
else:
if r.returncode:
self.fail(f"pylint test failed:\n\n{r.stdout}\n{r.stderr}".strip())
else:
_logger.debug("%s", r.stdout)