Commit 421d6068 authored by Kirill Smelkov's avatar Kirill Smelkov

pylint: Fix wendelin transform to yield module with a .name

In 5796a17a (core_test: Add test to make sure that wendelin.core
basically works) I added wendelin_transform to pylint so that the
checker could recognize wendelin.core's special wendelin top-level
module/package and handle ok

	from wendelin.bigarray.array_zodb import ZBigArray

this works, but e.g. for plain

	import wendelin			or
	from wendelin import bigarray

pylint currenly fails with

	AssertionError: explicit relative import, but no context_file?

To better see what is going on let's conside the following test program

	"""ZZZ"""

	from wendelin.bigarray.array_zodb import ZBigArray
	from wendelin import bigarray

	def main():
	    """main"""
	    _ = ZBigArray

and run pylint on it. Here is what it gives:

          wendelin_transform Module(wendelin)
          -> Module()

    visit_from From()
      basename: wendelin.bigarray.array_zodb
      names:    [('ZBigArray', None)]
      modnode:  Module(test)
        get_imported_module From() wendelin.bigarray.array_zodb
      importedmodnode: Module(wendelin.bigarray.array_zodb)
    ('_add_imported_module', <From() l.3 [test] at 0x7ff214b4cb90>, 'wendelin.bigarray.array_zodb.ZBigArray')
          wendelin_transform Module(wendelin)
          -> Module()

    visit_from From()
      basename: wendelin
      names:    [('bigarray', None)]
      modnode:  Module(test)
        get_imported_module From() wendelin
          wendelin_transform Module(wendelin)
          -> Module()
      importedmodnode: Module()
    ************* Module test
    W:  4, 0: Relative import 'wendelin', should be '' (relative-import)
    ('_add_imported_module', <From() l.4 [test] at 0x7ff214b4cf50>, '.bigarray')
    Traceback (most recent call last):
      File "./x.py", line 22, in <module>
        Run(['test.py', '--reports=n'], exit=False)
      File "/home/kirr/src/tools/py/pylint/pylint/lint.py", line 1332, in __init__
        linter.check(args)
      File "/home/kirr/src/tools/py/pylint/pylint/lint.py", line 747, in check
        self._do_check(files_or_modules)
      File "/home/kirr/src/tools/py/pylint/pylint/lint.py", line 869, in _do_check
        self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)
      File "/home/kirr/src/tools/py/pylint/pylint/lint.py", line 946, in check_astroid_module
        walker.walk(ast_node)
      File "/home/kirr/src/tools/py/pylint/pylint/utils.py", line 874, in walk
        self.walk(child)
      File "/home/kirr/src/tools/py/pylint/pylint/utils.py", line 871, in walk
        cb(astroid)
      File "/home/kirr/src/tools/py/pylint/pylint/checkers/imports.py", line 288, in visit_from
        self._add_imported_module(node, '%s.%s' % (importedmodnode.name, name))
      File "/home/kirr/src/tools/py/pylint/pylint/checkers/imports.py", line 328, in _add_imported_module
        importedmodname = get_module_part(importedmodname)
      File "/home/kirr/src/tools/py/astroid/astroid/modutils.py", line 359, in get_module_part
        'explicit relative import, but no context_file?'
    AssertionError: explicit relative import, but no context_file?

we see that the line

	from wendelin.bigarray.array_zodb import ZBigArray

corresponds to

	('_add_imported_module', <From() l.3 [test] at 0x7ff214b4cb90>, 'wendelin.bigarray.array_zodb.ZBigArray')

and the line

	from wendelin import bigarray

corresponds to

	('_add_imported_module', <From() l.4 [test] at 0x7ff214b4cf50>, '.bigarray')

notice that in the latter case there is no 'wendelin' prefix and the
import goes as just '.bigarray' instead of 'wendelin.bigarray' which
leads to further crash in get_module_part.

-> Fix it by initializing wendelin module yielded by wendelin_transform
with .name set. Not sure why it is working longer imports without that.

