Skip to content

pkgutil

The Python pkgutil module provides utilities for Python’s import system with a focus on package support. It lets you discover installed modules, walk package hierarchies, read binary data files bundled inside a package, and resolve dotted name strings to live Python objects:

Language: Python
>>> import pkgutil

>>> pkgutil.resolve_name("json:dumps")
<function dumps at 0x7f1a9c4d2fb0>

Key Features

  • Discovers modules and subpackages on a given search path
  • Walks recursively through a package hierarchy to list every submodule
  • Reads binary resources stored next to a package’s code
  • Resolves dotted or package:object strings to Python objects
  • Extends a package’s __path__ so one logical package can live in several directories

Frequently Used Classes and Functions

Object Type Description
pkgutil.iter_modules() Function Yields ModuleInfo entries for modules found on a given path
pkgutil.walk_packages() Function Recursively yields ModuleInfo for all submodules reachable from a path
pkgutil.get_data() Function Returns the contents of a resource file inside a package as bytes
pkgutil.resolve_name() Function Resolves a dotted or package:object string to a Python object
pkgutil.extend_path() Function Extends a package’s __path__ to support split package layouts
pkgutil.ModuleInfo Class Stores a finder, module name, and package flag as a named tuple

Examples

Listing the submodules of the standard library json package:

Language: Python
>>> import json
>>> import pkgutil

>>> for info in pkgutil.iter_modules(json.__path__, prefix="json."):
...     print(info.name)
...
json.__main__
json.decoder
json.encoder
json.scanner
json.tool

Reading a binary resource bundled with an installed package:

Language: Python
>>> import pkgutil

>>> data = pkgutil.get_data("email", "architecture.rst")
>>> type(data)
<class 'bytes'>
>>> data[:40]
b':mod:`email` Package Architecture\n======'

Resolving a name string to the corresponding Python object:

Language: Python
>>> import pkgutil

>>> pkgutil.resolve_name("os.path")
<module 'posixpath' (frozen)>
>>> dumps = pkgutil.resolve_name("json:dumps")
>>> dumps({"ok": True})
'{"ok": true}'

Common Use Cases

The most common tasks for pkgutil include:

  • Discovering plugins installed under a namespace package
  • Building command line tools that enumerate installed subcommands
  • Loading callables referenced by string in configuration files
  • Reading templates, schemas, or other data files shipped alongside a package
  • Distributing a single logical package across multiple directories on sys.path

Real-World Example

Consider a small application that loads plugins from a plugins subpackage without hard-coding their names. You can use pkgutil.iter_modules() to find every submodule and importlib.import_module() to load each one:

Language: Python Filename: plugin_loader.py
import importlib
import pkgutil

import myapp.plugins

def load_plugins():
    plugins = {}
    for info in pkgutil.iter_modules(
        myapp.plugins.__path__, prefix="myapp.plugins."
    ):
        plugins[info.name] = importlib.import_module(info.name)
    return plugins

if __name__ == "__main__":
    for name in load_plugins():
        print("Loaded", name)

Running the script prints every module that lives inside myapp/plugins/:

Language: Shell
$ python plugin_loader.py
Loaded myapp.plugins.csv_export
Loaded myapp.plugins.json_export

Any new file added to the plugins directory becomes available without editing the loader, which makes pkgutil a simple foundation for extensible Python applications.

Tutorial

What's a Python Namespace Package, and What's It For?

In this tutorial, you'll be exploring Python namespace packages: what they are, what they're for, and how you can use them in your package systems. Along the way, you'll create your own set of namespace packages and explore how you might be able to use them in your own projects.

advanced python

For additional information on related topics, take a look at the following resources:


By Leodanis Pozo Ramos • Updated May 8, 2026