Skip to content

Commit

Permalink
Merge pull request #35 from modern-python/24-feature-add-object-provider
Browse files Browse the repository at this point in the history
add object provider
  • Loading branch information
lesnik512 authored Jan 24, 2025
2 parents 46eda28 + 3cdca60 commit 3dc8c4d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
providers/factories
providers/collections
providers/context-providers
providers/object
.. toctree::
:maxdepth: 1
Expand Down
15 changes: 15 additions & 0 deletions docs/providers/object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Object

Object provider returns an object “as is”.

```python
from modern_di import BaseGraph, Container, Scope, providers


class Dependencies(BaseGraph):
object_provider = providers.Object(Scope.APP, 1)


with Container(scope=Scope.APP) as container:
assert Dependencies.object_provider.sync_resolve(container) == 1
```
2 changes: 2 additions & 0 deletions packages/modern-di/modern_di/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from modern_di.providers.dict import Dict
from modern_di.providers.factory import Factory
from modern_di.providers.list import List
from modern_di.providers.object import Object
from modern_di.providers.resource import Resource
from modern_di.providers.selector import Selector
from modern_di.providers.singleton import Singleton
Expand All @@ -16,6 +17,7 @@
"Dict",
"Factory",
"List",
"Object",
"Resource",
"Selector",
"Singleton",
Expand Down
27 changes: 27 additions & 0 deletions packages/modern-di/modern_di/providers/object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import enum
import typing

from modern_di import Container
from modern_di.providers.abstract import AbstractOverrideProvider


T_co = typing.TypeVar("T_co", covariant=True)
P = typing.ParamSpec("P")


class Object(AbstractOverrideProvider[T_co]):
__slots__ = [*AbstractOverrideProvider.BASE_SLOTS, "_obj"]

def __init__(self, scope: enum.IntEnum, obj: T_co) -> None:
super().__init__(scope)
self._obj: typing.Final = obj

async def async_resolve(self, container: Container) -> T_co:
return self.sync_resolve(container)

def sync_resolve(self, container: Container) -> T_co:
container = container.find_container(self.scope)
if (override := container.fetch_override(self.provider_id)) is not None:
return typing.cast(T_co, override)

return self._obj
29 changes: 29 additions & 0 deletions packages/modern-di/tests_core/providers/test_object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from modern_di import Container, Scope, providers


instance = ["some item"]


object_provider = providers.Object(Scope.APP, instance)


async def test_object_provider() -> None:
async with Container(scope=Scope.APP) as app_container:
instance1 = await object_provider.async_resolve(app_container)
instance2 = object_provider.sync_resolve(app_container)

assert instance1 is instance2 is instance


async def test_object_provider_overridden() -> None:
async with Container(scope=Scope.APP) as app_container:
instance1 = await object_provider.async_resolve(app_container)

object_provider.override(["override"], container=app_container)

instance2 = await object_provider.async_resolve(app_container)
instance3 = object_provider.sync_resolve(app_container)

assert instance1 is instance
assert instance2 is not instance
assert instance2 is instance3

0 comments on commit 3dc8c4d

Please sign in to comment.