If you need all available modules, not just the ones that are present as files in all the directories in your sys.path
, then you can use (the undocumented) pydoc.ModuleScanner
(which unfortunately loads the modules to work):
from pydoc import ModuleScanner
import warnings
def scan_modules():
"""Scans for available modules using pydoc.ModuleScanner, taken from help('modules')"""
modules = {}
def callback(path, modname, desc, modules=modules):
if modname and modname[-9:] == ".__init__":
modname = modname[:-9] + " (package)"
if modname.find(".") < 0:
modules[modname] = 1
def onerror(modname):
callback(None, modname, None)
with warnings.catch_warnings():
warnings.simplefilter("ignore") # ignore warnings from importing deprecated modules
ModuleScanner().run(callback, onerror=onerror)
return modules
modules = list(scan_modules().keys())
print(sorted(modules))
The problem with pkgutil.iter_modules
is that it doesn't return all packages, only the ones that are files or directories, but CPython loads a few modules in other special ways that can't be detected by just looking at the files.
The problem with ModuleScanner
is that it returns all available modules, including the ones you've pip install
ed. If you only need the packages that come with Python, then you can start Python with the -I
command line option.
Here are the packages that pkgutil
doesn't find on Python 3.9:
$ python3.9 -I
Python 3.9.0+ (default, Oct 19 2020, 09:51:18)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> modules = ... # paste the above code
...
>>> import pkgutil
>>> sorted(set(modules) - {m.name for m in pkgutil.iter_modules()})
['_abc', '_ast', '_bisect', '_blake2', '_codecs', '_collections', '_csv',
'_datetime', '_elementtree', '_functools', '_heapq', '_imp', '_io',
'_locale', '_md5', '_operator', '_peg_parser', '_pickle',
'_posixsubprocess', '_random', '_sha1', '_sha256', '_sha3', '_sha512',
'_signal', '_socket', '_sre', '_stat', '_statistics', '_string',
'_struct', '_symtable', '_thread', '_tracemalloc', '_warnings',
'_weakref', 'array', 'atexit', 'binascii', 'builtins', 'cmath', 'errno',
'faulthandler', 'fcntl', 'gc', 'grp', 'itertools', 'marshal', 'math',
'posix', 'pwd', 'pyexpat', 'select', 'spwd', 'sys', 'syslog', 'time',
'unicodedata', 'xxsubtype', 'zlib']
This answer is based on @sancho.s's, except instead of parsing the stdout
of help('modules')
, I have copy/pasted the code that that function runs (you need to copy/paste it because it prints to stdout, there's no helper function):