Skip to content

Stop embedding a manifest in Windows DLLs and extension modules - #1403

Open
mkanat wants to merge 1 commit into
astral-sh:mainfrom
mkanat:disable-dll-manifests
Open

mkanat wants to merge 1 commit into
astral-sh:mainfrom
mkanat:disable-dll-manifests

Conversation

@mkanat

@mkanat mkanat commented Oct 24, 2026 •

Copy link
Copy Markdown

Summary

The way that CPython compiles DLLs for Windows causes a (unnecessary) problem with long paths. I've filed an upstream issue, too (python/cpython#160624), but it seems worth fixing in PBS because it's just a simple build change that should have no consequences anywhere.

Problem

python.exe fails to start with STATUS_NAME_TOO_LONG once its path is 247 characters or longer. It turns out, this is actually from DLL loading, not from python.exe itself.

It happens only because the DLLs contain an unnecessary manifest. The manifest doesn't do anything in a DLL. Windows only takes the supported OS versions and the Common Controls dependency from the EXE's manifest.

Extension modules like _ctypes and _ssl also fail to import when the install itself is at a long path, for this same reason.

History

DLLs used to need a manifest. With Visual C++ 2008, which Python 2.6 through 3.2 were built with, a DLL had to declare its dependency on the C runtime in an embedded manifest to find it. However, Visual C++ 2010 stopped using manifests to find the C runtime, so DLLs haven't needed one since.

python/cpython#67207 (bpo-23018) added the manifest to python_nt.rc in 2015, at the same time as the one for python[w].exe, to declare supportedOS so that GetVersion would stop reporting Windows 8 on newer versions.

In 2016, python/cpython#71496 (bpo-27309) added the Common Controls dependency so that tkinter's native dialogs would get the right styles. From that change: "Windows needs to load a different version of a particular DLL for the entire process." However, that's only information that the process needs, not the DLLs.

python/cpython#71918 (bpo-27731) added longPathAware later that year.

Solution

This adds a patch that removes the manifest from both resource scripts, for every CPython version. The executables keep theirs.

@mkanat
mkanat force-pushed the disable-dll-manifests branch from 7109eb8 to d13b03e Compare October 24, 2026 21:11
CPython's python_nt.rc and sqlite3.rc embed python.exe's manifest in
python3XY.dll, python3.dll, sqlite3.dll, and every extension module as
resource ID 2. Windows fails to load a DLL with an embedded manifest
from a path near MAX_PATH, even with long paths enabled, so python.exe
fails to start once its path is 247 characters or longer when the DLL
is next to it. The executables keep their manifest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zanieb zanieb added the platform:windows Specific to the Windows platform label Oct 24, 2026
@mkanat
mkanat marked this pull request as ready for review October 24, 2026 21:16
@mkanat

mkanat commented Oct 24, 2026

Copy link
Copy Markdown
Author

Oh, and I did validate that this solves the problem I ran into, on a local Windows Server 2025 VM.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform:windows Specific to the Windows platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants