Skip to content
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

Add default pythonPath #1006

Merged
merged 9 commits into from
Jan 21, 2025
Merged
8 changes: 8 additions & 0 deletions docs/benefits-over-pyright/better-defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ used to be `"basic"`, but now defaults to `"recommended"`, which enables all dia
## `pythonPlatform`

used to assume that the operating system pyright is being run on is the only operating system your code will run on, which is rarely the case. in basedpyright, `pythonPlatform` defaults to `All`, which assumes your code can run on any operating system.

## default value for `pythonPath`

configuring your python interpreter in pyright is needlessly confusing. if you aren't using vscode or you aren't running it from inside a virtual environment, you'll likely encounter errors for unresolved imports as a result of pyright using the wrong interpreter. to fix this you'd have to use the `venv` and `venvPath` settings which are unnecessarily difficult to use. for example `venv` can only be set in either [the config file](../configuration/config-files.md) or [the language server settings](../configuration/language-server-settings.md) but `venvPath` can only be set in the language server settings or [the command line](../configuration/command-line.md).

most of the time your virtual environment is located in the same spot: a folder named `.venv` in your project root. this is the case if you're using [uv](https://docs.astral.sh/uv/) (which you should be, it's far better than any alternative).

so why not just check for this known common venv path and use that by default? that's exactly what basedpyright does. if neither `pythonPath` or `venvPath`/`venv` are set, basedpyright will check for a venv at `./.venv` and if it finds one, it will use its python interpreter as the value for `pythonPath`.
20 changes: 10 additions & 10 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,6 @@ The following settings control the *environment* in which basedpyright will chec

- **stubPath** [path, optional]: Path to a directory that contains custom type stubs. Each package's type stub file(s) are expected to be in its own subdirectory. The default value of this setting is "./typings". (typingsPath is now deprecated)

- **venvPath** [path, optional]: Path to a directory containing one or more subdirectories, each of which contains a virtual environment. When used in conjunction with a **venv** setting (see below), pyright will search for imports in the virtual environment’s site-packages directory rather than the paths specified by the default Python interpreter. This setting is ignored when using Pylance. VS Code's python interpreter path is used instead.

