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
Labels
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Jérome Perrin
erp5
Commits
5f1f54ca
Commit
5f1f54ca
authored
Mar 28, 2024
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ERP5Type: more pylint / astroid fixes
parent
487f1fff
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
98 deletions
+164
-98
product/ERP5Type/Tool/ComponentTool.py
product/ERP5Type/Tool/ComponentTool.py
+1
-2
product/ERP5Type/Utils.py
product/ERP5Type/Utils.py
+9
-8
product/ERP5Type/__init__.py
product/ERP5Type/__init__.py
+1
-2
product/ERP5Type/patches/pylint.py
product/ERP5Type/patches/pylint.py
+61
-36
product/ERP5Type/tests/testDynamicClassGeneration.py
product/ERP5Type/tests/testDynamicClassGeneration.py
+92
-50
No files found.
product/ERP5Type/Tool/ComponentTool.py
View file @
5f1f54ca
...
@@ -163,8 +163,7 @@ class ComponentTool(BaseTool):
...
@@ -163,8 +163,7 @@ class ComponentTool(BaseTool):
if
six
.
PY2
:
if
six
.
PY2
:
from
astroid.builder
import
MANAGER
from
astroid.builder
import
MANAGER
else
:
else
:
from
astroid.builder
import
AstroidManager
from
astroid.astroid_manager
import
MANAGER
MANAGER
=
AstroidManager
()
astroid_cache
=
MANAGER
.
astroid_cache
astroid_cache
=
MANAGER
.
astroid_cache
for
k
in
list
(
astroid_cache
.
keys
()):
for
k
in
list
(
astroid_cache
.
keys
()):
if
k
.
startswith
(
'erp5.component.'
)
and
k
not
in
component_package_list
:
if
k
.
startswith
(
'erp5.component.'
)
and
k
not
in
component_package_list
:
...
...
product/ERP5Type/Utils.py
View file @
5f1f54ca
...
@@ -467,10 +467,6 @@ _pylint_message_re = re.compile(
...
@@ -467,10 +467,6 @@ _pylint_message_re = re.compile(
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
[]
...
@@ -555,7 +551,13 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
...
@@ -555,7 +551,13 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
'--dummy-variables-rgx=_$|dummy|__traceback_info__|__traceback_supplement__'
,
'--dummy-variables-rgx=_$|dummy|__traceback_info__|__traceback_supplement__'
,
]
]
if
six
.
PY3
:
if
six
.
PY3
:
args
.
append
(
"--msg-template='{C}: {line},{column}: {msg} ({symbol})'"
)
args
.
extend
(
(
"--msg-template='{C}: {line},{column}: {msg} ({symbol})'"
,
# BBB until we drop compatibility with PY2
"--disable=redundant-u-string-prefix,raise-missing-from"
,
)
)
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'
)
...
@@ -581,10 +583,9 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
...
@@ -581,10 +583,9 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
finally
:
finally
:
if
six
.
PY2
:
if
six
.
PY2
:
from
astroid.builder
import
MANAGER
from
astroid.builder
import
MANAGER
astroid_cache
=
MANAGER
.
astroid_cache
else
:
else
:
from
astroid.
manager
import
AstroidManager
from
astroid.
astroid_manager
import
MANAGER
astroid_cache
=
AstroidManager
()
.
astroid_cache
astroid_cache
=
MANAGER
.
astroid_cache
astroid_cache
.
pop
(
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 @
5f1f54ca
...
@@ -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 @
5f1f54ca
...
@@ -19,9 +19,11 @@
...
@@ -19,9 +19,11 @@
# 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
importlib
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,27 +34,21 @@ sys.modules.setdefault('isort', None)
...
@@ -32,27 +34,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
from
astroid
import
node_classes
if
six
.
PY2
:
if
six
.
PY2
:
from
astroid
import
MANAGER
from
astroid.exceptions
import
AstroidBuildingException
as
AstroidBuildingError
else
:
else
:
from
astroid
import
AstroidManager
from
astroid.exceptions
import
AstroidBuildingError
MANAGER
=
AstroidManager
()
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
...
@@ -67,7 +63,7 @@ except ImportError:
...
@@ -67,7 +63,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
...
@@ -101,11 +97,11 @@ def string_build(self, data, modname='', path=None):
...
@@ -101,11 +97,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:
...
@@ -160,17 +156,17 @@ def _buildAstroidModuleFromComponentModuleName(modname):
...
@@ -160,17 +156,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
,
...
@@ -189,11 +185,12 @@ def _buildAstroidModuleFromComponentModuleName(modname):
...
@@ -189,11 +185,12 @@ def _buildAstroidModuleFromComponentModuleName(modname):
return
module
return
module
if
component_obj
is
None
:
if
component_obj
is
None
:
raise
AstroidBuildingException
()
raise
AstroidBuildingError
()
if
six
.
PY3
:
return
AstroidBuilder
(
MANAGER
).
module_build
(
importlib
.
import_module
(
modname
))
# 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
)
...
@@ -201,7 +198,7 @@ def _buildAstroidModuleFromComponentModuleName(modname):
...
@@ -201,7 +198,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'
,
...
@@ -229,8 +226,11 @@ MANAGER.register_failed_import_hook(fail_hook_erp5_component)
...
@@ -229,8 +226,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
:
...
@@ -238,8 +238,12 @@ def _getattr(self, name, *args, **kw):
...
@@ -238,8 +238,12 @@ 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
self
.
name
==
'numpy'
or
self
.
name
.
startswith
(
'numpy.'
):
real_module
=
__import__
(
self
.
name
,
fromlist
=
[
self
.
name
],
level
=
0
)
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
:
...
@@ -255,13 +259,21 @@ def _getattr(self, name, *args, **kw):
...
@@ -255,13 +259,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
)
...
@@ -272,16 +284,29 @@ def _getattr(self, name, *args, **kw):
...
@@ -272,16 +284,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
...
@@ -428,7 +453,7 @@ _inspected_modules = {}
...
@@ -428,7 +453,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(
...
@@ -444,7 +469,7 @@ def fail_hook_BTrees(modname):
...
@@ -444,7 +469,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)
...
...
product/ERP5Type/tests/testDynamicClassGeneration.py
View file @
5f1f54ca
This diff is collapsed.
Click to expand it.
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