test(vipeye-internal): 清理 Python 时代测试资产并修复陈旧期望
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

- 删除 fourslash 夹具(258 个 .py 用例)、fourSlashRunner、hoverProvider、typeEvaluator1-8、checker(共 276 个 pyright Python 语义用例文件)
- config/sourceFile: reportPrivateImportUsage 基本默认值期望改为 Viper 的 'none'
- config/uri/filesystem/diagnosticOverrides/localizer: 期望改为 .vp/.vpi 扩展、viper.analysis.* 命名空间与 locale 无关断言
- samples: project1/4、venv_auto_detect_*、extended_config 夹具 .py/.pyi 更名为 .vp/.vpi

验证: 相关 32 个套件 343 用例全绿
This commit is contained in:
TermiNexus committed 2026-09-18 22:50:03 +08:00
1 parent e4635eca37
commit a955a5356f
300 files changed
+38 -23110

No files matched your search

@@ -1,723 +0,0 @@
/*
* checker.test.ts
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
* Author: Eric Traut
*
* Unit tests for viper type checker. These tests also
* exercise the type evaluator (which the checker relies
* heavily upon).
*/
import { ConfigOptions } from '../common/configOptions';
import { pythonVersion3_10, pythonVersion3_8, pythonVersion3_9 } from '../common/pythonVersion';
import { Uri } from '../common/uri/uri';
import * as TestUtils from './testUtils';
test('BadToken1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['badToken1.py']);
// We include this in the checker test rather than the tokenizer or
// parser test suite because it has cascading effects that potentially
// affect the type checker logic.
TestUtils.validateResults(analysisResults, 1);
});
test('Unicode1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['unicode1.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('CircularBaseClass', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['circularBaseClass.py']);
TestUtils.validateResults(analysisResults, 2);
});
test('Private1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, optional diagnostics are ignored.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['private1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportPrivateUsage = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['private1.py'], configOptions);
TestUtils.validateResults(analysisResults, 4);
});
test('Private2', () => {
const configOptions = new ConfigOptions(Uri.empty());
configOptions.diagnosticRuleSet.reportPrivateUsage = 'error';
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['private4.py'], configOptions);
TestUtils.validateResults(analysisResults, 1);
});
test('Private3', () => {
const configOptions = new ConfigOptions(Uri.empty());
configOptions.diagnosticRuleSet.reportPrivateUsage = 'error';
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['private6.py'], configOptions);
TestUtils.validateResults(analysisResults, 1);
});
test('Constant1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, optional diagnostics are ignored.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['constant1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportConstantRedefinition = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['constant1.py'], configOptions);
TestUtils.validateResults(analysisResults, 5);
});
test('AbstractClass1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass1.py']);
TestUtils.validateResults(analysisResults, 2);
});
test('AbstractClass2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass2.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('AbstractClass3', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass3.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('AbstractClass4', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass4.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('AbstractClass5', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass5.py']);
TestUtils.validateResults(analysisResults, 3);
});
test('AbstractClass6', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass6.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('AbstractClass7', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass7.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('AbstractClass8', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass8.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('AbstractClass9', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass9.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('AbstractClass10', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass10.py']);
TestUtils.validateResults(analysisResults, 6);
});
test('AbstractClass11', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['abstractClass11.py']);
TestUtils.validateResults(analysisResults, 2);
});
test('Constants1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['constants1.py']);
TestUtils.validateResults(analysisResults, 20);
});
test('NoReturn1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['noreturn1.py']);
TestUtils.validateResults(analysisResults, 5);
});
test('NoReturn2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['noreturn2.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('NoReturn3', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['noreturn3.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('NoReturn4', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['noreturn4.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('With1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with1.py']);
TestUtils.validateResults(analysisResults, 4);
});
test('With2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with2.py']);
TestUtils.validateResults(analysisResults, 3);
});
test('With3', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with3.py']);
TestUtils.validateResults(analysisResults, 4);
});
test('With4', () => {
const configOptions = new ConfigOptions(Uri.empty());
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['with4.py'], configOptions);
TestUtils.validateResults(analysisResults1, 4);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['with4.py'], configOptions);
TestUtils.validateResults(analysisResults2, 0);
});
test('With5', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with5.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('With6', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with6.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('With7', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with7.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('Mro1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['mro1.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('Mro2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['mro2.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('Mro3', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['mro3.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('Mro4', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['mro4.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('DefaultInitializer1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, the reportCallInDefaultInitializer is disabled.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['defaultInitializer1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportCallInDefaultInitializer = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['defaultInitializer1.py'], configOptions);
TestUtils.validateResults(analysisResults, 5);
});
test('UnnecessaryIsInstance1', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryIsInstance1.py'], configOptions);
TestUtils.validateResults(analysisResults, 1);
// Turn on errors.
configOptions.diagnosticRuleSet.reportUnnecessaryIsInstance = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryIsInstance1.py'], configOptions);
TestUtils.validateResults(analysisResults, 5);
});
test('UnnecessaryIsInstance2', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryIsInstance2.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportUnnecessaryIsInstance = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryIsInstance2.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
});
test('UnnecessaryIsSubclass1', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryIsSubclass1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportUnnecessaryIsInstance = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryIsSubclass1.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
});
test('UnnecessaryCast1', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryCast1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportUnnecessaryCast = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryCast1.py'], configOptions);
TestUtils.validateResults(analysisResults, 6);
});
test('UnnecessaryContains1', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryContains1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportUnnecessaryContains = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryContains1.py'], configOptions);
TestUtils.validateResults(analysisResults, 5);
});
test('TypeIgnore1', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Disable type ignore
configOptions.diagnosticRuleSet.enableTypeIgnoreComments = false;
analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore1.py'], configOptions);
TestUtils.validateResults(analysisResults, 3);
});
test('TypeIgnore2', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore2.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Disable type ignore
configOptions.diagnosticRuleSet.enableTypeIgnoreComments = false;
analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore2.py'], configOptions);
TestUtils.validateResults(analysisResults, 4);
});
test('TypeIgnore3', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore3.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Disable type ignore
configOptions.diagnosticRuleSet.enableTypeIgnoreComments = false;
analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore3.py'], configOptions);
TestUtils.validateResults(analysisResults, 4);
});
test('TypeIgnore4', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore4.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
configOptions.diagnosticRuleSet.reportUnnecessaryTypeIgnoreComment = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore4.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
});
test('TypeIgnore5', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore5.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
configOptions.diagnosticRuleSet.reportUnnecessaryTypeIgnoreComment = 'warning';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeIgnore5.py'], configOptions);
TestUtils.validateResults(analysisResults, 0, 1);
});
test('ViperIgnore1', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['viperIgnore1.py'], configOptions);
TestUtils.validateResults(analysisResults, 1);
});
test('ViperIgnore2', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['viperIgnore2.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
configOptions.diagnosticRuleSet.reportUnnecessaryTypeIgnoreComment = 'warning';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['viperIgnore2.py'], configOptions);
TestUtils.validateResults(analysisResults, 2, 3);
});
test('ViperComment1', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['viperComment1.py'], configOptions);
TestUtils.validateResults(analysisResults, 9);
});
test('DuplicateImports1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, optional diagnostics are ignored.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['duplicateImports1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Turn on errors.
configOptions.diagnosticRuleSet.reportDuplicateImport = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['duplicateImports1.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
});
test('ParamNames1', () => {
const configOptions = new ConfigOptions(Uri.empty());
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['paramNames1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0, 11);
configOptions.diagnosticRuleSet.reportSelfClsParameterName = 'none';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['paramNames1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0, 0);
configOptions.diagnosticRuleSet.reportSelfClsParameterName = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['paramNames1.py'], configOptions);
TestUtils.validateResults(analysisResults, 11, 0);
});
test('ParamType1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['paramType1.py']);
TestUtils.validateResults(analysisResults, 9);
});
test('Python2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['python2.py']);
TestUtils.validateResults(analysisResults, 7);
});
test('InconsistentSpaceTab1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['inconsistentSpaceTab1.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('InconsistentSpaceTab2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['inconsistentSpaceTab2.py']);
TestUtils.validateResults(analysisResults, 1);
});
test('DuplicateDeclaration1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['duplicateDeclaration1.py']);
TestUtils.validateResults(analysisResults, 10);
});
test('DuplicateDeclaration2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['duplicateDeclaration2.py']);
TestUtils.validateResults(analysisResults, 4);
});
test('Strings1', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['strings1.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0);
configOptions.diagnosticRuleSet.reportImplicitStringConcatenation = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['strings1.py'], configOptions);
TestUtils.validateResults(analysisResults2, 2);
});
test('UnusedExpression1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, this is a warning.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedExpression1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0, 14);
// Disable it.
configOptions.diagnosticRuleSet.reportUnusedExpression = 'none';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedExpression1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Enable it as an error.
configOptions.diagnosticRuleSet.reportUnusedExpression = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedExpression1.py'], configOptions);
TestUtils.validateResults(analysisResults, 14);
});
test('UnusedImport1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// Enabled it
configOptions.diagnosticRuleSet.reportUnusedImport = 'warning';
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedImport1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0, 2);
// Disable it.
configOptions.diagnosticRuleSet.reportUnusedImport = 'none';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedImport1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Enable it as an error.
configOptions.diagnosticRuleSet.reportUnusedImport = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedImport1.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
});
test('UnusedImport2', () => {
const configOptions = new ConfigOptions(Uri.empty());
// Disable it.
configOptions.diagnosticRuleSet.reportUnusedImport = 'none';
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedImport2.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Enable it as an error.
configOptions.diagnosticRuleSet.reportUnusedImport = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedImport2.py'], configOptions);
TestUtils.validateResults(analysisResults, 2);
});
test('UninitializedVariable1', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, this is off.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['uninitializedVariable1.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Enable it as an error.
configOptions.diagnosticRuleSet.reportUninitializedInstanceVariable = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['uninitializedVariable1.py'], configOptions);
TestUtils.validateResults(analysisResults, 3);
});
test('UninitializedVariable2', () => {
const configOptions = new ConfigOptions(Uri.empty());
// By default, this is off.
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['uninitializedVariable2.py'], configOptions);
TestUtils.validateResults(analysisResults, 0);
// Enable it as an error.
configOptions.diagnosticRuleSet.reportUninitializedInstanceVariable = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['uninitializedVariable2.py'], configOptions);
TestUtils.validateResults(analysisResults, 3);
});
test('UninitializedVariable3', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['uninitializedVariable3.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('DeprecatedAlias1', () => {
const configOptions = new ConfigOptions(Uri.empty());
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults2, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_10;
const analysisResults3 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults3, 0, 0, 0, undefined, undefined, 0);
// Now enable the deprecateTypingAliases setting.
configOptions.diagnosticRuleSet.deprecateTypingAliases = true;
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults4 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults4, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults5 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults5, 0, 0, 0, undefined, undefined, 45);
configOptions.defaultPythonVersion = pythonVersion3_10;
const analysisResults6 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults6, 0, 0, 0, undefined, undefined, 49);
// Now change reportDeprecated to emit an error.
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults7 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults7, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults8 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults8, 45, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_10;
const analysisResults9 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias1.py'], configOptions);
TestUtils.validateResults(analysisResults9, 49, 0, 0, undefined, undefined, 0);
});
test('DeprecatedAlias2', () => {
const configOptions = new ConfigOptions(Uri.empty());
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults2, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_10;
const analysisResults3 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults3, 0, 0, 0, undefined, undefined, 0);
// Now enable the deprecateTypingAliases setting.
configOptions.diagnosticRuleSet.deprecateTypingAliases = true;
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults4 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults4, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults5 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults5, 0, 0, 0, undefined, undefined, 42);
configOptions.defaultPythonVersion = pythonVersion3_10;
const analysisResults6 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults6, 0, 0, 0, undefined, undefined, 46);
// Now change reportDeprecated to emit an error.
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
configOptions.defaultPythonVersion = pythonVersion3_8;
const analysisResults7 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults7, 0, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_9;
const analysisResults8 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults8, 42, 0, 0, undefined, undefined, 0);
configOptions.defaultPythonVersion = pythonVersion3_10;
const analysisResults9 = TestUtils.typeAnalyzeSampleFiles(['deprecatedAlias2.py'], configOptions);
TestUtils.validateResults(analysisResults9, 46, 0, 0, undefined, undefined, 0);
});
test('Deprecated2', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated2.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 14);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated2.py'], configOptions);
TestUtils.validateResults(analysisResults2, 14);
});
test('Deprecated3', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated3.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 5);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated3.py'], configOptions);
TestUtils.validateResults(analysisResults2, 5);
});
test('Deprecated4', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated4.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 7);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated4.py'], configOptions);
TestUtils.validateResults(analysisResults2, 7);
});
test('Deprecated5', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated5.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 2);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated5.py'], configOptions);
TestUtils.validateResults(analysisResults2, 2);
});
test('Deprecated6', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated6.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 3);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated6.py'], configOptions);
TestUtils.validateResults(analysisResults2, 3);
});
test('Deprecated7', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated7.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 2);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated7.py'], configOptions);
TestUtils.validateResults(analysisResults2, 2);
});
test('Deprecated8', () => {
const configOptions = new ConfigOptions(Uri.empty());
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated8.py'], configOptions);
TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 4);
configOptions.diagnosticRuleSet.reportDeprecated = 'error';
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated8.py'], configOptions);
TestUtils.validateResults(analysisResults2, 4);
});
@@ -55,7 +55,7 @@ describe(`config test'}`, () => {
const fileList = service.test_getFileNamesFromFileSpecs();
// The config file specifies a subdirectory, so we should find
// only two of the three "*.py" files present in the project
// only two of the three "*.vp" files present in the project
// directory.
assert.strictEqual(fileList.length, 2);
});
@@ -72,10 +72,10 @@ describe(`config test'}`, () => {
// The myVenv directory is detected as a venv and will be automatically excluded
const fileList = service.test_getFileNamesFromFileSpecs();
// There are 3 python files in the workspace, outside of myVenv
// There is 1 python file in myVenv, which should be excluded
// There are 3 Viper files in the workspace, outside of myVenv
// There is 1 Viper file in myVenv, which should be excluded
const fileNames = fileList.map((p) => p.fileName).sort();
assert.deepStrictEqual(fileNames, ['sample1.py', 'sample2.py', 'sample3.py']);
assert.deepStrictEqual(fileNames, ['sample1.vp', 'sample2.vp', 'sample3.vp']);
});
test('FindFilesVirtualEnvAutoDetectInclude', () => {
@@ -89,11 +89,11 @@ describe(`config test'}`, () => {
// Config file defines 'exclude' folder so virtual env will be included
const fileList = service.test_getFileNamesFromFileSpecs();
// There are 3 python files in the workspace, outside of myVenv
// There is 1 more python file in excluded folder
// There is 1 python file in myVenv, which should be included
// There are 3 Viper files in the workspace, outside of myVenv
// There is 1 more Viper file in excluded folder
// There is 1 Viper file in myVenv, which should be included
const fileNames = fileList.map((p) => p.fileName).sort();
assert.deepStrictEqual(fileNames, ['library1.py', 'sample1.py', 'sample2.py', 'sample3.py']);
assert.deepStrictEqual(fileNames, ['library1.vp', 'sample1.vp', 'sample2.vp', 'sample3.vp']);
});
test('FileSpecNotAnArray', () => {
@@ -416,7 +416,7 @@ describe(`config test'}`, () => {
const fileList = service.test_getFileNamesFromFileSpecs();
const fileNames = fileList.map((p) => p.fileName).sort();
assert.deepStrictEqual(fileNames, ['sample.pyi', 'test.py']);
assert.deepStrictEqual(fileNames, ['sample.vpi', 'test.vp']);
const configOptions = service.test_getConfigOptions(commandLineOptions);
assert.equal(configOptions.diagnosticRuleSet.strictListInference, true);
@@ -771,9 +771,9 @@ describe(`config test'}`, () => {
const configWithoutOverride = service.test_getConfigOptions(commandLineOptions);
assert.equal(configWithoutOverride.diagnosticRuleSet.reportPrivateImportUsage, 'none');
// The basic default would be 'error', verify our config overrides it.
// Viper 模式默认关闭 reportPrivateImportUsage(无 PEP 561 / py.typed 私有导入概念)。
const basicDefaults = getBasicDiagnosticRuleSet();
assert.equal(basicDefaults.reportPrivateImportUsage, 'error');
assert.equal(basicDefaults.reportPrivateImportUsage, 'none');
// Now simulate positional args overriding include (like `viper --project config.json subdir`).
const commandLineOptionsWithOverride = new CommandLineOptions(cwd, /* fromLanguageServer */ false);
@@ -68,7 +68,7 @@ describe('Diagnostic overrides', () => {
const json = JSON.parse(jsonString);
expect(json.contributes?.configuration?.properties).toBeDefined();
const overrides = json.contributes?.configuration?.properties['python.analysis.diagnosticSeverityOverrides'];
const overrides = json.contributes?.configuration?.properties['viper.analysis.diagnosticSeverityOverrides'];
expect(overrides).toBeDefined();
const props = overrides.properties;
expect(props).toBeDefined();
@@ -243,7 +243,7 @@ test('Mounted directory traversal is lazy for statSync', () => {
fs.mountSync(sourceRoot, normalizeSlashes('/mnt'), resolver);
// Path traversal to a single child should not force a full directory enumeration.
const stats = fs.statSync(UriEx.file(normalizeSlashes('/mnt/a.pyi')));
const stats = fs.statSync(UriEx.file(normalizeSlashes('/mnt/a.vpi')));
assert(stats.isFile());
assert.equal(calls.readdirSync, 0);
assert.equal(calls.statSync, 1);
@@ -1,36 +0,0 @@
/*
* fourSlashRunner.test.ts
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
*
* Entry point that will read all *.fourslash.ts files and
* register jest tests for them and run
*/
import * as path from 'path';
import { normalizeSlashes } from '../common/pathUtils';
import { runFourSlashTest } from './harness/fourslash/runner';
import * as host from './harness/testHost';
import { MODULE_PATH } from './harness/vfs/filesystem';
describe('fourslash tests', () => {
const testFiles: string[] = [];
const basePath = path.resolve(path.dirname(module.filename), 'fourslash/');
for (const file of host.HOST.listFiles(basePath, /.*\.fourslash\.ts$/i, { recursive: true })) {
testFiles.push(file);
}
testFiles.forEach((file) => {
describe(file, () => {
const fn = normalizeSlashes(file);
const justName = fn.replace(/^.*[\\/]/, '');
// TODO: make these to use promise/async rather than callback token
it('fourslash test ' + justName + ' run', (cb) => {
runFourSlashTest(MODULE_PATH, fn, cb, { enablePartialStub: true });
});
});
});
});
@@ -1,33 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import*/|][|Test/*marker*/|]
// @filename: test2.py
//// import testLib
// @filename: testLib/__init__.pyi
// @library: true
//// class Test:
//// pass
{
const importRange = helper.getPositionRange('import');
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'Test',
kind: Consts.CompletionItemKind.Class,
documentation: '```\nfrom testLib import Test\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'Test' },
additionalTextEdits: [{ range: importRange, newText: 'from testLib import Test\n\n\n' }],
},
],
},
});
}
@@ -1,47 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import*/|][|test/*marker*/|]
// @filename: test2.py
//// import testLib
//// import testLib.test1
//// import testLib.test2
//// a = testLib.test1.Test1()
//// b = testLib.test2.Test2()
// @filename: testLib/__init__.pyi
// @library: true
//// class Test:
//// pass
// @filename: testLib/test1.pyi
// @library: true
//// class Test1:
//// pass
// @filename: testLib/test2.pyi
// @library: true
//// class Test2:
//// pass
{
const importRange = helper.getPositionRange('import');
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'test1',
kind: Consts.CompletionItemKind.Module,
documentation: '```\nfrom testLib import test1\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'test1' },
additionalTextEdits: [{ range: importRange, newText: 'from testLib import test1\n\n\n' }],
},
],
},
});
}
@@ -1,14 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// Test[|/*marker*/|]
// @filename: testLib/__init__.pyi
// @library: true
//// class Test:
//// pass
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker: { completions: [{ label: 'Test', kind: undefined }] },
});
@@ -1,25 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "autoImportCompletions": false
//// }
// @filename: test1.py
//// Test[|/*marker*/|]
// @filename: test2.py
//// class Test:
//// pass
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker: {
completions: [
{
label: 'Test',
kind: Consts.CompletionItemKind.Class,
},
],
},
});
@@ -1,36 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @indexer: true
// @filename: test1.py
//// import math
//// import testLib
//// [|ata/*marker*/|]
// @filename: testLib/__init__.pyi
// @library: true
//// def atan(x: float) -> float: ...
{
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'atan',
kind: Consts.CompletionItemKind.Function,
documentation: '```\nfrom math import atan\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'math.atan' },
},
{
label: 'atan',
kind: Consts.CompletionItemKind.Function,
documentation: '```\nfrom testLib import atan\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'testLib.atan' },
},
],
},
});
}
@@ -1,29 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import*/|][|Test/*marker*/|]
// @filename: test2.py
//// class Test:
//// pass
{
const importRange = helper.getPositionRange('import');
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'Test',
kind: Consts.CompletionItemKind.Class,
documentation: '```\nfrom test2 import Test\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'Test' },
additionalTextEdits: [{ range: importRange, newText: 'from test2 import Test\n\n\n' }],
},
],
},
});
}
@@ -1,130 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from lib import (
//// [|/*import1*/|]MY_CONST_VAR[|/*import2*/|],
//// ClsOther[|/*import3*/|],
//// my_afunc[|/*import4*/|],
//// )
////
//// [|A_CONST/*marker1*/|]
//// [|MY_CONST_VAR2/*marker2*/|]
//// [|Cls/*marker3*/|]
//// [|ClsList/*marker4*/|]
//// [|my_func/*marker5*/|]
//// [|MYA_CONST_VAR/*marker6*/|]
//// [|MY_CONSTA_VAR/*marker7*/|]
// @filename: lib.py
//// A_CONST = 1
//// MY_CONST_VAR = 2
//// MY_CONST_VAR2 = 3
//// MY_CONSTA_VAR = 4
//// MYA_CONST_VAR = 4
//// class Cls: ...
//// class ClsOther: ...
//// ClsOtherList = list[ClsOther]
//// def my_afunc(): ...
//// def my_func(): ...
{
const import1Range = helper.getPositionRange('import1');
const import2Range = helper.getPositionRange('import2');
const import3Range = helper.getPositionRange('import3');
const import4Range = helper.getPositionRange('import4');
const marker1Range = helper.getPositionRange('marker1');
const marker2Range = helper.getPositionRange('marker2');
const marker3Range = helper.getPositionRange('marker3');
const marker4Range = helper.getPositionRange('marker4');
const marker5Range = helper.getPositionRange('marker5');
const marker6Range = helper.getPositionRange('marker6');
const marker7Range = helper.getPositionRange('marker7');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'A_CONST',
kind: Consts.CompletionItemKind.Constant,
documentation: '```\nfrom lib import A_CONST\n```',
detail: 'Auto-import',
textEdit: { range: marker1Range, newText: 'A_CONST' },
additionalTextEdits: [{ range: import1Range, newText: 'A_CONST,\n ' }],
},
],
},
marker2: {
completions: [
{
label: 'MY_CONST_VAR2',
kind: Consts.CompletionItemKind.Constant,
documentation: '```\nfrom lib import MY_CONST_VAR2\n```',
detail: 'Auto-import',
textEdit: { range: marker2Range, newText: 'MY_CONST_VAR2' },
additionalTextEdits: [{ range: import2Range, newText: ',\n MY_CONST_VAR2' }],
},
],
},
marker3: {
completions: [
{
label: 'Cls',
kind: Consts.CompletionItemKind.Class,
documentation: '```\nfrom lib import Cls\n```',
detail: 'Auto-import',
textEdit: { range: marker3Range, newText: 'Cls' },
additionalTextEdits: [{ range: import2Range, newText: ',\n Cls' }],
},
],
},
marker4: {
completions: [
{
label: 'ClsOtherList',
kind: Consts.CompletionItemKind.Variable,
documentation: '```\nfrom lib import ClsOtherList\n```',
detail: 'Auto-import',
textEdit: { range: marker4Range, newText: 'ClsOtherList' },
additionalTextEdits: [{ range: import3Range, newText: ',\n ClsOtherList' }],
},
],
},
marker5: {
completions: [
{
label: 'my_func',
kind: Consts.CompletionItemKind.Function,
documentation: '```\nfrom lib import my_func\n```',
detail: 'Auto-import',
textEdit: { range: marker5Range, newText: 'my_func' },
additionalTextEdits: [{ range: import4Range, newText: ',\n my_func' }],
},
],
},
marker6: {
completions: [
{
label: 'MYA_CONST_VAR',
kind: Consts.CompletionItemKind.Constant,
documentation: '```\nfrom lib import MYA_CONST_VAR\n```',
detail: 'Auto-import',
textEdit: { range: marker6Range, newText: 'MYA_CONST_VAR' },
additionalTextEdits: [{ range: import2Range, newText: ',\n MYA_CONST_VAR' }],
},
],
},
marker7: {
completions: [
{
label: 'MY_CONSTA_VAR',
kind: Consts.CompletionItemKind.Constant,
documentation: '```\nfrom lib import MY_CONSTA_VAR\n```',
detail: 'Auto-import',
textEdit: { range: marker7Range, newText: 'MY_CONSTA_VAR' },
additionalTextEdits: [{ range: import2Range, newText: ',\n MY_CONSTA_VAR' }],
},
],
},
});
}
@@ -1,61 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import*/|][|job/*marker*/|]
// @filename: test2.py
//// import dagster
// @filename: dagster/py.typed
// @library: true
//// partial
// @filename: dagster/__init__.py
// @library: true
//// from dagster.core.definitions import (
//// job
//// )
////
//// __all__ = [
//// "job"
//// ]
// @filename: dagster/core/__init__.py
// @library: true
//// from builtins import *
// @filename: dagster/core/definitions/__init__.py
// @library: true
//// from .decorators import (
//// job
//// )
// @filename: dagster/core/definitions/decorators/__init__.py
// @library: true
//// from .job_decorator import job
// @filename: dagster/core/definitions/decorators/job_decorator.py
// @library: true
//// def job():
//// ...
{
const importRange = helper.getPositionRange('import');
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'job',
kind: Consts.CompletionItemKind.Function,
documentation: '```\nfrom dagster import job\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'job' },
additionalTextEdits: [{ range: importRange, newText: 'from dagster import job\n\n\n' }],
},
],
},
});
}
@@ -1,29 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import*/|][|Test/*marker*/|]
// @filename: test2.py
//// class Test:
//// pass
{
const importRange = helper.getPositionRange('import');
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('included', 'plaintext', {
marker: {
completions: [
{
label: 'Test',
kind: Consts.CompletionItemKind.Class,
documentation: 'from test2 import Test',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'Test' },
additionalTextEdits: [{ range: importRange, newText: 'from test2 import Test\n\n\n' }],
},
],
},
});
}
@@ -1,48 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import*/|][|MyShadow/*marker*/|]
// @filename: test2.py
//// import testLib
//// a = testLib.MyShadow()
//// a.[|/*hover*/method|]()
// @filename: testLib/__init__.pyi
// @library: true
//// class MyShadow:
//// def method(self): ...
// @filename: testLib/__init__.py
// @library: true
//// class MyShadow:
//// def method(self):
//// 'doc string'
//// pass
{
// This will cause shadow file to be injected.
helper.openFile(helper.getMarkerByName('hover').fileName);
helper.verifyHover('markdown', {
hover: '```python\n(method) def method() -> Unknown\n```\n---\ndoc string',
});
const importRange = helper.getPositionRange('import');
const markerRange = helper.getPositionRange('marker');
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker: {
completions: [
{
label: 'MyShadow',
kind: Consts.CompletionItemKind.Class,
documentation: '```\nfrom testLib import MyShadow\n```',
detail: 'Auto-import',
textEdit: { range: markerRange, newText: 'MyShadow' },
additionalTextEdits: [{ range: importRange, newText: 'from testLib import MyShadow\n\n\n' }],
},
],
},
});
}
@@ -1,31 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import1*/|]from os.path import dirname
//// [|path/*marker1*/|]
// @filename: test2.py
//// import os
//// a = os.path
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'path',
kind: Consts.CompletionItemKind.Variable,
documentation: '```\nfrom os import path\n```',
detail: 'Auto-import',
textEdit: { range: helper.getPositionRange('marker1'), newText: 'path' },
additionalTextEdits: [
{ range: helper.getPositionRange('import1'), newText: 'from os import path\n' },
],
},
],
},
});
}
@@ -1,57 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// [|/*import1*/|][|os/*marker1*/|]
// @filename: test2.py
//// [|/*import2*/|][|sys/*marker2*/|]
// @filename: test3.py
//// import os
//// import sys
//// a = os.path
//// b = sys.path
{
helper.openFile('/test1.py');
const import1Range = helper.getPositionRange('import1');
const marker1Range = helper.getPositionRange('marker1');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'os',
kind: Consts.CompletionItemKind.Module,
documentation: '```\nimport os\n```',
detail: 'Auto-import',
textEdit: { range: marker1Range, newText: 'os' },
additionalTextEdits: [{ range: import1Range, newText: 'import os\n\n\n' }],
},
],
},
});
helper.openFile('/test2.py');
const import2Range = helper.getPositionRange('import2');
const marker2Range = helper.getPositionRange('marker2');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker2: {
completions: [
{
label: 'sys',
kind: Consts.CompletionItemKind.Module,
documentation: '```\nimport sys\n```',
detail: 'Auto-import',
textEdit: { range: marker2Range, newText: 'sys' },
additionalTextEdits: [{ range: import2Range, newText: 'import sys\n\n\n' }],
},
],
},
});
}
@@ -1,30 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: consume.py
//// [|/*import1*/|][|Ät/*marker1*/|]
// @filename: declare.py
//// class Äther: ...
//// class Ether: ...
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'Äther',
kind: Consts.CompletionItemKind.Class,
documentation: '```\nfrom declare import Äther\n```',
detail: 'Auto-import',
textEdit: { range: helper.getPositionRange('marker1'), newText: 'Äther' },
additionalTextEdits: [
{ range: helper.getPositionRange('import1'), newText: 'from declare import Äther\n\n\n' },
],
},
],
},
});
}
@@ -1,117 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: docstrings.py
//// class A: ...
////
//// class B:
//// """This is the class doc for B."""
//// def __init__(self):
//// """This is the __init__ doc for B."""
////
//// class C:
//// """This is the class doc for C."""
//// def __init__(self):
//// pass
////
//// class D:
//// def __init__(self):
//// """This is the __init__ doc for D."""
//// pass
////
//// [|/*global*/|]
//// object().[|/*object*/|]
//// A().[|/*a*/|]
//// B().[|/*b*/|]
//// C().[|/*c*/|]
//// D().[|/*d*/|]
// @filename: typeshed-fallback/stdlib/builtins.py
//// class object():
//// """This is the class doc for object."""
//// def __init__(self):
//// """This is the __init__ doc for object."""
//// pass
////
//// def __dir__(self):
//// """This is the __dir__ doc for object."""
//// pass
{
// @ts-ignore
await helper.verifyCompletion('included', 'plaintext', {
global: {
completions: [
{
label: 'object',
kind: Consts.CompletionItemKind.Class,
documentation: 'class object()\n\nThis is the class doc for object.',
},
{
label: 'A',
kind: Consts.CompletionItemKind.Class,
documentation: 'class A()',
},
{
label: 'B',
kind: Consts.CompletionItemKind.Class,
documentation: 'class B()\n\nThis is the class doc for B.',
},
{
label: 'C',
kind: Consts.CompletionItemKind.Class,
documentation: 'class C()\n\nThis is the class doc for C.',
},
{
label: 'D',
kind: Consts.CompletionItemKind.Class,
documentation: 'class D()',
},
],
},
object: {
completions: [
{
label: '__init__',
kind: Consts.CompletionItemKind.Method,
documentation: 'def __init__() -> None\n\nThis is the __init__ doc for object.',
},
],
},
a: {
completions: [
{
label: '__init__',
kind: Consts.CompletionItemKind.Method,
documentation: 'def __init__() -> None',
},
],
},
b: {
completions: [
{
label: '__init__',
kind: Consts.CompletionItemKind.Method,
documentation: 'def __init__() -> None\n\nThis is the __init__ doc for B.',
},
],
},
c: {
completions: [
{
label: '__init__',
kind: Consts.CompletionItemKind.Method,
documentation: 'def __init__() -> None',
},
],
},
d: {
completions: [
{
label: '__init__',
kind: Consts.CompletionItemKind.Method,
documentation: 'def __init__() -> None\n\nThis is the __init__ doc for D.',
},
],
},
});
}
@@ -1,22 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// Cust[|/*marker1*/|]
//// my_v[|/*marker2*/|]
// @filename: __builtins__.pyi
//// class CustomClass: ...
//// my_var: int = ...
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: 'CustomClass',
kind: Consts.CompletionItemKind.Class,
},
],
},
marker2: { completions: [{ label: 'my_var', kind: Consts.CompletionItemKind.Variable }] },
});
@@ -1,55 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import Literal
////
//// def thing(foo: Literal["hello", "world"]):
//// pass
////
//// thing([|/*marker1*/|])
//// thing(hel[|/*marker2*/|])
//// thing([|"/*marker3*/"|])
{
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: '"hello"',
kind: Consts.CompletionItemKind.Constant,
},
{
label: '"world"',
kind: Consts.CompletionItemKind.Constant,
},
],
},
marker2: {
completions: [
{
label: '"hello"',
kind: Consts.CompletionItemKind.Constant,
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker3: {
completions: [
{
label: '"hello"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"hello"' },
},
{
label: '"world"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"world"' },
},
],
},
});
}
@@ -1,247 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import TypedDict, Optional, Union, List, Dict, Any
////
//// class Movie(TypedDict):
//// name: str
//// age: int
////
//// def thing(movie: Movie):
//// pass
////
//// thing({'[|/*marker1*/|]'})
//// thing({'name': '[|/*marker2*/|]'})
//// thing({'name': 'Robert','[|/*marker3*/|]'})
//// thing({'name': 'Robert', '[|/*marker4*/|]'})
//// thing('[|/*marker5*/|]')
//// thing({'na[|/*marker6*/|]'})
//// thing({[|/*marker7*/|]})
//// thing({'a', '[|/*marker8*/|]'})
////
//// class Episode(TypedDict):
//// title: str
//// score: int
////
//// def thing2(item: Union[Episode, Movie]):
//// pass
////
//// thing2({'[|/*marker9*/|]'})
//// thing2({'unknown': 'a', '[|/*marker10*/|]': ''})
//// thing2({'title': 'Episode 01', '[|/*marker11*/|]': ''})
////
//// class Wrapper(TypedDict):
//// age: int
//// wrapped: Union[bool, Movie]
//// data: Dict[str, Any]
////
//// def thing3(wrapper: Optional[Wrapper]):
//// pass
////
//// thing3({'data': {'[|/*marker12*/|]'}})
//// thing3({'wrapped': {'[|/*marker13*/|]'}})
//// thing3({'age': 1, 'wrapped': {'[|/*marker14*/|]'}})
//// thing3({'unknown': {'[|/*marker15*/|]'}})
//// thing3({'age': {'[|/*marker16*/|]'}})
//// thing3({'wrapped': {'name': 'ET', '[|/*marker17*/|]'}})
{
const marker1Range = helper.expandPositionRange(helper.getPositionRange('marker1'), 1, 1);
const marker3Range = helper.expandPositionRange(helper.getPositionRange('marker3'), 1, 1);
const marker4Range = helper.expandPositionRange(helper.getPositionRange('marker4'), 1, 1);
const marker6Range = helper.expandPositionRange(helper.getPositionRange('marker6'), 3, 1);
const marker7Range = helper.getPositionRange('marker7');
const marker8Range = helper.expandPositionRange(helper.getPositionRange('marker8'), 1, 1);
const marker9Range = helper.expandPositionRange(helper.getPositionRange('marker9'), 1, 1);
const marker10Range = helper.expandPositionRange(helper.getPositionRange('marker10'), 1, 1);
const marker11Range = helper.expandPositionRange(helper.getPositionRange('marker11'), 1, 1);
const marker13Range = helper.expandPositionRange(helper.getPositionRange('marker13'), 1, 1);
const marker14Range = helper.expandPositionRange(helper.getPositionRange('marker14'), 1, 1);
const marker17Range = helper.expandPositionRange(helper.getPositionRange('marker17'), 1, 1);
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker1Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker1Range, newText: "'age'" },
},
],
},
marker2: {
completions: [],
},
marker3: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker3Range, newText: "'age'" },
},
],
},
marker4: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker4Range, newText: "'age'" },
},
],
},
marker5: {
completions: [],
},
marker6: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker6Range, newText: "'name'" },
},
],
},
marker8: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker8Range, newText: "'age'" },
},
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker8Range, newText: "'name'" },
},
],
},
marker9: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker9Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker9Range, newText: "'age'" },
},
{
label: "'title'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker9Range, newText: "'title'" },
},
{
label: "'score'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker9Range, newText: "'score'" },
},
],
},
marker10: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker10Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker10Range, newText: "'age'" },
},
{
label: "'title'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker10Range, newText: "'title'" },
},
{
label: "'score'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker10Range, newText: "'score'" },
},
],
},
marker11: {
completions: [
{
label: "'score'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker11Range, newText: "'score'" },
},
],
},
marker12: {
completions: [],
},
marker13: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker13Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker13Range, newText: "'age'" },
},
],
},
marker14: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker14Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker14Range, newText: "'age'" },
},
],
},
marker15: {
completions: [],
},
marker16: {
completions: [],
},
marker17: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker17Range, newText: "'age'" },
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker7: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker7Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker7Range, newText: "'age'" },
},
],
},
});
}
@@ -1,163 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import TypedDict, Union, List
////
//// class Movie(TypedDict):
//// name: str
//// age: int
////
//// class MultipleInputs(TypedDict):
//// items: List[Movie]
//// union: Union[bool, List[Movie]]
//// unions: Union[Movie, Union[bool, List[Movie]]]
////
//// def thing(inputs: MultipleInputs):
//// pass
////
//// thing({'items': ['[|/*marker1*/|]']})
//// thing({'items': {'[|/*marker2*/|]'}})
//// thing({'items': [{'[|/*marker3*/|]'}]})
//// thing({'union': [{'[|/*marker4*/|]'}]})
//// thing({'unions': {'[|/*marker5*/|]'}})
//// thing({'unions': [{'[|/*marker6*/|]'}]})
////
//// def thing2(movies: List[Movie]):
//// pass
////
//// thing2([{'[|/*marker7*/|]'}])
//// thing2({'[|/*marker8*/|]'})
////
//// class Wrapper(TypedDict):
//// wrapped: MultipleInputs
////
//// def thing3(wrapper: Wrapper):
//// pass
////
//// thing3({'wrapped': {'items': [{'[|/*marker9*/|]'}]}})
//// thing3({'wrapped': {'items': {'[|/*marker10*/|]'}}})
//// thing3({'wrapped': {'items': [{'a': 'b'}, {'[|/*marker11*/|]'}]}})
{
const marker3Range = helper.expandPositionRange(helper.getPositionRange('marker3'), 1, 1);
const marker4Range = helper.expandPositionRange(helper.getPositionRange('marker4'), 1, 1);
const marker5Range = helper.expandPositionRange(helper.getPositionRange('marker5'), 1, 1);
const marker6Range = helper.expandPositionRange(helper.getPositionRange('marker6'), 1, 1);
const marker7Range = helper.expandPositionRange(helper.getPositionRange('marker7'), 1, 1);
const marker9Range = helper.expandPositionRange(helper.getPositionRange('marker9'), 1, 1);
const marker11Range = helper.expandPositionRange(helper.getPositionRange('marker11'), 1, 1);
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [],
},
marker2: {
completions: [],
},
marker3: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker3Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker3Range, newText: "'age'" },
},
],
},
marker4: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker4Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker4Range, newText: "'age'" },
},
],
},
marker5: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker5Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker5Range, newText: "'age'" },
},
],
},
marker6: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker6Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker6Range, newText: "'age'" },
},
],
},
marker7: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker7Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker7Range, newText: "'age'" },
},
],
},
marker8: {
completions: [],
},
marker9: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker9Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker9Range, newText: "'age'" },
},
],
},
marker10: {
completions: [],
},
marker11: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker11Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker11Range, newText: "'age'" },
},
],
},
});
}
@@ -1,135 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import TypedDict
////
//// class Movie(TypedDict):
//// name: str
//// age: int
////
//// def thing(movie: Movie):
//// pass
////
//// thing(movie={'foo': 'a', '[|/*marker1*/|]'})
//// thing(movie={'foo': 'a', 'a[|/*marker2*/|]'})
//// thing(
//// movie={
//// 'name': 'Parasite',
//// '[|/*marker3*/|]
//// }
//// )
//// thing(
//// movie={
//// 'name': 'Parasite',
//// '[|/*marker4*/|]'
//// }
//// )
//// thing({
//// 'name': 'Parasite',
//// # hello world
//// '[|/*marker5*/|]'
//// })
//// thing({'foo': '[|/*marker6*/|]'})
{
// completions that rely on token parsing instead of node parsing
const marker1Range = helper.expandPositionRange(helper.getPositionRange('marker1'), 1, 1);
const marker2Range = helper.expandPositionRange(helper.getPositionRange('marker2'), 2, 1);
const marker3Range = helper.expandPositionRange(helper.getPositionRange('marker3'), 1, 0);
const marker4Range = helper.expandPositionRange(helper.getPositionRange('marker4'), 1, 1);
const marker5Range = helper.expandPositionRange(helper.getPositionRange('marker5'), 1, 1);
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker1Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker1Range, newText: "'age'" },
},
],
},
marker2: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker2Range, newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker2Range, newText: "'age'" },
},
],
},
marker6: {
completions: [],
},
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker3: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker3Range, newText: "'age'" },
},
],
},
marker4: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker4Range, newText: "'age'" },
},
],
},
marker5: {
completions: [
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker5Range, newText: "'age'" },
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker3: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
},
],
},
marker4: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
},
],
},
marker5: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
},
],
},
});
}
@@ -1,35 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// Unpacked parameterized TypedDict as a variadic keyword parameter.
// expandTypedKwargs() (consumed by both signature help and completion literal-value suggestions)
// must substitute the TypedDict type argument. Before the fix, the `t` entry kept the unspecialized
// TypeVar `T@TD`, so no literal-value completions were offered; after the fix the entry is
// `Literal['a', 'b']`, so the literal values are offered at the call site.
// @filename: test.py
//// from typing import Generic, Literal, TypedDict, TypeVar, Unpack
////
//// T = TypeVar('T')
////
//// class TD(TypedDict, Generic[T]):
//// t: T
////
//// def func(**kwargs: Unpack[TD[Literal['a', 'b']]]) -> None: ...
////
//// func(t=[|/*marker*/|])
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: "'a'",
kind: Consts.CompletionItemKind.Constant,
},
{
label: "'b'",
kind: Consts.CompletionItemKind.Constant,
},
],
},
});
@@ -1,135 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "pythonVersion": "3.11"
//// }
// @filename: test.py
//// class MyType: pass
////
//// class B:
//// var1 = 1
//// var2: MyType
//// var3: list[str] = ["hello"]
//// __var4 = 4
////
//// def __init__(self):
//// self.var6 = 1
////
//// class T(B):
//// var5: bool
//// [|va/*marker1*/|]
////
//// class T1(B):
//// var2: [|/*marker2*/|]
////
//// class T2(B):
//// var3: [|/*marker3*/|]
// @filename: test2.py
//// from typing import Generic, Sequence, TypeVar
////
////
//// T = TypeVar("T")
////
//// class A(Generic[T]):
//// var: Sequence[T]
////
//// class B(A[int]):
//// var: [|/*marker4*/|]
////
//// T2 = TypeVar("T2")
////
//// class C(A[T2]):
//// var: [|/*marker5*/|]
// @filename: test3.py
//// from typing import Generic, TypeVarTuple
////
//// T = TypeVarTuple('T')
////
//// class MyType(Generic[*T]):
//// pass
////
//// class A(Generic[*T]):
//// var: MyType[*T]
////
//// class B(A[int, str, float]):
//// var: [|/*marker6*/|]
////
//// T2 = TypeVarTuple('T2')
////
//// class C(A[int, *T2]):
//// var: [|/*marker7*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'var1',
kind: Consts.CompletionItemKind.Variable,
},
{
label: 'var2',
kind: Consts.CompletionItemKind.Variable,
},
{
label: 'var3',
kind: Consts.CompletionItemKind.Variable,
},
],
},
marker2: {
completions: [
{
label: 'MyType',
kind: Consts.CompletionItemKind.Reference,
},
],
},
marker3: {
completions: [
{
label: 'list[str]',
kind: Consts.CompletionItemKind.Reference,
},
],
},
marker4: {
completions: [
{
label: 'Sequence[int]',
kind: Consts.CompletionItemKind.Reference,
},
],
},
marker5: {
completions: [
{
label: 'Sequence[T2]',
kind: Consts.CompletionItemKind.Reference,
},
],
},
marker6: {
completions: [
{
label: 'MyType[int, str, float]',
kind: Consts.CompletionItemKind.Reference,
},
],
},
marker7: {
completions: [
{
label: 'MyType[int, *T2]',
kind: Consts.CompletionItemKind.Reference,
},
],
},
});
}
@@ -1,28 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// msg = 'hello'
//// [|/*marker1*/|]
//// # msg.[|/*marker2*/|]
//// [|/*marker3*/|]
//// print('upper: ' + msg.up[|/*marker4*/|]per())
//// print('#upper: ' + msg.up[|/*marker5*/|]per())
////
//// # msg.[|/*marker6*/|]
//// [|/*marker7*/|]
////
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker2: { completions: [] },
marker6: { completions: [] },
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: { completions: [{ label: 'msg', kind: Consts.CompletionItemKind.Variable }] },
marker3: { completions: [{ label: 'msg', kind: Consts.CompletionItemKind.Variable }] },
marker4: { completions: [{ label: 'upper', kind: Consts.CompletionItemKind.Method }] },
marker5: { completions: [{ label: 'upper', kind: Consts.CompletionItemKind.Method }] },
marker7: { completions: [{ label: 'msg', kind: Consts.CompletionItemKind.Variable }] },
});
@@ -1,35 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class [|/*marker1*/|]
////
// @filename: test1.py
//// class c[|/*marker2*/|]
////
// @filename: test2.py
//// class c1[|/*marker3*/|]():
//// pass
////
// @filename: test3.py
//// class c1([|/*marker4*/|]):
//// pass
////
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
marker3: { completions: [] },
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker4: { completions: [{ label: 'Exception', kind: Consts.CompletionItemKind.Class }] },
});
}
@@ -1,18 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// try:
//// pass
//// except ZeroDivisionError as d[|/*marker1*/|]:
//// pass
////
//// try:
//// pass
//// except ZeroDivisionError as [|/*marker2*/|]:
//// pass
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
});
@@ -1,30 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// for [|/*marker1*/|]
////
// @filename: test2.py
//// for c[|/*marker2*/|]
////
// @filename: test3.py
//// for c1[|/*marker3*/|] in [1, 2]:
//// pass
////
// @filename: test4.py
//// [c for c[|/*marker4*/|] in [1, 2]]
////
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [{ label: 'in', kind: Consts.CompletionItemKind.Keyword }] },
marker2: { completions: [] },
marker3: { completions: [] },
marker4: { completions: [] },
});
}
@@ -1,15 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import os as o[|/*marker1*/|]
//// import os as [|/*marker2*/|]
//// from os import path as p[|/*marker3*/|]
//// from os import path as [|/*marker4*/|]
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
marker3: { completions: [] },
marker4: { completions: [] },
});
@@ -1,45 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// lambda [|/*marker1*/|]
// @filename: test1.py
//// lambda x[|/*marker2*/|]
// @filename: test2.py
//// lambda x[|/*marker3*/|]:
// @filename: test3.py
//// lambda x, [|/*marker4*/|]
// @filename: test4.py
//// lambda x, [|/*marker5*/|]:
// @filename: test5.py
//// lambda x, y[|/*marker6*/|]
// @filename: test6.py
//// lambda x, y[|/*marker7*/|]:
// @filename: test7.py
//// lambda x: [|/*marker8*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
marker3: { completions: [] },
marker4: { completions: [] },
marker5: { completions: [] },
marker6: { completions: [] },
marker7: { completions: [] },
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker8: { completions: [{ label: 'str', kind: Consts.CompletionItemKind.Class }] },
});
}
@@ -1,71 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// def [|/*marker1*/|]
////
//// def d[|/*marker2*/|]
////
//// def d1[|/*marker3*/|]():
//// pass
////
//// async def [|/*marker4*/|]
////
//// async def a[|/*marker5*/|]
////
//// async def a1[|/*marker6*/|]():
//// pass
////
//// def method(x[|/*marker7*/|]):
//// pass
//// def method(x:[|/*marker8*/|]):
//// pass
////
//// def method(x, x2[|/*marker9*/|]):
//// pass
//// def method(x, x2:[|/*marker10*/|]):
//// pass
// @filename: test1.py
//// class A:
//// def a1[|/*marker11*/|]
////
//// def a2[|/*marker12*/|]():
//// pass
////
//// def method(x[|/*marker13*/|]):
//// pass
//// def method(x:[|/*marker14*/|]):
//// pass
////
//// def method(x, x2[|/*marker15*/|]):
//// pass
//// def method(x, x2:[|/*marker16*/|]):
//// pass
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
marker3: { completions: [] },
marker4: { completions: [] },
marker5: { completions: [] },
marker6: { completions: [] },
marker7: { completions: [] },
marker9: { completions: [] },
marker11: { completions: [] },
marker12: { completions: [] },
marker13: { completions: [] },
marker15: { completions: [] },
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker8: { completions: [{ label: 'str', kind: Consts.CompletionItemKind.Class }] },
marker10: { completions: [{ label: 'str', kind: Consts.CompletionItemKind.Class }] },
marker14: { completions: [{ label: 'str', kind: Consts.CompletionItemKind.Class }] },
marker16: { completions: [{ label: 'str', kind: Consts.CompletionItemKind.Class }] },
});
}
@@ -1,156 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// from typing import overload
////
//// class A:
//// @overload
//// def [|met/*marker1*/|]
// @filename: test2.py
//// from typing import overload
////
//// class A:
//// @overload
//// def [|met/*marker2*/|]()
// @filename: test3.py
//// from typing import overload
////
//// class A:
//// @overload
//// def [|met/*marker3*/|]():
//// pass
// @filename: test4.py
//// from typing import overload
////
//// class A:
//// @overload
//// def method(self):
//// pass
//// @overload
//// def [|met/*marker4*/|]
// @filename: test5.py
//// from typing import overload
////
//// class A:
//// @overload
//// def method(self):
//// pass
//// @overload
//// def method2(self):
//// pass
//// @overload
//// def [|met/*marker5*/|]
// @filename: test6.py
//// from typing import overload
////
//// class A:
//// @overload
//// def method(self):
//// pass
//// @overload
//// def method2(self):
//// pass
//// @overload
//// def [|diff/*marker6*/|]
// @filename: test7.py
//// from typing import overload
////
//// class A:
//// @overload
//// def method(self):
//// pass
//// @overload
//// def method2(self):
//// pass
////
//// class B(A):
//// @overload
//// def method3(self):
//// pass
//// @overload
//// def [|met/*marker7*/|]
// @filename: test8.py
//// from typing import overload
////
//// class A:
//// @overload
//// def method(self):
//// pass
//// @overload
//// def [|method/*marker8*/|](self, a):
//// pass
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
const marker4Range = helper.getPositionRange('marker4');
const marker5Range = helper.getPositionRange('marker5');
const marker7Range = helper.getPositionRange('marker7');
const marker8Range = helper.getPositionRange('marker8');
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
marker3: { completions: [] },
marker4: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker4Range, newText: 'method' },
},
],
},
marker5: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker5Range, newText: 'method' },
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker5Range, newText: 'method2' },
},
],
},
marker6: { completions: [] },
marker7: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker7Range, newText: 'method' },
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker7Range, newText: 'method2' },
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker7Range, newText: 'method3' },
},
],
},
marker8: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Method,
textEdit: { range: marker8Range, newText: 'method' },
},
],
},
});
}
@@ -1,141 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// from typing import overload
////
//// @overload
//// def [|met/*marker1*/|]
// @filename: test2.py
//// from typing import overload
////
//// @overload
//// def [|met/*marker2*/|]()
// @filename: test3.py
//// from typing import overload
////
//// @overload
//// def [|met/*marker3*/|]():
//// pass
// @filename: test4.py
//// from typing import overload
////
//// @overload
//// def method(self):
//// pass
//// @overload
//// def [|met/*marker4*/|]
// @filename: test5.py
//// from typing import overload
////
//// @overload
//// def method(self):
//// pass
//// @overload
//// def method2(self):
//// pass
//// @overload
//// def [|met/*marker5*/|]
// @filename: test6.py
//// from typing import overload
////
//// @overload
//// def method(self):
//// pass
//// @overload
//// def method2(self):
//// pass
//// @overload
//// def [|diff/*marker6*/|]
// @filename: test7.py
//// from typing import overload
////
//// @overload
//// def method(self):
//// pass
//// @overload
//// def method2(self):
//// pass
// @filename: test7-1.py
//// from typing import overload
//// from test7 import method, method2
////
//// @overload
//// def method3(self):
//// pass
//// @overload
//// def [|met/*marker7*/|]
// @filename: test8.py
//// from typing import overload
////
//// @overload
//// def method(self):
//// pass
//// @overload
//// def [|method/*marker8*/|](self, a):
//// pass
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
const marker4Range = helper.getPositionRange('marker4');
const marker5Range = helper.getPositionRange('marker5');
const marker7Range = helper.getPositionRange('marker7');
const marker8Range = helper.getPositionRange('marker8');
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: { completions: [] },
marker3: { completions: [] },
marker4: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Function,
textEdit: { range: marker4Range, newText: 'method' },
},
],
},
marker5: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Function,
textEdit: { range: marker5Range, newText: 'method' },
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Function,
textEdit: { range: marker5Range, newText: 'method2' },
},
],
},
marker6: { completions: [] },
marker7: {
completions: [
{
label: 'method3',
kind: Consts.CompletionItemKind.Function,
textEdit: { range: marker7Range, newText: 'method3' },
},
],
},
marker8: {
completions: [
{
label: 'method',
kind: Consts.CompletionItemKind.Function,
textEdit: { range: marker8Range, newText: 'method' },
},
],
},
});
}
@@ -1,76 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: dict_key_complex.py
//// d = { "key" : 1 }
////
//// if (len(d) > 0):
//// d["ifKey"] = 2
////
//// def foo():
//// d["capturedKey"] = 3
////
//// class C:
//// def method(self):
//// d["capturedInsideOfMethod"] = 4
////
//// d = dict(reassignedKey=5)
////
//// d[[|/*marker1*/|]]
// @filename: dict_expression_symbol.py
//// keyString = "key"
//// d = { keyString : 1 }
//// d[k/*marker2*/]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"ifKey"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"ifKey"' },
detail: Consts.IndexValueDetail,
},
{
label: '"capturedKey"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"capturedKey"' },
detail: Consts.IndexValueDetail,
},
{
label: '"capturedInsideOfMethod"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"capturedInsideOfMethod"' },
detail: Consts.IndexValueDetail,
},
{
label: '"reassignedKey"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"reassignedKey"' },
detail: Consts.IndexValueDetail,
},
],
},
marker2: {
completions: [{ label: 'keyString', kind: Consts.CompletionItemKind.Variable }],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker2: {
// Regular symbol should over take dict key.
completions: [{ label: 'keyString', kind: Consts.CompletionItemKind.Constant }],
},
});
}
@@ -1,75 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: dict_expression_number.py
//// d = { 1: 1 }
//// d[2] = 1
//// d[/*marker1*/]
// @filename: dict_expression_tuple.py
//// d = { (1, 2): 1 }
//// d[(2, 3)] = 1
//// d[/*marker2*/]
// @filename: dict_expression_key_expression.py
//// d = { 1 + 2: 1 }
//// d[2 + 3] = 1
//// d[/*marker3*/]
// @filename: dict_expression_partial_expression.py
//// d = { "key" : 1 }
//// d["key2"] = 1
//// d[[|key/*marker4*/|]]
// @filename: dict_expression_complex_key.py
//// class C:
//// key = "name"
////
//// d = { C.key : 1 }
//// d[key/*marker5*/]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{ label: '1', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
{ label: '2', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
],
},
marker2: {
completions: [
{ label: '(1, 2)', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
{ label: '(2, 3)', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
],
},
marker3: {
completions: [
{ label: '1 + 2', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
{ label: '2 + 3', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
],
},
marker4: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
],
},
marker5: {
completions: [
{ label: 'C.key', kind: Consts.CompletionItemKind.Constant, detail: Consts.IndexValueDetail },
],
},
});
}
@@ -1,161 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: literal_types.py
//// from typing import Mapping, Literal
////
//// d: Mapping[Literal["key", "key2"], int] = { "key" : 1 }
//// d[[|/*marker1*/|]]
// @filename: parameter_mapping.py
//// from typing import Mapping, Literal
////
//// def foo(d: Mapping[Literal["key", "key2"], int]):
//// d[[|/*marker2*/|]]
// @filename: literal_types_mixed.py
//// from typing import Mapping, Literal
////
//// d: Mapping[Literal["key", 1], int] = { "key" : 1 }
//// d[[|/*marker3*/|]]
// @filename: parameter_dict.py
//// from typing import Dict, Literal
////
//// def foo(d: Dict[Literal["key", "key2"], int]):
//// d[[|/*marker4*/|]]
// @filename: literal_types_boolean.py
//// from typing import Dict, Literal
////
//// d: Dict[Literal[True, False], int] = { True: 1, False: 2 }
//// d[[|/*marker5*/|]]
// @filename: literal_types_enum.py
//// from typing import Dict, Literal
//// from enum import Enum
////
//// class MyEnum(Enum):
//// red = 1
//// blue = 2
////
//// def foo(d: Dict[Literal[MyEnum.red, MyEum.blue], int]):
//// d[[|/*marker6/|]]
// @filename: literal_bytes.py
//// from typing import Mapping, Literal
////
//// d: Mapping[Literal[b"key", b"key2"], int] = { b"key" : 1 }
//// d[[|/*marker7*/|]]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
],
},
marker2: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
],
},
marker3: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '1',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
],
},
marker4: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
],
},
marker5: {
completions: [
{
label: 'True',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
{
label: 'False',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
],
},
marker6: {
completions: [
{
label: 'MyEnum.red',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
{
label: 'MyEnum.blue',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
],
},
marker7: {
completions: [
{
label: 'b"key"',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
{
label: 'b"key2"',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
],
},
});
}
@@ -1,151 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: simple_dict_expression.py
//// d = { "key" : 1 }
//// d[[|/*marker1*/|]]
// @filename: simple_dict_constructor.py
//// d = dict(key=1)
//// d[[|/*marker2*/|]]
// @filename: dict_expression_index.py
//// d = {}
//// d["key"] = 1
//// d[[|/*marker3*/|]]
// @filename: dict_constructor_index.py
//// d = dict()
//// d["key"] = 1
//// d[[|/*marker4*/|]]
// @filename: dict_expression_multiple_keys.py
//// d = { "key": 1, "key2": 2 }
//// d["key3"] = 3
//// d[[|/*marker5*/|]]
// @filename: dict_constructor_multiple_keys.py
//// d = dict(key=1, key2=2)
//// d["key3"] = 3
//// d[[|/*marker6*/|]]
// @filename: dict_expression_typeAnnotation.py
//// from typing import Mapping
//// d: Mapping[str, int] = { "key": 1}
//// d[[|/*marker7*/|]]
// @filename: dict_constructor_typeAnnotation.py
//// from typing import Mapping
//// d: Mapping[str, int] = dict(key=1)
//// d[[|/*marker8*/|]]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker2: {
completions: [
{
label: "'key'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: "'key'" },
detail: Consts.IndexValueDetail,
},
],
},
marker3: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker4: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker5: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker5'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker5'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key3"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker5'), newText: '"key3"' },
detail: Consts.IndexValueDetail,
},
],
},
marker6: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker6'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker6'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
{
label: '"key3"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker6'), newText: '"key3"' },
detail: Consts.IndexValueDetail,
},
],
},
marker7: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker7'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker8: {
completions: [
{
label: "'key'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker8'), newText: "'key'" },
detail: Consts.IndexValueDetail,
},
],
},
});
}
@@ -1,121 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: string_literals.py
//// d = { "key" : 1 }
//// d[[|"/*marker1*/"|]]
// @filename: dict_constructor.py
//// d = dict(key=1)
//// d[[|"/*marker2*/"|]]
// @filename: dict_key_no_end.py
//// d = { "key": 1 }
//// d[[|"/*marker3*/|]]
// @filename: dict_key_partial.py
//// d = dict(key=1)
//// d[[|"k/*marker4*/"|]]
// @filename: dict_key_stringLiteralsOnly.py
//// name = "key"
//// d = { name: 1 }
//// d["key2"] = 2
//// d[[|/*marker5*/|]]
// @filename: dict_key_name_conflicts.py
//// keyString = "key"
//// d = dict(keyString=1)
//// d[[|keyStr/*marker6*/|]]
// @filename: dict_key_mixed_literals.py
//// d = { "key": 1, 1 + 2: 1 }
//// d[[|/*marker7*/|]]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker2: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker3: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker4: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
],
},
marker5: {
completions: [
{
label: 'name',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
{
label: '"key2"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker5'), newText: '"key2"' },
detail: Consts.IndexValueDetail,
},
],
},
marker6: {
completions: [
{ label: 'keyString', kind: Consts.CompletionItemKind.Variable },
{
label: '"keyString"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker6'), newText: '"keyString"' },
detail: Consts.IndexValueDetail,
},
],
},
marker7: {
completions: [
{
label: '"key"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker7'), newText: '"key"' },
detail: Consts.IndexValueDetail,
},
{
label: '1 + 2',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
},
],
},
});
}
@@ -1,53 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: string_literals_with_symbols.py
//// d = { "key-1" : 1 }
//// d[[|"/*marker1*/"|]]
// @filename: string_literals_with_symbols2.py
//// d = { "key\"yo\"" : 1 }
//// d[[|"/*marker2*/"|]]
// @filename: string_literals_duplicates.py
//// d = { "hello" : 1 }
//// d["hello"] = 2
////
//// d[[|"/*marker3*/"|]]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: '"key-1"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: '"key-1"' },
detail: Consts.IndexValueDetail,
},
],
},
marker2: {
completions: [
{
label: '"key\\"yo\\""',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"key\\"yo\\""' },
detail: Consts.IndexValueDetail,
},
],
},
marker3: {
completions: [
{
label: '"hello"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"hello"' },
detail: Consts.IndexValueDetail,
},
],
},
});
}
@@ -1,30 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class Parent:
//// def __init__(self, *args: Any, **kwargs: Any):
//// pass
////
//// def __new__(cls, *args: Any, **kwargs: Any):
//// pass
////
//// class Child(Parent):
//// def __new__(cls, name:str):
//// return super().__new__(cls, name)
////
//// class GrandChild(Child):
//// pass
//// x = GrandChild([|/*marker1*/|])
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'name=',
kind: Consts.CompletionItemKind.Variable,
},
],
},
});
@@ -1,20 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class Foo:
//// def __new__(cls, name: str):
//// return super().__new__(cls)
////
//// x = Foo([|/*marker1*/|])
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'name=',
kind: Consts.CompletionItemKind.Variable,
},
],
},
});
@@ -1,44 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from enum import Enum
//// class Color(Enum):
//// RED = 1
//// GREEN = 2
//// BLUE = 3
////
//// NotAMember: int = 3
////
//// @property
//// def a_prop(self):
//// pass
////
//// Color./*marker*/
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'BLUE',
kind: Consts.CompletionItemKind.EnumMember,
},
{
label: 'GREEN',
kind: Consts.CompletionItemKind.EnumMember,
},
{
label: 'RED',
kind: Consts.CompletionItemKind.EnumMember,
},
{
label: 'a_prop',
kind: Consts.CompletionItemKind.Property,
},
{
label: 'NotAMember',
kind: Consts.CompletionItemKind.Variable,
},
],
},
});
@@ -1,27 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import os
//// class App():
//// def __init(self):
//// self.instance_path = "\\foo"
//// app = App()
//// try:
//// os.makedirs(app.in[|/*marker*/|])
//// except:
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'instance_path',
kind: Consts.CompletionItemKind.Variable,
},
],
},
});
@@ -1,12 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// a = 42
//// a.n[|/*marker1*/|]
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker1: {
completions: [{ label: 'capitalize', kind: undefined }],
},
});
@@ -1,51 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import time
//// time.gm[|/*marker1*/|]
//// aaaaaa = 100
//// aaaaa[|/*marker2*/|]
//// def some_func1(a):
//// '''some function docs'''
//// pass
//// def some_func2(a):
//// '''another function docs'''
//// pass
//// some_fun[|/*marker3*/|]
//// unknownVariable.[|/*marker4*/|]
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: 'gmtime',
kind: Consts.CompletionItemKind.Function,
},
{
label: 'clock_gettime',
kind: Consts.CompletionItemKind.Function,
},
{
label: 'clock_gettime_ns',
kind: Consts.CompletionItemKind.Function,
},
],
},
marker2: { completions: [{ label: 'aaaaaa', kind: Consts.CompletionItemKind.Variable }] },
marker3: {
completions: [
{
label: 'some_func1',
kind: Consts.CompletionItemKind.Function,
documentation: '```python\ndef some_func1(a: Unknown) -> None\n```\n---\nsome function docs',
},
{
label: 'some_func2',
kind: Consts.CompletionItemKind.Function,
documentation: '```python\ndef some_func2(a: Unknown) -> None\n```\n---\nanother function docs',
},
],
},
marker4: { completions: [] },
});
@@ -1,33 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// msg = "gekki"
////
//// a = f"{[|/*marker1*/|]}"
//// b = f"{msg.c[|/*marker2*/|]}"
//// c = f"{msg.[|/*marker3*/|]}"
//// d = f"msg.[|/*marker4*/|]{msg}"
//// e = f"{msg}msg.[|/*marker5*/|]"
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [{ label: 'msg', kind: Consts.CompletionItemKind.Variable }],
},
marker2: {
completions: [{ label: 'count', kind: Consts.CompletionItemKind.Method }],
},
marker3: {
completions: [{ label: 'capitalize', kind: Consts.CompletionItemKind.Method }],
},
});
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker4: {
completions: [],
},
marker5: {
completions: [],
},
});
@@ -1,96 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import TypedDict
////
//// class Movie(TypedDict):
//// name: str
//// age: int
////
//// m = Movie(name="hello", age=10)
////
//// a = f"{m[[|/*marker1*/|]]}"
//// b = f'{m[[|/*marker2*/|]]}'
//// c = f'{m[[|"ag/*marker3*/"|]]}'
////
////
////
//// m2 = { 'name' : "hello" }
////
//// d = f"{m2[[|/*marker4*/|]]}"
//// e = f'{m2[[|/*marker5*/|]]}'
//// f = f'{m2[[|"na/*marker6*/"|]]}'
////
{
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: "'name'" },
},
{
label: "'age'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: "'age'" },
},
],
},
marker2: {
completions: [
{
label: '"name"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"name"' },
},
{
label: '"age"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"age"' },
},
],
},
marker3: {
completions: [
{
label: '"age"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"age"' },
},
],
},
marker4: {
completions: [
{
label: "'name'",
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
textEdit: { range: helper.getPositionRange('marker4'), newText: "'name'" },
},
],
},
marker5: {
completions: [
{
label: '"name"',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
textEdit: { range: helper.getPositionRange('marker5'), newText: '"name"' },
},
],
},
marker6: {
completions: [
{
label: '"name"',
kind: Consts.CompletionItemKind.Constant,
detail: Consts.IndexValueDetail,
textEdit: { range: helper.getPositionRange('marker6'), newText: '"name"' },
},
],
},
});
}
@@ -1,30 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from unittest.mock import MagicMock
//// mock = MagicMock()
//// mock.call[|/*marker1*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'call_args',
kind: Consts.CompletionItemKind.Variable,
},
{
label: 'called',
kind: Consts.CompletionItemKind.Variable,
},
{
label: '__call__',
kind: Consts.CompletionItemKind.Method,
},
{
label: 'assert_called',
kind: Consts.CompletionItemKind.Method,
},
],
},
});
@@ -1,31 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import _[|/*marker1*/|]
//// import __pycache__[|/*marker2*/|]
//// from test2 import _[|/*marker3*/|]
//// from test2 import [|/*marker4*/|]
// @filename: test2.py
//// def foo():
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [{ label: '__future__', kind: Consts.CompletionItemKind.Module }],
},
marker4: {
completions: [{ label: 'foo', kind: Consts.CompletionItemKind.Function }],
},
});
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker2: {
completions: [],
},
marker3: {
completions: [],
},
});
@@ -1,23 +0,0 @@
// @filename: test_no_duplicate_tseries_completions.py
//// from testLib import [|t/*marker*/|]
// @filename: testLib/__init__.pyi
// @library: true
//// import tseries
//// __all__ = ['tseries']
// @filename: testLib/tseries/__init__.pyi
// @library: true
//
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker: {
completions: [
{
label: 'tseries',
kind: Consts.CompletionItemKind.Module,
},
],
},
});
@@ -1,30 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from testLib import [|/*marker1*/|]En[|/*marker2*/|]um[|/*marker3*/|]
// @filename: testLib.py
//// class Enum: pass
//// class EnumCheck: pass
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{ label: 'Enum', kind: Consts.CompletionItemKind.Class },
{ label: 'EnumCheck', kind: Consts.CompletionItemKind.Class },
],
},
marker2: {
completions: [
{ label: 'Enum', kind: Consts.CompletionItemKind.Class },
{ label: 'EnumCheck', kind: Consts.CompletionItemKind.Class },
],
},
marker3: {
completions: [
{ label: 'Enum', kind: Consts.CompletionItemKind.Class },
{ label: 'EnumCheck', kind: Consts.CompletionItemKind.Class },
],
},
});
@@ -1,15 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from testLib import Enum, Enu[|/*marker1*/|]
// @filename: testLib.py
//// class Enum: pass
//// class EnumCheck: pass
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [{ label: 'EnumCheck', kind: Consts.CompletionItemKind.Class }],
},
});
@@ -1,52 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// import al[|/*marker1*/|]
// @filename: altair/__init__.py
// @library: true
//// """module docstring"""
////
//// __all__ = [ "selection_interval" ]
////
//// from .vegalite import (
//// selection,
//// selection_interval
//// )
// @filename: altair/vegalite/__init__.py
// @library: true
//// def selection(): pass
//// def selection_interval(): pass
// @filename: altair/py.typed
// @library: true
//// # has to contain something for file to be written
{
// Force interim file to be created
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{ label: 'altair', kind: Consts.CompletionItemKind.Module, documentation: 'module docstring' },
],
},
});
helper.replace(helper.BOF, helper.getMarkerByName('marker1').position, 'import altair as alt\n\nalt.');
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [{ label: 'selection_interval', kind: Consts.CompletionItemKind.Function }],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker1: {
completions: [{ label: 'selection', kind: Consts.CompletionItemKind.Function }],
},
});
}
@@ -1,32 +0,0 @@
// @filename: test_private_completions.py
//// import testLib.[|/*marker*/|]
// @filename: testLib/__init__.py
// @library: true
//// # empty
// @filename: testLib/__privateclass.py
// @library: true
//// class PrivateClass():
//// pass
// @filename: testLib/publicclass.py
// @library: true
//// class PublicClass():
//// pass
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker: {
completions: [
{
label: 'publicclass',
kind: Consts.CompletionItemKind.Module,
},
{
label: '__privateclass',
kind: Consts.CompletionItemKind.Module,
},
],
},
});
@@ -1,32 +0,0 @@
// @filename: test_no_private_completions.py
//// import testLib.[|/*marker*/|]
// @filename: testLib/__init__.py
// @library: true
//// # empty
// @filename: testLib/__privateclass.py
// @library: true
//// class PrivateClass():
//// pass
// @filename: testLib/publicclass.py
// @library: true
//// class PublicClass():
//// pass
// @filename: testLib/py.typed
// @library: true
//// # has to contain something for file to be written
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker: {
completions: [
{
label: 'publicclass',
kind: Consts.CompletionItemKind.Module,
},
],
},
});
@@ -1,32 +0,0 @@
// @filename: test_no_private_completions.py
//// import testLib.[|/*marker*/|]
// @filename: testLib/__init__.py
//// # empty
// @filename: testLib/__privateclass.py
//// class PrivateClass():
//// pass
// @filename: testLib/publicclass.py
//// class PublicClass():
//// pass
// @filename: testLib/py.typed
//// # has to contain something for file to be written
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker: {
completions: [
{
label: 'publicclass',
kind: Consts.CompletionItemKind.Module,
},
{
label: '__privateclass',
kind: Consts.CompletionItemKind.Module,
},
],
},
});
@@ -1,26 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from submodule.[|/*marker1*/|]
// @filename: viperconfig.json
//// {
//// "extraPaths": ["submodule"]
//// }
// @filename: submodule/submodule/__init__.py
////
// @filename: submodule/submodule/submodule1.py
//// def test_function():
//// pass
// @filename: submodule/setup.py
////
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [{ label: 'submodule1', kind: Consts.CompletionItemKind.Module }],
},
});
@@ -1,33 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: testList.py
//// a = 42
//// x = [
//// a.[|/*marker1*/|]
//// ]
// @filename: testListWithCall.py
//// b = 42
//// y = [
//// print(b.[|/*marker2*/|])
//// ]
// @filename: testListWithCallMissingClosedParens.py
//// b = 42
//// y = [
//// print(b.[|/*marker3*/|]
//// ]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName)); // @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [{ label: 'numerator', kind: Consts.CompletionItemKind.Property }],
},
marker2: {
completions: [{ label: 'numerator', kind: Consts.CompletionItemKind.Property }],
},
marker3: {
completions: [{ label: 'numerator', kind: Consts.CompletionItemKind.Property }],
},
});
}
@@ -1,12 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// a = 42
//// a.n[|/*marker1*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [{ label: 'numerator', kind: Consts.CompletionItemKind.Property }],
},
});
@@ -1,103 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: getitem.py
//// from typing import Literal, Generic, TypeVar, overload
//// class ClassA:
//// def __getitem__(self, key: Literal['a', 'b']):
//// pass
//// T = TypeVar("T")
//// class ClassB(Generic[T]):
//// @overload
//// def __getitem__(self, key: T):
//// pass
//// @overload
//// def __getitem__(self, key: Literal['foo']):
//// pass
// @filename: test1.py
//// from typing import Literal
//// from getitem import ClassA, ClassB
//// a = ClassA()
//// a[[|/*marker1*/|]]
//// b = ClassB[Literal['x']]()
//// b[[|/*marker2*/|]]
// @filename: test2.py
//// from typing import Literal
//// from getitem import ClassA, ClassB
//// a = ClassA()
//// a[[|"/*marker3*/"|]]
//// b = ClassB[Literal['x']]()
//// b[[|"/*marker4*/"|]]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{
label: "'a'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: "'a'" },
detail: Consts.IndexValueDetail,
},
{
label: "'b'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker1'), newText: "'b'" },
detail: Consts.IndexValueDetail,
},
],
},
marker2: {
completions: [
{
label: "'x'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: "'x'" },
detail: Consts.IndexValueDetail,
},
{
label: "'foo'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: "'foo'" },
detail: Consts.IndexValueDetail,
},
],
},
marker3: {
completions: [
{
label: '"a"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"a"' },
detail: Consts.IndexValueDetail,
},
{
label: '"b"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: '"b"' },
detail: Consts.IndexValueDetail,
},
],
},
marker4: {
completions: [
{
label: '"x"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"x"' },
detail: Consts.IndexValueDetail,
},
{
label: '"foo"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker4'), newText: '"foo"' },
detail: Consts.IndexValueDetail,
},
],
},
});
}
@@ -1,28 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: testFunctionWithVariableStub.py
//// import module1
////
//// module1.[|/*marker1*/displayhook|]
// @filename: module1.py
//// def displayhook() -> None:
//// '''displayhook docs'''
//// ...
// @filename: module1.pyi
//// from typing import Callable
//// displayhook: Callable[[],Any]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'displayhook',
kind: Consts.CompletionItemKind.Variable,
documentation: '```python\ndef displayhook() -> Unknown\n```\n---\ndisplayhook docs',
},
],
},
});
@@ -1,52 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: overloads_client.py
//// from typing import overload
//// import moduleA
////
//// class ChildA(moduleA.A):
//// @overload
//// def func(self, x: str) -> str:
//// pass
////
//// @overload
//// def func(self, x: int) -> int:
//// pass
////
////
//// ChildA.f[|/*marker1*/|]
// @filename: typings/moduleA.pyi
//// from typing import overload
//// class A:
//// @overload
//// def func(self, x: str) -> str: ...
////
//// @overload
//// def func(self, x: int) -> int: ...
// @filename: typings/moduleA.py
//// from typing import overload
//// class A:
//// @overload
//// def func(self, x: str) -> str:
//// pass
////
//// @overload
//// def func(self, x: int) -> int:
//// '''func docs'''
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'func',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef func(self: ChildA, x: str) -> str: ...\ndef func(self: ChildA, x: int) -> int: ...\n```\n---\nfunc docs',
},
],
},
});
@@ -1,53 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: overloads_client.py
//// from typing import overload
//// import moduleA
////
//// class ChildA(moduleA.A):
//// @overload
//// def func(self, x: str) -> str:
//// pass
////
//// @overload
//// def func(self, x: int) -> int:
//// pass
////
////
//// ChildA.f[|/*marker1*/|]
// @filename: typings/moduleA.pyi
//// from typing import overload
//// class A:
//// @overload
//// def func(self, x: str) -> str: ...
////
//// @overload
//// def func(self, x: int) -> int:
//// '''func docs'''
//// ...
// @filename: typings/moduleA.py
//// from typing import overload
//// class A:
//// @overload
//// def func(self, x: str) -> str:
//// pass
////
//// @overload
//// def func(self, x: int) -> int:
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'func',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef func(self: ChildA, x: str) -> str: ...\ndef func(self: ChildA, x: int) -> int: ...\n```\n---\nfunc docs',
},
],
},
});
@@ -1,104 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// import testLib
//// class ChildGetterDocs(testLib.ClassWithGetterDocs):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// class ChildSetterDocs(testLib.ClassWithSetterDocs):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// one = ChildGetterDocs(3)
//// one.lengt[|/*marker1*/|]
//// two = ChildSetterDocs(3)
//// two.lengt[|/*marker2*/|]
// @filename: testLib/__init__.py
//// class ClassWithGetterDocs(object):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// """
//// read property doc
//// """
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// class ClassWithSetterDocs(object):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// """
//// setter property doc
//// """
//// pass
////
// @filename: testLib/__init__.pyi
//// class ClassWithGetterDocs(object):
//// @property
//// def length(self) -> int: ...
//// @length.setter
//// def length(self, value) -> None: ...
////
//// class ClassWithSetterDocs(object):
//// @property
//// def length(self) -> int: ...
//// @length.setter
//// def length(self, value) -> None: ...
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'length',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nlength: Unknown (property)\n```\n---\nread property doc',
},
],
},
marker2: {
completions: [
{
label: 'length',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nlength: Unknown (property)\n```\n---\nsetter property doc',
},
],
},
});
@@ -1,108 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// import testLib
//// class ChildGetterDocs(testLib.ClassWithGetterDocs):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// class ChildSetterDocs(testLib.ClassWithSetterDocs):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// one = ChildGetterDocs(3)
//// one.lengt[|/*marker1*/|]
//// two = ChildSetterDocs(3)
//// two.lengt[|/*marker2*/|]
// @filename: testLib/__init__.py
// @library: true
//// class ClassWithGetterDocs(object):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// class ClassWithSetterDocs(object):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
// @filename: testLib/__init__.pyi
// @library: true
//// class ClassWithGetterDocs(object):
//// @property
//// def length(self) -> int:
//// """
//// read property doc
//// """
//// ...
//// @length.setter
//// def length(self, value) -> None: ...
////
//// class ClassWithSetterDocs(object):
//// @property
//// def length(self) -> int: ...
//// @length.setter
//// def length(self, value) -> None:
//// """
//// setter property doc
//// """
//// ...
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'length',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nlength: Unknown (property)\n```\n---\nread property doc',
},
],
},
marker2: {
completions: [
{
label: 'length',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nlength: Unknown (property)\n```\n---\nsetter property doc',
},
],
},
});
@@ -1,99 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// Statement-only keywords (e.g. `raise`, `return`) should be suppressed in
// slots that can only contain an expression, while still being offered at the
// start of a statement. Expression-valid keywords (e.g. `lambda`) must keep
// appearing in expression slots.
// @filename: stmtStart.py
//// def func():
//// re[|/*stmtStart*/|]
// @filename: forIterable.py
//// for item in ra[|/*forIterable*/|]
// @filename: forIterableExprKeyword.py
//// for item in la[|/*forIterableExprKeyword*/|]
// @filename: assignRhs.py
//// x = re[|/*assignRhs*/|]
// @filename: assignRhsExprKeyword.py
//// x = la[|/*assignRhsExprKeyword*/|]
// @filename: walrusRhs.py
//// if (n := re[|/*walrusRhs*/|]):
//// pass
// @filename: comprehensionIterable.py
//// z = [i for i in re[|/*comprehensionIterable*/|]]
// @filename: callArg.py
//// print(re[|/*callArg*/|])
// @filename: subscript.py
//// data = [1, 2]
//// w = data[re[|/*subscript*/|]]
// @filename: returnValue.py
//// def func():
//// return ra[|/*returnValue*/|]
// @filename: whileCondition.py
//// while re[|/*whileCondition*/|]:
//// pass
// @filename: ifCondition.py
//// if re[|/*ifCondition*/|]:
//// pass
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// Statement-only keywords are still offered at statement start, and
// expression-valid keywords are still offered in expression slots.
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
stmtStart: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
forIterableExprKeyword: {
completions: [{ label: 'lambda', kind: Consts.CompletionItemKind.Keyword }],
},
assignRhsExprKeyword: {
completions: [{ label: 'lambda', kind: Consts.CompletionItemKind.Keyword }],
},
});
// Statement-only keywords are suppressed in expression-only slots.
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
forIterable: {
completions: [{ label: 'raise', kind: Consts.CompletionItemKind.Keyword }],
},
assignRhs: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
walrusRhs: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
comprehensionIterable: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
callArg: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
subscript: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
returnValue: {
completions: [{ label: 'raise', kind: Consts.CompletionItemKind.Keyword }],
},
whileCondition: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
ifCondition: {
completions: [{ label: 'return', kind: Consts.CompletionItemKind.Keyword }],
},
});
}
@@ -1,93 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "executionEnvironments": [
//// { "root": "python33", "pythonVersion": "3.3" },
//// { "root": "python35", "pythonVersion": "3.5" },
//// { "root": "python310", "pythonVersion": "3.10" },
//// { "root": "python315", "pythonVersion": "3.15" },
//// ]
//// }
// @filename: python33/test.py
//// def foo():
//// [|/*python33*/|]
// @filename: python35/test.py
//// def foo():
//// [|/*python35*/|]
// @filename: python310/test.py
//// def foo():
//// [|/*python310*/|]
// @filename: python315/test.py
//// def foo():
//// [|/*python315*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
python33: {
completions: [
{ label: 'def', kind: Consts.CompletionItemKind.Keyword },
{ label: 'import', kind: Consts.CompletionItemKind.Keyword },
],
},
python35: {
completions: [
{ label: 'def', kind: Consts.CompletionItemKind.Keyword },
{ label: 'import', kind: Consts.CompletionItemKind.Keyword },
{ label: 'async', kind: Consts.CompletionItemKind.Keyword },
{ label: 'await', kind: Consts.CompletionItemKind.Keyword },
],
},
python310: {
completions: [
{ label: 'def', kind: Consts.CompletionItemKind.Keyword },
{ label: 'import', kind: Consts.CompletionItemKind.Keyword },
{ label: 'async', kind: Consts.CompletionItemKind.Keyword },
{ label: 'await', kind: Consts.CompletionItemKind.Keyword },
{ label: 'case', kind: Consts.CompletionItemKind.Keyword },
{ label: 'match', kind: Consts.CompletionItemKind.Keyword },
],
},
python315: {
completions: [
{ label: 'def', kind: Consts.CompletionItemKind.Keyword },
{ label: 'import', kind: Consts.CompletionItemKind.Keyword },
{ label: 'async', kind: Consts.CompletionItemKind.Keyword },
{ label: 'await', kind: Consts.CompletionItemKind.Keyword },
{ label: 'case', kind: Consts.CompletionItemKind.Keyword },
{ label: 'match', kind: Consts.CompletionItemKind.Keyword },
{ label: 'lazy', kind: Consts.CompletionItemKind.Keyword },
],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
python33: {
completions: [
{ label: 'async', kind: Consts.CompletionItemKind.Keyword },
{ label: 'await', kind: Consts.CompletionItemKind.Keyword },
{ label: 'case', kind: Consts.CompletionItemKind.Keyword },
{ label: 'match', kind: Consts.CompletionItemKind.Keyword },
{ label: 'lazy', kind: Consts.CompletionItemKind.Keyword },
],
},
python35: {
completions: [
{ label: 'case', kind: Consts.CompletionItemKind.Keyword },
{ label: 'match', kind: Consts.CompletionItemKind.Keyword },
{ label: 'lazy', kind: Consts.CompletionItemKind.Keyword },
],
},
python310: {
completions: [{ label: 'lazy', kind: Consts.CompletionItemKind.Keyword }],
},
});
}
@@ -1,79 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// import testLib
//// obj = testLib.[|/*marker1*/Validator|]()
//// obj.is[|/*marker2*/|]
//// obj.read[|/*marker3*/|]
// @filename: testLib/__init__.py
// @library: true
//// class Validator:
//// '''The validator class'''
//// def is_valid(self, text):
//// '''Checks if the input string is valid.'''
//// return True
//// @property
//// def read_only_prop(self):
//// '''The read-only property.'''
//// return True
//// @property
//// def read_write_prop(self):
//// '''The read-write property.'''
//// return True
//// @read_write_prop.setter
//// def read_write_prop(self, val):
//// pass
// @filename: testLib/__init__.pyi
// @library: true
//// class Validator:
//// def is_valid(self, text: str) -> bool: ...
//// @property
//// def read_only_prop(self) -> bool: ...
//// @property
//// def read_write_prop(self) -> bool: ...
//// @read_write_prop.setter
//// def read_write_prop(self, val: bool): ...
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'Validator',
kind: Consts.CompletionItemKind.Class,
documentation: '```python\nclass Validator()\n```\n---\nThe validator class',
},
],
},
marker2: {
completions: [
{
label: 'is_valid',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef is_valid(text: str) -> bool\n```\n---\nChecks if the input string is valid.',
},
],
},
marker3: {
completions: [
{
label: 'read_only_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_only_prop: bool (property)\n```\n---\nThe read-only property.',
},
{
label: 'read_write_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_write_prop: bool (property)\n```\n---\nThe read-write property.',
},
],
},
});
@@ -1,69 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// import testLib
//// obj = testLib.[|/*marker1*/Validator|]()
//// obj.is[|/*marker2*/|]
//// obj.read[|/*marker3*/|]
// @filename: testLib/__init__.py
// @library: true
//// class Validator:
//// '''The validator class'''
//// def is_valid(self, text: str) -> bool:
//// '''Checks if the input string is valid.'''
//// return True
//// @property
//// def read_only_prop(self) -> bool:
//// '''The read-only property.'''
//// return True
//// @property
//// def read_write_prop(self) -> bool:
//// '''The read-write property.'''
//// return True
//// @read_write_prop.setter
//// def read_write_prop(self, val: bool):
//// '''The read-write property.'''
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'Validator',
kind: Consts.CompletionItemKind.Class,
documentation: '```python\nclass Validator()\n```\n---\nThe validator class',
},
],
},
marker2: {
completions: [
{
label: 'is_valid',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef is_valid(text: str) -> bool\n```\n---\nChecks if the input string is valid.',
},
],
},
marker3: {
completions: [
{
label: 'read_only_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_only_prop: bool (property)\n```\n---\nThe read-only property.',
},
{
label: 'read_write_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_write_prop: bool (property)\n```\n---\nThe read-write property.',
},
],
},
});
@@ -1,69 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// import testLib
//// obj = testLib.[|/*marker1*/Validator|]()
//// obj.is[|/*marker2*/|]
//// obj.read[|/*marker3*/|]
// @filename: testLib/__init__.pyi
// @library: true
//// class Validator:
//// '''The validator class'''
//// def is_valid(self, text: str) -> bool:
//// '''Checks if the input string is valid.'''
//// pass
//// @property
//// def read_only_prop(self) -> bool:
//// '''The read-only property.'''
//// pass
//// @property
//// def read_write_prop(self) -> bool:
//// '''The read-write property.'''
//// pass
//// @read_write_prop.setter
//// def read_write_prop(self, val: bool):
//// '''The read-write property.'''
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'Validator',
kind: Consts.CompletionItemKind.Class,
documentation: '```python\nclass Validator()\n```\n---\nThe validator class',
},
],
},
marker2: {
completions: [
{
label: 'is_valid',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef is_valid(text: str) -> bool\n```\n---\nChecks if the input string is valid.',
},
],
},
marker3: {
completions: [
{
label: 'read_only_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_only_prop: bool (property)\n```\n---\nThe read-only property.',
},
{
label: 'read_write_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_write_prop: bool (property)\n```\n---\nThe read-write property.',
},
],
},
});
@@ -1,33 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// from typing import Literal
//// a: Literal["Hello"] = "He[|/*marker1*/|]
// @filename: test2.py
//// from typing import Literal
//// a: Literal["Hello"] = [|/*marker2*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: '"Hello"',
kind: Consts.CompletionItemKind.Constant,
},
],
},
marker2: {
completions: [
{
label: '"Hello"',
kind: Consts.CompletionItemKind.Constant,
},
],
},
});
}
@@ -1,74 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import testLib
//// obj = testLib.[|/*marker1*/Validator|]()
//// obj.is[|/*marker2*/|]
//// obj.read[|/*marker3*/|]
//// testLib.Validator.is[|/*marker4*/|]
// @filename: testLib/__init__.py
//// class Validator:
//// '''The validator class'''
//// def is_valid(self, text: str) -> bool:
//// '''Checks if the input string is valid.'''
//// return True
//// @property
//// def read_only_prop(self) -> bool:
//// '''The read-only property.'''
//// return True
//// @property
//// def read_write_prop(self) -> bool:
//// '''The read-write property.'''
//// return True
//// @read_write_prop.setter
//// def read_write_prop(self, val: bool):
//// '''The read-write property.'''
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'Validator',
kind: Consts.CompletionItemKind.Class,
documentation: '```python\nclass Validator()\n```\n---\nThe validator class',
},
],
},
marker2: {
completions: [
{
label: 'is_valid',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef is_valid(text: str) -> bool\n```\n---\nChecks if the input string is valid.',
},
],
},
marker3: {
completions: [
{
label: 'read_only_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_only_prop: bool (property)\n```\n---\nThe read-only property.',
},
{
label: 'read_write_prop',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nread_write_prop: bool (property)\n```\n---\nThe read-write property.',
},
],
},
marker4: {
completions: [
{
label: 'is_valid',
kind: Consts.CompletionItemKind.Method,
documentation:
'```python\ndef is_valid(self: Validator, text: str) -> bool\n```\n---\nChecks if the input string is valid.',
},
],
},
});
@@ -1,17 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class Model:
//// pass
////
//// def some_func1(a: Model):
//// x = a.unknownName.[|/*marker1*/|]
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [],
memberAccessInfo: { lastKnownModule: 'test', lastKnownMemberName: 'Model', unknownMemberName: 'unknownName' },
},
});
@@ -1,57 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class Model:
//// @staticmethod
//// def foo( value ):
//// return value
////
////
//// x = Model.foo(unknownValue).[|/*marker1*/|]
//// pass
////
//// y = Model.unknownMember.[|/*marker2*/|]
//// pass
////
//// def some_func1(a: Model):
//// x = a.unknownMember.[|/*marker3*/|]
//// pass
////
//// Model.unknownValue.[|/*marker4*/|]
////
//// UnkownModel.unknownValue.[|/*marker5*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
// tests: _getLastKnownModule(): if (curNode.nodeType === ParseNodeType.MemberAccess && curNode.memberName)
marker1: {
completions: [],
memberAccessInfo: { lastKnownModule: 'test', lastKnownMemberName: 'foo', unknownMemberName: 'foo' },
},
// tests: _getLastKnownModule(): else if (curNode.nodeType === ParseNodeType.Name && isClassAndInstantiable(curType))
marker2: {
completions: [],
memberAccessInfo: {
lastKnownModule: 'test',
lastKnownMemberName: 'Model',
unknownMemberName: 'unknownMember',
},
},
// tests: _getLastKnownModule(): else if (curNode.nodeType === ParseNodeType.Name && isObject(curType))
marker3: {
completions: [],
memberAccessInfo: {
lastKnownModule: 'test',
lastKnownMemberName: 'Model',
unknownMemberName: 'unknownMember',
},
},
marker4: {
completions: [],
memberAccessInfo: { lastKnownModule: 'test', lastKnownMemberName: 'Model', unknownMemberName: 'unknownValue' },
},
marker5: {
completions: [],
memberAccessInfo: {},
},
});
@@ -1,30 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// import testnumpy
//// obj = testnumpy.random.randint("foo").[|/*marker1*/|]
// @filename: testnumpy/__init__.py
// @library: true
//// from . import random
// @filename: testnumpy/random/__init__.py
// @library: true
//// __all__ = ['randint']
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [],
memberAccessInfo: {
lastKnownModule: 'testnumpy.random',
lastKnownMemberName: 'random',
unknownMemberName: 'randint',
},
},
});
@@ -1,40 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: overloads_client.py
//// import overloads
//// overloads.f[|/*marker1*/|]
// @filename: typings/overloads.pyi
//// from typing import overload
////
//// @overload
//// def func(x: str) -> str: ...[|/*marker2*/|]
////
//// @overload
//// def func(x: bytes) -> bytes:
//// ...[|/*marker3*/|]
////
//// @overload
//// def func(x: int) -> int:
//// '''func docs'''
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'func',
kind: Consts.CompletionItemKind.Function,
documentation:
'```python\ndef func(x: str) -> str: ...\ndef func(x: bytes) -> bytes: ...\ndef func(x: int) -> int: ...\n```\n---\nfunc docs',
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker2: { completions: [] },
marker3: { completions: [] },
});
@@ -1,47 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class B:
//// def method1(self, a: str = 'hello', b: int = 1234):
//// pass
////
//// def method2(self, a=None):
//// pass
////
//// def method3(self, a=1234, b=object()):
//// pass
////
//// class C(B):
//// def [|method/*marker*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: "method1(self, a: str = 'hello', b: int = 1234):\n return super().method1(a, b)",
},
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method2(self, a=None):\n return super().method2(a)',
},
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method3(self, a=1234, b=object()):\n return super().method3(a, b)',
},
},
],
},
});
@@ -1,50 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: main.py
//// from test import B
////
//// class C(B):
//// def [|method/*marker*/|]
// @filename: test.pyi
//// class B:
//// def method1(self, a: str = 'hello', b: int = 1234):
//// pass
////
//// def method2(self, a=None):
//// pass
////
//// def method3(self, a=1234, b=object()):
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method1(self, a: str = ..., b: int = ...):\n return super().method1(a=a, b=b)',
},
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method2(self, a=...):\n return super().method2(a=a)',
},
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method3(self, a=..., b=...):\n return super().method3(a=a, b=b)',
},
},
],
},
});
@@ -1,61 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from foo import B
////
//// class C(B):
//// def [|method/*marker*/|]
// @filename: foo.py
//// class B:
//// def method1(self, a: str = 'hello', b: int = 1234):
//// pass
////
//// def method2(self, a=None):
//// pass
////
//// def method3(self, a=1234, b=object()):
//// pass
////
//// def method4(self, a=+1234, b=-1.23j, c=1+2j):
//// pass
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: "method1(self, a: str = 'hello', b: int = 1234):\n return super().method1(a, b)",
},
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method2(self, a=None):\n return super().method2(a)',
},
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method3(self, a=1234, b=...):\n return super().method3(a, b)',
},
},
{
label: 'method4',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method4(self, a=+1234, b=-1.23j, c=1 + 2j):\n return super().method4(a, b, c)',
},
},
],
},
});
@@ -1,47 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.pyi
//// class B:
//// def method1(self, a: str = 'hello', b: int = 1234):
//// pass
////
//// def method2(self, a=None):
//// pass
////
//// def method3(self, a=1234, b=object()):
//// pass
////
//// class C(B):
//// def [|method/*marker*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method1(self, a: str = ..., b: int = ...): ...',
},
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method2(self, a=...): ...',
},
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method3(self, a=..., b=...): ...',
},
},
],
},
});
@@ -1,47 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class B:
//// def method1(self, a: str, *args, **kwargs):
//// pass
////
//// def method2(self, b, /, *args):
//// pass
////
//// def method3(self, b, *, c: str):
//// pass
////
//// class C(B):
//// def [|method/*marker*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method1(self, a: str, *args, **kwargs):\n return super().method1(a, *args, **kwargs)',
},
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method2(self, b, /, *args):\n return super().method2(b, *args)',
},
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method3(self, b, *, c: str):\n return super().method3(b, c=c)',
},
},
],
},
});
@@ -1,31 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class B:
//// @property
//// def prop(self):
//// return 1
////
//// @prop.setter
//// def prop(self, value):
//// pass
////
//// class C(B):
//// @property
//// def [|pr/*marker*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'prop',
kind: Consts.CompletionItemKind.Property,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'prop(self):\n return super().prop',
},
},
],
},
});
@@ -1,31 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.pyi
//// class B:
//// @property
//// def prop(self):
//// return 1
////
//// @prop.setter
//// def prop(self, value):
//// pass
////
//// class C(B):
//// @property
//// def [|pr/*marker*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'prop',
kind: Consts.CompletionItemKind.Property,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'prop(self): ...',
},
},
],
},
});
@@ -1,64 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class A:
//// @staticmethod
//// def smethod(a, b):
//// pass
////
//// @classmethod
//// def cmethod(cls, a):
//// pass
////
//// class B1(A):
//// def [|m/*marker1*/|]
////
//// class B2(A):
//// @staticmethod
//// def [|m/*marker2*/|]
////
//// class B3(A):
//// @classmethod
//// def [|m/*marker3*/|]
{
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker2: {
completions: [
{
label: 'smethod',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker2'),
newText: 'smethod(a, b):\n return super().smethod(a, b)',
},
},
],
},
marker3: {
completions: [
{
label: 'cmethod',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker3'),
newText: 'cmethod(cls, a):\n return super().cmethod(a)',
},
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker1: {
completions: [
{ label: 'smethod', kind: undefined },
{ label: 'cmethod', kind: undefined },
],
},
marker2: { completions: [{ label: 'cmethod', kind: undefined }] },
marker3: { completions: [{ label: 'smethod', kind: undefined }] },
});
}
@@ -1,47 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.pyi
//// class B:
//// def method1(self, a: str, *args, **kwargs):
//// pass
////
//// def method2(self, b, /, *args):
//// pass
////
//// def method3(self, b, *, c: str):
//// pass
////
//// class C(B):
//// def [|method/*marker*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method1(self, a: str, *args, **kwargs): ...',
},
},
{
label: 'method2',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method2(self, b, /, *args): ...',
},
},
{
label: 'method3',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'method3(self, b, *, c: str): ...',
},
},
],
},
});
@@ -1,71 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class B(list):
//// def [|append/*marker*/|]
// @filename: test1.py
//// class A:
//// def __init__(self, *args, **kwargs):
//// pass
////
//// class B(A):
//// def [|__init__/*marker1*/|]
// @filename: test2.py
//// class A:
//// def [|__class__/*marker2*/|]
// @filename: test3.py
//// class A:
//// def [|__call__/*marker3*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'append',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker'),
newText: 'append(self, object: _T, /) -> None:\n return super().append(object)',
},
},
],
},
marker1: {
completions: [
{
label: '__init__',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker1'),
newText: '__init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)',
},
},
],
},
marker3: {
completions: [
{
label: '__call__',
kind: Consts.CompletionItemKind.Method,
textEdit: {
range: helper.getPositionRange('marker3'),
newText: '__call__(self, *args: Any, **kwds: Any) -> Any:\n ${0:pass}',
},
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
// Only method shows up. __class__ is property
marker2: { completions: [{ label: '__class__', kind: undefined }] },
});
}
@@ -1,23 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// def Method(a, b, c):
//// pass
////
//// Method([|/*marker1*/|]"[|/*marker2*/|]hello[|/*marker3*/|]"[|/*marker4*/|])
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [{ label: 'a=', kind: Consts.CompletionItemKind.Variable }],
},
marker4: {
completions: [{ label: 'b=', kind: Consts.CompletionItemKind.Variable }],
},
});
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker2: { completions: [] },
marker3: { completions: [] },
});
@@ -1,72 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import TypedDict, Unpack, Any
////
//// class Movie(TypedDict):
//// key1: str
//// key2: int
////
//// def method(param1=None, param2='active', param3=None):
//// pass
////
//// met/*marker1*/hod /*marker2*/ ( /*marker3*/ param2 = 'test')
////
//// def method2(param1: int, **kwargs: Unpack[Movie]):
//// pass
////
//// method2(p/*marker4*/, k/*marker5*/)
////
//// def method3(param1: int, **kwargs: Any):
//// pass
////
//// method3(p/*marker6*/, k/*marker7*/)
////
//// def method4(param1: int, /, param2: int):
//// pass
////
//// method4(p/*marker8*/)
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker1: {
completions: [{ label: 'param1', kind: undefined }],
},
marker2: {
completions: [{ label: 'param1', kind: undefined }],
},
marker4: {
completions: [{ label: 'key1', kind: undefined }],
},
marker5: {
completions: [{ label: 'param1', kind: undefined }],
},
marker7: {
completions: [{ label: 'key1', kind: undefined }],
},
marker8: {
completions: [{ label: 'param1', kind: undefined }],
},
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker3: {
completions: [{ label: 'param1=', kind: Consts.CompletionItemKind.Variable }],
},
marker4: {
completions: [{ label: 'param1=', kind: Consts.CompletionItemKind.Variable }],
},
marker5: {
completions: [
{ label: 'key2=', kind: Consts.CompletionItemKind.Variable },
{ label: 'key1=', kind: Consts.CompletionItemKind.Variable },
],
},
marker6: {
completions: [{ label: 'param1=', kind: Consts.CompletionItemKind.Variable }],
},
marker8: {
completions: [{ label: 'param2=', kind: Consts.CompletionItemKind.Variable }],
},
});
@@ -1,17 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: python/test.py
//// from d/*marker*/
// @filename: python/data_processing/__init__.py
//// #empty
// @filename: python/data_processing/create_fullname.py
//// #empty
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [{ label: 'data_processing', kind: Consts.CompletionItemKind.Module }],
},
});
@@ -1,77 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: module.py
//// # empty
// @filename: nested1/__init__.py
//// # empty
// @filename: nested1/module.py
//// # empty
// @filename: nested1/nested2/__init__.py
//// # empty
// @filename: nested1/nested2/test1.py
//// from .[|/*marker1*/|]
// @filename: nested1/nested2/test2.py
//// from ..[|/*marker2*/|]
// @filename: nested1/nested2/test3.py
//// from ..nested2.[|/*marker3*/|]
// @filename: nested1/nested2/test4.py
//// from ...nested1.[|/*marker4*/|]
// @filename: nested1/nested2/test5.py
//// from ...nested1.nested2.[|/*marker5*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: {
completions: [
{ label: 'import', kind: Consts.CompletionItemKind.Keyword },
{ label: 'test1', kind: Consts.CompletionItemKind.Module },
{ label: 'test2', kind: Consts.CompletionItemKind.Module },
{ label: 'test3', kind: Consts.CompletionItemKind.Module },
{ label: 'test4', kind: Consts.CompletionItemKind.Module },
{ label: 'test5', kind: Consts.CompletionItemKind.Module },
],
},
marker2: {
completions: [
{ label: 'import', kind: Consts.CompletionItemKind.Keyword },
{ label: 'nested2', kind: Consts.CompletionItemKind.Module },
{ label: 'module', kind: Consts.CompletionItemKind.Module },
],
},
marker3: {
completions: [
{ label: 'test1', kind: Consts.CompletionItemKind.Module },
{ label: 'test2', kind: Consts.CompletionItemKind.Module },
{ label: 'test3', kind: Consts.CompletionItemKind.Module },
{ label: 'test4', kind: Consts.CompletionItemKind.Module },
{ label: 'test5', kind: Consts.CompletionItemKind.Module },
],
},
marker4: {
completions: [
{ label: 'nested2', kind: Consts.CompletionItemKind.Module },
{ label: 'module', kind: Consts.CompletionItemKind.Module },
],
},
marker5: {
completions: [
{ label: 'test1', kind: Consts.CompletionItemKind.Module },
{ label: 'test2', kind: Consts.CompletionItemKind.Module },
{ label: 'test3', kind: Consts.CompletionItemKind.Module },
{ label: 'test4', kind: Consts.CompletionItemKind.Module },
{ label: 'test5', kind: Consts.CompletionItemKind.Module },
],
},
});
}
@@ -1,34 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import time
//// time.gmt[|/*marker1*/|]
//// aaaaaa = 100
//// aaaaa[|/*marker2*/|]
//// def some_func1(a):
//// '''some function docs'''
//// pass
//// def some_func2(a):
//// '''another function docs'''
//// pass
//// some_fun[|/*marker3*/|]
// @ts-ignore
await helper.verifyCompletion('exact', 'plaintext', {
marker1: { completions: [{ label: 'gmtime', kind: Consts.CompletionItemKind.Function }] },
marker2: { completions: [{ label: 'aaaaaa', kind: Consts.CompletionItemKind.Variable }] },
marker3: {
completions: [
{
label: 'some_func1',
kind: Consts.CompletionItemKind.Function,
documentation: 'def some_func1(a: Unknown) -> None\n\nsome function docs',
},
{
label: 'some_func2',
kind: Consts.CompletionItemKind.Function,
documentation: 'def some_func2(a: Unknown) -> None\n\nanother function docs',
},
],
},
});
@@ -1,64 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test1.py
//// def __hello():
//// pass
////
//// __hello[|/*marker1*/|]
// @filename: test2.pyi
//// from typing import Union
////
//// Union[|/*marker2*/|]
////
//// def __hello1():
//// pass
////
//// __hello1[|/*marker3*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
// Private symbol in same file suggested.
{
label: '__hello',
kind: Consts.CompletionItemKind.Function,
},
],
},
marker2: {
completions: [
// No Auto-import on Union exists.
{
label: 'Union',
kind: Consts.CompletionItemKind.Class,
},
],
},
marker3: {
completions: [
{
label: '__hello1',
kind: Consts.CompletionItemKind.Function,
},
],
},
});
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
marker3: {
completions: [
// Private symbol from other file not suggested.
{
label: '__hello',
kind: Consts.CompletionItemKind.Function,
},
],
},
});
}
@@ -1,28 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class C:
//// def __init__(self):
//// self._x = None
////
//// @property
//// def prop(self):
//// pass
////
//// @prop.setter
//// def prop(self, value):
//// pass
////
//// C()./*marker*/prop
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker: {
completions: [
{
label: 'prop',
kind: Consts.CompletionItemKind.Property,
},
],
},
});
@@ -1,64 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: viperconfig.json
//// {
//// "useLibraryCodeForTypes": true
//// }
// @filename: test.py
//// class ClassWithGetterDocs(object):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// """
//// read property doc
//// """
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// pass
////
//// one = ClassWithGetterDocs(3)
//// one.lengt[|/*marker1*/|]
////
//// class ClassWithSetterDocs(object):
//// def __init__(self, length):
//// self._length = length
////
//// @property
//// def length(self):
//// return self._length
////
//// @length.setter
//// def length(self, value):
//// """
//// setter property doc
//// """
//// pass
////
//// two = ClassWithSetterDocs(3)
//// two.lengt[|/*marker2*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'length',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nlength: Unknown (property)\n```\n---\nread property doc',
},
],
},
marker2: {
completions: [
{
label: 'length',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nlength: Unknown (property)\n```\n---\nsetter property doc',
},
],
},
});
@@ -1,35 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class A:
//// pass
////
//// a = A()
//// a.__[|/*instanceMarker*/|]
//// A.__[|/*classMarker*/|]
{
helper.openFiles(helper.getMarkers().map((m) => m.fileName));
// `__qualname__` is exposed via the metaclass (`type`), so it is a valid
// member of the class object but not of an instance.
// @ts-ignore
await helper.verifyCompletion('excluded', 'markdown', {
instanceMarker: {
completions: [{ label: '__qualname__', kind: Consts.CompletionItemKind.Variable }],
},
});
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
instanceMarker: {
completions: [
{ label: '__doc__', kind: Consts.CompletionItemKind.Variable },
{ label: '__module__', kind: Consts.CompletionItemKind.Variable },
],
},
classMarker: {
completions: [{ label: '__qualname__', kind: Consts.CompletionItemKind.Variable }],
},
});
}
@@ -1,43 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// class Foo:
//// def __init__(self):
//// self.var1 = 3
//// def method1(self):
//// '''Method 1.'''
//// pass
//// @property
//// def prop1(self):
//// '''Property 1.'''
//// return 2
//// def new_method(self):
//// self.[|/*marker1*/|]
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: 'method1',
kind: Consts.CompletionItemKind.Method,
documentation: '```python\ndef method1() -> None\n```\n---\nMethod 1.',
},
{
label: 'new_method',
kind: Consts.CompletionItemKind.Method,
documentation: '```python\ndef new_method() -> None\n```',
},
{
label: 'prop1',
kind: Consts.CompletionItemKind.Property,
documentation: '```python\nprop1: Literal[2] (property)\n```\n---\nProperty 1.',
},
{
label: 'var1',
kind: Consts.CompletionItemKind.Variable,
documentation: '```python\nvar1: int\n```',
},
],
},
});
@@ -1,71 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// from typing import Literal
////
//// def method(foo: Literal["'\"", '"\'', "'mixed'"]):
//// pass
////
//// method([|/*marker1*/|])
//// method([|"/*marker2*/"|])
//// method([|'/*marker3*/'|])
{
// @ts-ignore
await helper.verifyCompletion('included', 'markdown', {
marker1: {
completions: [
{
label: '"\'\\""',
kind: Consts.CompletionItemKind.Constant,
},
{
label: '"\\"\'"',
kind: Consts.CompletionItemKind.Constant,
},
{
label: '"\'mixed\'"',
kind: Consts.CompletionItemKind.Constant,
},
],
},
marker2: {
completions: [
{
label: '"\'\\""',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"\'\\""' },
},
{
label: '"\\"\'"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"\\"\'"' },
},
{
label: '"\'mixed\'"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker2'), newText: '"\'mixed\'"' },
},
],
},
marker3: {
completions: [
{
label: "'\\'\"'",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: "'\\'\"'" },
},
{
label: "'\"\\''",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: "'\"\\''" },
},
{
label: "'\\'mixed\\''",
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: helper.getPositionRange('marker3'), newText: "'\\'mixed\\''" },
},
],
},
});
}
@@ -1,79 +0,0 @@
/// <reference path="typings/fourslash.d.ts" />
// @filename: test.py
//// import os
//// from typing import Literal, TypedDict, Union
////
//// def method(a, b, c):
//// pass
////
//// method("os.[|/*marker1*/|]")
////
//// class Movie(TypedDict):
//// name: str
//// age: int
////
//// m = Movie(name="hello", age=10)
//// m[[|"/*marker2*/"|]]
////
//// a: Union[Literal["hello"], Literal["hallo"]]
//// a = [|"/*marker3*/"|]
////
//// class Nested(TypedDict):
//// movie: Movie
////
//// n: Nested = {"movie": {"name": "hello", "age": 10}}
//// n["movie"][[|/*marker4*/|]]
{
const marker2Range = helper.getPositionRange('marker2');
const marker3Range = helper.getPositionRange('marker3');
const marker4Range = helper.getPositionRange('marker4');
// @ts-ignore
await helper.verifyCompletion('exact', 'markdown', {
marker1: { completions: [] },
marker2: {
completions: [
{
label: '"name"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker2Range, newText: '"name"' },
},
{
label: '"age"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker2Range, newText: '"age"' },
},
],
},
marker3: {
completions: [
{
label: '"hello"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker3Range, newText: '"hello"' },
},
{
label: '"hallo"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker3Range, newText: '"hallo"' },
},
],
},
marker4: {
completions: [
{
label: '"name"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker4Range, newText: '"name"' },
},
{
label: '"age"',
kind: Consts.CompletionItemKind.Constant,
textEdit: { range: marker4Range, newText: '"age"' },
},
],
},
});
}
Loaded 100 of 300 files, more files were not shown because too many files have changed in this diff. Show more