Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 632: Proposed deprectation of distutils #7702

Closed
FRidh opened this issue Sep 6, 2020 · 28 comments · Fixed by #11133
Closed

PEP 632: Proposed deprectation of distutils #7702

FRidh opened this issue Sep 6, 2020 · 28 comments · Fixed by #11133
Milestone

Comments

@FRidh
Copy link

FRidh commented Sep 6, 2020

There is a PEP proposed for deprecating distutils. Meson uses distutils in the python module for, if I am correct, building extension modules, so this PEP may be of interest to you.

@lazka
Copy link
Contributor

lazka commented Sep 6, 2020

distutils is only used to decide if extensions should link against libpython to follow the platform defaults (Debian patched to not link, default was to link). With Python 3.8 upstream Python default changed to not link to libpython by default, so if distutils ever gets removed, meson can just default to not linking always: https://docs.python.org/3/whatsnew/3.8.html#debug-build-uses-the-same-abi-as-release-build

@eli-schwartz
Copy link
Member

Note that in #9288 we added an additional reliance on distutils (in the same exact introspection command that already imports distutils). In addition to detecting whether to link against libpython, we now also use distutils to detect whether sysconfig is completely crippled by the vendor and unable to tell the truth about install paths.

Handling libpython linking could be done by a try/except that reacts to an ImportError by saying "clearly this must be sys.version_info >= (3, 8) so the answer is don't link".

Handling debian paths cannot be resolved other than by waiting on debian to fix things.

As we get closer to the final removal of distutils in 3.12 we will need to both consider that try/except for libpython, and keep an eye on the debian situation.

@tacaswell
Copy link

distutils has now been pulled out of the main branch of CPython and meson is failing to detect it as a valid Python:

$ meson --version
0.64.0
$ python --version
Python 3.12.0a1+

adapted from numpy's meson branch:

project(
  'test',
  'c',
  version: '0',
  license: 'BSD-3',
  meson_version: '>= 0.64.0',
)

cc = meson.get_compiler('c')

# https://mesonbuild.com/Python-module.html
py_mod = import('python')
py = py_mod.find_installation(pure: false)
py_dep = py.dependency()

$ meson setup build --prefix=/home/tcaswell/.virtualenvs/bleeding/lib/python3.12/site-packages
The Meson build system
Version: 0.64.0
Source dir: /home/tcaswell/source/p/numpy/numpy
Build dir: /home/tcaswell/source/p/numpy/numpy/build
Build type: native build
Project name: test
Project version: 0
C compiler for the host machine: ccache cc (gcc 12.2.0 "cc (GCC) 12.2.0")
C linker for the host machine: cc ld.bfd 2.39.0
Host machine cpu family: x86_64
Host machine cpu: x86_64

meson.build:13:0: ERROR: <PythonExternalProgram 'python3' -> ['/home/tcaswell/.virtualenvs/bleeding/bin/python3']> is not a valid python or it is missing distutils

A full log can be found at /home/tcaswell/source/p/numpy/numpy/build/meson-logs/meson-log.txt

@dcbaker dcbaker added this to the 1.0.0 milestone Nov 14, 2022
@CAM-Gerlach
Copy link

FYI, there's been a migration among packaging tools to use the standalone, modern sysconfig stdlib module over distutils' equivalent, which mesonpy's @FFY00 has led the charge on. Perhaps he has some insightful comments on that here?

@eli-schwartz
Copy link
Member

We already use sysconfig for most things. There is:

  • one thing that sysconfig doesn't currently provide -- I've been meaning to open a CPython ticket to have it added (I mentioned it in passing in a meson-python ticket somewhere) which I will try doing soon
  • one thing that sysconfig does provide, but Debian has frustratingly broken, which I need to investigate whether it works now.

I'll try to see if I can get news on both counts in the near future. Because one of them is totally dependent on Debian's timeframe and they already know about the problem but have been flatly ignoring it for years, I've been letting the general issue slide, hoping that if I check in on it closer to the cutoff point it will finally resolve itself. But I didn't think about people using the alphas for 3.12 a year before the cutoff point. :)

@CAM-Gerlach
Copy link

I see, thanks. In that case, I'd suggest opening a CPython issue for the former as soon as possible (and the latter, if there's anything needed on the upstream end), to allow plenty of time before the beta freeze in less than 6 months for discussion, implementation, review and merging, and preferably allow you, distros and others to test with it.

@tacaswell
Copy link

The suggestion of installing a setuptools 60+ worked for getting meson to work with py312.

@dnicolodi
Copy link
Member

dnicolodi commented Nov 16, 2022

It seems that recent Debian patches sysconfig too now https://salsa.debian.org/cpython-team/python3/-/blob/master/debian/patches/sysconfig-debian-schemes.diff I'll have a look at when this was introduced. If it is old enough (how old?) we can probably rely on it. Otherwise we will need to make the checks conditional. I'll see what can be done.

Edit: it looks like the sysconfig patching goes way back to Python 3.7 https://salsa.debian.org/cpython-team/python3/-/blob/python3.7/debian/patches/sysconfig-debian-schemes.diff I think we can probably safely rely on it. I'll prepare a PR and see what the CI tests think about it.

@dnicolodi
Copy link
Member

It would be great to have some input from the Debian Python maintainers on this.

@dnicolodi
Copy link
Member

Probably worth checking https://www.debian.org/doc/packaging-manuals/python-policy/

@dnicolodi
Copy link
Member

I've done some more archeology. The sysconfig patch is in the repository for the Debian's Python package since a long time, but it is actually installed only starting with Python 3.10, in Debian testing. The only thing that can be done is to check the Python version ad fall back to distutils for Python versions earlier than 3.10.

The other distutils is used for is this:

def links_against_libpython():
from distutils.core import Distribution, Extension
cmd = Distribution().get_command_obj('build_ext')
cmd.ensure_finalized()
return bool(cmd.get_libraries(Extension('dummy', [])))
for which there is no replacement AFAICT. @eli-schwartz Do you want me to open an issue with CPython for this?

@FFY00
Copy link
Member

FFY00 commented Nov 17, 2022

I've done some more archeology. The sysconfig patch is in the repository for the Debian's Python package since a long time, but it is actually installed only starting with Python 3.10, in Debian testing. The only thing that can be done is to check the Python version ad fall back to distutils for Python versions earlier than 3.10.

See https://ffy00.github.io/blog/02-python-debian-and-the-install-locations/ if you want some more archeology 😛

Do you want me to open an issue with CPython for this?

python/cpython#88611 is the proposed fix.

@dnicolodi
Copy link
Member

IIUC, the linked issue is about where to find the headers, not about whether to link or not with libpython. Aren't these separate issues?

@FFY00
Copy link
Member

FFY00 commented Nov 17, 2022

Yes, sorry, I misread it.

@FFY00
Copy link
Member

FFY00 commented Nov 17, 2022

The reason Debian patches Python in this way is python/cpython#65735. I am trying to understand if it is still relevant, or if we can just revert to looking at sysconfig.get_config_var('Py_ENABLE_SHARED').

@eli-schwartz
Copy link
Member

Well, yes.

For Linux, it depends on the python version, and on older versions of python, it also depends on whether there's a Debian patch.

There's other rules for other platforms.

@FFY00
Copy link
Member

FFY00 commented Nov 17, 2022

But older platforms will have distutils available to do the check, we need to figure out if this is still relevant on newer versions, and if so, figure out a way to support it without distutils.

@dnicolodi
Copy link
Member

@FFY00 In python/cpython#88611 the conclusion is that Python itself should not bother defining the include path. This means that whatever solution will be identified will be in one of the PyPA packages. Which makes it unsuitable for consumption by Meson because of the no-external-dependencies policy. What's the plan B?

@dnicolodi
Copy link
Member

@FFY00 I have the impression that your analysis in https://ffy00.github.io/blog/02-python-debian-and-the-install-locations/ is not complete for recent Python distributed by Debian. Debian patches Python 3.10 to also update the paths returned by sysconfig.

@eli-schwartz
Copy link
Member

I see, thanks. In that case, I'd suggest opening a CPython issue for the former as soon as possible (and the latter, if there's anything needed on the upstream end), to allow plenty of time before the beta freeze in less than 6 months for discussion, implementation, review and merging, and preferably allow you, distros and others to test with it.

I finally got around to this (plus a bit more research into all the moving parts): python/cpython#99942

And in #11133 I have a draft PR that fully removes distutils, but may need a CPython fix. It actually turns out that there's a sysconfig variable that almost gives us what we need for link_libpython.

Debian should simply work without fuss after a version gate, mid-3.10.x

@eli-schwartz
Copy link
Member

I finally got around to this (plus a bit more research into all the moving parts): python/cpython#99942

I have two PRs linked to that issue, and it would be great to have confirmation that I'm on the right track here (obviously I think I am). Also, I think that maybe to handle Android correctly, we need to drop the pkg-config detection method? 🤔 This isn't tested in CI, but Cygwin is. Cygwin works okay, because Cygwin patches it to be correct.

