From 65512366d28f28bce4998975e94825a92e1d19ca Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Wed, 18 May 2016 01:17:15 +0300 Subject: [PATCH] Refactor callable and creational providers --- dependency_injector/injections.py | 4 - dependency_injector/providers/callable.py | 55 +----- dependency_injector/providers/creational.py | 183 +++----------------- 3 files changed, 36 insertions(+), 206 deletions(-) diff --git a/dependency_injector/injections.py b/dependency_injector/injections.py index 02b1400e..fe526715 100644 --- a/dependency_injector/injections.py +++ b/dependency_injector/injections.py @@ -261,7 +261,3 @@ def _parse_kwargs_injections(args, kwargs): kwarg_injections += tuple(itertools.starmap(KwArg, six.iteritems(kwargs))) return kwarg_injections - - -def _parse_attribute_injections(attributes): - return tuple(itertools.starmap(Attribute, six.iteritems(attributes))) diff --git a/dependency_injector/providers/callable.py b/dependency_injector/providers/callable.py index 3093927b..afc29964 100644 --- a/dependency_injector/providers/callable.py +++ b/dependency_injector/providers/callable.py @@ -3,10 +3,7 @@ import six from dependency_injector.providers.base import Provider -from dependency_injector.injections import ( - _parse_args_injections, - _parse_kwargs_injections, -) +from dependency_injector.injections import Arg, KwArg from dependency_injector.utils import represent_provider from dependency_injector.errors import Error @@ -25,27 +22,9 @@ class Callable(Provider): some_function = Callable(some_function) \ .args('arg1', 'arg2') \ .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): """Initializer. @@ -59,8 +38,7 @@ class Callable(Provider): self.__class__.__name__)), provides)) - self.provides = provides - + self._provides = provides self._args = tuple() self._kwargs = tuple() @@ -82,7 +60,7 @@ class Callable(Provider): :return: Reference ``self`` """ - self._args += _parse_args_injections(args) + self._args += tuple(Arg(value) for value in args) return self def kwargs(self, **kwargs): @@ -93,7 +71,8 @@ class Callable(Provider): :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 def _provide(self, *args, **kwargs): @@ -114,14 +93,14 @@ class Callable(Provider): if kwarg.name not in kwargs: kwargs[kwarg.name] = kwarg.value - return self.provides(*args, **kwargs) + return self._provides(*args, **kwargs) def __str__(self): """Return string representation of provider. :rtype: str """ - return represent_provider(provider=self, provides=self.provides) + return represent_provider(provider=self, provides=self._provides) __repr__ = __str__ @@ -131,24 +110,6 @@ class DelegatedCallable(Callable): :py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected "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 diff --git a/dependency_injector/providers/creational.py b/dependency_injector/providers/creational.py index 3069a872..d554361f 100644 --- a/dependency_injector/providers/creational.py +++ b/dependency_injector/providers/creational.py @@ -1,38 +1,32 @@ """Dependency injector creational providers.""" +import six + 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.errors import Error 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 - # simplified syntax for passing positional and keyword argument - # injections only: - factory = Factory(SomeClass, 'arg1', 'arg2', arg3=3, arg4=4) - - # 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)) + factory = Factory(SomeClass) \ + .args('arg1', 'arg2') \ + .kwargs(arg3=3, arg4=4) \ + .attributes(attribute1=5, attribute2=6) Retrieving of provided instance can be performed via calling :py:class:`Factory` object: .. code-block:: python - factory = Factory(SomeClass, - some_arg1=1, - some_arg2=2) + factory = Factory(SomeClass) some_object = factory() .. py:attribute:: provided_type @@ -43,54 +37,24 @@ class Factory(Callable): :type: type | None - .. py:attribute:: provides - - Class or other callable that provides object. - - :type: type | callable - .. py:attribute:: cls Class that provides object. Alias for :py:attr:`provides`. :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 __slots__ = ('cls', '_attributes') - def __init__(self, provides, *args, **kwargs): + def __init__(self, provides): """Initializer. :param provides: Class or other callable that provides object for creation. :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 not issubclass(provides, self.__class__.provided_type)): @@ -99,9 +63,9 @@ class Factory(Callable): self._attributes = tuple() - super(Factory, self).__init__(provides, *args, **kwargs) + super(Factory, self).__init__(provides) - self.cls = self.provides + self.cls = self._provides @property def injections(self): @@ -109,7 +73,7 @@ class Factory(Callable): :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): """Add attribute injections. @@ -119,7 +83,8 @@ class Factory(Callable): :return: Reference ``self`` """ - self._attributes += _parse_attribute_injections(kwargs) + self._attributes += tuple(Attribute(name, value) + for name, value in six.iteritems(kwargs)) return self def _provide(self, *args, **kwargs): @@ -140,7 +105,7 @@ class Factory(Callable): if kwarg.name not in kwargs: kwargs[kwarg.name] = kwarg.value - instance = self.provides(*args, **kwargs) + instance = self._provides(*args, **kwargs) for attribute in self._attributes: setattr(instance, attribute.name, attribute.value) @@ -162,36 +127,12 @@ class DelegatedFactory(Factory): :type: type | None - .. py:attribute:: provides - - Class or other callable that provides object. - - :type: type | callable - .. py:attribute:: cls Class that provides object. Alias for :py:attr:`provides`. :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 @@ -212,9 +153,7 @@ class Singleton(Factory): .. code-block:: python - singleton = Singleton(SomeClass, - some_arg1=1, - some_arg2=2) + singleton = Singleton(SomeClass) some_object = singleton() .. py:attribute:: provided_type @@ -225,68 +164,32 @@ class Singleton(Factory): :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 Class that provides object. Alias for :py:attr:`provides`. :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. :param provides: Class or other callable that provides object for creation. :type provides: type | callable - - :param args: Tuple of injections. - :type args: tuple - - :param kwargs: Dictionary of injections. - :type kwargs: dict """ - self.instance = None - super(Singleton, self).__init__(provides, *args, **kwargs) + self._instance = None + super(Singleton, self).__init__(provides) def reset(self): """Reset cached instance, if any. :rtype: None """ - self.instance = None + self._instance = None def _provide(self, *args, **kwargs): """Return provided instance. @@ -299,13 +202,13 @@ class Singleton(Factory): :rtype: object """ - if self.instance: - return self.instance + if self._instance: + return self._instance 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): @@ -322,42 +225,12 @@ class DelegatedSingleton(Singleton): :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 Class that provides object. Alias for :py:attr:`provides`. :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