Skip to content

Free-threaded and GIL-enabled Windows builds should share an abi3 libpython dll #148690

Closed

Description

@ngoldbaum

Bug description:

Currently, the free-threaded interpreter ships python3t.dll and the GIL-enabled interpreter ships python3.dll. If the guidance is for abi3t extensions to link against python3t.dll, then that means abi3t extensions won't be importable on the GIL-enabled build without shipping python3t.dll alongside python3.dll.

Another possible fix is to make the GIL-enabled build ship python3.dll and make abi3t extensions like against python3.dll.

Either way, fixing this will require touching the file layout of the Windows installation, which @zooba tells me has to happen before beta1.

You can reproduce this by cloning the stable-abi-testing repository and building the setuptools/c example on the free-threaded build and then trying to import the wheel you get on the GIL-enabled build:

Details
PS C:\Users\goldbaum\stable-abi-testing> uv venv --python=3.15.0a8t
Using CPython 3.15.0a8+freethreaded
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activate
PS C:\Users\goldbaum\stable-abi-testing> .\.venv\Scripts\activate
(stable-abi-testing) PS C:\Users\goldbaum\stable-abi-testing> uv pip install "git+https://github.com/ngoldbaum/setuptools@abi3.abi3t"
Resolved 1 package in 390ms
Installed 1 package in 378ms
 + setuptools==82.0.0 (from git+https://github.com/ngoldbaum/setuptools@f7b3c3c5ad49dd070cacf16599776c07be234449)
 (stable-abi-testing) PS C:\Users\goldbaum\stable-abi-testing> uv pip install "git+https://github.com/ngoldbaum/setuptools@abi3.abi3t"
Resolved 1 package in 390ms
Installed 1 package in 378ms
 + setuptools==82.0.0 (from git+https://github.com/ngoldbaum/setuptools@f7b3c3c5ad49dd070cacf16599776c07be234449)
 (stable-abi-testing) PS C:\Users\goldbaum\stable-abi-testing\setuptools\c> python -m build --no-isolation
* Getting build dependencies for sdist...
C:\Users\goldbaum\stable-abi-testing\.venv\Lib\site-packages\setuptools\config\pyprojecttoml.py:72: _ExperimentalConfiguration: `[tool.setuptools.ext-modules]` in `pyproject.toml` is still *experimental* and likely to change in future releases.
  config = read_configuration(filepath, True, ignore_option_errors, dist)
running egg_info
creating limited_api.egg-info
writing limited_api.egg-info\PKG-INFO
writing dependency_links to limited_api.egg-info\dependency_links.txt
writing top-level names to limited_api.egg-info\top_level.txt
writing manifest file 'limited_api.egg-info\SOURCES.txt'
reading manifest file 'limited_api.egg-info\SOURCES.txt'
writing manifest file 'limited_api.egg-info\SOURCES.txt'
* Building sdist...
C:\Users\goldbaum\stable-abi-testing\.venv\Lib\site-packages\setuptools\config\pyprojecttoml.py:72: _ExperimentalConfiguration: `[tool.setuptools.ext-modules]` in `pyproject.toml` is still *experimental* and likely to change in future releases.
  config = read_configuration(filepath, True, ignore_option_errors, dist)
running sdist
running egg_info
writing limited_api.egg-info\PKG-INFO
writing dependency_links to limited_api.egg-info\dependency_links.txt
writing top-level names to limited_api.egg-info\top_level.txt
reading manifest file 'limited_api.egg-info\SOURCES.txt'
writing manifest file 'limited_api.egg-info\SOURCES.txt'
warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md

running check
creating limited_api-1.2.3
creating limited_api-1.2.3\limited_api.egg-info
copying files to limited_api-1.2.3...
copying limited.c -> limited_api-1.2.3
copying pyproject.toml -> limited_api-1.2.3
copying setup.cfg -> limited_api-1.2.3
copying limited_api.egg-info\PKG-INFO -> limited_api-1.2.3\limited_api.egg-info
copying limited_api.egg-info\SOURCES.txt -> limited_api-1.2.3\limited_api.egg-info
copying limited_api.egg-info\dependency_links.txt -> limited_api-1.2.3\limited_api.egg-info
copying limited_api.egg-info\top_level.txt -> limited_api-1.2.3\limited_api.egg-info
copying limited_api.egg-info\SOURCES.txt -> limited_api-1.2.3\limited_api.egg-info
Writing limited_api-1.2.3\setup.cfg
Creating tar archive
removing 'limited_api-1.2.3' (and everything under it)
* Building wheel from sdist
* Getting build dependencies for wheel...
C:\Users\goldbaum\stable-abi-testing\.venv\Lib\site-packages\setuptools\config\pyprojecttoml.py:72: _ExperimentalConfiguration: `[tool.setuptools.ext-modules]` in `pyproject.toml` is still *experimental* and likely to change in future releases.
  config = read_configuration(filepath, True, ignore_option_errors, dist)
running egg_info
writing limited_api.egg-info\PKG-INFO
writing dependency_links to limited_api.egg-info\dependency_links.txt
writing top-level names to limited_api.egg-info\top_level.txt
reading manifest file 'limited_api.egg-info\SOURCES.txt'
writing manifest file 'limited_api.egg-info\SOURCES.txt'
* Building wheel...
C:\Users\goldbaum\stable-abi-testing\.venv\Lib\site-packages\setuptools\config\pyprojecttoml.py:72: _ExperimentalConfiguration: `[tool.setuptools.ext-modules]` in `pyproject.toml` is still *experimental* and likely to change in future releases.
  config = read_configuration(filepath, True, ignore_option_errors, dist)
running bdist_wheel
running build
running build_ext
building 'limited' extension
creating build\temp.win-amd64-cpython-315t\Release
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DPy_GIL_DISABLED=1 -IC:\Users\goldbaum\stable-abi-testing\.venv\include -IC:\Users\goldbaum\AppData\Roaming\uv\python\cpython-3.15+freethreaded-windows-x86_64-none\include -IC:\Users\goldbaum\AppData\Roaming\uv\python\cpython-3.15+freethreaded-windows-x86_64-none\Include "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.1\include\um" /Tclimited.c /Fobuild\temp.win-amd64-cpython-315t\Release\limited.obj -DPy_LIMITED_API=0x030f0000 -DPy_TARGET_ABI3T=0x030f0000
limited.c
creating C:\Users\goldbaum\AppData\Local\Temp\build-via-sdist-g3tcaad2\limited_api-1.2.3\build\lib.win-amd64-cpython-315t
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\goldbaum\stable-abi-testing\.venv\libs /LIBPATH:C:\Users\goldbaum\AppData\Roaming\uv\python\cpython-3.15+freethreaded-windows-x86_64-none\libs /LIBPATH:C:\Users\goldbaum\AppData\Roaming\uv\python\cpython-3.15+freethreaded-windows-x86_64-none /LIBPATH:C:\Users\goldbaum\stable-abi-testing\.venv\PCbuild\amd64 "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.26100.0\\um\x64" /EXPORT:PyInit_limited build\temp.win-amd64-cpython-315t\Release\limited.obj /OUT:build\lib.win-amd64-cpython-315t\limited.pyd /IMPLIB:build\temp.win-amd64-cpython-315t\Release\limited.lib
   Creating library build\temp.win-amd64-cpython-315t\Release\limited.lib and object build\temp.win-amd64-cpython-315t\Release\limited.exp
Generating code
Finished generating code
installing to build\bdist.win-amd64\wheel
running install
running install_lib
creating build\bdist.win-amd64\wheel
copying build\lib.win-amd64-cpython-315t\limited.pyd -> build\bdist.win-amd64\wheel\.
running install_egg_info
running egg_info
writing limited_api.egg-info\PKG-INFO
writing dependency_links to limited_api.egg-info\dependency_links.txt
writing top-level names to limited_api.egg-info\top_level.txt
reading manifest file 'limited_api.egg-info\SOURCES.txt'
writing manifest file 'limited_api.egg-info\SOURCES.txt'
Copying limited_api.egg-info to build\bdist.win-amd64\wheel\.\limited_api-1.2.3-py3.15.egg-info
running install_scripts
creating build\bdist.win-amd64\wheel\limited_api-1.2.3.dist-info\WHEEL
creating 'C:\\Users\\goldbaum\\stable-abi-testing\\setuptools\\c\\dist\\.tmp-t0bncj0f\\limited_api-1.2.3-cp315-abi3.abi3t-win_amd64.whl' and adding 'build\\bdist.win-amd64\\wheel' to it
adding 'limited.pyd'
adding 'limited_api-1.2.3.dist-info/METADATA'
adding 'limited_api-1.2.3.dist-info/WHEEL'
adding 'limited_api-1.2.3.dist-info/top_level.txt'
adding 'limited_api-1.2.3.dist-info/RECORD'
removing build\bdist.win-amd64\wheel
Successfully built limited_api-1.2.3.tar.gz and limited_api-1.2.3-cp315-abi3.abi3t-win_amd64.whl
(stable-abi-testing) PS C:\Users\goldbaum\stable-abi-testing\setuptools\c> deactivate
PS C:\Users\goldbaum\stable-abi-testing\setuptools\c> uv venv --python=3.15.0a8
Using CPython 3.15.0a8
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activate
PS C:\Users\goldbaum\stable-abi-testing\setuptools\c> .\.venv\Scripts\activate
(c) PS C:\Users\goldbaum\stable-abi-testing\setuptools\c> uv pip install .\dist\limited_api-1.2.3-cp315-abi3.abi3t-win_amd64.whl
Resolved 1 package in 16ms
Prepared 1 package in 20ms
Installed 1 package in 11ms
 + limited-api==1.2.3 (from file:///C:/Users/goldbaum/stable-abi-testing/setuptools/c/dist/limited_api-1.2.3-cp315-abi3.abi3t-win_amd64.whl)
 (c) PS C:\Users\goldbaum\stable-abi-testing\setuptools\c> python
Python 3.15.0a8 (main, Apr 14 2026, 14:44:01) [MSC v.1950 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import limited
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    import limited
ImportError: DLL load failed while importing limited: The specified module could not be found.

The dumpbin output says the extension is linked against python3t.dll:

PS C:\Program Files\Microsoft Visual Studio\2022\Community> dumpbin /dependents C:\Users\goldbaum\stable-abi-testing\.venv\Lib\site-packages\limited.pyd
Microsoft (R) COFF/PE Dumper Version 14.44.35225.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\Users\goldbaum\stable-abi-testing\.venv\Lib\site-packages\limited.pyd

File Type: DLL

  Image has the following dependencies:

    python3t.dll
    KERNEL32.dll
    VCRUNTIME140.dll
    api-ms-win-crt-runtime-l1-1-0.dll

  Summary

        1000 .data
        1000 .pdata
        1000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text

See discussion in this comment and the replies: #146636 (comment).

CPython versions tested on:

3.15

Operating systems tested on:

Windows

Linked PRs

Activity

  1. mgorny commented on Apr 17, 2026

    @mgorny
    Contributor

    A related problem is that PEP 739 build-details.json specifies a libpython.dynamic_stableapi entry that — at least to my best understanding — would list python3.dll on GIL-enabled biuld, and python3t.dll on freethreading build. However, for abi3t builds from GIL-enable Python, we'd need another entry specifying python3t.dll.

    CC @FFY00

  2. encukou commented on Apr 23, 2026

    @encukou
    Member

    Continuing from the thread in #146636 where we mapped the strategy:

    • GIL-ful build should add abi3t-compat\python3t.dll, linked to its python3XX.dll.
      • If the installation is potentially shared with free-threaded build, this should be installed in abi3t-compat\python3t.dll
      • Otherwise, it should be installed alongside python3.dll
    • abi3.abi3t extensions should be linked to python3t.dll

    I managed to do the building part in #148912. I'd welcome any reviews or pointers; it's the first time I looked at the XMLs seriously.

    I could not build the installer though; even on main, Tools\msi\build.bat gives me this error on my machine:1

    light.exe : error LGHT0217: Error executing ICE action 'ICE01'. The most common cause of this kind of ICE failure is 
    an incorrectly registered scripting engine. See http://wixtoolset.org/documentation/error217/ for details and how to  
    solve this problem. The following string format was not expected by the external UI message logger: "The Windows Inst 
    aller Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your 
     support personnel for assistance.". [C:\Users\encukou\dev\cpython\Tools\msi\launcher\launcher.wixproj]

    I'd appreciate any tips
    cc @chris-eibl -- do you have experience here?

    Footnotes

    1. “Error executing ICE action” sounds nice, but I'd rather not run the action at all if it was up to me... ↩

  3. zooba commented on Apr 23, 2026

    @zooba
    Member

    I could not build the installer though; even on main, Tools\msi\build.bat gives me this error on my machine

    I see a few suggestions that it means your environment is too big (>32KB for all variables), but you could try just adding SuppressValidation=true to your environment1 to skip those checks. They won't be so important for what you're doing here.

    Footnotes

    1. Yes, making it even bigger! ↩

  4. chris-eibl commented on Apr 23, 2026

    @chris-eibl
    Member

    cc @chris-eibl -- do you have experience here?

    Sorry, no idea, I have never seen this error before. Hopefull, Steve's hint already helped out ...

  5. encukou commented on May 1, 2026

    @encukou
    Member

    Marking as potential release blocker for visibility.

  6. added a commit that references this issue on May 4, 2026
  7. hugovk commented on May 4, 2026

    @hugovk
    Member

    Is this release blocker now resolved for 3.15?

  8. encukou commented on May 5, 2026

    @encukou
    Member

    Yeah, this is as good as it'll get before the actual release.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions