Skip to content

Commit 9a29f27

Browse files
Use the component adapter in the extension.
1 parent 016cce8 commit 9a29f27

22 files changed

Lines changed: 183 additions & 77 deletions

‎src/client/application/diagnostics/checks/macPythonInterpreter.ts‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,27 @@ export class InvalidMacPythonInterpreterService extends BaseDiagnosticsService {
9595
return [];
9696
}
9797

98-
if (!this.helper.isMacDefaultPythonPath(settings.pythonPath)) {
98+
if (!(await this.helper.isMacDefaultPythonPath(settings.pythonPath))) {
9999
return [];
100100
}
101101
if (!currentInterpreter || currentInterpreter.envType !== EnvironmentType.Unknown) {
102102
return [];
103103
}
104104

105105
const interpreters = await this.interpreterService.getInterpreters(resource);
106-
if (interpreters.filter((i) => !this.helper.isMacDefaultPythonPath(i.path)).length === 0) {
107-
return [
108-
new InvalidMacPythonInterpreterDiagnostic(
109-
DiagnosticCodes.MacInterpreterSelectedAndNoOtherInterpretersDiagnostic,
110-
resource
111-
)
112-
];
106+
for (const info of interpreters) {
107+
if (!(await this.helper.isMacDefaultPythonPath(info.path))) {
108+
return [
109+
new InvalidMacPythonInterpreterDiagnostic(
110+
DiagnosticCodes.MacInterpreterSelectedAndHaveOtherInterpretersDiagnostic,
111+
resource
112+
)
113+
];
114+
}
113115
}
114-
115116
return [
116117
new InvalidMacPythonInterpreterDiagnostic(
117-
DiagnosticCodes.MacInterpreterSelectedAndHaveOtherInterpretersDiagnostic,
118+
DiagnosticCodes.MacInterpreterSelectedAndNoOtherInterpretersDiagnostic,
118119
resource
119120
)
120121
];

‎src/client/common/process/pythonExecutionFactory.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class PythonExecutionFactory implements IPythonExecutionFactory {
7171
processService,
7272
this.fileSystem,
7373
undefined,
74-
this.windowsStoreInterpreter.isWindowsStoreInterpreter(pythonPath)
74+
await this.windowsStoreInterpreter.isWindowsStoreInterpreter(pythonPath)
7575
);
7676
}
7777

‎src/client/interpreter/contracts.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const IInterpreterHelper = Symbol('IInterpreterHelper');
100100
export interface IInterpreterHelper {
101101
getActiveWorkspaceUri(resource: Resource): WorkspacePythonPath | undefined;
102102
getInterpreterInformation(pythonPath: string): Promise<undefined | Partial<PythonEnvironment>>;
103-
isMacDefaultPythonPath(pythonPath: string): Boolean;
103+
isMacDefaultPythonPath(pythonPath: string): Promise<boolean>;
104104
getInterpreterTypeDisplayName(interpreterType: EnvironmentType): string | undefined;
105105
getBestInterpreter(interpreters?: PythonEnvironment[]): PythonEnvironment | undefined;
106106
}

‎src/client/interpreter/helpers.ts‎

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
PythonEnvironment,
1616
sortInterpreters
1717
} from '../pythonEnvironments/info';
18-
import { IInterpreterHelper } from './contracts';
18+
import { IComponentAdapter, IInterpreterHelper } from './contracts';
1919
import { IInterpreterHashProviderFactory } from './locators/types';
2020

2121
const EXPITY_DURATION = 24 * 60 * 60 * 1000;
@@ -44,12 +44,19 @@ export function isInterpreterLocatedInWorkspace(interpreter: PythonEnvironment,
4444
return interpreterPath.startsWith(resourcePath);
4545
}
4646

47+
// The parts of IComponentAdapter used here.
48+
interface IComponent {
49+
getInterpreterInformation(pythonPath: string): Promise<undefined | Partial<PythonEnvironment>>;
50+
isMacDefaultPythonPath(pythonPath: string): Promise<boolean | undefined>;
51+
}
52+
4753
@injectable()
4854
export class InterpreterHelper implements IInterpreterHelper {
4955
private readonly persistentFactory: IPersistentStateFactory;
5056
constructor(
5157
@inject(IServiceContainer) private serviceContainer: IServiceContainer,
52-
@inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory
58+
@inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory,
59+
@inject(IComponentAdapter) private readonly pyenvs: IComponent
5360
) {
5461
this.persistentFactory = this.serviceContainer.get<IPersistentStateFactory>(IPersistentStateFactory);
5562
}
@@ -78,6 +85,11 @@ export class InterpreterHelper implements IInterpreterHelper {
7885
}
7986
}
8087
public async getInterpreterInformation(pythonPath: string): Promise<undefined | Partial<PythonEnvironment>> {
88+
const found = await this.pyenvs.getInterpreterInformation(pythonPath);
89+
if (found !== undefined) {
90+
return found;
91+
}
92+
8193
const fileHash = await this.hashProviderFactory
8294
.create({ pythonPath })
8395
.then((provider) => provider.getInterpreterHash(pythonPath))
@@ -115,7 +127,11 @@ export class InterpreterHelper implements IInterpreterHelper {
115127
return;
116128
}
117129
}
118-
public isMacDefaultPythonPath(pythonPath: string) {
130+
public async isMacDefaultPythonPath(pythonPath: string): Promise<boolean> {
131+
const result = await this.pyenvs.isMacDefaultPythonPath(pythonPath);
132+
if (result !== undefined) {
133+
return result;
134+
}
119135
return isMacDefaultPythonPath(pythonPath);
120136
}
121137
public getInterpreterTypeDisplayName(interpreterType: EnvironmentType) {

‎src/client/interpreter/interpreterService.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { EnvironmentType, PythonEnvironment } from '../pythonEnvironments/info';
2525
import { captureTelemetry } from '../telemetry';
2626
import { EventName } from '../telemetry/constants';
2727
import {
28+
IComponentAdapter,
2829
IInterpreterDisplay,
2930
IInterpreterHelper,
3031
IInterpreterLocatorService,
@@ -40,6 +41,11 @@ export type GetInterpreterOptions = {
4041
onSuggestion?: boolean;
4142
};
4243

44+
// The parts of IComponentAdapter used here.
45+
interface IComponent {
46+
getInterpreterDetails(pythonPath: string): Promise<undefined | PythonEnvironment>;
47+
}
48+
4349
@injectable()
4450
export class InterpreterService implements Disposable, IInterpreterService {
4551
public get hasInterpreters(): Promise<boolean> {
@@ -70,7 +76,8 @@ export class InterpreterService implements Disposable, IInterpreterService {
7076

7177
constructor(
7278
@inject(IServiceContainer) private serviceContainer: IServiceContainer,
73-
@inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory
79+
@inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory,
80+
@inject(IComponentAdapter) private readonly pyenvs: IComponent
7481
) {
7582
this.locator = serviceContainer.get<IInterpreterLocatorService>(
7683
IInterpreterLocatorService,
@@ -160,6 +167,11 @@ export class InterpreterService implements Disposable, IInterpreterService {
160167
return this.getInterpreterDetails(fullyQualifiedPath, resource);
161168
}
162169
public async getInterpreterDetails(pythonPath: string, resource?: Uri): Promise<PythonEnvironment | undefined> {
170+
const info = await this.pyenvs.getInterpreterDetails(pythonPath);
171+
if (info !== undefined) {
172+
return info;
173+
}
174+
163175
// If we don't have the fully qualified path, then get it.
164176
if (path.basename(pythonPath) === pythonPath) {
165177
const pythonExecutionFactory = this.serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);

‎src/client/interpreter/locators/types.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export interface IWindowsStoreInterpreter {
5353
* @returns {boolean}
5454
* @memberof WindowsStoreInterpreter
5555
*/
56-
isWindowsStoreInterpreter(pythonPath: string): boolean;
56+
isWindowsStoreInterpreter(pythonPath: string): Promise<boolean>;
5757
/**
5858
* Whether this is a python executable in a windows app store folder that is internal and can be hidden from users.
5959
*

‎src/client/pythonEnvironments/discovery/locators/index.ts‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
CONDA_ENV_SERVICE,
1616
CURRENT_PATH_SERVICE,
1717
GLOBAL_VIRTUAL_ENV_SERVICE,
18+
IComponentAdapter,
1819
IInterpreterLocatorHelper,
1920
IInterpreterLocatorService,
2021
KNOWN_PATH_SERVICE,
@@ -180,6 +181,12 @@ function matchURI(uri: Uri, ...candidates: Uri[]): boolean {
180181
return matchedUri !== undefined;
181182
}
182183

184+
// The parts of IComponentAdapter used here.
185+
interface IComponent {
186+
hasInterpreters: Promise<boolean | undefined>;
187+
getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise<PythonEnvironment[] | undefined>;
188+
}
189+
183190
/**
184191
* Facilitates locating Python interpreters.
185192
*/
@@ -198,7 +205,10 @@ export class PythonInterpreterLocatorService implements IInterpreterLocatorServi
198205
private readonly onLocatingEmitter:EventEmitter<Promise<PythonEnvironment[]>> =
199206
new EventEmitter<Promise<PythonEnvironment[]>>();
200207

201-
constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) {
208+
constructor(
209+
@inject(IServiceContainer) private serviceContainer: IServiceContainer,
210+
@inject(IComponentAdapter) private readonly pyenvs: IComponent,
211+
) {
202212
this._hasInterpreters = createDeferred<boolean>();
203213
serviceContainer.get<Disposable[]>(IDisposableRegistry).push(this);
204214
this.platform = serviceContainer.get<IPlatformService>(IPlatformService);
@@ -219,7 +229,12 @@ export class PythonInterpreterLocatorService implements IInterpreterLocatorServi
219229
}
220230

221231
public get hasInterpreters(): Promise<boolean> {
222-
return this._hasInterpreters.completed ? this._hasInterpreters.promise : Promise.resolve(false);
232+
return this.pyenvs.hasInterpreters.then((res) => {
233+
if (res !== undefined) {
234+
return res;
235+
}
236+
return this._hasInterpreters.completed ? this._hasInterpreters.promise : Promise.resolve(false);
237+
});
223238
}
224239

225240
/**
@@ -239,6 +254,10 @@ export class PythonInterpreterLocatorService implements IInterpreterLocatorServi
239254
*/
240255
@traceDecorators.verbose('Get Interpreters')
241256
public async getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise<PythonEnvironment[]> {
257+
const envs = await this.pyenvs.getInterpreters(resource, options);
258+
if (envs !== undefined) {
259+
return envs;
260+
}
242261
const locators = this.getLocators(options);
243262
const promises = locators.map(async (provider) => provider.getInterpreters(resource));
244263
locators.forEach((locator) => {

‎src/client/pythonEnvironments/discovery/locators/services/condaService.ts‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { IFileSystem, IPlatformService } from '../../../../common/platform/types
1313
import { IProcessServiceFactory } from '../../../../common/process/types';
1414
import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory } from '../../../../common/types';
1515
import { cache } from '../../../../common/utils/decorators';
16-
import { ICondaService, IInterpreterLocatorService, WINDOWS_REGISTRY_SERVICE } from '../../../../interpreter/contracts';
16+
import { IComponentAdapter, ICondaService, IInterpreterLocatorService, WINDOWS_REGISTRY_SERVICE } from '../../../../interpreter/contracts';
1717
import { EnvironmentType, PythonEnvironment } from '../../../info';
1818
import { CondaEnvironmentInfo, CondaInfo } from './conda';
1919
import { parseCondaEnvFileContents } from './condaHelper';
@@ -49,6 +49,12 @@ export const CondaLocationsGlobWin = `{${condaGlobPathsForWindows.join(',')}}`;
4949

5050
export const CondaGetEnvironmentPrefix = 'Outputting Environment Now...';
5151

52+
// The parts of IComponentAdapter used here.
53+
interface IComponent {
54+
isCondaEnvironment(interpreterPath: string): Promise<boolean | undefined>;
55+
getCondaEnvironment(interpreterPath: string): Promise<CondaEnvironmentInfo | undefined>;
56+
}
57+
5258
/**
5359
* A wrapper around a conda installation.
5460
*/
@@ -66,6 +72,7 @@ export class CondaService implements ICondaService {
6672
@inject(IConfigurationService) private configService: IConfigurationService,
6773
@inject(IDisposableRegistry) private disposableRegistry: IDisposableRegistry,
6874
@inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService,
75+
@inject(IComponentAdapter) private readonly pyenvs: IComponent,
6976
@inject(IInterpreterLocatorService)
7077
@named(WINDOWS_REGISTRY_SERVICE)
7178
@optional()
@@ -183,6 +190,10 @@ export class CondaService implements ICondaService {
183190
* @memberof CondaService
184191
*/
185192
public async isCondaEnvironment(interpreterPath: string): Promise<boolean> {
193+
const result = await this.pyenvs.isCondaEnvironment(interpreterPath);
194+
if (result !== undefined) {
195+
return result;
196+
}
186197
const dir = path.dirname(interpreterPath);
187198
const { isWindows } = this.platform;
188199
const condaMetaDirectory = isWindows ? path.join(dir, 'conda-meta') : path.join(dir, '..', 'conda-meta');
@@ -193,6 +204,10 @@ export class CondaService implements ICondaService {
193204
* Return (env name, interpreter filename) for the interpreter.
194205
*/
195206
public async getCondaEnvironment(interpreterPath: string): Promise<{ name: string; path: string } | undefined> {
207+
const found = await this.pyenvs.getCondaEnvironment(interpreterPath);
208+
if (found !== undefined) {
209+
return found;
210+
}
196211
const isCondaEnv = await this.isCondaEnvironment(interpreterPath);
197212
if (!isCondaEnv) {
198213
return;

‎src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class InterpeterHashProviderFactory implements IInterpreterHashProviderFa
2828
? options.pythonPath
2929
: this.configService.getSettings(options.resource).pythonPath;
3030

31-
return this.windowsStoreInterpreter.isWindowsStoreInterpreter(pythonPath)
31+
return (await this.windowsStoreInterpreter.isWindowsStoreInterpreter(pythonPath))
3232
? this.windowsStoreHashProvider
3333
: this.hashProvider;
3434
}

‎src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export class WindowsRegistryService extends CacheableLocatorService {
186186
// Give preference to what we have retrieved from getInterpreterInformation.
187187
version: details.version || parsePythonVersion(version),
188188
companyDisplayName: interpreterInfo.companyDisplayName,
189-
envType: this.windowsStoreInterpreter.isWindowsStoreInterpreter(executablePath)
189+
envType: (await this.windowsStoreInterpreter.isWindowsStoreInterpreter(executablePath))
190190
? EnvironmentType.WindowsStore
191191
: EnvironmentType.Unknown,
192192
} as PythonEnvironment;

0 commit comments

Comments
 (0)