From 05df063ad80becc1ba6bd07d67b55b5965f32375 Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@python.org>
Date: Fri, 14 Jun 2024 20:39:50 +0200
Subject: gh-120417: Fix "imported but unused" linter warnings (#120461)

Add __all__ to the following modules:
importlib.machinery, importlib.util and xml.sax.

Add also "# noqa: F401" in collections.abc,
subprocess and xml.sax.

* Sort __all__; remove collections.abc.__all__; remove private names

* Add tests
---
 Lib/collections/abc.py              |  4 ++--
 Lib/importlib/machinery.py          |  8 ++++++++
 Lib/importlib/util.py               |  6 ++++++
 Lib/subprocess.py                   |  2 +-
 Lib/test/test_importlib/test_api.py | 40 +++++++++++++++++++++++++++++++++++++
 Lib/test/test_sax.py                | 18 ++++++++++++++++-
 Lib/xml/sax/__init__.py             | 14 +++++++++----
 7 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/Lib/collections/abc.py b/Lib/collections/abc.py
index 86ca8b8..bff7629 100644
--- a/Lib/collections/abc.py
+++ b/Lib/collections/abc.py
@@ -1,3 +1,3 @@
 from _collections_abc import *
-from _collections_abc import __all__
-from _collections_abc import _CallableGenericAlias
+from _collections_abc import __all__  # noqa: F401
+from _collections_abc import _CallableGenericAlias  # noqa: F401
diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py
index fbd30b1..6e294d5 100644
--- a/Lib/importlib/machinery.py
+++ b/Lib/importlib/machinery.py
@@ -19,3 +19,11 @@ from ._bootstrap_external import NamespaceLoader
 def all_suffixes():
     """Returns a list of all recognized module suffixes for this process"""
     return SOURCE_SUFFIXES + BYTECODE_SUFFIXES + EXTENSION_SUFFIXES
+
+
+__all__ = ['AppleFrameworkLoader', 'BYTECODE_SUFFIXES', 'BuiltinImporter',
+           'DEBUG_BYTECODE_SUFFIXES', 'EXTENSION_SUFFIXES',
+           'ExtensionFileLoader', 'FileFinder', 'FrozenImporter', 'ModuleSpec',
+           'NamespaceLoader', 'OPTIMIZED_BYTECODE_SUFFIXES', 'PathFinder',
+           'SOURCE_SUFFIXES', 'SourceFileLoader', 'SourcelessFileLoader',
+           'WindowsRegistryFinder', 'all_suffixes']
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index c94a148..7243d05 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -270,3 +270,9 @@ class LazyLoader(Loader):
         loader_state['is_loading'] = False
         module.__spec__.loader_state = loader_state
         module.__class__ = _LazyModule
+
+
+__all__ = ['LazyLoader', 'Loader', 'MAGIC_NUMBER',
+           'cache_from_source', 'decode_source', 'find_spec',
+           'module_from_spec', 'resolve_name', 'source_from_cache',
+           'source_hash', 'spec_from_file_location', 'spec_from_loader']
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index b2dcb14..bc08878 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -79,7 +79,7 @@ _can_fork_exec = sys.platform not in {"emscripten", "wasi", "ios", "tvos", "watc
 
 if _mswindows:
     import _winapi
-    from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP,
+    from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP,  # noqa: F401
                          STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
                          STD_ERROR_HANDLE, SW_HIDE,
                          STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW,
diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py
index 2a35f3d..973237c 100644
--- a/Lib/test/test_importlib/test_api.py
+++ b/Lib/test/test_importlib/test_api.py
@@ -6,6 +6,7 @@ machinery = test_util.import_importlib('importlib.machinery')
 
 import os.path
 import sys
+from test import support
 from test.support import import_helper
 from test.support import os_helper
 import types
@@ -437,5 +438,44 @@ class StartupTests:
  ) = test_util.test_both(StartupTests, machinery=machinery)
 
 
+class TestModuleAll(unittest.TestCase):
+    def test_machinery(self):
+        extra = (
+            # from importlib._bootstrap and importlib._bootstrap_external
+            'AppleFrameworkLoader',
+            'BYTECODE_SUFFIXES',
+            'BuiltinImporter',
+            'DEBUG_BYTECODE_SUFFIXES',
+            'EXTENSION_SUFFIXES',
+            'ExtensionFileLoader',
+            'FileFinder',
+            'FrozenImporter',
+            'ModuleSpec',
+            'NamespaceLoader',
+            'OPTIMIZED_BYTECODE_SUFFIXES',
+            'PathFinder',
+            'SOURCE_SUFFIXES',
+            'SourceFileLoader',
+            'SourcelessFileLoader',
+            'WindowsRegistryFinder',
+        )
+        support.check__all__(self, machinery['Source'], extra=extra)
+
+    def test_util(self):
+        extra = (
+            # from importlib.abc, importlib._bootstrap
+            # and importlib._bootstrap_external
+            'Loader',
+            'MAGIC_NUMBER',
+            'cache_from_source',
+            'decode_source',
+            'module_from_spec',
+            'source_from_cache',
+            'spec_from_file_location',
+            'spec_from_loader',
+        )
+        support.check__all__(self, util['Source'], extra=extra)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py
index 9b3014a..0d0f86c 100644
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -16,6 +16,7 @@ from xml.sax.expatreader import create_parser
 from xml.sax.handler import (feature_namespaces, feature_external_ges,
                              LexicalHandler)
 from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
+from xml import sax
 from io import BytesIO, StringIO
 import codecs
 import os.path
@@ -25,7 +26,7 @@ import sys
 from urllib.error import URLError
 import urllib.request
 from test.support import os_helper
-from test.support import findfile
+from test.support import findfile, check__all__
 from test.support.os_helper import FakePath, TESTFN
 
 
@@ -1557,5 +1558,20 @@ class CDATAHandlerTest(unittest.TestCase):
         self.assertEqual(self.char_index, 2)
 
 
+class TestModuleAll(unittest.TestCase):
+    def test_all(self):
+        extra = (
+            'ContentHandler',
+            'ErrorHandler',
+            'InputSource',
+            'SAXException',
+            'SAXNotRecognizedException',
+            'SAXNotSupportedException',
+            'SAXParseException',
+            'SAXReaderNotAvailable',
+        )
+        check__all__(self, sax, extra=extra)
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/xml/sax/__init__.py b/Lib/xml/sax/__init__.py
index b657310..fe4582c 100644
--- a/Lib/xml/sax/__init__.py
+++ b/Lib/xml/sax/__init__.py
@@ -21,9 +21,9 @@ expatreader -- Driver that allows use of the Expat parser with SAX.
 
 from .xmlreader import InputSource
 from .handler import ContentHandler, ErrorHandler
-from ._exceptions import SAXException, SAXNotRecognizedException, \
-                        SAXParseException, SAXNotSupportedException, \
-                        SAXReaderNotAvailable
+from ._exceptions import (SAXException, SAXNotRecognizedException,
+                          SAXParseException, SAXNotSupportedException,
+                          SAXReaderNotAvailable)
 
 
 def parse(source, handler, errorHandler=ErrorHandler()):
@@ -55,7 +55,7 @@ default_parser_list = ["xml.sax.expatreader"]
 # tell modulefinder that importing sax potentially imports expatreader
 _false = 0
 if _false:
-    import xml.sax.expatreader
+    import xml.sax.expatreader    # noqa: F401
 
 import os, sys
 if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ:
@@ -92,3 +92,9 @@ def make_parser(parser_list=()):
 def _create_parser(parser_name):
     drv_module = __import__(parser_name,{},{},['create_parser'])
     return drv_module.create_parser()
+
+
+__all__ = ['ContentHandler', 'ErrorHandler', 'InputSource', 'SAXException',
+           'SAXNotRecognizedException', 'SAXNotSupportedException',
+           'SAXParseException', 'SAXReaderNotAvailable',
+           'default_parser_list', 'make_parser', 'parse', 'parseString']
-- 
cgit v0.12