Skip to content

Type-narrowing in a union sometimes fails #19265

Closed

Description

@bzoracler

Possibly related: #10680

Bug Report, To Reproduce, & Actual Behaviour

The following snippet doesn't type-narrow properly (see mypy Playground):

from typing import Protocol

type StaticCallback[**P, R] = Callback[P, R] | staticmethod[P, R]

class Callback[**P, R](Protocol):
    def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> R: ...

def try_return_type(val: StaticCallback[[str], str], /) -> type[str]:
    if isinstance(val, type) and issubclass(val, str):
        return val  # E: Incompatible return value type (got "<subclass of "__main__.Callback[[builtins.str], builtins.str]" and "builtins.type"> | <subclass of "builtins.staticmethod[[builtins.str], builtins.str]" and "builtins.type">", expected "type[str]")  [return-value]
    assert False

This has something to do with the second member of the StaticCallback union. I've tried with these other random examples of <T> in type StaticCallback[**P, R] = Callback[P, R] | <T>, but the reason for failure still isn't obvious to me:

Narrowing succeeds:

  • <T> = int
  • <T> = None
  • <T> = dict[str, object]
  • <T> = dict[R, R]

Narrowing fails:

  • <T> = staticmethod[P, R] (same as the snippet)
  • <T> = bytes (fails regardless of whether --strict-bytes is on)
  • <T> = list[object]
  • <T> = list[R]

Expected Behavior

No errors

Your Environment

  • Mypy version used: 1.13—1.16
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.9, 3.12

Activity

  1. hauntsaninja commented on Apr 3, 2026

    @hauntsaninja
    Collaborator

    Looks like this got fixed in #19772

  2. hauntsaninja commented on Apr 3, 2026

    @hauntsaninja
    Collaborator

    I think this is probably the disjoint base stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-type-narrowingConditional type narrowing / binder

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions