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
23 changes: 23 additions & 0 deletions crates/ruff_db/src/system/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,13 @@ impl AsRef<SystemPath> for Utf8PathBuf {
}
}

impl AsRef<SystemPath> for camino::Utf8Component<'_> {
#[inline]
fn as_ref(&self) -> &SystemPath {
SystemPath::new(self.as_str())
}
}

impl AsRef<SystemPath> for str {
#[inline]
fn as_ref(&self) -> &SystemPath {
Expand Down Expand Up @@ -626,6 +633,22 @@ impl Deref for SystemPathBuf {
}
}

impl<P: AsRef<SystemPath>> FromIterator<P> for SystemPathBuf {
fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> Self {
let mut buf = SystemPathBuf::new();
buf.extend(iter);
buf
}
}

impl<P: AsRef<SystemPath>> Extend<P> for SystemPathBuf {
fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
for path in iter {
self.push(path);
}
}
}

impl std::fmt::Debug for SystemPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Tests for `site-packages` discovery

## Ephemeral uv environments

If you use the `--with` flag when invoking `uv run`, uv will create an "ephemeral" virtual
environment that is layered on top of the pre-existing environment. `site-packages` directories from
the pre-existing environment will be added as an import search path at runtime as well as the
`site-packages` directory from the ephemeral environment. The `VIRTUAL_ENV` environment variable
will only point to the ephemeral virtual environment, but, following uv commit
`7bba3d00d4ad1fb3daba86b98eb25d8d9e9836ae`, uv writes the `sys.prefix` path of the parent
environment to an `extends-environment` key in the ephemeral environment's `pyvenv.cfg` file.

This test ensures that we are able to resolve imports that point to packages in either
`site-packages` directory (the one of the ephemeral environment or the one of the parent
environment) if we detect that an ephemeral uv environment has been activated.

```toml
[environment]
python = "/.venv"
```

`/.venv/pyvenv.cfg`:

```cfg
home = /doo/doo/wop/cpython-3.13.2-macos-aarch64-none/bin
implementation = CPython
uv = 0.7.6
version_info = 3.13.2
include-system-site-packages = false
prompt = ruff
extends-environment = /.other-environment
```

`/doo/doo/wop/cpython-3.13.2-macos-aarch64-none/bin/python`:

```text
```

`/.venv/<path-to-site-packages>/foo.py`:

```py
X: int = 42
```

`/.other-environment/<path-to-site-packages>/bar.py`:

```py
Y: "str" = "Y"
```

`/src/main.py`:

```py
from foo import X
from bar import Y

reveal_type(X) # revealed: int
reveal_type(Y) # revealed: str
```
8 changes: 5 additions & 3 deletions crates/ty_python_semantic/src/module_resolver/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ 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, SitePackagesDiscoveryError, SysPrefixPathOrigin};
use crate::site_packages::{
PythonEnvironment, SitePackagesDiscoveryError, SitePackagesPaths, SysPrefixPathOrigin,
};
use crate::{Program, PythonPath, SearchPathSettings};

use super::module::{Module, ModuleKind};
Expand Down Expand Up @@ -289,7 +291,7 @@ impl SearchPaths {
virtual_env_path,
error
);
vec![]
SitePackagesPaths::default()
};

match PythonEnvironment::new(
Expand All @@ -304,7 +306,7 @@ impl SearchPaths {
}
} else {
tracing::debug!("No virtual environment found");
vec![]
SitePackagesPaths::default()
}
}

Expand Down
Loading
Loading