On Wed, Jul 30, 2014 at 2:43 AM, Steven D'Aprano <st...@pearwood.info>
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

Reply via email to