Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running pylint on class with duplicate bases raises DuplicateBasesError exception in astroid #3247

Closed
Jackenmen opened this issue Nov 15, 2019 · 2 comments · Fixed by pylint-dev/astroid#916 or PennyDreadfulMTG/Penny-Dreadful-Tools#8447
Labels
Bug 🪲 Crash 💥 A bug that makes pylint crash

Comments

@Jackenmen
Copy link
Contributor

Jackenmen commented Nov 15, 2019

Steps to reproduce

Minimal code to reproduce the error (running pylint on a file with this contents will error out):

import asyncio
from typing import AsyncContextManager, Awaitable


class _ReproCtxManager(Awaitable[None], AsyncContextManager[None]):
    def __init__(self):
        pass

    def __await__(self):
        return self.__aenter__().__await__()

    async def __aenter__(self):
        return "test"

    async def __aexit__(self, exc_type, exc, tb):
        return None


async def main():
    async with _ReproCtxManager() as x:
        print(x)
    print(await _ReproCtxManager())

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Current behavior

I get this traceback when running pylint min_bug.py

Traceback
************* Module min_bug
min_bug.py:1:0: C0114: Missing module docstring (missing-module-docstring)
min_bug.py:5:0: E0241: Duplicate bases for class '_ReproCtxManager' (duplicate-b
ases)
min_bug.py:10:15: E1101: Instance of 'str' has no '__await__' member (no-member)

min_bug.py:15:4: C0103: Argument name "tb" doesn't conform to snake_case naming 
style (invalid-name)
min_bug.py:19:0: C0116: Missing function or method docstring (missing-function-d
ocstring)
Traceback (most recent call last):
  File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python37\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python37\Scripts\pylint.exe\__main__.py", line 7, in <module>        
  File "c:\python37\lib\site-packages\pylint\__init__.py", line 23, in run_pylin
t
    PylintRun(sys.argv[1:])
  File "c:\python37\lib\site-packages\pylint\lint.py", line 1731, in __init__   
    linter.check(args)
  File "c:\python37\lib\site-packages\pylint\lint.py", line 1004, in check      
    self._do_check(files_or_modules)
  File "c:\python37\lib\site-packages\pylint\lint.py", line 1165, in _do_check  
    self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)     
  File "c:\python37\lib\site-packages\pylint\lint.py", line 1252, in check_astro
id_module
    walker.walk(ast_node)
  File "c:\python37\lib\site-packages\pylint\utils\ast_walker.py", line 77, in w
alk
    self.walk(child)
  File "c:\python37\lib\site-packages\pylint\utils\ast_walker.py", line 77, in w
alk
    self.walk(child)
  File "c:\python37\lib\site-packages\pylint\utils\ast_walker.py", line 74, in w
alk
    callback(astroid)
  File "c:\python37\lib\site-packages\pylint\checkers\async.py", line 56, in vis
it_asyncwith
    inferred = checker_utils.safe_infer(ctx_mgr)
  File "c:\python37\lib\site-packages\pylint\checkers\utils.py", line 1084, in s
afe_infer
    value = next(inferit)
  File "c:\python37\lib\site-packages\astroid\decorators.py", line 131, in raise
_if_nothing_inferred
    yield next(generator)
  File "c:\python37\lib\site-packages\astroid\decorators.py", line 95, in wrappe
d
    res = next(generator)
  File "c:\python37\lib\site-packages\astroid\inference.py", line 227, in infer_
call
    yield from callee.infer_call_result(caller=self, context=callcontext)       
  File "c:\python37\lib\site-packages\astroid\scoped_nodes.py", line 2136, in in
fer_call_result
    if any(cls.name in EXCEPTION_BASE_CLASSES for cls in self.mro()):
  File "c:\python37\lib\site-packages\astroid\scoped_nodes.py", line 2813, in mr
o
    return self._compute_mro(context=context)
  File "c:\python37\lib\site-packages\astroid\scoped_nodes.py", line 2802, in _c
ompute_mro
    unmerged_mro = list(clean_duplicates_mro(unmerged_mro, self, context))      
  File "c:\python37\lib\site-packages\astroid\scoped_nodes.py", line 104, in cle
an_duplicates_mro
    context=context,
astroid.exceptions.DuplicateBasesError: Duplicates found in MROs (_ReproCtxManag
er), (_GenericAlias, object), (_GenericAlias, object), (_GenericAlias, _GenericA
lias) for <ClassDef._ReproCtxManager l.5 at 0x2554c696988>.

Expected behavior

I would expect no exception raised and just have the E0241/duplicate-bases warning shown without the exception. I wasn't sure if I should put this issue here on astroid repo so I'm going with this one first.

pylint --version output

pylint 2.4.4
astroid 2.3.3
Python 3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 15 2019, 00:11:34) [MSC v.1916 64 bit 
(AMD64)]

This issue also happens on latest commit of master.

@PCManticore
Copy link
Contributor

Thanks for the report!

@PCManticore PCManticore added Bug 🪲 Crash 💥 A bug that makes pylint crash labels Nov 16, 2019
@PCManticore PCManticore added this to the Next bug fix release milestone Nov 16, 2019
@Jackenmen
Copy link
Contributor Author

Also let me add one thing, I am not sure if this was reported before so I'm not making issue for that as well, but I don't think this kind of code should generate duplicate-bases at all as it's valid to derive from 2 types to indicate it's both awaitable and async ctx manager.
In original code, we've just put ignore comment there (until this release which made it crash pylint) but ideally we shouldn't need to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🪲 Crash 💥 A bug that makes pylint crash
Projects
None yet
2 participants