Repository: pypa/setuptools

Issue:
[BUG] ImportError when using `importlib` with setuptools 60.9.0+
### setuptools version

`setuptools==62.1.0`

(The repro below uses the latest setuptools version, however, the first affected version was `setuptools==60.9.0`)

### Python version

Python 3.7

### OS

Docker image `python:3.7.13` which is Debian 11 (it also occurs on Ubuntu on Heroku)

### Additional environment information

Reduced `requirements.txt`:

```
celery==5.2.2
Django==3.2.8
importlib-metadata==0.20
```

### Description

Between setuptools 60.8.2 and 60.9.0, a previously working Django project now fails when using `importlib.import_module()`:

```
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/testcase.py", line 2, in <module>
    from celery import Celery
ImportError: cannot import name 'Celery' from 'celery' (/usr/local/lib/python3.7/site-packages/celery/__init__.py)
```

In the original project (which was from a customer), the `importlib.import_module()` usage was inside gunicorn, when it loads the provided WSGI application file. However, I've removed gunicorn (and much of the rest of the project) as part of creating a reduced testcase.

The changes between those two setuptools versions are:
https://github.com/pypa/setuptools/compare/v60.8.2...v60.9.0

In addition to the workaround of downgrading setuptools to `60.8.2`, I also found that making any of the following changes (each in isolation) prevents the error from occurring:
- Upgrading Python to 3.8+
- Upgrading importlib-metadata from 0.20 to 0.21+ ([changelog](https://github.com/python/importlib_metadata/compare/0.20...0.21))
- Upgrading Django from 3.2.8 to 3.2.9+ ([changelog](https://github.com/django/django/compare/3.2.8...3.2.9), of which [this](https://github.com/django/django/commit/8bebb1c04a40a8bb45368415cd01ccbf32fd3236) seems relevant)
- Upgrading Celery from 5.2.2 to 5.2.5 ([changelog](https://github.com/celery/celery/compare/v5.2.2...v5.2.5), of which [this](https://github.com/celery/celery/pull/7218) seems relevant) (skipped 5.2.3 and 5.2.4 since they pin setuptools to an earlier version that isn't affected by this)

### Expected behavior

Either:
1. The import succeed with newer versions of setuptools, as it did before.
2. Or, setuptools outputs a warning/error to make debugging this easier, or otherwise blocks usage with incompatible `importlib-metadata` versions.

### How to Reproduce

1. `docker run --rm -it python:3.7.13 bash`
2. `echo -e "from django.core.wsgi import get_wsgi_application\nfrom celery import Celery" > testcase.py`
3. `pip install setuptools==62.1.0`
4. `pip install celery==5.2.2 Django==3.2.8 importlib-metadata==0.20`
5. `python -c 'import importlib; importlib.import_module("testcase")'`

### Output

```console
$ docker run --rm -it python:3.7.13 bash
...
root@030ec79ad5e2:/# echo -e "from django.core.wsgi import get_wsgi_application\nfrom celery import Celery" > testcase.py
root@030ec79ad5e2:/# pip install setuptools==62.1.0
...
root@030ec79ad5e2:/# pip install celery==5.2.2 Django==3.2.8 importlib-metadata==0.20
...
Installing collected packages: wcwidth, pytz, cached-property, billiard, zipp, vine, typing-extensions, sqlparse, six, prompt-toolkit, importlib-metadata, asgiref, amqp, kombu, Django, click, click-repl, click-plugins, click-didyoumean, celery
Successfully installed Django-3.2.8 amqp-5.1.1 asgiref-3.5.0 billiard-3.6.4.0 cached-property-1.5.2 celery-5.2.2 click-8.1.2 click-didyoumean-0.3.0 click-plugins-1.1.1 click-repl-0.2.0 importlib-metadata-0.20 kombu-5.2.4 prompt-toolkit-3.0.29 pytz-2022.1 six-1.16.0 sqlparse-0.4.2 typing-extensions-4.2.0 vine-5.0.0 wcwidth-0.2.5 zipp-3.8.0

root@030ec79ad5e2:/# python -c 'import importlib; importlib.import_module("testcase")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/testcase.py", line 2, in <module>
    from celery import Celery
ImportError: cannot import name 'Celery' from 'celery' (/usr/local/lib/python3.7/site-packages/celery/__init__.py)
```


Discussion:

Resolving patch:
diff --git a/setuptools/_importlib.py b/setuptools/_importlib.py
--- a/setuptools/_importlib.py
+++ b/setuptools/_importlib.py
@@ -12,6 +12,17 @@ def disable_importlib_metadata_finder(metadata):
         import importlib_metadata
     except ImportError:
         return
+    except AttributeError:
+        import warnings
+
+        msg = (
+            "`importlib-metadata` version is incompatible with `setuptools`.\n"
+            "This problem is likely to be solved by installing an updated version of "
+            "`importlib-metadata`."
+        )
+        warnings.warn(msg)  # Ensure a descriptive message is shown.
+        raise  # This exception can be suppressed by _distutils_hack
+
     if importlib_metadata is metadata:
         return
     to_remove = [


Test patch: