Skip to content
Closed
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
46 changes: 46 additions & 0 deletions crates/uv/src/commands/pip/compile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use fs_err as fs;
use std::collections::{BTreeMap, BTreeSet};
use std::env;
use std::ffi::OsStr;
Expand Down Expand Up @@ -156,6 +157,51 @@ pub(crate) async fn pip_compile(
}
}

// Respect `.python-version` file
if python.is_none() && python_version.is_none() {
let mut version_file: Option<PathBuf> = None;

if PathBuf::from(".python-version").exists() {
// If there is `.python-version` in the current directory, use that.
// This is for cases like `uv pip compile requirements.in`.
version_file = Some(PathBuf::from(".python-version"));
} else if !requirements.is_empty() {
// If there is no `.python-version` present, try to find a sibling
// to the first RequirementsSource, which contains a path.
let file_name = match &requirements[0] {
RequirementsSource::PylockToml(file_name) => Some(file_name),
RequirementsSource::RequirementsTxt(file_name) => Some(file_name),
RequirementsSource::PyprojectToml(file_name) => Some(file_name),
RequirementsSource::SetupPy(file_name) => Some(file_name),
RequirementsSource::SetupCfg(file_name) => Some(file_name),
RequirementsSource::EnvironmentYml(file_name) => Some(file_name),
_ => None,
};

if let Some(file_name) = file_name {
let version_file_path = file_name
.as_path()
.parent()
.unwrap()
.join(PathBuf::from(".python-version"));

if version_file_path.exists() {
version_file = Some(version_file_path);
}
}
}

if let Some(version_file) = version_file {
if let Ok(request) = fs::read_to_string(version_file) {
if !request.is_empty() {
if let Some(first_line) = request.lines().next() {
python = Some(first_line.trim().to_string());
}
}
}
}
}

// If `--python` / `-p` is a simple Python version request, we treat it as `--python-version`
// for backwards compatibility. `-p` was previously aliased to `--python-version` but changed to
// `--python` for consistency with the rest of the CLI in v0.6.0. Since we assume metadata is
Expand Down
77 changes: 77 additions & 0 deletions crates/uv/tests/it/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17603,3 +17603,80 @@ fn omit_python_patch_universal() -> Result<()> {

Ok(())
}

#[test]
fn compile_requirements_in_respect_python_version_default() -> Result<()> {
let context = TestContext::new_with_versions(&["3.12", "3.11"]).with_filtered_python_sources();

let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("requests\nrich ; python_version >= '3.12'\n")?;

uv_snapshot!(context.filters(), context.pip_compile()
.arg("requirements.in"), @r"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] requirements.in
certifi==2024.2.2
# via requests
charset-normalizer==3.3.2
# via requests
idna==3.6
# via requests
markdown-it-py==3.0.0
# via rich
mdurl==0.1.2
# via markdown-it-py
pygments==2.17.2
# via rich
requests==2.31.0
# via -r requirements.in
rich==13.7.1
# via -r requirements.in
urllib3==2.2.1
# via requests

----- stderr -----
Resolved 9 packages in [TIME]
"
);

Ok(())
}

#[test]
fn compile_requirements_in_respect_python_version() -> Result<()> {
let context = TestContext::new_with_versions(&["3.12", "3.11"]).with_filtered_python_sources();

let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("requests\nrich ; python_version >= '3.12'\n")?;

let python_version = context.temp_dir.child(".python-version");
python_version.write_str("3.11")?;

uv_snapshot!(context.filters(), context.pip_compile()
.arg("requirements.in"), @r"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] requirements.in
certifi==2024.2.2
# via requests
charset-normalizer==3.3.2
# via requests
idna==3.6
# via requests
requests==2.31.0
# via -r requirements.in
urllib3==2.2.1
# via requests

----- stderr -----
Resolved 5 packages in [TIME]
"
);

Ok(())
}
Loading