Assuming that CPython upstream agrees with me, I think we can handle this reasonably okay on our end.

@CAM-Gerlach
Copy link

I've pinged about it to the core dev team.

@danyeaw
Copy link

danyeaw commented Jul 9, 2023

I just tested doing a meson build with Python 3.12.0b3. python = python.find_installation('python3') fails because it doesn't detect this version of Python as a valid one without distutils being there.

@dnicolodi
Copy link
Member

@danyeaw, currently you need to install setuptools to make meson work with Python 3.12 or later: setuptools provides distutils.

@danyeaw
Copy link

danyeaw commented Jul 9, 2023

@dnicolodi Correct, but meson finds the system Python, not necessarily the activated virtualenv. This may require users to install setuptools system wide, which isn't great.

@danyeaw
Copy link

danyeaw commented Jul 9, 2023

How can I help, are we still waiting on CPython to do something?

@FFY00
Copy link
Member

FFY00 commented Jul 9, 2023

No changes from CPython's side are required to fix this, and nothing significant will happen there until 3.14 at least anyway.

dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 8, 2023
Disagreement between distutils and sysconfig have been resolved for
Python 3.12, see python/cpython#100356 and
python/cpython#100967

This is the other half of the fix for mesonbuild#7702.
dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 8, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702.
dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 8, 2023
Disagreement between distutils and sysconfig have been resolved for
Python 3.12, see python/cpython#100356 and
python/cpython#100967

This is the other half of the fix for mesonbuild#7702.
dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 8, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702.
dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 8, 2023
Disagreement between distutils and sysconfig have been resolved for
Python 3.12, see python/cpython#100356 and
python/cpython#100967

This is the other half of the fix for mesonbuild#7702.
dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 9, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702.
dnicolodi pushed a commit to dnicolodi/meson that referenced this issue Sep 9, 2023
Disagreement between distutils and sysconfig have been resolved for
Python 3.12, see python/cpython#100356 and
python/cpython#100967

This is the other half of the fix for mesonbuild#7702.
eli-schwartz added a commit to eli-schwartz/meson that referenced this issue Sep 22, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702
eli-schwartz added a commit to eli-schwartz/meson that referenced this issue Sep 22, 2023
…nt python

On python >=3.8, this information is expected to be encoded in the
sysconfig vars.

In distutils, it is always necessary to link to libpython on Windows;
for posix platforms, it depends on the value of LIBPYTHON (which is the
library to link to, possibly the empty string) as generated by
configure.ac and embedded into python.pc and python-config.sh, and then
coded a second time in the distutils python sources.

There are a couple of caveats which have ramifications for Cygwin and
Android:

- python.pc and python-config.sh disagree with distutils when python is
  not built shared. In that case, the former act the same as a shared
  build, while the latter *never* links to libpython

- python.pc disagrees with python-config.sh and distutils when python is
  built shared. The former never links to libpython, while the latter do

The disagreement is resolved in favor of distutils' behavior in all
cases, and python.pc is correct for our purposes on python 3.12; see:
python/cpython#100356
python/cpython#100967

Although it was not backported to older releases, Cygwin at least has
always patched in a fix for python.pc, which behavior is now declared
canonical. We can reliably assume it is always correct.

This is the other half of the fix for mesonbuild#7702
pkgw added a commit to regro-cf-autotick-bot/gobject-introspection-feedstock that referenced this issue Sep 24, 2023
This is the current recommendation in mesonbuild/meson#7702 to deal with
Python 3.12's removal of distutils.
pkgw added a commit to regro-cf-autotick-bot/pycairo-feedstock that referenced this issue Sep 24, 2023
This is the current recommendation in mesonbuild/meson#7702 to deal with
Python 3.12's removal of distutils.
pkgw added a commit to regro-cf-autotick-bot/pycairo-feedstock that referenced this issue Sep 28, 2023
This is the current recommendation in mesonbuild/meson#7702 to deal with
Python 3.12's removal of distutils.
eli-schwartz added a commit to eli-schwartz/meson that referenced this issue Oct 2, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702
eli-schwartz added a commit to eli-schwartz/meson that referenced this issue Oct 2, 2023
…nt python

On python >=3.8, this information is expected to be encoded in the
sysconfig vars.

In distutils, it is always necessary to link to libpython on Windows;
for posix platforms, it depends on the value of LIBPYTHON (which is the
library to link to, possibly the empty string) as generated by
configure.ac and embedded into python.pc and python-config.sh, and then
coded a second time in the distutils python sources.

There are a couple of caveats which have ramifications for Cygwin and
Android:

