https://github.com/python/cpython/commit/bd3baa8b1a7755f17b2fc98c7fb7b872fec43af3
commit: bd3baa8b1a7755f17b2fc98c7fb7b872fec43af3
branch: main
author: Tomas R. <[email protected]>
committer: brettcannon <[email protected]>
date: 2025-01-14T16:48:46-08:00
summary:

gh-121604: Make sure all deprecated items in importlib raise DeprecationWarning 
(#128007)

Co-authored-by: rashansmith <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>
Co-authored-by: Brett Cannon <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-12-16-22-20-38.gh-issue-121604.m3Xn4G.rst
M Lib/importlib/_bootstrap_external.py
M Lib/importlib/abc.py
M Lib/importlib/machinery.py
M Lib/inspect.py
M Lib/test/test_importlib/test_abc.py
M Lib/test/test_importlib/test_api.py
M Lib/test/test_importlib/test_windows.py

diff --git a/Lib/importlib/_bootstrap_external.py 
b/Lib/importlib/_bootstrap_external.py
index fa36159711846f..697f7c55218a8f 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -716,6 +716,12 @@ def _search_registry(cls, fullname):
 
     @classmethod
     def find_spec(cls, fullname, path=None, target=None):
+        _warnings.warn('importlib.machinery.WindowsRegistryFinder is '
+                       'deprecated; use site configuration instead. '
+                       'Future versions of Python may not enable this '
+                       'finder by default.',
+                       DeprecationWarning, stacklevel=2)
+
         filepath = cls._search_registry(fullname)
         if filepath is None:
             return None
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index eea6b38af6fa13..bb2837d38d83f1 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -70,6 +70,15 @@ class ResourceLoader(Loader):
 
     """
 
+    def __init__(self):
+        import warnings
+        warnings.warn('importlib.abc.ResourceLoader is deprecated in '
+                      'favour of supporting resource loading through '
+                      'importlib.resources.abc.ResourceReader.',
+                      DeprecationWarning, stacklevel=2)
+        super().__init__()
+
+
     @abc.abstractmethod
     def get_data(self, path):
         """Abstract method which when implemented should return the bytes for
@@ -199,6 +208,10 @@ class SourceLoader(_bootstrap_external.SourceLoader, 
ResourceLoader, ExecutionLo
 
     def path_mtime(self, path):
         """Return the (int) modification time for the path (str)."""
+        import warnings
+        warnings.warn('SourceLoader.path_mtime is deprecated in favour of '
+                      'SourceLoader.path_stats().',
+                      DeprecationWarning, stacklevel=2)
         if self.path_stats.__func__ is SourceLoader.path_stats:
             raise OSError
         return int(self.path_stats(path)['mtime'])
diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py
index 6e294d59bfdcb9..63d726445c3d96 100644
--- a/Lib/importlib/machinery.py
+++ b/Lib/importlib/machinery.py
@@ -3,9 +3,11 @@
 from ._bootstrap import ModuleSpec
 from ._bootstrap import BuiltinImporter
 from ._bootstrap import FrozenImporter
-from ._bootstrap_external import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES,
-                     OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES,
-                     EXTENSION_SUFFIXES)
+from ._bootstrap_external import (
+    SOURCE_SUFFIXES, BYTECODE_SUFFIXES, EXTENSION_SUFFIXES,
+    DEBUG_BYTECODE_SUFFIXES as _DEBUG_BYTECODE_SUFFIXES,
+    OPTIMIZED_BYTECODE_SUFFIXES as _OPTIMIZED_BYTECODE_SUFFIXES
+)
 from ._bootstrap_external import WindowsRegistryFinder
 from ._bootstrap_external import PathFinder
 from ._bootstrap_external import FileFinder
@@ -27,3 +29,22 @@ def all_suffixes():
            'NamespaceLoader', 'OPTIMIZED_BYTECODE_SUFFIXES', 'PathFinder',
            'SOURCE_SUFFIXES', 'SourceFileLoader', 'SourcelessFileLoader',
            'WindowsRegistryFinder', 'all_suffixes']
