Skip to content

Type-narrowing in a union sometimes fails #19265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bzoracler opened this issue Jun 10, 2025 · 0 comments
Open

Type-narrowing in a union sometimes fails #19265

bzoracler opened this issue Jun 10, 2025 · 0 comments
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder

Comments

@bzoracler
Copy link
Contributor

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
@bzoracler bzoracler added the bug mypy got something wrong label Jun 10, 2025
@sterliakov sterliakov added the topic-type-narrowing Conditional type narrowing / binder label Jun 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder
Projects
None yet
Development

No branches or pull requests

2 participants