Skip to content

Commit

Permalink
fix Callable narrowing hack incorrectly being used on TypeIs
Browse files Browse the repository at this point in the history
  • Loading branch information
DetachHead committed Dec 1, 2024
1 parent 5d82b7a commit 56e2825
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
7 changes: 6 additions & 1 deletion packages/pyright-internal/src/analyzer/typeGuards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,12 @@ function narrowTypeForInstance(

if (
isClass(subtype) ||
(getFileInfo(errorNode).diagnosticRuleSet.strictGenericNarrowing && isFunction(subtype))
// when strictGenericNarrowing is enabled, we need to convert the Callable type to a Callable
// protocol to make sure it keeps the generics when narrowing, but this is only needed for
// isinstance checks because you can't specify generics to it
(!isTypeIsCheck &&
getFileInfo(errorNode).diagnosticRuleSet.strictGenericNarrowing &&
isFunction(subtype))
) {
if (isFunction(subtype)) {
subtype = synthesizeCallableProtocolFromFunctionType(evaluator, subtype, errorNode);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Never, assert_type, runtime_checkable, Protocol, Iterable, Iterator, MutableMapping, Reversible, Callable
from typing import Any, Never, assert_type, runtime_checkable, Protocol, Iterable, Iterator, MutableMapping, Reversible, Callable, TypeIs
from types import FunctionType

class Covariant[T]:
Expand Down Expand Up @@ -134,4 +134,10 @@ def _(f: CallableProtocol[[], None]):

def _(f: Callable[[int], str]):
if isinstance(f, FunctionType):
assert_type(f, FunctionType)
assert_type(f, FunctionType)

def takes_arg(value: object) -> TypeIs[Callable[[int], None]]: ...

def _(value: Callable[[], None] | Callable[[int], None]):
if takes_arg(value):
assert_type(value, Callable[[int], None])
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, assert_type, runtime_checkable, Protocol, Iterable, Iterator, MutableMapping, Reversible, Callable
from typing import Any, assert_type, runtime_checkable, Protocol, Iterable, Iterator, MutableMapping, Reversible, Callable, TypeIs
from types import FunctionType


Expand Down Expand Up @@ -132,4 +132,10 @@ def _(f: CallableProtocol[[], None]):

def _(f: Callable[[int], str]):
if isinstance(f, FunctionType):
assert_type(f, FunctionType)
assert_type(f, FunctionType)

def takes_arg(value: object) -> TypeIs[Callable[[int], None]]: ...

def _(value: Callable[[], None] | Callable[[int], None]):
if takes_arg(value):
assert_type(value, Callable[[int], None])

0 comments on commit 56e2825

Please sign in to comment.