On Wed, Jul 30, 2014 at 2:43 AM, Steven D'Aprano <[email protected]>
wrote:
> I'm looking for a programmatic way to get a list of all Python modules
> and packages. Not just those already imported, but all those which
> *could* be imported.
>
I wrote a modified dir(), which I inject into builtins in interactive
sessions. When getting a directory of an object, it attempts to identify
not-yet-imported modules it contains. Such modules are enclosed in square
brackets. Modules that smell like packages also get a trailing '/'. For
example:
% python
Python 2.7.5+ (2.7:2921f6c2009e, Apr 30 2014, 14:00:13)
[GCC 4.4.6 [TWW]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dateutil
>>> dir(dateutil)
['[easter]', '[parser]', '[relativedelta]', '[rrule]', '[tz]', '[tzwin]',
'[zoneinfo/]', '__author__', '__builtins__', '__doc__', '__file__',
'__license__', '__name__', '__package__', '__path__', '__version__']
It's not perfect, but works for my needs. Perhaps it will give you some
ideas.
Skip
import os
_dir = dir
def dir(o=globals(), hidden=False):
if not hidden and hasattr(o, "__all__"):
contents = o.__all__
else:
contents = _dir(o)
if hasattr(o, "__file__"):
dname = os.path.dirname(o.__file__)
# look for not-yet-imported modules within packages
if "/__init__.py" in o.__file__:
try:
stuff = os.listdir(dname)
except OSError:
# Searching eggs lands here. Introspect.
import zipfile
d = os.path.dirname(dname)
if not zipfile.is_zipfile(d):
return sorted(contents)
base = os.path.basename(dname)
stuff = [f[len(base)+1:]
for f in zipfile.ZipFile(d).namelist()
if f.startswith(base)]
for p in stuff:
m = os.path.splitext(p)[0]
if (
# not already known
m not in contents and
# isn't a package file
p != "__init__.py" and
# is a python or ...
(p.endswith(".py") or
# c module or ...
p.endswith(".so") or
# a subpackage
(os.path.isdir(os.path.join(dname, p)) and
os.path.exists(os.path.join(dname, p, "__init__.py"))))):
if os.path.isdir(os.path.join(dname, p)):
# tack on trailing / to distinguish packages from
# modules
m += "/"
if not m.startswith("_") or hidden:
# [...] shows it hasn't been imported yet
contents.append("[%s]" % m)
return sorted(contents)
--
https://mail.python.org/mailman/listinfo/python-list