@zzzen/pyright-internal 1.2.0-dev.20250119 → 1.2.0-dev.20250202
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +1 -0
- package/dist/analyzer/backgroundAnalysisProgram.js +3 -0
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/binder.js +24 -12
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -1
- package/dist/analyzer/checker.js +29 -24
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/dataClasses.js +4 -4
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/enums.js +140 -126
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +3 -2
- package/dist/analyzer/importResolver.js +80 -79
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +1 -0
- package/dist/analyzer/parseTreeUtils.js +14 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/pythonPathUtils.d.ts +2 -0
- package/dist/analyzer/pythonPathUtils.js +20 -11
- package/dist/analyzer/pythonPathUtils.js.map +1 -1
- package/dist/analyzer/service.js +2 -5
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/tuples.d.ts +1 -0
- package/dist/analyzer/tuples.js +34 -0
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +90 -49
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.js +10 -7
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/backgroundAnalysis.js +2 -0
- package/dist/backgroundAnalysis.js.map +1 -1
- package/dist/backgroundThreadBase.d.ts +1 -0
- package/dist/backgroundThreadBase.js +5 -8
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/envVarUtils.js +4 -0
- package/dist/common/envVarUtils.js.map +1 -1
- package/dist/common/languageServerInterface.d.ts +1 -1
- package/dist/common/realFileSystem.d.ts +1 -1
- package/dist/common/realFileSystem.js +10 -2
- package/dist/common/realFileSystem.js.map +1 -1
- package/dist/common/serviceProvider.d.ts +1 -0
- package/dist/common/serviceProvider.js +8 -0
- package/dist/common/serviceProvider.js.map +1 -1
- package/dist/languageServerBase.d.ts +3 -3
- package/dist/languageServerBase.js +7 -4
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/analyzerServiceExecutor.js +4 -1
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
- package/dist/localization/localize.d.ts +4 -7
- package/dist/localization/localize.js +4 -2
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +8 -6
- package/dist/localization/package.nls.de.json +8 -6
- package/dist/localization/package.nls.en-us.json +12 -4
- package/dist/localization/package.nls.es.json +8 -6
- package/dist/localization/package.nls.fr.json +8 -6
- package/dist/localization/package.nls.it.json +8 -6
- package/dist/localization/package.nls.ja.json +8 -6
- package/dist/localization/package.nls.ko.json +8 -6
- package/dist/localization/package.nls.pl.json +8 -6
- package/dist/localization/package.nls.pt-br.json +8 -6
- package/dist/localization/package.nls.qps-ploc.json +4 -2
- package/dist/localization/package.nls.ru.json +8 -6
- package/dist/localization/package.nls.tr.json +8 -6
- package/dist/localization/package.nls.zh-cn.json +8 -6
- package/dist/localization/package.nls.zh-tw.json +8 -6
- package/dist/pyright.js +11 -4
- package/dist/pyright.js.map +1 -1
- package/dist/server.d.ts +2 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tests/config.test.js +451 -427
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/harness/fourslash/fourSlashTypes.d.ts +2 -1
- package/dist/tests/harness/fourslash/fourSlashTypes.js +2 -0
- package/dist/tests/harness/fourslash/fourSlashTypes.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.d.ts +3 -1
- package/dist/tests/harness/fourslash/testState.js +30 -23
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/importResolver.test.js +537 -527
- package/dist/tests/importResolver.test.js.map +1 -1
- package/dist/tests/sourceFile.test.js +1 -0
- package/dist/tests/sourceFile.test.js.map +1 -1
- package/dist/tests/testUtils.js +1 -0
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +1 -1
- package/dist/tests/typeEvaluator3.test.js +4 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +5 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/typeEvaluator6.test.js +4 -0
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/uri.test.js +3 -0
- package/dist/tests/uri.test.js.map +1 -1
- package/dist/tests/zipfs.test.js +2 -0
- package/dist/tests/zipfs.test.js.map +1 -1
- package/dist/workspaceFactory.d.ts +2 -1
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +1 -1
@@ -26,32 +26,235 @@ const libraryRoot = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlash
|
|
26
26
|
function usingTrueVenv() {
|
27
27
|
return process.env.CI_IMPORT_TEST_VENVPATH !== undefined || process.env.CI_IMPORT_TEST_PYTHONPATH !== undefined;
|
28
28
|
}
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
describe('Import tests with fake venv', () => {
|
30
|
+
const tempFile = new realFileSystem_1.RealTempFile();
|
31
|
+
afterAll(() => tempFile.dispose());
|
32
|
+
if (!usingTrueVenv()) {
|
33
|
+
describe('Import tests that cannot run in a true venv', () => {
|
34
|
+
test('partial stub file exists', () => {
|
35
|
+
const files = [
|
36
|
+
{
|
37
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'partialStub.pyi'),
|
38
|
+
content: 'def test(): ...',
|
39
|
+
},
|
40
|
+
{
|
41
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
42
|
+
content: 'partial\n',
|
43
|
+
},
|
44
|
+
{
|
45
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py'),
|
46
|
+
content: 'def test(): pass',
|
47
|
+
},
|
48
|
+
];
|
49
|
+
const importResult = getImportResult(files, ['myLib', 'partialStub']);
|
50
|
+
(0, assert_1.default)(importResult.isImportFound);
|
51
|
+
(0, assert_1.default)(importResult.isStubFile);
|
52
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.pyi')).length);
|
53
|
+
});
|
54
|
+
test('partial stub __init__ exists', () => {
|
55
|
+
const files = [
|
56
|
+
{
|
57
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
58
|
+
content: 'def test(): ...',
|
59
|
+
},
|
60
|
+
{
|
61
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
62
|
+
content: 'partial\n',
|
63
|
+
},
|
64
|
+
{
|
65
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
66
|
+
content: 'def test(): pass',
|
67
|
+
},
|
68
|
+
];
|
69
|
+
const importResult = getImportResult(files, ['myLib']);
|
70
|
+
(0, assert_1.default)(importResult.isImportFound);
|
71
|
+
(0, assert_1.default)(importResult.isStubFile);
|
72
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
73
|
+
});
|
74
|
+
test('stub package', () => {
|
75
|
+
const files = [
|
76
|
+
{
|
77
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'stub.pyi'),
|
78
|
+
content: '# empty',
|
79
|
+
},
|
80
|
+
{
|
81
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
82
|
+
content: '# empty',
|
83
|
+
},
|
84
|
+
{
|
85
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py'),
|
86
|
+
content: 'def test(): pass',
|
87
|
+
},
|
88
|
+
];
|
89
|
+
// If fully typed stub package exists, that wins over the real package.
|
90
|
+
const importResult = getImportResult(files, ['myLib', 'partialStub']);
|
91
|
+
(0, assert_1.default)(!importResult.isImportFound);
|
92
|
+
});
|
93
|
+
test('partial stub package in typing folder', () => {
|
94
|
+
const typingFolder = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlashes)('/'), 'typing');
|
95
|
+
const files = [
|
96
|
+
{
|
97
|
+
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib-stubs', '__init__.pyi'),
|
98
|
+
content: 'def test(): ...',
|
99
|
+
},
|
100
|
+
{
|
101
|
+
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib-stubs', 'py.typed'),
|
102
|
+
content: 'partial\n',
|
103
|
+
},
|
104
|
+
{
|
105
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
106
|
+
content: 'def test(): pass',
|
107
|
+
},
|
108
|
+
];
|
109
|
+
const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = uriUtils_1.UriEx.file(typingFolder)));
|
110
|
+
(0, assert_1.default)(importResult.isImportFound);
|
111
|
+
(0, assert_1.default)(importResult.isStubFile);
|
112
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
113
|
+
});
|
114
|
+
test('typeshed folder', () => {
|
115
|
+
const typeshedFolder = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlashes)('/'), 'ts');
|
116
|
+
const files = [
|
117
|
+
{
|
118
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
119
|
+
content: 'def test(): ...',
|
120
|
+
},
|
121
|
+
{
|
122
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
123
|
+
content: 'partial\n',
|
124
|
+
},
|
125
|
+
{
|
126
|
+
path: (0, pathUtils_1.combinePaths)(typeshedFolder, 'stubs', 'myLibPackage', 'myLib.pyi'),
|
127
|
+
content: '# empty',
|
128
|
+
},
|
129
|
+
{
|
130
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
131
|
+
content: 'def test(): pass',
|
132
|
+
},
|
133
|
+
];
|
134
|
+
// Stub packages win over typeshed.
|
135
|
+
const importResult = getImportResult(files, ['myLib'], (c) => (c.typeshedPath = uriUtils_1.UriEx.file(typeshedFolder)));
|
136
|
+
(0, assert_1.default)(importResult.isImportFound);
|
137
|
+
(0, assert_1.default)(importResult.isStubFile);
|
138
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
139
|
+
});
|
140
|
+
test('typeshed fallback folder', () => {
|
141
|
+
const files = [
|
142
|
+
{
|
143
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
144
|
+
content: 'def test(): ...',
|
145
|
+
},
|
146
|
+
{
|
147
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
148
|
+
content: 'partial\n',
|
149
|
+
},
|
150
|
+
{
|
151
|
+
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'myLibPackage', 'myLib.pyi'),
|
152
|
+
content: '# empty',
|
153
|
+
},
|
154
|
+
{
|
155
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
156
|
+
content: 'def test(): pass',
|
157
|
+
},
|
158
|
+
];
|
159
|
+
// Stub packages win over typeshed.
|
160
|
+
const importResult = getImportResult(files, ['myLib']);
|
161
|
+
(0, assert_1.default)(importResult.isImportFound);
|
162
|
+
(0, assert_1.default)(importResult.isStubFile);
|
163
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
164
|
+
});
|
165
|
+
test('py.typed file', () => {
|
166
|
+
const files = [
|
167
|
+
{
|
168
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
169
|
+
content: 'def test(): ...',
|
170
|
+
},
|
171
|
+
{
|
172
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
173
|
+
content: 'partial\n',
|
174
|
+
},
|
175
|
+
{
|
176
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
177
|
+
content: 'def test(): pass',
|
178
|
+
},
|
179
|
+
{
|
180
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'py.typed'),
|
181
|
+
content: '# typed',
|
182
|
+
},
|
183
|
+
];
|
184
|
+
// Partial stub package always overrides original package.
|
185
|
+
const importResult = getImportResult(files, ['myLib']);
|
186
|
+
(0, assert_1.default)(importResult.isImportFound);
|
187
|
+
(0, assert_1.default)(importResult.isStubFile);
|
188
|
+
});
|
189
|
+
test('py.typed library', () => {
|
190
|
+
const files = [
|
191
|
+
{
|
192
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'os', '__init__.py'),
|
193
|
+
content: 'def test(): ...',
|
194
|
+
},
|
195
|
+
{
|
196
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'os', 'py.typed'),
|
197
|
+
content: '',
|
198
|
+
},
|
199
|
+
{
|
200
|
+
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'),
|
201
|
+
content: '# empty',
|
202
|
+
},
|
203
|
+
];
|
204
|
+
const importResult = getImportResult(files, ['os']);
|
205
|
+
(0, assert_1.default)(importResult.isImportFound);
|
206
|
+
assert_1.default.strictEqual(files[0].path, importResult.resolvedUris[importResult.resolvedUris.length - 1].getFilePath());
|
207
|
+
});
|
208
|
+
test('import side by side file sub under lib folder', () => {
|
209
|
+
const files = [
|
210
|
+
{
|
211
|
+
path: (0, pathUtils_1.combinePaths)('/lib/site-packages/myLib', 'file1.py'),
|
212
|
+
content: 'def test1(): ...',
|
213
|
+
},
|
214
|
+
{
|
215
|
+
path: (0, pathUtils_1.combinePaths)('/lib/site-packages/myLib', 'file2.py'),
|
216
|
+
content: 'def test2(): ...',
|
217
|
+
},
|
218
|
+
];
|
219
|
+
const importResult = getImportResult(files, ['file1']);
|
220
|
+
(0, assert_1.default)(!importResult.isImportFound);
|
221
|
+
});
|
222
|
+
});
|
223
|
+
test('getModuleNameForImport library file', () => {
|
32
224
|
const files = [
|
33
225
|
{
|
34
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib
|
35
|
-
content: '
|
226
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'myModule', 'file1.py'),
|
227
|
+
content: '# empty',
|
36
228
|
},
|
229
|
+
];
|
230
|
+
const moduleImportInfo = getModuleNameForImport(files);
|
231
|
+
assert_1.default.strictEqual(moduleImportInfo.importType, 1 /* ImportType.ThirdParty */);
|
232
|
+
(0, assert_1.default)(!moduleImportInfo.isThirdPartyPyTypedPresent);
|
233
|
+
(0, assert_1.default)(!moduleImportInfo.isLocalTypingsFile);
|
234
|
+
});
|
235
|
+
test('getModuleNameForImport py.typed library file', () => {
|
236
|
+
const files = [
|
37
237
|
{
|
38
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib
|
39
|
-
content: '
|
238
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'py.typed'),
|
239
|
+
content: '',
|
40
240
|
},
|
41
241
|
{
|
42
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '
|
43
|
-
content: '
|
242
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'myModule', 'file1.py'),
|
243
|
+
content: '# empty',
|
44
244
|
},
|
45
245
|
];
|
46
|
-
const
|
47
|
-
|
48
|
-
(0, assert_1.default)(
|
49
|
-
|
246
|
+
const moduleImportInfo = getModuleNameForImport(files);
|
247
|
+
assert_1.default.strictEqual(moduleImportInfo.importType, 1 /* ImportType.ThirdParty */);
|
248
|
+
(0, assert_1.default)(moduleImportInfo.isThirdPartyPyTypedPresent);
|
249
|
+
(0, assert_1.default)(!moduleImportInfo.isLocalTypingsFile);
|
50
250
|
});
|
51
|
-
|
251
|
+
}
|
252
|
+
describe('Import tests that can run with or without a true venv', () => {
|
253
|
+
test('side by side files', () => {
|
254
|
+
const myFile = (0, pathUtils_1.combinePaths)('src', 'file.py');
|
52
255
|
const files = [
|
53
256
|
{
|
54
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '
|
257
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'partialStub.pyi'),
|
55
258
|
content: 'def test(): ...',
|
56
259
|
},
|
57
260
|
{
|
@@ -59,25 +262,58 @@ if (!usingTrueVenv()) {
|
|
59
262
|
content: 'partial\n',
|
60
263
|
},
|
61
264
|
{
|
62
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '
|
265
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.pyi'),
|
266
|
+
content: '# empty',
|
267
|
+
},
|
268
|
+
{
|
269
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py'),
|
63
270
|
content: 'def test(): pass',
|
64
271
|
},
|
272
|
+
{
|
273
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'partialStub2.pyi'),
|
274
|
+
content: 'def test(): ...',
|
275
|
+
},
|
276
|
+
{
|
277
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub2.py'),
|
278
|
+
content: 'def test(): pass',
|
279
|
+
},
|
280
|
+
{
|
281
|
+
path: myFile,
|
282
|
+
content: '# not used',
|
283
|
+
},
|
65
284
|
];
|
66
|
-
const
|
67
|
-
|
68
|
-
(
|
69
|
-
|
285
|
+
const sp = createServiceProviderFromFiles(files);
|
286
|
+
const configOptions = new configOptions_1.ConfigOptions(uriUtils_1.UriEx.file('/'));
|
287
|
+
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]));
|
288
|
+
// Stub package wins over original package (per PEP 561 rules).
|
289
|
+
const myUri = uriUtils_1.UriEx.file(myFile);
|
290
|
+
const sideBySideResult = importResolver.resolveImport(myUri, configOptions.findExecEnvironment(myUri), {
|
291
|
+
leadingDots: 0,
|
292
|
+
nameParts: ['myLib', 'partialStub'],
|
293
|
+
importedSymbols: new Set(),
|
294
|
+
});
|
295
|
+
(0, assert_1.default)(sideBySideResult.isImportFound);
|
296
|
+
(0, assert_1.default)(sideBySideResult.isStubFile);
|
297
|
+
const sideBySideStubFile = uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.pyi'));
|
298
|
+
assert_1.default.strictEqual(1, sideBySideResult.resolvedUris.filter((f) => f.key === sideBySideStubFile.key).length);
|
299
|
+
assert_1.default.strictEqual('def test(): ...', sp.fs().readFileSync(sideBySideStubFile, 'utf8'));
|
300
|
+
// Side by side stub doesn't completely disable partial stub.
|
301
|
+
const partialStubResult = importResolver.resolveImport(myUri, configOptions.findExecEnvironment(myUri), {
|
302
|
+
leadingDots: 0,
|
303
|
+
nameParts: ['myLib', 'partialStub2'],
|
304
|
+
importedSymbols: new Set(),
|
305
|
+
});
|
306
|
+
(0, assert_1.default)(partialStubResult.isImportFound);
|
307
|
+
(0, assert_1.default)(partialStubResult.isStubFile);
|
308
|
+
const partialStubFile = uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub2.pyi'));
|
309
|
+
assert_1.default.strictEqual(1, partialStubResult.resolvedUris.filter((f) => f.key === partialStubFile.key).length);
|
70
310
|
});
|
71
|
-
test('stub package', () => {
|
311
|
+
test('stub namespace package', () => {
|
72
312
|
const files = [
|
73
313
|
{
|
74
314
|
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'stub.pyi'),
|
75
315
|
content: '# empty',
|
76
316
|
},
|
77
|
-
{
|
78
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
79
|
-
content: '# empty',
|
80
|
-
},
|
81
317
|
{
|
82
318
|
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py'),
|
83
319
|
content: 'def test(): pass',
|
@@ -85,31 +321,37 @@ if (!usingTrueVenv()) {
|
|
85
321
|
];
|
86
322
|
// If fully typed stub package exists, that wins over the real package.
|
87
323
|
const importResult = getImportResult(files, ['myLib', 'partialStub']);
|
88
|
-
(0, assert_1.default)(
|
324
|
+
(0, assert_1.default)(importResult.isImportFound);
|
325
|
+
(0, assert_1.default)(!importResult.isStubFile);
|
326
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py')).length);
|
89
327
|
});
|
90
|
-
test('
|
328
|
+
test('py.typed namespace package plus stubs', () => {
|
91
329
|
const typingFolder = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlashes)('/'), 'typing');
|
92
330
|
const files = [
|
93
331
|
{
|
94
|
-
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib
|
95
|
-
content: 'def test():
|
332
|
+
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib/core', 'foo.pyi'),
|
333
|
+
content: 'def test(): pass',
|
96
334
|
},
|
97
335
|
{
|
98
|
-
path: (0, pathUtils_1.combinePaths)(
|
99
|
-
content: '
|
336
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'py.typed'),
|
337
|
+
content: '',
|
100
338
|
},
|
101
339
|
{
|
102
340
|
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
103
341
|
content: 'def test(): pass',
|
104
342
|
},
|
343
|
+
{
|
344
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi'),
|
345
|
+
content: 'def test(): pass',
|
346
|
+
},
|
105
347
|
];
|
106
348
|
const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = uriUtils_1.UriEx.file(typingFolder)));
|
107
349
|
(0, assert_1.default)(importResult.isImportFound);
|
108
350
|
(0, assert_1.default)(importResult.isStubFile);
|
109
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
351
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
110
352
|
});
|
111
|
-
test('
|
112
|
-
const
|
353
|
+
test('stub in typing folder over partial stub package', () => {
|
354
|
+
const typingFolder = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlashes)('/'), 'typing');
|
113
355
|
const files = [
|
114
356
|
{
|
115
357
|
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
@@ -120,7 +362,7 @@ if (!usingTrueVenv()) {
|
|
120
362
|
content: 'partial\n',
|
121
363
|
},
|
122
364
|
{
|
123
|
-
path: (0, pathUtils_1.combinePaths)(
|
365
|
+
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib.pyi'),
|
124
366
|
content: '# empty',
|
125
367
|
},
|
126
368
|
{
|
@@ -128,561 +370,329 @@ if (!usingTrueVenv()) {
|
|
128
370
|
content: 'def test(): pass',
|
129
371
|
},
|
130
372
|
];
|
131
|
-
//
|
132
|
-
const importResult = getImportResult(files, ['myLib'], (c) => (c.
|
373
|
+
// If the package exists in typing folder, that gets picked up first.
|
374
|
+
const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = uriUtils_1.UriEx.file(typingFolder)));
|
133
375
|
(0, assert_1.default)(importResult.isImportFound);
|
134
376
|
(0, assert_1.default)(importResult.isStubFile);
|
135
|
-
assert_1.default.strictEqual(
|
377
|
+
assert_1.default.strictEqual(0, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
136
378
|
});
|
137
|
-
test('
|
379
|
+
test('non py.typed library', () => {
|
138
380
|
const files = [
|
139
381
|
{
|
140
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, '
|
382
|
+
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'os', '__init__.py'),
|
141
383
|
content: 'def test(): ...',
|
142
384
|
},
|
143
385
|
{
|
144
|
-
path: (0, pathUtils_1.combinePaths)(
|
145
|
-
content: '
|
386
|
+
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'),
|
387
|
+
content: '# empty',
|
146
388
|
},
|
389
|
+
];
|
390
|
+
const importResult = getImportResult(files, ['os']);
|
391
|
+
(0, assert_1.default)(importResult.isImportFound);
|
392
|
+
assert_1.default.strictEqual(files[1].path, importResult.resolvedUris[importResult.resolvedUris.length - 1].getFilePath());
|
393
|
+
});
|
394
|
+
test('no empty import roots', () => {
|
395
|
+
const sp = createServiceProviderFromFiles([]);
|
396
|
+
const configOptions = new configOptions_1.ConfigOptions(uri_1.Uri.empty()); // Empty, like open-file mode.
|
397
|
+
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]));
|
398
|
+
importResolver.getImportRoots(configOptions.getDefaultExecEnvironment()).forEach((path) => (0, assert_1.default)(path));
|
399
|
+
});
|
400
|
+
test('multiple typeshedFallback', () => {
|
401
|
+
const files = [
|
147
402
|
{
|
148
|
-
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', '
|
403
|
+
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'aLib', 'aLib', '__init__.pyi'),
|
149
404
|
content: '# empty',
|
150
405
|
},
|
151
406
|
{
|
152
|
-
path: (0, pathUtils_1.combinePaths)(
|
153
|
-
content: '
|
407
|
+
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'bLib', 'bLib', '__init__.pyi'),
|
408
|
+
content: '# empty',
|
154
409
|
},
|
155
410
|
];
|
156
|
-
|
157
|
-
const
|
158
|
-
(
|
159
|
-
|
160
|
-
assert_1.default.strictEqual(1,
|
411
|
+
const sp = createServiceProviderFromFiles(files);
|
412
|
+
const configOptions = new configOptions_1.ConfigOptions(uri_1.Uri.empty()); // Empty, like open-file mode.
|
413
|
+
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]));
|
414
|
+
const importRoots = importResolver.getImportRoots(configOptions.getDefaultExecEnvironment());
|
415
|
+
assert_1.default.strictEqual(1, importRoots.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'aLib')).length);
|
416
|
+
assert_1.default.strictEqual(1, importRoots.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'bLib')).length);
|
161
417
|
});
|
162
|
-
test('
|
418
|
+
test('import side by side file root', () => {
|
163
419
|
const files = [
|
164
420
|
{
|
165
|
-
path: (0, pathUtils_1.combinePaths)(
|
166
|
-
content: 'def
|
421
|
+
path: (0, pathUtils_1.combinePaths)('/', 'file1.py'),
|
422
|
+
content: 'def test1(): ...',
|
167
423
|
},
|
168
424
|
{
|
169
|
-
path: (0, pathUtils_1.combinePaths)(
|
170
|
-
content: '
|
425
|
+
path: (0, pathUtils_1.combinePaths)('/', 'file2.py'),
|
426
|
+
content: 'def test2(): ...',
|
171
427
|
},
|
428
|
+
];
|
429
|
+
const importResult = getImportResult(files, ['file1']);
|
430
|
+
(0, assert_1.default)(importResult.isImportFound);
|
431
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/', 'file1.py')).length);
|
432
|
+
});
|
433
|
+
test('import side by side file sub folder', () => {
|
434
|
+
const files = [
|
172
435
|
{
|
173
|
-
path: (0, pathUtils_1.combinePaths)(
|
174
|
-
content: 'def
|
436
|
+
path: (0, pathUtils_1.combinePaths)('/test', 'file1.py'),
|
437
|
+
content: 'def test1(): ...',
|
175
438
|
},
|
176
439
|
{
|
177
|
-
path: (0, pathUtils_1.combinePaths)(
|
178
|
-
content: '
|
440
|
+
path: (0, pathUtils_1.combinePaths)('/test', 'file2.py'),
|
441
|
+
content: 'def test2(): ...',
|
179
442
|
},
|
180
443
|
];
|
181
|
-
|
182
|
-
const importResult = getImportResult(files, ['myLib']);
|
444
|
+
const importResult = getImportResult(files, ['file1']);
|
183
445
|
(0, assert_1.default)(importResult.isImportFound);
|
184
|
-
(0,
|
446
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/test', 'file1.py')).length);
|
185
447
|
});
|
186
|
-
test('
|
448
|
+
test('import side by side file sub under src folder', () => {
|
187
449
|
const files = [
|
188
450
|
{
|
189
|
-
path: (0, pathUtils_1.combinePaths)(
|
190
|
-
content: 'def
|
191
|
-
},
|
192
|
-
{
|
193
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'os', 'py.typed'),
|
194
|
-
content: '',
|
451
|
+
path: (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py'),
|
452
|
+
content: 'def test1(): ...',
|
195
453
|
},
|
196
454
|
{
|
197
|
-
path: (0, pathUtils_1.combinePaths)('/',
|
198
|
-
content: '
|
455
|
+
path: (0, pathUtils_1.combinePaths)('/src/nested', 'file2.py'),
|
456
|
+
content: 'def test2(): ...',
|
199
457
|
},
|
200
458
|
];
|
201
|
-
const importResult = getImportResult(files, ['
|
459
|
+
const importResult = getImportResult(files, ['file1']);
|
202
460
|
(0, assert_1.default)(importResult.isImportFound);
|
203
|
-
assert_1.default.strictEqual(
|
461
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py'))
|
462
|
+
.length);
|
204
463
|
});
|
205
|
-
test('import
|
464
|
+
test('import file sub under containing folder', () => {
|
206
465
|
const files = [
|
207
466
|
{
|
208
|
-
path: (0, pathUtils_1.combinePaths)('/
|
467
|
+
path: (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py'),
|
209
468
|
content: 'def test1(): ...',
|
210
469
|
},
|
211
470
|
{
|
212
|
-
path: (0, pathUtils_1.combinePaths)('/
|
471
|
+
path: (0, pathUtils_1.combinePaths)('/src/nested/nested2', 'file2.py'),
|
213
472
|
content: 'def test2(): ...',
|
214
473
|
},
|
215
474
|
];
|
216
475
|
const importResult = getImportResult(files, ['file1']);
|
217
|
-
(0, assert_1.default)(
|
218
|
-
|
219
|
-
|
220
|
-
test('getModuleNameForImport library file', () => {
|
221
|
-
const files = [
|
222
|
-
{
|
223
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'myModule', 'file1.py'),
|
224
|
-
content: '# empty',
|
225
|
-
},
|
226
|
-
];
|
227
|
-
const moduleImportInfo = getModuleNameForImport(files);
|
228
|
-
assert_1.default.strictEqual(moduleImportInfo.importType, 1 /* ImportType.ThirdParty */);
|
229
|
-
(0, assert_1.default)(!moduleImportInfo.isThirdPartyPyTypedPresent);
|
230
|
-
(0, assert_1.default)(!moduleImportInfo.isLocalTypingsFile);
|
231
|
-
});
|
232
|
-
test('getModuleNameForImport py.typed library file', () => {
|
233
|
-
const files = [
|
234
|
-
{
|
235
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'py.typed'),
|
236
|
-
content: '',
|
237
|
-
},
|
238
|
-
{
|
239
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'myModule', 'file1.py'),
|
240
|
-
content: '# empty',
|
241
|
-
},
|
242
|
-
];
|
243
|
-
const moduleImportInfo = getModuleNameForImport(files);
|
244
|
-
assert_1.default.strictEqual(moduleImportInfo.importType, 1 /* ImportType.ThirdParty */);
|
245
|
-
(0, assert_1.default)(moduleImportInfo.isThirdPartyPyTypedPresent);
|
246
|
-
(0, assert_1.default)(!moduleImportInfo.isLocalTypingsFile);
|
247
|
-
});
|
248
|
-
}
|
249
|
-
describe('Import tests that can run with or without a true venv', () => {
|
250
|
-
test('side by side files', () => {
|
251
|
-
const myFile = (0, pathUtils_1.combinePaths)('src', 'file.py');
|
252
|
-
const files = [
|
253
|
-
{
|
254
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'partialStub.pyi'),
|
255
|
-
content: 'def test(): ...',
|
256
|
-
},
|
257
|
-
{
|
258
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
259
|
-
content: 'partial\n',
|
260
|
-
},
|
261
|
-
{
|
262
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.pyi'),
|
263
|
-
content: '# empty',
|
264
|
-
},
|
265
|
-
{
|
266
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py'),
|
267
|
-
content: 'def test(): pass',
|
268
|
-
},
|
269
|
-
{
|
270
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'partialStub2.pyi'),
|
271
|
-
content: 'def test(): ...',
|
272
|
-
},
|
273
|
-
{
|
274
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub2.py'),
|
275
|
-
content: 'def test(): pass',
|
276
|
-
},
|
277
|
-
{
|
278
|
-
path: myFile,
|
279
|
-
content: '# not used',
|
280
|
-
},
|
281
|
-
];
|
282
|
-
const sp = createServiceProviderFromFiles(files);
|
283
|
-
const configOptions = new configOptions_1.ConfigOptions(uriUtils_1.UriEx.file('/'));
|
284
|
-
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]));
|
285
|
-
// Stub package wins over original package (per PEP 561 rules).
|
286
|
-
const myUri = uriUtils_1.UriEx.file(myFile);
|
287
|
-
const sideBySideResult = importResolver.resolveImport(myUri, configOptions.findExecEnvironment(myUri), {
|
288
|
-
leadingDots: 0,
|
289
|
-
nameParts: ['myLib', 'partialStub'],
|
290
|
-
importedSymbols: new Set(),
|
476
|
+
(0, assert_1.default)(importResult.isImportFound);
|
477
|
+
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py'))
|
478
|
+
.length);
|
291
479
|
});
|
292
|
-
(
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
importedSymbols: new Set(),
|
480
|
+
test("don't walk up the root", () => {
|
481
|
+
const files = [
|
482
|
+
{
|
483
|
+
path: (0, pathUtils_1.combinePaths)('/', 'file1.py'),
|
484
|
+
content: 'def test1(): ...',
|
485
|
+
},
|
486
|
+
];
|
487
|
+
const importResult = getImportResult(files, ['notExist'], (c) => (c.projectRoot = uri_1.Uri.empty()));
|
488
|
+
(0, assert_1.default)(!importResult.isImportFound);
|
302
489
|
});
|
303
|
-
(
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
},
|
318
|
-
];
|
319
|
-
// If fully typed stub package exists, that wins over the real package.
|
320
|
-
const importResult = getImportResult(files, ['myLib', 'partialStub']);
|
321
|
-
(0, assert_1.default)(importResult.isImportFound);
|
322
|
-
(0, assert_1.default)(!importResult.isStubFile);
|
323
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'partialStub.py')).length);
|
324
|
-
});
|
325
|
-
test('py.typed namespace package plus stubs', () => {
|
326
|
-
const typingFolder = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlashes)('/'), 'typing');
|
327
|
-
const files = [
|
328
|
-
{
|
329
|
-
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib/core', 'foo.pyi'),
|
330
|
-
content: 'def test(): pass',
|
331
|
-
},
|
332
|
-
{
|
333
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', 'py.typed'),
|
334
|
-
content: '',
|
335
|
-
},
|
336
|
-
{
|
337
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
338
|
-
content: 'def test(): pass',
|
339
|
-
},
|
340
|
-
{
|
341
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi'),
|
342
|
-
content: 'def test(): pass',
|
343
|
-
},
|
344
|
-
];
|
345
|
-
const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = uriUtils_1.UriEx.file(typingFolder)));
|
346
|
-
(0, assert_1.default)(importResult.isImportFound);
|
347
|
-
(0, assert_1.default)(importResult.isStubFile);
|
348
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
349
|
-
});
|
350
|
-
test('stub in typing folder over partial stub package', () => {
|
351
|
-
const typingFolder = (0, pathUtils_1.combinePaths)((0, pathUtils_1.normalizeSlashes)('/'), 'typing');
|
352
|
-
const files = [
|
353
|
-
{
|
354
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', '__init__.pyi'),
|
355
|
-
content: 'def test(): ...',
|
356
|
-
},
|
357
|
-
{
|
358
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib-stubs', 'py.typed'),
|
359
|
-
content: 'partial\n',
|
360
|
-
},
|
361
|
-
{
|
362
|
-
path: (0, pathUtils_1.combinePaths)(typingFolder, 'myLib.pyi'),
|
363
|
-
content: '# empty',
|
364
|
-
},
|
365
|
-
{
|
366
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.py'),
|
367
|
-
content: 'def test(): pass',
|
368
|
-
},
|
369
|
-
];
|
370
|
-
// If the package exists in typing folder, that gets picked up first.
|
371
|
-
const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = uriUtils_1.UriEx.file(typingFolder)));
|
372
|
-
(0, assert_1.default)(importResult.isImportFound);
|
373
|
-
(0, assert_1.default)(importResult.isStubFile);
|
374
|
-
assert_1.default.strictEqual(0, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)(libraryRoot, 'myLib', '__init__.pyi')).length);
|
375
|
-
});
|
376
|
-
test('non py.typed library', () => {
|
377
|
-
const files = [
|
378
|
-
{
|
379
|
-
path: (0, pathUtils_1.combinePaths)(libraryRoot, 'os', '__init__.py'),
|
380
|
-
content: 'def test(): ...',
|
381
|
-
},
|
382
|
-
{
|
383
|
-
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'),
|
384
|
-
content: '# empty',
|
385
|
-
},
|
386
|
-
];
|
387
|
-
const importResult = getImportResult(files, ['os']);
|
388
|
-
(0, assert_1.default)(importResult.isImportFound);
|
389
|
-
assert_1.default.strictEqual(files[1].path, importResult.resolvedUris[importResult.resolvedUris.length - 1].getFilePath());
|
390
|
-
});
|
391
|
-
test('no empty import roots', () => {
|
392
|
-
const sp = createServiceProviderFromFiles([]);
|
393
|
-
const configOptions = new configOptions_1.ConfigOptions(uri_1.Uri.empty()); // Empty, like open-file mode.
|
394
|
-
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]));
|
395
|
-
importResolver.getImportRoots(configOptions.getDefaultExecEnvironment()).forEach((path) => (0, assert_1.default)(path));
|
396
|
-
});
|
397
|
-
test('multiple typeshedFallback', () => {
|
398
|
-
const files = [
|
399
|
-
{
|
400
|
-
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'aLib', 'aLib', '__init__.pyi'),
|
401
|
-
content: '# empty',
|
402
|
-
},
|
403
|
-
{
|
404
|
-
path: (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'bLib', 'bLib', '__init__.pyi'),
|
405
|
-
content: '# empty',
|
406
|
-
},
|
407
|
-
];
|
408
|
-
const sp = createServiceProviderFromFiles(files);
|
409
|
-
const configOptions = new configOptions_1.ConfigOptions(uri_1.Uri.empty()); // Empty, like open-file mode.
|
410
|
-
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]));
|
411
|
-
const importRoots = importResolver.getImportRoots(configOptions.getDefaultExecEnvironment());
|
412
|
-
assert_1.default.strictEqual(1, importRoots.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'aLib')).length);
|
413
|
-
assert_1.default.strictEqual(1, importRoots.filter((f) => !f.isEmpty() && f.getFilePath() === (0, pathUtils_1.combinePaths)('/', pathConsts_1.typeshedFallback, 'stubs', 'bLib')).length);
|
414
|
-
});
|
415
|
-
test('import side by side file root', () => {
|
416
|
-
const files = [
|
417
|
-
{
|
418
|
-
path: (0, pathUtils_1.combinePaths)('/', 'file1.py'),
|
419
|
-
content: 'def test1(): ...',
|
420
|
-
},
|
421
|
-
{
|
422
|
-
path: (0, pathUtils_1.combinePaths)('/', 'file2.py'),
|
423
|
-
content: 'def test2(): ...',
|
424
|
-
},
|
425
|
-
];
|
426
|
-
const importResult = getImportResult(files, ['file1']);
|
427
|
-
(0, assert_1.default)(importResult.isImportFound);
|
428
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/', 'file1.py')).length);
|
429
|
-
});
|
430
|
-
test('import side by side file sub folder', () => {
|
431
|
-
const files = [
|
432
|
-
{
|
433
|
-
path: (0, pathUtils_1.combinePaths)('/test', 'file1.py'),
|
434
|
-
content: 'def test1(): ...',
|
435
|
-
},
|
436
|
-
{
|
437
|
-
path: (0, pathUtils_1.combinePaths)('/test', 'file2.py'),
|
438
|
-
content: 'def test2(): ...',
|
439
|
-
},
|
440
|
-
];
|
441
|
-
const importResult = getImportResult(files, ['file1']);
|
442
|
-
(0, assert_1.default)(importResult.isImportFound);
|
443
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/test', 'file1.py')).length);
|
444
|
-
});
|
445
|
-
test('import side by side file sub under src folder', () => {
|
446
|
-
const files = [
|
447
|
-
{
|
448
|
-
path: (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py'),
|
449
|
-
content: 'def test1(): ...',
|
450
|
-
},
|
451
|
-
{
|
452
|
-
path: (0, pathUtils_1.combinePaths)('/src/nested', 'file2.py'),
|
453
|
-
content: 'def test2(): ...',
|
454
|
-
},
|
455
|
-
];
|
456
|
-
const importResult = getImportResult(files, ['file1']);
|
457
|
-
(0, assert_1.default)(importResult.isImportFound);
|
458
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py')).length);
|
459
|
-
});
|
460
|
-
test('import file sub under containing folder', () => {
|
461
|
-
const files = [
|
462
|
-
{
|
463
|
-
path: (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py'),
|
464
|
-
content: 'def test1(): ...',
|
465
|
-
},
|
466
|
-
{
|
467
|
-
path: (0, pathUtils_1.combinePaths)('/src/nested/nested2', 'file2.py'),
|
468
|
-
content: 'def test2(): ...',
|
469
|
-
},
|
470
|
-
];
|
471
|
-
const importResult = getImportResult(files, ['file1']);
|
472
|
-
(0, assert_1.default)(importResult.isImportFound);
|
473
|
-
assert_1.default.strictEqual(1, importResult.resolvedUris.filter((f) => f.getFilePath() === (0, pathUtils_1.combinePaths)('/src/nested', 'file1.py')).length);
|
474
|
-
});
|
475
|
-
test("don't walk up the root", () => {
|
476
|
-
const files = [
|
477
|
-
{
|
478
|
-
path: (0, pathUtils_1.combinePaths)('/', 'file1.py'),
|
479
|
-
content: 'def test1(): ...',
|
480
|
-
},
|
481
|
-
];
|
482
|
-
const importResult = getImportResult(files, ['notExist'], (c) => (c.projectRoot = uri_1.Uri.empty()));
|
483
|
-
(0, assert_1.default)(!importResult.isImportFound);
|
484
|
-
});
|
485
|
-
test('nested namespace package 1', () => {
|
486
|
-
const files = [
|
487
|
-
{
|
488
|
-
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', 'c', 'd.py'),
|
489
|
-
content: 'def f(): pass',
|
490
|
-
},
|
491
|
-
{
|
492
|
-
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', '__init__.py'),
|
493
|
-
content: '',
|
494
|
-
},
|
495
|
-
{
|
496
|
-
path: (0, pathUtils_1.combinePaths)('/', 'packages2', 'a', '__init__.py'),
|
497
|
-
content: '',
|
498
|
-
},
|
499
|
-
];
|
500
|
-
const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => {
|
501
|
-
config.defaultExtraPaths = [
|
502
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
503
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
490
|
+
test('nested namespace package 1', () => {
|
491
|
+
const files = [
|
492
|
+
{
|
493
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', 'c', 'd.py'),
|
494
|
+
content: 'def f(): pass',
|
495
|
+
},
|
496
|
+
{
|
497
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', '__init__.py'),
|
498
|
+
content: '',
|
499
|
+
},
|
500
|
+
{
|
501
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages2', 'a', '__init__.py'),
|
502
|
+
content: '',
|
503
|
+
},
|
504
504
|
];
|
505
|
+
const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => {
|
506
|
+
config.defaultExtraPaths = [
|
507
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
508
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
509
|
+
];
|
510
|
+
});
|
511
|
+
(0, assert_1.default)(importResult.isImportFound);
|
505
512
|
});
|
506
|
-
(
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
content: '',
|
521
|
-
},
|
522
|
-
];
|
523
|
-
const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => {
|
524
|
-
config.defaultExtraPaths = [
|
525
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
526
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
513
|
+
test('nested namespace package 2', () => {
|
514
|
+
const files = [
|
515
|
+
{
|
516
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', 'c', 'd.py'),
|
517
|
+
content: 'def f(): pass',
|
518
|
+
},
|
519
|
+
{
|
520
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', 'c', '__init__.py'),
|
521
|
+
content: '',
|
522
|
+
},
|
523
|
+
{
|
524
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages2', 'a', 'b', 'c', '__init__.py'),
|
525
|
+
content: '',
|
526
|
+
},
|
527
527
|
];
|
528
|
+
const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => {
|
529
|
+
config.defaultExtraPaths = [
|
530
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
531
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
532
|
+
];
|
533
|
+
});
|
534
|
+
(0, assert_1.default)(importResult.isImportFound);
|
528
535
|
});
|
529
|
-
(
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
content: '',
|
540
|
-
},
|
541
|
-
];
|
542
|
-
const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => {
|
543
|
-
config.defaultExtraPaths = [
|
544
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
545
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
536
|
+
test('nested namespace package 3', () => {
|
537
|
+
const files = [
|
538
|
+
{
|
539
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', 'c', 'd.py'),
|
540
|
+
content: 'def f(): pass',
|
541
|
+
},
|
542
|
+
{
|
543
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages2', 'a', '__init__.py'),
|
544
|
+
content: '',
|
545
|
+
},
|
546
546
|
];
|
547
|
+
const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => {
|
548
|
+
config.defaultExtraPaths = [
|
549
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
550
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
551
|
+
];
|
552
|
+
});
|
553
|
+
(0, assert_1.default)(!importResult.isImportFound);
|
547
554
|
});
|
548
|
-
(
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
content: '',
|
567
|
-
},
|
568
|
-
];
|
569
|
-
const importResult = getImportResult(files, ['a', 'b', 'c'], (config) => {
|
570
|
-
config.defaultExtraPaths = [
|
571
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
572
|
-
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
555
|
+
test('nested namespace package 4', () => {
|
556
|
+
const files = [
|
557
|
+
{
|
558
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', '__init__.py'),
|
559
|
+
content: '',
|
560
|
+
},
|
561
|
+
{
|
562
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages1', 'a', 'b', 'c.py'),
|
563
|
+
content: 'def f(): pass',
|
564
|
+
},
|
565
|
+
{
|
566
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages2', 'a', '__init__.py'),
|
567
|
+
content: '',
|
568
|
+
},
|
569
|
+
{
|
570
|
+
path: (0, pathUtils_1.combinePaths)('/', 'packages2', 'a', 'b', '__init__.py'),
|
571
|
+
content: '',
|
572
|
+
},
|
573
573
|
];
|
574
|
+
const importResult = getImportResult(files, ['a', 'b', 'c'], (config) => {
|
575
|
+
config.defaultExtraPaths = [
|
576
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages1')),
|
577
|
+
uriUtils_1.UriEx.file((0, pathUtils_1.combinePaths)('/', 'packages2')),
|
578
|
+
];
|
579
|
+
});
|
580
|
+
(0, assert_1.default)(!importResult.isImportFound);
|
574
581
|
});
|
575
|
-
(
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
582
|
+
test('default workspace importing side by side file', () => {
|
583
|
+
const files = [
|
584
|
+
{
|
585
|
+
path: (0, pathUtils_1.combinePaths)('/', 'src', 'a', 'b', 'file1.py'),
|
586
|
+
content: 'import file2',
|
587
|
+
},
|
588
|
+
{
|
589
|
+
path: (0, pathUtils_1.combinePaths)('/', 'src', 'a', 'b', 'file2.py'),
|
590
|
+
content: 'def f(): pass',
|
591
|
+
},
|
592
|
+
];
|
593
|
+
const importResult = getImportResult(files, ['file2'], (config) => {
|
594
|
+
config.projectRoot = uri_1.Uri.defaultWorkspace({ isCaseSensitive: () => true });
|
595
|
+
});
|
596
|
+
(0, assert_1.default)(importResult.isImportFound);
|
590
597
|
});
|
591
|
-
(
|
592
|
-
});
|
593
|
-
test('getModuleNameForImport user file', () => {
|
594
|
-
const files = [
|
595
|
-
{
|
596
|
-
path: (0, pathUtils_1.combinePaths)('/', 'src', 'file1.py'),
|
597
|
-
content: '# empty',
|
598
|
-
},
|
599
|
-
];
|
600
|
-
const moduleImportInfo = getModuleNameForImport(files);
|
601
|
-
assert_1.default.strictEqual(moduleImportInfo.importType, 2 /* ImportType.Local */);
|
602
|
-
(0, assert_1.default)(!moduleImportInfo.isThirdPartyPyTypedPresent);
|
603
|
-
(0, assert_1.default)(!moduleImportInfo.isLocalTypingsFile);
|
604
|
-
});
|
605
|
-
});
|
606
|
-
if (usingTrueVenv()) {
|
607
|
-
describe('Import tests that have to run with a venv', () => {
|
608
|
-
test('venv can find imports', () => {
|
598
|
+
test('getModuleNameForImport user file', () => {
|
609
599
|
const files = [
|
610
600
|
{
|
611
|
-
path: (0, pathUtils_1.combinePaths)('/', 'file1.py'),
|
612
|
-
content: '
|
601
|
+
path: (0, pathUtils_1.combinePaths)('/', 'src', 'file1.py'),
|
602
|
+
content: '# empty',
|
613
603
|
},
|
614
604
|
];
|
615
|
-
const
|
616
|
-
|
605
|
+
const moduleImportInfo = getModuleNameForImport(files);
|
606
|
+
assert_1.default.strictEqual(moduleImportInfo.importType, 2 /* ImportType.Local */);
|
607
|
+
(0, assert_1.default)(!moduleImportInfo.isThirdPartyPyTypedPresent);
|
608
|
+
(0, assert_1.default)(!moduleImportInfo.isLocalTypingsFile);
|
617
609
|
});
|
618
610
|
});
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
611
|
+
if (usingTrueVenv()) {
|
612
|
+
describe('Import tests that have to run with a venv', () => {
|
613
|
+
test('venv can find imports', () => {
|
614
|
+
const tempFile = new realFileSystem_1.RealTempFile();
|
615
|
+
const files = [
|
616
|
+
{
|
617
|
+
path: (0, pathUtils_1.combinePaths)('/', 'file1.py'),
|
618
|
+
content: 'import pytest',
|
619
|
+
},
|
620
|
+
];
|
621
|
+
const importResult = getImportResult(files, ['pytest']);
|
622
|
+
(0, assert_1.default)(importResult.isImportFound, `Import not found: ${importResult.importFailureInfo?.join('\n')}`);
|
623
|
+
tempFile.dispose();
|
624
|
+
});
|
625
|
+
});
|
631
626
|
}
|
632
|
-
|
633
|
-
}
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
return moduleImportInfo;
|
639
|
-
}
|
640
|
-
function setupImportResolver(files, setup) {
|
641
|
-
const defaultHostFactory = (sp) => new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]);
|
642
|
-
const defaultSetup = setup ??
|
643
|
-
((c) => {
|
644
|
-
/* empty */
|
627
|
+
function getImportResult(files, nameParts, setup) {
|
628
|
+
const { importResolver, uri, configOptions } = setupImportResolver(files, setup);
|
629
|
+
const importResult = importResolver.resolveImport(uri, configOptions.findExecEnvironment(uri), {
|
630
|
+
leadingDots: 0,
|
631
|
+
nameParts: nameParts,
|
632
|
+
importedSymbols: new Set(),
|
645
633
|
});
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
if (process.env.CI_IMPORT_TEST_VENVPATH) {
|
653
|
-
configModifier = (c) => {
|
654
|
-
defaultSetup(c);
|
655
|
-
c.venvPath = uriUtils_1.UriEx.file(process.env.CI_IMPORT_TEST_VENVPATH,
|
656
|
-
/* isCaseSensitive */ true,
|
657
|
-
/* checkRelative */ true);
|
658
|
-
c.venv = process.env.CI_IMPORT_TEST_VENV;
|
659
|
-
};
|
660
|
-
spFactory = (files) => createServiceProviderWithCombinedFs(files);
|
634
|
+
// Add the config venvpath to the import result so we can output it on failure.
|
635
|
+
if (!importResult.isImportFound) {
|
636
|
+
importResult.importFailureInfo = importResult.importFailureInfo ?? [];
|
637
|
+
importResult.importFailureInfo.push(`venvPath: ${configOptions.venvPath}`);
|
638
|
+
}
|
639
|
+
return importResult;
|
661
640
|
}
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
/* checkRelative */ true);
|
668
|
-
};
|
669
|
-
hostFactory = (sp) => new TruePythonTestAccessHost(sp);
|
670
|
-
spFactory = (files) => createServiceProviderWithCombinedFs(files);
|
641
|
+
function getModuleNameForImport(files, setup) {
|
642
|
+
const { importResolver, uri, configOptions } = setupImportResolver(files, setup);
|
643
|
+
const moduleImportInfo = importResolver.getModuleNameForImport(uri, configOptions.findExecEnvironment(uri), undefined,
|
644
|
+
/* detectPyTyped */ true);
|
645
|
+
return moduleImportInfo;
|
671
646
|
}
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
647
|
+
function setupImportResolver(files, setup) {
|
648
|
+
const defaultHostFactory = (sp) => new testAccessHost_1.TestAccessHost(sp.fs().getModulePath(), [uriUtils_1.UriEx.file(libraryRoot)]);
|
649
|
+
const defaultSetup = setup ??
|
650
|
+
((c) => {
|
651
|
+
/* empty */
|
652
|
+
});
|
653
|
+
const defaultSpFactory = (files) => createServiceProviderFromFiles(files);
|
654
|
+
// Use environment variables to determine how to create a host and how to modify the config options.
|
655
|
+
// These are set in the CI to test imports with different options.
|
656
|
+
let hostFactory = defaultHostFactory;
|
657
|
+
let configModifier = defaultSetup;
|
658
|
+
let spFactory = defaultSpFactory;
|
659
|
+
if (process.env.CI_IMPORT_TEST_VENVPATH) {
|
660
|
+
configModifier = (c) => {
|
661
|
+
defaultSetup(c);
|
662
|
+
c.venvPath = uriUtils_1.UriEx.file(process.env.CI_IMPORT_TEST_VENVPATH,
|
663
|
+
/* isCaseSensitive */ true,
|
664
|
+
/* checkRelative */ true);
|
665
|
+
c.venv = process.env.CI_IMPORT_TEST_VENV;
|
666
|
+
};
|
667
|
+
spFactory = (files) => createServiceProviderWithCombinedFs(files);
|
668
|
+
}
|
669
|
+
else if (process.env.CI_IMPORT_TEST_PYTHONPATH) {
|
670
|
+
configModifier = (c) => {
|
671
|
+
defaultSetup(c);
|
672
|
+
c.pythonPath = uriUtils_1.UriEx.file(process.env.CI_IMPORT_TEST_PYTHONPATH,
|
673
|
+
/* isCaseSensitive */ true,
|
674
|
+
/* checkRelative */ true);
|
675
|
+
};
|
676
|
+
hostFactory = (sp) => {
|
677
|
+
return new TruePythonTestAccessHost(sp, tempFile);
|
678
|
+
};
|
679
|
+
spFactory = (files) => createServiceProviderWithCombinedFs(files);
|
680
|
+
}
|
681
|
+
const sp = spFactory(files);
|
682
|
+
const configOptions = new configOptions_1.ConfigOptions(uriUtils_1.UriEx.file('/'));
|
683
|
+
configModifier(configOptions);
|
684
|
+
const file = files.length > 0 ? files[files.length - 1].path : (0, pathUtils_1.combinePaths)('src', 'file.py');
|
685
|
+
if (files.length === 0) {
|
686
|
+
files.push({
|
687
|
+
path: file,
|
688
|
+
content: '# not used',
|
689
|
+
});
|
690
|
+
}
|
691
|
+
const uri = uriUtils_1.UriEx.file(file);
|
692
|
+
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, hostFactory(sp));
|
693
|
+
return { importResolver, uri, configOptions };
|
681
694
|
}
|
682
|
-
|
683
|
-
const importResolver = new importResolver_1.ImportResolver(sp, configOptions, hostFactory(sp));
|
684
|
-
return { importResolver, uri, configOptions };
|
685
|
-
}
|
695
|
+
});
|
686
696
|
function createTestFileSystem(files) {
|
687
697
|
const fs = new filesystem_1.TestFileSystem(/* ignoreCase */ false, { cwd: (0, pathUtils_1.normalizeSlashes)('/') });
|
688
698
|
for (const file of files) {
|
@@ -704,11 +714,11 @@ function createServiceProviderWithCombinedFs(files) {
|
|
704
714
|
return (0, serviceProviderExtensions_1.createServiceProvider)(testFS, fs);
|
705
715
|
}
|
706
716
|
class TruePythonTestAccessHost extends fullAccessHost_1.FullAccessHost {
|
707
|
-
constructor(sp) {
|
708
|
-
// Make sure the service provide in use is using a real file system and real temporary file provider.
|
717
|
+
constructor(sp, tempFile) {
|
709
718
|
const clone = sp.clone();
|
710
|
-
|
711
|
-
clone.add(serviceKeys_1.ServiceKeys.tempFile,
|
719
|
+
// Make sure the service provide in use is using a real file system and real temporary file provider.
|
720
|
+
clone.add(serviceKeys_1.ServiceKeys.tempFile, tempFile);
|
721
|
+
clone.add(serviceKeys_1.ServiceKeys.fs, (0, realFileSystem_1.createFromRealFileSystem)(tempFile));
|
712
722
|
super(clone);
|
713
723
|
}
|
714
724
|
}
|