pull-pylance-with-pyright-1.1.369-9716881771

This commit is contained in:
GitHub Actions 2024-06-28 18:13:36 +00:00
parent 3c70b4e0d1
commit 1fde529ada
23 changed files with 270 additions and 162 deletions

View File

@ -109,7 +109,8 @@ export class ImportResolver {
private _cachedFilesForPath = new Map<string, Uri[]>();
private _cachedDirExistenceForRoot = new Map<string, boolean>();
private _stdlibModules: Set<string> | undefined;
protected cachedParentImportResults: ParentDirectoryCache;
protected readonly cachedParentImportResults: ParentDirectoryCache;
constructor(readonly serviceProvider: ServiceProvider, private _configOptions: ConfigOptions, readonly host: Host) {
this.cachedParentImportResults = new ParentDirectoryCache(() => this.getPythonSearchPaths([]));
@ -172,7 +173,7 @@ export class ImportResolver {
return suggestions;
}
const root = this.getParentImportResolutionRoot(sourceFileUri, execEnv.root);
const root = getParentImportResolutionRoot(sourceFileUri, execEnv.root);
const origin = sourceFileUri.getDirectory();
let current: Uri | undefined = origin;
@ -533,7 +534,7 @@ export class ImportResolver {
execEnv: ExecutionEnvironment,
moduleDescriptor: ImportedModuleDescriptor
): ImportResult {
const importName = this.formatImportName(moduleDescriptor);
const importName = formatImportName(moduleDescriptor);
const importFailureInfo: string[] = [];
const importResult = this._resolveImportStrict(
importName,
@ -559,7 +560,7 @@ export class ImportResolver {
}
// Check whether the given file is in the parent directory import resolution cache.
const root = this.getParentImportResolutionRoot(sourceFileUri, execEnv.root);
const root = getParentImportResolutionRoot(sourceFileUri, execEnv.root);
if (!this.cachedParentImportResults.checkValidPath(this.fileSystem, sourceFileUri, root)) {
return importResult;
}
@ -776,74 +777,12 @@ export class ImportResolver {
protected getNativeModuleName(uri: Uri): string | undefined {
const fileExtension = uri.lastExtension.toLowerCase();
if (this._isNativeModuleFileExtension(fileExtension)) {
if (_isNativeModuleFileExtension(fileExtension)) {
return stripFileExtension(uri.fileName, /* multiDotExtension */ true);
}
return undefined;
}
protected getModuleNameFromPath(
containerPath: Uri,
fileUri: Uri,
stripTopContainerDir = false
): string | undefined {
const moduleNameInfo = this.getModuleNameInfoFromPath(containerPath, fileUri, stripTopContainerDir);
if (!moduleNameInfo || moduleNameInfo.containsInvalidCharacters) {
return undefined;
}
return moduleNameInfo.moduleName;
}
protected getModuleNameInfoFromPath(
containerPath: Uri,
fileUri: Uri,
stripTopContainerDir = false
): ModuleNameInfoFromPath | undefined {
let fileUriWithoutExtension = fileUri.stripExtension();
// If module is native, strip platform part, such as 'cp36-win_amd64' in 'mtrand.cp36-win_amd64'.
if (this._isNativeModuleFileExtension(fileUri.lastExtension)) {
fileUriWithoutExtension = fileUriWithoutExtension.stripExtension();
}
if (!fileUriWithoutExtension.startsWith(containerPath)) {
return undefined;
}
// Strip off the '/__init__' if it's present.
if (fileUriWithoutExtension.pathEndsWith('__init__')) {
fileUriWithoutExtension = fileUriWithoutExtension.getDirectory();
}
const parts = Array.from(containerPath.getRelativePathComponents(fileUriWithoutExtension));
if (stripTopContainerDir) {
if (parts.length === 0) {
return undefined;
}
parts.shift();
}
if (parts.length === 0) {
return undefined;
}
// Handle the case where the symbol was resolved to a stubs package
// rather than the real package. We'll strip off the "-stubs" suffix
// in this case.
if (parts[0].endsWith(stubsSuffix)) {
parts[0] = parts[0].substr(0, parts[0].length - stubsSuffix.length);
}
// Check whether parts contains invalid characters.
const containsInvalidCharacters = parts.some((p) => !this._isIdentifier(p));
return {
moduleName: parts.join('.'),
containsInvalidCharacters,
};
}
// Potentially modifies the ImportResult by removing some or all of the
// implicit import entries. Only the imported symbols should be included.
protected filterImplicitImports(
@ -880,22 +819,6 @@ export class ImportResolver {
return newImportResult;
}
protected formatImportName(moduleDescriptor: ImportedModuleDescriptor) {
return '.'.repeat(moduleDescriptor.leadingDots) + moduleDescriptor.nameParts.join('.');
}
protected getParentImportResolutionRoot(sourceFileUri: Uri, executionRoot: Uri | undefined): Uri {
if (!this._isDefaultWorkspace(executionRoot)) {
return executionRoot!;
}
return sourceFileUri.getDirectory();
}
private _isDefaultWorkspace(uri: Uri | undefined) {
return !uri || uri.isEmpty() || Uri.isDefaultWorkspace(uri);
}
private _resolveImportStrict(
importName: string,
sourceFileUri: Uri,
@ -1119,7 +1042,7 @@ export class ImportResolver {
);
if (stdLibTypeshedPath) {
moduleName = this.getModuleNameFromPath(stdLibTypeshedPath, fileUri);
moduleName = getModuleNameFromPath(stdLibTypeshedPath, fileUri);
if (moduleName) {
const moduleDescriptor: ImportedModuleDescriptor = {
leadingDots: 0,
@ -1149,7 +1072,7 @@ export class ImportResolver {
// Look for it in the root directory of the execution environment.
if (execEnv.root) {
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(execEnv.root, fileUri);
const candidateModuleNameInfo = _getModuleNameInfoFromPath(execEnv.root, fileUri);
if (candidateModuleNameInfo) {
if (candidateModuleNameInfo.containsInvalidCharacters) {
@ -1163,7 +1086,7 @@ export class ImportResolver {
}
for (const extraPath of execEnv.extraPaths) {
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(extraPath, fileUri);
const candidateModuleNameInfo = _getModuleNameInfoFromPath(extraPath, fileUri);
if (candidateModuleNameInfo) {
if (candidateModuleNameInfo.containsInvalidCharacters) {
@ -1182,7 +1105,7 @@ export class ImportResolver {
// Check for a typings file.
if (this._configOptions.stubPath) {
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(this._configOptions.stubPath, fileUri);
const candidateModuleNameInfo = _getModuleNameInfoFromPath(this._configOptions.stubPath, fileUri);
if (candidateModuleNameInfo) {
if (candidateModuleNameInfo.containsInvalidCharacters) {
@ -1209,7 +1132,7 @@ export class ImportResolver {
);
if (thirdPartyTypeshedPath) {
const candidateModuleName = this.getModuleNameFromPath(
const candidateModuleName = getModuleNameFromPath(
thirdPartyTypeshedPath,
fileUri,
/* stripTopContainerDir */ true
@ -1226,7 +1149,7 @@ export class ImportResolver {
const thirdPartyTypeshedPathEx = this.getTypeshedPathEx(execEnv, importFailureInfo);
if (thirdPartyTypeshedPathEx) {
const candidateModuleName = this.getModuleNameFromPath(thirdPartyTypeshedPathEx, fileUri);
const candidateModuleName = getModuleNameFromPath(thirdPartyTypeshedPathEx, fileUri);
// Does this candidate look better than the previous best module name?
// We'll always try to use the shortest version.
@ -1241,7 +1164,7 @@ export class ImportResolver {
const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
for (const searchPath of pythonSearchPaths) {
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(searchPath, fileUri);
const candidateModuleNameInfo = _getModuleNameInfoFromPath(searchPath, fileUri);
if (candidateModuleNameInfo) {
if (candidateModuleNameInfo.containsInvalidCharacters) {
@ -1260,7 +1183,7 @@ export class ImportResolver {
}
if (detectPyTyped && importType === ImportType.ThirdParty) {
const root = this.getParentImportResolutionRoot(fileUri, execEnv.root);
const root = getParentImportResolutionRoot(fileUri, execEnv.root);
// Go up directories one by one looking for a py.typed file.
let current: Uri | undefined = fileUri.getDirectory();
@ -1552,7 +1475,7 @@ export class ImportResolver {
moduleDescriptor: ImportedModuleDescriptor,
allowPyi: boolean
): ImportResult | undefined {
const importName = this.formatImportName(moduleDescriptor);
const importName = formatImportName(moduleDescriptor);
const importFailureInfo: string[] = [];
// Check for a local stub file using stubPath.
@ -1828,16 +1751,6 @@ export class ImportResolver {
return bestImportSoFar;
}
private _isIdentifier(value: string) {
for (let i = 0; i < value.length; i++) {
if (i === 0 ? !isIdentifierStartChar(value.charCodeAt(i)) : !isIdentifierChar(value.charCodeAt(i))) {
return false;
}
}
return true;
}
private _findTypeshedPath(
execEnv: ExecutionEnvironment,
moduleDescriptor: ImportedModuleDescriptor,
@ -2588,7 +2501,7 @@ export class ImportResolver {
// Make sure we don't use parent folder resolution when checking whether the given name is resolvable.
let importResult: ImportResult | undefined;
if (strictOnly) {
const importName = this.formatImportName(moduleDescriptor);
const importName = formatImportName(moduleDescriptor);
const importFailureInfo: string[] = [];
importResult = this._resolveImportStrict(
@ -2653,7 +2566,7 @@ export class ImportResolver {
if (fileExt === '.py' || fileExt === '.pyi') {
strippedFileName = stripFileExtension(filePath.fileName);
} else if (
this._isNativeModuleFileExtension(fileExt) &&
_isNativeModuleFileExtension(fileExt) &&
!this.fileExistsCached(filePath.packageUri) &&
!this.fileExistsCached(filePath.packageStubUri)
) {
@ -2770,15 +2683,10 @@ export class ImportResolver {
const fileExtension = fileUri.lastExtension.toLowerCase();
const withoutExtension = stripFileExtension(fileUri.fileName, /* multiDotExtension */ true);
return (
this._isNativeModuleFileExtension(fileExtension) &&
equateStringsCaseInsensitive(moduleName, withoutExtension)
_isNativeModuleFileExtension(fileExtension) && equateStringsCaseInsensitive(moduleName, withoutExtension)
);
}
private _isNativeModuleFileExtension(fileExtension: string): boolean {
return supportedNativeLibExtensions.some((ext) => ext === fileExtension);
}
private _tryWalkUp(current: Uri | undefined): Uri | undefined {
if (!current || current.isEmpty() || current.isRoot()) {
return undefined;
@ -2796,7 +2704,7 @@ export class ImportResolver {
return (
current &&
!current.isEmpty() &&
(current.isChild(root) || (current.equals(root) && this._isDefaultWorkspace(execEnv.root)))
(current.isChild(root) || (current.equals(root) && _isDefaultWorkspace(execEnv.root)))
);
}
}
@ -2806,3 +2714,95 @@ export type ImportResolverFactory = (
options: ConfigOptions,
host: Host
) => ImportResolver;
export function formatImportName(moduleDescriptor: ImportedModuleDescriptor) {
return '.'.repeat(moduleDescriptor.leadingDots) + moduleDescriptor.nameParts.join('.');
}
export function getParentImportResolutionRoot(sourceFileUri: Uri, executionRoot: Uri | undefined): Uri {
if (!_isDefaultWorkspace(executionRoot)) {
return executionRoot!;
}
return sourceFileUri.getDirectory();
}
export function getModuleNameFromPath(
containerPath: Uri,
fileUri: Uri,
stripTopContainerDir = false
): string | undefined {
const moduleNameInfo = _getModuleNameInfoFromPath(containerPath, fileUri, stripTopContainerDir);
if (!moduleNameInfo || moduleNameInfo.containsInvalidCharacters) {
return undefined;
}
return moduleNameInfo.moduleName;
}
function _getModuleNameInfoFromPath(
containerPath: Uri,
fileUri: Uri,
stripTopContainerDir = false
): ModuleNameInfoFromPath | undefined {
let fileUriWithoutExtension = fileUri.stripExtension();
// If module is native, strip platform part, such as 'cp36-win_amd64' in 'mtrand.cp36-win_amd64'.
if (_isNativeModuleFileExtension(fileUri.lastExtension)) {
fileUriWithoutExtension = fileUriWithoutExtension.stripExtension();
}
if (!fileUriWithoutExtension.startsWith(containerPath)) {
return undefined;
}
// Strip off the '/__init__' if it's present.
if (fileUriWithoutExtension.pathEndsWith('__init__')) {
fileUriWithoutExtension = fileUriWithoutExtension.getDirectory();
}
const parts = Array.from(containerPath.getRelativePathComponents(fileUriWithoutExtension));
if (stripTopContainerDir) {
if (parts.length === 0) {
return undefined;
}
parts.shift();
}
if (parts.length === 0) {
return undefined;
}
// Handle the case where the symbol was resolved to a stubs package
// rather than the real package. We'll strip off the "-stubs" suffix
// in this case.
if (parts[0].endsWith(stubsSuffix)) {
parts[0] = parts[0].substr(0, parts[0].length - stubsSuffix.length);
}
// Check whether parts contains invalid characters.
const containsInvalidCharacters = parts.some((p) => !_isIdentifier(p));
return {
moduleName: parts.join('.'),
containsInvalidCharacters,
};
}
function _isNativeModuleFileExtension(fileExtension: string): boolean {
return supportedNativeLibExtensions.some((ext) => ext === fileExtension);
}
function _isDefaultWorkspace(uri: Uri | undefined) {
return !uri || uri.isEmpty() || Uri.isDefaultWorkspace(uri);
}
function _isIdentifier(value: string) {
for (let i = 0; i < value.length; i++) {
if (i === 0 ? !isIdentifierStartChar(value.charCodeAt(i)) : !isIdentifierChar(value.charCodeAt(i))) {
return false;
}
}
return true;
}

View File

@ -24,11 +24,13 @@ export class BackgroundAnalysis extends BackgroundAnalysisBase {
constructor(serviceProvider: ServiceProvider) {
super(serviceProvider.console());
const index = ++BackgroundAnalysis._workerIndex;
const initialData: InitializationData = {
rootUri: getRootUri(serviceProvider)?.toString() ?? '',
serviceId: index.toString(),
cancellationFolderName: getCancellationFolderName(),
runner: undefined,
workerIndex: ++BackgroundAnalysis._workerIndex,
workerIndex: index,
};
// this will load this same file in BG thread and start listener

View File

@ -310,7 +310,14 @@ export abstract class BackgroundAnalysisRunnerBase extends BackgroundThreadBase
const console = this.getConsole();
this.logTracker = new LogTracker(console, `BG(${threadId})`);
this._program = new Program(this.importResolver, this._configOptions, serviceProvider, this.logTracker);
this._program = new Program(
this.importResolver,
this._configOptions,
serviceProvider,
this.logTracker,
undefined,
data.serviceId
);
}
get program(): Program {

View File

@ -251,10 +251,10 @@ export function getBackgroundWaiter<T>(port: MessagePort, deserializer: (v: any)
export interface InitializationData {
rootUri: string;
serviceId: string;
workerIndex: number;
cancellationFolderName: string | undefined;
runner: string | undefined;
title?: string;
workerIndex: number;
}
export interface RequestResponse {

View File

@ -6,7 +6,7 @@
* Helper functions relating to collections and arrays.
*/
import { compareValues, Comparison, equateValues, isArray } from './core';
import { compareValues, Comparison, equateValues, isArray, MapLike } from './core';
export const emptyArray: never[] = [] as never[];
export type EqualityComparer<T> = (a: T, b: T) => boolean;
@ -318,7 +318,7 @@ export function getNestedProperty(object: any, property: string) {
return value;
}
export function getOrAdd<K, V>(map: Map<K, V>, key: K, newValueFactory: () => V): V {
export function getOrAdd<K, V>(map: MapLike<K, V>, key: K, newValueFactory: () => V): V {
const value = map.get(key);
if (value !== undefined) {
return value;

View File

@ -102,8 +102,11 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
* The `in` and `for-in` operators can *not* be safely used,
* since `Object.prototype` may be modified by outside code.
*/
export interface MapLike<T> {
[index: string]: T;
export interface MapLike<K, V> {
readonly [Symbol.toStringTag]: string;
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): this;
}
/**
@ -112,7 +115,7 @@ export interface MapLike<T> {
* @param map A map-like.
* @param key A property key.
*/
export function hasProperty(map: MapLike<any>, key: string): boolean {
export function hasProperty(map: { [index: string]: any }, key: string): boolean {
return hasOwnProperty.call(map, key);
}

View File

@ -70,6 +70,7 @@ export function expandPathVariables(path: string, rootPath: Uri, workspaces: Wor
const ws_regexp = RegExp(`\\$\\{workspaceFolder:${escapedWorkspaceName}\\}`, 'g');
path = path.replace(ws_regexp, workspace.rootUri.getPath());
}
if (process.env.HOME !== undefined) {
replace(/\$\{env:HOME\}/g, process.env.HOME || '');
}

View File

@ -46,6 +46,7 @@ import { printLiteralValue } from '../analyzer/typePrinter';
import {
ClassType,
combineTypes,
EnumLiteral,
FunctionType,
isClass,
isClassInstance,
@ -127,6 +128,7 @@ import {
import { DocumentSymbolCollector } from './documentSymbolCollector';
import { getAutoImportText, getDocumentationPartsForTypeAndDecl } from './tooltipUtils';
import '../common/serviceProviderExtensions';
import { transformTypeForEnumMember } from '../analyzer/enums';
namespace Keywords {
const base: string[] = [
@ -705,13 +707,7 @@ export class CompletionProvider {
// Handle enum members specially. Enum members normally look like
// variables, but the are declared using assignment expressions
// within an enum class.
if (
primaryDecl.type === DeclarationType.Variable &&
detail.boundObjectOrClass &&
isInstantiableClass(detail.boundObjectOrClass) &&
ClassType.isEnumClass(detail.boundObjectOrClass) &&
primaryDecl.node.parent?.nodeType === ParseNodeType.Assignment
) {
if (this._isEnumMember(detail.boundObjectOrClass, name)) {
itemKind = CompletionItemKind.EnumMember;
}
@ -757,19 +753,16 @@ export class CompletionProvider {
if (isClass(subtype)) {
const instance = TypeBase.isInstance(subtype);
if (ClassType.isEnumClass(subtype) && instance) {
// We don't add members for instances of enum members, but do add members of `enum.Enum` itself.
// ex) 'MyEnum.member.' <= here
const enumType = subtype.details.baseClasses.find(
(t) => isClass(t) && ClassType.isBuiltIn(t, 'Enum')
) as ClassType | undefined;
if (!enumType) {
return;
}
getMembersForClass(subtype, symbolTable, instance);
getMembersForClass(enumType, symbolTable, /* instance */ true);
} else {
getMembersForClass(subtype, symbolTable, instance);
if (ClassType.isEnumClass(subtype) && instance) {
// Don't show enum member out of another enum member
// ex) Enum.Member. <= shouldn't show `Member` again.
for (const name of symbolTable.keys()) {
if (this._isEnumMember(subtype, name)) {
symbolTable.delete(name);
}
}
}
} else if (isModule(subtype)) {
getMembersForModule(subtype, symbolTable);
@ -3143,6 +3136,21 @@ export class CompletionProvider {
// before doing more expensive type evaluation.
return decl.isMethod && decl.node.decorators.length > 0;
}
private _isEnumMember(containingType: ClassType | undefined, name: string) {
if (!containingType || !ClassType.isEnumClass(containingType)) {
return false;
}
const symbolType = transformTypeForEnumMember(this.evaluator, containingType, name);
return (
symbolType &&
isClassInstance(symbolType) &&
ClassType.isSameGenericClass(symbolType, containingType) &&
symbolType.literalValue instanceof EnumLiteral
);
}
}
export class CompletionMap {

View File

@ -118,7 +118,7 @@ export function setLocaleOverride(locale: string) {
localeOverride = locale.toLowerCase();
}
export function getLocaleFromEnv() {
export function getLocaleFromEnv(): string {
if (localeOverride) {
return localeOverride;
}
@ -130,7 +130,7 @@ export function getLocaleFromEnv() {
const vscodeConfigString = env?.VSCODE_NLS_CONFIG;
if (vscodeConfigString) {
try {
return JSON.parse(vscodeConfigString).locale;
return JSON.parse(vscodeConfigString).locale || defaultLocale;
} catch {
// Fall through
}
@ -142,7 +142,7 @@ export function getLocaleFromEnv() {
// This string may contain a local followed by an encoding (e.g. "en-us.UTF-8").
const localeStringSplit = localeString.split('.');
if (localeStringSplit.length > 0 && localeStringSplit[0]) {
return localeStringSplit[0];
return localeStringSplit[0] || defaultLocale;
}
}
} catch {

View File

@ -158,8 +158,8 @@
"enumMemberDelete": "Člen výčtu {name} se nedá odstranit.",
"enumMemberSet": "Člen výčtu {name} se nedá přiřadit.",
"enumMemberTypeAnnotation": "Poznámky typu nejsou pro členy výčtu povolené",
"exceptionGroupIncompatible": "Syntaxe skupiny výjimek (except*) vyžaduje Python 3.11 nebo novější",
"exceptionGroupTypeIncorrect": "Typ výjimky v kromě* se nedá odvodit z BaseGroupException.",
"exceptionGroupIncompatible": "Syntaxe skupiny výjimek (\"except*\") vyžaduje Python 3.11 nebo novější",
"exceptionGroupTypeIncorrect": "Typ výjimky v except* se nedá odvodit z BaseGroupException.",
"exceptionTypeIncorrect": "„{type}“ se neodvozuje od BaseException",
"exceptionTypeNotClass": "{type} není platná třída výjimky",
"exceptionTypeNotInstantiable": "Konstruktor pro výjimku typu {type} vyžaduje jeden nebo více argumentů",
@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Argumenty typu nejsou u třídy Protocol povoleny při použití syntaxe parametru typu",
"protocolIllegal": "Použití protokolu vyžaduje Python 3.7 nebo novější",
"protocolNotAllowed": "„Protocol“ nejde v tomto kontextu použít.",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "Argument typu pro „protokol“ musí být parametr typu",
"protocolUnsafeOverlap": "Třída se nebezpečně překrývá s názvem „{name}“ a může vytvořit shodu při spuštění.",
"protocolVarianceContravariant": "Proměnná typu „{variable}“ použitá v obecném protokolu „{class}“ by měla být kontravariantní",
"protocolVarianceCovariant": "Proměnná typu „{variable}“ použitá v obecném protokolu „{class}“ by měla být kovariantní",

View File

@ -159,7 +159,7 @@
"enumMemberSet": "Das Enumerationselement \"{name}\" kann nicht zugewiesen werden.",
"enumMemberTypeAnnotation": "Typanmerkungen sind für Enumerationsmember nicht zulässig",
"exceptionGroupIncompatible": "Die Ausnahmegruppensyntax (\"except*\") erfordert Python 3.11 oder höher.",
"exceptionGroupTypeIncorrect": "Der Ausnahmetyp in except* kann nicht von BaseGroupException abgeleitet werden.",
"exceptionGroupTypeIncorrect": "Der Ausnahmetyp in except* kann nicht von BaseGroupException abgeleitet werden.",
"exceptionTypeIncorrect": "\"{type}\" ist nicht von BaseException abgeleitet.",
"exceptionTypeNotClass": "\"{type}\" ist keine gültige Ausnahmeklasse.",
"exceptionTypeNotInstantiable": "Der Konstruktor für den Ausnahmetyp \"{type}\" erfordert mindestens ein Argument.",
@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Typargumente sind mit der Protokollklasse nicht zulässig, wenn die Typparametersyntax verwendet wird.",
"protocolIllegal": "Die Verwendung von \"Protocol\" erfordert Python 3.7 oder höher.",
"protocolNotAllowed": "\"Protocol\" kann in diesem Kontext nicht verwendet werden.",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "Das Typargument für „Protocol“ muss ein Typparameter sein.",
"protocolUnsafeOverlap": "Die Klasse überlappt unsicher mit „{name}“ und könnte zur Laufzeit eine Übereinstimmung erzeugen.",
"protocolVarianceContravariant": "Die Typvariable \"{variable}\", die im generischen Protokoll \"{class}\" verwendet wird, muss \"contravariant\" sein.",
"protocolVarianceCovariant": "Die Typvariable \"{variable}\", die im generischen Protokoll \"{class}\" verwendet wird, muss \"covariant\" sein.",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "No se permiten argumentos de tipo con la clase Protocol cuando se usa la sintaxis de parámetro de tipo",
"protocolIllegal": "El uso de \"Protocolo\" requiere Python 3.7 o posterior.",
"protocolNotAllowed": "\"Protocolo\" no puede utilizarse en este contexto",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "El argumento de tipo para \"Protocol\" debe ser un parámetro de tipo",
"protocolUnsafeOverlap": "La clase se superpone \"{name}\" de forma no segura y podría producir una coincidencia en tiempo de ejecución",
"protocolVarianceContravariant": "La variable de tipo \"{variable}\" usada en el protocolo genérico \"{class}\" debe ser contravariante.",
"protocolVarianceCovariant": "La variable de tipo \"{variable}\" usada en el protocolo genérico \"{class}\" debe ser covariante",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Les arguments de type ne sont pas autorisés avec la classe Protocol lors de l'utilisation de la syntaxe des paramètres de type",
"protocolIllegal": "Lutilisation de « Protocole » nécessite Python 3.7 ou une version plus récente",
"protocolNotAllowed": "\"Protocole\" ne peut pas être utilisé dans ce contexte",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "Largument de type pour « Protocol » doit être un paramètre de type",
"protocolUnsafeOverlap": "La classe chevauche « {name} » de manière non sécurisée et peut produire une correspondance au moment de lexécution",
"protocolVarianceContravariant": "La variable de type \"{variable}\" utilisée dans le protocole générique \"{class}\" doit être contravariante",
"protocolVarianceCovariant": "La variable de type \"{variable}\" utilisée dans le protocole générique \"{class}\" doit être covariante",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Gli argomenti tipo non sono consentiti con la classe Protocollo quando si usa la sintassi dei parametri tipo",
"protocolIllegal": "L'uso del \"protocollo\" richiede Python 3.7 o versione successiva",
"protocolNotAllowed": "\"Protocol\" non può essere usato in questo contesto",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "L'argomento di tipo per \"Protocol\" deve essere un parametro di tipo",
"protocolUnsafeOverlap": "La classe si sovrappone a \"{name}\" in modo non sicuro e può produrre una corrispondenza in fase di esecuzione",
"protocolVarianceContravariant": "La variabile di tipo \"{variable}\" usata nel protocollo generico \"{class}\" deve essere controvariante",
"protocolVarianceCovariant": "La variabile di tipo \"{variable}\" usata nel protocollo generico \"{class}\" deve essere covariante",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "型パラメーター構文を使用する場合、Protocol クラスでは型引数を使用できません",
"protocolIllegal": "\"Protocol\" を使用するには Python 3.7 以降が必要です",
"protocolNotAllowed": "\"Protocol\" はこのコンテキストでは使用できません",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "\"Protocol\" の型引数は型パラメーターである必要があります",
"protocolUnsafeOverlap": "クラスが安全でない方法で \"{name}\" と重複しており、実行時に一致する可能性があります",
"protocolVarianceContravariant": "ジェネリック プロトコル \"{class}\" で使用される型変数 \"{variable}\" は反変である必要があります",
"protocolVarianceCovariant": "ジェネリック プロトコル \"{class}\" で使用される型変数 \"{variable}\" は共変である必要があります",

View File

@ -159,7 +159,7 @@
"enumMemberSet": "열거형 멤버 \"{name}\"을(를) 할당할 수 없음",
"enumMemberTypeAnnotation": "열거형 멤버에는 형식 주석을 사용할 수 없습니다.",
"exceptionGroupIncompatible": "예외 그룹 구문(\"except*\")에는 Python 3.11 이상이 필요합니다.",
"exceptionGroupTypeIncorrect": "exception*의 예외 형식은 BaseGroupException에서 파생될 수 없습니다.",
"exceptionGroupTypeIncorrect": "except*의 예외 형식은 BaseGroupException에서 파생될 수 없습니다.",
"exceptionTypeIncorrect": "{type}’은 BaseException에서 파생되지 않습니다.",
"exceptionTypeNotClass": "\"{type}\"은(는) 올바른 예외 클래스가 아닙니다.",
"exceptionTypeNotInstantiable": "예외 형식 \"{type}\"에 대한 생성자에는 하나 이상의 인수가 필요합니다.",
@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "형식 매개 변수 구문을 사용할 때는 Protocol 클래스에 형식 인수가 허용되지 않습니다.",
"protocolIllegal": "\"프로토콜\"을 사용하려면 Python 3.7 이상이 필요합니다.",
"protocolNotAllowed": "이 컨텍스트에서는 \"Protocol\"을 사용할 수 없습니다.",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "\"Protocol\"의 형식 인수는 형식 매개 변수여야 합니다.",
"protocolUnsafeOverlap": "클래스가 \"{name}\"과(와) 안전하지 않게 겹치며 런타임에 일치 항목을 생성할 수 있습니다.",
"protocolVarianceContravariant": "{class} 제네릭 프로토콜에서 사용되는 {variable} 형식 변수는 반공변이어야 합니다.",
"protocolVarianceCovariant": "{class} 제네릭 프로토콜에서 사용되는 {variable} 형식 변수는 공변이어야 합니다",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Argumenty typu są niedozwolone w przypadku klasy protokołu, gdy jest używana składnia parametru typu",
"protocolIllegal": "Użycie elementu „Protocol” wymaga języka Python w wersji 3.7 lub nowszej",
"protocolNotAllowed": "„Protokół” nie może być używany w tym kontekście",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "Argument typu dla elementy „Protocol” musi być parametrem typu",
"protocolUnsafeOverlap": "Klasa nakłada się niebezpiecznie na element „{name}” i może utworzyć dopasowanie w czasie wykonywania",
"protocolVarianceContravariant": "Zmienna typu „{variable}” używana w klasie protokołu ogólnego „{class}” powinna być kontrawariantna",
"protocolVarianceCovariant": "Zmienna typu „{variable}” używana w klasie protokołu ogólnego „{class}” powinna być kowariantna",

View File

@ -158,8 +158,8 @@
"enumMemberDelete": "O membro enumerado \"{name}\" não pode ser excluído",
"enumMemberSet": "O membro enumerado \"{name}\" não pode ser atribuído",
"enumMemberTypeAnnotation": "Anotações de tipo não são permitidas para membros de enumeração",
"exceptionGroupIncompatible": "A sintaxe do grupo de exceção (\"exceto*\") requer o Python 3.11 ou mais recente",
"exceptionGroupTypeIncorrect": "O tipo de exceção em exceto* não pode derivar de BaseGroupException",
"exceptionGroupIncompatible": "A sintaxe do grupo de exceção (\"except*\") requer o Python 3.11 ou mais recente",
"exceptionGroupTypeIncorrect": "O tipo de exceção em except* não pode derivar de BaseGroupException",
"exceptionTypeIncorrect": "\"{type}\" não deriva de BaseException",
"exceptionTypeNotClass": "\"{type}\" não é uma classe de exceção válida",
"exceptionTypeNotInstantiable": "O construtor para o tipo de exceção \"{type}\" requer um ou mais argumentos",
@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Argumentos de tipo não são permitidos com a classe Protocol ao usar a sintaxe de parâmetro de tipo",
"protocolIllegal": "O uso de \"Protocol\" requer o Python 3.7 ou mais recente",
"protocolNotAllowed": "\"Protocol\" não pode ser usado nesse contexto",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "O argumento de tipo para o \"Protocolo\" deve ser um parâmetro de tipo",
"protocolUnsafeOverlap": "A classe se sobrepõe a \"{name}\" de forma não segura e pode produzir uma correspondência em runtime",
"protocolVarianceContravariant": "A variável de tipo \"{variable}\" usada no protocolo genérico \"{class}\" deve ser contravariante",
"protocolVarianceCovariant": "A variável de tipo \"{variable}\" usada no protocolo genérico \"{class}\" deve ser covariante",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Аргументы типа не допускаются с классом протокола при использовании синтаксиса параметра типа",
"protocolIllegal": "Ключевое слово \"Protocol\" можно использовать в Python версии не ниже 3.7",
"protocolNotAllowed": "Невозможно использовать \"Protocol\" в этом контексте",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "Аргумент типа для параметра \"Protocol\" должен быть параметром типа",
"protocolUnsafeOverlap": "Класс небезопасно перекрывает \"{name}\" и может вызвать совпадение во время выполнения",
"protocolVarianceContravariant": "Переменная типа \"{variable}\", используемая в универсальном протоколе \"{class}\", должна быть контравариантной.",
"protocolVarianceCovariant": "Переменная типа \"{variable}\", используемая в универсальном протоколе \"{class}\", должна быть ковариантной",

View File

@ -159,7 +159,7 @@
"enumMemberSet": "Sabit liste üyesi \"{name}\" atanamıyor",
"enumMemberTypeAnnotation": "Sabit listesi üyeleri için tür ek açıklamalarına izin verilmiyor",
"exceptionGroupIncompatible": "Özel durum grubu söz dizimi (\"except*\") için Python 3.11 veya daha yeni bir sürümü gerekiyor",
"exceptionGroupTypeIncorrect": "Except* altındaki özel durum türü BaseGroupException değerinden türetilemiyor",
"exceptionGroupTypeIncorrect": "except* altındaki özel durum türü BaseGroupException değerinden türetilemiyor",
"exceptionTypeIncorrect": "\"{type}\", BaseException türevi değil",
"exceptionTypeNotClass": "\"{type}\" geçerli bir özel durum sınıfı değil",
"exceptionTypeNotInstantiable": "\"{type}\" özel durum türü oluşturucusu bir veya daha fazla bağımsız değişken gerektiriyor",
@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "Tür parametresi söz dizimi kullanılırken, tür bağımsız değişkenlerinin Protokol sınıfıyla kullanılmasına izin verilmez",
"protocolIllegal": "\"Protocol\" kullanımı için Python 3.7 veya daha yeni bir sürümü gerekiyor",
"protocolNotAllowed": "\"Protokol\" bu bağlamda kullanılamaz",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "“Protokol” için tür bağımsız değişkeni bir tür parametresi olmalıdır",
"protocolUnsafeOverlap": "Sınıf, \"{name}\" ile güvenli olmayan bir şekilde çakışıyor ve çalışma zamanında bir eşleşme üretebilir",
"protocolVarianceContravariant": "\"{class}\" genel protokolünde kullanılan \"{variable}\" tür değişkeni, değişken karşıtı olmalıdır",
"protocolVarianceCovariant": "\"{class}\" genel protokolünde kullanılan \"{variable}\" tür değişkeni birlikte değişen olmalıdır",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "使用类型参数语法时,协议类不允许使用类型参数",
"protocolIllegal": "使用 \"Protocol\" 需要 Python 3.7 或更高版本",
"protocolNotAllowed": "\"Protocol\" 不能用于此上下文",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "“协议”的类型参数必须是类型参数",
"protocolUnsafeOverlap": "类与“{name}”不安全地重叠,并且可能在运行时生成匹配项",
"protocolVarianceContravariant": "泛型协议“{class}”中使用的类型变量“{variable}”应为逆变",
"protocolVarianceCovariant": "泛型协议“{class}”中使用的类型变量“{variable}”应为协变",

View File

@ -403,7 +403,7 @@
"protocolBaseClassWithTypeArgs": "使用型別參數語法時,通訊協定類別不允許使用型別引數",
"protocolIllegal": "使用 \"Protocol\" 需要 Python 3.7 或更新版本",
"protocolNotAllowed": "\"Protocol\" 不能用在此內容中",
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
"protocolTypeArgMustBeTypeParam": "“Protocol” 的型別引數必須是型別參數",
"protocolUnsafeOverlap": "類別以不安全方式重疊 \"{name}\",且可能會在運行時間產生相符專案",
"protocolVarianceContravariant": "一般通訊協定 \"{class}\" 中使用的型別變數 \"{variable}\" 必須為逆變數",
"protocolVarianceCovariant": "一般通訊協定 \"{class}\" 中使用的型別變數 \"{variable}\" 必須為共變數",

View File

@ -1302,3 +1302,90 @@ test('import from completion for namespace package', async () => {
},
});
});
test('members off enum member', async () => {
const code = `
// @filename: test.py
//// from enum import Enum
//// class Planet(Enum):
//// MERCURY = (3.303e+23, 2.4397e6)
//// EARTH = (5.976e+24, 6.37814e6)
////
//// def __init__(self, mass, radius):
//// self.mass = mass # in kilograms
//// self.radius = radius # in meters
////
//// @property
//// def surface_gravity(self):
//// # universal gravitational constant (m3 kg-1 s-2)
//// G = 6.67300E-11
//// return G * self.mass / (self.radius * self.radius)
////
//// Planet.EARTH.[|/*marker*/|]
`;
const state = parseAndGetTestState(code).state;
await state.verifyCompletion('excluded', 'markdown', {
['marker']: {
completions: [
{
label: 'MERCURY',
kind: CompletionItemKind.EnumMember,
},
{
label: 'EARTH',
kind: CompletionItemKind.EnumMember,
},
],
},
});
await state.verifyCompletion('included', 'markdown', {
['marker']: {
completions: [
{
label: 'mass',
kind: CompletionItemKind.Variable,
},
{
label: 'radius',
kind: CompletionItemKind.Variable,
},
{
label: 'surface_gravity',
kind: CompletionItemKind.Property,
},
],
},
});
});
test('enum with regular base type', async () => {
const code = `
// @filename: test.py
//// from enum import Enum
//// from datetime import timedelta
//// class Period(timedelta, Enum):
//// Today = -1
////
//// Period.Today.[|/*marker*/|]
`;
const state = parseAndGetTestState(code).state;
await state.verifyCompletion('included', 'markdown', {
['marker']: {
completions: [
{
label: 'days',
kind: CompletionItemKind.Property,
},
{
label: 'seconds',
kind: CompletionItemKind.Property,
},
],
},
});
});