8000 Fixed bug that results in incorrect type evaluation when a function w… · codemuse-app/scip-python@527a5ff · GitHub
[go: up one dir, main page]

Skip to content

Commit 527a5ff

Browse files
committed
Fixed bug that results in incorrect type evaluation when a function with a **kwargs parameter is captured by a ParamSpec in certain circumstances.
1 parent 6792731 commit 527a5ff

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

packages/pyright-internal/src/analyzer/typeUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,7 @@ export function buildTypeVarContext(
15211521
} else if (isAnyOrUnknown(typeArgType)) {
15221522
// Fill in an empty signature if the arg type is Any or Unknown.
15231523
typeVarContext.setParamSpec(typeParam, {
1524-
flags: FunctionTypeFlags.None,
1524+
flags: FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck,
15251525
parameters: FunctionType.getDefaultParameters(),
15261526
typeVarScopeId: undefined,
15271527
docString: undefined,

packages/pyright-internal/src/analyzer/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,12 @@ export namespace FunctionType {
14311431
newFunction.details.parameters.length - 2
14321432
);
14331433

1434+
// Update the flags of the function.
1435+
newFunction.details.flags &= ~FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck;
1436+
if (paramSpecValue.flags & FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck) {
1437+
newFunction.details.flags |= FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck;
1438+
}
1439+
14341440
// If there is a position-only separator in the captured param spec signature,
14351441
// remove the position-only separator in the existing signature. Otherwise,
14361442
// we'll end up with redundant position-only separators.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This sample tests that a **kwargs parameter captured by a ParamSpec
2+
# is preserved.
3+
4+
from typing import Callable, Generic, ParamSpec, TypeVar
5+
6+
7+
P = ParamSpec("P")
8+
T = TypeVar("T")
9+
10+
11+
class Foo(Generic[P, T]):
12+
def __init__(self, callback: Callable[P, T]):
13+
self.callback = callback
14+
15+
def method(self, *args: P.args, **kwargs: P.kwargs) -> T:
16+
return self.callback(*args, **kwargs)
17+
18+
19+
def func(obj: object, **kwargs: object) -> object:
20+
...
21+
22+
23+
reveal_type(Foo(func).method, expected_text="(obj: object, **kwargs: object) -> object")

packages/pyright-internal/src/tests/typeEvaluator4.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,14 @@ test('ParamSpec37', () => {
997997
TestUtils.validateResults(results, 0);
998998
});
999999

1000+
test('ParamSpec38', () => {
1001+
const configOptions = new ConfigOptions('.');
1002+
1003+
configOptions.defaultPythonVersion = PythonVersion.V3_10;
1004+
const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec38.py'], configOptions);
1005+
TestUtils.validateResults(results, 0);
1006+
});
1007+
10001008
test('ClassVar1', () => {
10011009
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['classVar1.py']);
10021010

0 commit comments

Comments
 (0)
0