Without the fix added test breaks as

    .../instance/slappart5/bin$ ./runUnitTest -v -v -v  testDynamicClassGeneration.TestZodbModuleComponent
    ...
    Running Unit tests of <class 'testDynamicClassGeneration.TestZodbModuleComponent'>
    ok
    testImportVersionedComponentOnly (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testInvalidId (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testInvalidSourceCode (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testModuleSecurityInfo (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testPylint (testDynamicClassGeneration.TestZodbModuleComponent) ... FAIL
    testPylintAstroidModuleGeneratedOnce (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testPylintNamedtupleUnicodeLiteralsRegression (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testReferenceWithReservedKeywords (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testValidateInvalidateDelete (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testVersionPriority (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testVersionWithReservedKeywords (testDynamicClassGeneration.TestZodbModuleComponent) ... ok
    testWorkflowErrorMessage (testDynamicClassGeneration.TestZodbModuleComponent)
    Check that validation error messages are stored in workflow ... ok

    ======================================================================
    FAIL: testPylint (testDynamicClassGeneration.TestZodbModuleComponent)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File ".../parts/erp5/Products/ERP5Type/tests/testDynamicClassGeneration.py", line 2347, in testPylint
        component.checkSourceCode()
      File ".../parts/erp5/product/ERP5Type/mixin/component.py", line 329, in checkSourceCode
        return checkPythonSourceCode(self.getTextContent(), self.getPortalType())
      File ".../parts/erp5/product/ERP5Type/Utils.py", line 540, in checkPythonSourceCode
        Run(args, reporter=TextReporter(output_file), exit=False)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/lint.py", line 1332, in __init__
        linter.check(args)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/lint.py", line 747, in check
        self._do_check(files_or_modules)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/lint.py", line 869, in _do_check
        self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/lint.py", line 946, in check_astroid_module
        walker.walk(ast_node)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/utils.py", line 874, in walk
        self.walk(child)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/utils.py", line 871, in walk
        cb(astroid)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/checkers/imports.py", line 253, in visit_import
        self._add_imported_module(node, importedmodnode.name)
      File ".../develop-eggs/pylint-1.4.4+slapospatched002-py2.7.egg/pylint/checkers/imports.py", line 319, in _add_imported_module
        importedmodname = get_module_part(importedmodname)
      File ".../develop-eggs/astroid-1.3.8+slapospatched001-py2.7.egg/astroid/modutils.py", line 359, in get_module_part
        'explicit relative import, but no context_file?'
    AssertionError: explicit relative import, but no context_file?

    ----------------------------------------------------------------------
    Ran 13 tests in 137.609s

    FAILED (failures=1)

/helped-and-reviewed-by @jerome
/reviewed-on nexedi/erp5!1762
parent a57e0e2f
...@@ -484,6 +484,7 @@ else: ...@@ -484,6 +484,7 @@ else:
def wendelin_transform(node): def wendelin_transform(node):
m = AstroidBuilder(MANAGER).string_build('__path__ = %r' % wendelin.__path__) m = AstroidBuilder(MANAGER).string_build('__path__ = %r' % wendelin.__path__)
m.package = True m.package = True
m.name = 'wendelin'
return m return m
MANAGER.register_transform(Module, wendelin_transform, lambda node: node.name == 'wendelin') MANAGER.register_transform(Module, wendelin_transform, lambda node: node.name == 'wendelin')
......
...@@ -2324,6 +2324,16 @@ numpy.sin([]) ...@@ -2324,6 +2324,16 @@ numpy.sin([])
import pandas import pandas
pandas.DataFrame([]) pandas.DataFrame([])
# wendelin is special top-level module for which we added custom pylint support
import wendelin
from wendelin import bigarray
from wendelin.bigarray import array_zodb
from wendelin.bigarray.array_zodb import ZBigArray
_ = wendelin
_ = bigarray
_ = array_zodb
_ = ZBigArray
""" % (dict(namespace=namespace, """ % (dict(namespace=namespace,
reference1=imported_reference1, reference1=imported_reference1,
module2=imported_module2, module2=imported_module2,
......
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