Skip to content

Commit 91c3ebc

Browse files
authored
Fix Python interpreter discovery on non-glibc hosts (#9005)
## Summary On Termux, uv currently fails to find any interpreter because it can't find a glibc version, because there isn't one. But the Python interpreter is still functional nonetheless. So, when glibc cannot be found, simply return 0 for the version numbers and mark the interpreter as being incompatible with manylinux I really don't know if this is the right way to address this, but I can attest that manual testing shows uv appears to be fully functional, at least for pip and virtualenvs. Fixes #7373 ## Test Plan I tried running the test suite, and after some tweaks, a good portion of the test suite passes as well. A significant number of tests fail, but this appears to be due to minor differences in output, like warnings about hard links not working (hard links are completely disallowed on Android), differences in the number of files removed, etc. The test suite seems to be very sensitive to minor variations in output.
1 parent e49ecd8 commit 91c3ebc

File tree

5 files changed

+36
-14
lines changed

5 files changed

+36
-14
lines changed

crates/uv-platform-tags/src/platform.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub enum Os {
5050
Dragonfly { release: String },
5151
Illumos { release: String, arch: String },
5252
Haiku { release: String },
53+
Android { api_level: u16 },
5354
}
5455

5556
impl fmt::Display for Os {
@@ -65,6 +66,7 @@ impl fmt::Display for Os {
6566
Self::Dragonfly { .. } => write!(f, "DragonFly"),
6667
Self::Illumos { .. } => write!(f, "Illumos"),
6768
Self::Haiku { .. } => write!(f, "Haiku"),
69+
Self::Android { .. } => write!(f, "Android"),
6870
}
6971
}
7072
}

crates/uv-platform-tags/src/tags.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,14 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<String>, PlatformError> {
543543
let os = os.to_string().to_lowercase();
544544
vec![format!("{}_{}_{}", os, release, arch)]
545545
}
546+
(Os::Android { api_level }, _) => {
547+
vec![format!(
548+
"{}_{}_{}",
549+
os.to_string().to_lowercase(),
550+
api_level,
551+
arch
552+
)]
553+
}
546554
_ => {
547555
return Err(PlatformError::OsVersionDetectionError(format!(
548556
"Unsupported operating system and architecture combination: {os} {arch}"

crates/uv-python/python/get_interpreter_info.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -462,22 +462,30 @@ def get_operating_system_and_architecture():
462462
from .packaging._musllinux import _get_musl_version
463463

464464
musl_version = _get_musl_version(sys.executable)
465-
glibc_version = _get_glibc_version()
465+
466466
if musl_version:
467467
operating_system = {
468468
"name": "musllinux",
469469
"major": musl_version[0],
470470
"minor": musl_version[1],
471471
}
472-
elif glibc_version != (-1, -1):
473-
operating_system = {
474-
"name": "manylinux",
475-
"major": glibc_version[0],
476-
"minor": glibc_version[1],
477-
}
478472
else:
479-
print(json.dumps({"result": "error", "kind": "libc_not_found"}))
480-
sys.exit(0)
473+
glibc_version = _get_glibc_version()
474+
475+
if glibc_version != (0, 0):
476+
operating_system = {
477+
"name": "manylinux",
478+
"major": glibc_version[0],
479+
"minor": glibc_version[1],
480+
}
481+
elif hasattr(sys, "getandroidapilevel"):
482+
operating_system = {
483+
"name": "android",
484+
"api_level": sys.getandroidapilevel(),
485+
}
486+
else:
487+
print(json.dumps({"result": "error", "kind": "libc_not_found"}))
488+
sys.exit(0)
481489
elif operating_system == "win":
482490
operating_system = {
483491
"name": "windows",
@@ -542,16 +550,20 @@ def main() -> None:
542550
"python_version": ".".join(platform.python_version_tuple()[:2]),
543551
"sys_platform": sys.platform,
544552
}
553+
545554
os_and_arch = get_operating_system_and_architecture()
546555

547-
manylinux_compatible = True
556+
manylinux_compatible = False
557+
548558
if os_and_arch["os"]["name"] == "manylinux":
549559
# noinspection PyProtectedMember
550560
from .packaging._manylinux import _get_glibc_version, _is_compatible
551561

552562
manylinux_compatible = _is_compatible(
553563
arch=os_and_arch["arch"], version=_get_glibc_version()
554564
)
565+
elif os_and_arch["os"]["name"] == "musllinux":
566+
manylinux_compatible = True
555567

556568
interpreter_info = {
557569
"result": "success",

crates/uv-python/python/packaging/_manylinux.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def _parse_glibc_version(version_str: str) -> tuple[int, int]:
173173
def _get_glibc_version() -> tuple[int, int]:
174174
version_str = _glibc_version_string()
175175
if version_str is None:
176-
return (-1, -1)
176+
return (0, 0)
177177
return _parse_glibc_version(version_str)
178178

179179

crates/uv-python/src/platform.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ impl From<&uv_platform_tags::Os> for Os {
203203
uv_platform_tags::Os::Haiku { .. } => Self(target_lexicon::OperatingSystem::Haiku),
204204
uv_platform_tags::Os::Illumos { .. } => Self(target_lexicon::OperatingSystem::Illumos),
205205
uv_platform_tags::Os::Macos { .. } => Self(target_lexicon::OperatingSystem::Darwin),
206-
uv_platform_tags::Os::Manylinux { .. } | uv_platform_tags::Os::Musllinux { .. } => {
207-
Self(target_lexicon::OperatingSystem::Linux)
208-
}
206+
uv_platform_tags::Os::Manylinux { .. }
207+
| uv_platform_tags::Os::Musllinux { .. }
208+
| uv_platform_tags::Os::Android { .. } => Self(target_lexicon::OperatingSystem::Linux),
209209
uv_platform_tags::Os::NetBsd { .. } => Self(target_lexicon::OperatingSystem::Netbsd),
210210
uv_platform_tags::Os::OpenBsd { .. } => Self(target_lexicon::OperatingSystem::Openbsd),
211211
uv_platform_tags::Os::Windows => Self(target_lexicon::OperatingSystem::Windows),

0 commit comments

Comments
 (0)