Skip to content

Incorrect inference of ancestors of Enum class with six.with_metaclass #713

@tkukushkin

Description

@tkukushkin

Steps to reproduce

import astroid

code = '''import six
from enum import Enum, EnumMeta

class FooMeta(EnumMeta):
    pass

class Foo(six.with_metaclass(FooMeta, Enum)):
    bar = 1'''

module = astroid.parse(code)
print(list(module.body[3].ancestors()))

Current behavior

Prints [<ClassDef.NoneType l.0 at 0x102bb4d68>, <ClassDef.object l.0 at 0x102bbe1d0>]

Expected behavior

Prints [<ClassDef.Enum l.10 at 0x10d0617b8>, <ClassDef.object l.0 at 0x10c4650f0>]

With another simple example without enums works ok:

import astroid

code = '''import six

class FooMeta(type):
    pass

class BaseFoo(object):
    pass

class Foo(six.with_metaclass(FooMeta, BaseFoo)):
    bar = 1'''

module = astroid.parse(code)
print(list(module.body[3].ancestors()))

Prints: [<ClassDef.BaseFoo l.6 at 0x1091531d0>, <ClassDef.object l.0 at 0x10853d128>]

python -c "from astroid import __pkginfo__; print(__pkginfo__.version)" output

2.3.2

This behaviour breaks pylint with exception:

Traceback (most recent call last):
  File "bin/pylint", line 8, in <module>
    sys.exit(run_pylint())
  File "lib/python3.7/site-packages/pylint/__init__.py", line 19, in run_pylint
    Run(sys.argv[1:])
  File "lib/python3.7/site-packages/pylint/lint.py", line 1394, in __init__
    linter.check(args)
  File "lib/python3.7/site-packages/pylint/lint.py", line 801, in check
    self._do_check(files_or_modules)
  File "lib/python3.7/site-packages/pylint/lint.py", line 938, in _do_check
    self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)
  File "lib/python3.7/site-packages/pylint/lint.py", line 1018, in check_astroid_module
    walker.walk(ast_node)
  File "lib/python3.7/site-packages/pylint/utils.py", line 1162, in walk
    self.walk(child)
  File "lib/python3.7/site-packages/pylint/utils.py", line 1162, in walk
    self.walk(child)
  File "lib/python3.7/site-packages/pylint/utils.py", line 1162, in walk
    self.walk(child)
  File "lib/python3.7/site-packages/pylint/utils.py", line 1159, in walk
    cb(astroid)
  File "lib/python3.7/site-packages/pylint/checkers/base.py", line 1509, in visit_assignname
    if not list(frame.local_attr_ancestors(node.name)):
  File "lib/python3.7/site-packages/astroid/scoped_nodes.py", line 2197, in local_attr_ancestors
    if name in astroid:
TypeError: argument of type 'Const' is not iterable

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions