microsoft / pyright

Static Type Checker for Python
Other
13.02k stars 1.39k forks source link

multiple output from single `reveal_type` #8435

Closed pinterior closed 1 month ago

pinterior commented 1 month ago

Describe the bug

reveal_type used inside lambda passed to union type of functions emits multiple output.

Code or Screenshots

on pyright-play.net

from collections.abc import Callable
from typing import reveal_type

class A:
    def f(self, x: Callable[[int], int]):
        ...

class B:
    def f(self, x: Callable[[str], str]):
        ...

type U = A | B

def f(u: U):
    u.f(lambda x: reveal_type(x))
rt.py
  rt.py:14:31 - information: Type of "x" is "int"
  rt.py:14:31 - information: Type of "x" is "str"

perhaps it could be:

Type of "x" is "int | str"

VS Code extension or command-line

command-line tool, 1.1.371

erictraut commented 1 month ago

This is a tricky case. The type is actually either int or str in this case, not int | str.

Pyright's behavior is consistent with mypy's in this case, which also emits two reveal_type outputs.

I'm going to mark this as "won't fix" because I think the current behavior is fine, and I don't see a straightforward way to change it.

pinterior commented 1 month ago

I see.

and, I have another question: If in case types are int and Never , is it possible for Pylance to infer int instead of the current Unknown, considering a lambda that takes Never as an argument as "should never be called"? (I'm not sure if the inference is from Pyright or Pylance, so I'm asking here)