[BUG] `export_symbols` kwarg of Extension modifies argument on Windows
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.9k
- Forks
- 1.4k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 1
Description
setuptools version
setuptools=='60.5.0'
Python version
Python 3.10.2
OS
Windows 10
Additional environment information
No response
Description
Setuptools/distutils mutates the list passed to export_symbols (adding the necessary PyInit_{ModuleName}). This causes issues when providing the same list of functions to export to multiple Extension.
Expected behavior
I see nothing listed about this behaviour in either the setuptools or distutils docs, and it isn't expected given that extra_compile_args etc do not work this way.
How to Reproduce
- Installed the latest version of setuptools from pip.
- Run the following simple MWE, which produces to short C files to compile into extensions. The first one (bar) is compiled and linked successfully, but baz fails to link as the linker tries to also export
PyInit_barwhich was picked up throughextra_export. This can be mitigated by passing a copy ofextra_exportto each of theExtension. - Attempt to build and install through pip (
python -m pip install .)
MWE:
from setuptools import setup
from setuptools import Extension
for mod in ['bar', 'baz']:
with open(f'{mod}.c', 'w') as f:
f.write(f'#include "Python.h"\nvoid test_fn() {{}}\nPyMODINIT_FUNC PyInit_{mod}() {{ return NULL; }}')
extra_export = ['test_fn']
exts = [Extension('foo.bar', ['bar.c'], export_symbols=extra_export),
Extension('foo.baz', ['baz.c'], export_symbols=extra_export),
]
setup(name='my_foo',
ext_modules=exts)
Output
(Lightweaver) C:\Users\goobley\SetupToolsRepro>python -m pip install .
Processing c:\users\goobley\setuptoolsrepro
Preparing metadata (setup.py) ... done
Building wheels for collected packages: my-foo
Building wheel for my-foo (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: 'E:\miniconda3\envs\Lightweaver\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\goobley\\SetupToolsRepro\\setup.py'"'"'; __file__='"'"'C:\\Users\\goobley\\SetupToolsRepro\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\goobley\AppData\Local\Temp\pip-wheel-biythkw1'
cwd: C:\Users\goobley\SetupToolsRepro\
Complete output (15 lines):
running bdist_wheel
running build
running build_ext
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IE:\miniconda3\envs\Lightweaver\include -IE:\miniconda3\envs\Lightweaver\Include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /Tcbar.c /Fobuild\temp.win-amd64-3.10\Release\bar.obj
bar.c
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:E:\miniconda3\envs\Lightweaver\libs /LIBPATH:E:\miniconda3\envs\Lightweaver /LIBPATH:E:\miniconda3\envs\Lightweaver\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64" /EXPORT:test_fn /EXPORT:PyInit_bar build\temp.win-amd64-3.10\Release\bar.obj /OUT:build\lib.win-amd64-3.10\foo\bar.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\bar.cp310-win_amd64.lib
Creating library build\temp.win-amd64-3.10\Release\bar.cp310-win_amd64.lib and object build\temp.win-amd64-3.10\Release\bar.cp310-win_amd64.exp
Generating code
Finished generating code
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IE:\miniconda3\envs\Lightweaver\include -IE:\miniconda3\envs\Lightweaver\Include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /Tcbaz.c /Fobuild\temp.win-amd64-3.10\Release\baz.obj
baz.c
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:E:\miniconda3\envs\Lightweaver\libs /LIBPATH:E:\miniconda3\envs\Lightweaver /LIBPATH:E:\miniconda3\envs\Lightweaver\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64" /EXPORT:test_fn /EXPORT:PyInit_bar /EXPORT:PyInit_baz build\temp.win-amd64-3.10\Release\baz.obj /OUT:build\lib.win-amd64-3.10\foo\baz.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\baz.cp310-win_amd64.lib
LINK : error LNK2001: unresolved external symbol PyInit_bar
build\temp.win-amd64-3.10\Release\baz.cp310-win_amd64.lib : fatal error LNK1120: 1 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\HostX86\\x64\\link.exe' failed with exit code 1120
----------------------------------------
ERROR: Failed building wheel for my-foo
Running setup.py clean for my-foo
Failed to build my-foo
Installing collected packages: my-foo
Attempting uninstall: my-foo
Found existing installation: my-foo 0.0.0
Can't uninstall 'my-foo'. No files were found to uninstall.
Running setup.py install for my-foo ... error
ERROR: Command errored out with exit status 1:
command: 'E:\miniconda3\envs\Lightweaver\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\goobley\\SetupToolsRepro\\setup.py'"'"'; __file__='"'"'C:\\Users\\goobley\\SetupToolsRepro\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\goobley\AppData\Local\Temp\pip-record-knfq7xj6\install-record.txt' --single-version-externally-managed --compile --install-headers 'E:\miniconda3\envs\Lightweaver\Include\my-foo'
cwd: C:\Users\goobley\SetupToolsRepro\
Complete output (22 lines):
running install
E:\miniconda3\envs\Lightweaver\lib\site-packages\setuptools\command\install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_ext
creating build
creating build\temp.win-amd64-3.10
creating build\temp.win-amd64-3.10\Release
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IE:\miniconda3\envs\Lightweaver\include -IE:\miniconda3\envs\Lightweaver\Include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /Tcbar.c /Fobuild\temp.win-amd64-3.10\Release\bar.obj
bar.c
creating C:\Users\goobley\SetupToolsRepro\build\lib.win-amd64-3.10
creating C:\Users\goobley\SetupToolsRepro\build\lib.win-amd64-3.10\foo
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:E:\miniconda3\envs\Lightweaver\libs /LIBPATH:E:\miniconda3\envs\Lightweaver /LIBPATH:E:\miniconda3\envs\Lightweaver\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64" /EXPORT:test_fn /EXPORT:PyInit_bar build\temp.win-amd64-3.10\Release\bar.obj /OUT:build\lib.win-amd64-3.10\foo\bar.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\bar.cp310-win_amd64.lib
Creating library build\temp.win-amd64-3.10\Release\bar.cp310-win_amd64.lib and object build\temp.win-amd64-3.10\Release\bar.cp310-win_amd64.exp
Generating code
Finished generating code
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IE:\miniconda3\envs\Lightweaver\include -IE:\miniconda3\envs\Lightweaver\Include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /Tcbaz.c /Fobuild\temp.win-amd64-3.10\Release\baz.obj
baz.c
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:E:\miniconda3\envs\Lightweaver\libs /LIBPATH:E:\miniconda3\envs\Lightweaver /LIBPATH:E:\miniconda3\envs\Lightweaver\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64" /EXPORT:test_fn /EXPORT:PyInit_bar /EXPORT:PyInit_baz build\temp.win-amd64-3.10\Release\baz.obj /OUT:build\lib.win-amd64-3.10\foo\baz.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\baz.cp310-win_amd64.lib
LINK : error LNK2001: unresolved external symbol PyInit_bar
build\temp.win-amd64-3.10\Release\baz.cp310-win_amd64.lib : fatal error LNK1120: 1 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\HostX86\\x64\\link.exe' failed with exit code 1120
----------------------------------------
ERROR: Can't roll back my-foo; was not uninstalled
ERROR: Command errored out with exit status 1: 'E:\miniconda3\envs\Lightweaver\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\goobley\\SetupToolsRepro\\setup.py'"'"'; __file__='"'"'C:\\Users\\goobley\\SetupToolsRepro\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\goobley\AppData\Local\Temp\pip-record-knfq7xj6\install-record.txt' --single-version-externally-managed --compile --install-headers 'E:\miniconda3\envs\Lightweaver\Include\my-foo' Check the logs for full command output.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the setup.py reproduction using two Extension objects that share extra_export, then trace how export_symbols is handled during the Windows build. Run python -m pip install . and confirm both extensions build successfully without the shared list gaining another module initializer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100