1010if TYPE_CHECKING :
1111 from collections .abc import Sequence
1212 from types import ModuleType
13- from typing import Protocol
14-
15- class Writer (Protocol ):
16- def write (self , s : str , / ) -> object : ...
1713
1814SEEN_MODS = set ()
1915
2016
21- def walk_pkgutil (mod_name : str , locations : Sequence [str ], io : Writer ) -> None :
17+ def walk_pkgutil (mod_name : str , locations : Sequence [str ]) -> None :
2218 for pkg in pkgutil .walk_packages (locations , f"{ mod_name } ." ):
2319 if pkg .name in SEEN_MODS :
2420 continue
2521 else :
2622 # We don't recurse here because `walk_packages` takes care of
2723 # it for us.
2824 SEEN_MODS .add (pkg .name )
29- print (pkg .name , file = io )
3025
3126
32- def walk_naive (mod_name : str , mod : ModuleType , io : Writer ) -> None :
27+ def walk_naive (mod_name : str , mod : ModuleType ) -> None :
3328 for attr in dir (mod ):
3429 attr_obj = getattr (mod , attr , None )
3530 # Shouldn't happen, but who knows.
@@ -46,7 +41,7 @@ def walk_naive(mod_name: str, mod: ModuleType, io: Writer) -> None:
4641 try :
4742 submod_name = f"{ mod_name } .{ attr } "
4843 importlib .import_module (submod_name )
49- walk (submod_name , io )
44+ walk (submod_name )
5045 except ImportError :
5146 # ...but sometimes we do want to include re-exports, since
5247 # they might be things like "accelerator" modules that don't
@@ -57,17 +52,16 @@ def walk_naive(mod_name: str, mod: ModuleType, io: Writer) -> None:
5752 # that don't actually appear on disk. Experimentally,
5853 # there are a few of these (like "TK").
5954 importlib .import_module (attr )
60- walk (attr , io )
55+ walk (attr )
6156 except ImportError :
6257 continue
6358
6459
65- def walk (mod_name : str , io : Writer ) -> None :
60+ def walk (mod_name : str ) -> None :
6661 if mod_name in SEEN_MODS :
6762 return
6863 else :
6964 SEEN_MODS .add (mod_name )
70- print (mod_name , file = io )
7165
7266 # Try and import it.
7367 try :
@@ -81,26 +75,35 @@ def walk(mod_name: str, io: Writer) -> None:
8175 locations = None
8276
8377 if locations is not None :
84- walk_pkgutil (mod_name , locations , io )
78+ walk_pkgutil (mod_name , locations )
8579 else :
86- walk_naive (mod_name , mod , io )
80+ walk_naive (mod_name , mod )
8781
8882
8983if __name__ == "__main__" :
9084 output = sys .argv [1 ]
9185
92- with open (output , mode = "w" ) as io :
93- for mod_name in sys .builtin_module_names :
94- walk (mod_name , io )
86+ for mod_name in sys .builtin_module_names :
87+ walk (mod_name )
9588
96- if hasattr (sys , "stdlib_module_names" ):
97- for mod_name in sys .stdlib_module_names :
98- walk (mod_name , io )
99- else :
100- for mod_name in sys .stdin :
101- # Our precomputed list might not start at the root, since it
102- # might be a package rather than a module.
103- if "." in mod_name :
104- top_mod = mod_name .split ("." )[0 ]
105- walk (top_mod , io )
106- walk (mod_name .rstrip ("\n " ), io )
89+ if hasattr (sys , "stdlib_module_names" ):
90+ for mod_name in sys .stdlib_module_names :
91+ walk (mod_name )
92+ else :
93+ for mod_name in sys .stdin :
94+ # Our precomputed list might not start at the root, since it
95+ # might be a package rather than a module.
96+ if "." in mod_name :
97+ top_mod = mod_name .split ("." )[0 ]
98+ walk (top_mod )
99+ walk (mod_name .rstrip ("\n " ))
100+
101+ try :
102+ with open (output , encoding = "utf-8" ) as io :
103+ SEEN_MODS .update (io .read ().splitlines ())
104+ except FileNotFoundError :
105+ pass
106+
107+ with open (output , mode = "w" , encoding = "utf-8" ) as io :
108+ for line in sorted (SEEN_MODS ):
109+ print (line , file = io )
0 commit comments