!!! note
If you are working on a project with other developers and not using a tool like [uv](https://docs.astral.sh/uv/pip/compatibility/#virtual-environments-by-default) or [pdm](https://pdm-project.org/en/latest/usage/venv/#virtualenv-auto-creation), it is best not to specify this setting in the config file, since this path will typically differ for each developer. Instead, it can be specified on the command line or in a [per-user setting](./language-server-settings.md). For more details, refer to the [import resolution](../usage/import-resolution.md#configuring-your-python-environment) documentation.


- **venv** [string, optional]: Used in conjunction with the venvPath, specifies the virtual environment to use. For more details, refer to the [import resolution](../usage/import-resolution.md#configuring-your-python-environment) documentation. This setting is ignored when using Pylance.

- **verboseOutput** [boolean]: Specifies whether output logs should be verbose. This is useful when diagnosing certain problems like import resolution issues.

- **extraPaths** [array of strings, optional]: Additional search paths that will be used when searching for modules imported by files.
Expand Down Expand Up @@ -79,6 +71,14 @@ The following settings determine how different types should be evaluated.

- <a name="strictGenericNarrowing"></a> **strictGenericNarrowing** [boolean]: When a type is narrowed in such a way that its type parameters are not known (eg. using an `isinstance` check), basedpyright will resolve the type parameter to the generic's bound or constraint instead of `Any`. [more info](../benefits-over-pyright/improved-generic-narrowing.md)

### Discouraged settings

these settings are discouraged in basedpyright. [see here for more info](../benefits-over-pyright/better-defaults.md#default-value-for-pythonpath).

- **venvPath** [path, optional]: Path to a directory containing one or more subdirectories, each of which contains a virtual environment. When used in conjunction with a **venv** setting (see below), pyright will search for imports in the virtual environment’s site-packages directory rather than the paths specified by the default Python interpreter. This setting is ignored when using Pylance. VS Code's python interpreter path is used instead.

- **venv** [string, optional]: Used in conjunction with the venvPath, specifies the virtual environment to use. For more details, refer to the [import resolution](../usage/import-resolution.md#configuring-your-python-environment) documentation. This setting is ignored when using Pylance.

## Diagnostic Categories

diagnostics can be configured to be reported as any of the following categories:
Expand Down Expand Up @@ -293,7 +293,7 @@ The following settings allow more fine grained control over the **typeCheckingMo

- <a name="reportUnannotatedClassAttribute"></a> **reportUnannotatedClassAttribute** [boolean or string, optional]: Generate or suppress diagnostics for class attribute declarations that do not have a type annotation. These are unsafe because for performance reasons, subtypes are not validated to ensure that they are compatible with the supertype. [more info](../benefits-over-pyright/new-diagnostic-rules.md#reportunannotatedclassattribute)

## Discouraged options
### Discouraged settings

there are rules in pyright that are discouraged in basedpyright because we provide a better alternative. these options are still available for backwards compatibility, but you shouldn't use them.

Expand Down Expand Up @@ -420,7 +420,7 @@ basedpyright introduces two new diagnostic rulesets in addition to the ones in p

!!! note

some settings which are enabled by default in pyright are disabled by default in basedpyright (even when `typeCheckingMode` is `"all"`). this is because these rules are [discouraged](#discouraged-options), but in the interest of backwards compatibility with pyright, they remain available to any users who still want to use them.
some settings which are enabled by default in pyright are disabled by default in basedpyright (even when `typeCheckingMode` is `"all"`). this is because these rules are [discouraged](#discouraged-settings), but in the interest of backwards compatibility with pyright, they remain available to any users who still want to use them.
<!--8<-- [end:before-table] -->

<!-- the table is generated by a macro in configuration/config-files.md because macros don't work in snippets -->
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration/command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ basedpyright can be run as either a language server or as a command-line tool. T
(4) This feature is experimental. If thread count is > 1, multiple copies of pyright are executed in parallel to type check files in a project. If no thread count is specified, the thread count is based on the number of available logical processors (if at least 4) or 1 (if less than 4).

(5) This option is the same as the language server setting `python.venvPath`. It used in conjunction with configuration file, which can refer to different virtual environments by name. For more details, refer to the [configuration](./config-files.md) and [import resolution](../usage/import-resolution.md#configuring-your-python-environment) documentation. This allows a common config file to be checked in to the project and shared by everyone on the development team without making assumptions about the local paths to the venv directory on each developer’s computer.
!!! note
`--venvpath` is discouraged in basedpyright. [more info](../benefits-over-pyright/better-defaults.md#default-value-for-pythonpath)

(6) When running in watch mode, pyright will reanalyze only those files that have been modified. These “deltas” are typically much faster than the initial analysis, which needs to analyze all files in the source tree.

Expand Down
4 changes: 2 additions & 2 deletions docs/configuration/language-server-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ The basedpyright language server honors the following settings.

**python.venvPath** [path]: Path to folder with subdirectories that contain virtual environments. The `python.pythonPath` setting is recommended over this mechanism for most users. For more details, refer to the [import resolution](../usage/import-resolution.md#configuring-your-python-environment) documentation.

!!! note "a note about `python.venvPath`"
if your venv path is the same for all users working on your project (which should be the case if you're using [uv](https://docs.astral.sh/uv/pip/compatibility/#virtual-environments-by-default) or [pdm](https://pdm-project.org/en/latest/usage/venv/#virtualenv-auto-creation)), we recommend configuring `venvPath` in [a config file](./config-files.md) instead. see [discouraged settings](#discouraged-settings) below for more information.
!!! note
`python.venvPath` is discouraged in basedpyright. [more info](../benefits-over-pyright/better-defaults.md#default-value-for-pythonpath)

### based settings

Expand Down
4 changes: 3 additions & 1 deletion docs/usage/import-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ Pyright uses the following mechanisms (in priority order) to determine which Pyt

2. Use the `python.pythonPath` setting. This setting is defined in the language server. if using VS Code, this can be configured using the Python extension’s environment picker interface. More recent versions of the Python extension no longer store the selected Python environment in the `python.pythonPath` setting and instead use a storage mechanism that is private to the extension. Pyright is able to access this through an API exposed by the Python extension.

3. As a fallback, use the default Python environment (i.e. the one that is invoked when typing `python` in the shell).
3. If a virtual environment exists in a `.venv` folder at the project root, its python interpreter its used as the default value for `python.pythonPath`. [more info](../benefits-over-pyright/better-defaults.md#default-value-for-pythonpath)

4. As a fallback, use the default Python environment (i.e. the one that is invoked when typing `python` in the shell).

### Editable installs

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"check:prettier": "prettier -c .",
"fix:prettier": "prettier --write .",
"typecheck": "npm exec --workspaces -- tsc --noEmit",
"run:cli:windows": "npm run build:cli:dev && node packages/pyright/index.js --pythonpath .venv/Scripts/python.exe",
"run:cli:unix": "npm run build:cli:dev && node packages/pyright/index.js --pythonpath .venv/bin/python",
"run:cli": "npm run build:cli:dev && node packages/pyright/index.js",
"run:langserver": "npm run build:cli:dev && node packages/pyright/langserver.index.js --stdio",
"jest": "cd packages/pyright-internal && jest",
"update-python-deps": "uv sync --upgrade",
"update-pyprojectx-lockfile": "python pw --lock",
Expand Down
20 changes: 20 additions & 0 deletions packages/pyright-internal/src/analyzer/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,26 @@ export class AnalyzerService {
// only apply to the language server.
this._applyLanguageServerOptions(configOptions, projectRoot, commandLineOptions.languageServerSettings);

// If user didn't set either (venvPath & venv) or pythonPath, and project root is found,
// try to fill pythonPath with a default value
if (
!configOptions.venvPath &&
!configOptions.venv &&
!configOptions.pythonPath &&
(configFilePath || pyprojectFilePath)
) {
// this is the most common name used for virtual environments, and newer tools like uv and pdm default to this name.
// so if a python path hasn't been specified, we check whether a venv with this name exists in the project root.
const defaultVenvPath = '.venv';
const defaultPythonPath = projectRoot.resolvePaths(
defaultVenvPath,
process.platform === 'win32' ? 'Scripts/python.exe' : 'bin/python'
);
if (this.fs.existsSync(defaultPythonPath)) {
configOptions.pythonPath = defaultPythonPath;
}
}

// Ensure that if no command line or config options were applied, we have some defaults.
this._ensureDefaultOptions(host, configOptions, projectRoot, executionRoot, commandLineOptions);

Expand Down
Loading