@@ -8,11 +8,9 @@ import * as fs from 'fs';
8
8
import * as fsExtra from 'fs-extra' ;
9
9
import * as os from 'os' ;
10
10
import * as path from 'path' ;
11
- import { CancellationToken , Range , TextDocument , Uri } from 'vscode' ;
11
+ import { Position , Range , TextDocument , Uri } from 'vscode' ;
12
12
import * as settings from './configSettings' ;
13
- import { mergeEnvVariables , parseEnvFile } from './envFileParser' ;
14
- import { isNotInstalledError } from './helpers' ;
15
- import { InterpreterInfoCache } from './interpreterInfoCache' ;
13
+ import { parseEnvFile } from './envFileParser' ;
16
14
17
15
export const IS_WINDOWS = / ^ w i n / . test ( process . platform ) ;
18
16
export const Is_64Bit = os . arch ( ) === 'x64' ;
@@ -53,51 +51,6 @@ export function fsReaddirAsync(root: string): Promise<string[]> {
53
51
} ) ;
54
52
}
55
53
56
- async function getPythonInterpreterDirectory ( resource ?: Uri ) : Promise < string > {
57
- const cache = InterpreterInfoCache . get ( resource ) ;
58
- const pythonFileName = settings . PythonSettings . getInstance ( resource ) . pythonPath ;
59
-
60
- // If we already have it and the python path hasn't changed, yay
61
- if ( cache . pythonInterpreterDirectory && cache . pythonInterpreterDirectory . length > 0
62
- && cache . pythonSettingsPath === pythonFileName ) {
63
- return cache . pythonInterpreterDirectory ;
64
- }
65
-
66
- // Check if we have the path
67
- if ( path . basename ( pythonFileName ) === pythonFileName ) {
68
- try {
69
- const pythonInterpreterPath = await getPathFromPythonCommand ( pythonFileName ) ;
70
- const pythonInterpreterDirectory = path . dirname ( pythonInterpreterPath ) ;
71
- InterpreterInfoCache . setPaths ( resource , pythonFileName , pythonInterpreterPath , pythonInterpreterDirectory ) ;
72
- return pythonInterpreterDirectory ;
73
- // tslint:disable-next-line:variable-name
74
- } catch ( _ex ) {
75
- InterpreterInfoCache . setPaths ( resource , pythonFileName , pythonFileName , '' ) ;
76
- return '' ;
77
- }
78
- }
79
-
80
- return new Promise < string > ( resolve => {
81
- // If we can execute the python, then get the path from the fully qualified name
82
- child_process . execFile ( pythonFileName , [ '-c' , 'print(1234)' ] , ( error , stdout , stderr ) => {
83
- // Yes this is a valid python path
84
- if ( stdout . startsWith ( '1234' ) ) {
85
- const pythonInterpreterDirectory = path . dirname ( pythonFileName ) ;
86
- InterpreterInfoCache . setPaths ( resource , pythonFileName , pythonFileName , pythonInterpreterDirectory ) ;
87
- resolve ( pythonInterpreterDirectory ) ;
88
- } else {
89
- // No idea, didn't work, hence don't reject, but return empty path
90
- InterpreterInfoCache . setPaths ( resource , pythonFileName , pythonFileName , '' ) ;
91
- resolve ( '' ) ;
92
- }
93
- } ) ;
94
- } ) ;
95
- }
96
- export async function getFullyQualifiedPythonInterpreterPath ( resource ?: Uri ) : Promise < string > {
97
- const pyDir = await getPythonInterpreterDirectory ( resource ) ;
98
- const cache = InterpreterInfoCache . get ( resource ) ;
99
- return cache . pythonInterpreterPath ;
100
- }
101
54
export async function getPathFromPythonCommand ( pythonPath : string ) : Promise < string > {
102
55
return await new Promise < string > ( ( resolve , reject ) => {
103
56
child_process . execFile ( pythonPath , [ '-c' , 'import sys;print(sys.executable)' ] , ( _ , stdout ) => {
@@ -110,197 +63,6 @@ export async function getPathFromPythonCommand(pythonPath: string): Promise<stri
110
63
} ) ;
111
64
} ) ;
112
65
}
113
- async function getEnvVariables ( resource ?: Uri ) : Promise < { } > {
114
- const cache = InterpreterInfoCache . get ( resource ) ;
115
- if ( cache . customEnvVariables ) {
116
- return cache . customEnvVariables ;
117
- }
118
-
119
- const pyPath = await getPythonInterpreterDirectory ( resource ) ;
120
- let customEnvVariables = await getCustomEnvVars ( resource ) || { } ;
121
-
122
- if ( pyPath . length > 0 ) {
123
- // Ensure to include the path of the current python.
124
- let newPath = '' ;
125
- const currentPath = typeof customEnvVariables [ PATH_VARIABLE_NAME ] === 'string' ? customEnvVariables [ PATH_VARIABLE_NAME ] : process . env [ PATH_VARIABLE_NAME ] ;
126
- if ( IS_WINDOWS ) {
127
- newPath = `${ pyPath } \\${ path . delimiter } ${ path . join ( pyPath , 'Scripts\\' ) } ${ path . delimiter } ${ currentPath } ` ;
128
- // This needs to be done for windows.
129
- process . env [ PATH_VARIABLE_NAME ] = newPath ;
130
- } else {
131
- newPath = `${ pyPath } ${ path . delimiter } ${ currentPath } ` ;
132
- }
133
- customEnvVariables = mergeEnvVariables ( customEnvVariables , process . env ) ;
134
- customEnvVariables [ PATH_VARIABLE_NAME ] = newPath ;
135
- }
136
-
137
- InterpreterInfoCache . setCustomEnvVariables ( resource , customEnvVariables ) ;
138
- return customEnvVariables ;
139
- }
140
- export async function execPythonFile ( resource : string | Uri | undefined , file : string , args : string [ ] , cwd : string , includeErrorAsResponse : boolean = false , stdOut : ( line : string ) => void = null , token ?: CancellationToken ) : Promise < string > {
141
- const resourceUri = typeof resource === 'string' ? Uri . file ( resource ) : resource ;
142
- const env = await getEnvVariables ( resourceUri ) ;
143
- const options = { cwd, env } ;
144
-
145
- if ( stdOut ) {
146
- return spawnFileInternal ( file , args , options , includeErrorAsResponse , stdOut , token ) ;
147
- }
148
-
149
- const fileIsPythonInterpreter = ( file . toUpperCase ( ) === 'PYTHON' || file === settings . PythonSettings . getInstance ( resourceUri ) . pythonPath ) ;
150
- const execAsModule = fileIsPythonInterpreter && args . length > 0 && args [ 0 ] === '-m' ;
151
-
152
- if ( execAsModule ) {
153
- return getFullyQualifiedPythonInterpreterPath ( resourceUri )
154
- . then ( p => execPythonModule ( p , args , options , includeErrorAsResponse , token ) ) ;
155
- }
156
- return execFileInternal ( file , args , options , includeErrorAsResponse , token ) ;
157
- }
158
-
159
- function handleResponse ( file : string , includeErrorAsResponse : boolean , error : Error , stdout : string , stderr : string , token ?: CancellationToken ) : Promise < string > {
160
- if ( token && token . isCancellationRequested ) {
161
- return Promise . resolve ( undefined ) ;
162
- }
163
- if ( isNotInstalledError ( error ) ) {
164
- return Promise . reject ( error ) ;
165
- }
166
-
167
- // pylint:
168
- // In the case of pylint we have some messages (such as config file not found and using default etc...) being returned in stderr
169
- // These error messages are useless when using pylint
170
- if ( includeErrorAsResponse && ( stdout . length > 0 || stderr . length > 0 ) ) {
171
- return Promise . resolve ( stdout + '\n' + stderr ) ;
172
- }
173
-
174
- let hasErrors = ( error && error . message . length > 0 ) || ( stderr && stderr . length > 0 ) ;
175
- if ( hasErrors && ( typeof stdout !== 'string' || stdout . length === 0 ) ) {
176
- let errorMsg = ( error && error . message ) ? error . message : ( stderr && stderr . length > 0 ? stderr + '' : '' ) ;
177
- return Promise . reject ( errorMsg ) ;
178
- }
179
- else {
180
- return Promise . resolve ( stdout + '' ) ;
181
- }
182
- }
183
- function handlePythonModuleResponse ( includeErrorAsResponse : boolean , error : Error , stdout : string , stderr : string , token ?: CancellationToken ) : Promise < string > {
184
- if ( token && token . isCancellationRequested ) {
185
- return Promise . resolve ( undefined ) ;
186
- }
187
- if ( isNotInstalledError ( error ) ) {
188
- return Promise . reject ( error ) ;
189
- }
190
-
191
- // pylint:
192
- // In the case of pylint we have some messages (such as config file not found and using default etc...) being returned in stderr
193
- // These error messages are useless when using pylint
194
- if ( includeErrorAsResponse && ( stdout . length > 0 || stderr . length > 0 ) ) {
195
- return Promise . resolve ( stdout + '\n' + stderr ) ;
196
- }
197
- if ( ! includeErrorAsResponse && stderr . length > 0 ) {
198
- return Promise . reject ( stderr ) ;
199
- }
200
-
201
- return Promise . resolve ( stdout + '' ) ;
202
- }
203
- function execPythonModule ( file : string , args : string [ ] , options : child_process . ExecFileOptions , includeErrorAsResponse : boolean , token ?: CancellationToken ) : Promise < string > {
204
- options . maxBuffer = options . maxBuffer ? options . maxBuffer : 1024 * 102400 ;
205
- return new Promise < string > ( ( resolve , reject ) => {
206
- let proc = child_process . execFile ( file , args , options , ( error , stdout , stderr ) => {
207
- handlePythonModuleResponse ( includeErrorAsResponse , error , stdout , stderr , token )
208
- . then ( resolve )
209
- . catch ( reject ) ;
210
- } ) ;
211
- if ( token && token . onCancellationRequested ) {
212
- token . onCancellationRequested ( ( ) => {
213
- if ( proc ) {
214
- proc . kill ( ) ;
215
- proc = null ;
216
- }
217
- } ) ;
218
- }
219
- } ) ;
220
- }
221
-
222
- function execFileInternal ( file : string , args : string [ ] , options : child_process . ExecFileOptions , includeErrorAsResponse : boolean , token ?: CancellationToken ) : Promise < string > {
223
- options . maxBuffer = options . maxBuffer ? options . maxBuffer : 1024 * 102400 ;
224
- return new Promise < string > ( ( resolve , reject ) => {
225
- let proc = child_process . execFile ( file , args , options , ( error , stdout , stderr ) => {
226
- handleResponse ( file , includeErrorAsResponse , error , stdout , stderr , token )
227
- . then ( data => resolve ( data ) )
228
- . catch ( err => reject ( err ) ) ;
229
- } ) ;
230
- if ( token && token . onCancellationRequested ) {
231
- token . onCancellationRequested ( ( ) => {
232
- if ( proc ) {
233
- proc . kill ( ) ;
234
- proc = null ;
235
- }
236
- } ) ;
237
- }
238
- } ) ;
239
- }
240
- function spawnFileInternal ( file : string , args : string [ ] , options : child_process . ExecFileOptions , includeErrorAsResponse : boolean , stdOut : ( line : string ) => void , token ?: CancellationToken ) : Promise < string > {
241
- return new Promise < string > ( ( resolve , reject ) => {
242
- options . env = options . env || { } ;
243
- options . env [ 'PYTHONIOENCODING' ] = 'UTF-8' ;
244
- let proc = child_process . spawn ( file , args , options ) ;
245
- let error = '' ;
246
- let exited = false ;
247
- if ( token && token . onCancellationRequested ) {
248
- token . onCancellationRequested ( ( ) => {
249
- if ( ! exited && proc ) {
250
- proc . kill ( ) ;
251
- proc = null ;
252
- }
253
- } ) ;
254
- }
255
- proc . on ( 'error' , error => {
256
- reject ( error ) ;
257
- } ) ;
258
- proc . stdout . setEncoding ( 'utf8' ) ;
259
- proc . stderr . setEncoding ( 'utf8' ) ;
260
- proc . stdout . on ( 'data' , function ( data : string ) {
261
- if ( token && token . isCancellationRequested ) {
262
- return ;
263
- }
264
- stdOut ( data ) ;
265
- } ) ;
266
-
267
- proc . stderr . on ( 'data' , function ( data : string ) {
268
- if ( token && token . isCancellationRequested ) {
269
- return ;
270
- }
271
- if ( includeErrorAsResponse ) {
272
- stdOut ( data ) ;
273
- }
274
- else {
275
- error += data ;
276
- }
277
- } ) ;
278
-
279
- proc . on ( 'exit' , function ( code ) {
280
- exited = true ;
281
-
282
- if ( token && token . isCancellationRequested ) {
283
- return reject ( ) ;
284
- }
285
- if ( error . length > 0 ) {
286
- return reject ( error ) ;
287
- }
288
-
289
- resolve ( ) ;
290
- } ) ;
291
-
292
- } ) ;
293
- }
294
- function execInternal ( command : string , args : string [ ] , options : child_process . ExecFileOptions , includeErrorAsResponse : boolean ) : Promise < string > {
295
- return new Promise < string > ( ( resolve , reject ) => {
296
- child_process . exec ( [ command ] . concat ( args ) . join ( ' ' ) , options , ( error , stdout , stderr ) => {
297
- handleResponse ( command , includeErrorAsResponse , error , stdout , stderr )
298
- . then ( data => resolve ( data ) )
299
- . catch ( err => reject ( err ) ) ;
300
- } ) ;
301
- } ) ;
302
- }
303
-
304
66
export function formatErrorForLogging ( error : Error | string ) : string {
305
67
let message : string = '' ;
306
68
if ( typeof error === 'string' ) {
@@ -332,7 +94,7 @@ export function getSubDirectories(rootDir: string): Promise<string[]> {
332
94
if ( error ) {
333
95
return resolve ( [ ] ) ;
334
96
}
335
- const subDirs = [ ] ;
97
+ const subDirs : string [ ] = [ ] ;
336
98
files . forEach ( name => {
337
99
const fullPath = path . join ( rootDir , name ) ;
338
100
try {
@@ -341,7 +103,7 @@ export function getSubDirectories(rootDir: string): Promise<string[]> {
341
103
}
342
104
}
343
105
// tslint:disable-next-line:no-empty
344
- catch ( ex ) { }
106
+ catch ( ex ) { }
345
107
} ) ;
346
108
resolve ( subDirs ) ;
347
109
} ) ;
@@ -396,7 +158,7 @@ export function getWindowsLineEndingCount(document: TextDocument, offset: Number
396
158
// In order to prevent the one-time loading of large files from taking up too much memory
397
159
for ( let pos = 0 ; pos < offset ; pos += readBlock ) {
398
160
let startAt = document . positionAt ( pos ) ;
399
- let endAt = null ;
161
+ let endAt : Position ;
400
162
401
163
if ( offsetDiff >= readBlock ) {
402
164
endAt = document . positionAt ( pos + readBlock ) ;
@@ -405,7 +167,7 @@ export function getWindowsLineEndingCount(document: TextDocument, offset: Number
405
167
endAt = document . positionAt ( pos + offsetDiff ) ;
406
168
}
407
169
408
- let text = document . getText ( new Range ( startAt , endAt ) ) ;
170
+ let text = document . getText ( new Range ( startAt , endAt ! ) ) ;
409
171
let cr = text . match ( eolPattern ) ;
410
172
411
173
count += cr ? cr . length : 0 ;
@@ -422,13 +184,3 @@ export function arePathsSame(path1: string, path2: string) {
422
184
return path1 === path2 ;
423
185
}
424
186
}
425
-
426
- export async function getInterpreterVersion ( pythonPath : string ) {
427
- return await new Promise < string > ( ( resolve , reject ) => {
428
- child_process . execFile ( pythonPath , [ '--version' ] , ( error , stdout , stdErr ) => {
429
- const out = ( typeof stdErr === 'string' ? stdErr : '' ) + os . EOL + ( typeof stdout === 'string' ? stdout : '' ) ;
430
- const lines = out . split ( / \r ? \n / g) . map ( line => line . trim ( ) ) . filter ( line => line . length > 0 ) ;
431
- resolve ( lines . length > 0 ? lines [ 0 ] : '' ) ;
432
- } ) ;
433
- } ) ;
434
- }
0 commit comments