]> granicus.if.org Git - python/commitdiff
Issue #13959: Deprecate imp.get_suffixes() for new attributes on
authorBrett Cannon <brett@python.org>
Fri, 11 May 2012 16:58:42 +0000 (12:58 -0400)
committerBrett Cannon <brett@python.org>
Fri, 11 May 2012 16:58:42 +0000 (12:58 -0400)
importlib.machinery that provide the suffix details for import.
The attributes were not put on imp so as to compartmentalize
everything importlib needs for setting up imports in
importlib.machinery.

This also led to an indirect deprecation of inspect.getmoduleinfo() as
it directly returned imp.get_suffix's returned tuple which no longer
makes sense.

17 files changed:
Doc/library/imp.rst
Doc/library/importlib.rst
Doc/library/inspect.rst
Lib/ctypes/util.py
Lib/idlelib/PathBrowser.py
Lib/imp.py
Lib/importlib/_bootstrap.py
Lib/importlib/machinery.py
Lib/importlib/test/benchmark.py
Lib/importlib/test/extension/util.py
Lib/importlib/test/source/test_case_sensitivity.py
Lib/importlib/test/source/test_finder.py
Lib/importlib/test/source/test_path_hook.py
Lib/inspect.py
Lib/modulefinder.py
Lib/pydoc.py
Misc/NEWS

index 1345b254d62f1d79dfd44e81e1d119d51eacc170..7270e3c690657eb94f37e0e4f9f312006a442cdb 100644 (file)
@@ -30,6 +30,9 @@ This module provides an interface to the mechanisms used to implement the
    :const:`PY_SOURCE`, :const:`PY_COMPILED`, or :const:`C_EXTENSION`, described
    below.
 
+   .. deprecated:: 3.3
+      Use the constants defined on :mod:`importlib.machinery` instead.
+
 
 .. function:: find_module(name[, path])
 
index 6855a7918aa065260a90d3353ff328158b14b10d..ddfaa211e7105ffef02ed47468dae5b582e7ed48 100644 (file)
@@ -477,6 +477,43 @@ are also provided to help in implementing the core ABCs.
 This module contains the various objects that help :keyword:`import`
 find and load modules.
 
+.. attribute:: SOURCE_SUFFIXES
+
+   A list of strings representing the recognized file suffixes for source
+   modules.
+
+   .. versionadded:: 3.3
+
+.. attribute:: DEBUG_BYTECODE_SUFFIXES
+
+   A list of strings representing the file suffixes for non-optimized bytecode
+   modules.
+
+   .. versionadded:: 3.3
+
+.. attribute:: OPTIMIZED_BYTECODE_SUFFIXES
+
+   A list of strings representing the file suffixes for optimized bytecode
+   modules.
+
+   .. versionadded:: 3.3
+
+.. attribute:: BYTECODE_SUFFIXES
+
+   A list of strings representing the recognized file suffixes for bytecode
+   modules. Set to either :attr:`DEBUG_BYTECODE_SUFFIXES` or
+   :attr:`OPTIMIZED_BYTECODE_SUFFIXES` based on whether ``__debug__`` is true.
+
+   .. versionadded:: 3.3
+
+.. attribute:: EXTENSION_SUFFIXES
+
+   A list of strings representing the the recognized file suffixes for
+   extension modules.
+
+   .. versionadded:: 3.3
+
+
 .. class:: BuiltinImporter
 
     An :term:`importer` for built-in modules. All known built-in modules are
index 90b7220a6b016f129b7e7e500b821db94053fdd8..611f780254fc89b4d6996445be602d0bdfccd4ef 100644 (file)
@@ -190,6 +190,10 @@ attributes:
    compared to the constants defined in the :mod:`imp` module; see the
    documentation for that module for more information on module types.
 
+   .. deprecated:: 3.3
+      You may check the file path's suffix against the supported suffixes
+      listed in :mod:`importlib.machinery` to infer the same information.
+
 
 .. function:: getmodulename(path)
 
index 97d0c2f3fa48ad9e8d3e5d25cefc526d3f572b4e..61eb09454b85c1bf150c8d2c689c6c1a1cb8a5b0 100644 (file)
@@ -40,8 +40,8 @@ if os.name == "nt":
             clibname = 'msvcr%d' % (version * 10)
 
         # If python was built with in debug mode
-        import imp
-        if imp.get_suffixes()[0][0] == '_d.pyd':
+        import importlib.machinery
+        if '_d.pyd' in importlib.machinery.EXTENSION_SUFFIXES:
             clibname += 'd'
         return clibname+'.dll'
 
index d88a48e344e769bb4a2aa53baa31c75ea8e255ea..9954f070c0a0dc3a73e3e46f6aae980ba3653a80 100644 (file)
@@ -1,6 +1,7 @@
 import os
 import sys
 import imp
+import importlib.machinery
 
 from idlelib.TreeWidget import TreeItem
 from idlelib.ClassBrowser import ClassBrowser, ModuleBrowserTreeItem
@@ -70,7 +71,9 @@ class DirBrowserTreeItem(TreeItem):
 
     def listmodules(self, allnames):
         modules = {}
-        suffixes = imp.get_suffixes()
+        suffixes = importlib.machinery.EXTENSION_SUFFIXES[:]
+        suffixes += importlib.machinery.SOURCE_SUFFIXES[:]
+        suffixes += importlib.machinery.BYTECODE_SUFFIXES[:]
         sorted = []
         for suff, mode, flag in suffixes:
             i = -len(suff)
index 717b6a43432a7f35575b2a218daf5256dfe73698..f60f0508bac62b510a2dc0f58f508ec699a7b8bc 100644 (file)
@@ -17,9 +17,11 @@ from importlib._bootstrap import new_module
 from importlib._bootstrap import cache_from_source
 
 from importlib import _bootstrap
+from importlib import machinery
 import os
 import sys
 import tokenize
+import warnings
 
 
 # XXX "deprecate" once find_module(), load_module(), and get_suffixes() are
@@ -37,9 +39,12 @@ IMP_HOOK = 9
 
 
 def get_suffixes():
+    warnings.warn('imp.get_suffixes() is deprecated; use the constants '
+                  'defined on importlib.machinery instead',
+                  DeprecationWarning, 2)
     extensions = [(s, 'rb', C_EXTENSION) for s in extension_suffixes()]
