diff --git a/astroid/brain/brain_namedtuple_enum.py b/astroid/brain/brain_namedtuple_enum.py index 1af5ba2bb4..9a9cc98981 100644 --- a/astroid/brain/brain_namedtuple_enum.py +++ b/astroid/brain/brain_namedtuple_enum.py @@ -315,6 +315,7 @@ def infer_enum_class(node): if node.root().name == "enum": # Skip if the class is directly from enum module. break + dunder_members = {} for local, values in node.locals.items(): if any(not isinstance(value, nodes.AssignName) for value in values): continue @@ -372,7 +373,16 @@ def name(self): for method in node.mymethods(): fake.locals[method.name] = [method] new_targets.append(fake.instantiate_class()) + dunder_members[local] = fake node.locals[local] = new_targets + members = nodes.Dict(parent=node) + members.postinit( + [ + (nodes.Const(k, parent=members), nodes.Name(v.name, parent=members)) + for k, v in dunder_members.items() + ] + ) + node.locals["__members__"] = [members] break return node diff --git a/tests/unittest_scoped_nodes.py b/tests/unittest_scoped_nodes.py index e9a15dafbe..7fe537b2fb 100644 --- a/tests/unittest_scoped_nodes.py +++ b/tests/unittest_scoped_nodes.py @@ -2054,6 +2054,22 @@ class Derived(Parent): assert isinstance(inferred, objects.Property) +def test_issue940_enums_as_a_real_world_usecase(): + node = builder.extract_node( + """ + from enum import Enum + class Sounds(Enum): + bee = "buzz" + cat = "meow" + Sounds.__members__ + """ + ) + inferred_result = next(node.infer()) + assert isinstance(inferred_result, nodes.Dict) + actual = [k.value for k, _ in inferred_result.items] + assert sorted(actual) == ["bee", "cat"] + + def test_metaclass_cannot_infer_call_yields_an_instance(): node = builder.extract_node( """