Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Rafael Monnerat
erp5
Commits
9781e7f9
Commit
9781e7f9
authored
May 19, 2024
by
Jérome Perrin
Committed by
Arnaud Fontaine
Jul 05, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
patchs/pylint: update for python3 support
this works with astroid 3.2.0 and pylint 3.2.0
parent
72ec7d78
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
309 additions
and
125 deletions
+309
-125
product/ERP5Type/Tool/ComponentTool.py
product/ERP5Type/Tool/ComponentTool.py
+6
-10
product/ERP5Type/Utils.py
product/ERP5Type/Utils.py
+31
-11
product/ERP5Type/__init__.py
product/ERP5Type/__init__.py
+1
-2
product/ERP5Type/patches/pylint.py
product/ERP5Type/patches/pylint.py
+90
-46
product/ERP5Type/patches/pylint_compatibility_disable.py
product/ERP5Type/patches/pylint_compatibility_disable.py
+70
-0
product/ERP5Type/tests/testDynamicClassGeneration.py
product/ERP5Type/tests/testDynamicClassGeneration.py
+111
-56
No files found.
product/ERP5Type/Tool/ComponentTool.py
View file @
9781e7f9
...
@@ -159,16 +159,12 @@ class ComponentTool(BaseTool):
...
@@ -159,16 +159,12 @@ 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
:
from
astroid
import
MANAGER
from
astroid.builder
import
MANAGER
astroid_cache
=
MANAGER
.
astroid_cache
except
ImportError
:
for
k
in
list
(
astroid_cache
.
keys
()):
pass
if
k
.
startswith
(
'erp5.component.'
)
and
k
not
in
component_package_list
:
else
:
del
astroid_cache
[
k
]
astroid_cache
=
MANAGER
.
astroid_cache
for
k
in
astroid_cache
.
keys
():
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
()
...
...
product/ERP5Type/Utils.py
View file @
9781e7f9
...
@@ -419,7 +419,7 @@ def fill_args_from_request(*optional_args):
...
@@ -419,7 +419,7 @@ 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<
r
ow>
\
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
):
"""
"""
...
@@ -462,8 +462,11 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
...
@@ -462,8 +462,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 +496,8 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
...
@@ -493,6 +496,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 +513,26 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
...
@@ -508,7 +513,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 +545,15 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
...
@@ -521,19 +545,15 @@ 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
from
astroid
import
MANAGER
MANAGER
.
astroid_cache
.
pop
(
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
)
...
...
product/ERP5Type/__init__.py
View file @
9781e7f9
...
@@ -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
...
...
product/ERP5Type/patches/pylint.py
View file @
9781e7f9
...
@@ -19,9 +19,10 @@
...
@@ -19,9 +19,10 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
import
six
import
sys
import
sys
import
types
import
warnings
import
warnings
import
six
from
Products.ERP5Type
import
IS_ZOPE2
from
Products.ERP5Type
import
IS_ZOPE2
# TODO: make sure that trying to use it does not import isort, because the
# TODO: make sure that trying to use it does not import isort, because the
...
@@ -32,21 +33,21 @@ sys.modules.setdefault('isort', None)
...
@@ -32,21 +33,21 @@ sys.modules.setdefault('isort', None)
## All arguments are passed as arguments and this needlessly outputs a 'No
## All arguments are passed as arguments and this needlessly outputs a 'No
## config file found, using default configuration' message on stderr.
## config file found, using default configuration' message on stderr.
try
:
if
six
.
PY2
:
from
logilab.common.configuration
import
OptionsManagerMixIn
from
logilab.common.configuration
import
OptionsManagerMixIn
except
ImportError
:
OptionsManagerMixIn
.
read_config_file
=
lambda
*
args
,
**
kw
:
None
# pylint 2.x (python3)
from
pylint.config
import
OptionsManagerMixIn
OptionsManagerMixIn
.
read_config_file
=
lambda
*
args
,
**
kw
:
None
## Pylint transforms and plugin to generate AST for ZODB Components
## Pylint transforms and plugin to generate AST for ZODB Components
from
astroid.builder
import
AstroidBuilder
from
astroid.builder
import
AstroidBuilder
from
astroid.exceptions
import
AstroidBuildingException
if
six
.
PY2
:
from
astroid
import
MANAGER
,
node_classes
from
astroid.exceptions
import
AstroidBuildingException
as
AstroidBuildingError
else
:
from
astroid.exceptions
import
AstroidBuildingError
from
astroid
import
node_classes
from
astroid
import
MANAGER
try
:
if
six
.
PY2
:
from
astroid.builder
import
_guess_encoding
from
astroid.builder
import
_guess_encoding
except
ImportError
:
# XXX: With python3, tokenize.detect_encoding() is used instead. This
# XXX: With python3, tokenize.detect_encoding() is used instead. This
# should do the same instead of copying/pasting legacy code...
# should do the same instead of copying/pasting legacy code...
import
re
import
re
...
@@ -61,7 +62,7 @@ except ImportError:
...
@@ -61,7 +62,7 @@ except ImportError:
match
=
_ENCODING_RGX
.
match
(
line
)
match
=
_ENCODING_RGX
.
match
(
line
)
if
match
is
not
None
:
if
match
is
not
None
:
return
match
.
group
(
1
)
return
match
.
group
(
1
)
def
string_build
(
self
,
data
,
modname
=
''
,
path
=
None
):
def
string_build
(
self
,
data
,
modname
=
''
,
path
=
None
):
"""
"""
build astroid from source code string and return rebuilded astroid
build astroid from source code string and return rebuilded astroid
...
@@ -95,11 +96,11 @@ def string_build(self, data, modname='', path=None):
...
@@ -95,11 +96,11 @@ def string_build(self, data, modname='', path=None):
LOG
(
"Products.ERP5Type.patches.pylint"
,
WARNING
,
LOG
(
"Products.ERP5Type.patches.pylint"
,
WARNING
,
"%s: Considered as not importable: Wrong encoding? (%r)"
%
"%s: Considered as not importable: Wrong encoding? (%r)"
%
(
modname
,
exc
))
(
modname
,
exc
))
raise
AstroidBuildingE
xception
(
exc
)
raise
AstroidBuildingE
rror
(
exc
)
module
=
self
.
_data_build
(
data
,
modname
,
path
)
module
=
self
.
_data_build
(
data
,
modname
,
path
)
module
.
file_bytes
=
data
module
.
file_bytes
=
data
return
self
.
_post_build
(
module
,
encoding
)
return
self
.
_post_build
(
module
,
encoding
)
AstroidBuilder
.
string_build
=
string_build
AstroidBuilder
.
string_build
=
string_build
# patch node_classes.const_factory not to fail on LazyModules that e.g.
# patch node_classes.const_factory not to fail on LazyModules that e.g.
# pygolang installs for pytest and ipython into sys.modules dict:
# pygolang installs for pytest and ipython into sys.modules dict:
...
@@ -154,17 +155,17 @@ def _buildAstroidModuleFromComponentModuleName(modname):
...
@@ -154,17 +155,17 @@ def _buildAstroidModuleFromComponentModuleName(modname):
obj
=
getattr
(
component_tool
,
obj
=
getattr
(
component_tool
,
component_id
.
replace
(
'_version'
,
''
,
1
))
component_id
.
replace
(
'_version'
,
''
,
1
))
except
AttributeError
:
except
AttributeError
:
raise
AstroidBuildingE
xception
()
raise
AstroidBuildingE
rror
()
if
obj
.
getValidationState
()
in
(
'modified'
,
'validated'
):
if
obj
.
getValidationState
()
in
(
'modified'
,
'validated'
):
component_obj
=
obj
component_obj
=
obj
else
:
else
:
raise
AstroidBuildingE
xception
()
raise
AstroidBuildingE
rror
()
else
:
else
:
try
:
try
:
package
,
reference
=
component_id
.
split
(
'.'
,
1
)
package
,
reference
=
component_id
.
split
(
'.'
,
1
)
except
ValueError
:
except
ValueError
:
raise
AstroidBuildingE
xception
()
raise
AstroidBuildingE
rror
()
for
version
in
portal
.
getVersionPriorityNameList
():
for
version
in
portal
.
getVersionPriorityNameList
():
try
:
try
:
obj
=
getattr
(
component_tool
,
obj
=
getattr
(
component_tool
,
...
@@ -183,11 +184,8 @@ def _buildAstroidModuleFromComponentModuleName(modname):
...
@@ -183,11 +184,8 @@ def _buildAstroidModuleFromComponentModuleName(modname):
return
module
return
module
if
component_obj
is
None
:
if
component_obj
is
None
:
raise
AstroidBuildingE
xception
()
raise
AstroidBuildingE
rror
()
# module_build() could also be used but this requires importing
# the ZODB Component and also monkey-patch it to support PEP-302
# for __file__ starting with '<'
module
=
AstroidBuilder
(
MANAGER
).
string_build
(
module
=
AstroidBuilder
(
MANAGER
).
string_build
(
component_obj
.
getTextContent
(
validated_only
=
True
),
component_obj
.
getTextContent
(
validated_only
=
True
),
modname
)
modname
)
...
@@ -195,7 +193,7 @@ def _buildAstroidModuleFromComponentModuleName(modname):
...
@@ -195,7 +193,7 @@ def _buildAstroidModuleFromComponentModuleName(modname):
def
fail_hook_erp5_component
(
modname
):
def
fail_hook_erp5_component
(
modname
):
if
not
modname
.
startswith
(
'erp5.'
):
if
not
modname
.
startswith
(
'erp5.'
):
raise
AstroidBuildingE
xception
()
raise
AstroidBuildingE
rror
()
if
(
modname
in
(
'erp5.portal_type'
,
if
(
modname
in
(
'erp5.portal_type'
,
'erp5.component'
,
'erp5.component'
,
...
@@ -223,8 +221,11 @@ MANAGER.register_failed_import_hook(fail_hook_erp5_component)
...
@@ -223,8 +221,11 @@ MANAGER.register_failed_import_hook(fail_hook_erp5_component)
## transforms but this would require either checking dynamically which
## transforms but this would require either checking dynamically which
## attributes has been added (much more complex than the current approach)
## attributes has been added (much more complex than the current approach)
## or listing them statically (inconvenient).
## or listing them statically (inconvenient).
from
astroid.exceptions
import
NotFoundError
from
astroid.exceptions
import
AstroidError
,
NotFoundError
from
astroid.scoped_nodes
import
Module
if
six
.
PY2
:
from
astroid.scoped_nodes
import
Module
else
:
from
astroid.nodes
import
Module
Module_getattr
=
Module
.
getattr
Module_getattr
=
Module
.
getattr
def
_getattr
(
self
,
name
,
*
args
,
**
kw
):
def
_getattr
(
self
,
name
,
*
args
,
**
kw
):
try
:
try
:
...
@@ -232,8 +233,22 @@ def _getattr(self, name, *args, **kw):
...
@@ -232,8 +233,22 @@ def _getattr(self, name, *args, **kw):
except
NotFoundError
as
e
:
except
NotFoundError
as
e
:
if
self
.
name
.
startswith
(
'erp5.'
):
if
self
.
name
.
startswith
(
'erp5.'
):
raise
raise
if
six
.
PY3
and
(
real_module
=
__import__
(
self
.
name
,
fromlist
=
[
self
.
name
],
level
=
0
)
# astroid/pylint on py3 have built-in support for numpy
self
.
name
==
'numpy'
or
self
.
name
.
startswith
(
'numpy.'
)
# SOAPPy.Types contains "from SOAPPy.Types import *" which confuses
# this patch
or
self
.
name
==
'SOAPpy.Types'
# pysvn also confuses pylint
or
self
.
name
==
'pysvn'
# XXX actually maybe we don't need this branch at all on py3
):
raise
real_module
=
__import__
(
self
.
name
,
fromlist
=
[
self
.
name
]
if
six
.
PY2
else
[
name
],
level
=
0
)
try
:
try
:
attr
=
getattr
(
real_module
,
name
)
attr
=
getattr
(
real_module
,
name
)
except
AttributeError
:
except
AttributeError
:
...
@@ -249,13 +264,21 @@ def _getattr(self, name, *args, **kw):
...
@@ -249,13 +264,21 @@ def _getattr(self, name, *args, **kw):
except
AttributeError
:
except
AttributeError
:
from
astroid
import
nodes
from
astroid
import
nodes
if
isinstance
(
attr
,
dict
):
if
isinstance
(
attr
,
dict
):
ast
=
nodes
.
Dict
(
attr
)
if
six
.
PY2
:
ast
=
nodes
.
Dict
(
attr
)
else
:
ast
=
nodes
.
Dict
(
attr
,
0
,
None
,
end_lineno
=
0
,
end_col_offset
=
0
)
elif
isinstance
(
attr
,
list
):
elif
isinstance
(
attr
,
list
):
ast
=
nodes
.
List
(
attr
)
ast
=
nodes
.
List
(
attr
)
elif
isinstance
(
attr
,
tuple
):
elif
isinstance
(
attr
,
tuple
):
ast
=
nodes
.
Tuple
(
attr
)
ast
=
nodes
.
Tuple
(
attr
)
elif
isinstance
(
attr
,
set
):
elif
isinstance
(
attr
,
set
):
ast
=
nodes
.
Set
(
attr
)
if
six
.
PY2
:
ast
=
nodes
.
Set
(
attr
)
else
:
ast
=
nodes
.
Set
(
attr
,
0
,
None
,
end_lineno
=
0
,
end_col_offset
=
0
)
elif
isinstance
(
attr
,
types
.
ModuleType
):
ast
=
MANAGER
.
ast_from_module
(
attr
)
else
:
else
:
try
:
try
:
ast
=
nodes
.
Const
(
attr
)
ast
=
nodes
.
Const
(
attr
)
...
@@ -266,16 +289,29 @@ def _getattr(self, name, *args, **kw):
...
@@ -266,16 +289,29 @@ def _getattr(self, name, *args, **kw):
raise
raise
# ast_from_class() actually works for any attribute of a Module
# ast_from_class() actually works for any attribute of a Module
# (on py2 at least), but it raises some AssertionError when the class
# is defined dynamically, for example with zope.hookable.hookable,
# which (in version 6.0) is defined as:
#
# if _PURE_PYTHON or _c_hookable is None:
# hookable = _py_hookable
# else: # pragma: no cover
# hookable = _c_hookable
try
:
try
:
ast
=
MANAGER
.
ast_from_class
(
attr
)
ast
=
MANAGER
.
ast_from_class
(
attr
)
except
AstroidBuildingException
:
except
(
AstroidError
,
AssertionError
):
raise
e
if
six
.
PY2
:
raise
e
try
:
ast
=
next
(
MANAGER
.
infer_ast_from_something
(
attr
))
except
AstroidError
:
raise
e
self
.
locals
[
name
]
=
[
ast
]
self
.
locals
[
name
]
=
[
ast
]
return
[
ast
]
return
[
ast
]
Module
.
getattr
=
_getattr
Module
.
getattr
=
_getattr
if
s
ys
.
version_info
<
(
2
,
8
)
:
if
s
ix
.
PY2
:
from
astroid.node_classes
import
From
from
astroid.node_classes
import
From
def
_absolute_import_activated
(
self
):
def
_absolute_import_activated
(
self
):
if
(
self
.
name
.
startswith
(
'checkPythonSourceCode'
)
or
if
(
self
.
name
.
startswith
(
'checkPythonSourceCode'
)
or
...
@@ -292,25 +328,25 @@ from astroid import register_module_extender
...
@@ -292,25 +328,25 @@ from astroid import register_module_extender
def
AccessControl_PermissionRole_transform
():
def
AccessControl_PermissionRole_transform
():
return
AstroidBuilder
(
MANAGER
).
string_build
(
'''
return
AstroidBuilder
(
MANAGER
).
string_build
(
'''
def rolesForPermissionOn(perm, object, default=_default_roles, n=None):
def rolesForPermissionOn(perm, object, default=_default_roles, n=None):
return
None
return
tuple()
class PermissionRole(object):
class PermissionRole(object):
def __init__(self, name, default=('Manager',)):
def __init__(self, name, default=('Manager',)):
return None
return None
def __of__(self, parent):
def __of__(self, parent):
return
None
return
imPermissionRole(self)
def rolesForPermissionOn(self, value):
def rolesForPermissionOn(self, value):
return
None
return
self.rolesForPermissionOn(None, self)
class imPermissionRole(object):
class imPermissionRole(object):
def __of__(self, value):
def __of__(self, value):
return
None
return
self.rolesForPermissionOn(None, self)
def rolesForPermissionOn(self, value):
def rolesForPermissionOn(self, value):
return
None
return
rolesForPermissionOn(None, self)
def __getitem__(self, i):
def __getitem__(self, i):
return None
return None
def __len__(self):
def __len__(self):
return
None
return
0
_what_not_even_god_should_do = []
_what_not_even_god_should_do = []
'''
)
'''
)
...
@@ -338,14 +374,14 @@ def build_stub(parent, identifier_re=r'^[A-Za-z_]\w*$'):
...
@@ -338,14 +374,14 @@ def build_stub(parent, identifier_re=r'^[A-Za-z_]\w*$'):
constants = {}
constants = {}
methods = {}
methods = {}
for name in dir(parent):
for name in dir(parent):
if name
.startswith("__"
):
if name
in dir(object
):
continue
continue
# Check if this is a valid name in python
# Check if this is a valid name in python
if not re.match(identifier_re, name):
if not re.match(identifier_re, name):
continue
continue
try:
try:
obj = getattr(parent, name)
obj = getattr(parent, name)
except:
except
AttributeError
:
continue
continue
if inspect.isclass(obj):
if inspect.isclass(obj):
classes[name] = obj
classes[name] = obj
...
@@ -422,7 +458,7 @@ _inspected_modules = {}
...
@@ -422,7 +458,7 @@ _inspected_modules = {}
def fail_hook_BTrees(modname):
def fail_hook_BTrees(modname):
# Only consider BTrees.OOBTree pattern
# Only consider BTrees.OOBTree pattern
if not modname.startswith('
BTrees
.
') or len(modname.split('
.
')) != 2:
if not modname.startswith('
BTrees
.
') or len(modname.split('
.
')) != 2:
raise AstroidBuildingE
xception
()
raise AstroidBuildingE
rror
()
if modname not in _inspected_modules:
if modname not in _inspected_modules:
try:
try:
modcode = build_stub(
modcode = build_stub(
...
@@ -438,7 +474,7 @@ def fail_hook_BTrees(modname):
...
@@ -438,7 +474,7 @@ def fail_hook_BTrees(modname):
else:
else:
astng = _inspected_modules[modname]
astng = _inspected_modules[modname]
if astng is None:
if astng is None:
raise AstroidBuildingE
xception
('
Failed
to
import
module
%
r' % modname)
raise AstroidBuildingE
rror
('
Failed
to
import
module
%
r' % modname)
return astng
return astng
MANAGER.register_failed_import_hook(fail_hook_BTrees)
MANAGER.register_failed_import_hook(fail_hook_BTrees)
...
@@ -484,12 +520,20 @@ def register_xpkg(pkgname):
...
@@ -484,12 +520,20 @@ def register_xpkg(pkgname):
except ImportError:
except ImportError:
pass
pass
else:
else:
def xpkg_transform(node):
if six.PY2:
m = AstroidBuilder(MANAGER).string_build('
__path__
=
%
r' % pkg.__path__)
def xpkg_transform(node):
m.package = True
m = AstroidBuilder(MANAGER).string_build('
__path__
=
%
r' % pkg.__path__)
m.name = pkgname
m.package = True
return m
m.name = pkgname
MANAGER.register_transform(Module, xpkg_transform, lambda node: node.name == pkgname)
return m
MANAGER.register_transform(Module, xpkg_transform, lambda node: node.name == pkgname)
else:
import importlib
def fail_hook_xpkg(modname):
if modname.split('
.
')[0] == pkgname:
return MANAGER.ast_from_module(importlib.import_module(modname))
raise AstroidBuildingError()
MANAGER.register_failed_import_hook(fail_hook_xpkg)
register_xpkg('
wendelin
')
register_xpkg('
wendelin
')
register_xpkg('
xlte
')
register_xpkg('
xlte
')
...
...
product/ERP5Type/patches/pylint_compatibility_disable.py
0 → 100644
View file @
9781e7f9
"""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
))
product/ERP5Type/tests/testDynamicClassGeneration.py
View file @
9781e7f9
...
@@ -1899,11 +1899,18 @@ class TestZodbModuleComponent(SecurityTestCase):
...
@@ -1899,11 +1899,18 @@ class TestZodbModuleComponent(SecurityTestCase):
component
.
setTextContent
(
"""import unexistent_module
component
.
setTextContent
(
"""import unexistent_module
"""
+
valid_code
)
"""
+
valid_code
)
self
.
tic
()
self
.
tic
()
self
.
assertEqual
(
if
six
.
PY2
:
[
m
.
getMessage
().
translate
()
for
m
in
component
.
checkConsistency
()],
self
.
assertEqual
(
[
"Error in Source Code: F: 1, 0: Unable to import 'unexistent_module' (import-error)"
])
[
m
.
getMessage
().
translate
()
for
m
in
component
.
checkConsistency
()],
self
.
assertEqual
(
component
.
getTextContentErrorMessageList
(),
[
"Error in Source Code: F: 1, 0: Unable to import 'unexistent_module' (import-error)"
])
[
"F: 1, 0: Unable to import 'unexistent_module' (import-error)"
])
self
.
assertEqual
(
component
.
getTextContentErrorMessageList
(),
[
"F: 1, 0: Unable to import 'unexistent_module' (import-error)"
])
else
:
self
.
assertEqual
(
[
m
.
getMessage
().
translate
()
for
m
in
component
.
checkConsistency
()],
[
"Error in Source Code: E: 1, 0: Unable to import 'unexistent_module' (import-error)"
])
self
.
assertEqual
(
component
.
getTextContentErrorMessageList
(),
[
"E: 1, 0: Unable to import 'unexistent_module' (import-error)"
])
self
.
assertEqual
(
component
.
getTextContentWarningMessageList
(),
self
.
assertEqual
(
component
.
getTextContentWarningMessageList
(),
[
"W: 1, 0: Unused import unexistent_module (unused-import)"
])
[
"W: 1, 0: Unused import unexistent_module (unused-import)"
])
...
@@ -1935,11 +1942,10 @@ class TestZodbModuleComponent(SecurityTestCase):
...
@@ -1935,11 +1942,10 @@ class TestZodbModuleComponent(SecurityTestCase):
[
ComponentMixin
.
_message_text_content_not_set
],
[
ComponentMixin
.
_message_text_content_not_set
],
[],
[],
[]),
[]),
(
"""def foobar(*args, **kwargs)
(
"""None()
return 42
"""
+
valid_code
,
"""
+
valid_code
,
[
"Error in Source Code: E: 1, 0:
invalid syntax (syntax-error
)"
],
[
"Error in Source Code: E: 1, 0:
None is not callable (not-callable
)"
],
[
"E: 1, 0:
invalid syntax (syntax-error
)"
],
[
"E: 1, 0:
None is not callable (not-callable
)"
],
[]),
[]),
# Make sure that foobar NameError is at the end to make sure that after
# Make sure that foobar NameError is at the end to make sure that after
# defining foobar function, it is not available at all
# defining foobar function, it is not available at all
...
@@ -2209,7 +2215,7 @@ def function_foo(*args, **kwargs):
...
@@ -2209,7 +2215,7 @@ def function_foo(*args, **kwargs):
def
_assertAstroidCacheContent
(
self
,
def
_assertAstroidCacheContent
(
self
,
must_be_in_cache_set
,
must_be_in_cache_set
,
must_not_be_in_cache_set
):
must_not_be_in_cache_set
):
from
astroid
.builder
import
MANAGER
from
astroid
import
MANAGER
should_not_be_in_cache_list
=
[]
should_not_be_in_cache_list
=
[]
for
modname
in
MANAGER
.
astroid_cache
:
for
modname
in
MANAGER
.
astroid_cache
:
if
(
modname
.
startswith
(
'checkPythonSourceCode'
)
or
if
(
modname
.
startswith
(
'checkPythonSourceCode'
)
or
...
@@ -2265,10 +2271,10 @@ def hoge():
...
@@ -2265,10 +2271,10 @@ def hoge():
"""# -*- coding: utf-8 -*-
"""# -*- coding: utf-8 -*-
# Source code with non-ASCII character should not fail: éàホゲ
# Source code with non-ASCII character should not fail: éàホゲ
from %(namespace)s import %(reference1)s
from %(namespace)s import %(reference1)s
from %(namespace)s.erp5_version import %(reference1)s
from %(namespace)s.erp5_version import %(reference1)s
# pylint:disable=reimported
from %(module2)s import hoge
from %(module2)s import hoge
from %(module2_with_version)s import hoge
from %(module2_with_version)s import hoge
# pylint:disable=reimported
import %(module2)s
import %(module2)s
import %(module2_with_version)s
import %(module2_with_version)s
...
@@ -2293,7 +2299,8 @@ from AccessControl.PermissionRole import rolesForPermissionOn, PermissionRole, i
...
@@ -2293,7 +2299,8 @@ from AccessControl.PermissionRole import rolesForPermissionOn, PermissionRole, i
# Monkey patch of astroid 1.3.8: it raised 'no-name-in-module' because
# Monkey patch of astroid 1.3.8: it raised 'no-name-in-module' because
# Shared.DC was not considered a namespace package
# Shared.DC was not considered a namespace package
from Shared.DC.ZRDB.Results import Results # pylint: disable=unused-import
from Shared.DC.ZRDB.Results import Results
_ = Results
import lxml.etree
import lxml.etree
lxml.etree.Element('test')
lxml.etree.Element('test')
...
@@ -2340,17 +2347,21 @@ _ = ZBigArray
...
@@ -2340,17 +2347,21 @@ _ = ZBigArray
module2_with_version
=
imported_module2_with_version
))
+
module2_with_version
=
imported_module2_with_version
))
+
component
.
getTextContent
())
component
.
getTextContent
())
must_be_in_cache_set
=
set
()
if
six
.
PY2
:
must_be_in_cache_set
.
add
(
namespace
)
self
.
_assertAstroidCacheContent
(
self
.
_assertAstroidCacheContent
(
must_be_in_cache_set
=
{
'%s'
%
namespace
}
,
must_be_in_cache_set
=
must_be_in_cache_set
,
must_not_be_in_cache_set
=
{
'%s.erp5_version'
%
namespace
,
must_not_be_in_cache_set
=
{
'%s.erp5_version'
%
namespace
,
imported_module1
,
imported_module1
,
imported_module1_with_version
,
imported_module1_with_version
,
imported_module2
,
imported_module2
,
imported_module2_with_version
})
imported_module2_with_version
})
component
.
checkSourceCode
()
component
.
checkSourceCode
()
if
six
.
PY2
:
must_be_in_cache_set
.
add
(
'%s.erp5_version'
%
namespace
)
self
.
_assertAstroidCacheContent
(
self
.
_assertAstroidCacheContent
(
must_be_in_cache_set
=
{
'%s'
%
namespace
,
must_be_in_cache_set
=
must_be_in_cache_set
,
'%s.erp5_version'
%
namespace
},
must_not_be_in_cache_set
=
{
imported_module1
,
must_not_be_in_cache_set
=
{
imported_module1
,
imported_module1_with_version
,
imported_module1_with_version
,
imported_module2
,
imported_module2
,
...
@@ -2358,35 +2369,69 @@ _ = ZBigArray
...
@@ -2358,35 +2369,69 @@ _ = ZBigArray
self
.
tic
()
self
.
tic
()
self
.
assertEqual
(
component
.
getValidationState
(),
'modified'
)
self
.
assertEqual
(
component
.
getValidationState
(),
'modified'
)
self
.
assertEqual
(
if
six
.
PY2
:
component
.
getTextContentErrorMessageList
(),
self
.
assertEqual
(
[
"E: 3, 0: No name '%s' in module '%s' (no-name-in-module)"
%
component
.
getTextContentErrorMessageList
(),
(
imported_reference1
,
namespace
),
[
"E: 4, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
"E: 3, 0: No name '%s' in module '%s' (no-name-in-module)"
%
(
imported_reference1
,
namespace
),
(
imported_reference1
,
namespace
),
# Spurious message but same as filesystem modules: 2 errors raised
"E: 4, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
# (no-name-in-module and import-error)
(
imported_reference1
,
namespace
),
"E: 6, 0: No name '%s' in module '%s' (no-name-in-module)"
%
# Spurious message but same as filesystem modules: 2 errors raised
(
imported_reference2
,
namespace
),
# (no-name-in-module and import-error)
"F: 6, 0: Unable to import '%s' (import-error)"
%
"E: 6, 0: No name '%s' in module '%s' (no-name-in-module)"
%
imported_module2
,
(
imported_reference2
,
namespace
),
# Spurious message (see above comment)
"F: 6, 0: Unable to import '%s' (import-error)"
%
"E: 7, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
imported_module2
,
(
imported_reference2
,
namespace
),
# Spurious message (see above comment)
"F: 7, 0: Unable to import '%s' (import-error)"
%
"E: 7, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
imported_module2_with_version
,
(
imported_reference2
,
namespace
),
# Spurious message (see above comment)
"F: 7, 0: Unable to import '%s' (import-error)"
%
"E: 9, 0: No name '%s' in module '%s' (no-name-in-module)"
%
imported_module2_with_version
,
(
imported_reference2
,
namespace
),
# Spurious message (see above comment)
"F: 9, 0: Unable to import '%s' (import-error)"
%
"E: 9, 0: No name '%s' in module '%s' (no-name-in-module)"
%
imported_module2
,
(
imported_reference2
,
namespace
),
# Spurious message (see above comment)
"F: 9, 0: Unable to import '%s' (import-error)"
%
"E: 10, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
imported_module2
,
(
imported_reference2
,
namespace
),
# Spurious message (see above comment)
"F: 10, 0: Unable to import '%s' (import-error)"
%
"E: 10, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
imported_module2_with_version
])
(
imported_reference2
,
namespace
),
"F: 10, 0: Unable to import '%s' (import-error)"
%
imported_module2_with_version
,
],
)
else
:
self
.
assertEqual
(
component
.
getTextContentErrorMessageList
(),
[
"E: 3, 0: No name '%s' in module '%s' (no-name-in-module)"
%
(
imported_reference1
,
namespace
),
"E: 4, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
(
imported_reference1
,
namespace
),
"E: 6, 0: Unable to import '%s.%s' (import-error)"
%
(
namespace
,
imported_reference2
),
# Spurious message but same as filesystem modules: 2 errors raised
# (no-name-in-module and import-error)
"E: 6, 0: No name '%s' in module '%s' (no-name-in-module)"
%
(
imported_reference2
,
namespace
),
"E: 7, 0: Unable to import '%s' (import-error)"
%
imported_module2_with_version
,
# Spurious message (see above comment)
"E: 7, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
(
imported_reference2
,
namespace
),
"E: 9, 0: Unable to import '%s.%s' (import-error)"
%
(
namespace
,
imported_reference2
),
# Spurious message (see above comment)
"E: 9, 0: No name '%s' in module '%s' (no-name-in-module)"
%
(
imported_reference2
,
namespace
),
"E: 10, 0: Unable to import '%s' (import-error)"
%
imported_module2_with_version
,
# Spurious message (see above comment)
"E: 10, 0: No name '%s' in module '%s.erp5_version' (no-name-in-module)"
%
(
imported_reference2
,
namespace
),
],
)
self
.
assertEqual
(
component
.
getTextContentWarningMessageList
(),
[])
self
.
assertEqual
(
component
.
getTextContentWarningMessageList
(),
[])
## Simulate user:
## Simulate user:
# 1) First check and validate 'imported' Components
# 1) First check and validate 'imported' Components
self
.
portal
.
portal_workflow
.
doActionFor
(
imported_component1
,
'validate_action'
)
self
.
portal
.
portal_workflow
.
doActionFor
(
imported_component1
,
'validate_action'
)
...
@@ -2397,20 +2442,29 @@ _ = ZBigArray
...
@@ -2397,20 +2442,29 @@ _ = ZBigArray
message_list
=
component
.
checkSourceCode
()
message_list
=
component
.
checkSourceCode
()
self
.
assertEqual
(
message_list
,
[])
self
.
assertEqual
(
message_list
,
[])
must_be_in_cache_set
=
{
imported_module1
,
imported_module1_with_version
,
imported_module2
,
imported_module2_with_version
,
}
if
six
.
PY2
:
must_be_in_cache_set
.
update
({
'%s'
%
namespace
,
'%s.erp5_version'
%
namespace
,
})
self
.
_assertAstroidCacheContent
(
self
.
_assertAstroidCacheContent
(
must_be_in_cache_set
=
{
'%s'
%
namespace
,
must_be_in_cache_set
=
must_be_in_cache_set
,
'%s.erp5_version'
%
namespace
,
imported_module1
,
imported_module1_with_version
,
imported_module2
,
imported_module2_with_version
},
must_not_be_in_cache_set
=
set
())
must_not_be_in_cache_set
=
set
())
# 2) Then modify the main one so that it automatically 'validate'
# 2) Then modify the main one so that it automatically 'validate'
component
.
setTextContent
(
component
.
getTextContent
()
+
'
\
n
'
)
component
.
setTextContent
(
component
.
getTextContent
()
+
'
\
n
'
)
self
.
tic
()
self
.
tic
()
must_be_in_cache_set
=
set
()
if
six
.
PY2
:
must_be_in_cache_set
.
add
(
namespace
)
self
.
_assertAstroidCacheContent
(
self
.
_assertAstroidCacheContent
(
must_be_in_cache_set
=
{
'%s'
%
namespace
}
,
must_be_in_cache_set
=
must_be_in_cache_set
,
must_not_be_in_cache_set
=
{
'%s.erp5_version'
%
namespace
,
must_not_be_in_cache_set
=
{
'%s.erp5_version'
%
namespace
,
imported_module1
,
imported_module1
,
imported_module1_with_version
,
imported_module1_with_version
,
...
@@ -2423,10 +2477,11 @@ _ = ZBigArray
...
@@ -2423,10 +2477,11 @@ _ = ZBigArray
component
.
setTextContent
(
component
.
setTextContent
(
"""# -*- coding: utf-8 -*-
"""# -*- coding: utf-8 -*-
from %(module)s import undefined
from %(module)s import undefined
from %(module_with_version)s import undefined
from %(module_with_version)s import undefined
2
# To avoid 'unused-import' warning...
# To avoid 'unused-import' warning...
undefined()
undefined()
undefined2()
"""
%
(
dict
(
module
=
imported_module2
,
"""
%
(
dict
(
module
=
imported_module2
,
module_with_version
=
imported_module2_with_version
))
+
module_with_version
=
imported_module2_with_version
))
+
...
@@ -2437,7 +2492,7 @@ undefined()
...
@@ -2437,7 +2492,7 @@ undefined()
component
.
getTextContentErrorMessageList
(),
component
.
getTextContentErrorMessageList
(),
[
"E: 2, 0: No name 'undefined' in module '%s' (no-name-in-module)"
%
[
"E: 2, 0: No name 'undefined' in module '%s' (no-name-in-module)"
%
imported_module2_with_version
,
imported_module2_with_version
,
"E: 3, 0: No name 'undefined' in module '%s' (no-name-in-module)"
%
"E: 3, 0: No name 'undefined
2
' in module '%s' (no-name-in-module)"
%
imported_module2_with_version
])
imported_module2_with_version
])
self
.
assertEqual
(
component
.
getTextContentWarningMessageList
(),
[])
self
.
assertEqual
(
component
.
getTextContentWarningMessageList
(),
[])
...
@@ -2473,8 +2528,8 @@ def hoge():
...
@@ -2473,8 +2528,8 @@ def hoge():
component
=
self
.
_newComponent
(
reference
)
component
=
self
.
_newComponent
(
reference
)
component
.
setTextContent
(
component
.
getTextContent
()
+
"""
component
.
setTextContent
(
component
.
getTextContent
()
+
"""
from %(namespace)s import %(reference)s
from %(namespace)s import %(reference)s
from %(namespace)s.bar_version import %(reference)s
from %(namespace)s.bar_version import %(reference)s
# pylint:disable=reimported
from %(namespace)s.erp5_version import %(reference)s
from %(namespace)s.erp5_version import %(reference)s
# pylint:disable=reimported
# To avoid 'unused-import' warning...
# To avoid 'unused-import' warning...
%(reference)s.hoge()
%(reference)s.hoge()
...
@@ -2482,7 +2537,7 @@ from %(namespace)s.erp5_version import %(reference)s
...
@@ -2482,7 +2537,7 @@ from %(namespace)s.erp5_version import %(reference)s
reference
=
imported_reference
))
reference
=
imported_reference
))
component
.
checkSourceCode
()
component
.
checkSourceCode
()
from
astroid
.builder
import
MANAGER
from
astroid
import
MANAGER
imported_module
=
self
.
_getComponentFullModuleName
(
imported_reference
)
imported_module
=
self
.
_getComponentFullModuleName
(
imported_reference
)
self
.
assertEqual
(
self
.
assertEqual
(
MANAGER
.
astroid_cache
[
self
.
_getComponentFullModuleName
(
imported_reference
,
version
=
'bar'
)],
MANAGER
.
astroid_cache
[
self
.
_getComponentFullModuleName
(
imported_reference
,
version
=
'bar'
)],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment