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

Add support for secondary architectures for Python #447

Merged
merged 4 commits into from
Oct 1, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ that were not yet released.

_Unreleased_

- Add support for fetching alternative CPU architectures. #447

- The order of git submodule initialization was changed. This improves the
automatic author detection when `includeIf` is used. #443

Expand Down
18 changes: 18 additions & 0 deletions docs/guide/toolchains/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ available compatible version for the virtual environment.

Relaxed pinning with `rye pin --relaxed` was added.

## Non Native Architectures

+++ 0.14.0

Support for fetching and pinning of non-native architectures was added.

By default the pin is for the architecture of the running machine. This means that
if you pin `cpython@3.11` on a mac with aarch64 architecture, you will use a cpython
interpreter of that CPU architecture. A different architecture can be selected by
adding `-{arch}` to the python family name. So for instance to force a `x86_64` version
you need to pin like this:

```
rye pin cpython-x86_64@3.11
```

Note that such custom pins are not reflected in `pyproject.toml` but only `.python-version`.

## Listing Toolchains

To see which toolchains are installed, `rye toolchain list` prints a list:
Expand Down
6 changes: 3 additions & 3 deletions rye/find-downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def _sort_key(info):
print("// generated code, do not edit")
print("use std::borrow::Cow;")
print(
"pub const PYTHON_VERSIONS: &[(PythonVersion, &str, &str, &str, Option<&str>)] = &["
"pub const PYTHON_VERSIONS: &[(PythonVersion, &str, Option<&str>)] = &["
)
for interpreter, py_ver, choices in sorted(
chain(
Expand All @@ -265,7 +265,7 @@ def _sort_key(info):
sha256 = read_sha256(url)
sha256 = 'Some("%s")' % sha256 if sha256 else "None"
print(
' (PythonVersion { kind: Cow::Borrowed("%s"), major: %d, minor: %d, patch: %d, suffix: None }, "%s", "%s", "%s", %s),'
% ((interpreter,) + py_ver + (arch, platform, url, sha256))
' (PythonVersion { name: Cow::Borrowed("%s"), arch: Cow::Borrowed("%s"), os: Cow::Borrowed("%s"), major: %d, minor: %d, patch: %d, suffix: None }, "%s", %s),'
% ((interpreter, arch, platform) + py_ver + (url, sha256))
)
print("];")
10 changes: 6 additions & 4 deletions rye/src/bootstrap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::borrow::Cow;
use std::env::consts::{ARCH, EXE_EXTENSION, OS};
use std::env::consts::EXE_EXTENSION;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
Expand All @@ -26,7 +26,9 @@ use crate::utils::{

/// this is the target version that we want to fetch
pub const SELF_PYTHON_TARGET_VERSION: PythonVersionRequest = PythonVersionRequest {
kind: Some(Cow::Borrowed("cpython")),
name: Some(Cow::Borrowed("cpython")),
arch: None,
os: None,
major: 3,
minor: Some(11),
patch: None,
Expand Down Expand Up @@ -298,7 +300,7 @@ pub fn get_pip_module(venv: &Path) -> Result<PathBuf, Error> {

/// we only support cpython 3.9 to 3.11
pub fn is_self_compatible_toolchain(version: &PythonVersion) -> bool {
version.kind == "cpython" && version.major == 3 && version.minor >= 9 && version.minor < 12
version.name == "cpython" && version.major == 3 && version.minor >= 9 && version.minor < 12
}

fn ensure_self_toolchain(output: CommandOutput) -> Result<PythonVersion, Error> {
Expand Down Expand Up @@ -333,7 +335,7 @@ pub fn fetch(
}
}

let (version, url, sha256) = match get_download_url(version, OS, ARCH) {
let (version, url, sha256) = match get_download_url(version) {
Some(result) => result,
None => bail!("unknown version {}", version),
};
Expand Down
5 changes: 5 additions & 0 deletions rye/src/cli/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ use crate::utils::CommandOutput;
pub struct Args {
/// The version of Python to fetch.
version: String,
/// Overrides the architecture to fetch.
///
/// When a non native architecture is fetched, the toolchain is
/// installed under an alias.
arch: Option<String>,
/// Enables verbose diagnostics.
#[arg(short, long)]
verbose: bool,
Expand Down
4 changes: 3 additions & 1 deletion rye/src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ pub fn execute(mut cmd: Args) -> Result<(), Error> {
let py_ver: PythonVersionRequest = match cmd.python {
Some(ref py) => py.parse()?,
None => PythonVersionRequest {
kind: None,
name: None,
arch: None,
os: None,
major: 3,
minor: None,
patch: None,
Expand Down
4 changes: 2 additions & 2 deletions rye/src/cli/rye.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ fn perform_install(mode: InstallMode, toolchain_path: Option<&Path>) -> Result<(
style(toolchain_path.display()).cyan()
);
let version = register_toolchain(toolchain_path, None, |ver| {
if ver.kind != "cpython" {
bail!("Only cpython toolchains are allowed, got '{}'", ver.kind);
if ver.name != "cpython" {
bail!("Only cpython toolchains are allowed, got '{}'", ver.name);
} else if !is_self_compatible_toolchain(ver) {
bail!(
"Toolchain {} is not version compatible for internal use.",
Expand Down
16 changes: 15 additions & 1 deletion rye/src/cli/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ struct ListVersion {
downloadable: Option<bool>,
}

fn secondary_architectures() -> &'static [&'static str] {
match (OS, ARCH) {
("windows", "x86_64") => &["x86"],
("windows", "aarch64") => &["x86_64", "x86"],
("macos", "aarch64") => &["x86_64"],
_ => &[],
}
}

fn list(cmd: ListCommand) -> Result<(), Error> {
let mut toolchains = list_known_toolchains()?
.into_iter()
Expand All @@ -139,10 +148,15 @@ fn list(cmd: ListCommand) -> Result<(), Error> {
for version in iter_downloadable(OS, ARCH) {
toolchains.entry(version).or_insert(None);
}
for secondary_arch in secondary_architectures() {
for version in iter_downloadable(OS, secondary_arch) {
toolchains.entry(version).or_insert(None);
}
}
}

let mut versions = toolchains.into_iter().collect::<Vec<_>>();
versions.sort_by_cached_key(|a| (a.1.is_none(), a.0.kind.to_string(), Reverse(a.clone())));
versions.sort_by_cached_key(|a| (a.1.is_none(), a.0.name.to_string(), Reverse(a.clone())));

if let Some(Format::Json) = cmd.format {
let json_versions = versions
Expand Down