Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/ruff/tests/analyze_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ fn command() -> Command {
command.arg("analyze");
command.arg("graph");
command.arg("--preview");
command.env_clear();
command
}

Expand Down
3 changes: 1 addition & 2 deletions crates/ruff_benchmark/benches/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,7 @@ impl<'a> ProjectBenchmark<'a> {
metadata.apply_options(Options {
environment: Some(EnvironmentOptions {
python_version: Some(RangedValue::cli(self.project.config.python_version)),
python: (!self.project.config().dependencies.is_empty())
.then_some(RelativePathBuf::cli(SystemPath::new(".venv"))),
python: Some(RelativePathBuf::cli(SystemPath::new(".venv"))),
..EnvironmentOptions::default()
}),
..Options::default()
Expand Down
3 changes: 1 addition & 2 deletions crates/ruff_benchmark/benches/ty_walltime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ impl<'a> Benchmark<'a> {
metadata.apply_options(Options {
environment: Some(EnvironmentOptions {
python_version: Some(RangedValue::cli(self.project.config.python_version)),
python: (!self.project.config().dependencies.is_empty())
.then_some(RelativePathBuf::cli(SystemPath::new(".venv"))),
python: Some(RelativePathBuf::cli(SystemPath::new(".venv"))),
..EnvironmentOptions::default()
}),
..Options::default()
Expand Down
32 changes: 19 additions & 13 deletions crates/ruff_benchmark/src/real_world_projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,17 @@ impl<'a> RealWorldProject<'a> {
};

// Install dependencies if specified
if !checkout.project().dependencies.is_empty() {
tracing::debug!(
"Installing {} dependencies for project '{}'...",
checkout.project().dependencies.len(),
checkout.project().name
);
let start = std::time::Instant::now();
install_dependencies(&checkout)?;
tracing::debug!(
"Dependency installation completed in {:.2}s",
start.elapsed().as_secs_f64()
);
}
tracing::debug!(
"Installing {} dependencies for project '{}'...",
checkout.project().dependencies.len(),
checkout.project().name
);
let start_install = std::time::Instant::now();
install_dependencies(&checkout)?;
tracing::debug!(
"Dependency installation completed in {:.2}s",
start_install.elapsed().as_secs_f64()
);

tracing::debug!("Project setup took: {:.2}s", start.elapsed().as_secs_f64());

Expand Down Expand Up @@ -281,6 +279,14 @@ fn install_dependencies(checkout: &Checkout) -> Result<()> {
String::from_utf8_lossy(&output.stderr)
);

if checkout.project().dependencies.is_empty() {
tracing::debug!(
"No dependencies to install for project '{}'",
checkout.project().name
);
return Ok(());
}

// Install dependencies with date constraint in the isolated environment
let mut cmd = Command::new("uv");
cmd.args([
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ filetime = { workspace = true }
glob = { workspace = true }
ignore = { workspace = true, optional = true }
matchit = { workspace = true }
path-slash = { workspace = true }
rustc-hash = { workspace = true }
salsa = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
path-slash = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, optional = true }
rustc-hash = { workspace = true }
zip = { workspace = true }

[target.'cfg(target_arch="wasm32")'.dependencies]
Expand Down
8 changes: 4 additions & 4 deletions crates/ruff_graph/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ruff_db::{Db as SourceDb, Upcast};
use ruff_python_ast::PythonVersion;
use ty_python_semantic::lint::{LintRegistry, RuleSelection};
use ty_python_semantic::{
Db, Program, ProgramSettings, PythonPath, PythonPlatform, PythonVersionSource,
Db, Program, ProgramSettings, PythonEnvironmentPath, PythonPlatform, PythonVersionSource,
PythonVersionWithSource, SearchPathSettings, SysPrefixPathOrigin, default_lint_registry,
};

Expand All @@ -36,11 +36,11 @@ impl ModuleDb {
venv_path: Option<SystemPathBuf>,
) -> Result<Self> {
let mut search_paths = SearchPathSettings::new(src_roots);
// TODO: Consider setting `PythonPath::Auto` if no venv_path is provided.
if let Some(venv_path) = venv_path {
search_paths.python_path =
PythonPath::sys_prefix(venv_path, SysPrefixPathOrigin::PythonCliFlag);
search_paths.python_environment =
PythonEnvironmentPath::explicit(venv_path, SysPrefixPathOrigin::PythonCliFlag);
}

let db = Self::default();
let search_paths = search_paths
.to_search_paths(db.system(), db.vendored())
Expand Down
5 changes: 2 additions & 3 deletions crates/ty/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,8 @@ impl CliTest {
let mut command = Command::new(get_cargo_bin("ty"));
command.current_dir(&self.project_dir).arg("check");

// Unset environment variables that can affect test behavior
command.env_remove("VIRTUAL_ENV");
command.env_remove("CONDA_PREFIX");
// Unset all environment variables because they can affect test behavior.
command.env_clear();

command
}
Expand Down
4 changes: 2 additions & 2 deletions crates/ty_project/src/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, hash::BuildHasher};
use ordermap::OrderMap;
use ruff_db::system::SystemPathBuf;
use ruff_python_ast::PythonVersion;
use ty_python_semantic::{PythonPath, PythonPlatform};
use ty_python_semantic::{PythonEnvironmentPath, PythonPlatform};

/// Combine two values, preferring the values in `self`.
///
Expand Down Expand Up @@ -141,7 +141,7 @@ macro_rules! impl_noop_combine {

impl_noop_combine!(SystemPathBuf);
impl_noop_combine!(PythonPlatform);
impl_noop_combine!(PythonPath);
impl_noop_combine!(PythonEnvironmentPath);
impl_noop_combine!(PythonVersion);

// std types
Expand Down
35 changes: 11 additions & 24 deletions crates/ty_project/src/metadata/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use crate::Db;
use crate::combine::Combine;
use crate::glob::{ExcludeFilter, IncludeExcludeFilter, IncludeFilter, PortableGlobKind};
use crate::metadata::settings::{OverrideSettings, SrcSettings};

use super::settings::{Override, Settings, TerminalSettings};
use crate::metadata::value::{
RangedValue, RelativeGlobPattern, RelativePathBuf, ValueSource, ValueSourceGuard,
};

use ordermap::OrderMap;
use ruff_db::RustDoc;
use ruff_db::diagnostic::{
Expand All @@ -28,13 +29,11 @@ use std::sync::Arc;
use thiserror::Error;
use ty_python_semantic::lint::{GetLintError, Level, LintSource, RuleSelection};
use ty_python_semantic::{
ProgramSettings, PythonPath, PythonPlatform, PythonVersionFileSource, PythonVersionSource,
PythonVersionWithSource, SearchPathSettings, SearchPathValidationError, SearchPaths,
SysPrefixPathOrigin,
ProgramSettings, PythonEnvironmentPath, PythonPlatform, PythonVersionFileSource,
PythonVersionSource, PythonVersionWithSource, SearchPathSettings, SearchPathValidationError,
SearchPaths, SysPrefixPathOrigin,
};

use super::settings::{Override, Settings, TerminalSettings};

#[derive(
Debug, Default, Clone, PartialEq, Eq, Combine, Serialize, Deserialize, OptionsMetadata,
)]
Expand Down Expand Up @@ -231,7 +230,7 @@ impl Options {
.typeshed
.as_ref()
.map(|path| path.absolute(project_root, system)),
python_path: environment
python_environment: environment
.python
.as_ref()
.map(|python_path| {
Expand All @@ -242,24 +241,12 @@ impl Options {
python_path.range(),
),
};
PythonPath::sys_prefix(python_path.absolute(project_root, system), origin)
})
.or_else(|| {
system.env_var("VIRTUAL_ENV").ok().map(|virtual_env| {
PythonPath::sys_prefix(virtual_env, SysPrefixPathOrigin::VirtualEnvVar)
})
})
.or_else(|| {
system.env_var("CONDA_PREFIX").ok().map(|path| {
PythonPath::sys_prefix(path, SysPrefixPathOrigin::CondaPrefixVar)
})
})
.unwrap_or_else(|| {
PythonPath::sys_prefix(
project_root.to_path_buf(),
SysPrefixPathOrigin::LocalVenv,
PythonEnvironmentPath::explicit(
python_path.absolute(project_root, system),
origin,
)
}),
})
.unwrap_or_else(|| PythonEnvironmentPath::Discover(project_root.to_path_buf())),
};

settings.to_search_paths(system, vendored)
Expand Down
2 changes: 1 addition & 1 deletion crates/ty_python_semantic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use module_resolver::{
system_module_search_paths,
};
pub use program::{
Program, ProgramSettings, PythonPath, PythonVersionFileSource, PythonVersionSource,
Program, ProgramSettings, PythonEnvironmentPath, PythonVersionFileSource, PythonVersionSource,
PythonVersionWithSource, SearchPathSettings,
};
pub use python_platform::PythonPlatform;
Expand Down
108 changes: 74 additions & 34 deletions crates/ty_python_semantic/src/module_resolver/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ use ruff_python_ast::PythonVersion;
use crate::db::Db;
use crate::module_name::ModuleName;
use crate::module_resolver::typeshed::{TypeshedVersions, vendored_typeshed_versions};
use crate::site_packages::{PythonEnvironment, SitePackagesPaths, SysPrefixPathOrigin};
use crate::site_packages::{
PythonEnvironment, SitePackagesDiscoveryError, SitePackagesPaths, SysPrefixPathOrigin,
};
use crate::{
Program, PythonPath, PythonVersionSource, PythonVersionWithSource, SearchPathSettings,
Program, PythonEnvironmentPath, PythonVersionSource, PythonVersionWithSource,
SearchPathSettings,
};

use super::module::{Module, ModuleKind};
Expand Down Expand Up @@ -188,7 +191,7 @@ impl SearchPaths {
extra_paths,
src_roots,
custom_typeshed: typeshed,
python_path,
python_environment: python_path,
} = settings;

let mut static_paths = vec![];
Expand Down Expand Up @@ -234,37 +237,16 @@ impl SearchPaths {
static_paths.push(stdlib_path);

let (site_packages_paths, python_version) = match python_path {
PythonPath::IntoSysPrefix(path, origin) => {
if origin == &SysPrefixPathOrigin::LocalVenv {
tracing::debug!("Discovering virtual environment in `{path}`");
let virtual_env_directory = path.join(".venv");
PythonEnvironmentPath::Discover(project_root) => {
Self::discover_python_environment(system, project_root)?
}

PythonEnvironment::new(
&virtual_env_directory,
SysPrefixPathOrigin::LocalVenv,
system,
)
.and_then(|venv| venv.into_settings(system))
.inspect_err(|err| {
if system.is_directory(&virtual_env_directory) {
tracing::debug!(
"Ignoring automatically detected virtual environment at `{}`: {}",
&virtual_env_directory,
err
);
}
})
.unwrap_or_else(|_| {
tracing::debug!("No virtual environment found");
(SitePackagesPaths::default(), None)
})
} else {
tracing::debug!("Resolving {origin}: {path}");
PythonEnvironment::new(path, origin.clone(), system)?.into_settings(system)?
}
PythonEnvironmentPath::Explicit(prefix, origin) => {
tracing::debug!("Resolving {origin}: {prefix}");
PythonEnvironment::new(prefix, origin.clone(), system)?.into_settings(system)?
}

PythonPath::KnownSitePackages(paths) => (
PythonEnvironmentPath::Testing(paths) => (
paths
.iter()
.map(|path| canonicalize(path, system))
Expand Down Expand Up @@ -307,6 +289,64 @@ impl SearchPaths {
})
}

fn discover_python_environment(
system: &dyn System,
project_root: &SystemPath,
) -> Result<(SitePackagesPaths, Option<PythonVersionWithSource>), SitePackagesDiscoveryError>
{
fn resolve_environment(
system: &dyn System,
path: &SystemPath,
origin: SysPrefixPathOrigin,
) -> Result<(SitePackagesPaths, Option<PythonVersionWithSource>), SitePackagesDiscoveryError>
{
tracing::debug!("Resolving {origin}: {path}");
PythonEnvironment::new(path, origin, system)?.into_settings(system)
}

if let Ok(virtual_env) = system.env_var("VIRTUAL_ENV") {
return resolve_environment(
system,
SystemPath::new(&virtual_env),
SysPrefixPathOrigin::VirtualEnvVar,
);
}

if let Ok(conda_env) = system.env_var("CONDA_PREFIX") {
return resolve_environment(
system,
SystemPath::new(&conda_env),
SysPrefixPathOrigin::CondaPrefixVar,
);
}

tracing::debug!("Discovering virtual environment in `{project_root}`");
let virtual_env_directory = project_root.join(".venv");

match PythonEnvironment::new(
&virtual_env_directory,
SysPrefixPathOrigin::LocalVenv,
system,
)
.and_then(|venv| venv.into_settings(system))
{
Ok(settings) => return Ok(settings),
Err(err) => {
if system.is_directory(&virtual_env_directory) {
tracing::debug!(
"Ignoring automatically detected virtual environment at `{}`: {}",
&virtual_env_directory,
err
);
}
}
}

tracing::debug!("No virtual environment found");

Ok((SitePackagesPaths::default(), None))
}

pub(crate) fn try_register_static_roots(&self, db: &dyn Db) {
let files = db.files();
for path in self.static_paths.iter().chain(self.site_packages.iter()) {
Expand Down Expand Up @@ -1494,7 +1534,7 @@ mod tests {
python_platform: PythonPlatform::default(),
search_paths: SearchPathSettings {
custom_typeshed: Some(custom_typeshed),
python_path: PythonPath::KnownSitePackages(vec![site_packages]),
python_environment: PythonEnvironmentPath::Testing(vec![site_packages]),
..SearchPathSettings::new(vec![src.clone()])
}
.to_search_paths(db.system(), db.vendored())
Expand Down Expand Up @@ -2009,7 +2049,7 @@ not_a_directory
python_version: PythonVersionWithSource::default(),
python_platform: PythonPlatform::default(),
search_paths: SearchPathSettings {
python_path: PythonPath::KnownSitePackages(vec![
python_environment: PythonEnvironmentPath::Testing(vec![
venv_site_packages,
system_site_packages,
]),
Expand Down Expand Up @@ -2126,7 +2166,7 @@ not_a_directory
python_version: PythonVersionWithSource::default(),
python_platform: PythonPlatform::default(),
search_paths: SearchPathSettings {
python_path: PythonPath::KnownSitePackages(vec![site_packages.clone()]),
python_environment: PythonEnvironmentPath::Testing(vec![site_packages.clone()]),
..SearchPathSettings::new(vec![project_directory])
}
.to_search_paths(db.system(), db.vendored())
Expand Down
Loading
Loading