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: Remove the distutils package (Python 3.12) #92584

Open
vstinner opened this issue May 9, 2022 · 28 comments
Open

PEP 632: Remove the distutils package (Python 3.12) #92584

vstinner opened this issue May 9, 2022 · 28 comments
Labels
3.12 release-blocker type-bug An unexpected behavior, bug, or error

Comments

@vstinner
Copy link
Member

vstinner commented May 9, 2022

The distutils module was deprecated in Python 3.10 and is scheduled for removal in Python 3.12.

Right now, Python still uses distutils for different purpose:

  • Build C extensions which can not be built by Makefile yet. Python 3.11 can build way more C extensions with Makefile than Python 3.10.
  • peg_generator uses distutils to build C extensions.
  • test_cppext uses distutils to check that the Python C API can be used in C++.
  • Tools/c-analyzer/ uses distutils to get a C preprocessor.

Until Python can be built and used without distutils, I propose to first rename the distutils package to _distutils: rename th Lib/distutils/ directory to Lib/_distutils/.

Right now, test_venv fails without distutils, because pip fails on importing the distutils module in pip/_internal/locations/_distutils.py: https://github.com/pypa/pip/blob/cb24fb4052ca8ab8009866b0de61980c81a7e13c/src/pip/_internal/locations/_distutils.py#L9-L12

I created the PR #92585 which renames distutils to _distutils.

@vstinner vstinner added the type-bug An unexpected behavior, bug, or error label May 9, 2022
@vstinner vstinner changed the title Remove the distutils package to _distutils Rename the distutils package to _distutils May 9, 2022
@vstinner
Copy link
Member Author

vstinner commented May 9, 2022

Right now, test_venv fails without distutils, because pip fails on importing the distutils module in pip/_internal/locations/_distutils.py

I reported this issue to pip: pypa/pip#11103

@vstinner
Copy link
Member Author

vstinner commented May 9, 2022

The distutils package was deprecated by the issue #85454.

@vstinner vstinner changed the title Rename the distutils package to _distutils PEP 632: Rename the distutils package to _distutils May 10, 2022
@vstinner
Copy link
Member Author

PEP 632 "Deprecate distutils module": https://peps.python.org/pep-0632/

@FFY00
Copy link
Member

FFY00 commented May 10, 2022

That seems like a good plan. Thanks.

@jaraco
Copy link
Member

jaraco commented May 10, 2022

My fear with renaming it is that it lingers indefinitely, and diverging in subtle ways from pypa/distutils. Why not address the dependencies and fully remove the functionality?

Regardless, I agree renaming is preferable to not removing the module at all.

@vstinner
Copy link
Member Author

Why not address the dependencies and fully remove the functionality?

Someone has to modify Python to no longer depend on distutils. The issue description lists code using it. It doesn't seem trivial.

@FFY00
Copy link
Member

FFY00 commented May 10, 2022

Would it be reasonable to keep it around in the repo while we don't drop the dependency but not ship it as part of Python installations?

@vstinner
Copy link
Member Author

Would it be reasonable to keep it around in the repo while we don't drop the dependency but not ship it as part of Python installations?

With my PR, the Lib/_distutils/ directory is not installed by make install.

@jkloth
Copy link
Contributor

jkloth commented May 10, 2022

Do note that we have buildbots that run from an installed Python. The tests would need to also be modified to fail gracefully
(or skip) when _distutils is not available.

@vstinner
Copy link
Member Author

Do note that we have buildbots that run from an installed Python. The tests would need to also be modified to fail gracefully (or skip) when _distutils is not available.

I propose skipping tests relying on _distutils if _distutils is not available.

@vstinner
Copy link
Member Author

I wrote two PRs to avoid the deprecated distutils module in two tests:

vstinner added a commit that referenced this issue May 10, 2022
test_decimal now uses shutil.which() rather than deprecated
distutils.spawn.find_executable().
vstinner added a commit that referenced this issue May 12, 2022
Rewrite test_cppext to run in a virtual environment and to build the
C++ extension with setuptools rather than distutils.
@AbhigyanBose
Copy link
Contributor

AbhigyanBose commented May 15, 2022

Hi @vstinner

I think #92639 is causing a test failure, details here #92820

PS: Commented here as I thought those changes are related to this PEP.

@encukou
Copy link
Member

encukou commented Jun 23, 2022

Marking as 3.12.0a1 release blocker. We want to have public-facing distutils gone in the first alpha, to have as much time as possible to deal with the fallout.

