mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 19:14:00 +03:00
Dict provider (#311)
* Add tests * Add implementation and typing stubs * Update README and docs pages * Add example and docs * Update changelog * Add long description to the doc block
This commit is contained in:
parent
5c1486e1a3
commit
b54bcb7b31
|
@ -57,8 +57,9 @@ It helps implementing the dependency injection principle.
|
||||||
Key features of the ``Dependency Injector``:
|
Key features of the ``Dependency Injector``:
|
||||||
|
|
||||||
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
||||||
``List``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help assembling your
|
``List``, ``Dict``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help
|
||||||
objects. See `Providers <https://python-dependency-injector.ets-labs.org/providers/index.html>`_.
|
assembling your objects.
|
||||||
|
See `Providers <https://python-dependency-injector.ets-labs.org/providers/index.html>`_.
|
||||||
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
||||||
and configuring dev / stage environment to replace API clients with stubs etc. See
|
and configuring dev / stage environment to replace API clients with stubs etc. See
|
||||||
`Provider overriding <https://python-dependency-injector.ets-labs.org/providers/overriding.html>`_.
|
`Provider overriding <https://python-dependency-injector.ets-labs.org/providers/overriding.html>`_.
|
||||||
|
|
|
@ -69,8 +69,8 @@ It helps implementing the dependency injection principle.
|
||||||
Key features of the ``Dependency Injector``:
|
Key features of the ``Dependency Injector``:
|
||||||
|
|
||||||
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
||||||
``List``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help assembling your
|
``List``, ``Dict``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help
|
||||||
objects. See :ref:`providers`.
|
assembling your objects. See :ref:`providers`.
|
||||||
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
||||||
and configuring dev / stage environment to replace API clients with stubs etc. See
|
and configuring dev / stage environment to replace API clients with stubs etc. See
|
||||||
:ref:`provider-overriding`.
|
:ref:`provider-overriding`.
|
||||||
|
|
|
@ -11,8 +11,8 @@ Key features
|
||||||
Key features of the ``Dependency Injector``:
|
Key features of the ``Dependency Injector``:
|
||||||
|
|
||||||
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
||||||
``List``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help assembling your
|
``List``, ``Dict``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help
|
||||||
objects. See :ref:`providers`.
|
assembling your objects. See :ref:`providers`.
|
||||||
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
||||||
and configuring dev / stage environment to replace API clients with stubs etc. See
|
and configuring dev / stage environment to replace API clients with stubs etc. See
|
||||||
:ref:`provider-overriding`.
|
:ref:`provider-overriding`.
|
||||||
|
|
|
@ -9,6 +9,7 @@ follows `Semantic versioning`_
|
||||||
|
|
||||||
Develop
|
Develop
|
||||||
-------
|
-------
|
||||||
|
- Add ``Dict`` provider.
|
||||||
- "Un-deprecate" ``@containers.override()`` and ``@containers.copy()`` decorators (
|
- "Un-deprecate" ``@containers.override()`` and ``@containers.copy()`` decorators (
|
||||||
see `Issue 301 <https://github.com/ets-labs/python-dependency-injector/issues/301>`_
|
see `Issue 301 <https://github.com/ets-labs/python-dependency-injector/issues/301>`_
|
||||||
for more information).
|
for more information).
|
||||||
|
|
23
docs/providers/dict.rst
Normal file
23
docs/providers/dict.rst
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Dict provider
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. meta::
|
||||||
|
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Dict,Injection
|
||||||
|
:description: Dict provider helps to inject a dictionary of the dependencies. This page demonstrates
|
||||||
|
how to use Dict provider.
|
||||||
|
|
||||||
|
.. currentmodule:: dependency_injector.providers
|
||||||
|
|
||||||
|
:py:class:`Dict` provider provides a dictionary of values.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/providers/dict.py
|
||||||
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
:emphasize-lines: 21-24
|
||||||
|
|
||||||
|
``Dict`` provider handles keyword arguments the same way as a :ref:`factory-provider`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Positional argument are not supported.
|
||||||
|
|
||||||
|
.. disqus::
|
|
@ -43,6 +43,7 @@ Providers module API docs - :py:mod:`dependency_injector.providers`
|
||||||
coroutine
|
coroutine
|
||||||
object
|
object
|
||||||
list
|
list
|
||||||
|
dict
|
||||||
configuration
|
configuration
|
||||||
selector
|
selector
|
||||||
dependency
|
dependency
|
||||||
|
|
45
examples/providers/dict.py
Normal file
45
examples/providers/dict.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
"""`Dict` provider example."""
|
||||||
|
|
||||||
|
import dataclasses
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class Module:
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class Dispatcher:
|
||||||
|
modules: Dict[str, Module]
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
dispatcher_factory = providers.Factory(
|
||||||
|
Dispatcher,
|
||||||
|
modules=providers.Dict(
|
||||||
|
module1=providers.Factory(Module, name='m1'),
|
||||||
|
module2=providers.Factory(Module, name='m2'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
dispatcher = container.dispatcher_factory()
|
||||||
|
|
||||||
|
assert isinstance(dispatcher.modules, dict)
|
||||||
|
assert dispatcher.modules['module1'].name == 'm1'
|
||||||
|
assert dispatcher.modules['module2'].name == 'm2'
|
||||||
|
|
||||||
|
# Call "dispatcher = container.dispatcher_factory()" is equivalent to:
|
||||||
|
# dispatcher = Dispatcher(
|
||||||
|
# modules={
|
||||||
|
# 'module1': Module(name='m1'),
|
||||||
|
# 'module2': Module(name='m2'),
|
||||||
|
# },
|
||||||
|
# )
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -184,6 +184,13 @@ cdef class List(Provider):
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
cdef class Dict(Provider):
|
||||||
|
cdef tuple __kwargs
|
||||||
|
cdef int __kwargs_len
|
||||||
|
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
cdef class Container(Provider):
|
cdef class Container(Provider):
|
||||||
cdef object __container_cls
|
cdef object __container_cls
|
||||||
cdef dict __overriding_providers
|
cdef dict __overriding_providers
|
||||||
|
|
|
@ -9,8 +9,8 @@ from typing import (
|
||||||
Any,
|
Any,
|
||||||
Tuple,
|
Tuple,
|
||||||
List as _List,
|
List as _List,
|
||||||
|
Dict as _Dict,
|
||||||
Optional,
|
Optional,
|
||||||
Dict,
|
|
||||||
Union,
|
Union,
|
||||||
Coroutine as _Coroutine,
|
Coroutine as _Coroutine,
|
||||||
)
|
)
|
||||||
|
@ -29,7 +29,7 @@ class OverridingContext:
|
||||||
class Provider(Generic[T]):
|
class Provider(Generic[T]):
|
||||||
def __init__(self) -> None: ...
|
def __init__(self) -> None: ...
|
||||||
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
||||||
def __deepcopy__(self, memo: Optional[Dict[Any, Any]]) -> Provider: ...
|
def __deepcopy__(self, memo: Optional[_Dict[Any, Any]]) -> Provider: ...
|
||||||
def __str__(self) -> str: ...
|
def __str__(self) -> str: ...
|
||||||
def __repr__(self) -> str: ...
|
def __repr__(self) -> str: ...
|
||||||
@property
|
@property
|
||||||
|
@ -44,7 +44,7 @@ class Provider(Generic[T]):
|
||||||
def provider(self) -> Provider: ...
|
def provider(self) -> Provider: ...
|
||||||
@property
|
@property
|
||||||
def provided(self) -> ProvidedInstance: ...
|
def provided(self) -> ProvidedInstance: ...
|
||||||
def _copy_overridings(self, copied: Provider, memo: Optional[Dict[Any, Any]]) -> None: ...
|
def _copy_overridings(self, copied: Provider, memo: Optional[_Dict[Any, Any]]) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class Object(Provider, Generic[T]):
|
class Object(Provider, Generic[T]):
|
||||||
|
@ -74,7 +74,7 @@ class DependenciesContainer(Object):
|
||||||
def __init__(self, **dependencies: Provider) -> None: ...
|
def __init__(self, **dependencies: Provider) -> None: ...
|
||||||
def __getattr__(self, name: str) -> Provider: ...
|
def __getattr__(self, name: str) -> Provider: ...
|
||||||
@property
|
@property
|
||||||
def providers(self) -> Dict[str, Provider]: ...
|
def providers(self) -> _Dict[str, Provider]: ...
|
||||||
|
|
||||||
|
|
||||||
class Callable(Provider, Generic[T]):
|
class Callable(Provider, Generic[T]):
|
||||||
|
@ -88,7 +88,7 @@ class Callable(Provider, Generic[T]):
|
||||||
def set_args(self, *args: Injection) -> Callable[T]: ...
|
def set_args(self, *args: Injection) -> Callable[T]: ...
|
||||||
def clear_args(self) -> Callable[T]: ...
|
def clear_args(self) -> Callable[T]: ...
|
||||||
@property
|
@property
|
||||||
def kwargs(self) -> Dict[str, Injection]: ...
|
def kwargs(self) -> _Dict[str, Injection]: ...
|
||||||
def add_kwargs(self, **kwargs: Injection) -> Callable[T]: ...
|
def add_kwargs(self, **kwargs: Injection) -> Callable[T]: ...
|
||||||
def set_kwargs(self, **kwargs: Injection) -> Callable[T]: ...
|
def set_kwargs(self, **kwargs: Injection) -> Callable[T]: ...
|
||||||
def clear_kwargs(self) -> Callable[T]: ...
|
def clear_kwargs(self) -> Callable[T]: ...
|
||||||
|
@ -135,7 +135,7 @@ class ConfigurationOption(Provider):
|
||||||
def update(self, value: Any) -> None: ...
|
def update(self, value: Any) -> None: ...
|
||||||
def from_ini(self, filepath: Union[Path, str]) -> None: ...
|
def from_ini(self, filepath: Union[Path, str]) -> None: ...
|
||||||
def from_yaml(self, filepath: Union[Path, str]) -> None: ...
|
def from_yaml(self, filepath: Union[Path, str]) -> None: ...
|
||||||
def from_dict(self, options: Dict[str, Any]) -> None: ...
|
def from_dict(self, options: _Dict[str, Any]) -> None: ...
|
||||||
def from_env(self, name: str, default: Optional[Any] = None) -> None: ...
|
def from_env(self, name: str, default: Optional[Any] = None) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ class Configuration(Object):
|
||||||
def update(self, value: Any) -> None: ...
|
def update(self, value: Any) -> None: ...
|
||||||
def from_ini(self, filepath: Union[Path, str]) -> None: ...
|
def from_ini(self, filepath: Union[Path, str]) -> None: ...
|
||||||
def from_yaml(self, filepath: Union[Path, str]) -> None: ...
|
def from_yaml(self, filepath: Union[Path, str]) -> None: ...
|
||||||
def from_dict(self, options: Dict[str, Any]) -> None: ...
|
def from_dict(self, options: _Dict[str, Any]) -> None: ...
|
||||||
def from_env(self, name: str, default: Optional[Any] = None) -> None: ...
|
def from_env(self, name: str, default: Optional[Any] = None) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,12 +174,12 @@ class Factory(Provider, Generic[T]):
|
||||||
def set_args(self, *args: Injection) -> Factory[T]: ...
|
def set_args(self, *args: Injection) -> Factory[T]: ...
|
||||||
def clear_args(self) -> Factory[T]: ...
|
def clear_args(self) -> Factory[T]: ...
|
||||||
@property
|
@property
|
||||||
def kwargs(self) -> Dict[str, Injection]: ...
|
def kwargs(self) -> _Dict[str, Injection]: ...
|
||||||
def add_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
def add_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def set_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
def set_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def clear_kwargs(self) -> Factory[T]: ...
|
def clear_kwargs(self) -> Factory[T]: ...
|
||||||
@property
|
@property
|
||||||
def attributes(self) -> Dict[str, Injection]: ...
|
def attributes(self) -> _Dict[str, Injection]: ...
|
||||||
def add_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
def add_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def set_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
def set_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def clear_attributes(self) -> Factory[T]: ...
|
def clear_attributes(self) -> Factory[T]: ...
|
||||||
|
@ -201,7 +201,7 @@ class FactoryAggregate(Provider):
|
||||||
def __call__(self, factory_name: str, *args: Injection, **kwargs: Injection) -> Any: ...
|
def __call__(self, factory_name: str, *args: Injection, **kwargs: Injection) -> Any: ...
|
||||||
def __getattr__(self, factory_name: str) -> Factory: ...
|
def __getattr__(self, factory_name: str) -> Factory: ...
|
||||||
@property
|
@property
|
||||||
def factories(self) -> Dict[str, Factory]: ...
|
def factories(self) -> _Dict[str, Factory]: ...
|
||||||
|
|
||||||
|
|
||||||
class BaseSingleton(Provider, Generic[T]):
|
class BaseSingleton(Provider, Generic[T]):
|
||||||
|
@ -216,12 +216,12 @@ class BaseSingleton(Provider, Generic[T]):
|
||||||
def set_args(self, *args: Injection) -> Factory[T]: ...
|
def set_args(self, *args: Injection) -> Factory[T]: ...
|
||||||
def clear_args(self) -> Factory[T]: ...
|
def clear_args(self) -> Factory[T]: ...
|
||||||
@property
|
@property
|
||||||
def kwargs(self) -> Dict[str, Injection]: ...
|
def kwargs(self) -> _Dict[str, Injection]: ...
|
||||||
def add_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
def add_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def set_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
def set_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def clear_kwargs(self) -> Factory[T]: ...
|
def clear_kwargs(self) -> Factory[T]: ...
|
||||||
@property
|
@property
|
||||||
def attributes(self) -> Dict[str, Injection]: ...
|
def attributes(self) -> _Dict[str, Injection]: ...
|
||||||
def add_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
def add_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def set_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
def set_attributes(self, **kwargs: Injection) -> Factory[T]: ...
|
||||||
def clear_attributes(self) -> Factory[T]: ...
|
def clear_attributes(self) -> Factory[T]: ...
|
||||||
|
@ -264,6 +264,16 @@ class List(Provider):
|
||||||
def clear_args(self) -> List: ...
|
def clear_args(self) -> List: ...
|
||||||
|
|
||||||
|
|
||||||
|
class Dict(Provider):
|
||||||
|
def __init__(self, **kwargs: Injection): ...
|
||||||
|
def __call__(self, *args: Injection, **kwargs: Injection) -> _Dict[Any, Any]: ...
|
||||||
|
@property
|
||||||
|
def kwargs(self) -> _Dict[Any, Injection]: ...
|
||||||
|
def add_kwargs(self, **kwargs: Injection) -> Dict: ...
|
||||||
|
def set_kwargs(self, **kwargs: Injection) -> Dict: ...
|
||||||
|
def clear_kwargs(self) -> Dict: ...
|
||||||
|
|
||||||
|
|
||||||
class Container(Provider):
|
class Container(Provider):
|
||||||
|
|
||||||
def __init__(self, container_cls: Type[T], container: Optional[T] = None, **overriding_providers: Provider) -> None: ...
|
def __init__(self, container_cls: Type[T], container: Optional[T] = None, **overriding_providers: Provider) -> None: ...
|
||||||
|
@ -278,7 +288,7 @@ class Selector(Provider):
|
||||||
def __call__(self, *args: Injection, **kwargs: Injection) -> Any: ...
|
def __call__(self, *args: Injection, **kwargs: Injection) -> Any: ...
|
||||||
def __getattr__(self, name: str) -> Provider: ...
|
def __getattr__(self, name: str) -> Provider: ...
|
||||||
@property
|
@property
|
||||||
def providers(self) -> Dict[str, Provider]: ...
|
def providers(self) -> _Dict[str, Provider]: ...
|
||||||
|
|
||||||
|
|
||||||
class ProvidedInstanceFluentInterface:
|
class ProvidedInstanceFluentInterface:
|
||||||
|
@ -315,7 +325,7 @@ def is_delegated(instance: Any) -> bool: ...
|
||||||
def represent_provider(provider: Provider, provides: Any) -> str: ...
|
def represent_provider(provider: Provider, provides: Any) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
def deepcopy(instance: Any, memo: Optional[Dict[Any, Any]]): Any: ...
|
def deepcopy(instance: Any, memo: Optional[_Dict[Any, Any]] = None): Any: ...
|
||||||
|
|
||||||
|
|
||||||
def merge_dicts(dict1: Dict[Any, Any], dict2: Dict[Any, Any]) -> Dict[Any, Any]: ...
|
def merge_dicts(dict1: _Dict[Any, Any], dict2: _Dict[Any, Any]) -> _Dict[Any, Any]: ...
|
||||||
|
|
|
@ -2449,6 +2449,108 @@ cdef class List(Provider):
|
||||||
return list(__provide_positional_args(args, self.__args, self.__args_len))
|
return list(__provide_positional_args(args, self.__args, self.__args_len))
|
||||||
|
|
||||||
|
|
||||||
|
cdef class Dict(Provider):
|
||||||
|
"""Dict provider provides a dictionary of values.
|
||||||
|
|
||||||
|
:py:class:`Dict` provider is needed for injecting a dictionary of dependencies. It handles
|
||||||
|
keyword argument injections the same way as :py:class:`Factory` provider.
|
||||||
|
|
||||||
|
Positional argument injections are not supported.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
dispatcher_factory = Factory(
|
||||||
|
Dispatcher,
|
||||||
|
modules=Dict(
|
||||||
|
module1=Factory(ModuleA, dependency_a),
|
||||||
|
module2=Factory(ModuleB, dependency_b),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
dispatcher = dispatcher_factory()
|
||||||
|
|
||||||
|
# is equivalent to:
|
||||||
|
|
||||||
|
dispatcher = Dispatcher(
|
||||||
|
modules={
|
||||||
|
'module1': ModuleA(dependency_a),
|
||||||
|
'module2': ModuleB(dependency_b),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
"""Initializer."""
|
||||||
|
self.__kwargs = tuple()
|
||||||
|
self.__kwargs_len = 0
|
||||||
|
self.set_kwargs(**kwargs)
|
||||||
|
super(Dict, self).__init__()
|
||||||
|
|
||||||
|
def __deepcopy__(self, memo):
|
||||||
|
"""Create and return full copy of provider."""
|
||||||
|
copied = memo.get(id(self))
|
||||||
|
if copied is not None:
|
||||||
|
return copied
|
||||||
|
|
||||||
|
copied = self.__class__(**deepcopy(self.kwargs, memo))
|
||||||
|
self._copy_overridings(copied, memo)
|
||||||
|
|
||||||
|
return copied
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return string representation of provider.
|
||||||
|
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return represent_provider(provider=self, provides=dict(self.kwargs))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kwargs(self):
|
||||||
|
"""Return keyword argument injections."""
|
||||||
|
cdef int index
|
||||||
|
cdef NamedInjection kwarg
|
||||||
|
cdef dict kwargs
|
||||||
|
|
||||||
|
kwargs = dict()
|
||||||
|
for index in range(self.__kwargs_len):
|
||||||
|
kwarg = self.__kwargs[index]
|
||||||
|
kwargs[kwarg.__name] = kwarg.__value
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def add_kwargs(self, **kwargs):
|
||||||
|
"""Add keyword argument injections.
|
||||||
|
|
||||||
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self.__kwargs += parse_named_injections(kwargs)
|
||||||
|
self.__kwargs_len = len(self.__kwargs)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_kwargs(self, **kwargs):
|
||||||
|
"""Set keyword argument injections.
|
||||||
|
|
||||||
|
Existing keyword argument injections are dropped.
|
||||||
|
|
||||||
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self.__kwargs = parse_named_injections(kwargs)
|
||||||
|
self.__kwargs_len = len(self.__kwargs)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def clear_kwargs(self):
|
||||||
|
"""Drop keyword argument injections.
|
||||||
|
|
||||||
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self.__kwargs = tuple()
|
||||||
|
self.__kwargs_len = len(self.__kwargs)
|
||||||
|
return self
|
||||||
|
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
|
"""Return result of provided callable's call."""
|
||||||
|
return __provide_keyword_args(kwargs, self.__kwargs, self.__kwargs_len)
|
||||||
|
|
||||||
|
|
||||||
cdef class Container(Provider):
|
cdef class Container(Provider):
|
||||||
"""Container provider provides an instance of declarative container.
|
"""Container provider provides an instance of declarative container.
|
||||||
|
|
||||||
|
|
149
tests/unit/providers/test_dict_py2_py3.py
Normal file
149
tests/unit/providers/test_dict_py2_py3.py
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
"""Dependency injector dict provider unit tests."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import unittest2 as unittest
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
|
||||||
|
class DictTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_is_provider(self):
|
||||||
|
self.assertTrue(providers.is_provider(providers.Dict()))
|
||||||
|
|
||||||
|
def test_provided_instance_provider(self):
|
||||||
|
provider = providers.Dict()
|
||||||
|
self.assertIsInstance(provider.provided, providers.ProvidedInstance)
|
||||||
|
|
||||||
|
def test_call_with_init_keyword_args(self):
|
||||||
|
provider = providers.Dict(a1='i1', a2='i2')
|
||||||
|
|
||||||
|
dict1 = provider()
|
||||||
|
dict2 = provider()
|
||||||
|
|
||||||
|
self.assertEqual(dict1, {'a1': 'i1', 'a2': 'i2'})
|
||||||
|
self.assertEqual(dict2, {'a1': 'i1', 'a2': 'i2'})
|
||||||
|
|
||||||
|
self.assertIsNot(dict1, dict2)
|
||||||
|
|
||||||
|
def test_call_with_context_keyword_args(self):
|
||||||
|
provider = providers.Dict(a1='i1', a2='i2')
|
||||||
|
self.assertEqual(
|
||||||
|
provider(a3='i3', a4='i4'),
|
||||||
|
{'a1': 'i1', 'a2': 'i2', 'a3': 'i3', 'a4': 'i4'},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_call_with_provider(self):
|
||||||
|
provider = providers.Dict(
|
||||||
|
a1=providers.Factory(str, 'i1'),
|
||||||
|
a2=providers.Factory(str, 'i2'),
|
||||||
|
)
|
||||||
|
self.assertEqual(provider(), {'a1': 'i1', 'a2': 'i2'})
|
||||||
|
|
||||||
|
def test_fluent_interface(self):
|
||||||
|
provider = providers.Dict() \
|
||||||
|
.add_kwargs(a1='i1', a2='i2')
|
||||||
|
self.assertEqual(provider(), {'a1': 'i1', 'a2': 'i2'})
|
||||||
|
|
||||||
|
def test_set_kwargs(self):
|
||||||
|
provider = providers.Dict() \
|
||||||
|
.add_kwargs(a1='i1', a2='i2') \
|
||||||
|
.set_kwargs(a3='i3', a4='i4')
|
||||||
|
self.assertEqual(provider.kwargs, {'a3': 'i3', 'a4': 'i4'})
|
||||||
|
|
||||||
|
def test_clear_kwargs(self):
|
||||||
|
provider = providers.Dict() \
|
||||||
|
.add_kwargs(a1='i1', a2='i2') \
|
||||||
|
.clear_kwargs()
|
||||||
|
self.assertEqual(provider.kwargs, {})
|
||||||
|
|
||||||
|
def test_call_overridden(self):
|
||||||
|
provider = providers.Dict(a1='i1', a2='i2')
|
||||||
|
overriding_provider1 = providers.Dict(a2='i2', a3='i3')
|
||||||
|
overriding_provider2 = providers.Dict(a3='i3', a4='i4')
|
||||||
|
|
||||||
|
provider.override(overriding_provider1)
|
||||||
|
provider.override(overriding_provider2)
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
self.assertIsNot(instance1, instance2)
|
||||||
|
self.assertEqual(instance1, {'a3': 'i3', 'a4': 'i4'})
|
||||||
|
self.assertEqual(instance2, {'a3': 'i3', 'a4': 'i4'})
|
||||||
|
|
||||||
|
def test_deepcopy(self):
|
||||||
|
provider = providers.Dict(a1='i1', a2='i2')
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
self.assertIsNot(provider, provider_copy)
|
||||||
|
self.assertEqual(provider.kwargs, provider_copy.kwargs)
|
||||||
|
self.assertIsInstance(provider, providers.Dict)
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo(self):
|
||||||
|
provider = providers.Dict(a1='i1', a2='i2')
|
||||||
|
provider_copy_memo = providers.Dict(a1='i1', a2='i2')
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(
|
||||||
|
provider,
|
||||||
|
memo={id(provider): provider_copy_memo},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIs(provider_copy, provider_copy_memo)
|
||||||
|
|
||||||
|
def test_deepcopy_args(self):
|
||||||
|
provider = providers.Dict()
|
||||||
|
dependent_provider1 = providers.Factory(list)
|
||||||
|
dependent_provider2 = providers.Factory(dict)
|
||||||
|
|
||||||
|
provider.add_kwargs(d1=dependent_provider1, d2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.kwargs['d1']
|
||||||
|
dependent_provider_copy2 = provider_copy.kwargs['d2']
|
||||||
|
|
||||||
|
self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
|
||||||
|
|
||||||
|
self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
|
||||||
|
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
||||||
|
|
||||||
|
self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
|
||||||
|
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
||||||
|
|
||||||
|
def test_deepcopy_overridden(self):
|
||||||
|
provider = providers.Dict()
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
provider.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
self.assertIsNot(provider, provider_copy)
|
||||||
|
self.assertEqual(provider.kwargs, provider_copy.kwargs)
|
||||||
|
self.assertIsInstance(provider, providers.Dict)
|
||||||
|
|
||||||
|
self.assertIsNot(object_provider, object_provider_copy)
|
||||||
|
self.assertIsInstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
def test_deepcopy_with_sys_streams(self):
|
||||||
|
provider = providers.Dict()
|
||||||
|
provider.add_kwargs(stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
self.assertIsNot(provider, provider_copy)
|
||||||
|
self.assertIsInstance(provider_copy, providers.Dict)
|
||||||
|
self.assertIs(provider.kwargs['stdin'], sys.stdin)
|
||||||
|
self.assertIs(provider.kwargs['stdout'], sys.stdout)
|
||||||
|
self.assertIs(provider.kwargs['stderr'], sys.stderr)
|
||||||
|
|
||||||
|
def test_repr(self):
|
||||||
|
provider = providers.Dict(a1=1, a2=2)
|
||||||
|
self.assertEqual(repr(provider),
|
||||||
|
'<dependency_injector.providers.'
|
||||||
|
'Dict({0}) at {1}>'.format(
|
||||||
|
repr(provider.kwargs),
|
||||||
|
hex(id(provider))))
|
Loading…
Reference in New Issue
Block a user