Fixed recent regression that results in a false positive error when applying a @property decorator to a method that has already had a decorator applied to it. This addresses #7667. (#7671)

This commit is contained in:
Eric Traut 2024-04-11 20:44:46 -07:00 committed by GitHub
parent dd09712579
commit f2e277aa5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 30 additions and 0 deletions

View File

@ -944,6 +944,7 @@ function assignTypeToParamSpec(
newFunction.details.docString = srcType.details.docString;
newFunction.details.deprecatedMessage = srcType.details.deprecatedMessage;
newFunction.details.paramSpec = srcType.details.paramSpec;
newFunction.details.methodClass = srcType.details.methodClass;
let updateContextWithNewFunction = false;

View File

@ -25433,6 +25433,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
remainingFunction.details.typeVarScopeId = effectiveSrcType.details.typeVarScopeId;
remainingFunction.details.constructorTypeVarScopeId =
effectiveSrcType.details.constructorTypeVarScopeId;
remainingFunction.details.methodClass = effectiveSrcType.details.methodClass;
remainingParams.forEach((param) => {
FunctionType.addParameter(remainingFunction, param);
});

View File

@ -1821,6 +1821,7 @@ export namespace FunctionType {
FunctionType.addHigherOrderTypeVarScopeIds(newFunction, paramSpecValue.details.higherOrderTypeVarScopeIds);
newFunction.details.paramSpec = paramSpecValue.details.paramSpec;
newFunction.details.methodClass = paramSpecValue.details.methodClass;
}
return newFunction;

View File

@ -0,0 +1,21 @@
# This sample tests the case where a @property decorator is applied to
# a method that has been previously decorated.
from typing import ParamSpec, TypeVar, Callable
P = ParamSpec("P")
R = TypeVar("R")
def deco1(func: Callable[P, R]) -> Callable[P, R]: ...
class ClassA:
@property
@deco1
def prop(self) -> int:
return 1
a = ClassA()
reveal_type(a.prop, expected_text="int")

View File

@ -1189,6 +1189,12 @@ test('Property17', () => {
TestUtils.validateResults(analysisResults, 0);
});
test('Property18', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['property18.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('Operator1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['operator1.py']);