Repository: pypa/setuptools

Issue:
[BUG] AttributeError: module 'distutils.log' has no attribute 'warning'
### setuptools version

setuptools==65.6.2

### Python version

Python 3.8.15

### OS

macOS 12.5.1

### Additional environment information

_No response_

### Description

Installing a package `kappa=0.6.0` doesn't work. I think it could be the issue on setuptools's side.

### Expected behavior

Installing the package works.

### How to Reproduce

```console
$ python3.8 -m venv .venv
$ source .venv/bin/activate
$ pip install setuptools==65.6.2
$ pip install wheel
$ pip install kappa==0.6.0
```

### Output

```console
(.venv) dmytro@Dmytros-MacBook-Pro install_kappa % pip install kappa==0.6.0
Collecting kappa==0.6.0
  Using cached kappa-0.6.0.tar.gz (29 kB)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error

  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [20 lines of output]
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/private/var/folders/kv/zxwjm57d3jdgwyylrg2db6r80000gn/T/pip-install-xjv7l4bl/kappa_6f4dfc99aa59445e99fd8697c5e00cd7/setup.py", line 54, in <module>
          run_setup()
        File "/private/var/folders/kv/zxwjm57d3jdgwyylrg2db6r80000gn/T/pip-install-xjv7l4bl/kappa_6f4dfc99aa59445e99fd8697c5e00cd7/setup.py", line 18, in run_setup
          setup(
        File "/Users/dmytro/Tests/install_kappa/.venv/lib/python3.8/site-packages/setuptools/__init__.py", line 87, in setup
          return distutils.core.setup(**attrs)
        File "/Users/dmytro/Tests/install_kappa/.venv/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 147, in setup
          _setup_distribution = dist = klass(attrs)
        File "/Users/dmytro/Tests/install_kappa/.venv/lib/python3.8/site-packages/setuptools/dist.py", line 475, in __init__
          _Distribution.__init__(
        File "/Users/dmytro/Tests/install_kappa/.venv/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 258, in __init__
          getattr(self.metadata, "set_" + key)(val)
        File "/Users/dmytro/Tests/install_kappa/.venv/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 1242, in set_classifiers
          self.classifiers = _ensure_list(value, 'classifiers')
        File "/Users/dmytro/Tests/install_kappa/.venv/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 48, in _ensure_list
          log.warning(msg)
      AttributeError: module 'distutils.log' has no attribute 'warning'
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
```



Discussion:
I've been experiencing the same issue on python 3.7.9, I think I've narrowed it down to the patching happening in `setuptools.logging` where a root logger at `distutils.dist.log` which has that attributed is overwritten by a seemingly broken logger from `distutils.log` which does not have the warning attribute.

I might suggest a very naive potential solution for the maintainers of this repo is to simply reverse the patch so the functional logger from `distutuls.dist.log` is the one that is used everywhere rather than the broken logger from `distutils.log`


My pull request with the above change:
https://github.com/pypa/setuptools/pull/3708
We're also hitting this in our github actions (py3.8/3.9) and locally (py3.11).

reproducer: `pip install -U git+https://github.com/SatelliteQE/airgun.git@master#egg=airgun`

failing actions against python 3.8 and 3.9:
https://github.com/SatelliteQE/robottelo/actions/runs/3534164190/jobs/5930929334

@jaraco it looks like this was an unintended consequence of #3674 
I believe that the reason why the test suite did not catch this problem is because the conditions are somehow rare: the `setup.py` needs to use tuples for the classifiers or similar fields.

If the `setup.py` is using tuples, distutils will try to display a warning, which will cause the problem.

Regardless, I am working on a fix in #3709. 

Resolving patch:
diff --git a/setuptools/logging.py b/setuptools/logging.py
--- a/setuptools/logging.py
+++ b/setuptools/logging.py
@@ -1,4 +1,5 @@
 import sys
+import inspect
 import logging
 import distutils.log
 from . import monkey
@@ -22,7 +23,7 @@ def configure():
     handlers = err_handler, out_handler
     logging.basicConfig(
         format="{message}", style='{', handlers=handlers, level=logging.DEBUG)
-    if hasattr(distutils.log, 'Log'):
+    if inspect.ismodule(distutils.dist.log):
         monkey.patch_func(set_threshold, distutils.log, 'set_threshold')
         # For some reason `distutils.log` module is getting cached in `distutils.dist`
         # and then loaded again when patched,


Test patch:
diff --git a/setuptools/tests/test_logging.py b/setuptools/tests/test_logging.py
--- a/setuptools/tests/test_logging.py
+++ b/setuptools/tests/test_logging.py
@@ -1,4 +1,6 @@
+import inspect
 import logging
+import os
 
 import pytest
 
@@ -34,3 +36,18 @@ def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level):
     log_level = logger.getEffectiveLevel()
     log_level_name = logging.getLevelName(log_level)
     assert log_level_name == expected_level
+
+
+def test_patching_does_not_cause_problems():
+    # Ensure `dist.log` is only patched if necessary
+
+    import setuptools.logging
+    from distutils import dist
+
+    setuptools.logging.configure()
+
+    if os.getenv("SETUPTOOLS_USE_DISTUTILS", "local").lower() == "local":
+        # Modern logging infra, no problematic patching.
+        assert isinstance(dist.log, logging.Logger)
+    else:
+        assert inspect.ismodule(dist.log)