diff --git a/skbuild/command/build_py.py b/skbuild/command/build_py.py index b87820eb6..e04231674 100644 --- a/skbuild/command/build_py.py +++ b/skbuild/command/build_py.py @@ -3,13 +3,11 @@ import os -from distutils import log as distutils_log - from setuptools.command.build_py import build_py as _build_py from . import set_build_base_mixin from ..constants import CMAKE_INSTALL_DIR -from ..utils import distribution_hide_listing, new_style +from ..utils import distribution_hide_listing, new_style, distutils_log class build_py(set_build_base_mixin, new_style(_build_py)): diff --git a/skbuild/command/clean.py b/skbuild/command/clean.py index 36c49ce86..fe494af2d 100644 --- a/skbuild/command/clean.py +++ b/skbuild/command/clean.py @@ -7,15 +7,13 @@ except ImportError: from distutils.command.clean import clean as _clean -from distutils import log - from shutil import rmtree from . import set_build_base_mixin from ..constants import (CMAKE_BUILD_DIR, CMAKE_INSTALL_DIR, SKBUILD_DIR) -from ..utils import new_style +from ..utils import new_style, distutils_log class clean(set_build_base_mixin, new_style(_clean)): @@ -28,6 +26,6 @@ def run(self): CMAKE_BUILD_DIR(), SKBUILD_DIR()): if os.path.exists(dir_): - log.info("removing '%s'", dir_) + distutils_log.info("removing '%s'", dir_) if not self.dry_run and os.path.exists(dir_): rmtree(dir_) diff --git a/skbuild/command/install_lib.py b/skbuild/command/install_lib.py index fea39ffb7..d856592f7 100644 --- a/skbuild/command/install_lib.py +++ b/skbuild/command/install_lib.py @@ -1,12 +1,10 @@ """This module defines custom implementation of ``install_lib`` setuptools command.""" -from distutils import log as distutils_log - from setuptools.command.install_lib import install_lib as _install_lib from . import set_build_base_mixin -from ..utils import distribution_hide_listing, new_style +from ..utils import distribution_hide_listing, new_style, distutils_log class install_lib(set_build_base_mixin, new_style(_install_lib)): diff --git a/skbuild/command/install_scripts.py b/skbuild/command/install_scripts.py index 7a131e404..6c37033f9 100644 --- a/skbuild/command/install_scripts.py +++ b/skbuild/command/install_scripts.py @@ -1,13 +1,11 @@ """This module defines custom implementation of ``install_scripts`` setuptools command.""" -from distutils import log as distutils_log - from setuptools.command.install_scripts import ( install_scripts as _install_scripts) from . import set_build_base_mixin -from ..utils import distribution_hide_listing, new_style +from ..utils import distribution_hide_listing, new_style, distutils_log class install_scripts(set_build_base_mixin, new_style(_install_scripts)): diff --git a/skbuild/command/sdist.py b/skbuild/command/sdist.py index d18e5bd17..2a8b4631e 100644 --- a/skbuild/command/sdist.py +++ b/skbuild/command/sdist.py @@ -3,11 +3,10 @@ import contextlib import os -from distutils import log as distutils_log from distutils.command.sdist import sdist as _sdist from . import set_build_base_mixin -from ..utils import distribution_hide_listing, new_style +from ..utils import distribution_hide_listing, new_style, distutils_log class sdist(set_build_base_mixin, new_style(_sdist)): diff --git a/skbuild/utils/__init__.py b/skbuild/utils/__init__.py index 77fa4d9e4..b876d9326 100644 --- a/skbuild/utils/__init__.py +++ b/skbuild/utils/__init__.py @@ -4,14 +4,27 @@ import os from collections import namedtuple +import contextlib from contextlib import contextmanager -from distutils import log as distutils_log from distutils.command.build_py import build_py as distutils_build_py from distutils.errors import DistutilsTemplateError from distutils.filelist import FileList from distutils.text_file import TextFile from functools import wraps +try: + import setuptools.logging # noqa: F401 + import logging + + distutils_log = logging.getLogger("skbuild") + distutils_log.setLevel(logging.INFO) + logging_module = True + +except ImportError: + from distutils import log as distutils_log + + logging_module = False + class ContextDecorator(object): """A base class or mixin that enables context managers to work as @@ -161,8 +174,12 @@ def check_module(self, module, module_file): if os.path.exists(updated_module_file): module_file = updated_module_file if not os.path.isfile(module_file): - distutils_log.warn( - "file %s (for module %s) not found", module_file, module) + if logging_module: + distutils_log.warning( + "file %s (for module %s) not found", module_file, module) + else: + distutils_log.warn( + "file %s (for module %s) not found", module_file, module) return False return True @@ -186,15 +203,34 @@ def distribution_hide_listing(distribution): It yields True if ``--hide-listing`` argument was provided. """ + + hide_listing = hasattr(distribution, "hide_listing") and distribution.hide_listing + # pylint:disable=protected-access - old_threshold = distutils_log._global_log.threshold - hide_listing = False - if (hasattr(distribution, "hide_listing") - and distribution.hide_listing): - hide_listing = True - distutils_log.set_threshold(distutils_log.WARN) - yield hide_listing - distutils_log.set_threshold(old_threshold) + if logging_module: + # Setuptools 60.2+, will always be on Python 3.6+ + old_level = distutils_log.getEffectiveLevel() + if hide_listing: + distutils_log.setLevel(logging.WARNING) + try: + if hide_listing: + # The classic logger doesn't respond to set_threshold anymore, + # but it does log info and above to stdout, so let's hide that + with open(os.devnull, 'w') as f, contextlib.redirect_stdout(f): + yield hide_listing + else: + yield hide_listing + finally: + distutils_log.setLevel(old_level) + + else: + old_threshold = distutils_log._global_log.threshold + if hide_listing: + distutils_log.set_threshold(distutils_log.WARN) + try: + yield hide_listing + finally: + distutils_log.set_threshold(old_threshold) def parse_manifestin(template): diff --git a/tests/test_command_line.py b/tests/test_command_line.py index 0572d697d..1d91edaa4 100644 --- a/tests/test_command_line.py +++ b/tests/test_command_line.py @@ -159,7 +159,7 @@ def should_fail(): @pytest.mark.parametrize("action", ['sdist', 'bdist_wheel']) @pytest.mark.parametrize("hide_listing", [True, False]) -def test_hide_listing(action, hide_listing, capfd): +def test_hide_listing(action, hide_listing, capfd, caplog): cmd = [action] if hide_listing: @@ -171,7 +171,9 @@ def run(): run() - out, _ = capfd.readouterr() + out, err = capfd.readouterr() + out += err + caplog.text + if hide_listing: assert to_platform_path("bonjour/__init__.py") not in out else: diff --git a/tests/test_logging.py b/tests/test_logging.py new file mode 100644 index 000000000..637824b62 --- /dev/null +++ b/tests/test_logging.py @@ -0,0 +1,32 @@ +from skbuild.utils import distutils_log, distribution_hide_listing +import pytest + +setuptools_logging = pytest.importorskip("setuptools.logging") + + +class SimpleNamespace(object): + pass + + +def test_hide_listing(caplog): + setuptools_logging.configure() + + distribution = SimpleNamespace() + distribution.hide_listing = True + + with distribution_hide_listing(distribution): + distutils_log.info("This is hidden") + + assert "This is hidden" not in caplog.text + + +def test_no_hide_listing(caplog): + setuptools_logging.configure() + + distribution = SimpleNamespace() + distribution.hide_listing = False + + with distribution_hide_listing(distribution): + distutils_log.info("This is not hidden") + + assert "This is not hidden" in caplog.text