python-babel / babel

The official repository for Babel, the Python Internationalization Library
http://babel.pocoo.org/
BSD 3-Clause "New" or "Revised" License
1.29k stars 433 forks source link

distutils no longer part of Python 3.12 - error due to missing dependency #1031

Closed oprypin closed 8 months ago

oprypin commented 9 months ago

Overview Description

babel has some code that tries to use "setuptools" or fall back to "distutils". https://github.com/python-babel/babel/blob/76677eacd10cc35bea0a11ec1d2f0566cadd4066/babel/messages/frontend.py#L54

"distutils" used to be shipped with Python. Additionally, "setuptools" used to be ensured by virtualenvs. But both of these are gone with Python 3.12 so now babel ends up using a dependency that it never declared. https://github.com/python-babel/babel/blob/76677eacd10cc35bea0a11ec1d2f0566cadd4066/setup.py#L64

From my assessment, it seems it would be correct to add a dependency on setuptools directly. Either only for python_version>=3.12 or perhaps always add this dependency and drop the distutils fallback code.

Workaround: pip install setuptools

Steps to Reproduce

Install babel not in virtualenv and run it under Python 3.12

Actual Results

https://github.com/mkdocs/mkdocs/actions/runs/6382007433/job/17355070257

      Traceback (most recent call last):
        File "/tmp/pip-build-env-z7xd48v4/normal/lib/python3.12/site-packages/babel/messages/frontend.py", line 45, in <module>
          from setuptools import Command as _Command
      ModuleNotFoundError: No module named 'setuptools'

      During handling of the above exception, another exception occurred:

      Traceback (most recent call last):
        File "/home/runner/.local/share/hatch/env/virtual/mkdocs/FPjLbWME/test.py3.12-default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/home/runner/.local/share/hatch/env/virtual/mkdocs/FPjLbWME/test.py3.12-default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/runner/.local/share/hatch/env/virtual/mkdocs/FPjLbWME/test.py3.12-default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 176, in prepare_metadata_for_build_editable
          whl_basename = build_hook(metadata_directory, config_settings)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-build-env-z7xd48v4/overlay/lib/python3.12/site-packages/hatchling/build.py", line 78, in build_editable
          return os.path.basename(next(builder.build(wheel_directory, ['editable'])))
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-build-env-z7xd48v4/overlay/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 150, in build
          build_hook.initialize(version, build_data)
        File "/home/runner/work/mkdocs/mkdocs/hatch_build.py", line 8, in initialize
          from babel.messages.frontend import compile_catalog
        File "/tmp/pip-build-env-z7xd48v4/normal/lib/python3.12/site-packages/babel/messages/frontend.py", line 54, in <module>
          from distutils import log as distutils_log
      ModuleNotFoundError: No module named 'distutils'
      [end of output]

Expected Results

No error

Background

https://docs.python.org/3.12/whatsnew/3.12.html#distutils

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.

easy_install, pkg_resources, setuptools and distutils are no longer provided by default in environments created with venv or bootstrapped with ensurepip, since they are part of the setuptools package. For projects relying on these at runtime, the setuptools project should be declared as a dependency and installed separately (typically, using pip).

vstinner commented 9 months ago

I proposed a fix, someone can create a PR from this example:

https://github.com/python-babel/babel/issues/1005#issuecomment-1728105742

oprypin commented 9 months ago

Indeed I have created https://github.com/python-babel/babel/pull/1033

sigma67 commented 8 months ago

It's a bit rough that this forces setuptools on everyone that has babel in their dependency chain - is there a plan to remove it again eventually? Could this be made an optional feature?

akx commented 8 months ago

@sigma67 It wouldn't be impossible, but right now CLI use will require it (since it was, way back when, easier to wrap the setuptools-based commands in optparse magic than the other way around).

I wish I knew how many people actually depended on the setuptools command extensions.

oprypin commented 8 months ago

Let's discuss further at https://github.com/python-babel/babel/issues/1040

@sigma67 This issue is unrelated, it's not adding a new dependency. The setuptools dependency was always there, but before Python 3.12 it was built-in but now just need to declare it.

sigma67 commented 7 months ago

Thanks for addressing this so quickly despite initial concerns 💖