-    source = [(s, 'U', PY_SOURCE) for s in _bootstrap._SOURCE_SUFFIXES]
-    bytecode = [(_bootstrap._BYTECODE_SUFFIX, 'rb', PY_COMPILED)]
+    source = [(s, 'U', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
+    bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
 
     return extensions + source + bytecode
 
@@ -61,7 +66,7 @@ def source_from_cache(path):
         raise ValueError('expected only 2 dots in '
                          '{!r}'.format(pycache_filename))
     base_filename = pycache_filename.partition('.')[0]
-    return os.path.join(head, base_filename + _bootstrap._SOURCE_SUFFIXES[0])
+    return os.path.join(head, base_filename + machinery.SOURCE_SUFFIXES[0])
 
 
 class NullImporter:
@@ -126,7 +131,7 @@ def load_compiled(name, pathname, file=None):
 # XXX deprecate
 def load_package(name, path):
     if os.path.isdir(path):
-        extensions = _bootstrap._SOURCE_SUFFIXES + [_bootstrap._BYTECODE_SUFFIX]
+        extensions = machinery.SOURCE_SUFFIXES[:] + [machinery.BYTECODE_SUFFIXES]
         for extension in extensions:
             path = os.path.join(path, '__init__'+extension)
             if os.path.exists(path):
@@ -190,19 +195,21 @@ def find_module(name, path=None):
 
     for entry in path:
         package_directory = os.path.join(entry, name)
-        for suffix in ['.py', _bootstrap._BYTECODE_SUFFIX]:
+        for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
             package_file_name = '__init__' + suffix
             file_path = os.path.join(package_directory, package_file_name)
             if os.path.isfile(file_path):
                 return None, package_directory, ('', '', PKG_DIRECTORY)
-        for suffix, mode, type_ in get_suffixes():
-            file_name = name + suffix
-            file_path = os.path.join(entry, file_name)
-            if os.path.isfile(file_path):
-                break
-        else:
-            continue
-        break  # Break out of outer loop when breaking out of inner loop.
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore')
+            for suffix, mode, type_ in get_suffixes():
+                file_name = name + suffix
+                file_path = os.path.join(entry, file_name)
+                if os.path.isfile(file_path):
+                    break
+            else:
+                continue
+            break  # Break out of outer loop when breaking out of inner loop.
     else:
         raise ImportError('No module name {!r}'.format(name), name=name)
 
index 9952b067f1363f879d8f4e8710955de794623684..ce23043665f1a069e8dba648722056c2ca8af137 100644 (file)
@@ -163,11 +163,14 @@ def new_module(name):
 
 _PYCACHE = '__pycache__'
 
-_SOURCE_SUFFIXES = ['.py']  # _setup() adds .pyw as needed.
+SOURCE_SUFFIXES = ['.py']  # _setup() adds .pyw as needed.
 
-_DEBUG_BYTECODE_SUFFIX = '.pyc'
-_OPT_BYTECODE_SUFFIX = '.pyo'
-_BYTECODE_SUFFIX = _DEBUG_BYTECODE_SUFFIX if __debug__ else _OPT_BYTECODE_SUFFIX
+DEBUG_BYTECODE_SUFFIXES = ['.pyc']
+OPTIMIZED_BYTECODE_SUFFIXES = ['.pyo']
+if __debug__:
+    BYTECODE_SUFFIXES = DEBUG_BYTECODE_SUFFIXES
+else:
+    BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES
 
 def cache_from_source(path, debug_override=None):
     """Given the path to a .py file, return the path to its .pyc/.pyo file.
@@ -181,10 +184,13 @@ def cache_from_source(path, debug_override=None):
 
     """
     debug = __debug__ if debug_override is None else debug_override
-    suffix = _DEBUG_BYTECODE_SUFFIX if debug else _OPT_BYTECODE_SUFFIX
+    if debug:
+        suffixes = DEBUG_BYTECODE_SUFFIXES
+    else:
+        suffixes = OPTIMIZED_BYTECODE_SUFFIXES
     head, tail = _path_split(path)
     base_filename, sep, _ = tail.partition('.')
-    filename = ''.join([base_filename, sep, _TAG, suffix])
+    filename = ''.join([base_filename, sep, _TAG, suffixes[0]])
     return _path_join(head, _PYCACHE, filename)
 
 
@@ -1147,15 +1153,15 @@ def _setup(sys_module, _imp_module):
     setattr(self_module, '_MAGIC_NUMBER', _imp_module.get_magic())
     setattr(self_module, '_TAG', _imp.get_tag())
     if builtin_os == 'nt':
-        _SOURCE_SUFFIXES.append('.pyw')
+        SOURCE_SUFFIXES.append('.pyw')
 
 
 def _install(sys_module, _imp_module):
     """Install importlib as the implementation of import."""
     _setup(sys_module, _imp_module)
     extensions = ExtensionFileLoader, _imp_module.extension_suffixes(), False
-    source = SourceFileLoader, _SOURCE_SUFFIXES, True
-    bytecode = SourcelessFileLoader, [_BYTECODE_SUFFIX], True
+    source = SourceFileLoader, SOURCE_SUFFIXES, True
+    bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES, True
     supported_loaders = [extensions, source, bytecode]
     sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
     sys.meta_path.extend([BuiltinImporter, FrozenImporter, PathFinder])
index 07465ced68a5281c46e380b3a60160aba1f2efd4..d5e7250479c5c55649c8784da51d8416ce69eb1c 100644 (file)
@@ -1,5 +1,9 @@
 """The machinery of importlib: finders, loaders, hooks, etc."""
 
+import _imp
+
+from ._bootstrap import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES,
+                         OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES)
 from ._bootstrap import BuiltinImporter
 from ._bootstrap import FrozenImporter
 from ._bootstrap import PathFinder
@@ -7,3 +11,5 @@ from ._bootstrap import FileFinder
 from ._bootstrap import SourceFileLoader
 from ._bootstrap import SourcelessFileLoader
 from ._bootstrap import ExtensionFileLoader
+
+EXTENSION_SUFFIXES = _imp.extension_suffixes()
index 16863146b5a2b3b5c5c04702a4de2d7ffc1c76e9..183e8180c94a8d77b058b8a6f0645c7f26d3256b 100644 (file)
@@ -9,7 +9,6 @@ from .source import util as source_util
 import decimal
 import imp
 import importlib
-import importlib._bootstrap
 import importlib.machinery
 import json
 import os
@@ -72,7 +71,7 @@ def source_wo_bytecode(seconds, repeat):
             assert not os.path.exists(imp.cache_from_source(mapping[name]))
             sys.meta_path.append(importlib.machinery.PathFinder)
             loader = (importlib.machinery.SourceFileLoader,
-                      importlib._bootstrap._SOURCE_SUFFIXES, True)
+                      importlib.machinery.SOURCE_SUFFIXES, True)
             sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader))
             for result in bench(name, lambda: sys.modules.pop(name), repeat=repeat,
                                 seconds=seconds):
