spectras :
Alright, I was curious, and I digged a bit into pkgutil, and I came up with this, which is much simpler than I expected:\nlist(pkgutil.iter_modules())\n\nIt lists all top-level packages/modules available either as regular files or zip packages, without loading them. It will not see other types of packages though, unless they properly register with the pkgutil internals.\nEach returned entry is a 3-tuple with the items:\n\nmodule_finder: The file finder instance that found the module\nname: The name of the module\nispkg: A boolean specifying whether it is a regular module or a package.\n\nExample 3-tuple:\n(FileFinder('/usr/lib/python3/dist-packages'), 'PIL', True)\n\nAnd I can confirm that this did not load the PIL package:\nIn [11]: sys.modules['PIL']\n---------------------------------------------------------------------------\nKeyError Traceback (most recent call last)\n<ipython-input-11-b0fc0af6cc34> in <module>()\n----> 1 sys.modules['PIL']\n\nKeyError: 'PIL'\n",
2016-06-10T16:37:24
Boris Verkhovskiy :
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):\nfrom pydoc import ModuleScanner\nimport warnings\n\ndef scan_modules():\n """Scans for available modules using pydoc.ModuleScanner, taken from help('modules')"""\n modules = {}\n def callback(path, modname, desc, modules=modules):\n if modname and modname[-9:] == ".__init__":\n modname = modname[:-9] + " (package)"\n if modname.find(".") < 0:\n modules[modname] = 1\n def onerror(modname):\n callback(None, modname, None)\n with warnings.catch_warnings():\n warnings.simplefilter("ignore") # ignore warnings from importing deprecated modules\n ModuleScanner().run(callback, onerror=onerror)\n return modules\n\nmodules = list(scan_modules().keys())\nprint(sorted(modules))\n\nThe 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.\nThe problem with ModuleScanner is that it returns all available modules, including the ones you've pip installed. If you only need the packages that come with Python, then you can start Python with the -I command line option.\nHere are the packages that pkgutil doesn't find on Python 3.9:\n$ python3.9 -I\nPython 3.9.0+ (default, Oct 19 2020, 09:51:18) \n[GCC 10.2.0] on linux\nType "help", "copyright", "credits" or "license" for more information.\n>>> modules = ... # paste the above code\n...\n>>> import pkgutil\n>>> sorted(set(modules) - {m.name for m in pkgutil.iter_modules()})\n['_abc', '_ast', '_bisect', '_blake2', '_codecs', '_collections', '_csv', \n'_datetime', '_elementtree', '_functools', '_heapq', '_imp', '_io', \n'_locale', '_md5', '_operator', '_peg_parser', '_pickle', \n'_posixsubprocess', '_random', '_sha1', '_sha256', '_sha3', '_sha512', \n'_signal', '_socket', '_sre', '_stat', '_statistics', '_string', \n'_struct', '_symtable', '_thread', '_tracemalloc', '_warnings', \n'_weakref', 'array', 'atexit', 'binascii', 'builtins', 'cmath', 'errno', \n'faulthandler', 'fcntl', 'gc', 'grp', 'itertools', 'marshal', 'math', \n'posix', 'pwd', 'pyexpat', 'select', 'spwd', 'sys', 'syslog', 'time', \n'unicodedata', 'xxsubtype', 'zlib']\n\n\nThis 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):",
2021-01-23T02:24:18