Is there a standard way to list names of Python modules in a package?

Is there a straightforward way to list the names of all modules in a package, without using __all__?

For example, given this package:

/testpkg
/testpkg/__init__.py
/testpkg/modulea.py
/testpkg/moduleb.py

I'm wondering if there is a standard or built-in way to do something like this:

>>> package_contents("testpkg")
['modulea', 'moduleb']

The manual approach would be to iterate through the module search paths in order to find the package's directory. One could then list all the files in that directory, filter out the uniquely-named py/pyc/pyo files, strip the extensions, and return that list. But this seems like a fair amount of work for something the module import mechanism is already doing internally. Is that functionality exposed anywhere?


Asked by: Agata269 | Posted: 06-12-2021






Answer 1

Using python2.3 and above, you could also use the pkgutil module:

>>> import pkgutil
>>> [name for _, name, _ in pkgutil.iter_modules(['testpkg'])]
['modulea', 'moduleb']

EDIT: Note that the parameter for pkgutil.iter_modules is not a list of modules, but a list of paths, so you might want to do something like this:

>>> import os.path, pkgutil
>>> import testpkg
>>> pkgpath = os.path.dirname(testpkg.__file__)
>>> print([name for _, name, _ in pkgutil.iter_modules([pkgpath])])

Answered by: Kate775 | Posted: 07-01-2022



Answer 2

import module
help(module)

Answered by: Aston863 | Posted: 07-01-2022



Answer 3

Maybe this will do what you're looking for?

import imp
import os
MODULE_EXTENSIONS = ('.py', '.pyc', '.pyo')

def package_contents(package_name):
    file, pathname, description = imp.find_module(package_name)
    if file:
        raise ImportError('Not a package: %r', package_name)
    # Use a set because some may be both source and compiled.
    return set([os.path.splitext(module)[0]
        for module in os.listdir(pathname)
        if module.endswith(MODULE_EXTENSIONS)])

Answered by: Julian305 | Posted: 07-01-2022



Answer 4

Don't know if I'm overlooking something, or if the answers are just out-dated but;

As stated by user815423426 this only works for live objects and the listed modules are only modules that were imported before.

Listing modules in a package seems really easy using inspect:

>>> import inspect, testpkg
>>> inspect.getmembers(testpkg, inspect.ismodule)
['modulea', 'moduleb']

Answered by: Thomas984 | Posted: 07-01-2022



Answer 5

This is a recursive version that works with python 3.6 and above:

import importlib.util
from pathlib import Path
import os
MODULE_EXTENSIONS = '.py'

def package_contents(package_name):
    spec = importlib.util.find_spec(package_name)
    if spec is None:
        return set()

    pathname = Path(spec.origin).parent
    ret = set()
    with os.scandir(pathname) as entries:
        for entry in entries:
            if entry.name.startswith('__'):
                continue
            current = '.'.join((package_name, entry.name.partition('.')[0]))
            if entry.is_file():
                if entry.name.endswith(MODULE_EXTENSIONS):
                    ret.add(current)
            elif entry.is_dir():
                ret.add(current)
                ret |= package_contents(current)


    return ret

Answered by: Haris385 | Posted: 07-01-2022



Answer 6

This should list the modules:

help("modules")

Answered by: Miranda192 | Posted: 07-01-2022



Answer 7

If you would like to view an inforamtion about your package outside of the python code (from a command prompt) you can use pydoc for it.

# get a full list of packages that you have installed on you machine
$ python -m pydoc modules

# get information about a specific package
$ python -m pydoc <your package>

You will have the same result as pydoc but inside of interpreter using help

>>> import <my package>
>>> help(<my package>)

Answered by: Chester452 | Posted: 07-01-2022



Answer 8

Based on cdleary's example, here's a recursive version listing path for all submodules:

import imp, os

def iter_submodules(package):
    file, pathname, description = imp.find_module(package)
    for dirpath, _, filenames in os.walk(pathname):
        for  filename in filenames:
            if os.path.splitext(filename)[1] == ".py":
                yield os.path.join(dirpath, filename)

Answered by: Arthur514 | Posted: 07-01-2022



Answer 9

The other answers here will run the code in the package as they inspect it. If you don't want that, you can grep the files like this answer

def _get_class_names(file_name: str) -> List[str]:
    """Get the python class name defined in a file without running code
    file_name: the name of the file to search for class definitions in
    return: all the classes defined in that python file, empty list if no matches"""
    defined_class_names = []
    # search the file for class definitions
    with open(file_name, "r") as file:
        for line in file:
            # regular expression for class defined in the file
            # searches for text that starts with "class" and ends with ( or :,
            # whichever comes first
            match = re.search("^class(.+?)(\(|:)", line) # noqa
            if match:
                # add the cleaned match to the list if there is one
                defined_class_name = match.group(1).strip()
                defined_class_names.append(defined_class_name)
    return defined_class_names

