Skip to content

Commit

Permalink
Fixed bug that causes a false positive overlapping overload error whe…
Browse files Browse the repository at this point in the history
…n the overload accepts a `Callable[..., T]` form. This addresses #9514. (#9516)
  • Loading branch information
erictraut authored Nov 29, 2024
1 parent 5cbf483 commit 4042841
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
10 changes: 10 additions & 0 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26416,6 +26416,16 @@ export function createTypeEvaluator(
}
}

// If we're checking for full overlapping overloads and the source is
// a gradual form, the dest must also be a gradual form.
if (
(flags & AssignTypeFlags.OverloadOverlap) !== 0 &&
FunctionType.isGradualCallableForm(srcType) &&
!FunctionType.isGradualCallableForm(destType)
) {
canAssign = false;
}

// If the source and the dest are using the same ParamSpec, any additional
// concatenated parameters must match.
if (targetIncludesParamSpec && srcParamSpec?.priv.nameWithScope === destParamSpec?.priv.nameWithScope) {
Expand Down
31 changes: 31 additions & 0 deletions packages/pyright-internal/src/tests/samples/overloadOverlap1.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,34 @@ def func28(a: int, /, b: None = ...) -> None: ...
@overload
def func28(a: int, /) -> bool: ...
def func28(a: int, /, b: bool | None = None) -> bool | None: ...


class CBProto29(Protocol):
def __call__(self, *args: Any) -> Any: ...


@overload
def func29(func: CBProto29) -> None: ...


@overload
def func29(func: Callable[..., Any]) -> None: ...


def func29(func: Any) -> None: ...


class CBProto30(Protocol):
def __call__(self, *args: Any, **kwargs: Any) -> Any: ...


@overload
def func30(func: CBProto30) -> None: ...


@overload
# This should generate an error because this overload will never be used.
def func30(func: Callable[..., Any]) -> None: ...


def func30(func: Any) -> None: ...
2 changes: 1 addition & 1 deletion packages/pyright-internal/src/tests/typeEvaluator6.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ test('OverloadOverlap1', () => {

configOptions.diagnosticRuleSet.reportOverlappingOverload = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['overloadOverlap1.py'], configOptions);
TestUtils.validateResults(analysisResults, 14);
TestUtils.validateResults(analysisResults, 15);
});

test('TypeGuard1', () => {
Expand Down

0 comments on commit 4042841

Please sign in to comment.