ghc-compiler-python 9.4.8__py3-none-any.whl → 9.4.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ghc_compiler_python/__init__.py +5 -1
- ghc_compiler_python/bootstrap.py +24 -7
- ghc_compiler_python/payload_hashes.json +3 -3
- ghc_compiler_python/wrapper.py +77 -5
- {ghc_compiler_python-9.4.8.dist-info → ghc_compiler_python-9.4.9.dist-info}/METADATA +4 -4
- ghc_compiler_python-9.4.9.dist-info/RECORD +10 -0
- ghc_compiler_python-9.4.8.dist-info/RECORD +0 -10
- {ghc_compiler_python-9.4.8.dist-info → ghc_compiler_python-9.4.9.dist-info}/WHEEL +0 -0
- {ghc_compiler_python-9.4.8.dist-info → ghc_compiler_python-9.4.9.dist-info}/entry_points.txt +0 -0
- {ghc_compiler_python-9.4.8.dist-info → ghc_compiler_python-9.4.9.dist-info}/licenses/LICENSE +0 -0
ghc_compiler_python/__init__.py
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"""ghc-compiler-python: Native GHC and Cabal packaged as a Python Wheel."""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# The distribution version and the compiler version are separate axes and no
|
|
4
|
+
# longer agree. 9.4.8 published a wrapper that rejected every Windows machine
|
|
5
|
+
# without a system gcc; PyPI forbids re-uploading a version, so the fix ships
|
|
6
|
+
# as 9.4.9. The compiler inside is still GHC 9.4.8 and still says so.
|
|
7
|
+
__version__ = "9.4.9"
|
|
4
8
|
__ghc_version__ = "9.4.8"
|
|
5
9
|
__cabal_version__ = "3.10.3.0"
|
|
6
10
|
__author__ = "ghc-compiler-python contributors"
|
ghc_compiler_python/bootstrap.py
CHANGED
|
@@ -39,13 +39,30 @@ import zipfile
|
|
|
39
39
|
from pathlib import Path
|
|
40
40
|
from typing import NoReturn, Optional
|
|
41
41
|
|
|
42
|
+
#: The compiler actually inside the payload. This is GHC's own version and it
|
|
43
|
+
#: moves only when the bindist does.
|
|
42
44
|
GHC_VERSION = "9.4.8"
|
|
43
45
|
|
|
46
|
+
#: The distribution coordinate: the git tag, the release, the payload asset
|
|
47
|
+
#: names, the cache directory, and the version on PyPI.
|
|
48
|
+
#:
|
|
49
|
+
#: These were one constant until 9.4.9, which read well while the two agreed
|
|
50
|
+
#: and became a trap the moment they had to diverge. 9.4.8 shipped a wrapper
|
|
51
|
+
#: that rejected every Windows machine without a system gcc; PyPI forbids
|
|
52
|
+
#: re-uploading a version, so the fix needed a new one, and a single constant
|
|
53
|
+
#: made "publish a fixed wheel" and "claim a GHC release that does not exist"
|
|
54
|
+
#: the same edit.
|
|
55
|
+
#:
|
|
56
|
+
#: They are now separate axes. The package version is 9.4.9; the compiler it
|
|
57
|
+
#: installs is, and reports itself as, 9.4.8. `ghc-wrapper --numeric-version`
|
|
58
|
+
#: answers for the compiler, never for the package.
|
|
59
|
+
RELEASE_VERSION = "9.4.9"
|
|
60
|
+
|
|
44
61
|
#: Release assets are addressed by tag, so a wheel always fetches the payload
|
|
45
62
|
#: built alongside it rather than whatever happens to be newest.
|
|
46
63
|
_RELEASE_BASE = (
|
|
47
64
|
"https://github.com/Saimonokuma/GHC-COMPILER-PYTHON/releases/download"
|
|
48
|
-
f"/v{
|
|
65
|
+
f"/v{RELEASE_VERSION}"
|
|
49
66
|
)
|
|
50
67
|
|
|
51
68
|
_HASH_MANIFEST = Path(__file__).resolve().parent / "payload_hashes.json"
|
|
@@ -107,7 +124,7 @@ def _archive_suffix() -> str:
|
|
|
107
124
|
|
|
108
125
|
|
|
109
126
|
def payload_name() -> str:
|
|
110
|
-
return f"ghc-payload-{
|
|
127
|
+
return f"ghc-payload-{RELEASE_VERSION}-{platform_tag()}{_archive_suffix()}"
|
|
111
128
|
|
|
112
129
|
|
|
113
130
|
def payload_url() -> str:
|
|
@@ -142,7 +159,7 @@ def cache_root() -> Path:
|
|
|
142
159
|
|
|
143
160
|
def payload_root() -> Path:
|
|
144
161
|
"""Where this version's toolchain lives once installed."""
|
|
145
|
-
return cache_root() /
|
|
162
|
+
return cache_root() / RELEASE_VERSION / platform_tag()
|
|
146
163
|
|
|
147
164
|
|
|
148
165
|
def is_installed() -> bool:
|
|
@@ -196,7 +213,7 @@ def _offline_hint() -> str:
|
|
|
196
213
|
"If this machine has no network access, install the self-contained "
|
|
197
214
|
"wheel instead — it bundles the toolchain and never downloads:\n"
|
|
198
215
|
f" {_RELEASE_BASE}/"
|
|
199
|
-
f"ghc_compiler_python-{
|
|
216
|
+
f"ghc_compiler_python-{RELEASE_VERSION}-py3-none-{platform_tag()}.whl"
|
|
200
217
|
)
|
|
201
218
|
|
|
202
219
|
|
|
@@ -206,7 +223,7 @@ def _download(url: str, dest: Path, quiet: bool) -> None:
|
|
|
206
223
|
sys.stderr.write(f" from {url}\n")
|
|
207
224
|
|
|
208
225
|
request = urllib.request.Request(
|
|
209
|
-
url, headers={"User-Agent": f"ghc-compiler-python/{
|
|
226
|
+
url, headers={"User-Agent": f"ghc-compiler-python/{RELEASE_VERSION}"}
|
|
210
227
|
)
|
|
211
228
|
try:
|
|
212
229
|
with urllib.request.urlopen(request, timeout=_DOWNLOAD_TIMEOUT) as response:
|
|
@@ -358,7 +375,7 @@ def ensure_payload(quiet: bool = False) -> Path:
|
|
|
358
375
|
|
|
359
376
|
expected = _expected_digest()
|
|
360
377
|
|
|
361
|
-
with _DirectoryLock(cache_root() / f".lock-{
|
|
378
|
+
with _DirectoryLock(cache_root() / f".lock-{RELEASE_VERSION}-{platform_tag()}"):
|
|
362
379
|
if is_installed():
|
|
363
380
|
return root
|
|
364
381
|
|
|
@@ -390,7 +407,7 @@ def ensure_payload(quiet: bool = False) -> Path:
|
|
|
390
407
|
|
|
391
408
|
_restore_exec_bits(unpacked)
|
|
392
409
|
(unpacked / ".complete").write_text(
|
|
393
|
-
f"{
|
|
410
|
+
f"{RELEASE_VERSION} {platform_tag()}\n", encoding="utf-8"
|
|
394
411
|
)
|
|
395
412
|
|
|
396
413
|
if root.exists():
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"ghc-payload-9.4.
|
|
3
|
-
"ghc-payload-9.4.
|
|
4
|
-
"ghc-payload-9.4.
|
|
2
|
+
"ghc-payload-9.4.9-macosx_11_0_arm64.tar.xz": "6cc3d01e5e69524001d9211138382093c41d09da852aeee7f871b0d563afb31c",
|
|
3
|
+
"ghc-payload-9.4.9-manylinux_2_39_x86_64.tar.xz": "13dc0b399796c6a2fadeb1f11154cfa9e7698507fb9ba07cf0e5aa7a2024293a",
|
|
4
|
+
"ghc-payload-9.4.9-win_amd64.zip": "4ff104a37873757d7c2f4414360a08c3f07ccb49aa018c8b29a70c7cb4989e14"
|
|
5
5
|
}
|
ghc_compiler_python/wrapper.py
CHANGED
|
@@ -223,10 +223,56 @@ def _resolve_binary(name: str) -> str:
|
|
|
223
223
|
)
|
|
224
224
|
|
|
225
225
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
226
|
+
#: Where the Windows bindist keeps the C toolchain it ships with itself,
|
|
227
|
+
#: relative to the toolchain root. Verified against the published payload:
|
|
228
|
+
#: mingw/bin/clang.exe and mingw/bin/ld.exe are both present. GHC 9.4.8 for
|
|
229
|
+
#: Windows drives clang, not gcc.
|
|
230
|
+
_BUNDLED_LINKERS = (
|
|
231
|
+
"mingw/bin/clang.exe",
|
|
232
|
+
"mingw/bin/gcc.exe",
|
|
233
|
+
"mingw/bin/clang",
|
|
234
|
+
"mingw/bin/gcc",
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _bundled_c_linker(root: Optional[Path]) -> Optional[Path]:
|
|
239
|
+
"""Return the C compiler shipped inside the toolchain, if there is one."""
|
|
240
|
+
if root is None:
|
|
241
|
+
return None
|
|
242
|
+
for relative in _BUNDLED_LINKERS:
|
|
243
|
+
candidate = root / relative
|
|
244
|
+
if candidate.is_file():
|
|
245
|
+
return candidate
|
|
246
|
+
return None
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _validate_c_linker(root: Optional[Path] = None) -> None:
|
|
250
|
+
"""Assert that a C toolchain GHC can actually drive is reachable.
|
|
251
|
+
|
|
252
|
+
GHC shells out to a C compiler to assemble and link, so its absence is
|
|
253
|
+
worth catching before the user sees a confusing error from deep inside
|
|
254
|
+
the compiler. But *where* that compiler comes from differs by platform:
|
|
255
|
+
|
|
256
|
+
Unix GHC uses the system cc. Absent means absent.
|
|
257
|
+
Windows the bindist carries its own. mingw/bin/clang.exe and
|
|
258
|
+
mingw/bin/ld.exe live inside the payload, and that toolchain
|
|
259
|
+
is the single largest reason the Windows payload is 395 MB
|
|
260
|
+
against 87 MB for Linux.
|
|
261
|
+
|
|
262
|
+
Checking only `shutil.which` therefore rejected every Windows machine
|
|
263
|
+
without a system gcc -- including machines that had just downloaded a
|
|
264
|
+
complete toolchain and were holding it in the cache. CI never caught it
|
|
265
|
+
because the windows-latest runner installs mingw via chocolatey, so a
|
|
266
|
+
system compiler is always on PATH there. The delivered path found it on
|
|
267
|
+
the first real user run.
|
|
268
|
+
"""
|
|
269
|
+
if shutil.which("gcc") or shutil.which("clang"):
|
|
270
|
+
return
|
|
271
|
+
|
|
272
|
+
if _bundled_c_linker(root) is not None:
|
|
273
|
+
return
|
|
274
|
+
|
|
275
|
+
_die("FATAL ERROR: The GHC compiler requires a host C-linker (gcc or clang).")
|
|
230
276
|
|
|
231
277
|
|
|
232
278
|
def _find_platform_lib_subdir() -> str:
|
|
@@ -309,6 +355,16 @@ def _sterilize_environment() -> dict:
|
|
|
309
355
|
ghc_root / "lib" / f"ghc-{GHC_VERSION}",
|
|
310
356
|
ghc_root / "lib" / f"ghc-{GHC_VERSION}" / "lib",
|
|
311
357
|
Path(_find_platform_lib_subdir() or "."),
|
|
358
|
+
# Shipped inside the payload, so the thin-wheel path is as
|
|
359
|
+
# self-contained as the Windows one. GHC 9.4.8 links against
|
|
360
|
+
# ncurses 5; Ubuntu 24.04 ships ncurses 6 and has no
|
|
361
|
+
# libtinfo.so.5, so without this the first command a user runs
|
|
362
|
+
# dies with "error while loading shared libraries".
|
|
363
|
+
#
|
|
364
|
+
# This is the Linux twin of the mingw case above: the payload
|
|
365
|
+
# carries the dependency, and the launcher has to be willing to
|
|
366
|
+
# look inside the payload for it.
|
|
367
|
+
ghc_root / "vendor-lib",
|
|
312
368
|
# auditwheel vendors shared objects here on the offline wheel.
|
|
313
369
|
Path(__file__).resolve().parent.parent / "ghc_compiler_python.libs",
|
|
314
370
|
]
|
|
@@ -676,7 +732,23 @@ def _ghc_pkg_recache(pkg_db_dir: str, env: dict) -> None:
|
|
|
676
732
|
|
|
677
733
|
def _execute_tool(tool_name: str, extra_args: Optional[List[str]] = None) -> NoReturn:
|
|
678
734
|
"""Generic subprocess proxy for bundled Haskell tooling."""
|
|
679
|
-
|
|
735
|
+
# Acquire the toolchain first. Everything below describes or patches it,
|
|
736
|
+
# and none of that can be done correctly before it exists.
|
|
737
|
+
#
|
|
738
|
+
# The previous order validated the linker, sterilised the environment and
|
|
739
|
+
# ran _resolve_runtime_paths -- which rewrites @GHC_PREFIX@ to the real
|
|
740
|
+
# root -- and only then called _resolve_binary, which is what actually
|
|
741
|
+
# downloads the payload. On a thin-wheel install there was no toolchain on
|
|
742
|
+
# disk during the patch step, so _ghc_root_or_prefix fell back to
|
|
743
|
+
# sys.prefix, the resource scan found nothing, and the placeholders were
|
|
744
|
+
# left unresolved.
|
|
745
|
+
#
|
|
746
|
+
# This never showed up in CI because the offline wheel ships the toolchain
|
|
747
|
+
# inside the package, so a bundled root is present from the first line and
|
|
748
|
+
# the ordering makes no observable difference. It only breaks on the path
|
|
749
|
+
# every PyPI user takes.
|
|
750
|
+
root = _ghc_root()
|
|
751
|
+
_validate_c_linker(root)
|
|
680
752
|
env = _sterilize_environment()
|
|
681
753
|
_resolve_runtime_paths(env)
|
|
682
754
|
binary_path = _resolve_binary(tool_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghc-compiler-python
|
|
3
|
-
Version: 9.4.
|
|
3
|
+
Version: 9.4.9
|
|
4
4
|
Summary: Native GHC 9.4.8 compiler and Cabal 3.10.3.0 tooling packaged as an isolated Python Wheel
|
|
5
5
|
Project-URL: Homepage, https://github.com/Saimonokuma/GHC-COMPILER-PYTHON
|
|
6
6
|
Project-URL: Source, https://github.com/Saimonokuma/GHC-COMPILER-PYTHON
|
|
@@ -80,9 +80,9 @@ The PyPI package is **~17 KiB**. It fetches the toolchain for your platform on f
|
|
|
80
80
|
Self-contained wheels with the toolchain already bundled live on the [releases page](https://github.com/Saimonokuma/GHC-COMPILER-PYTHON/releases). These never contact the network:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
pip install ghc_compiler_python-9.4.
|
|
84
|
-
pip install ghc_compiler_python-9.4.
|
|
85
|
-
pip install ghc_compiler_python-9.4.
|
|
83
|
+
pip install ghc_compiler_python-9.4.9-py3-none-manylinux_2_38_x86_64.manylinux_2_39_x86_64.whl # Linux
|
|
84
|
+
pip install ghc_compiler_python-9.4.9-py3-none-macosx_11_0_arm64.whl # macOS
|
|
85
|
+
pip install ghc_compiler_python-9.4.9-py3-none-win_amd64.whl # Windows
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
> The Linux offline wheel carries the tags `manylinux_2_38` **and** `manylinux_2_39`, so it installs on glibc 2.38 or newer. That floor is not chosen — auditwheel derives it by inspecting the versioned symbols the binaries actually reference. A tag lower than the binaries support would install on systems where the toolchain then fails at runtime, so the build states what is true rather than what would be convenient. On older distributions use the thin wheel; its payload is a plain tarball and carries no such constraint.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ghc_compiler_python/__init__.py,sha256=EQl3IbIry2EdSHPHCO3qj5PgXEDzKOUlpGcqf6lc_m8,609
|
|
2
|
+
ghc_compiler_python/bootstrap.py,sha256=eDe0uRaIFhDWfEjntQP9F043PiHvWljmVnL9Xqix3Bo,15902
|
|
3
|
+
ghc_compiler_python/payload_hashes.json,sha256=_fyFJqESXvFLgVyulav8Pk8M-3mhYekegxGAoRU5s_Q,344
|
|
4
|
+
ghc_compiler_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
ghc_compiler_python/wrapper.py,sha256=RLeOeGc2kn9CVrebHIpbjfWiI-yWn8qcmjIJ5HwyK4s,31021
|
|
6
|
+
ghc_compiler_python-9.4.9.dist-info/METADATA,sha256=wlN_tefM9ZittG3MKTrmOsSUwBBpFMmw6KO6y503xrA,9247
|
|
7
|
+
ghc_compiler_python-9.4.9.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
8
|
+
ghc_compiler_python-9.4.9.dist-info/entry_points.txt,sha256=9QtlqeGuoonFb4bB4F-gLlBbY0koqkTJ2PknLFrvsvo,610
|
|
9
|
+
ghc_compiler_python-9.4.9.dist-info/licenses/LICENSE,sha256=OOef9xbIXwIBos0C1icJ5Z_i44n_VO33KjqyeBTa-tk,1068
|
|
10
|
+
ghc_compiler_python-9.4.9.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
ghc_compiler_python/__init__.py,sha256=N4kbpSKof782d2NNXc5JGUwbpJD7GDB-PpMT0PJbNuk,306
|
|
2
|
-
ghc_compiler_python/bootstrap.py,sha256=kISTQ9uEFDvTccL__a0q94_stYDUCCfqBkYA1be2ySU,14985
|
|
3
|
-
ghc_compiler_python/payload_hashes.json,sha256=r-HmvRveNzX92xGq-3K8JGcnTFdGp8KIXkub5CmDg_A,344
|
|
4
|
-
ghc_compiler_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
ghc_compiler_python/wrapper.py,sha256=golkrZaFxSl0iXzy-0blkaW-ic0f3Q6FPRCAPVZOw4A,27705
|
|
6
|
-
ghc_compiler_python-9.4.8.dist-info/METADATA,sha256=B4Kbst9XS3NafvbWI1CarYQakEDjfCDyF5SQIbQfi40,9247
|
|
7
|
-
ghc_compiler_python-9.4.8.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
8
|
-
ghc_compiler_python-9.4.8.dist-info/entry_points.txt,sha256=9QtlqeGuoonFb4bB4F-gLlBbY0koqkTJ2PknLFrvsvo,610
|
|
9
|
-
ghc_compiler_python-9.4.8.dist-info/licenses/LICENSE,sha256=OOef9xbIXwIBos0C1icJ5Z_i44n_VO33KjqyeBTa-tk,1068
|
|
10
|
-
ghc_compiler_python-9.4.8.dist-info/RECORD,,
|
|
File without changes
|
{ghc_compiler_python-9.4.8.dist-info → ghc_compiler_python-9.4.9.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{ghc_compiler_python-9.4.8.dist-info → ghc_compiler_python-9.4.9.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|