Repository: pypa/setuptools

Issue:
[BUG] INFO log level is no longer default for some commands
### setuptools version

60.0.0 and newer

### Python version

Python 3.8

### OS

OpenSUSE Tumbleweed

### Additional environment information

_No response_

### Description

When running certain commands setuptools seems to log at a `WARN` level and not `INFO` level which was the previous default. This appears to have changed with the switch from `stdlib` to `local` distutils vendoring in 60.0.0. 59.8.0 continues to log at an `INFO` level as expected. The latest 60.5.4 release continues to log at a WARN level by default. Commands like `sdist` appear to log at an `INFO` level though making me suspect that this is limited to distutils commands and not those that setuptools has overridden.

The example I've used below is `build_scripts` because it is relatively simple but it seems to affect others as well. Calling this out as recent changing to setuptools logging seem to indicate a desire to maintain backward compat with distutils for now and that seems to have broken though I don't understand how/why. Also, pointing this out in case it points to bigger issues in the local vendoring of distutils.

### Expected behavior

I expect setuptools to continue logging at INFO level by default.

### How to Reproduce

1. Create setup.py with scripts entry.
2. Install setuptools 59.8.0
3. Run `setup.py build_scripts --dry-run`
4. Install setuptools 60.0.0
5. Run `setup.py build_scripts --dry-run`
6. Note that there is no log.info() message indicating a mode change would occur.

Note that setting -v on the commands does not change the output. Additionally setting SETUPTOOLS_USE_DISTUTILS=stdlib corrects this on newer setuptools indicating the local vendoring is likely to blame.

### Output

```console
$ .tox/py38/bin/pip install -U setuptools==59.8.0
Collecting setuptools==59.8.0
  Using cached setuptools-59.8.0-py3-none-any.whl (952 kB)
Installing collected packages: setuptools
  Attempting uninstall: setuptools
    Found existing installation: setuptools 60.0.0
    Uninstalling setuptools-60.0.0:
      Successfully uninstalled setuptools-60.0.0
Successfully installed setuptools-59.8.0
$ .tox/py38/bin/python3 setup.py build_scripts --dry-run
running build_scripts
creating build/scripts-3.8
warning: build_scripts: foo/bar.py is an empty file (skipping)

changing mode of build/scripts-3.8/bar.py
$ .tox/py38/bin/pip install -U setuptools==60.0.0
Collecting setuptools==60.0.0
  Using cached setuptools-60.0.0-py3-none-any.whl (952 kB)
Installing collected packages: setuptools
  Attempting uninstall: setuptools
    Found existing installation: setuptools 59.8.0
    Uninstalling setuptools-59.8.0:
      Successfully uninstalled setuptools-59.8.0
Successfully installed setuptools-60.0.0
$ .tox/py38/bin/python3 setup.py build_scripts --dry-run
running build_scripts
creating build/scripts-3.8
warning: build_scripts: foo/bar.py is an empty file (skipping)

```


### Code of Conduct

- [X] I agree to follow the PSF Code of Conduct


Discussion:
@cboylan I believe this is a duplicate of #3035
> @cboylan I believe this is a duplicate of #3035

I agree this seems to be the case. I'll leave this open as it has a bit of additional info, but won't be bothered if someone closes it. Or feel free to tell me I should close it and I'll do that.

Resolving patch:
diff --git a/setuptools/logging.py b/setuptools/logging.py
--- a/setuptools/logging.py
+++ b/setuptools/logging.py
@@ -24,6 +24,12 @@ def configure():
         format="{message}", style='{', handlers=handlers, level=logging.DEBUG)
     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,
+    # implying: id(distutils.log) != id(distutils.dist.log).
+    # Make sure the same module object is used everywhere:
+    distutils.dist.log = distutils.log
+
 
 def set_threshold(level):
     logging.root.setLevel(level*10)


Test patch:
diff --git a/setuptools/tests/test_logging.py b/setuptools/tests/test_logging.py
new file mode 100644
--- /dev/null
+++ b/setuptools/tests/test_logging.py
@@ -0,0 +1,36 @@
+import logging
+
+import pytest
+
+
+setup_py = """\
+from setuptools import setup
+
+setup(
+    name="test_logging",
+    version="0.0"
+)
+"""
+
+
+@pytest.mark.parametrize(
+    "flag, expected_level", [("--dry-run", "INFO"), ("--verbose", "DEBUG")]
+)
+def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level):
+    """Make sure the correct verbosity level is set (issue #3038)"""
+    import setuptools  # noqa: Import setuptools to monkeypatch distutils
+    import distutils  # <- load distutils after all the patches take place
+
+    logger = logging.Logger(__name__)
+    monkeypatch.setattr(logging, "root", logger)
+    unset_log_level = logger.getEffectiveLevel()
+    assert logging.getLevelName(unset_log_level) == "NOTSET"
+
+    setup_script = tmp_path / "setup.py"
+    setup_script.write_text(setup_py)
+    dist = distutils.core.run_setup(setup_script, stop_after="init")
+    dist.script_args = [flag, "sdist"]
+    dist.parse_command_line()  # <- where the log level is set
+    log_level = logger.getEffectiveLevel()
+    log_level_name = logging.getLevelName(log_level)
+    assert log_level_name == expected_level