Skip to content

Commit

Permalink
Fixed bug that resulted in a false positive error when one ParamSpec …
Browse files Browse the repository at this point in the history
…was captured by another ParamSpec. This addresses #6741.
  • Loading branch information
erictraut committed Dec 15, 2023
1 parent 8bb790c commit a656676
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9962,6 +9962,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
} else if (typeResult.type.details.paramSpec) {
const paramSpecScopeId = typeResult.type.details.paramSpec.scopeId;
if (
typeResult.type.details.typeVarScopeId === WildcardTypeVarScopeId ||
paramSpecScopeId === typeResult.type.details.typeVarScopeId ||
paramSpecScopeId === typeResult.type.details.constructorTypeVarScopeId
) {
Expand Down
38 changes: 38 additions & 0 deletions packages/pyright-internal/src/tests/samples/paramSpec50.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This sample tests the case where a ParamSpec captures another ParamSpec.

from typing import Callable, Iterator, ParamSpec, TypeVar

P = ParamSpec("P")
T = TypeVar("T")


def deco1(func: Callable[P, Iterator[T]]) -> Callable[P, Iterator[T]]:
...


@deco1
def func1(
func: Callable[P, str],
*func_args: P.args,
**func_kwargs: P.kwargs,
) -> Iterator[str]:
...


def func2(a: int, b: float) -> str:
...


def func3(a: int) -> str:
...


func1(func2, 3, 1.1)

# This should generate an error.
func1(func2, 3.1, 1.1)

func1(func3, 3)

# This should generate an error.
func1(func3)
5 changes: 5 additions & 0 deletions packages/pyright-internal/src/tests/typeEvaluator4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,11 @@ test('ParamSpec49', () => {
TestUtils.validateResults(results, 5);
});

test('ParamSpec50', () => {
const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec50.py']);
TestUtils.validateResults(results, 2);
});

test('ClassVar1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['classVar1.py']);

Expand Down

0 comments on commit a656676

Please sign in to comment.