`cffi>=1.16.0` failing to install on `mingw`
abravalheri opened this issue · 2 comments
Recently I was changing something unrelated in setuptools-rust
and I noticed that pip install cffi
started to fail in mingw
. When I tried to cap the version with cffi<1.16
everything installed well.
Which lead me to investigate what is causing this.
I created this repo just to use github CI (since I don't have access to a mingw
environment to run the tests manually).
The reproducer (encoded in the Github workflow of the repository mentioned above) is relatively simple:
- Given: a
mingw
environment setup usingmsys2
and with the following packages installed:mingw-w64-{i686/x86_64}-python
⇒ This should give you Python 3.11.6mingw-w64-{i686/x86_64}-python-pip
mingw-w64-{i686/x86_64}-openssl
mingw-w64-{i686/x86_64}-toolchain
(The choice betweeni686
andx86_64
depends on themingw
architecture you are running)
- Install the latest versions of
pip
,setuptools
,wheel
:python -m pip install -U pip setuptools wheel python -m pip list # Package Version # ---------- ------- # distlib 0.3.7 # pip 23.2.1 # setuptools 68.2.2 # wheel 0.41.2
- Attempt to install the latest version of
cffi
... and observe the error (triggered by https://github.com/python-cffi/cffi/blob/v1.16.0/setup.py#L105 - https://github.com/python-cffi/cffi/blob/v1.16.0/setup.py#L126).python -m pip -v install -U "cffi>=1.16.0" # ... # File "D:/a/_temp/msys64/tmp/pip-build-env-l9qomo_f/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 341, in run_setup # exec(code, locals()) # File "<string>", line 126, in <module> # File "<string>", line 105, in uses_msvc # File "D:/a/_temp/msys64/tmp/pip-build-env-l9qomo_f/overlay/lib/python3.11/site-packages/setuptools/_distutils/command/config.py", line 223, in try_compile # ... # distutils.errors.DistutilsPlatformError: --plat-name must be one of ('win32', 'win-amd64', 'win-arm32', 'win-arm64') # ...
As show in the Github workflow there are a few interesting things:
- The error does not happen for
cffi<1.16
(even if I installsetuptools
and exportSETUPTOOLS_USE_DISTUTILS=local
, which I expect to replace any imports fromdistutils
withsetuptools._distutils
even ifsetuptools
is not imported -- including during the build ofcffi
). - The error does not happen if I pass
--no-build-isolation
topip
I can see that mingw==1.16.0
added pyproject.toml
which makes pip
treat the installation process differently (instead of running python setup.py ...
it will call the PEP 517 hooks), and the error seems to happen when pip
calls the PEP 517 hook: setuptools.build_meta.get_requires_for_build_wheel
(which is internally translated by setuptools
into a patched egg_info
call -- it is a lot of patching...).
Something else that I am not understanding (probably unrelated) is why in some cases distutils
is still being loaded from setuptools._distutils
even when SETUPTOOLS_USE_DISTUTILS=stdlib
.
The reason why I opened the issue is to bring this problem to your attention and ask if you have any suggestions, tips that can help to solve this problem.
In principle it seems to be a compatibility issue with the procedure setuptools employs to support backwards compatibility with packages that need setup_requires
, but I still couldn't figure out exactly was is causing the problem.
The fact that cffi<1.16
is compatible with setuptools._distutils
puzzles me.
Moreover, cffi==1.16
works fine with pip install --no-build-isolation
.
So when running the other PEP 517 hooks, distutils/_msvccompiler.py
never seems to be used, but for that specific patched egg_info
, this problematic code path is triggered. Any idea why is that the case?
One thing that might be important to mention is that mingw
does not seem to be officially supported in distutils
(pypa/distutils#34), but cffi
seems to support it.
Yeah, the ongoing tug-of-war around PEP517/518 config_settings mappings and how pip/build/setuptools maps them to old distutils command args and decide which build hooks receive them is causing grief in a lot of places. The setuptools-embedded distutils has been provided and used by default for a very long time via their _distutils_hack
.pth
shim, so that's probably a red herring. As you noted, CFFI 1.16 is the first release that uses a PEP517 build, and when you're running that with build isolation, pip passes the build args through setuptools' generic PEP517 hooks, which then tries to map those args and fails on unsupported values.
IIRC, pip currently skips calling the get_requires_for_build_wheel
PEP517 hook when you disable build isolation, as that also implicitly disables automatic requirements installation (and just uses whatever setuptools/wheel is laying around in your current Python env). Since that setuptools hook's arg translator is the one that's barfing on the unknown platform, skipping it lets the build continue.
I'm just guessing based on my own fights with this same stuff in build
and pip
trying to modernize ancient custom distutils build config stuff in other projects- I don't have mingw/msys2 stuff laying around either. I'm probably unlikely to add it to CFFI's test matrix at this point, as Windows build/test is already by far the slowest and most expensive (further complicated by libffi requiring a GNU toolchain to build).
I don't think there's anything more CFFI can do here- running with build isolation disabled should continue to work for now. You might want to consider a fix PR to setuptools that allows the mingw/msys2 platform arg through that gate, but that's about all I can think of for now. In light of that, I'm going to close this issue.