Skip to main content

Runtime capability registry for optional Python dependencies

Project description

Pantry

PyPI version Tests codecov Documentation Python 3.11+ License Code style: ruff

Pantry is a runtime capability registry for optional Python dependencies. It discovers dependency groups from your pyproject.toml, probes which packages are actually installed, and gives you a clean API to check availability, import modules safely, and guard functions with decorators.

Why Pantry?

When your library supports optional features powered by third-party packages, you need to:

Problem Without Pantry With Pantry
Check if a package is installed try: import pkg scattered everywhere pantry.has("pkg")
Import with fallback Repeated try/except blocks pantry.get("pkg")
Fail with clear message Custom error handling per feature pantry["pkg"] raises with install instructions
Guard a function Manual checks at every entry point @pantry("pkg1", "pkg2")
Show what's available Roll your own reporting pantry.report()

Zero configuration — just declare optional dependencies in pyproject.toml as you normally would.

Installation

pip install mypantry

Only runtime dependency: packaging (454 KB, zero transitive deps, already present in most Python environments).

Quick Start

import pantry

# Strict import — raises RuntimeError with install instructions if missing
PIL = pantry["pillow"]
img = PIL.Image.open("photo.jpg")

# Safe import — returns None (or a custom default) if missing
np = pantry.get("numpy")
redis = pantry.get("redis", None)

# Check availability (single or multiple)
if pantry.has("pillow"):
    ...
if pantry.has("numpy", "pandas"):  # all must be available
    ...

# Guard a function — fails at call-time, not import-time
@pantry("numpy", "pandas")
def analyze(data):
    import numpy as np
    import pandas as pd
    ...

# See what's available
print(pantry.report())

Output of report():

pantry report
──────────────────────────────────────────────────────
group     package  module  version  ok
imaging   pillow   PIL     10.4.0   ✓
imaging   wand     wand    -        ✗
data      numpy    numpy   1.26.4   ✓
data      pandas   pandas  2.1.4    ✓
──────────────────────────────────────────────────────
available: 3/4

How It Works

Pantry reads your standard pyproject.toml optional dependencies:

[project.optional-dependencies]
imaging = ["pillow>=10.0", "wand"]
data = ["numpy>=1.24", "pandas>=2.0"]
cache = ["redis>=5.0"]

When you import pantry, the module:

  1. Walks up from cwd to find pyproject.toml
  2. Reads [project.optional-dependencies]
  3. Probes each package (installed? importable? version?)
  4. Replaces itself with a Pantry instance — so you use it directly

Smart module name resolution handles the pip-name-to-import-name mapping automatically (pillowPIL, scikit-learnsklearn, etc.).

Explicit Construction

When you need to target a specific pyproject.toml:

from pantry import Pantry

p = Pantry.from_pyproject("path/to/pyproject.toml")
p = Pantry.discover(start="/my/project")

Lazy Import — Breaking Circular Dependencies

Pantry has a second, independent feature for your own project modules: deferred imports that break circular dependency chains.

# module_a.py — module_b imports module_a, so direct import would cycle
import pantry

pantry.lazy_import("myapp.module_b.Helper")

class Service:
    def run(self):
        Helper = pantry["myapp.module_b.Helper"]  # import happens here
        return Helper()

lazy_import just registers the name — no import occurs. The actual import happens on first pantry["..."] access, when all modules are fully loaded. Results are cached.

This is a bridge toward PEP 690 (Lazy Imports).

Note: Lazy imports are separate from external dependencies. has(), get(), report() only know about pyproject.toml packages.

API Summary

External Dependencies (pyproject.toml)

Syntax Description
pantry["pkg"] Import module; raise RuntimeError if missing
pantry.get("pkg") Import module; return None if missing
pantry.get("pkg", default) Import module; return default if missing
pantry.has("pkg") True if installed and importable
pantry.has("p1", "p2") True if all are available
pantry.has_group("grp") True if any in group is available
@pantry("p1", "p2") Decorator; RuntimeError at call-time if missing
pantry.report() Formatted availability table
Pantry.discover() Explicit construction from auto-discovered pyproject.toml
Pantry.from_pyproject(path) Explicit construction from a specific file

Lazy Import (own modules)

Syntax Description
pantry.lazy_import("a.b.C") Register for deferred import
pantry["a.b.C"] Resolve on first access (cached)

Key Features

  1. Zero config — reads standard pyproject.toml, no extra files or setup
  2. Module-as-instanceimport pantry gives you a ready-to-use object
  3. Smart resolution — pip names mapped to import names automatically
  4. Multiple access patterns — strict ([]), safe (.get()), check (.has())
  5. Decorator guards — fail at call-time with clear install instructions
  6. Group awareness — check entire dependency groups at once
  7. Lazy import — break circular dependencies in your own modules
  8. Availability report — formatted table for diagnostics
  9. Fully typed — PEP 561 py.typed marker included

Documentation

Full documentation: mypantry.readthedocs.io

Testing

pip install mypantry[dev]
pytest

Repository Structure

genro-pantry/
├── src/pantry/
│   ├── __init__.py       # Module-as-instance bootstrap
│   ├── _discovery.py     # pyproject.toml discovery and parsing
│   ├── _probe.py         # Package probing and module name resolution
│   ├── _registry.py      # Pantry class (query, decorator, report)
│   └── py.typed          # PEP 561 marker
├── tests/
├── docs/
├── pyproject.toml
└── LICENSE

Project Status

  • Status: Alpha
  • Python: 3.11, 3.12, 3.13
  • License: Apache 2.0

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

License

Copyright 2025 Softwell S.r.l. — Licensed under the Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mypantry-0.2.0.tar.gz (27.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mypantry-0.2.0-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file mypantry-0.2.0.tar.gz.

File metadata

  • Download URL: mypantry-0.2.0.tar.gz
  • Upload date:
  • Size: 27.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mypantry-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a18b0f93a1085133989c7c391971eb0e385cfe829729d1bb9ee79c2461cbfe75
MD5 c8cf3aab75f1f56474af1d88efc26ae0
BLAKE2b-256 a813f1d21c49b1876891ee0dff9fb895d415edbf36ee6b03d68a85ca79d3e5c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for mypantry-0.2.0.tar.gz:

Publisher: publish.yml on genropy/genro-pantry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mypantry-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mypantry-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 14.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mypantry-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3d43090df46499c7375882d78af4ee5321aebd990c4818257525895742dd637c
MD5 bbe8d90a134ba55e9b7464010d4bf83c
BLAKE2b-256 1f7b78f1475f4c883ec4cd6b044b53963c111ac9600a22f3b5c4203182c66230

See more details on using hashes here.

Provenance

The following attestation bundles were made for mypantry-0.2.0-py3-none-any.whl:

Publisher: publish.yml on genropy/genro-pantry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page