@@ -110,7 +109,7 @@ def source_writing_bytecode(seconds, repeat):
     with source_util.create_modules(name) as mapping:
         sys.meta_path.append(importlib.machinery.PathFinder)
         loader = (importlib.machinery.SourceFileLoader,
-                  importlib._bootstrap._SOURCE_SUFFIXES, True)
+                  importlib.machinery.SOURCE_SUFFIXES, True)
         sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader))
         def cleanup():
             sys.modules.pop(name)
@@ -145,7 +144,7 @@ def source_using_bytecode(seconds, repeat):
     with source_util.create_modules(name) as mapping:
         sys.meta_path.append(importlib.machinery.PathFinder)
         loader = (importlib.machinery.SourceFileLoader,
-                importlib._bootstrap._SOURCE_SUFFIXES, True)
+                importlib.machinery.SOURCE_SUFFIXES, True)
         sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader))
         py_compile.compile(mapping[name])
         assert os.path.exists(imp.cache_from_source(mapping[name]))
index d149169748346b249f6e89f5ba2b8b3f8c79ad6f..a266dd98c831561ef5b0f8fe010a67178821dcde 100644 (file)
@@ -1,4 +1,5 @@
 import imp
+from importlib import machinery
 import os
 import sys
 
@@ -6,10 +7,9 @@ PATH = None
 EXT = None
 FILENAME = None
 NAME = '_testcapi'
-_file_exts = [x[0] for x in imp.get_suffixes() if x[2] == imp.C_EXTENSION]
 try:
     for PATH in sys.path:
-        for EXT in _file_exts:
+        for EXT in machinery.EXTENSION_SUFFIXES:
             FILENAME = NAME + EXT
             FILEPATH = os.path.join(PATH, FILENAME)
             if os.path.exists(os.path.join(PATH, FILENAME)):
@@ -18,4 +18,3 @@ try:
         PATH = EXT = FILENAME = FILEPATH = None
 except StopIteration:
     pass
-del _file_exts
index fade25fe104db1bf9d7ff4a2eacfa92a75e3e7fd..21a4378ce9d5d64df9a29b97b2c41d059e0d6bac 100644 (file)
@@ -1,5 +1,6 @@
 """Test case-sensitivity (PEP 235)."""
 from importlib import _bootstrap
+from importlib import machinery
 from .. import util
 from . import util as source_util
 import imp
@@ -20,12 +21,12 @@ class CaseSensitivityTest(unittest.TestCase):
     assert name != name.lower()
 
     def find(self, path):
