Restore static linking of the C++ runtime for Windows wheels - #526
Merged
jamadden merged 1 commit intoAug 10, 2026
Merged
Conversation
The Appveyor builds set GREENLET_STATIC_RUNTIME; the GHA step that replaced them does not, so every Windows wheel since 3.3.1 imports MSVCP140.dll, which no Windows CPython distribution ships. Fixes: python-greenlet#525
Contributor
Author
|
CI is green on all Windows jobs. Reading the import table of the wheels this run produced: No |
This was referenced Aug 8, 2026
stickerdaniel
added a commit
to stickerdaniel/linkedin-mcp-server
that referenced
this pull request
Aug 9, 2026
Closes #697 On Windows the server can exit before it starts, with an `ImportError` about `_greenlet` and a DLL that is never named. greenlet moved its Windows builds from Appveyor to GitHub Actions in 3.3.1 and lost the `GREENLET_STATIC_RUNTIME` flag on the way, so `_greenlet.pyd` links the C++ runtime dynamically and needs `MSVCP140.dll`. That DLL comes with the Visual C++ redistributable and no Python distribution ships it, so a machine without the redistributable cannot load greenlet at all. We never call greenlet ourselves; patchright imports it unconditionally on the async-only path, which is why the failure lands before any of our code runs. The probe lives in the package `__init__` because that is the only place both entry paths reach before `cli_main` pulls in patchright, and it costs nothing on the path that matters since patchright imports the same module moments later. It runs on Windows only. It matches on `DLL load failed`, a prefix CPython formats itself in `dynload_win.c` and keeps English on every install, and re-raises anything else untouched so a merely absent greenlet is not handed advice about a redistributable. The message names both routes, because installing the redistributable needs administrator rights that a `uvx` user may not have, and the stopgap it offers is marked x86-64 only since there are no Windows ARM64 wheels before 3.3.1. Two README troubleshooting sections gain the same pointer. The upstream fix is filed as python-greenlet/greenlet#525 with the one-line restore in python-greenlet/greenlet#526, where CI now builds x64 and ARM64 wheels that import nothing beyond `KERNEL32.dll` and the Python DLL again. That does not retire this guard: the affected wheels stay on PyPI, and any resolver landing on one reproduces the failure. Eight tests cover the translated message, the preserved cause, the re-raise, the platform gate and the import ordering, and they run on every platform because the reasoning about a Windows failure should not need a Windows machine; full suite green. See also: #688 ## Synthetic prompt > On Windows without the Visual C++ redistributable the server dies at import with `DLL load failed while importing _greenlet`, because greenlet's wheels stopped linking the C++ runtime statically in 3.3.1. Add a Windows-only startup probe that turns that bare ImportError into a message naming `MSVCP140.dll` and the redistributable, with a stopgap for machines without admin rights. Put it where both entry paths reach it before patchright is imported, keep the detection locale-independent, re-raise unrelated import failures unchanged, and add README troubleshooting entries plus tests that run on every platform. Generated with Claude Opus 5 high + Sol 5.6 xhigh
Contributor
|
Thanks for the diagnosis and quick fix! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
appveyor.ymlsetGREENLET_STATIC_RUNTIME: "1"andsetup.pystill honours it by adding/MT. #490 removed that file when the Windows builds moved to GHA, and the step that replaced it does not set the variable, so every Windows wheel since 3.3.1 links the C++ runtime dynamically and importsMSVCP140.dll. No Windows CPython distribution ships that DLL, so greenlet fails to import on machines without the Visual C++ redistributable.Setting the variable in the step that builds the published Windows wheels restores the behaviour of 3.3.0 and earlier.
setup.pyguards it withis_win, so the Linux build in the same step is unaffected, and the Windows ARM wheels that #490 added keep being produced.Fixes #525