Skip to content

Commit 3f8f4f4

Browse files
committed
fix: parsing generic and freebsk platforms
Signed-off-by: Frost Ming <[email protected]>
1 parent 9989d64 commit 3f8f4f4

File tree

1 file changed

+66
-30
lines changed

1 file changed

+66
-30
lines changed

src/dep_logic/tags/platform.py

+66-30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import annotations
33

44
import re
5+
import struct
56
import sys
67
from dataclasses import dataclass
78
from enum import Enum
@@ -22,6 +23,15 @@ class PlatformError(Exception):
2223
r"(?P<os>manylinux|macos|musllinux)_(?P<major>\d+?)_(?P<minor>\d+?)_(?P<arch>[a-z0-9_]+)$"
2324
)
2425

26+
_os_mapping = {
27+
"freebsd": os.FreeBsd,
28+
"netbsd": os.NetBsd,
29+
"openbsd": os.OpenBsd,
30+
"dragonfly": os.Dragonfly,
31+
"illumos": os.Illumos,
32+
"haiku": os.Haiku,
33+
}
34+
2535

2636
@dataclass(frozen=True)
2737
class Platform:
@@ -73,6 +83,9 @@ def parse(cls, platform: str) -> Self:
7383
return cls(os.Musllinux(int(major), int(minor)), Arch.parse(arch))
7484
else:
7585
os_, arch = platform.split("_", 1)
86+
if os_ in _os_mapping:
87+
release, _, arch = arch.partition("_")
88+
return cls(_os_mapping[os_](release), Arch.parse(arch))
7689
try:
7790
return cls(os.Generic(os_), Arch.parse(arch))
7891
except ValueError as e:
@@ -89,38 +102,61 @@ def __str__(self) -> str:
89102
def current(cls) -> Self:
90103
"""Return the current platform."""
91104
import platform
105+
import sysconfig
92106

93-
system = platform.system()
94-
arch = Arch.parse(platform.machine().lower())
95-
if (
96-
platform.machine().lower() == "amd64"
97-
and platform.architecture()[0] == "32bit"
98-
):
99-
arch = Arch.parse("x86")
100-
if system == "Linux":
101-
libc_ver = platform.libc_ver()[1]
102-
if libc_ver:
103-
parts = libc_ver.split(".")
104-
return cls(os.Manylinux(int(parts[0]), int(parts[1])), arch)
105-
else: # musl
106-
from packaging._musllinux import _get_musl_version
107-
108-
musl_version = _get_musl_version(sys.executable)
109-
if musl_version is None:
110-
raise PlatformError(
111-
"Failed to detect musl version or glibc version"
112-
)
113-
return cls(os.Musllinux(musl_version.major, musl_version.minor), arch)
114-
elif system == "Windows":
115-
return cls(os.Windows(), arch)
116-
elif system == "Darwin":
117-
mac_ver = platform.mac_ver()[0].split(".")
118-
major, minor = int(mac_ver[0]), int(mac_ver[1])
119-
if major >= 11:
120-
minor = 0
121-
return cls(os.Macos(major, minor), arch)
107+
platform_ = sysconfig.get_platform()
108+
platform_info = platform_.split("-", 1)
109+
if len(platform_info) == 1:
110+
if platform_info[0] == "win32":
111+
return cls(os.Windows(), Arch.X86)
112+
else:
113+
raise PlatformError(f"Unsupported platform {platform_}")
114+
else:
115+
[operating_system, version_arch] = platform_info
116+
if "-" in version_arch:
117+
# Ex: macosx-11.2-arm64
118+
version, architecture = version_arch.rsplit("-", 1)
122119
else:
123-
raise PlatformError("Unsupported platform")
120+
# Ex: linux-x86_64
121+
version = None
122+
architecture = version_arch
123+
124+
if operating_system == "linux":
125+
from packaging._manylinux import _get_glibc_version
126+
from packaging._musllinux import _get_musl_version
127+
128+
musl_version = _get_musl_version(sys.executable)
129+
glibc_version = _get_glibc_version()
130+
if musl_version:
131+
os_ = os.Musllinux(musl_version[0], musl_version[1])
132+
elif glibc_version != (-1, -1):
133+
os_ = os.Manylinux(glibc_version[0], glibc_version[1])
134+
else:
135+
raise PlatformError("Unsupported platform: libc not found")
136+
elif operating_system == "win":
137+
os_ = os.Windows()
138+
elif operating_system == "macosx":
139+
# Apparently, Mac OS is reporting i386 sometimes in sysconfig.get_platform even
140+
# though that's not a thing anymore.
141+
# https://github.com/astral-sh/uv/issues/2450
142+
version, _, architecture = platform.mac_ver()
143+
144+
# https://github.com/pypa/packaging/blob/cc938f984bbbe43c5734b9656c9837ab3a28191f/src/packaging/tags.py#L356-L363
145+
is_32bit = struct.calcsize("P") == 4
146+
if is_32bit:
147+
if architecture.startswith("ppc"):
148+
architecture = "ppc"
149+
else:
150+
architecture = "i386"
151+
152+
version = version.split(".")
153+
os_ = os.Macos(int(version[0]), int(version[1]))
154+
elif operating_system in _os_mapping:
155+
os_ = _os_mapping[operating_system](version)
156+
else:
157+
os_ = os.Generic(operating_system)
158+
159+
return cls(os_, Arch.parse(architecture))
124160

125161
@classmethod
126162
def choices(cls) -> list[str]:

0 commit comments

Comments
 (0)