Skip to content

Commit

Permalink
Add python.interpreters.include and python.interpreters.exclude s…
Browse files Browse the repository at this point in the history
…ettings (#6398)

### Summary
- addresses #3574 for both the JS and native locators
- also implements #6254 for the JS locator (previously [only implemented
for the native
locator](#6261))
- introduces new settings
- `python.interpreters.include`: List of folders to search for Python
installations. These folders are searched in addition to the default
folders for your operating system.
- `python.interpreters.exclude`: List of interpreter paths or folders to
exclude from the available Python installations. These interpreters will
not be displayed in the Positron UI. This option takes precedence over
the `include` option.
- adds new command available via Command Palette:
`python.interpreters.debugInfo`: "Print interpreter debug information to
Output"
- Opens the Python Language Pack Output and prints python interpreter
settings info as well as info about each discovered python runtime

#### Settings UI

<img width="1020" alt="image"
src="https://github.com/user-attachments/assets/137d7798-50c8-4668-9444-db9917e91417"
/>

#### Settings JSON

```json
    "python.interpreters.include": [
        "~/scratch"
    ],
    "python.interpreters.exclude": [
        "/usr/bin/python3",
        "/opt/homebrew",
        "/usr/local/bin",
        "/opt/python",
        "~/scratch"
    ]
```

#### Python Language Pack Output
Some log prefixes/messages to search for:
- `pythonRuntimeDiscoverer`: to find out if any runtimes were filtered
out during discovery
- `shouldIncludeInterpreter`: whether or not the interpreter will be
included based on the user settings
- `Not registering runtime ${extraData.pythonPath} as it is excluded via
user settings.`: if the runtime is not getting registered because the
user excluded it
- `getAdditionalEnvDirs`: native python finder -- list all the
additional directories being searched, such as the user-included dirs

<details><summary>Sample Output from `python.interpreters.debugInfo`:
"Print interpreter debug information to Output"</summary>

```js
2025-02-24 10:43:17.026 [info] =====================================================================
2025-02-24 10:43:17.026 [info] =============== [START] PYTHON INTERPRETER DEBUG INFO ===============
2025-02-24 10:43:17.026 [info] =====================================================================
2025-02-24 10:43:17.026 [info] Python interpreter settings: {
  defaultInterpreterPath: '/Users/hello/qa-example-content/.venv/bin/python',
  'interpreters.include': [ '/Users/hello/scratch' ],
  'interpreters.exclude': [
    '/usr/bin/python3',
    '/opt/homebrew',
    '/usr/local/bin',
    '/opt/python',
    '/Users/hello/scratch'
  ]
}
2025-02-24 10:43:17.026 [info] Python interpreters discovered: [
  {
    name: 'Python 3.13.1 64-bit',
    path: '/opt/homebrew/bin/python3',
    versionInfo: { version: '3.13.1', supportedVersion: true },
    envInfo: { envType: 'Global', envName: '' },
    enablementInfo: {
      visibleInUI: false,
      includedInSettings: false,
      excludedInSettings: true
    }
  },
  {
    name: 'Python 3.10.4 64-bit',
    path: '/opt/python/3.10.4/bin/python',
    versionInfo: { version: '3.10.4', supportedVersion: true },
    envInfo: { envType: 'Unknown', envName: '' },
    enablementInfo: {
      visibleInUI: false,
      includedInSettings: false,
      excludedInSettings: true
    }
  },
  {
    name: "Python 3.12.2 64-bit ('3.12.2': pyenv)",
    path: '/Users/hello/.pyenv/versions/3.12.2/bin/python',
    versionInfo: { version: '3.12.2', supportedVersion: true },
    envInfo: { envType: 'Pyenv', envName: '3.12.2' },
    enablementInfo: {
      visibleInUI: true,
      includedInSettings: false,
      excludedInSettings: false
    }
  },
  {
    name: "Python 3.6.15 64-bit ('3.6.15': pyenv)",
    path: '/Users/hello/.pyenv/versions/3.6.15/bin/python',
    versionInfo: { version: '3.6.15', supportedVersion: false },
    envInfo: { envType: 'Pyenv', envName: '3.6.15' },
    enablementInfo: {
      visibleInUI: true,
      includedInSettings: false,
      excludedInSettings: false
    }
  },
  {
    name: "Python 3.10.4 ('.venv': venv)",
    path: '/Users/hello/qa-example-content/.venv/bin/python',
    versionInfo: { version: '3.10.4', supportedVersion: true },
    envInfo: { envType: 'Venv', envName: '.venv' },
    enablementInfo: {
      visibleInUI: true,
      includedInSettings: false,
      excludedInSettings: false
    }
  },
  {
    name: 'Python 3.10.4 64-bit (custom)',
    path: '/Users/hello/scratch/3.10.4/bin/python',
    versionInfo: { version: '3.10.4', supportedVersion: true },
    envInfo: { envType: 'Unknown', envName: '' },
    enablementInfo: {
      visibleInUI: false,
      includedInSettings: true,
      excludedInSettings: true
    }
  },
  {
    name: 'Python 3.9.6 64-bit',
    path: '/usr/bin/python3',
    versionInfo: { version: '3.9.6', supportedVersion: true },
    envInfo: { envType: 'Global', envName: '' },
    enablementInfo: {
      visibleInUI: false,
      includedInSettings: false,
      excludedInSettings: true
    }
  },
  {
    name: 'Python 3.10.4 64-bit',
    path: '/usr/local/bin/python3',
    versionInfo: { version: '3.10.4', supportedVersion: true },
    envInfo: { envType: 'Global', envName: '' },
    enablementInfo: {
      visibleInUI: false,
      includedInSettings: false,
      excludedInSettings: true
    }
  },
  {
    name: 'Python 3.11.6 64-bit',
    path: '/usr/local/bin/python3.11',
    versionInfo: { version: '3.11.6', supportedVersion: true },
    envInfo: { envType: 'Global', envName: '' },
    enablementInfo: {
      visibleInUI: false,
      includedInSettings: false,
      excludedInSettings: true
    }
  }
]
2025-02-24 10:43:17.026 [info] =====================================================================
2025-02-24 10:43:17.026 [info] ================ [END] PYTHON INTERPRETER DEBUG INFO ================
2025-02-24 10:43:17.026 [info] =====================================================================


```

</details> 


### Release Notes

#### New Features

- New settings to include additional Python interpreter search
directories or exclude Python interpreters from the UI (#3574)

#### Bug Fixes

- filters out unsupported (<3.8) Python versions from the `Python:
Select Interpreter` dropdown (#3740) @isabelizimm

### QA Notes

- Please verify these options using both the JS and Native locators.
Toggle between the locators by updating setting `python.locator`.
- Positron will need to be restarted upon changing the
`python.interpreters.include`/`python.interpreters.exclude` settings so
that discovery can re-run with the settings applied
- If an interpreter path is captured in both options, it will be
excluded
- If a user has a python install they want to include at path
`/1/2/3/4/5/3.10.4/bin/python`, they should use `/1/2/3/4/5` or
`/1/2/3/4/5/3.10.4` as the included directory.
- Windows users can specify paths with either path separator
- Relative paths specified in the options are ignored
- If a user starts an interpreter, then excludes or un-includes it and
restarts Positron, it will still be selected upon restart
    - if they shut it down and then restart, it should no longer show

---------

Co-authored-by: Isabel Zimmerman <54685329+isabelizimm@users.noreply.github.com>
  • Loading branch information
sharon-wang and isabelizimm authored Feb 24, 2025
1 parent e069410 commit b0a41ac
Show file tree
Hide file tree
Showing 19 changed files with 788 additions and 40 deletions.
25 changes: 25 additions & 0 deletions extensions/positron-python/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,11 @@
"category": "Python",
"command": "python.installJupyter",
"title": "%python.command.python.installJupyter.title%"
},
{
"category": "Python",
"command": "python.interpreters.debugInfo",
"title": "%python.command.python.interpreterDebugInfo.title%"
}
],
"configuration": {
Expand Down Expand Up @@ -530,6 +535,26 @@
"scope": "machine-overridable",
"type": "string"
},
"python.interpreters.include": {
"default": [],
"markdownDescription": "%python.interpreters.include.markdownDescription%",
"scope": "window",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"python.interpreters.exclude": {
"default": [],
"markdownDescription": "%python.interpreters.exclude.markdownDescription%",
"scope": "window",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"python.envFile": {
"default": "${workspaceFolder}/.env",
"description": "%python.envFile.description%",
Expand Down
3 changes: 3 additions & 0 deletions extensions/positron-python/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"python.command.python.analysis.restartLanguageServer.title": "Restart Language Server",
"python.command.python.launchTensorBoard.title": "Launch TensorBoard",
"python.command.python.refreshTensorBoard.title": "Refresh TensorBoard",
"python.command.python.interpreterDebugInfo.title": "Print interpreter debug information to Output",
"python.createEnvironment.contentButton.description": "Show or hide Create Environment button in the editor for `requirements.txt` or other dependency files.",
"python.createEnvironment.trigger.description": "Detect if environment creation is required for the current project",
"python.menu.createNewFile.title": "Python File",
Expand All @@ -49,6 +50,8 @@
"python.condaPath.description": "Path to the conda executable to use for activation (version 4.4+).",
"python.debugger.deprecatedMessage": "This configuration will be deprecated soon. Please replace `python` with `debugpy` to use the new Python Debugger extension.",
"python.defaultInterpreterPath.description": "Path to default Python to use when extension loads up for the first time, no longer used once an interpreter is selected for the workspace. See [here](https://aka.ms/AAfekmf) to understand when this is used",
"python.interpreters.include.markdownDescription": "List of folders (absolute paths) to search for Python installations. These folders are searched in addition to the default folders for your operating system.\n\nExample: if you have Python located at `/custom/pythons/3.10.4/bin/python`, add path `/custom/pythons` or `/custom/pythons/3.10.4` to this setting.\n\nNote: If an interpreter is both included via `python.interpreters.include` and excluded via `python.interpreters.exclude`, it will not be displayed in the Positron UI.\n\nRequires a restart to take effect.",
"python.interpreters.exclude.markdownDescription": "List of interpreter paths or folders (absolute paths) to exclude from the available Python installations. These interpreters will not be displayed in the Positron UI.\n\nExample: Add `/usr/bin/python3` to exclude the specific interpreter, or `/opt/homebrew` to exclude all brew-installed Pythons on macOS.\n\nRequires a restart to take effect.",
"python.envFile.description": "Absolute path to a file containing environment variable definitions.",
"python.experiments.enabled.description": "Enables A/B tests experiments in the Python extension. If enabled, you may get included in proposed enhancements and/or features.",
"python.experiments.optInto.description": "List of experiments to opt into. If empty, user is assigned the default experiment groups. See [here](https://github.com/microsoft/vscode-python/wiki/AB-Experiments) for more details.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ interface ICommandNameWithoutArgumentTypeMapping {
[Commands.CreateNewFile]: [];
[Commands.ReportIssue]: [];
[LSCommands.RestartLS]: [];
// --- Start Positron ---
[Commands.Show_Interpreter_Debug_Info]: [];
// --- End Positron ---
}

export type AllCommands = keyof ICommandNameArgumentTypeMapping;
Expand Down
30 changes: 30 additions & 0 deletions extensions/positron-python/src/client/common/configSettings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
'use strict';

// --- Start Positron ---
/* eslint-disable import/no-duplicates */
// --- End Positron ---

// eslint-disable-next-line camelcase
import * as path from 'path';
import * as fs from 'fs';
Expand Down Expand Up @@ -38,6 +42,10 @@ import { SystemVariables } from './variables/systemVariables';
import { getOSType, OSType, isWindows } from './utils/platform';
import { untildify } from './helpers';

// --- Start Positron ---
import { INTERPRETERS_EXCLUDE_SETTING_KEY, INTERPRETERS_INCLUDE_SETTING_KEY } from './constants';
// --- End Positron ---

export class PythonSettings implements IPythonSettings {
private get onDidChange(): Event<ConfigurationChangeEvent | undefined> {
return this.changed.event;
Expand Down Expand Up @@ -82,6 +90,16 @@ export class PythonSettings implements IPythonSettings {
}
}

// --- Start Positron ---
public get interpretersInclude(): string[] {
return this._interpretersInclude;
}

public get interpretersExclude(): string[] {
return this._interpretersExclude;
}
// --- End Positron ---

private static pythonSettings: Map<string, PythonSettings> = new Map<string, PythonSettings>();

public envFile = '';
Expand Down Expand Up @@ -143,6 +161,12 @@ export class PythonSettings implements IPythonSettings {

private _defaultInterpreterPath = '';

// --- Start Positron ---
private _interpretersInclude: string[] = [];

private _interpretersExclude: string[] = [];
// --- End Positron ---

private readonly workspace: IWorkspaceService;

constructor(
Expand Down Expand Up @@ -310,6 +334,12 @@ export class PythonSettings implements IPythonSettings {

// Whether to suppress the banner on startup of the IPython shell
this.quietMode = pythonSettings.get<boolean>('quietMode') === true;

// User-specified interpreter paths to include in discovery
this._interpretersInclude = pythonSettings.get<string[]>(INTERPRETERS_INCLUDE_SETTING_KEY) ?? [];

// User-specified interpreter paths to exclude from available interpreters
this._interpretersExclude = pythonSettings.get<string[]>(INTERPRETERS_EXCLUDE_SETTING_KEY) ?? [];
// --- End Positron ---

const autoCompleteSettings = systemVariables.resolveAny(
Expand Down
3 changes: 3 additions & 0 deletions extensions/positron-python/src/client/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export namespace Commands {
export const Is_Conda_Installed = 'python.isCondaInstalled';
export const Get_Conda_Python_Versions = 'python.getCondaPythonVersions';
export const Is_Global_Python = 'python.isGlobalPython';
export const Show_Interpreter_Debug_Info = 'python.interpreters.debugInfo';
// --- End Positron ---
export const InstallJupyter = 'python.installJupyter';
export const InstallPython = 'python.installPython';
Expand Down Expand Up @@ -149,6 +150,8 @@ export const UseProposedApi = Symbol('USE_VSC_PROPOSED_API');
// --- Start Positron ---
export const IPYKERNEL_VERSION = '>=6.19.1';
export const MINIMUM_PYTHON_VERSION = { major: 3, minor: 8, patch: 0, raw: '3.8.0' } as PythonVersion;
export const INTERPRETERS_INCLUDE_SETTING_KEY = 'interpreters.include';
export const INTERPRETERS_EXCLUDE_SETTING_KEY = 'interpreters.exclude';
// --- End Positron

export * from '../constants';
2 changes: 2 additions & 0 deletions extensions/positron-python/src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ export interface IPythonSettings {
readonly languageServerDebug: boolean;
readonly languageServerLogLevel: string;
readonly quietMode: boolean;
readonly interpretersInclude: string[];
readonly interpretersExclude: string[];
// --- End Positron ---
readonly defaultInterpreterPath: string;
readonly REPL: IREPLSettings;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// --- Start Positron ---
// Disable eslint rules for our import block below. This appears at the top of the file to stop
// auto-formatting tools from reordering the imports.
/* eslint-disable import/no-duplicates */
// --- End Positron ---

'use strict';

Expand Down Expand Up @@ -50,11 +55,12 @@ import { BaseInterpreterSelectorCommand } from './base';
// --- Start Positron ---
// eslint-disable-next-line import/order
import * as fs from 'fs-extra';
// eslint-disable-next-line import/no-duplicates
import { CreateEnv } from '../../../../common/utils/localize';
import { IPythonRuntimeManager } from '../../../../positron/manager';
import { showErrorMessage } from '../../../../common/vscodeApis/windowApis';
import { traceError } from '../../../../logging';
import { isVersionSupported, shouldIncludeInterpreter } from '../../../../positron/interpreterSettings';
import { MINIMUM_PYTHON_VERSION } from '../../../../common/constants';
// --- End Positron ---
import { untildify } from '../../../../common/helpers';
import { useEnvExtension } from '../../../../envExt/api.internal';
Expand Down Expand Up @@ -283,7 +289,11 @@ export class SetInterpreterCommand extends BaseInterpreterSelectorCommand implem
if (defaultInterpreterPathSuggestion) {
suggestions.push(defaultInterpreterPathSuggestion);
}
const interpreterSuggestions = this.getSuggestions(resource, filter, params);

// --- Start Positron ---
// Apply additional filtering to the suggestions by wrapping the filter
const interpreterSuggestions = this.getSuggestions(resource, filterWrapper(filter), params);
// --- End Positron ---
this.finalizeItems(interpreterSuggestions, resource, params);
suggestions.push(...interpreterSuggestions);
return suggestions;
Expand Down Expand Up @@ -399,7 +409,11 @@ export class SetInterpreterCommand extends BaseInterpreterSelectorCommand implem
const updatedItems = [...items.values()];
const areItemsGrouped = items.find((item) => isSeparatorItem(item));
const env = event.old ?? event.new;
if (filter && event.new && !filter(event.new)) {

// --- Start Positron ---
// Apply additional filtering to the suggestions by wrapping the filter
if (filterWrapper(filter) && event.new && !filterWrapper(filter)(event.new)) {
// --- End Positron ---
event.new = undefined; // Remove envs we're not looking for from the list.
}
let envIndex = -1;
Expand Down Expand Up @@ -719,3 +733,18 @@ function getGroup(item: IInterpreterQuickPickItem, workspacePath?: string) {
return EnvGroups[item.interpreter.envType];
}
}

// --- Start Positron ---
/**
* Wraps the original filter function to include additional filtering logic.
* If no filter is provided, the returned function will only include the additional filtering logic.
* @param filter The original filter function
* @returns A new filter function that includes the original filter function and the additional filtering logic
*/
function filterWrapper(filter: ((i: PythonEnvironment) => boolean) | undefined) {
return (i: PythonEnvironment) =>
(filter ? filter(i) : true) &&
shouldIncludeInterpreter(i.path) &&
isVersionSupported(i.version, MINIMUM_PYTHON_VERSION);
}
// --- End Positron ---
79 changes: 50 additions & 29 deletions extensions/positron-python/src/client/positron/discoverer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2024 Posit Software, PBC. All rights reserved.
* Copyright (C) 2024-2025 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

Expand All @@ -12,10 +12,10 @@ import { IInterpreterService } from '../interpreter/contracts';
import { IServiceContainer } from '../ioc/types';
import { traceError, traceInfo } from '../logging';
import { PythonEnvironment } from '../pythonEnvironments/info';
import { PythonVersion } from '../pythonEnvironments/info/pythonVersion';
import { createPythonRuntimeMetadata } from './runtime';
import { comparePythonVersionDescending } from '../interpreter/configuration/environmentTypeComparer';
import { MINIMUM_PYTHON_VERSION } from '../common/constants';
import { isVersionSupported, shouldIncludeInterpreter } from './interpreterSettings';

/**
* Provides Python language runtime metadata to Positron; called during the
Expand Down Expand Up @@ -49,12 +49,19 @@ export async function* pythonRuntimeDiscoverer(

// Discover Python interpreters
let interpreters = interpreterService.getInterpreters();

traceInfo(`pythonRuntimeDiscoverer: discovered ${interpreters.length} Python interpreters`);

// Filter out unsupported and user-excluded interpreters
traceInfo('pythonRuntimeDiscoverer: filtering interpreters');
interpreters = filterInterpreters(interpreters);

traceInfo(`pythonRuntimeDiscoverer: ${interpreters.length} Python interpreters remain after filtering`);

// Sort the available interpreters, favoring the recommended interpreter (if one is available)
traceInfo('pythonRuntimeDiscoverer: sorting interpreters');
interpreters = sortInterpreters(interpreters, recommendedInterpreter);

traceInfo(`pythonRuntimeDiscoverer: discovered ${interpreters.length} Python interpreters`);

// Recommend Python for the workspace if it contains Python-relevant files
let recommendedForWorkspace = await hasFiles([
// Code and notebook files
Expand All @@ -75,23 +82,19 @@ export async function* pythonRuntimeDiscoverer(
// Register each interpreter as a language runtime metadata entry
for (const interpreter of interpreters) {
try {
if (isVersionSupported(interpreter?.version, MINIMUM_PYTHON_VERSION)) {
const runtime = await createPythonRuntimeMetadata(
interpreter,
serviceContainer,
recommendedForWorkspace,
);

// Ensure we only recommend one runtime for the workspace.
recommendedForWorkspace = false;

traceInfo(
`pythonRuntimeDiscoverer: registering runtime for interpreter ${interpreter.path} with id ${runtime.runtimeId}`,
);
yield runtime;
} else {
traceInfo(`pythonRuntimeDiscoverer: skipping unsupported interpreter ${interpreter.path}`);
}
const runtime = await createPythonRuntimeMetadata(
interpreter,
serviceContainer,
recommendedForWorkspace,
);

// Ensure we only recommend one runtime for the workspace.
recommendedForWorkspace = false;

traceInfo(
`pythonRuntimeDiscoverer: registering runtime for interpreter ${interpreter.path} with id ${runtime.runtimeId}`,
);
yield runtime;
} catch (err) {
traceError(
`pythonRuntimeDiscoverer: failed to register runtime for interpreter ${interpreter.path}`,
Expand All @@ -104,6 +107,32 @@ export async function* pythonRuntimeDiscoverer(
}
}

/**
* Returns a list of Python interpreters with unsupported and user-excluded interpreters removed.
* @param interpreters The list of Python interpreters to filter.
* @returns A list of Python interpreters that are supported and not user-excluded.
*/
function filterInterpreters(interpreters: PythonEnvironment[]): PythonEnvironment[] {
return interpreters.filter((interpreter) => {
// Check if the interpreter version is supported
const isSupported = isVersionSupported(interpreter.version, MINIMUM_PYTHON_VERSION);
if (!isSupported) {
traceInfo(`pythonRuntimeDiscoverer: filtering out unsupported interpreter ${interpreter.path}`);
return false;
}

// Check if the interpreter is excluded by the user
const shouldInclude = shouldIncludeInterpreter(interpreter.path);
if (!shouldInclude) {
traceInfo(`pythonRuntimeDiscoverer: filtering out user-excluded interpreter ${interpreter.path}`);
return false;
}

// Otherwise, keep the interpreter!
return true;
});
}

// Returns a sorted copy of the array of Python environments, in descending order
function sortInterpreters(
interpreters: PythonEnvironment[],
Expand All @@ -130,11 +159,3 @@ async function hasFiles(includes: string[]): Promise<boolean> {
// Exclude node_modules for performance reasons
return (await vscode.workspace.findFiles(include, '**/node_modules/**', 1)).length > 0;
}

/**
* Check if a version is supported (i.e. >= the minimum supported version).
* Also returns true if the version could not be determined.
*/
function isVersionSupported(version: PythonVersion | undefined, minimumSupportedVersion: PythonVersion): boolean {
return !version || comparePythonVersionDescending(minimumSupportedVersion, version) >= 0;
}
15 changes: 14 additions & 1 deletion extensions/positron-python/src/client/positron/extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2023-2024 Posit Software, PBC. All rights reserved.
* Copyright (C) 2023-2025 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

Expand All @@ -18,6 +18,7 @@ import { Interpreters } from '../common/utils/localize';
import { IApplicationShell } from '../common/application/types';
import { activateAppDetection as activateWebAppDetection } from './webAppContexts';
import { activateWebAppCommands } from './webAppCommands';
import { printInterpreterDebugInfo } from './interpreterSettings';

export async function activatePositron(serviceContainer: IServiceContainer): Promise<void> {
try {
Expand Down Expand Up @@ -73,6 +74,18 @@ export async function activatePositron(serviceContainer: IServiceContainer): Pro
disposables.push(
vscode.commands.registerCommand('python.getMinimumPythonVersion', (): string => MINIMUM_PYTHON_VERSION.raw),
);
// Register a command to output information about Python environments.
disposables.push(
vscode.commands.registerCommand(Commands.Show_Interpreter_Debug_Info, async () => {
// Open up the Python Language Pack output channel.
await vscode.commands.executeCommand(Commands.ViewOutput);

// Log information about the Python environments.
const interpreterService = serviceContainer.get<IInterpreterService>(IInterpreterService);
const interpreters = interpreterService.getInterpreters();
printInterpreterDebugInfo(interpreters);
}),
);

// Activate detection for web applications
activateWebAppDetection(disposables);
Expand Down
Loading

0 comments on commit b0a41ac

Please sign in to comment.