Skip to content

Type-narrowing Union with Literal using comparison to Literal variable #16465

@Garrett-R

Description

@Garrett-R

Bug Report

Strangely, type-narrowing for unions including a Literal works for int but not datetime

To Reproduce

Mypy Playground. Copied here for convenience:

from datetime import datetime
from typing import Final, Literal

Unspecified = Literal['unspecified']
UNSPECIFIED: Final[Unspecified] = 'unspecified'

def do_thing(x: datetime | Unspecified) -> None:
    if x != UNSPECIFIED:
        print(x.utcnow())  # Unexpected error!

def do_thing_2(x: int | Unspecified) -> None:
    if x != UNSPECIFIED:
        print(x.real)  # No prob

Expected Behavior

No errors.

Actual Behavior

Has errors:

main.py:9: error: Item "str" of "datetime | Literal['unspecified']" has no attribute "utcnow"  [union-attr]

Your Environment

  • Mypy version used: 1.7.0
  • Mypy command-line flags: <none>
  • Mypy configuration options from mypy.ini (and other config files): <none>
  • Python version used: 3.11

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions