Skip to content

Commit 4732c58

Browse files
authored
Rename venv-path to python (#16347)
1 parent 45bae29 commit 4732c58

12 files changed

Lines changed: 83 additions & 59 deletions

File tree

crates/red_knot/src/args.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ pub(crate) struct CheckCommand {
4141
#[arg(long, value_name = "PROJECT")]
4242
pub(crate) project: Option<SystemPathBuf>,
4343

44-
/// Path to the virtual environment the project uses.
44+
/// Path to the Python installation from which Red Knot resolves type information and third-party dependencies.
4545
///
46-
/// If provided, red-knot will use the `site-packages` directory of this virtual environment
47-
/// to resolve type information for the project's third-party dependencies.
46+
/// Red Knot will search in the path's `site-packages` directories for type information and
47+
/// third-party imports.
48+
///
49+
/// This option is commonly used to specify the path to a virtual environment.
4850
#[arg(long, value_name = "PATH")]
49-
pub(crate) venv_path: Option<SystemPathBuf>,
51+
pub(crate) python: Option<SystemPathBuf>,
5052

5153
/// Custom directory to use for stdlib typeshed stubs.
5254
#[arg(long, value_name = "PATH", alias = "custom-typeshed-dir")]
@@ -97,7 +99,7 @@ impl CheckCommand {
9799
python_version: self
98100
.python_version
99101
.map(|version| RangedValue::cli(version.into())),
100-
venv_path: self.venv_path.map(RelativePathBuf::cli),
102+
python: self.python.map(RelativePathBuf::cli),
101103
typeshed: self.typeshed.map(RelativePathBuf::cli),
102104
extra_paths: self.extra_search_path.map(|extra_search_paths| {
103105
extra_search_paths

crates/red_knot/src/main.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use red_knot_project::{watch, Db};
1616
use red_knot_project::{ProjectDatabase, ProjectMetadata};
1717
use red_knot_server::run_server;
1818
use ruff_db::diagnostic::{Diagnostic, DisplayDiagnosticConfig, Severity};
19-
use ruff_db::system::{OsSystem, System, SystemPath, SystemPathBuf};
19+
use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf};
2020
use salsa::plumbing::ZalsaDatabase;
2121

2222
mod args;
@@ -69,7 +69,7 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
6969
let _guard = setup_tracing(verbosity)?;
7070

7171
// The base path to which all CLI arguments are relative to.
72-
let cli_base_path = {
72+
let cwd = {
7373
let cwd = std::env::current_dir().context("Failed to get the current working directory")?;
7474
SystemPathBuf::from_path_buf(cwd)
7575
.map_err(|path| {
@@ -80,25 +80,27 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
8080
})?
8181
};
8282

83-
let cwd = args
83+
let project_path = args
8484
.project
8585
.as_ref()
86-
.map(|cwd| {
87-
if cwd.as_std_path().is_dir() {
88-
Ok(SystemPath::absolute(cwd, &cli_base_path))
86+
.map(|project| {
87+
if project.as_std_path().is_dir() {
88+
Ok(SystemPath::absolute(project, &cwd))
8989
} else {
90-
Err(anyhow!("Provided project path `{cwd}` is not a directory"))
90+
Err(anyhow!(
91+
"Provided project path `{project}` is not a directory"
92+
))
9193
}
9294
})
9395
.transpose()?
94-
.unwrap_or_else(|| cli_base_path.clone());
96+
.unwrap_or_else(|| cwd.clone());
9597

9698
let system = OsSystem::new(cwd);
9799
let watch = args.watch;
98100
let exit_zero = args.exit_zero;
99101

100102
let cli_options = args.into_options();
101-
let mut project_metadata = ProjectMetadata::discover(system.current_directory(), &system)?;
103+
let mut project_metadata = ProjectMetadata::discover(&project_path, &system)?;
102104
project_metadata.apply_cli_options(cli_options.clone());
103105
project_metadata.apply_configuration_files(&system)?;
104106

crates/red_knot_project/src/combine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{collections::HashMap, hash::BuildHasher};
22

3-
use red_knot_python_semantic::{PythonPlatform, SitePackages};
3+
use red_knot_python_semantic::{PythonPath, PythonPlatform};
44
use ruff_db::system::SystemPathBuf;
55
use ruff_python_ast::PythonVersion;
66

@@ -128,7 +128,7 @@ macro_rules! impl_noop_combine {
128128

129129
impl_noop_combine!(SystemPathBuf);
130130
impl_noop_combine!(PythonPlatform);
131-
impl_noop_combine!(SitePackages);
131+
impl_noop_combine!(PythonPath);
132132
impl_noop_combine!(PythonVersion);
133133

134134
// std types

crates/red_knot_project/src/metadata/options.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::metadata::value::{RangedValue, RelativePathBuf, ValueSource, ValueSourceGuard};
22
use crate::Db;
33
use red_knot_python_semantic::lint::{GetLintError, Level, LintSource, RuleSelection};
4-
use red_knot_python_semantic::{ProgramSettings, PythonPlatform, SearchPathSettings, SitePackages};
4+
use red_knot_python_semantic::{ProgramSettings, PythonPath, PythonPlatform, SearchPathSettings};
55
use ruff_db::diagnostic::{Diagnostic, DiagnosticId, Severity, Span};
66
use ruff_db::files::system_path_to_file;
77
use ruff_db::system::{System, SystemPath};
@@ -90,7 +90,7 @@ impl Options {
9090
.map(|env| {
9191
(
9292
env.extra_paths.clone(),
93-
env.venv_path.clone(),
93+
env.python.clone(),
9494
env.typeshed.clone(),
9595
)
9696
})
@@ -104,11 +104,11 @@ impl Options {
104104
.collect(),
105105
src_roots,
106106
custom_typeshed: typeshed.map(|path| path.absolute(project_root, system)),
107-
site_packages: python
108-
.map(|venv_path| SitePackages::Derived {
109-
venv_path: venv_path.absolute(project_root, system),
107+
python_path: python
108+
.map(|python_path| {
109+
PythonPath::SysPrefix(python_path.absolute(project_root, system))
110110
})
111-
.unwrap_or(SitePackages::Known(vec![])),
111+
.unwrap_or(PythonPath::KnownSitePackages(vec![])),
112112
}
113113
}
114114

@@ -236,10 +236,14 @@ pub struct EnvironmentOptions {
236236
#[serde(skip_serializing_if = "Option::is_none")]
237237
pub typeshed: Option<RelativePathBuf>,
238238

239-
// TODO: Rename to python, see https://github.com/astral-sh/ruff/issues/15530
240-
/// The path to the user's `site-packages` directory, where third-party packages from ``PyPI`` are installed.
239+
/// Path to the Python installation from which Red Knot resolves type information and third-party dependencies.
240+
///
241+
/// Red Knot will search in the path's `site-packages` directories for type information and
242+
/// third-party imports.
243+
///
244+
/// This option is commonly used to specify the path to a virtual environment.
241245
#[serde(skip_serializing_if = "Option::is_none")]
242-
pub venv_path: Option<RelativePathBuf>,
246+
pub python: Option<RelativePathBuf>,
243247
}
244248

245249
#[derive(Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize)]

crates/red_knot_python_semantic/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::suppression::{INVALID_IGNORE_COMMENT, UNKNOWN_RULE, UNUSED_IGNORE_COM
77
pub use db::Db;
88
pub use module_name::ModuleName;
99
pub use module_resolver::{resolve_module, system_module_search_paths, KnownModule, Module};
10-
pub use program::{Program, ProgramSettings, SearchPathSettings, SitePackages};
10+
pub use program::{Program, ProgramSettings, PythonPath, SearchPathSettings};
1111
pub use python_platform::PythonPlatform;
1212
pub use semantic_model::{HasType, SemanticModel};
1313

crates/red_knot_python_semantic/src/module_resolver/resolver.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::db::Db;
1212
use crate::module_name::ModuleName;
1313
use crate::module_resolver::typeshed::{vendored_typeshed_versions, TypeshedVersions};
1414
use crate::site_packages::VirtualEnvironment;
15-
use crate::{Program, SearchPathSettings, SitePackages};
15+
use crate::{Program, PythonPath, SearchPathSettings};
1616

1717
use super::module::{Module, ModuleKind};
1818
use super::path::{ModulePath, SearchPath, SearchPathValidationError};
@@ -171,7 +171,7 @@ impl SearchPaths {
171171
extra_paths,
172172
src_roots,
173173
custom_typeshed: typeshed,
174-
site_packages: site_packages_paths,
174+
python_path,
175175
} = settings;
176176

177177
let system = db.system();
@@ -222,16 +222,16 @@ impl SearchPaths {
222222

223223
static_paths.push(stdlib_path);
224224

225-
let site_packages_paths = match site_packages_paths {
226-
SitePackages::Derived { venv_path } => {
225+
let site_packages_paths = match python_path {
226+
PythonPath::SysPrefix(sys_prefix) => {
227227
// TODO: We may want to warn here if the venv's python version is older
228228
// than the one resolved in the program settings because it indicates
229229
// that the `target-version` is incorrectly configured or that the
230230
// venv is out of date.
231-
VirtualEnvironment::new(venv_path, system)
231+
VirtualEnvironment::new(sys_prefix, system)
232232
.and_then(|venv| venv.site_packages_directories(system))?
233233
}
234-
SitePackages::Known(paths) => paths
234+
PythonPath::KnownSitePackages(paths) => paths
235235
.iter()
236236
.map(|path| canonicalize(path, system))
237237
.collect(),
@@ -1310,7 +1310,7 @@ mod tests {
13101310
extra_paths: vec![],
13111311
src_roots: vec![src.clone()],
13121312
custom_typeshed: Some(custom_typeshed),
1313-
site_packages: SitePackages::Known(vec![site_packages]),
1313+
python_path: PythonPath::KnownSitePackages(vec![site_packages]),
13141314
},
13151315
},
13161316
)
@@ -1816,7 +1816,7 @@ not_a_directory
18161816
extra_paths: vec![],
18171817
src_roots: vec![SystemPathBuf::from("/src")],
18181818
custom_typeshed: None,
1819-
site_packages: SitePackages::Known(vec![
1819+
python_path: PythonPath::KnownSitePackages(vec![
18201820
venv_site_packages,
18211821
system_site_packages,
18221822
]),

crates/red_knot_python_semantic/src/module_resolver/testing.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use ruff_python_ast::PythonVersion;
44

55
use crate::db::tests::TestDb;
66
use crate::program::{Program, SearchPathSettings};
7-
use crate::{ProgramSettings, PythonPlatform, SitePackages};
7+
use crate::{ProgramSettings, PythonPath, PythonPlatform};
88

99
/// A test case for the module resolver.
1010
///
@@ -239,7 +239,7 @@ impl TestCaseBuilder<MockedTypeshed> {
239239
extra_paths: vec![],
240240
src_roots: vec![src.clone()],
241241
custom_typeshed: Some(typeshed.clone()),
242-
site_packages: SitePackages::Known(vec![site_packages.clone()]),
242+
python_path: PythonPath::KnownSitePackages(vec![site_packages.clone()]),
243243
},
244244
},
245245
)
@@ -294,7 +294,7 @@ impl TestCaseBuilder<VendoredTypeshed> {
294294
python_version,
295295
python_platform,
296296
search_paths: SearchPathSettings {
297-
site_packages: SitePackages::Known(vec![site_packages.clone()]),
297+
python_path: PythonPath::KnownSitePackages(vec![site_packages.clone()]),
298298
..SearchPathSettings::new(vec![src.clone()])
299299
},
300300
},

crates/red_knot_python_semantic/src/program.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ pub struct SearchPathSettings {
110110
/// bundled as a zip file in the binary
111111
pub custom_typeshed: Option<SystemPathBuf>,
112112

113-
/// The path to the user's `site-packages` directory, where third-party packages from ``PyPI`` are installed.
114-
pub site_packages: SitePackages,
113+
/// Path to the Python installation from which Red Knot resolves third party dependencies
114+
/// and their type information.
115+
pub python_path: PythonPath,
115116
}
116117

117118
impl SearchPathSettings {
@@ -120,17 +121,32 @@ impl SearchPathSettings {
120121
src_roots,
121122
extra_paths: vec![],
122123
custom_typeshed: None,
123-
site_packages: SitePackages::Known(vec![]),
124+
python_path: PythonPath::KnownSitePackages(vec![]),
124125
}
125126
}
126127
}
127128

128129
#[derive(Debug, Clone, Eq, PartialEq)]
129130
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
130-
pub enum SitePackages {
131-
Derived {
132-
venv_path: SystemPathBuf,
133-
},
134-
/// Resolved site packages paths
135-
Known(Vec<SystemPathBuf>),
131+
pub enum PythonPath {
132+
/// A path that represents the value of [`sys.prefix`] at runtime in Python
133+
/// for a given Python executable.
134+
///
135+
/// For the case of a virtual environment, where a
136+
/// Python binary is at `/.venv/bin/python`, `sys.prefix` is the path to
137+
/// the virtual environment the Python binary lies inside, i.e. `/.venv`,
138+
/// and `site-packages` will be at `.venv/lib/python3.X/site-packages`.
139+
/// System Python installations generally work the same way: if a system
140+
/// Python installation lies at `/opt/homebrew/bin/python`, `sys.prefix`
141+
/// will be `/opt/homebrew`, and `site-packages` will be at
142+
/// `/opt/homebrew/lib/python3.X/site-packages`.
143+
///
144+
/// [`sys.prefix`]: https://docs.python.org/3/library/sys.html#sys.prefix
145+
SysPrefix(SystemPathBuf),
146+
147+
/// Resolved site packages paths.
148+
///
149+
/// This variant is mainly intended for testing where we want to skip resolving `site-packages`
150+
/// because it would unnecessarily complicate the test setup.
151+
KnownSitePackages(Vec<SystemPathBuf>),
136152
}

crates/red_knot_python_semantic/src/site_packages.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,11 @@ System site-packages will not be used for module resolution.",
205205

206206
#[derive(Debug, thiserror::Error)]
207207
pub(crate) enum SitePackagesDiscoveryError {
208-
#[error("Invalid --venv-path argument: {0} could not be canonicalized")]
208+
#[error("Invalid --python argument: `{0}` could not be canonicalized")]
209209
VenvDirCanonicalizationError(SystemPathBuf, #[source] io::Error),
210-
#[error("Invalid --venv-path argument: {0} does not point to a directory on disk")]
210+
#[error("Invalid --python argument: `{0}` does not point to a directory on disk")]
211211
VenvDirIsNotADirectory(SystemPathBuf),
212-
#[error("--venv-path points to a broken venv with no pyvenv.cfg file")]
212+
#[error("--python points to a broken venv with no pyvenv.cfg file")]
213213
NoPyvenvCfgFile(#[source] io::Error),
214214
#[error("Failed to parse the pyvenv.cfg file at {0} because {1}")]
215215
PyvenvCfgParseError(SystemPathBuf, PyvenvCfgParseErrorKind),

crates/red_knot_test/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use camino::Utf8Path;
44
use colored::Colorize;
55
use parser as test_parser;
66
use red_knot_python_semantic::types::check_types;
7-
use red_knot_python_semantic::{Program, ProgramSettings, SearchPathSettings, SitePackages};
7+
use red_knot_python_semantic::{Program, ProgramSettings, PythonPath, SearchPathSettings};
88
use ruff_db::diagnostic::{Diagnostic, DisplayDiagnosticConfig, ParseDiagnostic};
99
use ruff_db::files::{system_path_to_file, File, Files};
1010
use ruff_db::panic::catch_unwind;
@@ -180,7 +180,7 @@ fn run_test(
180180
src_roots: vec![src_path],
181181
extra_paths: vec![],
182182
custom_typeshed: custom_typeshed_path,
183-
site_packages: SitePackages::Known(vec![]),
183+
python_path: PythonPath::KnownSitePackages(vec![]),
184184
},
185185
},
186186
)

0 commit comments

Comments
 (0)