From 2ccada55b049f7f2efbe518fdba53a0d584d3534 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 23 Sep 2023 19:34:10 -0700 Subject: [PATCH 1/2] Added check for the use of an ellipsis for a default argument value for a function that is not in a stub, not overloaded, and without a placeholder implementation. This addresses #5985. --- .../pyright-internal/src/analyzer/decorators.ts | 2 ++ .../pyright-internal/src/analyzer/typeEvaluator.ts | 13 ++++++++++++- .../src/tests/samples/constrainedTypeVar1.py | 4 ++-- .../src/tests/samples/overload12.py | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/decorators.ts b/packages/pyright-internal/src/analyzer/decorators.ts index ed0742aa24f7..4e584b342f34 100644 --- a/packages/pyright-internal/src/analyzer/decorators.ts +++ b/packages/pyright-internal/src/analyzer/decorators.ts @@ -91,6 +91,8 @@ export function getFunctionFlagsFromDecorators(evaluator: TypeEvaluator, node: F flags |= FunctionTypeFlags.Overridden; } else if (decoratorType.details.builtInName === 'type_check_only') { flags |= FunctionTypeFlags.TypeCheckOnly; + } else if (decoratorType.details.builtInName === 'overload') { + flags |= FunctionTypeFlags.Overloaded; } } else if (isInstantiableClass(decoratorType)) { if (ClassType.isBuiltIn(decoratorType, 'staticmethod')) { diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 8239fc7315f1..6f1cccefc363 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -17278,9 +17278,20 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let defaultValueType: Type | undefined; if (param.defaultValue) { + // If this is a stub file, a protocol, an overload, or a class + // whose body is a placeholder implementation, treat a "...", as + // an "Any" value. + let treatEllipsisAsAny = fileInfo.isStubFile || ParseTreeUtils.isSuiteEmpty(node.suite); + if (containingClassType && ClassType.isProtocolClass(containingClassType)) { + treatEllipsisAsAny = true; + } + if (FunctionType.isOverloaded(functionType)) { + treatEllipsisAsAny = true; + } + defaultValueType = getTypeOfExpression( param.defaultValue, - EvaluatorFlags.ConvertEllipsisToAny, + treatEllipsisAsAny ? EvaluatorFlags.ConvertEllipsisToAny : EvaluatorFlags.None, makeInferenceContext(annotatedType) ).type; } diff --git a/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py b/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py index adcad679f43f..02f4a4b8c9d6 100644 --- a/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py +++ b/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py @@ -17,8 +17,8 @@ def constrained(first: S, second: S) -> S: class Foo(Generic[U]): - def generic_func1(self, a: U, b: U = ..., **kwargs: U) -> U: - return b + def generic_func1(self, a: U, b: str = "", **kwargs: U) -> U: + return a foo = Foo[str]() diff --git a/packages/pyright-internal/src/tests/samples/overload12.py b/packages/pyright-internal/src/tests/samples/overload12.py index 3d2eee77b882..3af8b8fa15f9 100644 --- a/packages/pyright-internal/src/tests/samples/overload12.py +++ b/packages/pyright-internal/src/tests/samples/overload12.py @@ -276,7 +276,7 @@ def overload9(x: object, y: int, z: str, a: None) -> str: ... -def overload9(x, y, z=..., a=...) -> Any: +def overload9(x, y, z="", a=None) -> Any: pass From ef65464343cd8be09ed0f25d06951857bd3c4df9 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 23 Sep 2023 19:55:23 -0700 Subject: [PATCH 2/2] Exempt abstract methods as well. --- packages/pyright-internal/src/analyzer/typeEvaluator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 6f1cccefc363..80c3749ba8b5 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -17285,7 +17285,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (containingClassType && ClassType.isProtocolClass(containingClassType)) { treatEllipsisAsAny = true; } - if (FunctionType.isOverloaded(functionType)) { + if (FunctionType.isOverloaded(functionType) || FunctionType.isAbstractMethod(functionType)) { treatEllipsisAsAny = true; }