- python.pc and python-config.sh disagree with distutils when python is
  not built shared. In that case, the former act the same as a shared
  build, while the latter *never* links to libpython

- python.pc disagrees with python-config.sh and distutils when python is
  built shared. The former never links to libpython, while the latter do

The disagreement is resolved in favor of distutils' behavior in all
cases, and python.pc is correct for our purposes on python 3.12; see:
python/cpython#100356
python/cpython#100967

Although it was not backported to older releases, Cygwin at least has
always patched in a fix for python.pc, which behavior is now declared
canonical. We can reliably assume it is always correct.

This is the other half of the fix for mesonbuild#7702
eli-schwartz added a commit to eli-schwartz/meson that referenced this issue Oct 3, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702

(cherry picked from commit 40f897f)
eli-schwartz added a commit to eli-schwartz/meson that referenced this issue Oct 3, 2023
…nt python

On python >=3.8, this information is expected to be encoded in the
sysconfig vars.

In distutils, it is always necessary to link to libpython on Windows;
for posix platforms, it depends on the value of LIBPYTHON (which is the
library to link to, possibly the empty string) as generated by
configure.ac and embedded into python.pc and python-config.sh, and then
coded a second time in the distutils python sources.

There are a couple of caveats which have ramifications for Cygwin and
Android:

- python.pc and python-config.sh disagree with distutils when python is
  not built shared. In that case, the former act the same as a shared
  build, while the latter *never* links to libpython

- python.pc disagrees with python-config.sh and distutils when python is
  built shared. The former never links to libpython, while the latter do

The disagreement is resolved in favor of distutils' behavior in all
cases, and python.pc is correct for our purposes on python 3.12; see:
python/cpython#100356
python/cpython#100967

Although it was not backported to older releases, Cygwin at least has
always patched in a fix for python.pc, which behavior is now declared
canonical. We can reliably assume it is always correct.

This is the other half of the fix for mesonbuild#7702

(cherry picked from commit 2d6c109)
robtaylor pushed a commit to robtaylor/meson that referenced this issue Oct 14, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for mesonbuild#7702
robtaylor pushed a commit to robtaylor/meson that referenced this issue Oct 14, 2023
…nt python

On python >=3.8, this information is expected to be encoded in the
sysconfig vars.

In distutils, it is always necessary to link to libpython on Windows;
for posix platforms, it depends on the value of LIBPYTHON (which is the
library to link to, possibly the empty string) as generated by
configure.ac and embedded into python.pc and python-config.sh, and then
coded a second time in the distutils python sources.

There are a couple of caveats which have ramifications for Cygwin and
Android:

- python.pc and python-config.sh disagree with distutils when python is
  not built shared. In that case, the former act the same as a shared
  build, while the latter *never* links to libpython

- python.pc disagrees with python-config.sh and distutils when python is
  built shared. The former never links to libpython, while the latter do

The disagreement is resolved in favor of distutils' behavior in all
cases, and python.pc is correct for our purposes on python 3.12; see:
python/cpython#100356
python/cpython#100967

Although it was not backported to older releases, Cygwin at least has
always patched in a fix for python.pc, which behavior is now declared
canonical. We can reliably assume it is always correct.

This is the other half of the fix for mesonbuild#7702
nirbheek pushed a commit that referenced this issue Oct 17, 2023
Since 3.10.3, Debian finally started patching sysconfig with custom
paths, instead of just distutils. This means we can now go use that
instead. It reduces our reliance on the deprecated distutils module.

Partial fix for #7702
nirbheek pushed a commit that referenced this issue Oct 17, 2023
…nt python

On python >=3.8, this information is expected to be encoded in the
sysconfig vars.

In distutils, it is always necessary to link to libpython on Windows;
for posix platforms, it depends on the value of LIBPYTHON (which is the
library to link to, possibly the empty string) as generated by
configure.ac and embedded into python.pc and python-config.sh, and then
coded a second time in the distutils python sources.

There are a couple of caveats which have ramifications for Cygwin and
Android:

- python.pc and python-config.sh disagree with distutils when python is
  not built shared. In that case, the former act the same as a shared
  build, while the latter *never* links to libpython

- python.pc disagrees with python-config.sh and distutils when python is
  built shared. The former never links to libpython, while the latter do

The disagreement is resolved in favor of distutils' behavior in all
cases, and python.pc is correct for our purposes on python 3.12; see:
python/cpython#100356
python/cpython#100967

Although it was not backported to older releases, Cygwin at least has
always patched in a fix for python.pc, which behavior is now declared
canonical. We can reliably assume it is always correct.

This is the other half of the fix for #7702
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants