Skip to content
misutPublic

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

33 Commits

Folders and files

Repository files navigation

Prion

A dependency injection framework using pure Python. No external dependencies.

Installation

pip install prion

Usage

Define a container by subclassing Syringe and declaring dependencies with single[T]() or factory[T]().

>>> from prion import Syringe, single, factory

>>> class AppSyringe(Syringe):
...     config = single[dict]()
...     session = factory[dict]()

Create an instance and register providers using decorators.

>>> syringe = AppSyringe()

>>> @syringe.config
... def create_config() -> dict:
...     return {"debug": True}

>>> @syringe.session
... def create_session() -> dict:
...     return {}

Access dependencies as attributes.

>>> syringe.config is syringe.config
True

>>> syringe.session is not syringe.session
True

Dependency Wiring

Providers can receive other dependencies as parameters. Parameter names are matched to dependency names automatically.

>>> class WiredSyringe(Syringe):
...     config = single[dict]()
...     greeting = single[str]()

>>> syringe = WiredSyringe()

>>> @syringe.config
... def create_config() -> dict:
...     return {"name": "world"}

>>> @syringe.greeting
... def create_greeting(config: dict) -> str:
...     return f"hello {config['name']}"

>>> syringe.greeting
'hello world'

Circular dependencies are detected at resolve time with a RuntimeError.

Eager Initialization

Use warm() to resolve all dependencies upfront. This validates that every provider is registered and detects circular dependencies at boot time.

>>> syringe = AppSyringe()

>>> @syringe.config
... def create_config() -> dict:
...     return {"debug": True}

>>> @syringe.session
... def create_session() -> dict:
...     return {}

>>> syringe.warm()

Lifecycle

Use reset() to clear all cached singletons, or use the container as a context manager.

>>> syringe = AppSyringe()

>>> @syringe.config
... def create_config() -> dict:
...     return {"debug": True}

>>> with syringe:
...     _ = syringe.config
...
>>> # singleton cache is cleared after exiting the context

Testing

Use override() to temporarily replace a provider in tests.

>>> syringe = AppSyringe()

>>> @syringe.config
... def create_config() -> dict:
...     return {"debug": True}

>>> syringe.config
{'debug': True}

>>> with syringe.override("config", lambda: {"debug": False}):
...     syringe.config
{'debug': False}

>>> syringe.config
{'debug': True}

Strategies

Strategy Behavior
single[T]() Creates once, returns cached
factory[T]() Creates a new instance each time

License

MIT

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages