Skip to content

Use Native python finder as the main locator #23735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/client/environmentApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Architecture } from './common/utils/platform';
import { IServiceContainer } from './ioc/types';
import { PythonEnvInfo, PythonEnvKind, PythonEnvType } from './pythonEnvironments/base/info';
import { getEnvPath } from './pythonEnvironments/base/info/env';
import { IDiscoveryAPI } from './pythonEnvironments/base/locator';
import { IDiscoveryAPI, ProgressReportStage } from './pythonEnvironments/base/locator';
import { IPythonExecutionFactory } from './common/process/types';
import { traceError, traceVerbose } from './logging';
import { isParentPath, normCasePath } from './common/platform/fs-paths';
Expand Down Expand Up @@ -147,6 +147,11 @@ export function buildEnvironmentApi(
.ignoreErrors();
}
disposables.push(
discoveryApi.onProgress((e) => {
if (e.stage === ProgressReportStage.discoveryFinished) {
knownCache = initKnownCache();
}
}),
discoveryApi.onChanged((e) => {
const env = e.new ?? e.old;
if (!env || !filterUsingVSCodeContext(env)) {
Expand Down
2 changes: 2 additions & 0 deletions src/client/interpreter/display/progressDisplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export class InterpreterLocatorProgressStatubarHandler implements IExtensionSing
if (refreshPromise) {
refreshPromise.then(() => this.hideProgress());
}
} else if (event.stage === ProgressReportStage.discoveryFinished) {
this.hideProgress();
}
},
this,
Expand Down
1 change: 1 addition & 0 deletions src/client/pythonEnvironments/base/locator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export interface IPythonEnvsIterator<I = PythonEnvInfo> extends IAsyncIterableIt
}

export enum ProgressReportStage {
idle = 'idle',
discoveryStarted = 'discoveryStarted',
allPathsDiscovered = 'allPathsDiscovered',
discoveryFinished = 'discoveryFinished',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { Disposable, EventEmitter, Event, Uri } from 'vscode';
import { Disposable, EventEmitter, Event, Uri, LogOutputChannel } from 'vscode';
import * as ch from 'child_process';
import * as path from 'path';
import * as rpc from 'vscode-jsonrpc/node';
Expand All @@ -22,13 +22,13 @@ const untildify = require('untildify');

const PYTHON_ENV_TOOLS_PATH = isWindows()
? path.join(EXTENSION_ROOT_DIR, 'python-env-tools', 'bin', 'pet.exe')
: path.join(EXTENSION_ROOT_DIR, 'python-env-tools', 'bin', 'pet');
: '/Users/donjayamanne/Development/vsc/python-environment-tools/target/debug/pet';

export interface NativeEnvInfo {
displayName?: string;
name?: string;
executable?: string;
kind: string;
kind?: string;
version?: string;
prefix?: string;
manager?: NativeEnvManagerInfo;
Expand All @@ -46,18 +46,19 @@ export interface NativeEnvManagerInfo {
version?: string;
}

export interface NativeGlobalPythonFinder extends Disposable {
export interface NativePythonFinder extends Disposable {
resolve(executable: string): Promise<NativeEnvInfo>;
refresh(): AsyncIterable<NativeEnvInfo>;
categoryToKind(category?: string): PythonEnvKind;
logger(): LogOutputChannel;
}

interface NativeLog {
level: string;
message: string;
}

class NativeGlobalPythonFinderImpl extends DisposableBase implements NativeGlobalPythonFinder {
class NativeGlobalPythonFinderImpl extends DisposableBase implements NativePythonFinder {
private readonly connection: rpc.MessageConnection;

private firstRefreshResults: undefined | (() => AsyncGenerator<NativeEnvInfo, void, unknown>);
Expand Down Expand Up @@ -158,6 +159,10 @@ class NativeGlobalPythonFinderImpl extends DisposableBase implements NativeGloba
}
}

logger(): LogOutputChannel {
return this.outputChannel;
}

refreshFirstTime() {
const result = this.doRefresh();
const completed = createDeferredFrom(result.completed);
Expand Down Expand Up @@ -289,7 +294,6 @@ class NativeGlobalPythonFinderImpl extends DisposableBase implements NativeGloba
disposable.add(
this.connection.onNotification('environment', (data: NativeEnvInfo) => {
this.outputChannel.info(`Discovered env: ${data.executable || data.prefix}`);
this.outputChannel.trace(`Discovered env info:\n ${JSON.stringify(data, undefined, 4)}`);
// We know that in the Python extension if either Version of Prefix is not provided by locator
// Then we end up resolving the information.
// Lets do that here,
Expand All @@ -306,7 +310,6 @@ class NativeGlobalPythonFinderImpl extends DisposableBase implements NativeGloba
})
.then((environment) => {
this.outputChannel.info(`Resolved ${environment.executable}`);
this.outputChannel.trace(`Environment resolved:\n ${JSON.stringify(data, undefined, 4)}`);
discovered.fire(environment);
})
.catch((ex) => this.outputChannel.error(`Error in Resolving ${JSON.stringify(data)}`, ex));
Expand Down Expand Up @@ -369,6 +372,10 @@ function getPythonSettingAndUntildify<T>(name: string, scope?: Uri): T | undefin
return value;
}

export function createNativeGlobalPythonFinder(): NativeGlobalPythonFinder {
return new NativeGlobalPythonFinderImpl();
let _finder: NativePythonFinder | undefined;
export function getNativePythonFinder(): NativePythonFinder {
if (!_finder) {
_finder = new NativeGlobalPythonFinderImpl();
}
return _finder;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import { getQueryFilter } from '../../locatorUtils';
import { PythonEnvCollectionChangedEvent, PythonEnvsWatcher } from '../../watcher';
import { IEnvsCollectionCache } from './envsCollectionCache';
import { createNativeGlobalPythonFinder, NativeEnvInfo } from '../common/nativePythonFinder';
import { getNativePythonFinder, NativeEnvInfo } from '../common/nativePythonFinder';
import { pathExists } from '../../../../common/platform/fs-paths';
import { noop } from '../../../../common/utils/misc';
import { parseVersion } from '../../info/pythonVersion';
Expand All @@ -47,7 +47,7 @@ export class EnvsCollectionService extends PythonEnvsWatcher<PythonEnvCollection

private readonly progress = new EventEmitter<ProgressNotificationEvent>();

private nativeFinder = createNativeGlobalPythonFinder();
private nativeFinder = getNativePythonFinder();

public refreshState = ProgressReportStage.discoveryFinished;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Conda } from '../../../common/environmentManagers/conda';
import { traceError } from '../../../../logging';
import type { KnownEnvironmentTools } from '../../../../api/types';
import { setPyEnvBinary } from '../../../common/environmentManagers/pyenv';
import { NativeGlobalPythonFinder, createNativeGlobalPythonFinder } from '../common/nativePythonFinder';
import { NativePythonFinder, getNativePythonFinder } from '../common/nativePythonFinder';
import { disposeAll } from '../../../../common/utils/resourceLifecycle';
import { Architecture } from '../../../../common/utils/platform';

Expand Down Expand Up @@ -54,11 +54,11 @@ export class NativeLocator implements ILocator<BasicEnvInfo>, IDisposable {

private readonly disposables: IDisposable[] = [];

private readonly finder: NativeGlobalPythonFinder;
private readonly finder: NativePythonFinder;

constructor() {
this.onChanged = this.onChangedEmitter.event;
this.finder = createNativeGlobalPythonFinder();
this.finder = getNativePythonFinder();
this.disposables.push(this.onChangedEmitter, this.finder);
}

Expand Down
18 changes: 18 additions & 0 deletions src/client/pythonEnvironments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,34 @@ import { traceError } from '../logging';
import { ActiveStateLocator } from './base/locators/lowLevel/activeStateLocator';
import { CustomWorkspaceLocator } from './base/locators/lowLevel/customWorkspaceLocator';
import { PixiLocator } from './base/locators/lowLevel/pixiLocator';
import { getConfiguration } from '../common/vscodeApis/workspaceApis';
import { getNativePythonFinder } from './base/locators/common/nativePythonFinder';
import { createNativeEnvironmentsApi } from './nativeAPI';

const PYTHON_ENV_INFO_CACHE_KEY = 'PYTHON_ENV_INFO_CACHEv2';

export function shouldUseNativeLocator(): boolean {
const config = getConfiguration('python');
return config.get<string>('locator', 'js') === 'native';
}

/**
* Set up the Python environments component (during extension activation).'
*/
export async function initialize(ext: ExtensionState): Promise<IDiscoveryAPI> {
// Set up the legacy IOC container before api is created.
initializeLegacyExternalDependencies(ext.legacyIOC.serviceContainer);

if (shouldUseNativeLocator()) {
const finder = getNativePythonFinder();
const api = createNativeEnvironmentsApi(finder);
registerNewDiscoveryForIOC(
// These are what get wrapped in the legacy adapter.
ext.legacyIOC.serviceManager,
api,
);
return api;
}
const api = await createPythonEnvironments(() => createLocator(ext));
registerNewDiscoveryForIOC(
// These are what get wrapped in the legacy adapter.
Expand Down
Loading
Loading