mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-26 11:33:58 +03:00
Refactor callable and creational providers
This commit is contained in:
parent
f2a9b35c6d
commit
65512366d2
|
@ -261,7 +261,3 @@ def _parse_kwargs_injections(args, kwargs):
|
||||||
kwarg_injections += tuple(itertools.starmap(KwArg,
|
kwarg_injections += tuple(itertools.starmap(KwArg,
|
||||||
six.iteritems(kwargs)))
|
six.iteritems(kwargs)))
|
||||||
return kwarg_injections
|
return kwarg_injections
|
||||||
|
|
||||||
|
|
||||||
def _parse_attribute_injections(attributes):
|
|
||||||
return tuple(itertools.starmap(Attribute, six.iteritems(attributes)))
|
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from dependency_injector.providers.base import Provider
|
from dependency_injector.providers.base import Provider
|
||||||
from dependency_injector.injections import (
|
from dependency_injector.injections import Arg, KwArg
|
||||||
_parse_args_injections,
|
|
||||||
_parse_kwargs_injections,
|
|
||||||
)
|
|
||||||
from dependency_injector.utils import represent_provider
|
from dependency_injector.utils import represent_provider
|
||||||
from dependency_injector.errors import Error
|
from dependency_injector.errors import Error
|
||||||
|
|
||||||
|
@ -25,27 +22,9 @@ class Callable(Provider):
|
||||||
some_function = Callable(some_function) \
|
some_function = Callable(some_function) \
|
||||||
.args('arg1', 'arg2') \
|
.args('arg1', 'arg2') \
|
||||||
.kwargs(arg3=3, arg4=4)
|
.kwargs(arg3=3, arg4=4)
|
||||||
|
|
||||||
.. py:attribute:: provides
|
|
||||||
|
|
||||||
Provided callable.
|
|
||||||
|
|
||||||
:type: callable
|
|
||||||
|
|
||||||
.. py:attribute:: _args
|
|
||||||
|
|
||||||
Tuple of positional argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
|
||||||
|
|
||||||
.. py:attribute:: _kwargs
|
|
||||||
|
|
||||||
Tuple of keyword argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('provides', '_args', '_kwargs')
|
__slots__ = ('_provides', '_args', '_kwargs')
|
||||||
|
|
||||||
def __init__(self, provides):
|
def __init__(self, provides):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
@ -59,8 +38,7 @@ class Callable(Provider):
|
||||||
self.__class__.__name__)),
|
self.__class__.__name__)),
|
||||||
provides))
|
provides))
|
||||||
|
|
||||||
self.provides = provides
|
self._provides = provides
|
||||||
|
|
||||||
self._args = tuple()
|
self._args = tuple()
|
||||||
self._kwargs = tuple()
|
self._kwargs = tuple()
|
||||||
|
|
||||||
|
@ -82,7 +60,7 @@ class Callable(Provider):
|
||||||
|
|
||||||
:return: Reference ``self``
|
:return: Reference ``self``
|
||||||
"""
|
"""
|
||||||
self._args += _parse_args_injections(args)
|
self._args += tuple(Arg(value) for value in args)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def kwargs(self, **kwargs):
|
def kwargs(self, **kwargs):
|
||||||
|
@ -93,7 +71,8 @@ class Callable(Provider):
|
||||||
|
|
||||||
:return: Reference ``self``
|
:return: Reference ``self``
|
||||||
"""
|
"""
|
||||||
self._kwargs += _parse_kwargs_injections(tuple(), kwargs)
|
self._kwargs += tuple(KwArg(name, value)
|
||||||
|
for name, value in six.iteritems(kwargs))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
|
@ -114,14 +93,14 @@ class Callable(Provider):
|
||||||
if kwarg.name not in kwargs:
|
if kwarg.name not in kwargs:
|
||||||
kwargs[kwarg.name] = kwarg.value
|
kwargs[kwarg.name] = kwarg.value
|
||||||
|
|
||||||
return self.provides(*args, **kwargs)
|
return self._provides(*args, **kwargs)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return string representation of provider.
|
"""Return string representation of provider.
|
||||||
|
|
||||||
:rtype: str
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
return represent_provider(provider=self, provides=self.provides)
|
return represent_provider(provider=self, provides=self._provides)
|
||||||
|
|
||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
||||||
|
@ -131,24 +110,6 @@ class DelegatedCallable(Callable):
|
||||||
|
|
||||||
:py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected
|
:py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected
|
||||||
"as is".
|
"as is".
|
||||||
|
|
||||||
.. py:attribute:: provides
|
|
||||||
|
|
||||||
Provided callable.
|
|
||||||
|
|
||||||
:type: callable
|
|
||||||
|
|
||||||
.. py:attribute:: args
|
|
||||||
|
|
||||||
Tuple of positional argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
|
||||||
|
|
||||||
.. py:attribute:: kwargs
|
|
||||||
|
|
||||||
Tuple of keyword argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__IS_DELEGATED__ = True
|
__IS_DELEGATED__ = True
|
||||||
|
|
|
@ -1,38 +1,32 @@
|
||||||
"""Dependency injector creational providers."""
|
"""Dependency injector creational providers."""
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
from dependency_injector.providers.callable import Callable
|
from dependency_injector.providers.callable import Callable
|
||||||
from dependency_injector.injections import _parse_attribute_injections
|
from dependency_injector.injections import Attribute
|
||||||
from dependency_injector.utils import GLOBAL_LOCK
|
from dependency_injector.utils import GLOBAL_LOCK
|
||||||
from dependency_injector.errors import Error
|
from dependency_injector.errors import Error
|
||||||
|
|
||||||
|
|
||||||
class Factory(Callable):
|
class Factory(Callable):
|
||||||
""":py:class:`Factory` provider creates new instance on every call.
|
r""":py:class:`Factory` provider creates new instance on every call.
|
||||||
|
|
||||||
:py:class:`Factory` supports different syntaxes of passing injections:
|
:py:class:`Factory` supports positional & keyword argument injections,
|
||||||
|
as well as attribute injections:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# simplified syntax for passing positional and keyword argument
|
factory = Factory(SomeClass) \
|
||||||
# injections only:
|
.args('arg1', 'arg2') \
|
||||||
factory = Factory(SomeClass, 'arg1', 'arg2', arg3=3, arg4=4)
|
.kwargs(arg3=3, arg4=4) \
|
||||||
|
.attributes(attribute1=5, attribute2=6)
|
||||||
# extended (full) syntax for passing any type of injections:
|
|
||||||
factory = Factory(SomeClass,
|
|
||||||
injections.Arg(1),
|
|
||||||
injections.Arg(2),
|
|
||||||
injections.KwArg('some_arg', 3),
|
|
||||||
injections.KwArg('other_arg', 4),
|
|
||||||
injections.Attribute('some_attribute', 5))
|
|
||||||
|
|
||||||
Retrieving of provided instance can be performed via calling
|
Retrieving of provided instance can be performed via calling
|
||||||
:py:class:`Factory` object:
|
:py:class:`Factory` object:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
factory = Factory(SomeClass,
|
factory = Factory(SomeClass)
|
||||||
some_arg1=1,
|
|
||||||
some_arg2=2)
|
|
||||||
some_object = factory()
|
some_object = factory()
|
||||||
|
|
||||||
.. py:attribute:: provided_type
|
.. py:attribute:: provided_type
|
||||||
|
@ -43,54 +37,24 @@ class Factory(Callable):
|
||||||
|
|
||||||
:type: type | None
|
:type: type | None
|
||||||
|
|
||||||
.. py:attribute:: provides
|
|
||||||
|
|
||||||
Class or other callable that provides object.
|
|
||||||
|
|
||||||
:type: type | callable
|
|
||||||
|
|
||||||
.. py:attribute:: cls
|
.. py:attribute:: cls
|
||||||
|
|
||||||
Class that provides object.
|
Class that provides object.
|
||||||
Alias for :py:attr:`provides`.
|
Alias for :py:attr:`provides`.
|
||||||
|
|
||||||
:type: type
|
:type: type
|
||||||
|
|
||||||
.. py:attribute:: args
|
|
||||||
|
|
||||||
Tuple of positional argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
|
||||||
|
|
||||||
.. py:attribute:: kwargs
|
|
||||||
|
|
||||||
Tuple of keyword argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
|
||||||
|
|
||||||
.. py:attribute:: attributes
|
|
||||||
|
|
||||||
Tuple of attribute injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Attribute`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
provided_type = None
|
provided_type = None
|
||||||
|
|
||||||
__slots__ = ('cls', '_attributes')
|
__slots__ = ('cls', '_attributes')
|
||||||
|
|
||||||
def __init__(self, provides, *args, **kwargs):
|
def __init__(self, provides):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
|
||||||
:param provides: Class or other callable that provides object
|
:param provides: Class or other callable that provides object
|
||||||
for creation.
|
for creation.
|
||||||
:type provides: type | callable
|
:type provides: type | callable
|
||||||
|
|
||||||
:param args: Tuple of injections.
|
|
||||||
:type args: tuple
|
|
||||||
|
|
||||||
:param kwargs: Dictionary of injections.
|
|
||||||
:type kwargs: dict
|
|
||||||
"""
|
"""
|
||||||
if (self.__class__.provided_type and
|
if (self.__class__.provided_type and
|
||||||
not issubclass(provides, self.__class__.provided_type)):
|
not issubclass(provides, self.__class__.provided_type)):
|
||||||
|
@ -99,9 +63,9 @@ class Factory(Callable):
|
||||||
|
|
||||||
self._attributes = tuple()
|
self._attributes = tuple()
|
||||||
|
|
||||||
super(Factory, self).__init__(provides, *args, **kwargs)
|
super(Factory, self).__init__(provides)
|
||||||
|
|
||||||
self.cls = self.provides
|
self.cls = self._provides
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def injections(self):
|
def injections(self):
|
||||||
|
@ -109,7 +73,7 @@ class Factory(Callable):
|
||||||
|
|
||||||
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
||||||
"""
|
"""
|
||||||
return self._args + self._kwargs + self._attributes
|
return super(Factory, self).injections + self._attributes
|
||||||
|
|
||||||
def attributes(self, **kwargs):
|
def attributes(self, **kwargs):
|
||||||
"""Add attribute injections.
|
"""Add attribute injections.
|
||||||
|
@ -119,7 +83,8 @@ class Factory(Callable):
|
||||||
|
|
||||||
:return: Reference ``self``
|
:return: Reference ``self``
|
||||||
"""
|
"""
|
||||||
self._attributes += _parse_attribute_injections(kwargs)
|
self._attributes += tuple(Attribute(name, value)
|
||||||
|
for name, value in six.iteritems(kwargs))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
|
@ -140,7 +105,7 @@ class Factory(Callable):
|
||||||
if kwarg.name not in kwargs:
|
if kwarg.name not in kwargs:
|
||||||
kwargs[kwarg.name] = kwarg.value
|
kwargs[kwarg.name] = kwarg.value
|
||||||
|
|
||||||
instance = self.provides(*args, **kwargs)
|
instance = self._provides(*args, **kwargs)
|
||||||
|
|
||||||
for attribute in self._attributes:
|
for attribute in self._attributes:
|
||||||
setattr(instance, attribute.name, attribute.value)
|
setattr(instance, attribute.name, attribute.value)
|
||||||
|
@ -162,36 +127,12 @@ class DelegatedFactory(Factory):
|
||||||
|
|
||||||
:type: type | None
|
:type: type | None
|
||||||
|
|
||||||
.. py:attribute:: provides
|
|
||||||
|
|
||||||
Class or other callable that provides object.
|
|
||||||
|
|
||||||
:type: type | callable
|
|
||||||
|
|
||||||
.. py:attribute:: cls
|
.. py:attribute:: cls
|
||||||
|
|
||||||
Class that provides object.
|
Class that provides object.
|
||||||
Alias for :py:attr:`provides`.
|
Alias for :py:attr:`provides`.
|
||||||
|
|
||||||
:type: type
|
:type: type
|
||||||
|
|
||||||
.. py:attribute:: args
|
|
||||||
|
|
||||||
Tuple of positional argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
|
||||||
|
|
||||||
.. py:attribute:: kwargs
|
|
||||||
|
|
||||||
Tuple of keyword argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
|
||||||
|
|
||||||
.. py:attribute:: attributes
|
|
||||||
|
|
||||||
Tuple of attribute injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Attribute`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__IS_DELEGATED__ = True
|
__IS_DELEGATED__ = True
|
||||||
|
@ -212,9 +153,7 @@ class Singleton(Factory):
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
singleton = Singleton(SomeClass,
|
singleton = Singleton(SomeClass)
|
||||||
some_arg1=1,
|
|
||||||
some_arg2=2)
|
|
||||||
some_object = singleton()
|
some_object = singleton()
|
||||||
|
|
||||||
.. py:attribute:: provided_type
|
.. py:attribute:: provided_type
|
||||||
|
@ -225,68 +164,32 @@ class Singleton(Factory):
|
||||||
|
|
||||||
:type: type | None
|
:type: type | None
|
||||||
|
|
||||||
.. py:attribute:: instance
|
|
||||||
|
|
||||||
Read-only reference to singleton's instance.
|
|
||||||
|
|
||||||
:type: object
|
|
||||||
|
|
||||||
.. py:attribute:: provides
|
|
||||||
|
|
||||||
Class or other callable that provides object.
|
|
||||||
|
|
||||||
:type: type | callable
|
|
||||||
|
|
||||||
.. py:attribute:: cls
|
.. py:attribute:: cls
|
||||||
|
|
||||||
Class that provides object.
|
Class that provides object.
|
||||||
Alias for :py:attr:`provides`.
|
Alias for :py:attr:`provides`.
|
||||||
|
|
||||||
:type: type
|
:type: type
|
||||||
|
|
||||||
.. py:attribute:: args
|
|
||||||
|
|
||||||
Tuple of positional argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
|
||||||
|
|
||||||
.. py:attribute:: kwargs
|
|
||||||
|
|
||||||
Tuple of keyword argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
|
||||||
|
|
||||||
.. py:attribute:: attributes
|
|
||||||
|
|
||||||
Tuple of attribute injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Attribute`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('instance',)
|
__slots__ = ('_instance',)
|
||||||
|
|
||||||
def __init__(self, provides, *args, **kwargs):
|
def __init__(self, provides):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
|
||||||
:param provides: Class or other callable that provides object
|
:param provides: Class or other callable that provides object
|
||||||
for creation.
|
for creation.
|
||||||
:type provides: type | callable
|
:type provides: type | callable
|
||||||
|
|
||||||
:param args: Tuple of injections.
|
|
||||||
:type args: tuple
|
|
||||||
|
|
||||||
:param kwargs: Dictionary of injections.
|
|
||||||
:type kwargs: dict
|
|
||||||
"""
|
"""
|
||||||
self.instance = None
|
self._instance = None
|
||||||
super(Singleton, self).__init__(provides, *args, **kwargs)
|
super(Singleton, self).__init__(provides)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset cached instance, if any.
|
"""Reset cached instance, if any.
|
||||||
|
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
self.instance = None
|
self._instance = None
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
"""Return provided instance.
|
"""Return provided instance.
|
||||||
|
@ -299,13 +202,13 @@ class Singleton(Factory):
|
||||||
|
|
||||||
:rtype: object
|
:rtype: object
|
||||||
"""
|
"""
|
||||||
if self.instance:
|
if self._instance:
|
||||||
return self.instance
|
return self._instance
|
||||||
|
|
||||||
with GLOBAL_LOCK:
|
with GLOBAL_LOCK:
|
||||||
self.instance = super(Singleton, self)._provide(*args, **kwargs)
|
self._instance = super(Singleton, self)._provide(*args, **kwargs)
|
||||||
|
|
||||||
return self.instance
|
return self._instance
|
||||||
|
|
||||||
|
|
||||||
class DelegatedSingleton(Singleton):
|
class DelegatedSingleton(Singleton):
|
||||||
|
@ -322,42 +225,12 @@ class DelegatedSingleton(Singleton):
|
||||||
|
|
||||||
:type: type | None
|
:type: type | None
|
||||||
|
|
||||||
.. py:attribute:: instance
|
|
||||||
|
|
||||||
Read-only reference to singleton's instance.
|
|
||||||
|
|
||||||
:type: object
|
|
||||||
|
|
||||||
.. py:attribute:: provides
|
|
||||||
|
|
||||||
Class or other callable that provides object.
|
|
||||||
|
|
||||||
:type: type | callable
|
|
||||||
|
|
||||||
.. py:attribute:: cls
|
.. py:attribute:: cls
|
||||||
|
|
||||||
Class that provides object.
|
Class that provides object.
|
||||||
Alias for :py:attr:`provides`.
|
Alias for :py:attr:`provides`.
|
||||||
|
|
||||||
:type: type
|
:type: type
|
||||||
|
|
||||||
.. py:attribute:: args
|
|
||||||
|
|
||||||
Tuple of positional argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
|
||||||
|
|
||||||
.. py:attribute:: kwargs
|
|
||||||
|
|
||||||
Tuple of keyword argument injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
|
||||||
|
|
||||||
.. py:attribute:: attributes
|
|
||||||
|
|
||||||
Tuple of attribute injections.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`dependency_injector.injections.Attribute`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__IS_DELEGATED__ = True
|
__IS_DELEGATED__ = True
|
||||||
|
|
Loading…
Reference in New Issue
Block a user