0004: Discovery through packages, entry points and pluggy¶
Context and Problem Statement¶
Modules must be found without manual registration, both inside Heinzelmännchen and in independently installed plugins, and a broken plugin must never break Heinzelmännchen.
Considered Options¶
- Walk declaring packages and
heinzel.modulesentry points; register with pluggy (chosen) - One entry point per command: ties plugins to the CLI head.
- Scanning
sys.modulesfor subclasses: implicit and order-dependent.
Decision Outcome¶
Chosen option: discovery through packages, entry points and pluggy, because built-ins and plugins share one mechanism and pluggy is already familiar to plugin authors.
- The kernel walks
heinzel.modulesand every package named by an entry point in theheinzel.modulesgroup. A declaring package is a module; its qualified name follows the nearest declaring ancestor. Packages starting with_are skipped. - Modules are registered with a pluggy plugin manager under their qualified name;
lets flow through the
heinzel_letshook.HZ_DISABLED_MODULESblocks modules and their submodules;HZ_PLUGINS_ENABLED=falseskips entry points entirely. - Plugin import errors are collected and shown by
hz system info; built-in errors raise, because they are bugs.
Consequences¶
- Good: one mechanism for built-ins and plugins. Plugins can have submodules too.
- Good: pluggy gives us blocking, introspection and room for lifecycle hooks without inventing a plugin manager. pytest and Datasette use the same combination (pluggy + entry points), which keeps Heinzelmännchen familiar to plugin authors.
Confirmation¶
tests/integration/discovery_test.py (test_walks_nested_packages_and_skips_private_ones),
tests/unit/kernel/discovery_test.py (test_broken_plugins_are_reported_not_raised, test_plugins_can_be_skipped)
and tests/unit/kernel/kernel_test.py::test_disabled_modules_and_their_submodules_are_blocked.