+
+
+def __getattr__(name):
+    import warnings
+
+    if name == 'DEBUG_BYTECODE_SUFFIXES':
+        warnings.warn('importlib.machinery.DEBUG_BYTECODE_SUFFIXES is '
+                      'deprecated; use importlib.machinery.BYTECODE_SUFFIXES '
+                      'instead.',
+                      DeprecationWarning, stacklevel=2)
+        return _DEBUG_BYTECODE_SUFFIXES
+    elif name == 'OPTIMIZED_BYTECODE_SUFFIXES':
+        warnings.warn('importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES is '
+                      'deprecated; use importlib.machinery.BYTECODE_SUFFIXES '
+                      'instead.',
+                      DeprecationWarning, stacklevel=2)
+        return _OPTIMIZED_BYTECODE_SUFFIXES
+
+    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 5b7c4df8927c87..facad478103668 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -858,8 +858,7 @@ def getsourcefile(object):
     Return None if no way can be identified to get the source.
     """
     filename = getfile(object)
-    all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
-    all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
+    all_bytecode_suffixes = importlib.machinery.BYTECODE_SUFFIXES[:]
     if any(filename.endswith(s) for s in all_bytecode_suffixes):
         filename = (os.path.splitext(filename)[0] +
                     importlib.machinery.SOURCE_SUFFIXES[0])
diff --git a/Lib/test/test_importlib/test_abc.py 
b/Lib/test/test_importlib/test_abc.py
index 603125f6d926f6..00af2dd712425a 100644
--- a/Lib/test/test_importlib/test_abc.py
+++ b/Lib/test/test_importlib/test_abc.py
@@ -913,5 +913,37 @@ def test_universal_newlines(self):
                          SourceOnlyLoaderMock=SPLIT_SOL)
 
 
+class SourceLoaderDeprecationWarningsTests(unittest.TestCase):
+    """Tests SourceLoader deprecation warnings."""
+
+    def test_deprecated_path_mtime(self):
+        from importlib.abc import SourceLoader
+        class DummySourceLoader(SourceLoader):
+            def get_data(self, path):
+                return b''
+
+            def get_filename(self, fullname):
+                return 'foo.py'
+
+            def path_stats(self, path):
+                return {'mtime': 1}
+
+        loader = DummySourceLoader()
+        with self.assertWarns(DeprecationWarning):
+            loader.path_mtime('foo.py')
+
+
+class ResourceLoaderDeprecationWarningsTests(unittest.TestCase):
+    """Tests ResourceLoader deprecation warnings."""
+
+    def test_deprecated_resource_loader(self):
+        from importlib.abc import ResourceLoader
+        class DummyLoader(ResourceLoader):
+            def get_data(self, path):
+                return b''
+
+        with self.assertWarns(DeprecationWarning):
+            DummyLoader()
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_importlib/test_api.py 
b/Lib/test/test_importlib/test_api.py
index 51ea5270b1a928..6035b2ca72efb9 100644
--- a/Lib/test/test_importlib/test_api.py
+++ b/Lib/test/test_importlib/test_api.py
@@ -492,5 +492,18 @@ def test_util(self):
         support.check__all__(self, util['Source'], extra=extra)
 
 
+class TestDeprecations(unittest.TestCase):
+    def test_machinery_deprecated_attributes(self):
+        from importlib import machinery
+        attributes = (
+            'DEBUG_BYTECODE_SUFFIXES',
+            'OPTIMIZED_BYTECODE_SUFFIXES',
+        )
+        for attr in attributes:
+            with self.subTest(attr=attr):
+                with self.assertWarns(DeprecationWarning):
+                    getattr(machinery, attr)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_importlib/test_windows.py 
b/Lib/test/test_importlib/test_windows.py
index 8a9a8fffcd10d4..f32680bdbeb9e3 100644
--- a/Lib/test/test_importlib/test_windows.py
+++ b/Lib/test/test_importlib/test_windows.py
@@ -104,6 +104,12 @@ def test_module_not_found(self):
             spec = 
self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
             self.assertIsNone(spec)
 
+    def test_raises_deprecation_warning(self):
+        # WindowsRegistryFinder is not meant to be instantiated, so the
+        # deprecation warning is raised in the 'find_spec' method instead.
+        with self.assertWarns(DeprecationWarning):
+            self.machinery.WindowsRegistryFinder.find_spec('spam')
+
 (Frozen_WindowsRegistryFinderTests,
  Source_WindowsRegistryFinderTests
  ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery)
diff --git 
a/Misc/NEWS.d/next/Library/2024-12-16-22-20-38.gh-issue-121604.m3Xn4G.rst 
b/Misc/NEWS.d/next/Library/2024-12-16-22-20-38.gh-issue-121604.m3Xn4G.rst
new file mode 100644
index 00000000000000..9a6fce8647cc6b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-16-22-20-38.gh-issue-121604.m3Xn4G.rst
@@ -0,0 +1 @@
+Add missing Deprecation warnings for 
:attr:`importlib.machinery.DEBUG_BYTECODE_SUFFIXES`, 
:attr:`importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES`, 
:class:`importlib.machinery.WindowsRegistryFinder`, 
:class:`importlib.abc.ResourceLoader`, 
:meth:`importlib.abc.SourceLoader.path_mtime`.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to