Commit 48d6deba authored by Jérome Perrin's avatar Jérome Perrin

patchs/pylint: update for python3 support

this works with astroid 3.2.0 and pylint 3.2.0
parent aca9c72d
...@@ -159,16 +159,15 @@ class ComponentTool(BaseTool): ...@@ -159,16 +159,15 @@ class ComponentTool(BaseTool):
erp5.component.filesystem_import_dict = None erp5.component.filesystem_import_dict = None
erp5.component.ref_manager.gc() erp5.component.ref_manager.gc()
# Clear pylint cache # Clear astroid (pylint) cache
try: if six.PY2:
from astroid.builder import MANAGER from astroid.builder import MANAGER
except ImportError:
pass
else: else:
astroid_cache = MANAGER.astroid_cache from astroid.astroid_manager import MANAGER
for k in astroid_cache.keys(): astroid_cache = MANAGER.astroid_cache
if k.startswith('erp5.component.') and k not in component_package_list: for k in list(astroid_cache.keys()):
del astroid_cache[k] if k.startswith('erp5.component.') and k not in component_package_list:
del astroid_cache[k]
if reset_portal_type_at_transaction_boundary: if reset_portal_type_at_transaction_boundary:
portal.portal_types.resetDynamicDocumentsOnceAtTransactionBoundary() portal.portal_types.resetDynamicDocumentsOnceAtTransactionBoundary()
......
...@@ -419,15 +419,11 @@ def fill_args_from_request(*optional_args): ...@@ -419,15 +419,11 @@ def fill_args_from_request(*optional_args):
return decorator return decorator
_pylint_message_re = re.compile( _pylint_message_re = re.compile(
'^(?P<type>[CRWEF]):\s*(?P<row>\d+),\s*(?P<column>\d+):\s*(?P<message>.*)$') r'^(?P<type>[CRWEF]):\s*(?P<row>\d+),\s*(?P<column>\d+):\s*(?P<message>.*)$')
def checkPythonSourceCode(source_code_str, portal_type=None): def checkPythonSourceCode(source_code_str, portal_type=None):
""" """
Check source code with pylint or compile() builtin if not available. Check source code with pylint or compile() builtin if not available.
TODO-arnau: Get rid of NamedTemporaryFile (require a patch on pylint to
allow passing a string) and this should probably return a proper
ERP5 object rather than a dict...
""" """
if not source_code_str: if not source_code_str:
return [] return []
...@@ -462,8 +458,11 @@ def checkPythonSourceCode(source_code_str, portal_type=None): ...@@ -462,8 +458,11 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
message_list = [] message_list = []
output_file = StringIO() output_file = StringIO()
try: try:
with tempfile.NamedTemporaryFile(prefix='checkPythonSourceCode', with tempfile.NamedTemporaryFile(
suffix='.py') as input_file: prefix='checkPythonSourceCode',
suffix='.py',
mode='w',
) as input_file:
input_file.write(source_code_str) input_file.write(source_code_str)
input_file.flush() input_file.flush()
...@@ -493,6 +492,8 @@ def checkPythonSourceCode(source_code_str, portal_type=None): ...@@ -493,6 +492,8 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
# TODO-arnau: Enable it properly would require inspection API # TODO-arnau: Enable it properly would require inspection API
# '%s %r has no %r member' # '%s %r has no %r member'
'--disable=E1101,E1103', '--disable=E1101,E1103',
# XXX duplicate-bases causes too many false positives
'--disable=duplicate-bases',
# map and filter should not be considered bad as in some cases # map and filter should not be considered bad as in some cases
# map is faster than its recommended replacement (list # map is faster than its recommended replacement (list
# comprehension) # comprehension)
...@@ -508,7 +509,26 @@ def checkPythonSourceCode(source_code_str, portal_type=None): ...@@ -508,7 +509,26 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
# unused variables # unused variables
'--dummy-variables-rgx=_$|dummy|__traceback_info__|__traceback_supplement__', '--dummy-variables-rgx=_$|dummy|__traceback_info__|__traceback_supplement__',
] ]
if six.PY3:
args.extend(
(
"--msg-template='{C}: {line},{column}: {msg} ({symbol})'",
'--load-plugins=pylint.extensions.bad_builtin',
# BBB until we drop compatibility with PY2
'--disable=redundant-u-string-prefix,raise-missing-from,keyword-arg-before-vararg',
# XXX acceptable to ignore in the context of ERP5
'--disable=unspecified-encoding',
# XXX to many errors for now
'--disable=arguments-differ,arguments-renamed',
'--disable=duplicate-bases,inconsistent-mro',
)
)
else:
args.extend(
(
'--load-plugins=Products.ERP5Type.patches.pylint_compatibility_disable',
)
)
if portal_type == 'Interface Component': if portal_type == 'Interface Component':
# __init__ method from base class %r is not called # __init__ method from base class %r is not called
args.append('--disable=W0231') args.append('--disable=W0231')
...@@ -521,19 +541,18 @@ def checkPythonSourceCode(source_code_str, portal_type=None): ...@@ -521,19 +541,18 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
# Method should have "self" as first argument (no-self-argument) # Method should have "self" as first argument (no-self-argument)
args.append('--disable=E0213') args.append('--disable=E0213')
try:
from pylint.extensions.bad_builtin import __name__ as ext
args.append('--load-plugins=' + ext)
except ImportError:
pass
try: try:
# Note that we don't run pylint as a subprocess, but directly from # Note that we don't run pylint as a subprocess, but directly from
# ERP5 process, so that pylint can access the code from ERP5Type # ERP5 process, so that pylint can access the code from ERP5Type
# dynamic modules from ZODB. # dynamic modules from ZODB.
Run(args, reporter=TextReporter(output_file), exit=False) Run(args, reporter=TextReporter(output_file), exit=False)
finally: finally:
from astroid.builder import MANAGER if six.PY2:
MANAGER.astroid_cache.pop( from astroid.builder import MANAGER
else:
from astroid.astroid_manager import MANAGER
astroid_cache = MANAGER.astroid_cache
astroid_cache.pop(
os.path.splitext(os.path.basename(input_file.name))[0], os.path.splitext(os.path.basename(input_file.name))[0],
None) None)
......
...@@ -39,8 +39,7 @@ if getZopeVersion()[0] == 2: # BBB Zope2 ...@@ -39,8 +39,7 @@ if getZopeVersion()[0] == 2: # BBB Zope2
else: else:
IS_ZOPE2 = False IS_ZOPE2 = False
import six import six
if six.PY2: from .patches import pylint
from .patches import pylint
from zLOG import LOG, INFO from zLOG import LOG, INFO
DISPLAY_BOOT_PROCESS = False DISPLAY_BOOT_PROCESS = False
......
This diff is collapsed.
"""A dummy checker to register messages from pylint3, to be able to
disable the messages on python2 without causing bad-option-value
"""
from __future__ import absolute_import
from pylint import checkers, interfaces
class CompatibilityDisableChecker(checkers.BaseChecker):
name = "compatibility-disable"
msgs = {
"E9999": (
"not-an-iterable",
"not-an-iterable",
"",
),
"E9998": (
"misplaced-bare-raise",
"misplaced-bare-raise",
"",
),
"E9997": (
"unused-private-member",
"unused-private-member",
"",
),
"E9996": (
"using-constant-test",
"using-constant-test",
""
),
"E9995": (
"modified-iterating-list",
"modified-iterating-list",
"",
),
"E9994": (
"unsubscriptable-object",
"unsubscriptable-object",
"",
),
"E9993": (
"invalid-unary-operand-type",
"invalid-unary-operand-type",
"",
),
"E9992": (
"unbalanced-dict-unpacking",
"unbalanced-dict-unpacking",
"",
),
"E9991": (
"self-cls-assignment",
"self-cls-assignment",
"",
),
"E9990": (
"deprecated-class",
"deprecated-class",
"",
),
"E9989": (
"possibly-used-before-assignment",
"possibly-used-before-assignment",
""
)
}
def register(linter):
linter.register_checker(CompatibilityDisableChecker(linter))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment