From 4cb43d39a33e507e4be9b27bb23c297ecd1c485b Mon Sep 17 00:00:00 2001 From: detachhead Date: Mon, 16 Dec 2024 22:01:31 +1000 Subject: [PATCH] fix `reportUnusedParameter` false positive on abstract setters --- packages/pyright-internal/src/analyzer/properties.ts | 8 ++++++++ .../pyright-internal/src/analyzer/typeEvaluator.ts | 1 + .../src/analyzer/typeEvaluatorTypes.ts | 1 + packages/pyright-internal/src/analyzer/typeUtils.ts | 3 ++- .../src/tests/samples/reportUnusedParameter.py | 12 ++++++++++-- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/properties.ts b/packages/pyright-internal/src/analyzer/properties.ts index be6536b636..a55fa483f2 100644 --- a/packages/pyright-internal/src/analyzer/properties.ts +++ b/packages/pyright-internal/src/analyzer/properties.ts @@ -121,6 +121,14 @@ export function clonePropertyWithSetter( if (!isProperty(prop)) { return prop; } + // this is safe. see comment on isProperty + prop = prop as ClassType; + + // if it's an abstract property, mark the parameter as accessed + if (prop.priv?.fgetInfo?.methodType && FunctionType.isAbstractMethod(prop.priv.fgetInfo.methodType)) { + // first parameter is self, there should only ever be one other parameter. + evaluator.markParamAccessed(errorNode.d.params[1]); + } const classType = prop as ClassType; const flagsToClone = classType.shared.flags; diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index ca4f8bf7ef..7549202eb9 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -28434,6 +28434,7 @@ export function createTypeEvaluator( checkForCancellation, printControlFlowGraph, typesOverlap, + markParamAccessed, }; const codeFlowEngine = getCodeFlowEngine(evaluatorInterface, speculativeTypeTracker); diff --git a/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts b/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts index fc3a7fae1f..4ff0b7a83b 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts @@ -884,4 +884,5 @@ export interface TypeEvaluator { logger: ConsoleInterface ) => void; typesOverlap: (leftType: Type, rightType: Type, checkEq: boolean) => boolean; + markParamAccessed: (param: ParameterNode) => void; } diff --git a/packages/pyright-internal/src/analyzer/typeUtils.ts b/packages/pyright-internal/src/analyzer/typeUtils.ts index 2b889e4413..26d5d6cf81 100644 --- a/packages/pyright-internal/src/analyzer/typeUtils.ts +++ b/packages/pyright-internal/src/analyzer/typeUtils.ts @@ -1423,7 +1423,8 @@ export function isEllipsisType(type: Type): boolean { return isAny(type) && type.priv.isEllipsis; } -export function isProperty(type: Type) { +// type guard commented out due to https://github.com/microsoft/TypeScript/issues/15048 +export function isProperty(type: Type) /* : type is ClassType */ { return isClassInstance(type) && ClassType.isPropertyClass(type); } diff --git a/packages/pyright-internal/src/tests/samples/reportUnusedParameter.py b/packages/pyright-internal/src/tests/samples/reportUnusedParameter.py index 1a040e6bc3..60dffcff7b 100644 --- a/packages/pyright-internal/src/tests/samples/reportUnusedParameter.py +++ b/packages/pyright-internal/src/tests/samples/reportUnusedParameter.py @@ -1,4 +1,4 @@ -from abc import abstractmethod +from abc import ABC, abstractmethod from typing import override @@ -23,4 +23,12 @@ def __baz__(self, asdf: int): # no error, dunder def qux(self, __asdf: int): # error, unused cringe positional argument ... -def bar(_value: int): ... \ No newline at end of file +def bar(_value: int): ... + +class Baz(ABC): + @property + @abstractmethod + def foo(self) -> str:... + @foo.setter + def foo(self, new_value: str): # no error, abstract property + ... \ No newline at end of file