Closed robert-bn closed 1 month ago
Pyright is working correctly here, so this isn't a bug.
In Python, binary operators like >>
are relatively complex. The runtime evaluates both the left and right operands and determines whether to call __rshift__
on the left operand or its inverse (__lshift__
) on the right operands. It may attempt one and then the other if the first fails. For this reason, static type checkers must evaluate the types of the left operand and the right operand independently without the help of bidirectional type inference. Lambdas require bidirectional type inference for complete type evaluation because their parameter types cannot be annotated.
When you call a.seq
directly, bidirectional type inference can be used because the argument lambda i: i
has an expected type of Callable[[T], U]
. The same is true if you manually call __rshift__
(a.__rshift__(lambda i: i))
). But if you use the >>
operator, a static type checker cannot determine the types unambiguously.
If you want to use the >>
with a lambda expression, you can create a temporary variable with the needed type infromation:
def example(a: A[int]):
temp: Callable[[int], int] = lambda i: i
reveal_type(a >> temp)
or
def example(a: A[int]):
def temp(i: int): return i
reveal_type(a >> temp)
Ah okay. Thank you for the detailed explanation.
Consider the following code
This produces the following output when analysed with pyright:
Since
__rshift__
andseq
are the same type, I would expect type inference to work the same and infer that thei
is typeint
in both cases.I've seen the behaviour as
__rshift__
for all the operators I've tried, but I haven't tested them all.Tested with cli pyright version 1.1.370