GeezerVison is showing github.com — `PyMODINIT_FUNC` does not apply `__declspec(dllexport)` on Windows · Issue #141671 · python/cpython
PyMODINIT_FUNC does not apply __declspec(dllexport) on Windows #141671
DescriptionThe macro is documented as:
Declare an extension module initialization function. This macro:
- specifies the PyObject* return type,
- adds any special linkage declarations required by the platform, and
- for C++, declares the function as extern "C".
Specifically, the special linkage declarations should be __attribute__ ((visibility ("default"))) on GCC/clang, and __declspec(dllexport) on Windows.
However, the definition assumes we're building CPython itself, and only adds a linkage declaration with Py_ENABLE_SHARED -- that is, when Python itself is built with a shared library.
According to MSVC docs:
There are four methods for exporting a definition, listed in recommended order of use:
__declspec(dllexport) in the source code
- An EXPORTS statement in a .def file
- An /EXPORT specification in a LINK command
- A comment directive in the source code, of the form
#pragma comment(linker, "/export: definition ").
Setuptools, and historically distutils, does (2) -- and so does, presumably, any other build system for native extensions on Windows.
However, this breaks for modules that define the PEP-793 PyModExport hook.
It would be great to switch to the preferred (1), and then tell Setuptools to avoid /EXPORT for 3.15+.
Linked PRs
Activityencukou commented on Nov 18, 2025 AraHaan commented on Dec 29, 2025 I personally think this would be safe to be backported to 3.12, 3.13, 3.14 as adding __declspec(dllexport) to PyMODINIT_FUNC does not break anything.
Also then the setuptools patch would also apply to those versions of python as well when they upgrade the package.
This is because currently what I do to work around this was to
#undef PyMODINIT_FUNC
#if defined(__cplusplus)
#define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
#else /* __cplusplus */
#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
#endif /* __cplusplus */
in my C extension code which I feel could have been avoided entirely. added a commit that references this issue on Jan 7, 2026gh-141671: PyMODINIT_FUNC: apply `__declspec(dllexport)` on Windows (G… encukou commented on Jan 7, 2026 I'd rather let this change have the full alpha/beta period before it hits production. It's old, platform-specific, widely used, and tied to build systems. rgommers commented on Jan 13, 2026
Setuptools, and historically distutils, does (2) -- and so does, presumably, any other build system for native extensions on Windows.
For clarity: I think you meant that setuptools/distutils does (3), not (2). And other build systems/backends do (2).
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|