python / python/mypy

Type narrowing of `Any` with `is` can widen type of variable for enum member to `Any`

Open
#21,667 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Bug Report

Possibly related to #21364 and other union narrowing, although this occurs without a union.

When the following pattern is used to define a sentinel, strange "narrowing" behavior can occur:

class SentinelType(enum.Enum):
    SENTINEL = enum.auto()
SENTINEL: SentinelType = SentinelType.SENTINEL

If x: Any is narrowed by the comparison x is SENTINEL, mypy will start to treat SENTINEL as having type Any.

This does not happen if the namespaced enum member, SentinelType.SENTINEL is used. Only when a separate variable is used.

To Reproduce

https://mypy-play.net/?gist=174c92c83f84f44b2e8fefdcf5a0cd9b

import enum
import typing as t

class SentinelType(enum.Enum):
    SENTINEL = enum.auto()
SENTINEL: SentinelType = SentinelType.SENTINEL

x: t.Any = None
if x is SENTINEL:
    t.reveal_type(SENTINEL)

Expected Behavior

The type of SENTINEL should not be altered.

Actual Behavior

SENTINEL's revealed type is Any.

Your Environment

  • Mypy version used: 2.0, 2.1
  • Python version used: 3.10, 3.12, 3.14

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 linked mypy-play reproducer and run it with the shown Python code, checking the reveal_type output for SENTINEL inside the is branch. Trace the type-narrowing path for comparisons involving Any and a separately assigned enum member; done means SENTINEL retains its declared SentinelType rather than becoming Any.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers, devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.