@@ -11,19 +11,16 @@ import {
1111 ResolvedEnvironment ,
1212 Resource ,
1313} from '@vscode/python-extension' ;
14- import { commands , EventEmitter , extensions , Uri , Event , Disposable , Extension } from 'vscode' ;
15- import { createDeferred } from './utils/async' ;
14+ import { commands , EventEmitter , extensions , Uri , Event , Disposable } from 'vscode' ;
1615import { traceError , traceLog } from './log/logging' ;
16+ import { PythonEnvironment , PythonEnvironmentApi , PythonEnvsExtension } from '../envExtApi' ;
1717
18- /**
19- * Interface for the Python extension API.
20- */
21- interface IExtensionApi {
22- ready : Promise < void > ;
23- settings : {
24- getExecutionDetails ( resource ?: Resource ) : { execCommand : string [ ] | undefined } ;
25- } ;
26- }
18+ // interface IExtensionApi {
19+ // ready: Promise<void>;
20+ // settings: {
21+ // getExecutionDetails(resource?: Resource): { execCommand: string[] | undefined };
22+ // };
23+ // }
2724
2825/**
2926 * Details about a Python interpreter.
@@ -70,20 +67,18 @@ async function activateEnvsExtension(): Promise<Extension<any> | undefined> {
7067 return extension ;
7168}
7269
73- /**
74- * Gets the Python extension's API interface.
75- * @returns The Python extension API or undefined if not available
76- */
77- async function getPythonExtensionAPI ( ) : Promise < IExtensionApi | undefined > {
78- const extension = await activateExtension ( ) ;
79- return extension ?. exports as IExtensionApi ;
70+ async function getPythonEnviromentExtensionAPI ( ) : Promise < PythonEnvironmentApi > {
71+ // Load the Python extension API
72+ await activateEnvsExtension ( ) ;
73+ return await PythonEnvsExtension . api ( ) ;
8074}
8175
82- /**
83- * Gets the Python extension's environment API.
84- * @returns The Python extension environment API
85- */
86- async function getPythonExtensionEnviromentAPI ( ) : Promise < PythonExtension > {
76+ // async function getLegacyPythonExtensionAPI(): Promise<IExtensionApi | undefined> {
77+ // const extension = await activateExtension();
78+ // return extension?.exports as IExtensionApi;
79+ // }
80+
81+ async function getLegacyPythonExtensionEnviromentAPI ( ) : Promise < PythonExtension > {
8782 // Load the Python extension API
8883 await activateExtension ( ) ;
8984 return await PythonExtension . api ( ) ;
@@ -95,7 +90,7 @@ async function getPythonExtensionEnviromentAPI(): Promise<PythonExtension> {
9590 */
9691export async function initializePython ( disposables : Disposable [ ] ) : Promise < void > {
9792 try {
98- const api = await getPythonExtensionEnviromentAPI ( ) ;
93+ const api = await getLegacyPythonExtensionEnviromentAPI ( ) ;
9994
10095 if ( api ) {
10196 disposables . push (
@@ -140,86 +135,115 @@ export async function runPythonExtensionCommand(command: string, ...rest: any[])
140135 * @returns Array of command components or undefined if not available
141136 */
142137export async function getSettingsPythonPath ( resource ?: Uri ) : Promise < string [ ] | undefined > {
143- const api = await getPythonExtensionAPI ( ) ;
144- return api ?. settings . getExecutionDetails ( resource ) . execCommand ;
138+ // const api = await getLegacyPythonExtensionAPI();
139+ // return api?.settings.getExecutionDetails(resource).execCommand;
140+
141+ const apiNew = await getPythonEnviromentExtensionAPI ( ) ;
142+ const abc : PythonEnvironment [ ] = await apiNew . getEnvironments ( resource || 'all' ) ;
143+ console . log ( 'Python envs:' , abc ) ;
144+ return undefined ;
145145}
146146
147- /**
148- * Returns the environment variables used by the extension for a resource, which includes the custom
149- * variables configured by user in `.env` files.
150- * @param resource Optional workspace resource to get environment variables for
151- * @returns Environment variables object
152- */
153- export async function getEnvironmentVariables ( resource ?: Resource ) : Promise < EnvironmentVariables > {
154- const api = await getPythonExtensionEnviromentAPI ( ) ;
155- return Promise . resolve ( api . environments . getEnvironmentVariables ( resource ) ) ;
147+ export async function getEnvironmentVariables ( resource ?: Resource ) {
148+ const api = await getLegacyPythonExtensionEnviromentAPI ( ) ;
149+ return api . environments . getEnvironmentVariables ( resource ) ;
156150}
157151
158- /**
159- * Returns details for the given environment, or `undefined` if the env is invalid.
160- * @param env Environment to resolve (can be Environment object, path, or string)
161- * @returns Resolved environment details
162- */
163152export async function resolveEnvironment (
164153 env : Environment | EnvironmentPath | string ,
154+ ) : Promise < PythonEnvironment | undefined > {
155+ // const api = await getLegacyPythonExtensionEnviromentAPI();
156+ // return api.environments.resolveEnvironment(env);
157+
158+ const apiNew = await getPythonEnviromentExtensionAPI ( ) ;
159+
160+ // Handle different input types for the new API
161+ if ( typeof env === 'string' ) {
162+ // Convert string path to Uri for the new API
163+ return apiNew . resolveEnvironment ( Uri . file ( env ) ) ;
164+ } else if ( typeof env === 'object' && 'path' in env ) {
165+ // EnvironmentPath has a uri property
166+ return apiNew . resolveEnvironment ( Uri . file ( env . path ) ) ;
167+ } else {
168+ return undefined ;
169+ }
170+ }
171+
172+ export async function legacyResolveEnvironment (
173+ env : Environment | EnvironmentPath | string ,
165174) : Promise < ResolvedEnvironment | undefined > {
166- const api = await getPythonExtensionEnviromentAPI ( ) ;
175+ const api = await getLegacyPythonExtensionEnviromentAPI ( ) ;
167176 return api . environments . resolveEnvironment ( env ) ;
168177}
169178
170- /**
171- * Returns the environment configured by user in settings. Note that this can be an invalid environment, use
172- * resolve the environment to get full details.
173- * @param resource Optional workspace resource to get active environment for
174- * @returns Path to the active environment
175- */
176- export async function getActiveEnvironmentPath ( resource ?: Resource ) : Promise < EnvironmentPath > {
177- const api = await getPythonExtensionEnviromentAPI ( ) ;
179+ export async function getLegacyActiveEnvironmentPath ( resource ?: Resource ) {
180+ const api = await getLegacyPythonExtensionEnviromentAPI ( ) ;
178181 return api . environments . getActiveEnvironmentPath ( resource ) ;
179182}
180183
184+ export async function getActiveEnvironmentPath ( resource ?: Resource ) : Promise < PythonEnvironment | undefined > {
185+ const api = await getPythonEnviromentExtensionAPI ( ) ;
186+
187+ // Convert Resource to Uri if it exists
188+ let resourceUri : Uri | undefined ;
189+ if ( resource instanceof Uri ) {
190+ resourceUri = resource ;
191+ } else if ( resource && 'uri' in resource ) {
192+ // WorkspaceFolder type
193+ resourceUri = resource . uri ;
194+ }
195+
196+ return api . getEnvironment ( resourceUri ) ;
197+ }
198+
181199/**
182- * Gets detailed information about the active Python interpreter.
183- * @param resource Optional workspace resource to get interpreter details for
184- * @returns Interpreter details including path and resource information
200+ * Gets Python interpreter details using the legacy Python extension API.
201+ *
202+ * This function retrieves the active Python environment for a given resource using the
203+ * legacy @vscode/python-extension API. It resolves the environment to get the executable
204+ * path and handles path quoting for paths containing spaces.
205+ *
206+ * @param resource Optional URI to specify the workspace/folder context for interpreter selection
207+ * @returns Promise resolving to interpreter details containing the executable path and resource
185208 */
186- export async function getInterpreterDetails ( resource ?: Uri ) : Promise < IInterpreterDetails > {
187- const api = await getPythonExtensionEnviromentAPI ( ) ;
209+ export async function getLegacyInterpreterDetails ( resource ?: Uri ) : Promise < IInterpreterDetails > {
210+ const api = await getLegacyPythonExtensionEnviromentAPI ( ) ;
211+
188212 const environment = await api . environments . resolveEnvironment ( api . environments . getActiveEnvironmentPath ( resource ) ) ;
189213 if ( environment ?. executable . uri ) {
190214 return { path : [ environment ?. executable . uri . fsPath ] , resource } ;
191215 }
192216 return { path : undefined , resource } ;
193217}
194218
195- /**
196- * Checks if any Python interpreters are available in the system.
197- * @returns True if interpreters are found, false otherwise
198- */
199- export async function hasInterpreters ( ) : Promise < boolean > {
200- const api = await getPythonExtensionEnviromentAPI ( ) ;
201- const onAddedToCollection = createDeferred ( ) ;
202- api . environments . onDidChangeEnvironments ( async ( ) => {
203- if ( api . environments . known ) {
204- onAddedToCollection . resolve ( ) ;
205- }
206- } ) ;
207- const initialEnvs = api . environments . known ;
208- if ( initialEnvs . length > 0 ) {
209- return true ;
219+ export function quoteStringIfNecessary ( arg : string ) : string {
220+ // Always return if already quoted to avoid double-quoting
221+ if ( arg . startsWith ( '"' ) && arg . endsWith ( '"' ) ) {
222+ return arg ;
210223 }
211- // Initiates a refresh of Python environments within the specified scope.
212- await Promise . race ( [ onAddedToCollection . promise , api ?. environments . refreshEnvironments ( ) ] ) ;
213224
214- return api . environments . known . length > 0 ;
225+ // Quote if contains common shell special characters that are problematic across multiple shells
226+ // Includes: space, &, |, <, >, ;, ', ", `, (, ), [, ], {, }, $
227+ const needsQuoting = / [ \s & | < > ; ' " ` ( ) \[ \] { } $ ] / . test ( arg ) ;
228+
229+ return needsQuoting ? `"${ arg } "` : arg ;
215230}
216231
217- /**
218- * Gets environments known to the extension at the time of fetching the property. Note this may not
219- * contain all environments in the system as a refresh might be going on.
220- * @returns Array of known Python environments
221- */
222- export async function getInterpreters ( ) : Promise < readonly Environment [ ] > {
223- const api = await getPythonExtensionEnviromentAPI ( ) ;
224- return api . environments . known || [ ] ;
232+ export async function getInterpreterDetails ( resource ?: Uri ) : Promise < IInterpreterDetails > {
233+ const api = await getPythonEnviromentExtensionAPI ( ) ;
234+
235+ // A promise that resolves to the current Python environment, or undefined if none is set.
236+ const env : PythonEnvironment | undefined = await api . getEnvironment ( resource ) ;
237+ // resolve the environment to get full details
238+ const resolvedEnv = env ? await api . resolveEnvironment ( env ?. environmentPath ) : undefined ;
239+ const executablePath = resolvedEnv ?. execInfo . activatedRun ?. executable
240+ ? resolvedEnv . execInfo . activatedRun . executable
241+ : resolvedEnv ?. execInfo . run . executable ;
242+
243+ // Quote the executable path if necessary
244+ const a : IInterpreterDetails = {
245+ path : executablePath ? [ quoteStringIfNecessary ( executablePath ) ] : undefined ,
246+ resource,
247+ } ;
248+ return a ;
225249}
0 commit comments