From 4855cd2a5b1b76da61a83b2583f15cc2ab261620 Mon Sep 17 00:00:00 2001 From: eleanorjboyd <26030610+eleanorjboyd@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:17:57 -0800 Subject: [PATCH] Remove native locator experiment and setting --- package.json | 14 -- package.nls.json | 1 - src/client/pythonEnvironments/index.ts | 190 +------------------------ 3 files changed, 5 insertions(+), 200 deletions(-) diff --git a/package.json b/package.json index bc9131276c59..658aeb8afd1b 100644 --- a/package.json +++ b/package.json @@ -578,20 +578,6 @@ "scope": "resource", "type": "string" }, - "python.locator": { - "default": "js", - "description": "%python.locator.description%", - "enum": [ - "js", - "native" - ], - "tags": [ - "onExP", - "preview" - ], - "scope": "machine", - "type": "string" - }, "python.pipenvPath": { "default": "pipenv", "description": "%python.pipenvPath.description%", diff --git a/package.nls.json b/package.nls.json index 57f2ed95b2c0..76942d120cae 100644 --- a/package.nls.json +++ b/package.nls.json @@ -63,7 +63,6 @@ "python.logging.level.description": "The logging level the extension logs at, defaults to 'error'", "python.logging.level.deprecation": "This setting is deprecated. Please use command `Developer: Set Log Level...` to set logging level.", "python.missingPackage.severity.description": "Set severity of missing packages in requirements.txt or pyproject.toml", - "python.locator.description": "[Experimental] Select implementation of environment locators. This is an experimental setting while we test native environment location.", "python.pipenvPath.description": "Path to the pipenv executable to use for activation.", "python.poetryPath.description": "Path to the poetry executable.", "python.pixiToolPath.description": "Path to the pixi executable.", diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 299dfab59132..ce642522bf1a 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -2,45 +2,15 @@ // Licensed under the MIT License. import * as vscode from 'vscode'; -import { Uri } from 'vscode'; -import { cloneDeep } from 'lodash'; -import { getGlobalStorage, IPersistentStorage } from '../common/persistentState'; -import { getOSType, OSType } from '../common/utils/platform'; +import { getGlobalStorage } from '../common/persistentState'; import { ActivationResult, ExtensionState } from '../components'; import { PythonEnvInfo } from './base/info'; -import { BasicEnvInfo, IDiscoveryAPI, ILocator } from './base/locator'; -import { PythonEnvsReducer } from './base/locators/composite/envsReducer'; -import { PythonEnvsResolver } from './base/locators/composite/envsResolver'; -import { WindowsPathEnvVarLocator } from './base/locators/lowLevel/windowsKnownPathsLocator'; -import { WorkspaceVirtualEnvironmentLocator } from './base/locators/lowLevel/workspaceVirtualEnvLocator'; +import { IDiscoveryAPI } from './base/locator'; import { initializeExternalDependencies as initializeLegacyExternalDependencies, normCasePath, } from './common/externalDependencies'; -import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './base/locators/wrappers'; -import { CustomVirtualEnvironmentLocator } from './base/locators/lowLevel/customVirtualEnvLocator'; -import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; -import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/globalVirtualEnvronmentLocator'; -import { PosixKnownPathsLocator } from './base/locators/lowLevel/posixKnownPathsLocator'; -import { PyenvLocator } from './base/locators/lowLevel/pyenvLocator'; -import { WindowsRegistryLocator } from './base/locators/lowLevel/windowsRegistryLocator'; -import { MicrosoftStoreLocator } from './base/locators/lowLevel/microsoftStoreLocator'; -import { getEnvironmentInfoService } from './base/info/environmentInfoService'; import { registerNewDiscoveryForIOC } from './legacyIOC'; -import { PoetryLocator } from './base/locators/lowLevel/poetryLocator'; -import { HatchLocator } from './base/locators/lowLevel/hatchLocator'; -import { createPythonEnvironments } from './api'; -import { - createCollectionCache as createCache, - IEnvsCollectionCache, -} from './base/locators/composite/envsCollectionCache'; -import { EnvsCollectionService } from './base/locators/composite/envsCollectionService'; -import { IDisposable } from '../common/types'; -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'; import { useEnvExtension } from '../envExt/api.internal'; @@ -48,11 +18,6 @@ import { createEnvExtApi } from '../envExt/envExtApi'; const PYTHON_ENV_INFO_CACHE_KEY = 'PYTHON_ENV_INFO_CACHEv2'; -export function shouldUseNativeLocator(): boolean { - const config = getConfiguration('python'); - return config.get('locator', 'js') === 'native'; -} - /** * Set up the Python environments component (during extension activation).' */ @@ -70,19 +35,9 @@ export async function initialize(ext: ExtensionState): Promise { return api; } - if (shouldUseNativeLocator()) { - const finder = getNativePythonFinder(ext.context); - const api = createNativeEnvironmentsApi(finder); - ext.disposables.push(api); - registerNewDiscoveryForIOC( - // These are what get wrapped in the legacy adapter. - ext.legacyIOC.serviceManager, - api, - ); - return api; - } - - const api = await createPythonEnvironments(() => createLocator(ext)); + const finder = getNativePythonFinder(ext.context); + const api = createNativeEnvironmentsApi(finder); + ext.disposables.push(api); registerNewDiscoveryForIOC( // These are what get wrapped in the legacy adapter. ext.legacyIOC.serviceManager, @@ -136,138 +91,3 @@ export async function activate(api: IDiscoveryAPI, ext: ExtensionState): Promise fullyReady: Promise.resolve(), }; } - -/** - * Get the locator to use in the component. - */ -async function createLocator( - ext: ExtensionState, - // This is shared. -): Promise { - // Create the low-level locators. - const locators: ILocator = new ExtensionLocators( - // Here we pull the locators together. - createNonWorkspaceLocators(ext), - createWorkspaceLocator(ext), - ); - - // Create the env info service used by ResolvingLocator and CachingLocator. - const envInfoService = getEnvironmentInfoService(ext.disposables); - - // Build the stack of composite locators. - const reducer = new PythonEnvsReducer(locators); - const resolvingLocator = new PythonEnvsResolver( - reducer, - // These are shared. - envInfoService, - ); - const caching = new EnvsCollectionService( - await createCollectionCache(ext), - // This is shared. - resolvingLocator, - shouldUseNativeLocator(), - ); - return caching; -} - -function createNonWorkspaceLocators(ext: ExtensionState): ILocator[] { - const locators: (ILocator & Partial)[] = []; - locators.push( - // OS-independent locators go here. - new PyenvLocator(), - new CondaEnvironmentLocator(), - new ActiveStateLocator(), - new GlobalVirtualEnvironmentLocator(), - new CustomVirtualEnvironmentLocator(), - ); - - if (getOSType() === OSType.Windows) { - locators.push( - // Windows specific locators go here. - new WindowsRegistryLocator(), - new MicrosoftStoreLocator(), - new WindowsPathEnvVarLocator(), - ); - } else { - locators.push( - // Linux/Mac locators go here. - new PosixKnownPathsLocator(), - ); - } - - const disposables = locators.filter((d) => d.dispose !== undefined) as IDisposable[]; - ext.disposables.push(...disposables); - return locators; -} - -function watchRoots(args: WatchRootsArgs): IDisposable { - const { initRoot, addRoot, removeRoot } = args; - - const folders = vscode.workspace.workspaceFolders; - if (folders) { - folders.map((f) => f.uri).forEach(initRoot); - } - - return vscode.workspace.onDidChangeWorkspaceFolders((event) => { - for (const root of event.removed) { - removeRoot(root.uri); - } - for (const root of event.added) { - addRoot(root.uri); - } - }); -} - -function createWorkspaceLocator(ext: ExtensionState): WorkspaceLocators { - const locators = new WorkspaceLocators(watchRoots, [ - (root: vscode.Uri) => [ - new WorkspaceVirtualEnvironmentLocator(root.fsPath), - new PoetryLocator(root.fsPath), - new HatchLocator(root.fsPath), - new PixiLocator(root.fsPath), - new CustomWorkspaceLocator(root.fsPath), - ], - // Add an ILocator factory func here for each kind of workspace-rooted locator. - ]); - ext.disposables.push(locators); - return locators; -} - -function getFromStorage(storage: IPersistentStorage): PythonEnvInfo[] { - return storage.get().map((e) => { - if (e.searchLocation) { - if (typeof e.searchLocation === 'string') { - e.searchLocation = Uri.parse(e.searchLocation); - } else if ('scheme' in e.searchLocation && 'path' in e.searchLocation) { - e.searchLocation = Uri.parse(`${e.searchLocation.scheme}://${e.searchLocation.path}`); - } else { - traceError('Unexpected search location', JSON.stringify(e.searchLocation)); - } - } - return e; - }); -} - -function putIntoStorage(storage: IPersistentStorage, envs: PythonEnvInfo[]): Promise { - storage.set( - // We have to `cloneDeep()` here so that we don't overwrite the original `PythonEnvInfo` objects. - cloneDeep(envs).map((e) => { - if (e.searchLocation) { - // Make TS believe it is string. This is temporary. We need to serialize this in - // a custom way. - e.searchLocation = (e.searchLocation.toString() as unknown) as Uri; - } - return e; - }), - ); - return Promise.resolve(); -} - -async function createCollectionCache(ext: ExtensionState): Promise { - const storage = getGlobalStorage(ext.context, PYTHON_ENV_INFO_CACHE_KEY, []); - const cache = await createCache({ - get: () => getFromStorage(storage), - store: async (e) => putIntoStorage(storage, e), - }); - return cache; -}