Install & Compatibility
Where this runs
tested against v0.24.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.058s · 17.9MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.5s · import 0.056s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Injector
✓ from injector import Injector
The core class for managing bindings and resolving dependencies.
inject
✓ from injector import inject
✗ @inject(dependency=DependencyType)
As of Injector 0.11+, the `@inject` decorator no longer supports keyword arguments for declaring bindings and should primarily be used on class constructors to signal dependencies via type hints. [12, 13]
Module
✓ from injector import Module
Used to group related bindings and configurations.
provider
✓ from injector import provider
✗ @provides
The `@provides` decorator was removed in earlier versions; use `@provider` instead for methods within a Module that provide dependencies. [13]
singleton
✓ from injector import singleton
Decorator or scope to ensure a single instance of a class is provided across the injector's lifecycle. [4]
Key
✓ from injector import Key
Used for binding types with annotations to uniquely identify providers, especially for generic types like `str` or when multiple implementations of an interface exist. [4]
This quickstart demonstrates how to set up basic dependency injection using `injector`. It defines `Config`, `DatabaseConnection` (as a singleton), and `Service` classes. A `Module` is used to provide the `Config` instance, including a placeholder for environment variable-driven configuration. The `Injector` then resolves and provides instances, showcasing constructor injection with type hints. [4, 10, 11]
from injector import Injector, inject, singleton, Module, provider
class Config:
def __init__(self, value: str = "default"):
self.value = value
@singleton
class DatabaseConnection:
def __init__(self, config: Config):
self.config = config
# Simulate a connection based on config
self.status = f"Connected to DB with {self.config.value}"
class Service:
@inject
def __init__(self, db: DatabaseConnection):
self.db = db
class MyModule(Module):
@singleton
@provider
def provide_config(self) -> Config:
# In a real app, this might come from env vars or a file
env_val = os.environ.get('APP_CONFIG_VALUE', 'configured_via_module')
return Config(value=env_val)
def main():
injector = Injector([MyModule])
service = injector.get(Service)
print(service.db.status)
if __name__ == "__main__":
import os
# os.environ['APP_CONFIG_VALUE'] = 'production_setting' # Uncomment to test env var injection
main()
Debug
Known issues
breakingInjector 0.24.0 dropped Python 2 wheel support. The library now officially supports CPython 3.10+ and PyPy 3. Additionally, version 0.25.0 (upcoming) will drop support for Python 3.8 and 3.9. Users on older Python versions will need to upgrade. [3, 13, 20]fixUpgrade to Python 3.10 or newer. Check the official documentation for the latest Python compatibility matrix when upgrading 'injector'.
affects: 0.24.0, 0.25.0 (upcoming)
breakingIn `0.23.0`, the scoping behavior of `multibind()` changed. Previously, the scope applied to the entire collection (e.g., `list` or `dict` instance). Now, the scope applies to the individual bound types *within* the collection. This can lead to unexpected behavior if relying on the old scoping mechanism. [13, 20]fixReview `multibind()` usages and adjust code to reflect that scopes are now applied per-item within the collection. If the old behavior is desired, custom scoping might be necessary.
affects: >=0.23.0
deprecatedSupport for passing keyword arguments to `@inject` (e.g., `@inject(some_dep=SomeType)`) was deprecated in 0.11+ and subsequently removed. Similarly, injecting into non-constructor methods was also removed. `@inject` should now be used on class constructors with type hints. [12, 13]fixRemove keyword arguments from `@inject` decorators and rely on type hints for dependency declaration in constructors. Avoid using `@inject` on non-constructor methods.
affects: <0.11 (deprecated), >=0.11 (removed)
gotchaInjector instances maintain no global state. Attempting to directly instantiate a class with injected dependencies (e.g., `MyClass()`) will fail if the class expects dependencies to be provided by an `Injector`. You must explicitly obtain instances via `injector.get()` or `injector.create_object()`. [3, 10, 19]fixAlways retrieve dependency-injected objects from an `Injector` instance using `injector.get(MyClass)` or `injector.create_object(MyClass)`.
affects: All versions
gotchaAvoid performing I/O or other long-running, blocking operations within `Module.configure` methods or `@provider` functions. The `Injector`'s internal state is protected by a lock, meaning such operations can block other threads attempting to resolve dependencies, potentially leading to performance issues or deadlocks. [12]fixMinimize logic within module configuration and provider methods. If resources need to be acquired, ensure they are fast or manage their lifecycle externally if blocking calls are unavoidable.
affects: All versions
gotchaThere are two popular dependency injection libraries in Python with similar names: `injector` and `dependency-injector`. They are distinct libraries with different APIs and approaches. Ensure you are using the correct library's documentation and patterns for `injector` to avoid confusion. [11, 14, 15]fixVerify that you are importing from `injector` and referring to its specific documentation when developing or troubleshooting.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'injector'
The `injector` library is not installed in the Python environment or the environment where the code is being run.
fixInstall the library using pip: `pip install injector`
injector.errors.NoProviderFound: No provider for X
The injector could not find a binding for the requested type `X`. This means you've asked the injector to provide an instance of `X`, but haven't told it how to create one through a binding or a `@provider` decorated method.
fixYou need to define a binding for the type `X`. This can be done by using `binder.bind(X, to=Y)` where `Y` is the class to provide, or by decorating a method in a `Module` with `@provider` that returns an instance of `X`.
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType' (when using pydantic BaseSettings with injector)
This error occurs with Python 3.8 and 3.9 when `injector.Injector.create_object` attempts to instantiate Pydantic `BaseSettings` classes that use `PEP-604` style union type hints (e.g., `str | None`). Pydantic's `BaseSettings` base class has initialization characteristics that are incompatible with `injector`'s direct object creation mechanism for these Python versions, but it works correctly on Python 3.10 and newer.
fixFor Python 3.8/3.9, provide a factory function for the `BaseSettings` class to `injector`. For example, `binder.bind(Settings, to=Settings)` in a module, or upgrade to Python 3.10 or higher.
injector.errors.CircularDependencyError: Circular dependency detected: X -> Y -> X
This error indicates that two or more objects have a mutual dependency, forming a loop that the injector cannot resolve. For example, if class `X` requires `Y`, and class `Y` also requires `X`.
fixRefactor your code to break the circular dependency. This often involves introducing an interface, delaying the resolution of one dependency, or passing a factory/provider for one of the types instead of the type itself.
RuntimeError: Working outside of request context (often seen with Flask or similar frameworks)
This error isn't directly from `injector` but occurs when `injector` tries to resolve dependencies that require an active application or request context, which is common in web frameworks like Flask, and the injection happens outside of such a context.
fixEnsure that dependency injection (especially calls to `injector.get()` or methods that trigger injection) happens within an active application or request context provided by your web framework. For Flask, this might involve using `app.app_context()` or `app.test_request_context()` for manual wiring or testing.
Upgrade
Version history
0.24.0latest on PyPI · released Jan 9, 2026
Audit
Dependencies
No dependency data recorded yet.