@pablogsal pablogsal added the 3.12 label Jun 23, 2022
@vstinner vstinner changed the title PEP 632: Rename the distutils package to _distutils PEP 632: Rename the distutils package to _distutils (Python 3.12) Jul 7, 2022
@tiran
Copy link
Member

tiran commented Jul 7, 2022

Actually we can get rid of distutils entirely. I have a working PR that gets rid of our setup.py and builds all extension modules with configure and make.

@pradyunsg
Copy link
Member

For the curious, the PR that @tiran is refering to is #94474

tiran added a commit to tiran/cpython that referenced this issue Aug 5, 2022
`make test_cppmods` compiles C++ test extension modules.
@hroncok
Copy link
Contributor

hroncok commented Oct 25, 2022

Marking as 3.12.0a1 release blocker. We want to have public-facing distutils gone in the first alpha, to have as much time as possible to deal with the fallout.

It seems that 3.12.0a1 was released with distutils. Was that intentional? cc. @Yhg1s

@Yhg1s
Copy link
Member

Yhg1s commented Oct 25, 2022

I was going to ping the issue during the core dev sprint and then intentionally ignore it for the alpha 1 release (using it more as a practice run rather than trying to get everything right) -- but then I accidentally ignored it instead 😬. This should just get done for alpha 2.

@zooba zooba removed their assignment Oct 25, 2022
@zooba
Copy link
Member

zooba commented Oct 25, 2022

Not sure why this got put on me. If nobody else wants to do it, I can get to it eventually, but I definitely don't want to prevent anyone else from taking the honours.

@vstinner
Copy link
Member Author

vstinner commented Nov 3, 2022

Since May, the situation evolved:

  • Python setup.py has been removed: distutils is no longer needed to build Python
  • pip has been fixed: it now works if there is no distutils package
  • test_cppext now creates a virtual environment to build the C++ with setuptools
  • test_decimal now uses shutil.which(), rather than distutils.spawn.find_executable()

Thanks to that, I was able to create PR #99061. This PR removes the distutils package. It always skips test_check_c_globals and test_peg_generator since they use distutils. I prefer to remove distutils now, and fix these tests later, rather than missing the next Python 3.12 alpha release.

vstinner added a commit that referenced this issue Nov 3, 2022
The _bootsubprocess module was removed in gh-93939
by commit 81dca70.
vstinner added a commit that referenced this issue Nov 3, 2022
Remove the distutils package. It was deprecated in Python 3.10 by PEP
632 "Deprecate distutils module". For projects still using distutils
and cannot be updated to something else, the setuptools project can
be installed: it still provides distutils.

* Remove Lib/distutils/ directory
* Remove test_distutils
* Remove references to distutils
* Skip test_check_c_globals and test_peg_generator since they use
  distutils
@vstinner vstinner changed the title PEP 632: Rename the distutils package to _distutils (Python 3.12) PEP 632: Remove the distutils package (Python 3.12) Nov 3, 2022
@vstinner
Copy link
Member Author

Python 3.12 alpha 2 was released without distutils.

test_check_c_globals and test_peg_generator are currently skipped because of this removal. These tests should be rewritten without distutils.

sumslogs added a commit to sumslogs/ViennaRNA that referenced this issue Dec 12, 2022
distutils.sysconfig.get_config_var('SO') was deprecated in python 3.4, and is unset in python 3.11.0.
Causes PYTHON3_SO=None -> _RNA.so builds as "_RNANone" -> build failure:
```
ImportError: cannot import name '_RNA' from partially initialized module 'RNA'
```
See: python/cpython#60958, python/cpython#63754 and [deprecation notice here](https://github.com/python/cpython/blob/dd53b79de0ea98af6a11481217a961daef4e9774/Doc/whatsnew/3.4.rst#deprecations-in-the-python-api).