-        finder = _bootstrap.FileFinder(path,
-                                        (_bootstrap.SourceFileLoader,
-                                            _bootstrap._SOURCE_SUFFIXES,
+        finder = machinery.FileFinder(path,
+                                      (machinery.SourceFileLoader,
+                                            machinery.SOURCE_SUFFIXES,
                                             True),
-                                        (_bootstrap.SourcelessFileLoader,
-                                            [_bootstrap._BYTECODE_SUFFIX],
+                                        (machinery.SourcelessFileLoader,
+                                            machinery.BYTECODE_SUFFIXES,
                                             True))
         return finder.find_module(self.name)
 
index 45b804ffdffc2c471bd0e582a54796091311547e..bbe01639fdec3397d7200013f37b7a9bb9bd25fe 100644 (file)
@@ -1,7 +1,7 @@
 from .. import abc
 from . import util as source_util
 
-from importlib import _bootstrap
+from importlib import machinery
 import errno
 import imp
 import os
@@ -36,11 +36,11 @@ class FinderTests(abc.FinderTests):
     """
 
     def import_(self, root, module):
-        loader_details = [(_bootstrap.SourceFileLoader,
-                            _bootstrap._SOURCE_SUFFIXES, True),
-                          (_bootstrap.SourcelessFileLoader,
-                            [_bootstrap._BYTECODE_SUFFIX], True)]
-        finder = _bootstrap.FileFinder(root, *loader_details)
+        loader_details = [(machinery.SourceFileLoader,
+                            machinery.SOURCE_SUFFIXES, True),
+                          (machinery.SourcelessFileLoader,
+                            machinery.BYTECODE_SUFFIXES, True)]
+        finder = machinery.FileFinder(root, *loader_details)
         return finder.find_module(module)
 
     def run_test(self, test, create=None, *, compile_=None, unlink=None):
@@ -138,8 +138,8 @@ class FinderTests(abc.FinderTests):
 
     def test_empty_string_for_dir(self):
         # The empty string from sys.path means to search in the cwd.
-        finder = _bootstrap.FileFinder('', (_bootstrap.SourceFileLoader,
-            _bootstrap._SOURCE_SUFFIXES, True))
+        finder = machinery.FileFinder('', (machinery.SourceFileLoader,
+            machinery.SOURCE_SUFFIXES, True))
         with open('mod.py', 'w') as file:
             file.write("# test file for importlib")
         try:
@@ -150,8 +150,8 @@ class FinderTests(abc.FinderTests):
 
     def test_invalidate_caches(self):
         # invalidate_caches() should reset the mtime.
-        finder = _bootstrap.FileFinder('', (_bootstrap.SourceFileLoader,
-            _bootstrap._SOURCE_SUFFIXES, True))
+        finder = machinery.FileFinder('', (machinery.SourceFileLoader,
+            machinery.SOURCE_SUFFIXES, True))
         finder._path_mtime = 42
         finder.invalidate_caches()
         self.assertEqual(finder._path_mtime, -1)
index df69b4d61edd00bd56c7eeaae02ca1dd12736cd8..54c069950140840020ca46e75439461fb20da5b1 100644 (file)
@@ -1,6 +1,6 @@
 from . import util as source_util
 
-from importlib import _bootstrap
+from importlib import machinery
 import imp
 import unittest
 
@@ -10,8 +10,8 @@ class PathHookTest(unittest.TestCase):
     """Test the path hook for source."""
 
     def path_hook(self):
-        return _bootstrap.FileFinder.path_hook((_bootstrap.SourceFileLoader,
-            _bootstrap._SOURCE_SUFFIXES, True))
+        return machinery.FileFinder.path_hook((machinery.SourceFileLoader,
+            machinery.SOURCE_SUFFIXES, True))
 
     def test_success(self):
         with source_util.create_modules('dummy') as mapping:
index fc9f61204468fa15c93d97940548e0ca618100ca..56d05fb9d4f2bea8439ea090a452b1614268f66c 100644 (file)
@@ -29,14 +29,15 @@ Here are some of the useful functions provided by this module:
 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
 __date__ = '1 Jan 2001'
 
-import sys
-import os
-import types
+import imp
+import importlib.machinery
 import itertools
+import linecache
+import os
 import re
-import imp
+import sys
 import tokenize
-import linecache
+import types
 from operator import attrgetter
 from collections import namedtuple
 
@@ -432,6 +433,8 @@ ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')
 
 def getmoduleinfo(path):
     """Get the module name, suffix, mode, and module type for a given file."""
+    warnings.warn('inspect.getmoduleinfo() is deprecated', DeprecationWarning,
+                  2)
     filename = os.path.basename(path)
     suffixes = [(-len(suffix), suffix, mode, mtype)
                     for suffix, mode, mtype in imp.get_suffixes()]
@@ -450,12 +453,14 @@ def getsourcefile(object):
     Return None if no way can be identified to get the source.
     """
     filename = getfile(object)
-    if filename[-4:].lower() in ('.pyc', '.pyo'):
-        filename = filename[:-4] + '.py'
-    for suffix, mode, kind in imp.get_suffixes():
-        if 'b' in mode and filename[-len(suffix):].lower() == suffix:
-            # Looks like a binary file.  We want to only return a text file.
-            return None
+    all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
+    all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
+    if any(filename.endswith(s) for s in all_bytecode_suffixes):
+        filename = (os.path.splitext(filename)[0] +
+                    importlib.machinery.SOURCE_SUFFIXES[0])
+    elif any(filename.endswith(s) for s in
+                 importlib.machinery.EXTENSION_SUFFIXES):
+        return None
     if os.path.exists(filename):
         return filename
     # only return a non-existent filename if the module has a PEP 302 loader
index c0910aa8774f10bec3082d206d1b376f25331e2a..683e30549643c6890e371e3deff3b617e6f49eba 100644 (file)
@@ -222,8 +222,9 @@ class ModuleFinder:
         # But we must also collect Python extension modules - although
         # we cannot separate normal dlls from Python extensions.
         suffixes = []
-        for triple in imp.get_suffixes():
-            suffixes.append(triple[0])
+        suffixes += importlib.machinery.EXTENSION_SUFFIXES[:]
+        suffixes += importlib.machinery.SOURCE_SUFFIXES[:]
+        suffixes += importlib.machinery.BYTECODE_SUFFIXES[:]
         for dir in m.__path__:
             try:
                 names = os.listdir(dir)
index b319d11b5e49fb64337f1fbf65f457854f703418..9c9658cef5934886b7bfc1f0661d0f179fd55385 100755 (executable)
@@ -53,6 +53,7 @@ Richard Chamberlain, for the first implementation of textdoc.
 
 import builtins
 import imp
+import importlib.machinery
 import inspect
 import io
 import os
@@ -220,20 +221,34 @@ def synopsis(filename, cache={}):
     mtime = os.stat(filename).st_mtime
     lastupdate, result = cache.get(filename, (None, None))
     if lastupdate is None or lastupdate < mtime:
-        info = inspect.getmoduleinfo(filename)
         try:
             file = tokenize.open(filename)
         except IOError:
             # module can't be opened, so skip it
             return None
-        if info and 'b' in info[2]: # binary modules have to be imported
-            try: module = imp.load_module('__temp__', file, filename, info[1:])
-            except: return None
+        binary_suffixes = importlib.machinery.BYTECODE_SUFFIXES[:]
+        binary_suffixes += importlib.machinery.EXTENSION_SUFFIXES[:]
+        if any(filename.endswith(x) for x in binary_suffixes):
+            # binary modules have to be imported
+            file.close()
+            if any(filename.endswith(x) for x in
+                    importlib.machinery.BYTECODE_SUFFIXES):
+                loader = importlib.machinery.SourcelessFileLoader('__temp__',
+                                                                  filename)
+            else:
+                loader = importlib.machinery.ExtensionFileLoader('__temp__',
+                                                                 filename)
+            try:
+                module = loader.load_module('__temp__')
+            except:
+                return None
             result = (module.__doc__ or '').splitlines()[0]
             del sys.modules['__temp__']
-        else: # text modules can be directly examined
+        else:
+            # text modules can be directly examined
             result = source_synopsis(file)
             file.close()
+
         cache[filename] = (mtime, result)
     return result
 
index 2f11eefd58ad96b4ce68c1e78e6b89e0fcd1b9e6..29b2d861ed4e4f1bd04ee7ee0ab6543805a8ea61 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -23,6 +23,11 @@ Core and Builtins
 Library
 -------
 
+- Issue #13959: imp.get_suffixes() has been deprecated in favour of the new
+  attributes on importlib.machinery: SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES,
+  OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, and EXTENSION_SUFFIXES. This
+  led to an indirect deprecation of inspect.getmoduleinfo().
+
 - Issue #14662: Prevent shutil failures on OS X when destination does not
   support chflag operations.  Patch by Hynek Schlawack.