pypa / pypa/setuptools

[BUG] `export_symbols` kwarg of Extension modifies argument on Windows

Open
#3,058 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug help wanted
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
  1. Installed the latest version of setuptools from pip.
  2. 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_bar which was picked up through extra_export. This can be mitigated by passing a copy of extra_export to each of the Extension.
  3. 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.