python / python/mypy

allow-redefinition-new for enum results in incompatible type of Literal[members]

Open
#19,894 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-enum topic-inference topic-literal-types
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Followup to the advice at https://github.com/python/mypy/issues/19280#issuecomment-2971970574 :)

Reduced from https://github.com/mesonbuild/meson/blob/5f3d12abc814b9ea99e56ea31b79a4cb3e8411fc/mesonbuild/dependencies/base.py#L605-L643

from enum import Enum
import typing as T

class DependencyMethods(Enum):
    # Auto means to use whatever dependency checking mechanisms in whatever order meson thinks is best.
    AUTO = 'auto'
    PKGCONFIG = 'pkg-config'
    CMAKE = 'cmake'
    # The dependency is provided by the standard library and does not need to be linked
    BUILTIN = 'builtin'
    # Just specify the standard link arguments, assuming the operating system provides the library.
    SYSTEM = 'system'
    # This is only supported on OSX - search the frameworks directory by name.
    EXTRAFRAMEWORK = 'extraframework'
    # Detect using the sysconfig module.
    SYSCONFIG = 'sysconfig'
    # Specify using a "program"-config style tool
    CONFIG_TOOL = 'config-tool'
    # For backwards compatibility
    SDLCONFIG = 'sdlconfig'
    CUPSCONFIG = 'cups-config'
    PCAPCONFIG = 'pcap-config'
    LIBWMFCONFIG = 'libwmf-config'
    QMAKE = 'qmake'
    # Misc
    DUB = 'dub'

def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: T.Dict[str, T.Any]) -> T.List[DependencyMethods]:
    method: T.Union[DependencyMethods, str] = kwargs.get('method', 'auto')
    method = DependencyMethods(method)

    # handle renames...

    # Set the detection method. If the method is set to auto, use any available method.
    # If method is set to a specific string, allow only that detection method.
    if method == DependencyMethods.AUTO:
        methods = list(possible)
    elif method in possible:
        methods = [method]
    else:
        raise Exception('argh')

    return methods

Expected Behavior

Passes type checking.

Actual Behavior

$ mypy --local-partial-types --allow-redefinition-new foo.py 
foo.py:43: error: Incompatible return value type (got "list[DependencyMethods] | list[Literal[DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE, DependencyMethods.BUILTIN, DependencyMethods.SYSTEM, DependencyMethods.EXTRAFRAMEWORK, DependencyMethods.SYSCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SDLCONFIG, DependencyMethods.CUPSCONFIG, DependencyMethods.PCAPCONFIG, DependencyMethods.LIBWMFCONFIG, DependencyMethods.QMAKE, DependencyMethods.DUB]]", expected "list[DependencyMethods]")  [return-value]
Found 1 error in 1 file (checked 1 source file)

It is being redefined as "Literal for every possible enum value". If I annotate the first assignment as T.List[DependencyMethods] then it works (the second assignment fits into the first!), but I feel like I ought not need this.

Your Environment

  • Mypy version used: mypy 1.18.2 (compiled: yes)
  • Mypy command-line flags: --local-partial-types --allow-redefinition-new

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 with the reduced example in foo.py and run mypy 1.18.2 using --local-partial-types and --allow-redefinition-new to reproduce the return-type error. Trace how the redefined enum variable is inferred and check the corresponding type-checking tests or implementation entry points. Done means the example passes type checking without annotating the first assignment.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.