@@ -217,9 +217,9 @@ Module export hook
217217
218218Unless you've done this step already, your extension module defines a
219219:ref: `module initialization function <extension-pyinit >`
220- named :samp: `PyInit_{ <module_name > } `.
220+ named :samp: `PyInit_{ <modname > } ` (where `` modname `` is the name of your module) .
221221You will need to port it to a :ref: `module export hook <extension-export-hook >`,
222- :samp: `PyModExport_{ <module name > } `, a feature added in CPython 3.15 in
222+ :samp: `PyModExport_{ <modname > } `, a feature added in CPython 3.15 in
223223:pep: `793 `.
224224
225225Your existing init function should look like this (with your own names
@@ -297,6 +297,34 @@ pointer to static data.
297297If you cannot avoid additional code, refer to the
298298:ref: `caveats in PyModExport documentation <pymodexport-api-caveats >`.
299299
300+ .. note ::
301+
302+ When building for Windows using the Setuptools _ build tool,
303+ removing the :samp: `PyInit_{ <modname> } ` function may result in the linker error
304+ :samp: `LINK : error LNK2001: unresolved external symbol PyInit_{ <modname> } `.
305+ This is caused by Setuptools passing an ``/EXPORT `` linker flag, which
306+ is redundant since Python 3.15 (see :gh: `141671 `).
307+ A workaround is to add a dummy :samp: `PyInit_{ <modname> } ` function
308+ to your code.
309+ Python 3.15+ will never call this function if
310+ :samp: `PyModExport_{ <modname> } ` is present, so it can always fail:
311+
312+ .. code-block :: c
313+
314+ // Workaround for https://github.com/pypa/distutils/issues/387
315+ PyMODINIT_FUNC
316+ PyInit_<modname>(void)
317+ {
318+ PyErr_SetString(PyExc_SystemError,
319+ "PyInit_* called for module with PyModExport_*");
320+ return NULL;
321+ }
322+
323+ (This issue is present in Setuptools 84.0.0; it might be fixed in newer
324+ versions.)
325+
326+ .. _Setuptools : https://setuptools.pypa.io/
327+
300328
301329Existing slots
302330--------------
0 commit comments