Feature Description
On Windows the server can exit before it starts, with nothing that points at why:
ImportError: DLL load failed while importing _greenlet: The specified module could not be found.
Turn that into a message naming what is missing and where it comes from, and record it in the troubleshooting sections of the README.
Use Case
Reported in #688, and independently by the same user against another project that ships this server as a channel. Both landed on pinning greenlet<3.3 as the fix, which is the wrong medicine: the wheel is fine, it gained a system dependency.
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 now. Import tables of the published cp312-win_amd64 wheels:
| release |
imports |
| 3.2.4 |
KERNEL32.dll, python312.dll |
| 3.3.0 |
KERNEL32.dll, python312.dll |
| 3.3.1 through 3.5.4 |
plus MSVCP140.dll, VCRUNTIME140.dll, VCRUNTIME140_1.dll |
MSVCP140.dll comes with the Visual C++ redistributable and no Python distribution ships it. The python.org installer and the python-build-standalone builds uv uses both carry vcruntime140.dll and vcruntime140_1.dll and stop there, so a uvx user is more exposed than most.
We never call greenlet. patchright imports it unconditionally from _impl/_connection.py, on the async-only path too, so it loads in every run and a failure there stops the server before anything of ours executes.
Fixed upstream in python-greenlet/greenlet#525 / python-greenlet/greenlet#526, which does not retire this: the affected wheels stay on PyPI for good, and any resolver landing on one reproduces the failure.
Suggested Approach
A probe in the package __init__, which is the only place both entry paths reach before cli_main pulls in patchright. Windows only, and free on the path that matters because patchright imports the same module moments later. Match on DLL load failed, which CPython formats itself and is English on every install, and re-raise anything else untouched so a merely absent greenlet is not handed advice about a redistributable.
Feature Description
On Windows the server can exit before it starts, with nothing that points at why:
Turn that into a message naming what is missing and where it comes from, and record it in the troubleshooting sections of the README.
Use Case
Reported in #688, and independently by the same user against another project that ships this server as a channel. Both landed on pinning
greenlet<3.3as the fix, which is the wrong medicine: the wheel is fine, it gained a system dependency.greenlet moved its Windows builds from Appveyor to GitHub Actions in 3.3.1 and lost the
GREENLET_STATIC_RUNTIMEflag on the way, so_greenlet.pydlinks the C++ runtime dynamically now. Import tables of the publishedcp312-win_amd64wheels:KERNEL32.dll,python312.dllKERNEL32.dll,python312.dllMSVCP140.dll,VCRUNTIME140.dll,VCRUNTIME140_1.dllMSVCP140.dllcomes with the Visual C++ redistributable and no Python distribution ships it. The python.org installer and the python-build-standalone buildsuvuses both carryvcruntime140.dllandvcruntime140_1.dlland stop there, so auvxuser is more exposed than most.We never call greenlet. patchright imports it unconditionally from
_impl/_connection.py, on the async-only path too, so it loads in every run and a failure there stops the server before anything of ours executes.Fixed upstream in python-greenlet/greenlet#525 / python-greenlet/greenlet#526, which does not retire this: the affected wheels stay on PyPI for good, and any resolver landing on one reproduces the failure.
Suggested Approach
A probe in the package
__init__, which is the only place both entry paths reach beforecli_mainpulls in patchright. Windows only, and free on the path that matters because patchright imports the same module moments later. Match onDLL load failed, which CPython formats itself and is English on every install, and re-raise anything else untouched so a merely absent greenlet is not handed advice about a redistributable.