Further, module [distutils](https://docs.python.org/3/library/distutils.html) is deprecated, and has planned removal in 3.12.
Functions get_python_inc, get_python_lib are removed, see: python/cpython#92584.
sumslogs added a commit to sumslogs/ViennaRNA that referenced this issue Dec 12, 2022
distutils.sysconfig.get_config_var('SO') was deprecated in python 3.4, and is unset in python 3.11.0.

Causes PYTHON3_SO=None -> _RNA.so builds as "_RNANone" -> build failure:
```
ImportError: cannot import name '_RNA' from partially initialized module 'RNA'
```
See: python/cpython#60958, python/cpython#63754 and [deprecation notice here](https://github.com/python/cpython/blob/dd53b79de0ea98af6a11481217a961daef4e9774/Doc/whatsnew/3.4.rst#deprecations-in-the-python-api).

Also, module [distutils](https://docs.python.org/3/library/distutils.html) is deprecated and has planned removal in 3.12.
Functions get_python_inc, get_python_lib are removed, see: python/cpython#92584.
@vstinner
Copy link
Member Author

@ericsnowcurrently: FYI test_check_c_globals is simply skipped in the main branch, since the distutils package was removed. This test should be modified to use something else to build C code, like setuptools, or simply create a virtual environment to get the distutils packages from setuptools: trick used by test_cppext.

@pablogsal @lysnikolaou: test_peg_generator has the same issue, the whole test is also simply skipped in the main branch.

@vstinner
Copy link
Member Author

You may create new issues for these two currently skipped tests. As you want.

@pablogsal
Copy link
Member

pablogsal commented Dec 13, 2022

test_peg_generator has the same issue, the whole test is also simply skipped in the main branch.

What do you mean is skipped? I don't feel comfortable with just skipping this test without thinking how to fix it. I think this aspect should have taken into account when merging the original PR.

@vstinner I am sure you understand that is not good to just do something without thinking how to fix the problems you are creating and then throwing the issue to someone else.

@encukou
Copy link
Member

encukou commented Dec 14, 2022

To me it looks like peg_generator and check_c_globals are in the same situation as the rest of the ecosystem will be with 3.12: they broke and the maintainers need to fix them.

IMO, PEP 632 underestimated the amount of work needed, and failed to mention that no one was really interested in actually implementing it. (AFAIK we have an implicit assumption that a PEP author will manage the work if the PEP is accepted, we might want to add that to the PEP process docs.)

Thanks for picking up the slack at the last moment, Victor.

@pablogsal
Copy link
Member

To me it looks like peg_generator and check_c_globals are in the same situation as the rest of the ecosystem will be with 3.12: they broke and the maintainers need to fix them.

IMO, PEP 632 underestimated the amount of work needed, and failed to mention that no one was really interested in actually implementing it. (AFAIK we have an implicit assumption that a PEP author will manage the work if the PEP is accepted, we might want to add that to the PEP process docs.)

Thanks for picking up the slack at the last moment, Victor.

I was under the impression that the plan was to have distutils outside the standard library but available until we figure out what to do with the tests that depend on it. The PEP suggests this as well:

The final dependency on distutils is CPython itself, which uses it to build native extension modules in the standard library (except on Windows). Because this is a CPython build-time dependency, it is possible to continue to use distutils for this specific case without it being part of the standard library.

Using alternatives within the test suite of CPython differs from using alternatives outside because installing packages like pip and setuptools is not that straightforward.

If this was the plan all along and I was under the wrong impression I apologize for the confusion but I still think having tests deactivated in main is just dangerous and we should have though about this first.

@merwok
Copy link
Member

merwok commented Dec 14, 2022

Reverting the removal would be some churn, but there are other options:

  • should be quick to make the testsuite install setuptools, import distutils from setuptools and adjust code if needed
  • a bit longer to replace the distutils code in tests with setuptools code, but hopefully not too hard (Extension class should have the same interface, various compiler functions should exist too even if renamed, etc)

@ericsnowcurrently
Copy link
Member

FWIW, test_check_c_globals basically covers Tools/c-analyzer/check-c-globals.py. We shouldn't be losing any coverage of CPython with that test disabled. Plus, there are a few things that need to be fixed with that test that I'd been putting off. It having been disabled is an extra motivator. 😄

That said, I agree it is surprising that we merged something requiring any tests to be disabled and then fixed after the fact by someone other than the author of that PR. At the very least there should have been some discussion beforehand with the maintainers of the to-be-disabled tests and a clear agreement on how to proceed, all before the PR was merged. While what happened with distutils may seem relatively benign and innocuous, it's a risky precedent to set.

@zooba
Copy link
Member

zooba commented Jan 9, 2023

AFAIK we have an implicit assumption that a PEP author will manage the work if the PEP is accepted, we might want to add that to the PEP process docs.

There was an explicit agreement that the author of this PEP (me) was just putting it in writing and wasn't obligated to do all the work. But feel free to make that an explicit requirement - it just means that I won't volunteer for PEPs that we all want but nobody is willing to do (and will simply withdraw from maintaining the module that we all want to remove) ;)

But yes, I agree that breaking/disabling the tests is not right. Moving distutils into Tools and pointing the tests at it there would have been fine - they'd have eventually broken with bitrot rather than immediately, but that was happening anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 release-blocker type-bug An unexpected behavior, bug, or error
Projects
Status: No status
Development

No branches or pull requests