Skip to content

Commit

Permalink
Allow --python and --system on pip compile
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Apr 18, 2024
1 parent 37aefbd commit 428e4ef
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 18 deletions.
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>,

/// 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

0 comments on commit 428e4ef

Please sign in to comment.