Answered by: Lana427 | Posted: 07-01-2022



Answer 10

There is a __loader__ variable inside each package instance. So, if you import the package, you can find the "module resources" inside the package:

import testpkg # change this by your package name

for mod in testpkg.__loader__.get_resource_reader().contents():
    print(mod)

You can of course improve the loop to find the "module" name:

import testpkg

from pathlib import Path

for mod in testpkg.__loader__.get_resource_reader().contents():
    # You can filter the name like 
    # Path(l).suffix not in (".py", ".pyc")
    print(Path(mod).stem)
    

Inside the package, you can find your modules by directly using __loader__ of course.

Answered by: Rafael635 | Posted: 07-01-2022



Answer 11

def package_contents(package_name):
  package = __import__(package_name)
  return [module_name for module_name in dir(package) if not module_name.startswith("__")]

Answered by: Anna463 | Posted: 07-01-2022



Similar questions

Most useful Python modules from the standard library?

Closed. This question is opinion-based. It is not c...


I can't load the modules from the standard library in python

The problem is only in visual studio and atom, in the python IDLE my code runs perfectly. When I try to import the math module and call the sqrt function it doesn't work and I only get the error: "AttributeError: module 'math' has no attribute 'sqrt'" I tried reinstalling python and pip but the same problem came up again. First I though the problem was with atom...


Where are the standard python modules located?

Where are the standard python modules located? I'm talking about the random, turtle, etc. modules.


What's a standard way to do a no-op in python?

I often find myself writing if / elif / else constructs in python, and I want to include options which can occur, but for which the corresponding action is to do nothing. I realise I could just exclude those if statements, but for readability I find it helps to include them all, so that if you are looking through the code you can see what happens as a result of each option. How do I code the no-op? Currently, I'm doing it ...


python - Standard Django way for letting users edit rich content

I have a Django website in which I want site administrators to be able to edit rich content. Suppose we're talking about an organizational info page, which might include some pictures, and some links, where the page is not as structured as a news page (which updates with news pieces every few days), but still needs the ability to be easily edited by site admins which do not necessarily want to mess with HTML (or rather, I ...


python - Simple List of All Java Standard Classes and Methods?

I'm building a very simple Java parser, to look for some specific usage models. This is in no way lex/yacc or any other form of interpreter/compiler for puposes of running the code. When I encounter a word or a set of two words separated by a dot ("word.word"), I would like to know if that's a standard Java class (and method), e.g. "Integer", or some user defined name. I'm not interested in whether the proper clas...


python - How to use standard toolbar icons with WxPython?

I'm designing a simple text editor using WxPython, and I want to put the platform's native icons in the toolbar. It seems that the only way to make toolbars is with custom images, which are not good for portability. Is there some kind of (e.g.) GetSaveIcon()?


python - Standard Solution for Decoding Additive Numbers

From the Oracle docs. A number representing one or more statistics class. The following class numbers are additive: 1 - User 2 - Redo 4 - Enqueue 8 - Cache 16 - OS 32 - Real Application Clusters 64 - SQL 128 - Debug It there a standard solution for taking say 22 and decoding that into 16, 4, and 2? My first guess would be to create an ob...


audio - System standard sound in Python

How play standard system sounds from a Python script? I'm writing a GUI program in wxPython that needs to beep on events to attract user's attention, maybe there are functions in wxPython I can utilize?


Most useful Python modules from the standard library?

Closed. This question is opinion-based. It is not c...


python - parsing a text string for dates - not the standard convert problem!

Does anyone know of a library - ideally Python, that can have a stab at pulling dates out of text? "Shall we go to the library today" -> 21 Jan 10 "Starting on the 1st of January" -> 1 Jan 10 "Anytime between 3nd and 5th of Feb 2009" -> 3 Feb 09, 5 Feb 09 It's a tough problem and probably why I havn't found anything! Already using NLTK by the way if that helps.


sqlite - Is there are standard way to store a database schema outside a python app

I am working on a small database application in Python (currently targeting 2.5 and 2.6) using sqlite3. It would be helpful to be able to provide a series of functions that could setup the database and validate that it matches the current schema. Before I reinvent the wheel, I thought I'd look around for libraries that would provide something similar. I'd love to have something akin to RoR's migrations.


stdin - Is it possible to access the source code of a python script passed to python on standard in?

This is a bit of a random question that is more out of curiosity than any specific need. Is it possible to write some python code that will print some stuff out, including the source code itself, without having the python code stored in a file? For example, doing something like this at the Bash prompt: $ echo ' &gt; print "The Code:" &gt; PrintScript() # What would this function look like? &gt; for...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top