158 lines
4.0 KiB
Python
158 lines
4.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
|
|
|
import logging
|
|
try:
|
|
import pylint
|
|
except ImportError:
|
|
pylint = None
|
|
import subprocess
|
|
from distutils.version import LooseVersion
|
|
import os
|
|
from os.path import join
|
|
import sys
|
|
|
|
from flectra.tests.common import TransactionCase
|
|
from flectra import tools
|
|
from flectra.modules import get_modules, get_module_path
|
|
|
|
HERE = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class TestPyLint(TransactionCase):
|
|
|
|
ENABLED_CODES = [
|
|
'used-before-assignment',
|
|
'undefined-variable',
|
|
'eval-used',
|
|
'unreachable',
|
|
|
|
'mixed-indentation',
|
|
|
|
# py3k checks
|
|
'print-statement',
|
|
'backtick',
|
|
'next-method-called',
|
|
|
|
'misplaced-future',
|
|
'relative-import',
|
|
'deprecated-module',
|
|
'import-star-module-level',
|
|
|
|
'bad-builtin',
|
|
|
|
'dict-iter-method',
|
|
'dict-view-method',
|
|
|
|
'long-suffix',
|
|
'old-ne-operator',
|
|
'old-octal-operator',
|
|
'parameter-unpacking',
|
|
'invalid-string-codec',
|
|
|
|
'metaclass-assignment',
|
|
'deprecated-module',
|
|
|
|
'exception-message-attribute',
|
|
'indexing-exception',
|
|
'old-raise-syntax',
|
|
'raising-string',
|
|
'unpacking-in-except',
|
|
|
|
'no-comma-exception',
|
|
]
|
|
|
|
BAD_FUNCTIONS = [
|
|
'apply',
|
|
'cmp',
|
|
'coerce',
|
|
'execfile',
|
|
'input',
|
|
'intern',
|
|
'long',
|
|
'raw_input',
|
|
'reload',
|
|
'xrange',
|
|
'long',
|
|
'map',
|
|
'filter',
|
|
'zip',
|
|
|
|
'basestring',
|
|
'unichr',
|
|
'unicode',
|
|
|
|
'file',
|
|
'reduce',
|
|
]
|
|
|
|
BAD_MODULES = [
|
|
'commands',
|
|
'cPickle',
|
|
'csv',
|
|
'cStringIO',
|
|
'md5',
|
|
'urllib',
|
|
'urllib2',
|
|
'urlparse',
|
|
'sgmllib',
|
|
'sha',
|
|
'cgi',
|
|
'htmlentitydefs',
|
|
'HTMLParser',
|
|
'Queue',
|
|
'StringIO',
|
|
'UserDict',
|
|
'UserString',
|
|
'UserList',
|
|
] + list(tools.SUPPORTED_DEBUGGER)
|
|
|
|
def _skip_test(self, reason):
|
|
_logger.warn(reason)
|
|
self.skipTest(reason)
|
|
|
|
def test_pylint(self):
|
|
if pylint is None:
|
|
self._skip_test('please install pylint')
|
|
required_pylint_version = LooseVersion('1.6.4')
|
|
if sys.version_info >= (3, 6):
|
|
required_pylint_version = LooseVersion('1.7.0')
|
|
if LooseVersion(getattr(pylint, '__version__', '0.0.1')) < 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 not module_path.startswith(join(tools.config['root_path'], 'addons')):
|
|
paths.append(module_path)
|
|
|
|
options = [
|
|
'--rcfile=%s' % os.devnull,
|
|
'--disable=all',
|
|
'--enable=%s' % ','.join(self.ENABLED_CODES),
|
|
'--reports=n',
|
|
"--msg-template='{msg} ({msg_id}) at {path}:{line}'",
|
|
'--load-plugins=pylint.extensions.bad_builtin,_flectra_checkers',
|
|
'--bad-functions=%s' % ','.join(self.BAD_FUNCTIONS),
|
|
'--deprecated-modules=%s' % ','.join(self.BAD_MODULES)
|
|
]
|
|
|
|
pypath = HERE + os.pathsep + os.environ.get('PYTHONPATH', '')
|
|
env = dict(os.environ, PYTHONPATH=pypath)
|
|
try:
|
|
pylint_bin = tools.which('pylint')
|
|
process = subprocess.Popen(
|
|
[pylint_bin] + options + paths,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
env=env,
|
|
)
|
|
except (OSError, IOError):
|
|
self._skip_test('pylint executable not found in the path')
|
|
else:
|
|
out, err = process.communicate()
|
|
if process.returncode:
|
|
self.fail("pylint test failed:\n" + (b"\n" + out + b"\n" + err).decode('utf-8').strip())
|