@@ -8,9 +8,11 @@ import { getExecutablePath } from '../../pythonEnvironments/info/executable';
8
8
import { getInterpreterInfo } from '../../pythonEnvironments/info/interpreter' ;
9
9
import { traceError , traceInfo } from '../logger' ;
10
10
import { IFileSystem } from '../platform/types' ;
11
+ import { createDeferred , Deferred } from '../utils/async' ;
11
12
import * as internalPython from './internal/python' ;
12
13
import { ExecutionResult , IProcessService , ShellOptions , SpawnOptions } from './types' ;
13
14
15
+ const cachedExecutablePath : Map < string , Deferred < string > > = new Map < string , Deferred < string > > ( ) ;
14
16
class PythonEnvironment {
15
17
private cachedInterpreterInformation : InterpreterInformation | undefined | null = null ;
16
18
@@ -49,8 +51,18 @@ class PythonEnvironment {
49
51
if ( await this . deps . isValidExecutable ( this . pythonPath ) ) {
50
52
return this . pythonPath ;
51
53
}
54
+ const result = cachedExecutablePath . get ( this . pythonPath ) ;
55
+ if ( result !== undefined ) {
56
+ // Another call for this environment has already been made, return its result
57
+ return result . promise ;
58
+ }
59
+ const deferred = createDeferred < string > ( ) ;
60
+ cachedExecutablePath . set ( this . pythonPath , deferred ) ;
52
61
const python = this . getExecutionInfo ( ) ;
53
- return getExecutablePath ( python , this . deps . exec ) ;
62
+ return getExecutablePath ( python , this . deps . exec ) . then ( ( r ) => {
63
+ deferred . resolve ( r ) ;
64
+ return r ;
65
+ } ) ;
54
66
}
55
67
56
68
public async getModuleVersion ( moduleName : string ) : Promise < string | undefined > {
@@ -139,7 +151,7 @@ export function createCondaEnv(
139
151
}
140
152
const pythonArgv = [ condaFile , ...runArgs , 'python' ] ;
141
153
const deps = createDeps (
142
- async ( filename ) => fs . fileExists ( filename ) ,
154
+ async ( filename ) => fs . pathExists ( filename ) ,
143
155
pythonArgv ,
144
156
145
157
// TODO: Use pythonArgv here once 'conda run' can be
0 commit comments