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

Allow --python and --system on pip compile #3115

Merged
merged 1 commit into from
Apr 18, 2024
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
26 changes: 16 additions & 10 deletions crates/uv-interpreter/src/find_python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ impl PythonVersionSelector {
#[instrument(skip_all, fields(?python_version))]
pub fn find_best_python(
python_version: Option<&PythonVersion>,
system: bool,
cache: &Cache,
) -> Result<Interpreter, Error> {
if let Some(python_version) = python_version {
Expand All @@ -437,22 +438,24 @@ pub fn find_best_python(
}

// First, check for an exact match (or the first available version if no Python version was provided)
if let Some(interpreter) = find_version(python_version, cache)? {
if let Some(interpreter) = find_version(python_version, system, cache)? {
return Ok(interpreter);
}

if let Some(python_version) = python_version {
// If that fails, and a specific patch version was requested try again allowing a
// different patch version
if python_version.patch().is_some() {
if let Some(interpreter) = find_version(Some(&python_version.without_patch()), cache)? {
if let Some(interpreter) =
find_version(Some(&python_version.without_patch()), system, cache)?
{
return Ok(interpreter);
}
}
}

// If a Python version was requested but cannot be fulfilled, just take any version
if let Some(interpreter) = find_version(None, cache)? {
if let Some(interpreter) = find_version(None, system, cache)? {
return Ok(interpreter);
}

Expand All @@ -477,6 +480,7 @@ pub fn find_best_python(
/// we will return [`None`].
fn find_version(
python_version: Option<&PythonVersion>,
system: bool,
cache: &Cache,
) -> Result<Option<Interpreter>, Error> {
let version_matches = |interpreter: &Interpreter| -> bool {
Expand All @@ -490,14 +494,16 @@ fn find_version(
};

// Check if the venv Python matches.
if let Some(venv) = detect_virtual_env()? {
let executable = detect_python_executable(venv);
let interpreter = Interpreter::query(executable, cache)?;
if !system {
if let Some(venv) = detect_virtual_env()? {
let executable = detect_python_executable(venv);
let interpreter = Interpreter::query(executable, cache)?;

if version_matches(&interpreter) {
return Ok(Some(interpreter));
}
};
if version_matches(&interpreter) {
return Ok(Some(interpreter));
}
};
}

// Look for the requested version with by search for `python{major}.{minor}` in `PATH` on
// Unix and `py --list-paths` on Windows.
Expand Down
43 changes: 37 additions & 6 deletions crates/uv/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,15 @@ pub(crate) struct PipCompileArgs {
#[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)]
pub(crate) extra_index_url: Option<Vec<Maybe<IndexUrl>>>,

/// Locations to search for candidate distributions, beyond those found in the indexes.
///
/// If a path, the target must be a directory that contains package as wheel files (`.whl`) or
/// source distributions (`.tar.gz` or `.zip`) at the top level.
///
/// If a URL, the page must contain a flat list of links to package files.
#[arg(long, short)]
pub(crate) find_links: Option<Vec<FlatIndexLocation>>,

/// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those
/// discovered via `--find-links`.
#[arg(long)]
Expand All @@ -406,14 +415,36 @@ pub(crate) struct PipCompileArgs {
#[arg(long, value_enum, env = "UV_KEYRING_PROVIDER")]
pub(crate) keyring_provider: Option<KeyringProviderType>,

/// Locations to search for candidate distributions, beyond those found in the indexes.
/// The Python interpreter against which to compile the requirements.
///
/// If a path, the target must be a directory that contains package as wheel files (`.whl`) or
/// source distributions (`.tar.gz` or `.zip`) at the top level.
/// By default, `uv` uses the virtual environment in the current working directory or any parent
/// directory, falling back to searching for a Python executable in `PATH`. The `--python`
/// option allows you to specify a different interpreter.
///
/// If a URL, the page must contain a flat list of links to package files.
#[arg(long, short)]
pub(crate) find_links: Option<Vec<FlatIndexLocation>>,
/// Supported formats:
/// - `3.10` looks for an installed Python 3.10 using `py --list-paths` on Windows, or
/// `python3.10` on Linux and macOS.
/// - `python3.10` or `python.exe` looks for a binary with the given name in `PATH`.
/// - `/home/ferris/.local/bin/python3.10` uses the exact Python at the given path.
#[arg(long, verbatim_doc_comment, group = "discovery")]
pub(crate) python: Option<String>,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of wish this was -p for consistency with other commands, but --python-version is already -p.


/// Install packages into the system Python.
///
/// By default, `uv` uses the virtual environment in the current working directory or any parent
/// directory, falling back to searching for a Python executable in `PATH`. The `--system`
/// option instructs `uv` to avoid using a virtual environment Python and restrict its search to
/// the system path.
#[arg(
long,
env = "UV_SYSTEM_PYTHON",
group = "discovery",
overrides_with("no_system")
)]
pub(crate) system: bool,

#[arg(long, overrides_with("system"))]
pub(crate) no_system: bool,

/// Allow package upgrades, ignoring pinned versions in the existing output file.
#[arg(long, short = 'U')]
Expand Down
11 changes: 9 additions & 2 deletions crates/uv/src/commands/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use uv_configuration::{
use uv_dispatch::BuildDispatch;
use uv_fs::Simplified;
use uv_installer::Downloader;
use uv_interpreter::{find_best_python, PythonEnvironment};
use uv_interpreter::{find_best_python, find_requested_python, PythonEnvironment};
use uv_normalize::{ExtraName, PackageName};
use uv_requirements::{
upgrade::read_lockfile, ExtrasSpecification, LookaheadResolver, NamedRequirementsResolver,
Expand Down Expand Up @@ -80,6 +80,8 @@ pub(crate) async fn pip_compile(
exclude_newer: Option<ExcludeNewer>,
annotation_style: AnnotationStyle,
link_mode: LinkMode,
python: Option<String>,
system: bool,
native_tls: bool,
quiet: bool,
cache: Cache,
Expand Down Expand Up @@ -145,7 +147,12 @@ pub(crate) async fn pip_compile(
}

// Find an interpreter to use for building distributions
let interpreter = find_best_python(python_version.as_ref(), &cache)?;
let interpreter = if let Some(python) = python.as_ref() {
find_requested_python(python, &cache)?
.ok_or_else(|| uv_interpreter::Error::RequestedPythonNotFound(python.to_string()))?
} else {
find_best_python(python_version.as_ref(), system, &cache)?
};
debug!(
"Using Python {} interpreter at {} for builds",
interpreter.python_version(),
Expand Down
2 changes: 2 additions & 0 deletions crates/uv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ async fn run() -> Result<ExitStatus> {
args.shared.exclude_newer,
args.shared.annotation_style,
args.shared.link_mode,
args.shared.python,
args.shared.system,
globals.native_tls,
globals.quiet,
cache,
Expand Down
5 changes: 5 additions & 0 deletions crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ impl PipCompileSettings {
index_strategy,
keyring_provider,
find_links,
python,
system,
no_system,
upgrade,
upgrade_package,
generate_hashes,
Expand Down Expand Up @@ -156,6 +159,8 @@ impl PipCompileSettings {
// Shared settings.
shared: PipSharedSettings::combine(
PipOptions {
python,
system: flag(system, no_system),
offline: flag(offline, no_offline),
index_url: index_url.and_then(Maybe::into_option),
extra_index_url: extra_index_url.map(|extra_index_urls| {
Expand Down
Loading