From e6fe8cb0fcc5135560ed0e1fd769a346543d8bd8 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Tue, 29 Oct 2024 21:55:28 -0700 Subject: [PATCH 01/11] Fixed a bug that results in a false positive when a class is defined within a generic function and uses type parameters from that function. This addresses #9359. (#9360) --- packages/pyright-internal/src/analyzer/typeUtils.ts | 5 +++++ .../src/tests/samples/typeParams8.py | 13 +++++++++++++ .../src/tests/typeEvaluator5.test.ts | 8 ++++++++ 3 files changed, 26 insertions(+) create mode 100644 packages/pyright-internal/src/tests/samples/typeParams8.py diff --git a/packages/pyright-internal/src/analyzer/typeUtils.ts b/packages/pyright-internal/src/analyzer/typeUtils.ts index 23524b713..10592ec77 100644 --- a/packages/pyright-internal/src/analyzer/typeUtils.ts +++ b/packages/pyright-internal/src/analyzer/typeUtils.ts @@ -2037,6 +2037,11 @@ export function getTypeVarArgsRecursive(type: Type, recursionCount = 0): TypeVar return []; } + // Don't return any bound type variables. + if (TypeVarType.isBound(type)) { + return []; + } + // Don't return any P.args or P.kwargs types. if (isParamSpec(type) && type.priv.paramSpecAccess) { return [TypeVarType.cloneForParamSpecAccess(type, /* access */ undefined)]; diff --git a/packages/pyright-internal/src/tests/samples/typeParams8.py b/packages/pyright-internal/src/tests/samples/typeParams8.py new file mode 100644 index 000000000..1e0368242 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/typeParams8.py @@ -0,0 +1,13 @@ +# This sample tests the case where a class defined in an inner scope +# uses type variables from an outer scope. + + +class Parent[S, T]: + def task(self, input: S) -> T: ... + + +def outer_func1[S, T](): + class Child(Parent[S, T]): + def task(self, input: S) -> T: ... + + return Child diff --git a/packages/pyright-internal/src/tests/typeEvaluator5.test.ts b/packages/pyright-internal/src/tests/typeEvaluator5.test.ts index f1259b714..bbdd97c54 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator5.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator5.test.ts @@ -73,6 +73,14 @@ test('TypeParams7', () => { TestUtils.validateResults(analysisResults, 4); }); +test('TypeParams8', () => { + const configOptions = new ConfigOptions(Uri.empty()); + configOptions.defaultPythonVersion = pythonVersion3_12; + + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeParams8.py'], configOptions); + TestUtils.validateResults(analysisResults, 0); +}); + test('AutoVariance1', () => { const configOptions = new ConfigOptions(Uri.empty()); configOptions.defaultPythonVersion = pythonVersion3_12; From 0ce78f86afe7c89b0e3f5cb30ac99dde67172890 Mon Sep 17 00:00:00 2001 From: Bill Schnurr Date: Wed, 30 Oct 2024 09:28:17 -0700 Subject: [PATCH 02/11] pull-pylance-with-pyright-1.1.387 (#9363) Co-authored-by: Rich Chiodo --- .../pyright-internal/src/analyzer/binder.ts | 17 +--------- .../src/analyzer/declaration.ts | 4 --- .../src/analyzer/sourceFile.ts | 6 +--- .../src/languageService/hoverProvider.ts | 34 ++++++++++++++++--- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/binder.ts b/packages/pyright-internal/src/analyzer/binder.ts index c1585aacd..58a04999d 100644 --- a/packages/pyright-internal/src/analyzer/binder.ts +++ b/packages/pyright-internal/src/analyzer/binder.ts @@ -22,7 +22,6 @@ import { DiagnosticLevel } from '../common/configOptions'; import { assert, assertNever, fail } from '../common/debug'; import { CreateTypeStubFileAction, Diagnostic } from '../common/diagnostic'; import { DiagnosticRule } from '../common/diagnosticRules'; -import { DocStringService } from '../common/docStringService'; import { stripFileExtension } from '../common/pathUtils'; import { convertTextRangeToRange } from '../common/positionUtils'; import { TextRange, getEmptyRange } from '../common/textRange'; @@ -256,11 +255,7 @@ export class Binder extends ParseTreeWalker { // the current function. private _codeFlowComplexity = 0; - constructor( - fileInfo: AnalyzerFileInfo, - private _docStringService: DocStringService, - private _moduleSymbolOnly = false - ) { + constructor(fileInfo: AnalyzerFileInfo, private _moduleSymbolOnly = false) { super(); this._fileInfo = fileInfo; @@ -542,15 +537,6 @@ export class Binder extends ParseTreeWalker { if (paramNode.d.name) { const symbol = this._bindNameToScope(this._currentScope, paramNode.d.name); - // Extract the parameter docString from the function docString - let docString = ParseTreeUtils.getDocString(node?.d.suite?.d.statements ?? []); - if (docString !== undefined) { - docString = this._docStringService.extractParameterDocumentation( - docString, - paramNode.d.name.d.value - ); - } - if (symbol) { const paramDeclaration: ParamDeclaration = { type: DeclarationType.Param, @@ -559,7 +545,6 @@ export class Binder extends ParseTreeWalker { range: convertTextRangeToRange(paramNode, this._fileInfo.lines), moduleName: this._fileInfo.moduleName, isInExceptSuite: this._isInExceptSuite, - docString: docString, }; symbol.addDeclaration(paramDeclaration); diff --git a/packages/pyright-internal/src/analyzer/declaration.ts b/packages/pyright-internal/src/analyzer/declaration.ts index dca2d6456..9b1220eb5 100644 --- a/packages/pyright-internal/src/analyzer/declaration.ts +++ b/packages/pyright-internal/src/analyzer/declaration.ts @@ -109,10 +109,6 @@ export interface ParamDeclaration extends DeclarationBase { type: DeclarationType.Param; node: ParameterNode; - // Documentation specified in the function's docstring (if any) can be - // associated with the parameter - docString?: string; - // Inferred parameters can be inferred from pieces of an actual NameNode, so this // value represents the actual 'name' as the user thinks of it. inferredName?: string; diff --git a/packages/pyright-internal/src/analyzer/sourceFile.ts b/packages/pyright-internal/src/analyzer/sourceFile.ts index f28f34029..78d9c0c09 100644 --- a/packages/pyright-internal/src/analyzer/sourceFile.ts +++ b/packages/pyright-internal/src/analyzer/sourceFile.ts @@ -823,11 +823,7 @@ export class SourceFile { ); AnalyzerNodeInfo.setFileInfo(this._writableData.parserOutput!.parseTree, fileInfo); - const binder = new Binder( - fileInfo, - this.serviceProvider.docStringService(), - configOptions.indexGenerationMode - ); + const binder = new Binder(fileInfo, configOptions.indexGenerationMode); this._writableData.isBindingInProgress = true; binder.bindModule(this._writableData.parserOutput!.parseTree); diff --git a/packages/pyright-internal/src/languageService/hoverProvider.ts b/packages/pyright-internal/src/languageService/hoverProvider.ts index 3a04d75c9..d429afa06 100644 --- a/packages/pyright-internal/src/languageService/hoverProvider.ts +++ b/packages/pyright-internal/src/languageService/hoverProvider.ts @@ -94,6 +94,35 @@ export function convertHoverResults(hoverResults: HoverResults | null, format: M }; } +export function addParameterResultsPart( + serviceProvider: ServiceProvider, + paramNameNode: NameNode, + resolvedDecl: Declaration | undefined, + format: MarkupKind, + parts: HoverTextPart[] +) { + // See if we have a docstring for the parent function. + let docString: string | undefined = undefined; + const funcNode = ParseTreeUtils.getEnclosingFunction(resolvedDecl?.node || paramNameNode); + if (funcNode) { + docString = ParseTreeUtils.getDocString(funcNode?.d.suite?.d.statements ?? []); + if (docString) { + // Compute the docstring now. + docString = serviceProvider + .docStringService() + .extractParameterDocumentation(docString, paramNameNode.d.value, format); + } + } + if (!docString) { + return; + } + + parts.push({ + python: false, + text: docString, + }); +} + export function addDocumentationResultsPart( serviceProvider: ServiceProvider, docString: string | undefined, @@ -376,10 +405,7 @@ export class HoverProvider { case DeclarationType.Param: { this._addResultsPart(parts, '(parameter) ' + node.d.value + this._getTypeText(node), /* python */ true); - - if (resolvedDecl.docString) { - this._addResultsPart(parts, resolvedDecl.docString); - } + addParameterResultsPart(this._program.serviceProvider, node, resolvedDecl, this._format, parts); this._addDocumentationPart(parts, node, resolvedDecl); break; } From e054478a3c026c0754979c72345d270c4b2d325a Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Wed, 30 Oct 2024 16:20:54 -0700 Subject: [PATCH 03/11] Enhanced the special-case logic for functools.partial so it handles the case where the function has a `**kwargs` parameter typed with an unpacked TypedDict. This addresses #9181. (#9365) --- .../src/analyzer/constructorTransform.ts | 27 +++++++++++++++++- .../src/analyzer/parameterUtils.ts | 2 ++ .../src/tests/samples/partial7.py | 28 +++++++++++++++++++ .../src/tests/typeEvaluator8.test.ts | 6 ++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 packages/pyright-internal/src/tests/samples/partial7.py diff --git a/packages/pyright-internal/src/analyzer/constructorTransform.ts b/packages/pyright-internal/src/analyzer/constructorTransform.ts index 3334945f0..6ebe74d56 100644 --- a/packages/pyright-internal/src/analyzer/constructorTransform.ts +++ b/packages/pyright-internal/src/analyzer/constructorTransform.ts @@ -18,6 +18,7 @@ import { ArgCategory, ExpressionNode, ParamCategory } from '../parser/parseNodes import { ConstraintTracker } from './constraintTracker'; import { createFunctionFromConstructor } from './constructors'; import { getParamListDetails, ParamKind } from './parameterUtils'; +import { getTypedDictMembersForClass } from './typedDicts'; import { Arg, FunctionResult, TypeEvaluator } from './typeEvaluatorTypes'; import { AnyType, @@ -31,8 +32,10 @@ import { isOverloaded, isTypeSame, isTypeVar, + isUnpackedClass, OverloadedType, Type, + TypedDictEntry, } from './types'; import { convertToInstance, lookUpObjectMember, makeInferenceContext, MemberAccessFlags } from './typeUtils'; @@ -404,7 +407,29 @@ function applyPartialTransformToFunction( // Create a new parameter list that omits parameters that have been // populated already. const updatedParamList: FunctionParam[] = specializedFunctionType.shared.parameters.map((param, index) => { - const newType = FunctionType.getParamType(specializedFunctionType, index); + let newType = FunctionType.getParamType(specializedFunctionType, index); + + // If this is an **kwargs with an unpacked TypedDict, mark the provided + // TypedDict entries as provided. + if ( + param.category === ParamCategory.KwargsDict && + isClassInstance(newType) && + isUnpackedClass(newType) && + ClassType.isTypedDictClass(newType) + ) { + const typedDictEntries = getTypedDictMembersForClass(evaluator, newType); + const narrowedEntriesMap = new Map(newType.priv.typedDictNarrowedEntries ?? []); + + typedDictEntries.knownItems.forEach((entry, name) => { + if (paramMap.has(name)) { + narrowedEntriesMap.set(name, { ...entry, isRequired: false }); + } + }); + + newType = ClassType.cloneAsInstance( + ClassType.cloneForNarrowedTypedDictEntries(newType, narrowedEntriesMap) + ); + } // If it's a keyword parameter that has been assigned a value through // the "partial" mechanism, mark it has having a default value. diff --git a/packages/pyright-internal/src/analyzer/parameterUtils.ts b/packages/pyright-internal/src/analyzer/parameterUtils.ts index 53caf7b47..022ff3327 100644 --- a/packages/pyright-internal/src/analyzer/parameterUtils.ts +++ b/packages/pyright-internal/src/analyzer/parameterUtils.ts @@ -242,6 +242,8 @@ export function getParamListDetails(type: FunctionType): ParamListDetails { const typedDictType = paramType; paramType.shared.typedDictEntries.knownItems.forEach((entry, name) => { + entry = paramType.priv.typedDictNarrowedEntries?.get(name) ?? entry; + const specializedParamType = partiallySpecializeType( entry.valueType, typedDictType, diff --git a/packages/pyright-internal/src/tests/samples/partial7.py b/packages/pyright-internal/src/tests/samples/partial7.py new file mode 100644 index 000000000..53ff80e77 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/partial7.py @@ -0,0 +1,28 @@ +# This sample tests the case where functools.partial is applied to +# a function that has a **kwargs parameter that is typed as an +# unpacked TypedDict. + +from functools import partial +from typing import TypedDict, NotRequired, Unpack + + +class TD1(TypedDict): + c: list[str] + a: int + b: NotRequired[str] + + +def func1(**kwargs: Unpack[TD1]) -> None: + print(f"a: {kwargs['a']}, b: {kwargs.get( 'b' )}, c: {kwargs['c']}") + + +func1_1 = partial(func1, c=["a", "b"], a=2) +func1_1(b="2") + +func1_2 = partial(func1, a=2, b="", c=["a", "b"]) +func1_2(a=2, b="2") + +func1_3 = partial(func1, c=["a", "b"]) + +# This should generate an error. +func1_3(b="2") diff --git a/packages/pyright-internal/src/tests/typeEvaluator8.test.ts b/packages/pyright-internal/src/tests/typeEvaluator8.test.ts index a5994d09b..32ad5f1c9 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator8.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator8.test.ts @@ -761,6 +761,12 @@ test('Partial6', () => { TestUtils.validateResults(analysisResults, 2); }); +test('Partial7', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['partial7.py']); + + TestUtils.validateResults(analysisResults, 1); +}); + test('TotalOrdering1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['totalOrdering1.py']); From f7b6099d24f1af9075cb54cfae261abd54945db0 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Wed, 30 Oct 2024 17:32:40 -0700 Subject: [PATCH 04/11] Fixed a bug that results in unexpected constraint solver results in certain cases involving arguments with lambda expressions. This addresses #8697. (#9367) --- .../src/analyzer/typeUtils.ts | 59 +++++++++++-------- .../src/tests/samples/solver44.py | 13 ++++ .../src/tests/typeEvaluator2.test.ts | 6 ++ 3 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 packages/pyright-internal/src/tests/samples/solver44.py diff --git a/packages/pyright-internal/src/analyzer/typeUtils.ts b/packages/pyright-internal/src/analyzer/typeUtils.ts index 10592ec77..6ad73150e 100644 --- a/packages/pyright-internal/src/analyzer/typeUtils.ts +++ b/packages/pyright-internal/src/analyzer/typeUtils.ts @@ -4202,30 +4202,43 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer { // in cases where TypeVars can go unsolved due to unions in parameter // annotations, like this: // def test(x: Union[str, T]) -> Union[str, T] - if (this._options.replaceUnsolved?.eliminateUnsolvedInUnions) { - if ( - isTypeVar(preTransform) && - this._shouldReplaceTypeVar(preTransform) && - this._shouldReplaceUnsolvedTypeVar(preTransform) - ) { - const solutionSet = this._solution.getSolutionSet(this._activeConstraintSetIndex ?? 0); - const typeVarType = solutionSet.getType(preTransform); - - // Did the TypeVar remain unsolved? - if (!typeVarType || (isTypeVar(typeVarType) && TypeVarType.isUnification(typeVarType))) { - // If the TypeVar was not transformed, then it was unsolved, - // and we'll eliminate it. - if (preTransform === postTransform) { - return undefined; - } + if (!this._options.replaceUnsolved?.eliminateUnsolvedInUnions) { + return postTransform; + } - // If useDefaultForUnsolved or useUnknownForUnsolved is true, the postTransform type will - // be Unknown, which we want to eliminate. - if (this._options.replaceUnsolved) { - if (isUnknown(postTransform)) { - return undefined; - } - } + const solutionSet = this._solution.getSolutionSet(this._activeConstraintSetIndex ?? 0); + + if (isTypeVar(preTransform)) { + if (!this._shouldReplaceTypeVar(preTransform) || !this._shouldReplaceUnsolvedTypeVar(preTransform)) { + return postTransform; + } + + const typeVarType = solutionSet.getType(preTransform); + + // Did the TypeVar remain unsolved? + if (typeVarType) { + if (!isTypeVar(typeVarType) || !TypeVarType.isUnification(typeVarType)) { + return postTransform; + } + } + + // If the TypeVar was not transformed, then it was unsolved, + // and we'll eliminate it. + if (preTransform === postTransform) { + return undefined; + } + + // If useDefaultForUnsolved or useUnknownForUnsolved is true, the postTransform type will + // be Unknown, which we want to eliminate. + if (this._options.replaceUnsolved && isUnknown(postTransform)) { + return undefined; + } + } else if (preTransform.props?.condition) { + // If this is a type that is conditioned on a unification TypeVar, + // see if TypeVar was solved. If not, eliminate the type. + for (const condition of preTransform.props.condition) { + if (TypeVarType.isUnification(condition.typeVar) && !solutionSet.getType(condition.typeVar)) { + return undefined; } } } diff --git a/packages/pyright-internal/src/tests/samples/solver44.py b/packages/pyright-internal/src/tests/samples/solver44.py new file mode 100644 index 000000000..31735645e --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/solver44.py @@ -0,0 +1,13 @@ +# This sample tests the case where the solver generates an unsolved +# unification variable that has been specialized into a conditional type. + +from typing import Callable, Iterable, Self + + +class map[S]: + def __new__[T](cls, func: Callable[[T], S], iter1: Iterable[T]) -> Self: ... + + +def func(a: list[int | None]): + b = map(lambda x: x or 0, a) + reveal_type(b, expected_text="map[int]") diff --git a/packages/pyright-internal/src/tests/typeEvaluator2.test.ts b/packages/pyright-internal/src/tests/typeEvaluator2.test.ts index 899e29dc9..155ed7cce 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator2.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator2.test.ts @@ -831,6 +831,12 @@ test('Solver43', () => { TestUtils.validateResults(analysisResults, 0); }); +test('Solver44', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solver44.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + test('SolverScoring1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverScoring1.py']); From 8ee65a67fef371ffd383eb91c6d261e02bc62917 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Fri, 1 Nov 2024 14:18:23 -0700 Subject: [PATCH 05/11] Improved the synthesized type of the `keys`, `values` and `items` methods on a closed TypedDict to provide a more precise (narrower) type for the key values. --- .../pyright-internal/src/analyzer/typedDicts.ts | 12 +++++++++++- .../src/tests/samples/typedDictClosed5.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/pyright-internal/src/analyzer/typedDicts.ts b/packages/pyright-internal/src/analyzer/typedDicts.ts index caa2fd9b1..7e0e55de2 100644 --- a/packages/pyright-internal/src/analyzer/typedDicts.ts +++ b/packages/pyright-internal/src/analyzer/typedDicts.ts @@ -761,6 +761,16 @@ export function synthesizeTypedDictClassMethods( const mappingValueType = getTypedDictMappingEquivalent(evaluator, classType); if (mappingValueType) { + let keyValueType: Type = strType; + + // If we know that there can be no more items, we can provide + // a more accurate key type consisting of all known keys. + if (entries.extraItems && isNever(entries.extraItems.valueType)) { + keyValueType = combineTypes( + Array.from(entries.knownItems.keys()).map((key) => ClassType.cloneWithLiteral(strType, key)) + ); + } + ['items', 'keys', 'values'].forEach((methodName) => { const method = FunctionType.createSynthesizedInstance(methodName); FunctionType.addParam(method, selfParam); @@ -773,7 +783,7 @@ export function synthesizeTypedDictClassMethods( ) { method.shared.declaredReturnType = ClassType.specialize( ClassType.cloneAsInstance(returnTypeClass), - [strType, mappingValueType] + [keyValueType, mappingValueType] ); symbolTable.set(methodName, Symbol.createWithType(SymbolFlags.ClassMember, method)); diff --git a/packages/pyright-internal/src/tests/samples/typedDictClosed5.py b/packages/pyright-internal/src/tests/samples/typedDictClosed5.py index 5f004693c..8b2c9ed5e 100644 --- a/packages/pyright-internal/src/tests/samples/typedDictClosed5.py +++ b/packages/pyright-internal/src/tests/samples/typedDictClosed5.py @@ -37,3 +37,20 @@ def func2(movie: MovieNotClosed) -> None: reveal_type(movie.items(), expected_text="dict_items[str, object]") reveal_type(movie.keys(), expected_text="dict_keys[str, object]") reveal_type(movie.values(), expected_text="dict_values[str, object]") + + +class MovieClosed(TypedDict, closed=True): + name: str + year: int + + +def func3(movie: MovieClosed) -> None: + reveal_type( + movie.items(), expected_text="dict_items[Literal['name', 'year'], str | int]" + ) + reveal_type( + movie.keys(), expected_text="dict_keys[Literal['name', 'year'], str | int]" + ) + reveal_type( + movie.values(), expected_text="dict_values[Literal['name', 'year'], str | int]" + ) From d8391e6fc12a92082c93246c8cda1594b96c1430 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 2 Nov 2024 20:21:59 -0700 Subject: [PATCH 06/11] Improved the handling of a TypeVar whose definition involves a circular definition. This partially addresses #9353. (#9377) --- .../pyright-internal/src/analyzer/checker.ts | 6 +++++ .../src/analyzer/typeEvaluator.ts | 25 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/checker.ts b/packages/pyright-internal/src/analyzer/checker.ts index e3bdba5c1..c1c9d31c4 100644 --- a/packages/pyright-internal/src/analyzer/checker.ts +++ b/packages/pyright-internal/src/analyzer/checker.ts @@ -5357,6 +5357,12 @@ export class Checker extends ParseTreeWalker { return; } + // Skip type variables that have been internally synthesized + // for a variety of reasons. + if (param.shared.isSynthesized) { + return; + } + // Skip type variables with auto-variance. if (param.shared.declaredVariance === Variance.Auto) { return; diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index f78ae9c69..a1467b287 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -17232,8 +17232,7 @@ export function createTypeEvaluator( arg.d.valueExpr ); } - genericTypeParams = []; - addTypeVarsToListIfUnique(genericTypeParams, getTypeVarArgsRecursive(argType)); + genericTypeParams = buildTypeParamsFromTypeArgs(argType); } } } else if ( @@ -17249,8 +17248,7 @@ export function createTypeEvaluator( arg.d.valueExpr ); } - protocolTypeParams = []; - addTypeVarsToListIfUnique(protocolTypeParams, getTypeVarArgsRecursive(argType)); + protocolTypeParams = buildTypeParamsFromTypeArgs(argType); if (node.d.typeParams && protocolTypeParams.length > 0) { addDiagnostic( @@ -17749,6 +17747,25 @@ export function createTypeEvaluator( }); } + function buildTypeParamsFromTypeArgs(classType: ClassType): TypeVarType[] { + const typeParams: TypeVarType[] = []; + const typeArgs = classType.priv.typeArgs ?? []; + + typeArgs.forEach((typeArg, index) => { + if (isTypeVar(typeArg)) { + typeParams.push(typeArg); + return; + } + + // Synthesize a dummy type parameter. + const typeVar = TypeVarType.createInstance(`__P${index}`); + typeVar.shared.isSynthesized = true; + typeParams.push(typeVar); + }); + + return typeParams; + } + // Determines whether the type parameters has a default that refers to another // type parameter. If so, validates that it is in the list of "live" type // parameters and updates the scope of the type parameter referred to in the From 3d9c95f49848539f48da31626c7729ca12bc65ec Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sun, 3 Nov 2024 15:45:16 -0800 Subject: [PATCH 07/11] Fixed bug that results in false positive under certain circumstances involving classes parameterized with a contravariant type variable. This addresses #9054. (#9379) --- .../src/analyzer/typeEvaluator.ts | 2 +- .../src/tests/samples/overloadImpl1.py | 336 ++++-------------- .../src/tests/samples/overloadImpl2.py | 145 ++++++++ .../src/tests/typeEvaluator6.test.ts | 7 +- 4 files changed, 223 insertions(+), 267 deletions(-) create mode 100644 packages/pyright-internal/src/tests/samples/overloadImpl2.py diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index a1467b287..71653a3fe 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -23876,7 +23876,7 @@ export function createTypeEvaluator( effectiveFlags = flags | AssignTypeFlags.RetainLiteralsForTypeVar; errorSource = LocAddendum.typeVarIsCovariant; } else if (variance === Variance.Contravariant) { - effectiveFlags = (flags ^ AssignTypeFlags.Contravariant) | AssignTypeFlags.RetainLiteralsForTypeVar; + effectiveFlags = flags | AssignTypeFlags.Contravariant | AssignTypeFlags.RetainLiteralsForTypeVar; errorSource = LocAddendum.typeVarIsContravariant; } else { effectiveFlags = flags | AssignTypeFlags.Invariant | AssignTypeFlags.RetainLiteralsForTypeVar; diff --git a/packages/pyright-internal/src/tests/samples/overloadImpl1.py b/packages/pyright-internal/src/tests/samples/overloadImpl1.py index c054ecb0c..13842efd3 100644 --- a/packages/pyright-internal/src/tests/samples/overloadImpl1.py +++ b/packages/pyright-internal/src/tests/samples/overloadImpl1.py @@ -9,22 +9,19 @@ Iterable, Literal, NoReturn, - ParamSpec, - Protocol, TypeVar, - TypeVarTuple, overload, ) +T = TypeVar("T") + @overload -def func1(a: int) -> str: - ... +def func1(a: int) -> str: ... @overload -def func1(a: str) -> int: - ... +def func1(a: str) -> int: ... # This should generate two errors: @@ -37,420 +34,229 @@ def func1(a: str) -> str: @overload -def func2(a: int, b: str = ...) -> str: - ... +def func2(a: int, b: str = ...) -> str: ... @overload -def func2(a: None) -> str: - ... +def func2(a: None) -> str: ... # This should generate an error because the parameter "b" is missing # from the implementation but is required by overload 1. -def func2(a: int | None) -> str: - ... +def func2(a: int | None) -> str: ... @overload -def func3(a: int, *, b: Literal["r"]) -> str: - ... +def func3(a: int, *, b: Literal["r"]) -> str: ... @overload -def func3(a: int, *, b: Literal["b"]) -> bytes: - ... - - -def func3(*args: Any, **kwargs: Any) -> Any: - ... +def func3(a: int, *, b: Literal["b"]) -> bytes: ... -_T = TypeVar("_T") +def func3(*args: Any, **kwargs: Any) -> Any: ... @overload -def func4(a: None) -> None: - ... +def func4(a: None) -> None: ... @overload -def func4(a: list[_T]) -> _T: - ... +def func4(a: list[T]) -> T: ... -def func4(a: list[_T] | None) -> _T | None: - ... +def func4(a: list[T] | None) -> T | None: ... -class A: +class ClassA: @overload - def method4(self, a: None) -> None: - ... + def method4(self, a: None) -> None: ... @overload - def method4(self, a: list[_T]) -> _T: - ... + def method4(self, a: list[T]) -> T: ... - def method4(self, a: list[_T] | None) -> _T | None: - ... + def method4(self, a: list[T] | None) -> T | None: ... @overload -def func5(a: list[_T]) -> _T: - ... +def func5(a: list[T]) -> T: ... @overload -def func5(a: None) -> None: - ... +def func5(a: None) -> None: ... # This should generate an error because list is not compatible with dict. -def func5(a: dict[Any, Any] | None) -> Any | None: - ... +def func5(a: dict[Any, Any] | None) -> Any | None: ... @overload -def func6(foo: int, /) -> int: - ... +def func6(foo: int, /) -> int: ... @overload -def func6(bar: str, /) -> int: - ... +def func6(bar: str, /) -> int: ... def func6(p0: int | str, /) -> int: return 3 -_T1 = TypeVar("_T1") - - -class ClassA(Generic[_T1]): +class ClassB(Generic[T]): @overload - def method1(self: "ClassA[None]") -> None: - ... + def method1(self: "ClassB[None]") -> None: ... @overload - def method1(self, value: _T1) -> None: - ... + def method1(self, value: T) -> None: ... - def method1(self, value: Any = None) -> None: - ... + def method1(self, value: Any = None) -> None: ... -class ClassB: - ... +class ClassC: ... -class ClassC: - ... +class ClassD: ... -_T2 = TypeVar("_T2", ClassB, ClassC) +T_CD = TypeVar("T_CD", ClassC, ClassD) @overload -def func7(cls: type[ClassB], var: int) -> ClassB: - ... +def func7(cls: type[ClassC], var: int) -> ClassC: ... @overload -def func7(cls: type[ClassC], var: str) -> ClassC: - ... +def func7(cls: type[ClassD], var: str) -> ClassD: ... -def func7(cls: type[_T2], var: int | str) -> _T2: +def func7(cls: type[T_CD], var: int | str) -> T_CD: return cls() -_T3 = TypeVar("_T3", bound=str) +T_str = TypeVar("T_str", bound=str) @overload -def func8(foo: int) -> int: - ... +def func8(foo: int) -> int: ... @overload -def func8(foo: _T3) -> tuple[_T3]: - ... +def func8(foo: T_str) -> tuple[T_str]: ... -def func8(foo: _T3 | int) -> tuple[_T3] | int: - ... +def func8(foo: T_str | int) -> tuple[T_str] | int: ... -class Foo: - ... +class ClassE: ... -_T4 = TypeVar("_T4", bound=Foo) +T_E = TypeVar("T_E", bound=ClassE) @overload -def func9() -> None: - ... +def func9() -> None: ... @overload -def func9(bar: _T4) -> _T4: - ... +def func9(bar: T_E) -> T_E: ... -def func9(bar: _T4 | None = None) -> _T4 | None: +def func9(bar: T_E | None = None) -> T_E | None: raise NotImplementedError -_T5 = TypeVar("_T5", int, str) +T_int_str = TypeVar("T_int_str", int, str) @overload -def func10(option: Literal["a"], var: str) -> str: - ... +def func10(option: Literal["a"], var: str) -> str: ... @overload -def func10(option: Literal["b"], var: int) -> str: - ... +def func10(option: Literal["b"], var: int) -> str: ... # This should generate an error. -def func10(option: Literal["a", "b"], var: _T5) -> _T5: - ... +def func10(option: Literal["a", "b"], var: T_int_str) -> T_int_str: ... -class X: - ... +class ClassF: ... -_T6 = TypeVar("_T6", bound=type[X]) +T_F = TypeVar("T_F", bound=type[ClassF]) @overload -def func11(var: _T6) -> _T6: - ... +def func11(var: T_F) -> T_F: ... @overload -def func11(var: int) -> int: - ... +def func11(var: int) -> int: ... -def func11(var: _T6 | int) -> _T6 | int: - ... +def func11(var: T_F | int) -> T_F | int: ... -_T7 = TypeVar("_T7") -_T8 = TypeVar("_T8") -_T9 = TypeVar("_T9") +T7 = TypeVar("T7") +T8 = TypeVar("T8") +T9 = TypeVar("T9") @overload def func12( - func: Callable[[_T7], _T8], iterable: Iterable[_T7], default_value: None = None, / -) -> Iterable[_T8 | None]: - ... + func: Callable[[T7], T8], iterable: Iterable[T7], default_value: None = None, / +) -> Iterable[T8 | None]: ... @overload def func12( - func: Callable[[_T7], _T8], iterable: Iterable[_T7], /, default_value: _T9 -) -> Iterable[_T8 | _T9]: - ... + func: Callable[[T7], T8], iterable: Iterable[T7], /, default_value: T9 +) -> Iterable[T8 | T9]: ... def func12( - func: Callable[[_T7], _T8], - iterable: Iterable[_T7], + func: Callable[[T7], T8], + iterable: Iterable[T7], /, - default_value: _T9 = None, -) -> Iterable[_T8 | _T9]: - ... + default_value: T9 = None, +) -> Iterable[T8 | T9]: ... @overload -def func13(x: int) -> NoReturn: - ... +def func13(x: int) -> NoReturn: ... @overload -def func13(x: str) -> str | NoReturn: - ... +def func13(x: str) -> str | NoReturn: ... -def func13(x: int | str) -> str: - ... +def func13(x: int | str) -> str: ... -_T14 = TypeVar("_T14") - - -class Wrapper1(Generic[_T14]): - ... +class ClassG(Generic[T]): ... @overload -def func14(target: Callable[..., Awaitable[_T14]]) -> Wrapper1[_T14]: - ... +def func14(target: Callable[..., Awaitable[T]]) -> ClassG[T]: ... @overload -def func14(target: Callable[..., _T14]) -> Wrapper1[_T14]: - ... +def func14(target: Callable[..., T]) -> ClassG[T]: ... def func14( - target: Callable[..., Awaitable[_T14]] | Callable[..., _T14], -) -> Wrapper1[_T14]: - ... + target: Callable[..., Awaitable[T]] | Callable[..., T], +) -> ClassG[T]: ... @overload -def func15(client_id: str, client_secret: str, /) -> None: - ... +def func15(client_id: str, client_secret: str, /) -> None: ... @overload -def func15(client_id: str, client_secret: str) -> None: - ... +def func15(client_id: str, client_secret: str) -> None: ... # This should generate an error because some of the keyword arguments are not present. def func15(*creds: str) -> None: pass - - -T1 = TypeVar("T1", covariant=True) -T2 = TypeVar("T2", bound=Callable[..., Any]) -R = TypeVar("R") -P = ParamSpec("P") - - -class Builds(Protocol[T1]): - _target_: str - - -class BuildsWithSig(Builds[T1], Protocol[T1, P]): - def __init__(self, *args: P.args, **kwds: P.kwargs): - ... - - -class ClassD(Protocol): - @overload - def __call__( - self, - x: Callable[P, R], - *, - sig: Literal[True] = ..., - ) -> BuildsWithSig[type[R], P]: - ... - - @overload - def __call__(self, x: T2, *, sig: Literal[False] = ...) -> Builds[type[T2]]: - ... - - @overload - def __call__( - self, x: T2 | Callable[P, R], *, sig: bool - ) -> Builds[type[T2]] | BuildsWithSig[type[R], P]: - ... - - def __call__( - self, x: T2 | Callable[P, R], *, sig: bool = False - ) -> Builds[type[T2]] | BuildsWithSig[type[R], P]: - ... - - -Ts = TypeVarTuple("Ts") - -Func = Callable[[*Ts], None] - - -@overload -def func16(function: Func[*Ts]) -> Func[*Ts]: - ... - - -@overload -def func16() -> Callable[[Func[*Ts]], Func[*Ts]]: - ... - - -def func16( - function: Func[*Ts] | None = None, -) -> Func[*Ts] | Callable[[Func[*Ts]], Func[*Ts]]: - ... - - -@overload -def func17(d: dict[str, float], /) -> None: - ... - - -@overload -def func17(**kwargs: float) -> None: - ... - - -def func17(d: dict[str, float] | None = None, /, **kwargs: float) -> None: - pass - - -@overload -def func18(a: int) -> int: - ... - - -@overload -def func18(*args: int) -> int: - ... - - -# This should generate an error because the keyword parameter "a" is missing. -def func18(*args: int) -> int: - ... - - -@overload -def func19(a: int) -> int: - ... - - -@overload -def func19(*args: int) -> int: - ... - - -def func19(*args: int, a: int = 1) -> int: - ... - - -@overload -def func20(a: int) -> int: - ... - - -@overload -def func20(*args: int) -> int: - ... - - -def func20(*args: int, **kwargs: int) -> int: - ... - - -@overload -def func21(x: tuple[()], /) -> None: - ... - - -@overload -def func21(x: tuple[object], /) -> None: - ... - - -def func21(x: tuple[object, ...], /) -> None: - ... diff --git a/packages/pyright-internal/src/tests/samples/overloadImpl2.py b/packages/pyright-internal/src/tests/samples/overloadImpl2.py new file mode 100644 index 000000000..47936c912 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/overloadImpl2.py @@ -0,0 +1,145 @@ +# This sample tests the verification that overload implementation signatures +# are a superset of their associated overload signatures. + +from typing import ( + Any, + Callable, + Generic, + Literal, + ParamSpec, + Protocol, + TypeVar, + TypeVarTuple, + overload, +) + + +T = TypeVar("T") +T_contra = TypeVar("T_contra", contravariant=True) +T_co = TypeVar("T_co", covariant=True) +TCall = TypeVar("TCall", bound=Callable[..., Any]) +R = TypeVar("R") +P = ParamSpec("P") +Ts = TypeVarTuple("Ts") + + +class ClassA(Protocol[T_co]): + _target_: str + + +class ClassB(ClassA[T_co], Protocol[T_co, P]): + def __init__(self, *args: P.args, **kwds: P.kwargs): ... + + +class ClassC(Protocol): + @overload + def __call__( + self, + x: Callable[P, R], + *, + sig: Literal[True] = ..., + ) -> ClassB[type[R], P]: ... + + @overload + def __call__( + self, x: TCall, *, sig: Literal[False] = ... + ) -> ClassA[type[TCall]]: ... + + @overload + def __call__( + self, x: TCall | Callable[P, R], *, sig: bool + ) -> ClassA[type[TCall]] | ClassB[type[R], P]: ... + + def __call__( + self, x: TCall | Callable[P, R], *, sig: bool = False + ) -> ClassA[type[TCall]] | ClassB[type[R], P]: ... + + +Func = Callable[[*Ts], None] + + +@overload +def func1(function: Func[*Ts]) -> Func[*Ts]: ... + + +@overload +def func1() -> Callable[[Func[*Ts]], Func[*Ts]]: ... + + +def func1( + function: Func[*Ts] | None = None, +) -> Func[*Ts] | Callable[[Func[*Ts]], Func[*Ts]]: ... + + +@overload +def func2(d: dict[str, float], /) -> None: ... + + +@overload +def func2(**kwargs: float) -> None: ... + + +def func2(d: dict[str, float] | None = None, /, **kwargs: float) -> None: + pass + + +@overload +def func3(a: int) -> int: ... + + +@overload +def func3(*args: int) -> int: ... + + +# This should generate an error because the keyword parameter "a" is missing. +def func3(*args: int) -> int: ... + + +@overload +def func4(a: int) -> int: ... + + +@overload +def func4(*args: int) -> int: ... + + +def func4(*args: int, a: int = 1) -> int: ... + + +@overload +def func5(a: int) -> int: ... + + +@overload +def func5(*args: int) -> int: ... + + +def func5(*args: int, **kwargs: int) -> int: ... + + +@overload +def func6(x: tuple[()], /) -> None: ... + + +@overload +def func6(x: tuple[object], /) -> None: ... + + +def func6(x: tuple[object, ...], /) -> None: ... + + +class ClassD(Generic[T_contra]): + def method(self, x: T_contra) -> int: + assert False + + +@overload +def func7(x: None) -> int: ... + + +@overload +def func7(x: ClassD[T]) -> int: ... + + +def func7(x: ClassD[T] | None) -> int: + assert False diff --git a/packages/pyright-internal/src/tests/typeEvaluator6.test.ts b/packages/pyright-internal/src/tests/typeEvaluator6.test.ts index 5551158ef..1e89799dd 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator6.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator6.test.ts @@ -96,7 +96,12 @@ test('OverloadOverride1', () => { test('OverloadImpl1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['overloadImpl1.py']); - TestUtils.validateResults(analysisResults, 7); + TestUtils.validateResults(analysisResults, 6); +}); + +test('OverloadImpl2', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['overloadImpl2.py']); + TestUtils.validateResults(analysisResults, 1); }); test('OverloadOverlap1', () => { From 6fb940a761b456a8dcf2f63bbff851c68ee3653a Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 4 Nov 2024 09:00:28 -0800 Subject: [PATCH 08/11] Fixed bug that results in incorrect evaluation of class variables assigned in an `__init_subclass__` or `__class_getitem__` method. These methods are implicitly class methods even though they are not decorated with `@classmethod`. This addresses https://github.com/microsoft/pylance-release/discussions/2781. (#9381) --- packages/pyright-internal/src/analyzer/binder.ts | 7 ++++--- .../src/tests/samples/initsubclass1.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/binder.ts b/packages/pyright-internal/src/analyzer/binder.ts index 58a04999d..49eb10d7c 100644 --- a/packages/pyright-internal/src/analyzer/binder.ts +++ b/packages/pyright-internal/src/analyzer/binder.ts @@ -4033,9 +4033,10 @@ export class Binder extends ParseTreeWalker { // To determine whether the first parameter of the method // refers to the class or the instance, we need to apply // some heuristics. - if (methodNode.d.name.d.value === '__new__') { - // The __new__ method is special. It acts as a classmethod even - // though it doesn't have a @classmethod decorator. + const implicitClassMethods = ['__new__', '__init_subclass__', '__class_getitem__']; + if (implicitClassMethods.includes(methodNode.d.name.d.value)) { + // Several methods are special. They act as class methods even + // though they don't have a @classmethod decorator. isInstanceMember = false; } else { // Assume that it's an instance member unless we find diff --git a/packages/pyright-internal/src/tests/samples/initsubclass1.py b/packages/pyright-internal/src/tests/samples/initsubclass1.py index fa6b5673c..f39eb94cb 100644 --- a/packages/pyright-internal/src/tests/samples/initsubclass1.py +++ b/packages/pyright-internal/src/tests/samples/initsubclass1.py @@ -62,3 +62,14 @@ class ClassH(ClassG): # in the object.__init_subclass__ method. class ClassI(a=3): a: int + + +class ClassJ: + def __init_subclass__(cls, **kwargs: Any) -> None: + super().__init_subclass__(**kwargs) + cls.custom_attribute = 9 + + +class ClassJChild(ClassJ): + def __init__(self): + reveal_type(self.custom_attribute, expected_text="int") From ae9160e13e452d947b9a4d70f57e0546c6a8d5c8 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Tue, 5 Nov 2024 08:39:29 -0800 Subject: [PATCH 09/11] Added check for `__slots__` initialization when the `__slots__` list is empty and the class is marked `@final`. This addresses #9387. (#9389) --- packages/pyright-internal/src/analyzer/typeEvaluator.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 71653a3fe..008ace33d 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -3693,10 +3693,11 @@ export function createTypeEvaluator( const inheritedSlotsNames = ClassType.getInheritedSlotsNames(memberClass); if (inheritedSlotsNames && memberClass.shared.localSlotsNames) { - // Skip this check if the local slots is specified but empty because this pattern - // is used in a legitimate manner for mix-in classes. + // Skip this check if the local slots is specified but empty + // and the class isn't final. This pattern is used in a + // legitimate manner for mix-in classes. if ( - memberClass.shared.localSlotsNames.length > 0 && + (memberClass.shared.localSlotsNames.length > 0 || ClassType.isFinal(memberClass)) && !inheritedSlotsNames.some((name) => name === memberName) ) { // Determine whether the assignment corresponds to a descriptor From d0bc751a248aa54fbf13e29bed8ad9765e8318a6 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Tue, 5 Nov 2024 08:52:41 -0800 Subject: [PATCH 10/11] Removed recent check for illegal identifiers used in `alias` for `dataclass_transform` field. This isn't an illegal condition, so the resulting error was a false positive. Instead, changed completion provider to not suggest the illegal identifier as a valid keyword argument. This addresses #9386, #9220, #9278. (#9390) --- packages/pyright-internal/src/analyzer/dataClasses.ts | 9 --------- .../src/languageService/completionProvider.ts | 6 +++++- packages/pyright-internal/src/localization/localize.ts | 2 -- .../src/localization/package.nls.cs.json | 1 - .../src/localization/package.nls.de.json | 1 - .../src/localization/package.nls.en-us.json | 1 - .../src/localization/package.nls.es.json | 1 - .../src/localization/package.nls.fr.json | 1 - .../src/localization/package.nls.it.json | 1 - .../src/localization/package.nls.ja.json | 1 - .../src/localization/package.nls.ko.json | 1 - .../src/localization/package.nls.pl.json | 1 - .../src/localization/package.nls.pt-br.json | 1 - .../src/localization/package.nls.qps-ploc.json | 1 - .../src/localization/package.nls.ru.json | 1 - .../src/localization/package.nls.tr.json | 1 - .../src/localization/package.nls.zh-cn.json | 1 - .../src/localization/package.nls.zh-tw.json | 1 - .../src/tests/samples/dataclassTransform3.py | 8 -------- .../pyright-internal/src/tests/typeEvaluator5.test.ts | 2 +- 20 files changed, 6 insertions(+), 36 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/dataClasses.ts b/packages/pyright-internal/src/analyzer/dataClasses.ts index 676bb3ed2..5b694e23f 100644 --- a/packages/pyright-internal/src/analyzer/dataClasses.ts +++ b/packages/pyright-internal/src/analyzer/dataClasses.ts @@ -25,7 +25,6 @@ import { ParseNodeType, TypeAnnotationNode, } from '../parser/parseNodes'; -import { Tokenizer } from '../parser/tokenizer'; import * as AnalyzerNodeInfo from './analyzerNodeInfo'; import { getFileInfo } from './analyzerNodeInfo'; import { ConstraintSolution } from './constraintSolution'; @@ -333,14 +332,6 @@ export function synthesizeDataClassMethods( isLiteralType(valueType) ) { aliasName = valueType.priv.literalValue as string; - - if (!Tokenizer.isPythonIdentifier(aliasName)) { - evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, - LocMessage.dataClassFieldInvalidAlias().format({ aliasName }), - aliasArg.d.valueExpr - ); - } } } diff --git a/packages/pyright-internal/src/languageService/completionProvider.ts b/packages/pyright-internal/src/languageService/completionProvider.ts index 2bf0b1dbe..037da522e 100644 --- a/packages/pyright-internal/src/languageService/completionProvider.ts +++ b/packages/pyright-internal/src/languageService/completionProvider.ts @@ -111,6 +111,7 @@ import { TypeAnnotationNode, } from '../parser/parseNodes'; import { ParseFileResults } from '../parser/parser'; +import { Tokenizer } from '../parser/tokenizer'; import { FStringStartToken, OperatorToken, @@ -2893,7 +2894,10 @@ export class CompletionProvider { paramInfo.kind !== ParamKind.Positional && paramInfo.kind !== ParamKind.ExpandedArgs ) { - if (!SymbolNameUtils.isPrivateOrProtectedName(paramInfo.param.name)) { + if ( + !SymbolNameUtils.isPrivateOrProtectedName(paramInfo.param.name) && + Tokenizer.isPythonIdentifier(paramInfo.param.name) + ) { names.add(paramInfo.param.name); } } diff --git a/packages/pyright-internal/src/localization/localize.ts b/packages/pyright-internal/src/localization/localize.ts index 9e2058727..227e0d01c 100644 --- a/packages/pyright-internal/src/localization/localize.ts +++ b/packages/pyright-internal/src/localization/localize.ts @@ -370,8 +370,6 @@ export namespace Localizer { ); export const dataClassFieldInheritedDefault = () => new ParameterizedString<{ fieldName: string }>(getRawString('Diagnostic.dataClassFieldInheritedDefault')); - export const dataClassFieldInvalidAlias = () => - new ParameterizedString<{ aliasName: string }>(getRawString('Diagnostic.dataClassFieldInvalidAlias')); export const dataClassFieldWithDefault = () => getRawString('Diagnostic.dataClassFieldWithDefault'); export const dataClassFieldWithoutAnnotation = () => getRawString('Diagnostic.dataClassFieldWithoutAnnotation'); export const dataClassFieldWithPrivateName = () => getRawString('Diagnostic.dataClassFieldWithPrivateName'); diff --git a/packages/pyright-internal/src/localization/package.nls.cs.json b/packages/pyright-internal/src/localization/package.nls.cs.json index 73d99815c..bbc2ad746 100644 --- a/packages/pyright-internal/src/localization/package.nls.cs.json +++ b/packages/pyright-internal/src/localization/package.nls.cs.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "Argument typu {argType} není platný převaděč pro pole {fieldName} typu {fieldType}", "dataClassConverterOverloads": "Žádná přetížení {funcName} nejsou platné převaděče pro pole {fieldName} typu {fieldType}", "dataClassFieldInheritedDefault": "{fieldName} přepíše pole se stejným názvem, ale chybí mu výchozí hodnota.", - "dataClassFieldInvalidAlias": "Název aliasu {aliasName} není platný identifikátor.", "dataClassFieldWithDefault": "Pole bez výchozích hodnot se nemůžou zobrazit po polích s výchozími hodnotami", "dataClassFieldWithPrivateName": "Pole datové třídy nemůže používat privátní název", "dataClassFieldWithoutAnnotation": "Pole dataclass bez poznámky typu způsobí výjimku modulu runtime", diff --git a/packages/pyright-internal/src/localization/package.nls.de.json b/packages/pyright-internal/src/localization/package.nls.de.json index 5f4924d10..608d81419 100644 --- a/packages/pyright-internal/src/localization/package.nls.de.json +++ b/packages/pyright-internal/src/localization/package.nls.de.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "Das Argument vom Typ \"{argType}\" ist kein gültiger Konverter für das Feld \"{fieldName}\" vom Typ \"{fieldType}\"", "dataClassConverterOverloads": "Keine Überladungen von \"{funcName}\" sind gültige Konverter für das Feld \"{fieldName}\" vom Typ \"{fieldType}\"", "dataClassFieldInheritedDefault": "„{fieldName}“ überschreibt ein Feld mit demselben Namen, aber es fehlt ein Standardwert", - "dataClassFieldInvalidAlias": "Der Aliasname „{aliasName}“ ist kein gültiger Bezeichner.", "dataClassFieldWithDefault": "Felder ohne Standardwerte dürfen nicht nach Feldern mit Standardwerten angezeigt werden.", "dataClassFieldWithPrivateName": "Das Feld \"Dataclass\" kann keinen privaten Namen verwenden.", "dataClassFieldWithoutAnnotation": "Datenklassenfeld ohne Typanmerkung verursacht eine Laufzeitausnahme", diff --git a/packages/pyright-internal/src/localization/package.nls.en-us.json b/packages/pyright-internal/src/localization/package.nls.en-us.json index 3b1463395..2711360bc 100644 --- a/packages/pyright-internal/src/localization/package.nls.en-us.json +++ b/packages/pyright-internal/src/localization/package.nls.en-us.json @@ -218,7 +218,6 @@ "dataClassConverterFunction": "Argument of type \"{argType}\" is not a valid converter for field \"{fieldName}\" of type \"{fieldType}\"", "dataClassConverterOverloads": "No overloads of \"{funcName}\" are valid converters for field \"{fieldName}\" of type \"{fieldType}\"", "dataClassFieldInheritedDefault": "\"{fieldName}\" overrides a field of the same name but is missing a default value", - "dataClassFieldInvalidAlias": "Alias name \"{aliasName}\" is not a valid identifier", "dataClassFieldWithDefault": "Fields without default values cannot appear after fields with default values", "dataClassFieldWithPrivateName": "Dataclass field cannot use private name", "dataClassFieldWithoutAnnotation": "Dataclass field without type annotation will cause runtime exception", diff --git a/packages/pyright-internal/src/localization/package.nls.es.json b/packages/pyright-internal/src/localization/package.nls.es.json index 078a0c1a7..f9ca0e4ae 100644 --- a/packages/pyright-internal/src/localization/package.nls.es.json +++ b/packages/pyright-internal/src/localization/package.nls.es.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "Argumento de tipo \"{argType}\" no es un convertidor válido para el campo \"{fieldName}\" de tipo \"{fieldType}\"", "dataClassConverterOverloads": "No hay sobrecargas de \"{funcName}\" que sean convertidores válidos para el campo \"{fieldName}\" de tipo \"{fieldType}\"", "dataClassFieldInheritedDefault": "\"{fieldName}\" invalida un campo con el mismo nombre, pero falta un valor predeterminado", - "dataClassFieldInvalidAlias": "El nombre de alias \"{aliasName}\" no es un identificador válido", "dataClassFieldWithDefault": "Los campos sin valores predeterminados no pueden aparecer después de los campos con valores predeterminados", "dataClassFieldWithPrivateName": "El campo Dataclass no puede utilizar un nombre privado", "dataClassFieldWithoutAnnotation": "El campo Dataclass sin anotación de tipo provocará una excepción en tiempo de ejecución", diff --git a/packages/pyright-internal/src/localization/package.nls.fr.json b/packages/pyright-internal/src/localization/package.nls.fr.json index 7069ba60c..aa7743f2a 100644 --- a/packages/pyright-internal/src/localization/package.nls.fr.json +++ b/packages/pyright-internal/src/localization/package.nls.fr.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "L’argument de type « {argType} » n’est pas un convertisseur valide pour le champ « {fieldName} » de type « {fieldType} »", "dataClassConverterOverloads": "Aucune surcharge de « {funcName} » n’est valide pour le champ « {fieldName} » de type « {fieldType} »", "dataClassFieldInheritedDefault": "« {fieldName} » remplace un champ du même nom mais n’a pas de valeur par défaut", - "dataClassFieldInvalidAlias": "Le nom d’alias « {aliasName} » n’est pas un identificateur valide", "dataClassFieldWithDefault": "Les champs sans valeurs par défaut ne peuvent pas apparaître après les champs avec des valeurs par défaut", "dataClassFieldWithPrivateName": "Le champ Dataclass ne peut pas utiliser de nom privé", "dataClassFieldWithoutAnnotation": "Le champ Dataclass sans annotation de type provoquera une exception d'exécution", diff --git a/packages/pyright-internal/src/localization/package.nls.it.json b/packages/pyright-internal/src/localization/package.nls.it.json index 61d20841d..cd48d83de 100644 --- a/packages/pyright-internal/src/localization/package.nls.it.json +++ b/packages/pyright-internal/src/localization/package.nls.it.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "L'argomento di tipo \"{argType}\" non è un convertitore valido per il campo \"{fieldName}\" di tipo \"{fieldType}\"", "dataClassConverterOverloads": "Nessun overload di \"{funcName}\" è un convertitore valido per il campo \"{fieldName}\" di tipo \"{fieldType}\"", "dataClassFieldInheritedDefault": "\"{fieldName}\" esegue l'override di un campo con lo stesso nome, ma manca un valore predefinito", - "dataClassFieldInvalidAlias": "Il nome alias \"{aliasName}\" non è un identificatore valido", "dataClassFieldWithDefault": "I campi senza valori predefiniti non possono essere visualizzati dopo i campi con valori predefiniti", "dataClassFieldWithPrivateName": "Il campo dataclass non può usare un nome privato", "dataClassFieldWithoutAnnotation": "Il campo dataclass senza annotazione del tipo causerà un'eccezione di runtime", diff --git a/packages/pyright-internal/src/localization/package.nls.ja.json b/packages/pyright-internal/src/localization/package.nls.ja.json index 0ec193de4..29efbd5cc 100644 --- a/packages/pyright-internal/src/localization/package.nls.ja.json +++ b/packages/pyright-internal/src/localization/package.nls.ja.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "型 \"{argType}\" の引数は、型 \"{fieldType}\" のフィールド \"{fieldName}\" の有効なコンバーターではありません", "dataClassConverterOverloads": "{funcName}\" のオーバーロードは、型 \"{fieldType}\" のフィールド \"{fieldName}\" に対して有効なコンバーターではありません", "dataClassFieldInheritedDefault": "\"{fieldName}\" は同じ名前のフィールドをオーバーライドしますが、既定値がありません", - "dataClassFieldInvalidAlias": "エイリアス名 \"{aliasName}\" は有効な識別子ではありません", "dataClassFieldWithDefault": "既定値のないフィールドは、既定値を持つフィールドの後に表示できません", "dataClassFieldWithPrivateName": "データクラス フィールドはプライベート名を使用できません", "dataClassFieldWithoutAnnotation": "型注釈のないデータクラス フィールドが原因でランタイム例外が発生する", diff --git a/packages/pyright-internal/src/localization/package.nls.ko.json b/packages/pyright-internal/src/localization/package.nls.ko.json index 230e3fa9d..bac7f0080 100644 --- a/packages/pyright-internal/src/localization/package.nls.ko.json +++ b/packages/pyright-internal/src/localization/package.nls.ko.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "\"{argType}\" 형식의 인수는 \"{fieldType}\" 형식의 \"{fieldName}\" 필드에 유효한 변환기가 아닙니다.", "dataClassConverterOverloads": "\"{funcName}\"의 오버로드는 \"{fieldType}\" 형식의 \"{fieldName}\" 필드에 유효한 변환기가 아닙니다.", "dataClassFieldInheritedDefault": "\"{fieldName}\"이(가) 같은 이름의 필드를 재정의하지만 기본값이 없음", - "dataClassFieldInvalidAlias": "별칭 이름 \"{aliasName}\"은(는) 유효한 식별자가 아닙니다.", "dataClassFieldWithDefault": "기본값이 없는 필드는 기본값이 있는 필드 뒤에 나타날 수 없습니다.", "dataClassFieldWithPrivateName": "데이터 클래스 필드는 프라이빗 이름을 사용할 수 없습니다.", "dataClassFieldWithoutAnnotation": "형식 주석이 없는 데이터 클래스 필드를 사용하면 런타임 예외가 발생합니다.", diff --git a/packages/pyright-internal/src/localization/package.nls.pl.json b/packages/pyright-internal/src/localization/package.nls.pl.json index 4dc4ca2cc..ddc9ea95e 100644 --- a/packages/pyright-internal/src/localization/package.nls.pl.json +++ b/packages/pyright-internal/src/localization/package.nls.pl.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "Argument typu „{argType}” nie jest prawidłowym konwerterem pola „{fieldName}” typu „{fieldType}”", "dataClassConverterOverloads": "Żadne przeciążenia „{funcName}” nie są prawidłowymi konwerterami dla pola „{fieldName}” typu „{fieldType}”", "dataClassFieldInheritedDefault": "Pole „{fieldName}” zastępuje pole o tej samej nazwie, ale brakuje wartości domyślnej", - "dataClassFieldInvalidAlias": "Nazwa aliasu „{aliasName}” nie jest prawidłowym identyfikatorem", "dataClassFieldWithDefault": "Pola bez wartości domyślnych nie mogą występować po polach z wartościami domyślnymi", "dataClassFieldWithPrivateName": "Pole klasy danych nie może używać nazwy prywatnej", "dataClassFieldWithoutAnnotation": "Pole klasy danych bez adnotacji typu spowoduje wyjątek środowiska uruchomieniowego", diff --git a/packages/pyright-internal/src/localization/package.nls.pt-br.json b/packages/pyright-internal/src/localization/package.nls.pt-br.json index d7795ca7f..5bda11783 100644 --- a/packages/pyright-internal/src/localization/package.nls.pt-br.json +++ b/packages/pyright-internal/src/localization/package.nls.pt-br.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "O argumento do tipo \"{argType}\" não é um conversor válido para o campo \"{fieldName}\" do tipo \"{fieldType}\"", "dataClassConverterOverloads": "Nenhuma sobrecarga de \"{funcName}\" são conversores válidos para o campo \"{fieldName}\" do tipo \"{fieldType}\"", "dataClassFieldInheritedDefault": "\"{fieldName}\" substitui um campo com o mesmo nome, mas não possui um valor padrão", - "dataClassFieldInvalidAlias": "O nome de alias \"{aliasName}\" não é um identificador válido", "dataClassFieldWithDefault": "Campos sem valores padrão não podem aparecer após campos com valores padrão", "dataClassFieldWithPrivateName": "O campo Dataclass não pode usar o nome privado", "dataClassFieldWithoutAnnotation": "O campo Dataclass sem anotação de tipo causará uma exceção de runtime", diff --git a/packages/pyright-internal/src/localization/package.nls.qps-ploc.json b/packages/pyright-internal/src/localization/package.nls.qps-ploc.json index d32a2ca12..f5c8137ff 100644 --- a/packages/pyright-internal/src/localization/package.nls.qps-ploc.json +++ b/packages/pyright-internal/src/localization/package.nls.qps-ploc.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "[FxD8r][นั้Ærgµmëñt øf tÿpë \"{ærgTÿpë}\" ïs ñøt æ vælïð çøñvërtër før fïëlð \"{fïëlðÑæmë}\" øf tÿpë \"{fïëlðTÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", "dataClassConverterOverloads": "[ZJ0SE][นั้Ñø øvërløæðs øf \"{fµñçÑæmë}\" ærë vælïð çøñvërtërs før fïëlð \"{fïëlðÑæmë}\" øf tÿpë \"{fïëlðTÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "dataClassFieldInheritedDefault": "[BKxvn][นั้\"{fïëlðÑæmë}\" øvërrïðës æ fïëlð øf thë sæmë ñæmë þµt ïs mïssïñg æ ðëfæµlt vælµëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", - "dataClassFieldInvalidAlias": "[Yie5U][นั้Ælïæs ñæmë \"{ælïæsÑæmë}\" ïs ñøt æ vælïð ïðëñtïfïërẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "dataClassFieldWithDefault": "[iJuju][นั้Fïëlðs wïthøµt ðëfæµlt vælµës çæññøt æppëær æftër fïëlðs wïth ðëfæµlt vælµësẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "dataClassFieldWithPrivateName": "[miQYb][นั้Ðætæçlæss fïëlð çæññøt µsë prïvætë ñæmëẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "dataClassFieldWithoutAnnotation": "[zq5t5][นั้Ðætæçlæss fïëlð wïthøµt tÿpë æññøtætïøñ wïll çæµsë rµñtïmë ëxçëptïøñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", diff --git a/packages/pyright-internal/src/localization/package.nls.ru.json b/packages/pyright-internal/src/localization/package.nls.ru.json index b52f3bb73..605ffd4a7 100644 --- a/packages/pyright-internal/src/localization/package.nls.ru.json +++ b/packages/pyright-internal/src/localization/package.nls.ru.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "Аргумент типа \"{argType}\" не является допустимым преобразователем для поля \"{fieldName}\" типа \"{fieldType}\"", "dataClassConverterOverloads": "Ни одна перегрузка \"{funcName}\" не является допустимым преобразователем поля \"{fieldName}\" типа \"{fieldType}\"", "dataClassFieldInheritedDefault": "\"{fieldName}\" переопределяет поле с тем же именем, но в нем отсутствует значение по умолчанию", - "dataClassFieldInvalidAlias": "Псевдоним \"{aliasName}\" не является допустимым идентификатором", "dataClassFieldWithDefault": "Поля без значений по умолчанию не могут отображаться после полей со значениями по умолчанию.", "dataClassFieldWithPrivateName": "Поле класса данных не может использовать закрытое имя", "dataClassFieldWithoutAnnotation": "Поле dataclass без заметки с типом вызовет исключение среды выполнения", diff --git a/packages/pyright-internal/src/localization/package.nls.tr.json b/packages/pyright-internal/src/localization/package.nls.tr.json index 7056a298c..ba1601b4a 100644 --- a/packages/pyright-internal/src/localization/package.nls.tr.json +++ b/packages/pyright-internal/src/localization/package.nls.tr.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "\"{argType}\" türündeki bağımsız değişken, \"{fieldName}\" türündeki \"{fieldType}\" alanı için geçerli bir dönüştürücü değil", "dataClassConverterOverloads": "\"{funcName}\" işlevinin aşırı yüklemelerinden hiçbiri \"{fieldType}\" türündeki \"{fieldName}\" alanı için geçerli dönüştürücüler değil", "dataClassFieldInheritedDefault": "\"{fieldName}\", aynı ada sahip bir alanı geçersiz kılıyor ancak varsayılan değeri yok", - "dataClassFieldInvalidAlias": "\"{aliasName}\" diğer adı geçerli bir tanımlayıcı değil", "dataClassFieldWithDefault": "Varsayılan değerleri olmayan alanlar, varsayılan değerleri olan alanlardan sonra gelemez", "dataClassFieldWithPrivateName": "Veri sınıfı alanı özel ad kullanamıyor", "dataClassFieldWithoutAnnotation": "Tür ek açıklaması olmayan veri sınıfı alanı çalışma zamanı özel durumuna neden olur", diff --git a/packages/pyright-internal/src/localization/package.nls.zh-cn.json b/packages/pyright-internal/src/localization/package.nls.zh-cn.json index 5b961feb1..502d299af 100644 --- a/packages/pyright-internal/src/localization/package.nls.zh-cn.json +++ b/packages/pyright-internal/src/localization/package.nls.zh-cn.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "类型“{argType}”的参数不是类型为“{fieldType}”的字段“{fieldName}”的有效转换器", "dataClassConverterOverloads": "“{funcName}”的重载不是类型为“{fieldType}”的字段“{fieldName}”的有效转换器", "dataClassFieldInheritedDefault": "“{fieldName}”替代同名字段,但缺少默认值", - "dataClassFieldInvalidAlias": "别名“{aliasName}”不是有效的标识符", "dataClassFieldWithDefault": "没有默认值的字段不能出现在具有默认值的字段之后", "dataClassFieldWithPrivateName": "数据类字段不能使用专用名称", "dataClassFieldWithoutAnnotation": "不带类型批注的数据类字段将导致运行时异常", diff --git a/packages/pyright-internal/src/localization/package.nls.zh-tw.json b/packages/pyright-internal/src/localization/package.nls.zh-tw.json index d061f01ae..d9c10d2cc 100644 --- a/packages/pyright-internal/src/localization/package.nls.zh-tw.json +++ b/packages/pyright-internal/src/localization/package.nls.zh-tw.json @@ -104,7 +104,6 @@ "dataClassConverterFunction": "類型 \"{argType}\" 的引數不是類型 \"{fieldType}\" 欄位 \"{fieldName}\" 的有效轉換程式", "dataClassConverterOverloads": "\"{funcName}\" 沒有任何多載是類型 \"{fieldType}\" 欄位 \"{fieldName}\" 的有效轉換程式", "dataClassFieldInheritedDefault": "\"{fieldName}\" 覆寫相同名稱的欄位,但缺少預設值", - "dataClassFieldInvalidAlias": "別名名稱 \"{aliasName}\" 並非有效的識別碼", "dataClassFieldWithDefault": "沒有預設值的欄位無法出現在具有預設值的欄位後面", "dataClassFieldWithPrivateName": "Dataclass 欄位不能使用私人名稱", "dataClassFieldWithoutAnnotation": "沒有型別註釋的 Dataclass 欄位會造成執行階段例外狀況", diff --git a/packages/pyright-internal/src/tests/samples/dataclassTransform3.py b/packages/pyright-internal/src/tests/samples/dataclassTransform3.py index d6e7a05c2..6b72b366d 100644 --- a/packages/pyright-internal/src/tests/samples/dataclassTransform3.py +++ b/packages/pyright-internal/src/tests/samples/dataclassTransform3.py @@ -123,11 +123,3 @@ class Customer3(ModelBaseFrozen): # This should generate an error because Customer3 is frozen. c3_1.id = 4 - - -class Customer4(ModelBase): - # This should generate an error because alias must be a valid identifier. - name1: str = model_field(alias="other name") - - # This should generate an error because alias must be a valid identifier. - name2: str = model_field(alias="+test") diff --git a/packages/pyright-internal/src/tests/typeEvaluator5.test.ts b/packages/pyright-internal/src/tests/typeEvaluator5.test.ts index bbdd97c54..738911234 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator5.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator5.test.ts @@ -439,7 +439,7 @@ test('DataclassTransform2', () => { test('DataclassTransform3', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['dataclassTransform3.py']); - TestUtils.validateResults(analysisResults, 8); + TestUtils.validateResults(analysisResults, 6); }); test('DataclassTransform4', () => { From 0e5eb7aa19565380e2e4c56ad884e3801dbfef4c Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Tue, 5 Nov 2024 18:10:21 -0800 Subject: [PATCH 11/11] Published 1.1.388 --- lerna.json | 2 +- packages/pyright-internal/package-lock.json | 4 ++-- packages/pyright-internal/package.json | 2 +- packages/pyright/package-lock.json | 4 ++-- packages/pyright/package.json | 2 +- packages/vscode-pyright/package-lock.json | 4 ++-- packages/vscode-pyright/package.json | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lerna.json b/lerna.json index 47e628a9e..ef9b201b8 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "1.1.387", + "version": "1.1.388", "command": { "version": { "push": false, diff --git a/packages/pyright-internal/package-lock.json b/packages/pyright-internal/package-lock.json index b8527a9ed..97deef153 100644 --- a/packages/pyright-internal/package-lock.json +++ b/packages/pyright-internal/package-lock.json @@ -1,12 +1,12 @@ { "name": "pyright-internal", - "version": "1.1.387", + "version": "1.1.388", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pyright-internal", - "version": "1.1.387", + "version": "1.1.388", "license": "MIT", "dependencies": { "@yarnpkg/fslib": "2.10.4", diff --git a/packages/pyright-internal/package.json b/packages/pyright-internal/package.json index 19bf3dfe7..93ba1bb58 100644 --- a/packages/pyright-internal/package.json +++ b/packages/pyright-internal/package.json @@ -2,7 +2,7 @@ "name": "pyright-internal", "displayName": "pyright", "description": "Type checker for the Python language", - "version": "1.1.387", + "version": "1.1.388", "license": "MIT", "private": true, "files": [ diff --git a/packages/pyright/package-lock.json b/packages/pyright/package-lock.json index ea20b561f..2cde3fdbe 100644 --- a/packages/pyright/package-lock.json +++ b/packages/pyright/package-lock.json @@ -1,12 +1,12 @@ { "name": "pyright", - "version": "1.1.387", + "version": "1.1.388", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pyright", - "version": "1.1.387", + "version": "1.1.388", "license": "MIT", "bin": { "pyright": "index.js", diff --git a/packages/pyright/package.json b/packages/pyright/package.json index 4a96eaa11..c800dc032 100644 --- a/packages/pyright/package.json +++ b/packages/pyright/package.json @@ -2,7 +2,7 @@ "name": "pyright", "displayName": "Pyright", "description": "Type checker for the Python language", - "version": "1.1.387", + "version": "1.1.388", "license": "MIT", "author": { "name": "Microsoft Corporation" diff --git a/packages/vscode-pyright/package-lock.json b/packages/vscode-pyright/package-lock.json index 3a1bfe22f..06039a9d5 100644 --- a/packages/vscode-pyright/package-lock.json +++ b/packages/vscode-pyright/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-pyright", - "version": "1.1.387", + "version": "1.1.388", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vscode-pyright", - "version": "1.1.387", + "version": "1.1.388", "license": "MIT", "dependencies": { "vscode-jsonrpc": "^9.0.0-next.5", diff --git a/packages/vscode-pyright/package.json b/packages/vscode-pyright/package.json index 20f6e5976..6ae571052 100644 --- a/packages/vscode-pyright/package.json +++ b/packages/vscode-pyright/package.json @@ -2,7 +2,7 @@ "name": "vscode-pyright", "displayName": "Pyright", "description": "VS Code static type checking for Python", - "version": "1.1.387", + "version": "1.1.388", "private": true, "license": "MIT", "author": {