Pull Pylance with Pyright 1.1.406 (#11010)
Some checks failed
Run mypy_primer on push / Run mypy_primer on push (push) Has been cancelled
Validation / Typecheck (push) Has been cancelled
Validation / Style (push) Has been cancelled
Validation / Test macos-latest (push) Has been cancelled
Validation / Test ubuntu-latest (push) Has been cancelled
Validation / Test windows-latest (push) Has been cancelled
Validation / Build (push) Has been cancelled
Validation / Required (push) Has been cancelled

* pull-pylance-with-pyright-1.1.406-20251008-232729

* fixed linting issue

---------

Co-authored-by: Azure Piplines <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: HeeJae Chang <hechang@microsoft.com>
This commit is contained in:
Bill Schnurr 2025-10-08 17:02:24 -07:00 committed by GitHub
parent 9ed33cf7be
commit 20aa20a100
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 368 additions and 132 deletions

View file

@ -88,10 +88,10 @@ export interface AnalyzerServiceOptions {
serviceId?: string;
skipScanningUserFiles?: boolean;
fileSystem?: FileSystem;
usingPullDiagnostics?: boolean;
onInvalidated?: (reason: InvalidatedReason) => void;
// Optional callback fired once when initial source file enumeration completes.
onSourceEnumerationComplete?: () => void;
shouldRunAnalysis: () => boolean;
}
interface ConfigFileContents {
@ -214,6 +214,10 @@ export class AnalyzerService {
return this.options.serviceId!;
}
get checkOnlyOpenFiles() {
return !!this._commandLineOptions?.languageServerSettings.checkOnlyOpenFiles;
}
setServiceName(instanceName: string) {
this._instanceName = instanceName;
}
@ -230,7 +234,6 @@ export class AnalyzerService {
backgroundAnalysis,
skipScanningUserFiles: true,
fileSystem,
usingPullDiagnostics: this.options.usingPullDiagnostics,
});
// Cloned service will use whatever user files the service currently has.
@ -492,6 +495,11 @@ export class AnalyzerService {
);
}
invalidateAndScheduleReanalysis(reason: InvalidatedReason) {
this.invalidateAndForceReanalysis(reason);
this.scheduleReanalysis(/* requireTrackedFileUpdate */ false);
}
invalidateAndForceReanalysis(reason: InvalidatedReason) {
if (this.options.onInvalidated) {
this.options.onInvalidated(reason);
@ -566,13 +574,17 @@ export class AnalyzerService {
}
protected runAnalysis(token: CancellationToken) {
// In pull diagnostics mode, the service doesn't perform analysis on its own.
// Instead the client deliberately asks for diagnostics on a file-by-file basis.
if (!this.options.usingPullDiagnostics) {
// Double check we're allowed to run analysis now. We might be in pull mode or
// we might not have a workspace response callback. The creation of the workspace
// callback will cause this to rerun, so no need to start polling.
if (this.options.shouldRunAnalysis()) {
const moreToAnalyze = this._backgroundAnalysisProgram.startAnalysis(token);
if (moreToAnalyze) {
this.scheduleReanalysis(/* requireTrackedFileUpdate */ false);
}
} else if (this.options.onInvalidated) {
// Just cause a refresh.
this.options.onInvalidated(InvalidatedReason.Reanalyzed);
}
}

View file

@ -190,14 +190,15 @@ export class FullAccessHost extends LimitedAccessHost {
code: string,
args: string[],
cwd: Uri,
token: CancellationToken
token: CancellationToken,
forceIsolated: boolean = false
): Promise<ScriptOutput> {
// If it is already cancelled, don't bother to run snippet.
throwIfCancellationRequested(token);
// What to do about conda here?
return new Promise<ScriptOutput>((resolve, reject) => {
const commandLineArgs = ['-c', code, ...args];
const commandLineArgs = forceIsolated ? ['-I', '-c', code, ...args] : ['-c', code, ...args];
const child = this._executePythonInterpreter(pythonPath?.getFilePath(), (p) =>
child_process.spawn(p, commandLineArgs, {

View file

@ -46,7 +46,8 @@ export interface Host {
code: string,
args: string[],
cwd: Uri,
token: CancellationToken
token: CancellationToken,
forceIsolated?: boolean
): Promise<ScriptOutput>;
}

View file

@ -69,7 +69,8 @@ import {
TextDocumentSyncKind,
WorkDoneProgressReporter,
WorkspaceDiagnosticParams,
WorkspaceDocumentDiagnosticReport,
WorkspaceDiagnosticReport,
WorkspaceDiagnosticReportPartialResult,
WorkspaceEdit,
WorkspaceFoldersChangeEvent,
WorkspaceSymbol,
@ -82,7 +83,7 @@ import { BackgroundAnalysisProgram, InvalidatedReason } from './analyzer/backgro
import { ImportResolver } from './analyzer/importResolver';
import { MaxAnalysisTime } from './analyzer/program';
import { AnalyzerService, LibraryReanalysisTimeProvider, getNextServiceId } from './analyzer/service';
import { IPythonMode, SourceFile } from './analyzer/sourceFile';
import { IPythonMode } from './analyzer/sourceFile';
import type { IBackgroundAnalysis } from './backgroundAnalysisBase';
import { CommandResult } from './commands/commandResult';
import { CancelAfter } from './common/cancellationUtils';
@ -136,9 +137,33 @@ import {
Workspace,
WorkspaceFactory,
} from './workspaceFactory';
import { PullDiagnosticsDynamicFeature } from './languageService/pullDiagnosticsDynamicFeature';
const UncomputedDiagnosticsVersion = -1;
export function wrapProgressReporter(reporter: WorkDoneProgressReporter): ProgressReporter {
let isDisplayingProgress = false;
return {
isDisplayingProgress: () => {
return isDisplayingProgress;
},
isEnabled: () => {
return true;
},
begin: () => {
isDisplayingProgress = true;
reporter.begin('', /* percentage */ undefined, /* message */ undefined, /* cancellable */ false);
},
report: (message) => {
reporter.report(message);
},
end: () => {
isDisplayingProgress = false;
reporter.done();
},
};
}
export abstract class LanguageServerBase implements LanguageServerInterface, Disposable {
// We support running only one "find all reference" at a time.
private _pendingFindAllRefsCancellationSource: AbstractCancellationTokenSource | undefined;
@ -153,6 +178,9 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
private _initialized = false;
private _workspaceFoldersChangedDisposable: Disposable | undefined;
private _workspaceDiagnosticsReporter: ResultProgressReporter<WorkspaceDiagnosticReportPartialResult> | undefined;
private _workspaceDiagnosticsProgressReporter: ProgressReporter | undefined;
private _workspaceDiagnosticsResolve: ((value: WorkspaceDiagnosticReport) => void) | undefined;
protected client: ClientCapabilities = {
hasConfigurationCapability: false,
@ -278,12 +306,20 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
libraryReanalysisTimeProvider,
serviceId,
fileSystem: services?.fs ?? this.serverOptions.serviceProvider.fs(),
usingPullDiagnostics: this.client.supportsPullDiagnostics,
onInvalidated: (reason) => {
if (this.client.supportsPullDiagnostics) {
this.connection.sendRequest(DiagnosticRefreshRequest.type);
// If we're in openFilesOnly mode and the client supports pull diagnostics, request a refresh. In
// workspace mode we just use the 'push' notification to respond to the workspace diagnostics
if (this.client.supportsPullDiagnostics && service.checkOnlyOpenFiles) {
void this.connection.sendRequest(DiagnosticRefreshRequest.type);
}
},
shouldRunAnalysis: () => {
// We should run analysis if:
// The client doesn't support pull diagnostics (meaning we have to run analysis ourselves)
// or
// We have a workspace partial result callback (meaning in pull mode, we're waiting for workspace results)
return !this.client.supportsPullDiagnostics || this._workspaceDiagnosticsReporter !== undefined;
},
});
service.setCompletionCallback((results) => this.onAnalysisCompletedHandler(service.fs, results));
@ -350,6 +386,12 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
this.dynamicFeatures.update(serverSettings);
// If the workspace mode has changed, we may need to resolve the workspace diagnostics promise.
if (serverSettings.openFilesOnly && this._workspaceDiagnosticsResolve) {
this._workspaceDiagnosticsResolve({ items: [] });
this._workspaceDiagnosticsResolve = undefined;
}
// Then use the updated settings to restart the service.
this.updateOptionsAndRestartService(workspace, serverSettings);
@ -510,8 +552,8 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
this.connection.onDidChangeWatchedFiles((params) => this.onDidChangeWatchedFiles(params));
this.connection.languages.diagnostics.on(async (params, token) => this.onDiagnostics(params, token));
this.connection.languages.diagnostics.onWorkspace(async (params, token) =>
this.onWorkspaceDiagnostics(params, token)
this.connection.languages.diagnostics.onWorkspace(async (params, token, progress, reporter) =>
this.onWorkspaceDiagnostics(params, token, progress, reporter)
);
this.connection.onExecuteCommand(async (params, token, reporter) =>
this.onExecuteCommand(params, token, reporter)
@ -575,11 +617,9 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
);
this.client.supportsPullDiagnostics =
!!capabilities.textDocument?.diagnostic?.dynamicRegistration &&
initializationOptions?.diagnosticMode !== 'workspace' &&
initializationOptions?.disablePullDiagnostics !== true;
this.client.requiresPullRelatedInformationCapability =
!!capabilities.textDocument?.diagnostic?.relatedInformation &&
initializationOptions?.diagnosticMode !== 'workspace' &&
initializationOptions?.disablePullDiagnostics !== true;
// Create a service instance for each of the workspace folders.
@ -641,12 +681,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
};
if (this.client.supportsPullDiagnostics) {
result.capabilities.diagnosticProvider = {
identifier: 'pyright',
documentSelector: null,
interFileDependencies: true,
workspaceDiagnostics: false, // Workspace wide are not pull diagnostics.
};
this.addDynamicFeature(new PullDiagnosticsDynamicFeature(this.connection, this.serverOptions.productName));
}
return result;
@ -1177,23 +1212,33 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
return result;
}
protected async onWorkspaceDiagnostics(params: WorkspaceDiagnosticParams, token: CancellationToken) {
const workspaces = await this.getWorkspaces();
const promises: Promise<WorkspaceDocumentDiagnosticReport>[] = [];
workspaces.forEach((workspace) => {
if (!workspace.disableLanguageServices) {
const files = workspace.service.getOwnedFiles();
files.forEach((file) => {
const sourceFile = workspace.service.getSourceFile(file)!;
if (canNavigateToFile(workspace.service.fs, sourceFile.getUri())) {
promises.push(this._getWorkspaceDocumentDiagnostics(params, sourceFile, workspace, token));
}
});
}
protected async onWorkspaceDiagnostics(
params: WorkspaceDiagnosticParams,
token: CancellationToken,
workDoneProgress: WorkDoneProgressReporter,
resultReporter?: ResultProgressReporter<WorkspaceDiagnosticReportPartialResult>
) {
// Resolve any pending workspace diagnostics. We only allow one at a time.
this._workspaceDiagnosticsResolve?.({ items: [] });
this._workspaceDiagnosticsResolve = undefined;
// Save the progress reporters and force a refresh of analysis.
this._workspaceDiagnosticsProgressReporter = !isNullProgressReporter(workDoneProgress)
? wrapProgressReporter(workDoneProgress)
: undefined;
this._workspaceDiagnosticsReporter = resultReporter;
this.workspaceFactory.getNonDefaultWorkspaces().forEach((workspace) => {
workspace.service.invalidateAndScheduleReanalysis(InvalidatedReason.Reanalyzed);
});
return new Promise<WorkspaceDiagnosticReport>((resolve, reject) => {
// We never resolve as this should be a continually occurring process. Scheduling analysis
// should cause a new workspace diagnostic to be generated.
// Save the resolve callback to be used during shutdown so that tests don't crash
// on the unresolved promise for the workspace diagnostics.
this._workspaceDiagnosticsResolve = resolve;
});
return {
items: await Promise.all(promises),
};
}
protected onDidChangeWatchedFiles(params: DidChangeWatchedFilesParams) {
@ -1262,6 +1307,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
protected onShutdown(token: CancellationToken) {
// Shutdown remaining workspaces.
this._workspaceDiagnosticsResolve?.({ items: [] });
this.workspaceFactory.clear();
// Stop tracking all open files.
@ -1286,11 +1332,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
}
protected onAnalysisCompletedHandler(fs: FileSystem, results: AnalysisResults): void {
// If we're in pull mode, disregard any 'tracking' results. They're not necessary.
if (this.client.supportsPullDiagnostics && results.reason === 'tracking') {
return;
}
// Send the computed diagnostics to the client.
results.diagnostics.forEach((fileDiag) => {
if (!this.canNavigateToFile(fileDiag.fileUri, fs)) {
@ -1300,17 +1341,18 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
this.sendDiagnostics(this.convertDiagnostics(fs, fileDiag));
});
if (!this._progressReporter.isEnabled(results)) {
const reporter = this.getAnalysisProgressReporter();
if (!reporter.isEnabled(results)) {
// Make sure to disable progress bar if it is currently active.
// This can happen if a user changes typeCheckingMode in the middle
// of analysis.
// end() is noop if there is no active progress bar.
this._progressReporter.end();
reporter.end();
return;
}
// Update progress.
this.sendProgressMessage(results.requiringAnalysisCount.files);
this.sendProgressMessage(results.requiringAnalysisCount.files, results.requiringAnalysisCount.cells);
}
protected incrementAnalysisProgress() {
@ -1326,9 +1368,17 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
this.sendProgressMessage(this._progressReportCounter);
}
protected sendProgressMessage(fileCount: number) {
protected getAnalysisProgressReporter(): ProgressReporter {
if (this._workspaceDiagnosticsProgressReporter) {
return this._workspaceDiagnosticsProgressReporter;
}
return this._progressReporter;
}
protected sendProgressMessage(fileCount: number, cellCount?: number) {
const reporter = this.getAnalysisProgressReporter();
if (fileCount <= 0) {
this._progressReporter.end();
reporter.end();
return;
}
const progressMessage =
@ -1339,10 +1389,10 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
});
// Update progress.
if (!this._progressReporter.isDisplayingProgress()) {
this._progressReporter.begin();
if (!reporter.isDisplayingProgress()) {
reporter.begin();
}
this._progressReporter.report(progressMessage);
reporter.report(progressMessage);
}
protected onWorkspaceCreated(workspace: Workspace) {
@ -1442,7 +1492,16 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
} else {
this.documentsWithDiagnostics.add(param.uri);
}
this.connection.sendDiagnostics(param);
// If we're waiting for a pending workspace diagnostic, send a partial result.
if (this._workspaceDiagnosticsReporter) {
// Skip storing previous result ids, just send new results every time.
this._workspaceDiagnosticsReporter.report({
items: [{ ...param, kind: 'full', version: param.version || null, items: param.diagnostics }],
});
} else {
// Otherwise send a publish diagnostic notification.
this.connection.sendDiagnostics(param);
}
}
}
@ -1465,33 +1524,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
return MarkupKind.PlainText;
}
private async _getWorkspaceDocumentDiagnostics(
params: WorkspaceDiagnosticParams,
sourceFile: SourceFile,
workspace: Workspace,
token: CancellationToken
) {
const originalUri = workspace.service.fs.getOriginalUri(sourceFile.getUri());
const result: WorkspaceDocumentDiagnosticReport = {
uri: originalUri.toString(),
version: sourceFile.getClientVersion() ?? null,
kind: 'full',
items: [],
};
const previousId = params.previousResultIds.find((x) => x.uri === originalUri.toString());
const documentResult = await this.onDiagnostics(
{ previousResultId: previousId?.value, textDocument: { uri: result.uri } },
token
);
if (documentResult.kind === 'full') {
result.items = documentResult.items;
} else {
(result as any).kind = documentResult.kind;
delete (result as any).items;
}
return result;
}
private _convertDiagnostics(fs: FileSystem, diags: AnalyzerDiagnostic[]): Diagnostic[] {
const convertedDiags: Diagnostic[] = [];
@ -1501,12 +1533,19 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
const code = this.getDiagCode(diag, rule);
const vsDiag = Diagnostic.create(diag.range, diag.message, severity, code, this.serverOptions.productName);
// Save all of the actions in the data.
const actions = diag.getActions();
if (actions?.length) {
vsDiag.data = { ...vsDiag.data, actions: actions };
}
if (
diag.category === DiagnosticCategory.UnusedCode ||
diag.category === DiagnosticCategory.UnreachableCode
) {
vsDiag.tags = [DiagnosticTag.Unnecessary];
vsDiag.severity = DiagnosticSeverity.Hint;
vsDiag.data = { ...vsDiag.data, category: diag.category, rule: rule };
// If the client doesn't support "unnecessary" tags, don't report unused code.
if (!this.client.supportsUnnecessaryDiagnosticTag) {

View file

@ -0,0 +1,46 @@
/*
* PullDiagnosticsDynamicFeature.ts
* Copyright (c) Microsoft Corporation.
*
* implementation of pull mode diagnostics feature registration
*/
import {
Connection,
DiagnosticRegistrationOptions,
Disposable,
DocumentDiagnosticRequest,
} from 'vscode-languageserver';
import { DynamicFeature } from './dynamicFeature';
import { ServerSettings } from '../common/languageServerInterface';
export class PullDiagnosticsDynamicFeature extends DynamicFeature {
private _workspaceSupport = false;
private _registered = false;
constructor(private readonly _connection: Connection, private readonly _id: string = 'pyright') {
super('pull diagnostics');
}
override update(settings: ServerSettings): void {
// There is one caveat with these settings. These settings can be set
// per workspace, but these features apply to the entire language server.
// Therefore, if the user has set these settings differently per workspace,
// the last setting will take precedence.
const workspaceSupport = settings.openFilesOnly === false;
if (this._workspaceSupport !== workspaceSupport || !this._registered) {
this._workspaceSupport = workspaceSupport;
this.register();
}
}
protected override registerFeature(): Promise<Disposable> {
this._registered = true;
const options: DiagnosticRegistrationOptions = {
interFileDependencies: true,
workspaceDiagnostics: this._workspaceSupport,
documentSelector: null,
identifier: this._id,
};
return this._connection.client.register(DocumentDiagnosticRequest.type, options);
}
}

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Všechny základní třídy pro třídy TypedDict musí být také třídami TypedDict",
"typedDictBoolParam": "Očekávalo se, že parametr {name} bude mít hodnotu True nebo False",
"typedDictClosedExtras": "Základní \"{name}\" třídy je TypedDict, který omezuje typ dalších položek na typ \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "Základní třída {name} je closed TypedDict; položky navíc nejsou povolené.",
"typedDictDelete": "Nepovedlo se odstranit položku v TypedDict",
"typedDictEmptyName": "Názvy v rámci TypedDict nemůžou být prázdné",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "Analýza funkce „{name}“ se přeskočila, protože není označená",
"unaryOperationNotAllowed": "Ve výrazu typu není povolený unární operátor.",
"unexpectedAsyncToken": "Očekávalo se, že za async bude následovat def, with nebo for",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Neočekávaný token na konci výrazu",
"unexpectedIndent": "Neočekávané odsazení",
"unexpectedUnindent": "Neočekává se unindent",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple se nedá použít pro kontroly instancí nebo tříd.",
"newMethodLocation": "Metoda __new__ je definována ve třídě {type}",
"newMethodSignature": "Podpis __new__ je {type}",
"newTypeClassNotAllowed": "Třídu vytvořenou pomocí NewType nelze použít s kontrolami instancí a tříd.",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Typ {type} neodpovídá žádné přetížené funkci",
"noneNotAllowed": "Možnost None se nedá použít pro kontroly instancí nebo tříd.",
"orPatternMissingName": "Chybějící názvy: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Alle Basisklassen für TypedDict-Klassen müssen auch TypedDict-Klassen sein.",
"typedDictBoolParam": "Es wird erwartet, dass \"{name}\" Parameter den Wert \"True\" oder \"False\" aufweist.",
"typedDictClosedExtras": "Die Basisklasse \"{name}\" ist eine TypedDict, die den Typ zusätzlicher Elemente auf den Typ \"{type}\" beschränkt.",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "Die Basisklasse „{name}“ ist ein closed TypedDict; zusätzliche Elemente sind nicht zulässig.",
"typedDictDelete": "Das Element in TypedDict konnte nicht gelöscht werden.",
"typedDictEmptyName": "Namen innerhalb eines TypedDict dürfen nicht leer sein.",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "Die Analyse der Funktion \"{name}\" wird übersprungen, da sie nicht kommentiert wurde.",
"unaryOperationNotAllowed": "Der unäre Operator ist im Typausdruck nicht zulässig",
"unexpectedAsyncToken": "Es wurde erwartet, dass \"def\", \"with\" oder \"for\" auf \"async\" folgt.",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Unerwartetes Token am Ende des Ausdrucks.",
"unexpectedIndent": "Unerwarteter Einzug",
"unexpectedUnindent": "\"Unindent\" nicht erwartet.",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple kann nicht für Instanzen- oder Klassenüberprüfungen verwendet werden.",
"newMethodLocation": "Die __new__ Methode ist in der Klasse \"{type}\" definiert.",
"newMethodSignature": "Signatur von __new__ ist \"{type}\"",
"newTypeClassNotAllowed": "Die mit NewType erstellte Klasse kann nicht mit Instanz- und Klassenüberprüfungen verwendet werden.",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Keine überladene Funktion stimmt mit dem Typ \"{type}\" überein.",
"noneNotAllowed": "\"None\" kann nicht für Instanz- oder Klassenprüfungen verwendet werden.",
"orPatternMissingName": "Fehlende Namen: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Todas las clases base de las clases TypedDict deben ser también clases TypedDict",
"typedDictBoolParam": "Se esperaba que el parámetro \"{name}\" tuviera un valor de True o False.",
"typedDictClosedExtras": "El \"{name}\" de clase base es un TypedDict que limita el tipo de elementos adicionales al tipo \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "La clase base \"{name}\" es un TypedDict closed; no se permiten elementos adicionales",
"typedDictDelete": "No se puede eliminar un elemento en TypedDict",
"typedDictEmptyName": "Los nombres de un TypedDict no pueden estar vacíos",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "Se omite el análisis de la función \"{name}\" porque no está anotada",
"unaryOperationNotAllowed": "Operador unario no permitido en la expresión de tipo",
"unexpectedAsyncToken": "Se esperaba que \"def\", \"with\" o \"for\" siguieran a \"async\".",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Token inesperado al final de la expresión",
"unexpectedIndent": "sangSangría inesperadaría inesperada",
"unexpectedUnindent": "No se espera sangría",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "No se puede usar NamedTuple para comprobaciones de instancia o clase",
"newMethodLocation": "El método __new__ está definido en la clase \"{type}\"",
"newMethodSignature": "La firma de __new__ es \"{type}\"",
"newTypeClassNotAllowed": "La clase creada con NewType no se puede usar con comprobaciones de instancia y clase",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Ninguna función sobrecargada coincide con el tipo \"{type}\"",
"noneNotAllowed": "No se puede usar None para comprobaciones de instancia o clase",
"orPatternMissingName": "Nombres que faltan: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Toutes les classes de base pour les classes TypedDict doivent également être des classes TypedDict",
"typedDictBoolParam": "Paramètre « {name} » attendu avec la valeur True ou False",
"typedDictClosedExtras": "Le \"{name}\" de classe de base est un TypedDict qui limite le type déléments supplémentaires au type \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "La classe de base « {name} » est un TypedDict closed, les éléments supplémentaires ne sont pas autorisés",
"typedDictDelete": "Impossible de supprimer lélément dans TypedDict",
"typedDictEmptyName": "Les noms dans un TypedDict ne peuvent pas être vides",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "L'analyse de la fonction \"{name}\" est ignorée car elle n'est pas annotée",
"unaryOperationNotAllowed": "L'opérateur unaire n'est pas autorisé dans l'expression de type",
"unexpectedAsyncToken":  def », « with » ou « for » attendu pour suivre « async »",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Jeton inattendu à la fin de lexpression",
"unexpectedIndent": "Retrait inattendu",
"unexpectedUnindent": "Unindent non attendu",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple ne peut pas être utilisé pour les vérifications dinstance ou de classe",
"newMethodLocation": "La méthode __new__ est définie dans la classe « {type} »",
"newMethodSignature": "La signature de __new__ est « {type} »",
"newTypeClassNotAllowed": "La classe créée avec NewType ne peut pas être utilisée avec des vérifications de instance et de classe",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Aucune fonction surchargée ne correspond au type « {type} »",
"noneNotAllowed": "None ne peut être utilisé pour les vérifications de instance ou de classe",
"orPatternMissingName": "Noms manquants : {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Anche tutte le classi di base per le classi TypedDict devono essere classi TypedDict",
"typedDictBoolParam": "È previsto che il parametro \"{name}\" abbia il valore True o False",
"typedDictClosedExtras": "La classe di base \"{name}\" è una TypedDict che limita il tipo di elementi aggiuntivi al tipo \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "La classe di base \"{name}\" è un TypedDict closed; elementi aggiuntivi non consentiti",
"typedDictDelete": "Non è stato possibile eliminare l'elemento in TypedDict",
"typedDictEmptyName": "I nomi all'interno di un TypedDict non possono essere vuoti",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "L'analisi della funzione \"{name}\" è stata ignorata perché non è annotata",
"unaryOperationNotAllowed": "Operatore unario non consentito nell'espressione di tipo",
"unexpectedAsyncToken": "È previsto che \"def\", \"with\" o \"for\" seguano \"async\"",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Token imprevisto alla fine dell'espressione",
"unexpectedIndent": "Rientro imprevisto",
"unexpectedUnindent": "Riduci rientro non previsto",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "Non è possibile usare NamedTuple per i controlli di istanze o classi",
"newMethodLocation": "Il metodo __new__ è definito nella classe \"{type}\"",
"newMethodSignature": "La firma del __new__ è \"{type}\"",
"newTypeClassNotAllowed": "Impossibile utilizzare la classe creata con NewType con controlli di classe e di istanza",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Nessuna funzione di overload corrisponde al tipo \"{type}\"",
"noneNotAllowed": "Non è possibile usare None per i controlli di istanze o classi",
"orPatternMissingName": "Nomi mancanti: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "TypedDict クラスのすべての基底クラスも TypedDict クラスである必要があります",
"typedDictBoolParam": "\"{name}\" パラメーターの値は True または False である必要があります",
"typedDictClosedExtras": "基底クラス \"{name}\" は、余分な項目の型を型 \"{type}\" に制限する TypedDict です",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "基底クラス \"{name}\" は closed した TypedDict です。追加の項目は許可されていません",
"typedDictDelete": "TypedDict の項目を削除できませんでした",
"typedDictEmptyName": "TypedDict 内の名前を空にすることはできません",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "関数 \"{name}\" の分析は、表示されないためスキップされます",
"unaryOperationNotAllowed": "単項演算子は型式では使用できません",
"unexpectedAsyncToken": "\"def\"、\"with\"、または \"for\" が \"async\" の後に続く必要があります",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "式の最後に予期しないトークンが含まれています",
"unexpectedIndent": "予期しないインデント",
"unexpectedUnindent": "インデント解除は予期されていません",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple はインスタンスまたはクラスのチェックには使用できません",
"newMethodLocation": "__new__ メソッドはクラス \"{type}\" で定義されています",
"newMethodSignature": "__new__の署名は \"{type}\" です",
"newTypeClassNotAllowed": "NewType で作成されたクラスは、インスタンスおよびクラスのチェックでは使用できません",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "型 \"{type}\" に一致するオーバーロードされた関数はありません",
"noneNotAllowed": "インスタンスまたはクラスのチェックには None 使用できません",
"orPatternMissingName": "名前がありません: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "TypedDict 클래스의 모든 기본 클래스도 TypedDict 클래스여야 합니다.",
"typedDictBoolParam": "\"{name}\" 매개 변수에 True 또는 False 값이 있어야 합니다.",
"typedDictClosedExtras": "기본 클래스 \"{name}\" 추가 항목의 유형을 \"{type}\" 형식으로 제한하는 TypedDict.",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "기본 클래스 \"{name}\"은(는) closed TypedDict입니다. 추가 항목은 허용되지 않습니다.",
"typedDictDelete": "TypedDict에서 항목을 삭제할 수 없습니다.",
"typedDictEmptyName": "TypedDict 내의 이름은 비워 둘 수 없습니다.",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "주석이 없으므로 {name} 함수 분석을 건너뜁니다.",
"unaryOperationNotAllowed": "단항 연산자는 형식 식에 사용할 수 없습니다.",
"unexpectedAsyncToken": "\"async\"를 따르려면 \"def\", \"with\" 또는 \"for\"가 필요합니다.",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "식 끝에 예기치 않은 토큰이 있습니다.",
"unexpectedIndent": "예기치 않은 들여쓰기",
"unexpectedUnindent": "들여쓰기가 필요 없음",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "인스턴스 또는 클래스 검사에는 NamedTuple을 사용할 수 없습니다.",
"newMethodLocation": "__new__ 메서드가 \"{type}\" 클래스에 정의되어 있습니다.",
"newMethodSignature": "__new__ 의 서명은 \"{type}\"입니다.",
"newTypeClassNotAllowed": "NewType으로 만든 클래스는 인스턴스 및 클래스 검사에 사용할 수 없습니다.",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "\"{type}\" 형식과 일치하는 오버로드된 함수가 없습니다.",
"noneNotAllowed": "인스턴스 또는 클래스 검사에는 None을 사용할 수 없음",
"orPatternMissingName": "누락된 이름: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Wszystkie klasy bazowe dla klas TypedDict muszą być również klasami TypedDict",
"typedDictBoolParam": "Oczekiwano, że parametr „{name}” będzie miał wartość True lub False",
"typedDictClosedExtras": "\"{name}\" klasy bazowej to TypedDict ograniczająca typ dodatkowych elementów do typu \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "Klasa bazowa „{name}” jest closed TypedDict; dodatkowe elementy są niedozwolone",
"typedDictDelete": "Nie można usunąć elementu w typie TypedDict",
"typedDictEmptyName": "Nazwy w elemencie TypedDict nie mogą być puste",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "Analiza funkcji „{name}” została pominięta, ponieważ nie ma adnotacji",
"unaryOperationNotAllowed": "Operator jednoargumentowy nie jest dozwolony w wyrażeniu typu",
"unexpectedAsyncToken": "Oczekiwano wartości „def”, „with” lub „for” po „async”",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Nieoczekiwany token na końcu wyrażenia",
"unexpectedIndent": "Nieoczekiwane wcięcie",
"unexpectedUnindent": "Nieoczekiwany brak wcięcia",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "Funkcja NamedTuple nie może być używana do sprawdzania wystąpień lub klas",
"newMethodLocation": "Metoda __new__ jest zdefiniowana w klasie „{type}”",
"newMethodSignature": "Sygnatura __new__ to typ „{type}”",
"newTypeClassNotAllowed": "Klasy utworzonej za pomocą elementu NewType nie można używać z sprawdzaniem wystąpień i klas",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Żadna przeciążona funkcja nie pasuje do typu „{type}”",
"noneNotAllowed": "Wartość None nie może być używana w przypadku kontroli wystąpień lub klas",
"orPatternMissingName": "Brak nazw: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Todas as classes base para classes TypedDict também devem ser classes TypedDict",
"typedDictBoolParam": "Esperava-se que o parâmetro \"{name}\" tivesse um valor True ou False",
"typedDictClosedExtras": "A classe \"{name}\" é um TypedDict que limita o tipo de itens extras a serem digitados \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "A classe base \"{name}\" é um TypedDict closed; itens extras não são permitidos",
"typedDictDelete": "Não foi possível excluir o item em TypedDict",
"typedDictEmptyName": "Os nomes dentro de um TypedDict não podem estar vazios",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "A análise da função \"{name}\" foi ignorada porque não foi anotada",
"unaryOperationNotAllowed": "Operador unário não permitido na expressão de tipo",
"unexpectedAsyncToken": "Esperado \"def\", \"with\" ou \"for\" para acompanhar \"async\"",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Token inesperado no final da expressão",
"unexpectedIndent": "Recuo inesperado",
"unexpectedUnindent": "Recuo não esperado",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple não pode ser usado para verificações de instância ou de classe",
"newMethodLocation": "O método __new__ é definido na classe \"{type}\"",
"newMethodSignature": "A assinatura de__new__ é \"{type}\"",
"newTypeClassNotAllowed": "A classe criada com NewType não pode ser usada com verificações de instância e classe",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Nenhuma função sobrecarregada corresponde ao tipo \"{type}\"",
"noneNotAllowed": "None não pode ser usado para verificações de instância ou de classe",
"orPatternMissingName": "Nomes ausentes: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "[HxyA2][นั้Æll þæsë çlæssës før TypedDict çlæssës mµst ælsø þë TypedDict çlæssësẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]",
"typedDictBoolParam": "[GALOD][นั้Ëxpëçtëð \"{ñæmë}\" pæræmëtër tø hævë æ vælµë øf True ør FalseẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]",
"typedDictClosedExtras": "[mlkJO][นั้ßæsë çlæss \"{ñæmë}\" ïs æ TypedDict thæt lïmïts thë tÿpë øf ëxtræ ïtëms tø tÿpë \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]",
"typedDictClosedFalseNonOpenBase": "[ifIlm][นั้ßæsë çlæss \"{ñæmë}\" ïs ñøt æñ øpëñ TypedDict; closed=Fælsë ïs ñøt ælløwëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]",
"typedDictClosedNoExtras": "[BCyXd][นั้ßæsë çlæss \"{ñæmë}\" ïs æ closed TypedDict; ëxtræ ïtëms ærë ñøt ælløwëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]",
"typedDictDelete": "[bdBu7][นั้Çøµlð ñøt ðëlëtë ïtëm ïñ TypedDictẤğ倪İЂҰक्र्तिृまนั้ढूँ]",
"typedDictEmptyName": "[h45e7][นั้Ñæmës wïthïñ æ TypedDict çæññøt þë ëmptÿẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "[Ovgyl][นั้Æñælÿsïs øf fµñçtïøñ \"{ñæmë}\" ïs skïppëð þëçæµsë ït ïs µñæññøtætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]",
"unaryOperationNotAllowed": "[2WB31][นั้Üñærÿ øpërætør ñøt ælløwëð ïñ tÿpë ëxprëssïøñẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]",
"unexpectedAsyncToken": "[fKSJb][นั้Ëxpëçtëð \"def\", \"with\" ør \"for\" tø følløw \"async\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]",
"unexpectedEof": "[SyST0][นั้Üñëxpëçtëð ËØFẤğ倪İЂҰนั้ढूँ]",
"unexpectedExprToken": "[MtBsu][นั้Üñëxpëçtëð tøkëñ æt ëñð øf ëxprëssïøñẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]",
"unexpectedIndent": "[uZUVS][นั้Üñëxpëçtëð ïñðëñtætïøñẤğ倪İЂҰक्र्นั้ढूँ]",
"unexpectedUnindent": "[yqwy4][นั้Üñïñðëñt ñøt ëxpëçtëðẤğ倪İЂҰक्นั้ढूँ]",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "[gAlSp][นั้NamedTuple çæññøt þë µsëð før ïñstæñçë ør çlæss çhëçksẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]",
"newMethodLocation": "[n0dxL][นั้Thë __new__ mëthøð ïs ðëfïñëð ïñ çlæss \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]",
"newMethodSignature": "[NeWKO][นั้§ïgñætµrë øf __new__ ïs \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृนั้ढूँ]",
"newTypeClassNotAllowed": "[JQmcY][นั้Çlæss çrëætëð wïth NewType çæññøt þë µsëð wïth ïñstæñçë æñð çlæss çhëçksẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]",
"newTypeClassNotAllowed": "[JQmcY][นั้Tÿpë çrëætëð wïth NewType çæññøt þë µsëð wïth ïñstæñçë æñð çlæss çhëçksẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]",
"noOverloadAssignable": "[FJ88c][นั้Ñø øvërløæðëð fµñçtïøñ mætçhës tÿpë \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]",
"noneNotAllowed": "[Yn8Lx][นั้None çæññøt þë µsëð før ïñstæñçë ør çlæss çhëçksẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]",
"orPatternMissingName": "[kgiPM][นั้Mïssïñg ñæmës: {ñæmë}Ấğ倪İЂҰक्นั้ढूँ]",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "Все базовые классы для классов TypedDict также должны быть классами TypedDict",
"typedDictBoolParam": "От параметра \"{name}\" ожидается значение True или False",
"typedDictClosedExtras": "Базовый класс \"{name}\" является TypedDict, который ограничивает тип дополнительных элементов типом \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "Базовый класс \"{name}\" представляет собой closed TypedDict; дополнительные элементы не разрешены",
"typedDictDelete": "Не удалось удалить элемент в TypedDict",
"typedDictEmptyName": "Имена в TypedDict не могут быть пустыми",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "Анализ функции \"{name}\" пропущен, так как она не аннотирована.",
"unaryOperationNotAllowed": "Унарный оператор нельзя использовать в выражении типа",
"unexpectedAsyncToken": "После \"async\" ожидается \"def\", \"with\" или \"for\"",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "Непредвиденный токен в конце выражения",
"unexpectedIndent": "Непредвиденный отступ",
"unexpectedUnindent": "Отступ не ожидается",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple не может использоваться для проверок экземпляров или классов",
"newMethodLocation": "Метод __new__ определен в классе \"{type}\"",
"newMethodSignature": "Сигнатура метода __new__ требует \"{type}\"",
"newTypeClassNotAllowed": "Класс, созданный с NewType, нельзя использовать с проверками экземпляров и классов",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Нет перегруженной функции, соответствующей типу \"{type}\"",
"noneNotAllowed": "None невозможно использовать для проверок экземпляров или классов",
"orPatternMissingName": "Отсутствуют имена: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "TypedDict sınıfları için tüm temel sınıflar da TypedDict sınıfları olmalıdır",
"typedDictBoolParam": "True veya False değeri olması için \"{name}\" parametresi bekleniyordu",
"typedDictClosedExtras": "Temel sınıf \"{name}\", TypedDict öğe türünü türle sınırlanmış bir \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "\"{name}\" temel sınıfı closed bir TypedDict öğesidir; ek öğelere izin verilmiyor",
"typedDictDelete": "TypedDict'da öğe silinemedi",
"typedDictEmptyName": "TypedDict içindeki adlar boş olamaz",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "\"{name}\" işlevinin analizi, açıklanmadığından atlandı",
"unaryOperationNotAllowed": "Tür ifadesinde birli işleç kullanılamaz",
"unexpectedAsyncToken": "\"async\" öğesinin ardından \"def\", \"with\" veya \"for\" bekleniyordu",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "İfadenin sonunda beklenmeyen belirteç",
"unexpectedIndent": "Beklenmeyen girinti",
"unexpectedUnindent": "Girintiyi kaldırma beklenmiyordu",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "NamedTuple örnek veya sınıf kontrolleri için kullanılamaz",
"newMethodLocation": "\"{type}\" sınıfı içinde __new__ metodu tanımlandı",
"newMethodSignature": "__new__ imzası \"{type}\"",
"newTypeClassNotAllowed": "NewType ile oluşturulan sınıf, örnek ve sınıf denetimleriyle kullanılamaz",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "Aşırı yüklenmiş işlevlerden hiçbiri \"{type}\" türüyle uyuşmuyor",
"noneNotAllowed": "Örnek veya sınıf denetimleri için None kullanılamaz",
"orPatternMissingName": "Eksik adlar: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "TypedDict 类的所有基类也必须是 TypedDict 类",
"typedDictBoolParam": "预期“{name}”参数的值为 True 或 False",
"typedDictClosedExtras": "基类 \"{name}\" 是限制额外项类型 \"{type}\" 的 TypedDict",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "基类 \"{name}\" 是 closed TypedDict; 不允许使用额外的项",
"typedDictDelete": "无法删除 TypedDict 中的项",
"typedDictEmptyName": "TypedDict 中的名称不能为空",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "已跳过对函数“{name}”的分析,因为它未被批注",
"unaryOperationNotAllowed": "类型表达式中不允许使用一元运算符",
"unexpectedAsyncToken": "“def”、“with” 或 “for” 应跟随 “async”",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "表达式末尾出现意外标记",
"unexpectedIndent": "意外缩进",
"unexpectedUnindent": "不应取消缩进",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "不能对实例或类检查使用 NamedTuple",
"newMethodLocation": "__new__方法已在类“{type}”中定义",
"newMethodSignature": "__new__的签名为“{type}”",
"newTypeClassNotAllowed": "不能将使用 NewType 创建的类用于实例和类检查",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "没有重载函数与类型“{type}”匹配",
"noneNotAllowed": "不能对实例或类检查使用 None",
"orPatternMissingName": "缺少名称: {name}",

View file

@ -580,6 +580,7 @@
"typedDictBaseClass": "TypedDict 類別的所有基底類別也必須是 TypedDict 類別",
"typedDictBoolParam": "預期 \"{name}\" 參數的值為 True 或 False",
"typedDictClosedExtras": "基類 \"{name}\" 是限制額外專案類型的 TypedDict \"{type}\"",
"typedDictClosedFalseNonOpenBase": "Base class \"{name}\" is not an open TypedDict; closed=False is not allowed",
"typedDictClosedNoExtras": "基底類別 \"{name}\" 是 closed 的 TypedDict; 不允許額外項目",
"typedDictDelete": "無法刪除 TypedDict 中的項目",
"typedDictEmptyName": "TypedDict 內的名稱不可為空白",
@ -605,6 +606,7 @@
"unannotatedFunctionSkipped": "因為未標註函式 \"{name}\",所以略過其分析",
"unaryOperationNotAllowed": "類型運算式中不允許一元運算子",
"unexpectedAsyncToken": "預期為 \"def\"、\"with\" 或 \"for\" 來追蹤 \"async\"",
"unexpectedEof": "Unexpected EOF",
"unexpectedExprToken": "運算式結尾未預期的權杖",
"unexpectedIndent": "未預期的縮排",
"unexpectedUnindent": "取消縮排未預期",
@ -741,7 +743,7 @@
"namedTupleNotAllowed": "執行個體或類別檢查無法使用 NamedTuple",
"newMethodLocation": "__new__ 方法於類別 \"{type}\" 中定義",
"newMethodSignature": "__new__ 的簽章為 \"{type}\"",
"newTypeClassNotAllowed": "使用 NewType 建立的類別不能與執行個體和類別檢查一起使用",
"newTypeClassNotAllowed": "Type created with NewType cannot be used with instance and class checks",
"noOverloadAssignable": "沒有任何多載函式符合類型 \"{type}\"",
"noneNotAllowed": "無法對執行個體或類別檢查使用 None",
"orPatternMissingName": "遺失名稱: {name}",

View file

@ -420,6 +420,7 @@ async function processArgs(): Promise<ExitStatus> {
hostFactory: () => new FullAccessHost(serviceProvider),
// Refresh service 2 seconds after the last library file change is detected.
libraryReanalysisTimeProvider: () => 2 * 1000,
shouldRunAnalysis: () => true,
});
if ('threads' in args) {
@ -792,6 +793,7 @@ function runWorkerMessageLoop(workerNum: number, tempFolderName: string) {
hostFactory: () => new FullAccessHost(serviceProvider!),
// Refresh service 2 seconds after the last library file change is detected.
libraryReanalysisTimeProvider: () => 2 * 1000,
shouldRunAnalysis: () => true,
});
service.setCompletionCallback((results) => {

View file

@ -269,6 +269,7 @@ function createServiceWithChainedSourceFiles(basePath: Uri, code: string) {
importResolverFactory: AnalyzerService.createImportResolver,
configOptions: new ConfigOptions(basePath),
fileSystem: fs,
shouldRunAnalysis: () => true,
});
const data = parseTestData(basePath.getFilePath(), code, '');

View file

@ -607,6 +607,10 @@ describe(`config test'}`, () => {
const serviceProvider = createServiceProvider(fs, cons, tempFile);
const host = new TestAccessHost();
host.getPythonVersion = () => pythonVersion3_13;
return new AnalyzerService('<default>', serviceProvider, { console: cons, hostFactory: () => host });
return new AnalyzerService('<default>', serviceProvider, {
console: cons,
hostFactory: () => host,
shouldRunAnalysis: () => true,
});
}
});

View file

@ -216,6 +216,7 @@ function createWorkspace(rootUri: Uri | undefined) {
hostFactory: () => new TestAccessHost(),
importResolverFactory: AnalyzerService.createImportResolver,
configOptions: new ConfigOptions(Uri.empty()),
shouldRunAnalysis: () => true,
}),
disableLanguageServices: false,
disableTaggedHints: false,

View file

@ -99,6 +99,7 @@ export class TestLanguageService implements LanguageServerInterface {
importResolverFactory: AnalyzerService.createImportResolver,
configOptions: new ConfigOptions(Uri.empty()),
fileSystem: this.fs,
shouldRunAnalysis: () => true,
}
),
disableLanguageServices: false,

View file

@ -1732,6 +1732,7 @@ export class TestState {
configOptions,
fileSystem: this.fs,
libraryReanalysisTimeProvider: () => 0,
shouldRunAnalysis: () => true,
});
// directly set files to track rather than using fileSpec from config

View file

@ -31,6 +31,7 @@ import {
PyrightServerInfo,
runPyrightServer,
waitForDiagnostics,
waitForPushDiagnostics,
} from './lsp/languageServerTestUtils';
describe(`Basic language server tests`, () => {
@ -155,7 +156,7 @@ describe(`Basic language server tests`, () => {
describe(`Diagnostics ${supportsPullDiagnostics ? 'pull' : 'push'}`, () => {
// Background analysis takes longer than 5 seconds sometimes, so we need to
// increase the timeout.
jest.setTimeout(15000);
jest.setTimeout(20000);
test('background thread diagnostics', async () => {
const code = `
// @filename: root/test.py
@ -190,7 +191,7 @@ describe(`Basic language server tests`, () => {
await openFile(info, 'marker');
// Wait for the diagnostics to publish
const diagnostics = await waitForDiagnostics(info);
const diagnostics = await waitForPushDiagnostics(info, false);
const diagnostic = diagnostics.find((d) => d.uri.includes('root/test.py'));
assert(diagnostic);
assert.equal(diagnostic.diagnostics.length, 6);
@ -237,12 +238,8 @@ describe(`Basic language server tests`, () => {
const diagnostics = await waitForDiagnostics(info);
const diagnostic = diagnostics.find((d) => d.uri.includes('root/test.py'));
assert(diagnostic);
assert.equal(diagnostic.diagnostics.length, 6);
// Make sure the error has a special rule
assert.equal(diagnostic.diagnostics[1].code, 'reportUnusedImport');
assert.equal(diagnostic.diagnostics[3].code, 'reportUnusedImport');
assert.equal(diagnostic.diagnostics[4].code, 'reportUnusedImport');
const unusedImports = diagnostic.diagnostics.filter((d) => d.code === 'reportUnusedImport');
assert.equal(unusedImports.length, 3);
});
test('Diagnostic severity overrides test', async () => {

View file

@ -116,6 +116,8 @@ export interface PyrightServerInfo {
getInitializeParams(): InitializeParams;
dispose(): Promise<void>;
convertPathToUri(path: string): Uri;
workspaceDiagnosticsPartialResultToken?: string;
pendingWorkspaceDiagnostics?: Promise<any>;
}
export class TestHostOptions {
@ -288,20 +290,53 @@ export async function getOpenFiles(info: PyrightServerInfo, projectRoot?: Uri):
return deserialize(result.files);
}
async function waitForPushDiagnostics(info: PyrightServerInfo, timeout = 10000) {
const deferred = createDeferred<void>();
const disposable = info.diagnosticsEvent((params) => {
if (params.diagnostics.length > 0) {
deferred.resolve();
}
});
const timer = setTimeout(() => deferred.reject('Timed out waiting for diagnostics'), timeout);
try {
await deferred.promise;
} finally {
clearTimeout(timer);
disposable.dispose();
export async function waitForPushDiagnostics(
info: PyrightServerInfo,
clearFirst: boolean,
numberOfFiles = 1,
timeout = 10000
): Promise<PublishDiagnosticsParams[]> {
if (clearFirst) {
info.diagnostics = [];
}
// We may already have the necessary diagnostics.
const currentCount = info.diagnostics.filter((d) => d.diagnostics.length > 0).length;
if (currentCount >= numberOfFiles) {
return info.diagnostics;
}
// Otherwise we have to get called back with the diagnostics. Swallow any errors (timeouts, etc.)
// and just return what we currently have so callers can choose how strict to be.
let eventCount = currentCount;
try {
await waitForEvent(
info.diagnosticsEvent,
'diagnostics',
(params) => {
if (params.diagnostics.length > 0) {
eventCount++;
if (eventCount >= numberOfFiles) {
return true;
}
}
return false;
},
timeout
);
} catch (e: any) {
try {
console.log?.(
`waitForPushDiagnostics: ignoring error while waiting for diagnostics: ${
e?.message || e
}. Had ${eventCount} of ${numberOfFiles} events`
);
} catch {
/* ignore logging issues */
}
}
return info.diagnostics;
}
@ -354,11 +389,7 @@ export function convertDiagnosticReport(
async function waitForPullDiagnostics(info: PyrightServerInfo): Promise<PublishDiagnosticsParams[]> {
const openFiles = await getOpenFiles(info);
if (openFiles.length <= 0) {
const results = await info.connection.sendRequest(WorkspaceDiagnosticRequest.type, {
identifier: 'Pylance',
previousResultIds: [],
});
return convertDiagnosticReport(undefined, results);
return waitForPushDiagnostics(info, false);
} else {
const results: PublishDiagnosticsParams[] = [];
for (const openFile of openFiles) {
@ -378,7 +409,7 @@ export async function waitForDiagnostics(info: PyrightServerInfo, timeout = 2000
// Timeout doesn't apply on pull because we can actually ask for them.
return waitForPullDiagnostics(info);
}
return waitForPushDiagnostics(info, timeout);
return waitForPushDiagnostics(info, false, undefined, timeout);
}
interface ProgressPart {}
@ -419,6 +450,24 @@ class TestProgressPart implements ProgressPart {
}
}
export async function waitForPromise(promise: Promise<any>, timeout = 10000, message?: string): Promise<any> {
return await new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error(message || `Timed out waiting for promise`));
}, timeout);
promise
.then((result) => {
clearTimeout(timer);
resolve(result);
})
.catch((error) => {
clearTimeout(timer);
reject(error);
});
});
}
export async function runPyrightServer(
projectRoots: string[] | string,
code: string,
@ -469,7 +518,7 @@ export async function runPyrightServer(
const serverStarted = createDeferred<string>();
const diagnosticsEmitter = new Emitter<PublishDiagnosticsParams>();
const workspaceEditsEmitter = new Emitter<ApplyWorkspaceEditParams>();
const diagnosticsMode = extraSettings?.find((s) => s.item.section === 'python.analysis')?.value?.diagnosticMode;
const partialResultToken = `4fb5ab8a-37a6-4c16-a290-03cfc892ea7e`; // Doesn't need to be different, just a random guid
// Setup the server info.
const info: PyrightServerInfo = {
@ -484,26 +533,28 @@ export async function runPyrightServer(
testData,
testName: testServerData.testName,
telemetry: [],
supportsPullDiagnostics: (supportPullDiagnostics && diagnosticsMode !== 'workspace') ?? false,
supportsPullDiagnostics: !!supportPullDiagnostics,
projectRoots: testServerData.projectRoots,
diagnostics: [],
diagnosticsEvent: diagnosticsEmitter.event,
workspaceEdits: [],
workspaceEditsEvent: workspaceEditsEmitter.event,
getInitializeParams: () =>
getInitializeParams(testServerData.projectRoots, !!supportPullDiagnostics, diagnosticsMode),
getInitializeParams: () => getInitializeParams(testServerData.projectRoots, !!supportPullDiagnostics),
convertPathToUri: (path: string) => UriEx.file(path, !ignoreCase),
dispose: async () => {
// Send shutdown. This should disconnect the dispatcher and kill the server.
if (serverWorker) {
await connection.sendRequest(ShutdownRequest.type, undefined);
}
// Shutdown of the server should resolve any pending workspace diagnostics requests.
await stopWorkspaceDiagnostics(info, 'shutdown');
// Now we can dispose the connection.
disposables.forEach((d) => d.dispose());
logToDisk(`Finished test ${testServerData.testName}`, testServerData.logFile);
},
workspaceDiagnosticsPartialResultToken: supportPullDiagnostics ? partialResultToken : undefined,
};
info.disposables.push(
info.connection.onNotification(CustomLSP.Notifications.TestStartServerResponse, (p) => {
@ -511,6 +562,18 @@ export async function runPyrightServer(
}),
info.connection.onRequest(RegistrationRequest.type, (p) => {
info.registrations.push(...p.registrations);
// If this is a DocumentDiagnostic registration, we may need to start workspace diagnostics.
const documentDiagnosticRegistration = p.registrations.find(
(r) => r.method === DocumentDiagnosticRequest.type.method
);
if (documentDiagnosticRegistration) {
if (documentDiagnosticRegistration.registerOptions.workspaceDiagnostics) {
startWorkspaceDiagnostics(info, 'registration');
} else {
stopWorkspaceDiagnostics(info, 'registration');
}
}
}),
info.connection.onNotification(CustomLSP.Notifications.TestSignal, (p: CustomLSP.TestSignal) => {
info.signals.get(p.kind)!.resolve(true);
@ -558,6 +621,15 @@ export async function runPyrightServer(
}),
info.connection.onNotification(TelemetryEventNotification.type, (p) => {
info.telemetry.push(p);
}),
info.connection.onProgress(WorkspaceDiagnosticRequest.partialResult, partialResultToken, (progress) => {
const converted = convertDiagnosticReport(undefined, progress);
// Replace any current diagnostics with their new set
for (const p of converted) {
info.diagnostics = info.diagnostics.filter((d) => d.uri !== p.uri);
info.diagnostics.push(p);
diagnosticsEmitter.fire(p);
}
})
);
info.disposables.push(
@ -617,6 +689,37 @@ export async function runPyrightServer(
return info;
}
function startWorkspaceDiagnostics(info: PyrightServerInfo, extraMessage: string) {
if (!info.pendingWorkspaceDiagnostics) {
info.logs.push({ message: `Starting workspace diagnostics request: ${extraMessage}`, type: 4 });
info.pendingWorkspaceDiagnostics = info.connection
.sendRequest(WorkspaceDiagnosticRequest.type, {
identifier: 'Pylance',
previousResultIds: [],
partialResultToken: info.workspaceDiagnosticsPartialResultToken,
})
.then(() => {
info.logs.push({ message: 'Workspace diagnostics request completed', type: 4 });
});
}
}
async function stopWorkspaceDiagnostics(info: PyrightServerInfo, extraMessage: string) {
if (info.pendingWorkspaceDiagnostics) {
const pending = info.pendingWorkspaceDiagnostics;
info.pendingWorkspaceDiagnostics = undefined;
try {
await waitForPromise(
pending,
5000,
`Timed out waiting for stopping workspace diagnostics during ${extraMessage}`
);
} catch {
// Ignore errors. We're trying to stop it.
}
}
}
export async function initializeLanguageServer(info: PyrightServerInfo) {
const params = info.getInitializeParams();
@ -640,6 +743,10 @@ export async function initializeLanguageServer(info: PyrightServerInfo) {
await info.signals.get(CustomLSP.TestSignalKinds.Initialization)!.promise;
}
// Start the polling for workspace diagnostics as done by the VS Code LSP client.
if (result.capabilities.diagnosticProvider?.workspaceDiagnostics) {
startWorkspaceDiagnostics(info, 'initialize');
}
return result;
}
@ -677,11 +784,7 @@ export async function hover(info: PyrightServerInfo, markerName: string) {
return hoverResult;
}
export function getInitializeParams(
projectRoots: Uri[],
supportsPullDiagnostics: boolean,
diagnosticMode: string | undefined = undefined
) {
export function getInitializeParams(projectRoots: Uri[], supportsPullDiagnostics: boolean) {
// cloned vscode "1.71.0-insider"'s initialize params.
const workspaceFolders = projectRoots
? projectRoots.map((root, i) => ({ name: root.fileName, uri: projectRoots[i].toString() }))
@ -1034,7 +1137,6 @@ export function getInitializeParams(
},
initializationOptions: {
autoFormatStrings: true,
diagnosticMode: diagnosticMode ?? 'openFilesOnly',
disablePullDiagnostics: !supportsPullDiagnostics,
},
workspaceFolders,