python / python/mypy

Enums with only descriptor members should not be final

Open
#12,494 0 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-descriptors topic-enum topic-runtime-semantics
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

If all members of an Enum class are descriptors, the class should still be subclassable.

Quote from the Python documentation:

The rules for what is allowed are as follows: names that start and end with a single underscore are reserved by enum and cannot be used; all other attributes defined within an enumeration will become members of this enumeration, with the exception of special methods (__str__(), __add__(), etc.), descriptors (methods are also descriptors), and variable names listed in _ignore_.

This would also match the behaviour of Pyright (1.1.234)

To Reproduce

  1. Install mypy==0.941
  2. Run mypy on this code:
import logging
from enum import Enum


class LoggedAccess:
    def __set_name__(self, owner, name):
        self.public_name = name
        self.private_name = '_' + name

    def __get__(self, obj, objtype=None):
        value = getattr(obj, self.private_name)
        logging.info('Accessing %r giving %r', self.public_name, value)
        return value

    def __set__(self, obj, value):
        logging.info('Updating %r to %r', self.public_name, value)
        setattr(obj, self.private_name, value)


class Foo(Enum):
    thing = LoggedAccess()

    
class Bar(Foo):
    x = 42

Expected Behavior

No errors - this runs just fine

Actual Behavior

 error: Cannot extend enum with existing members: "Foo"

Your Environment

  • Mypy version used: 0.941

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the reported example with mypy 0.941, then trace the enum analysis that decides whether Foo has existing members. The issue is done when an enum containing only descriptors can be subclassed without an error, while enums with actual members retain the existing restriction.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.