128 lines
3.5 KiB
Python
128 lines
3.5 KiB
Python
"""Dependency injector callable providers."""
|
|
|
|
import six
|
|
|
|
from dependency_injector.providers.base import (
|
|
Provider,
|
|
_parse_positional_injections,
|
|
_parse_keyword_injections,
|
|
)
|
|
from dependency_injector.utils import represent_provider
|
|
from dependency_injector.errors import Error
|
|
|
|
|
|
@six.python_2_unicode_compatible
|
|
class Callable(Provider):
|
|
r""":py:class:`Callable` provider calls wrapped callable on every call.
|
|
|
|
:py:class:`Callable` supports positional and keyword argument injections:
|
|
|
|
.. code-block:: python
|
|
|
|
some_function = Callable(some_function,
|
|
'positional_arg1', 'positional_arg2',
|
|
keyword_argument1=3, keyword_argument=4)
|
|
|
|
# or
|
|
|
|
some_function = Callable(some_function) \
|
|
.add_args('positional_arg1', 'positional_arg2') \
|
|
.add_kwargs(keyword_argument1=3, keyword_argument=4)
|
|
|
|
# or
|
|
|
|
some_function = Callable(some_function)
|
|
some_function.add_args('positional_arg1', 'positional_arg2')
|
|
some_function.add_kwargs(keyword_argument1=3, keyword_argument=4)
|
|
"""
|
|
|
|
__slots__ = ('provides', 'args', 'kwargs')
|
|
|
|
def __init__(self, provides, *args, **kwargs):
|
|
"""Initializer.
|
|
|
|
:param provides: Wrapped callable.
|
|
:type provides: callable
|
|
"""
|
|
if not callable(provides):
|
|
raise Error('Provider {0} expected to get callable, '
|
|
'got {0}'.format('.'.join((self.__class__.__module__,
|
|
self.__class__.__name__)),
|
|
provides))
|
|
|
|
self.provides = provides
|
|
|
|
self.args = tuple()
|
|
self.kwargs = dict()
|
|
|
|
self.add_args(*args)
|
|
self.add_kwargs(**kwargs)
|
|
|
|
super(Callable, self).__init__()
|
|
|
|
def add_args(self, *args):
|
|
"""Add postional argument injections.
|
|
|
|
:param args: Tuple of injections.
|
|
:type args: tuple
|
|
|
|
:return: Reference ``self``
|
|
"""
|
|
self.args += _parse_positional_injections(args)
|
|
return self
|
|
|
|
def add_kwargs(self, **kwargs):
|
|
"""Add keyword argument injections.
|
|
|
|
:param kwargs: Dictionary of injections.
|
|
:type kwargs: dict
|
|
|
|
:return: Reference ``self``
|
|
"""
|
|
self.kwargs.update(_parse_keyword_injections(kwargs))
|
|
return self
|
|
|
|
def _provide(self, *args, **kwargs):
|
|
"""Return provided instance.
|
|
|
|
:param args: Tuple of context positional arguments.
|
|
:type args: tuple[object]
|
|
|
|
:param kwargs: Dictionary of context keyword arguments.
|
|
:type kwargs: dict[str, object]
|
|
|
|
:rtype: object
|
|
"""
|
|
if self.args:
|
|
args = tuple(arg.provide_injection() for arg in self.args) + args
|
|
|
|
for name, arg in six.iteritems(self.kwargs):
|
|
if name not in kwargs:
|
|
kwargs[name] = arg.provide_injection()
|
|
|
|
return self.provides(*args, **kwargs)
|
|
|
|
def __str__(self):
|
|
"""Return string representation of provider.
|
|
|
|
:rtype: str
|
|
"""
|
|
return represent_provider(provider=self, provides=self.provides)
|
|
|
|
__repr__ = __str__
|
|
|
|
|
|
class DelegatedCallable(Callable):
|
|
""":py:class:`DelegatedCallable` is a delegated :py:class:`Callable`.
|
|
|
|
:py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected
|
|
"as is".
|
|
"""
|
|
|
|
def provide_injection(self):
|
|
"""Injection strategy implementation.
|
|
|
|
:rtype: object
|
|
"""
|
|
return self
|