mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Update factory provider API docs
This commit is contained in:
		
							parent
							
								
									7eed1cf880
								
							
						
					
					
						commit
						fb6deaec96
					
				| 
						 | 
					@ -16,7 +16,23 @@ from .errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Provider(object):
 | 
					class Provider(object):
 | 
				
			||||||
    """Base provider class."""
 | 
					    """Base provider class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :py:class:`Provider` is callable (implements ``__call__`` method). Every
 | 
				
			||||||
 | 
					    call to provider object returns provided result, according to the providing
 | 
				
			||||||
 | 
					    strategy of particular provider. This ``callable`` functionality is a
 | 
				
			||||||
 | 
					    regular part of providers API and it should be the same for all provider's
 | 
				
			||||||
 | 
					    subclasses.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :py:class:`Provider` implements provider overriding logic that should be
 | 
				
			||||||
 | 
					    also common for all providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Implementation of particular providing strategy should be done in
 | 
				
			||||||
 | 
					    :py:meth:`Provider._provide` of :py:class:`Provider` subclass. Current
 | 
				
			||||||
 | 
					    method is called every time when not overridden provider is called.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    All providers should extend this class.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __IS_PROVIDER__ = True
 | 
					    __IS_PROVIDER__ = True
 | 
				
			||||||
    __slots__ = ('overridden_by',)
 | 
					    __slots__ = ('overridden_by',)
 | 
				
			||||||
| 
						 | 
					@ -26,7 +42,15 @@ class Provider(object):
 | 
				
			||||||
        self.overridden_by = None
 | 
					        self.overridden_by = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, *args, **kwargs):
 | 
					    def __call__(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance."""
 | 
					        """Return provided instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Implementation of current method adds ``callable`` functionality for
 | 
				
			||||||
 | 
					        providers API and it should be common for all provider's subclasses.
 | 
				
			||||||
 | 
					        Also this method implements provider overriding logic that is also
 | 
				
			||||||
 | 
					        common for all providers. Implementation of particular providing
 | 
				
			||||||
 | 
					        strategy should be done in :py:meth:`Provider._provide` of
 | 
				
			||||||
 | 
					        :py:class:`Provider` subclass.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        if self.overridden_by:
 | 
					        if self.overridden_by:
 | 
				
			||||||
            return self.last_overriding(*args, **kwargs)
 | 
					            return self.last_overriding(*args, **kwargs)
 | 
				
			||||||
        return self._provide(*args, **kwargs)
 | 
					        return self._provide(*args, **kwargs)
 | 
				
			||||||
| 
						 | 
					@ -40,12 +64,33 @@ class Provider(object):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError()
 | 
					        raise NotImplementedError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delegate(self):
 | 
					    @property
 | 
				
			||||||
        """Return provider's delegate."""
 | 
					    def is_overridden(self):
 | 
				
			||||||
        return Delegate(self)
 | 
					        """Read-only property that is set to ``True`` if provider is overridden.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: bool
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return bool(self.overridden_by)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def last_overriding(self):
 | 
				
			||||||
 | 
					        """Read-only reference to the last overriding provider, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: :py:class:`Provider`
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            return self.overridden_by[-1]
 | 
				
			||||||
 | 
					        except (TypeError, IndexError):
 | 
				
			||||||
 | 
					            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def override(self, provider):
 | 
					    def override(self, provider):
 | 
				
			||||||
        """Override provider with another provider."""
 | 
					        """Override provider with another provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provider: overriding provider
 | 
				
			||||||
 | 
					        :type provider: :py:class:`Provider`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        if provider is self:
 | 
					        if provider is self:
 | 
				
			||||||
            raise Error('Provider {0} could not be overridden '
 | 
					            raise Error('Provider {0} could not be overridden '
 | 
				
			||||||
                        'with itself'.format(self))
 | 
					                        'with itself'.format(self))
 | 
				
			||||||
| 
						 | 
					@ -54,29 +99,29 @@ class Provider(object):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.overridden_by += (ensure_is_provider(provider),)
 | 
					            self.overridden_by += (ensure_is_provider(provider),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def is_overridden(self):
 | 
					 | 
				
			||||||
        """Check if provider is overridden by another provider."""
 | 
					 | 
				
			||||||
        return bool(self.overridden_by)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def last_overriding(self):
 | 
					 | 
				
			||||||
        """Return last overriding provider."""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            return self.overridden_by[-1]
 | 
					 | 
				
			||||||
        except (TypeError, IndexError):
 | 
					 | 
				
			||||||
            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def reset_last_overriding(self):
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
        """Reset last overriding provider."""
 | 
					        """Reset last overriding provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        if not self.is_overridden:
 | 
					        if not self.is_overridden:
 | 
				
			||||||
            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
					            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
				
			||||||
        self.overridden_by = self.overridden_by[:-1]
 | 
					        self.overridden_by = self.overridden_by[:-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset_override(self):
 | 
					    def reset_override(self):
 | 
				
			||||||
        """Reset all overriding providers."""
 | 
					        """Reset all overriding providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        self.overridden_by = None
 | 
					        self.overridden_by = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def delegate(self):
 | 
				
			||||||
 | 
					        """Return provider's delegate.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: :py:class:`Delegate`
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return Delegate(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Delegate(Provider):
 | 
					class Delegate(Provider):
 | 
				
			||||||
    """Provider's delegate."""
 | 
					    """Provider's delegate."""
 | 
				
			||||||
| 
						 | 
					@ -92,36 +137,126 @@ class Delegate(Provider):
 | 
				
			||||||
        super(Delegate, self).__init__()
 | 
					        super(Delegate, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def _provide(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance."""
 | 
					        """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
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        return self.delegated
 | 
					        return self.delegated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Factory(Provider):
 | 
					class Factory(Provider):
 | 
				
			||||||
    """Factory provider.
 | 
					    """:py:class:`Factory` provider creates new instance on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Factory provider creates new instance of specified class on every call.
 | 
					    :py:class:`Factory` supports different syntaxes of passing injections:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    + simplified one syntax for passing positional and keyword argument
 | 
				
			||||||
 | 
					      injections only:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass, 'arg1', 'arg2', arg3=3, arg4=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - extended (full) one syntax for passing any type of injections:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
 | 
					    :py:class:`Factory` object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass,
 | 
				
			||||||
 | 
					                          some_arg1=1,
 | 
				
			||||||
 | 
					                          some_arg2=2)
 | 
				
			||||||
 | 
					        some_object = factory()
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __slots__ = ('provides', 'args', 'kwargs', 'attributes', 'methods')
 | 
					    __slots__ = ('provides', 'args', 'kwargs', 'attributes', 'methods')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, provides, *args, **kwargs):
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
        """Initializer."""
 | 
					        """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 not callable(provides):
 | 
					        if not callable(provides):
 | 
				
			||||||
            raise Error('Factory provider expects to get callable, ' +
 | 
					            raise Error('Factory provider expects to get callable, ' +
 | 
				
			||||||
                        'got {0} instead'.format(str(provides)))
 | 
					                        'got {0} instead'.format(str(provides)))
 | 
				
			||||||
        self.provides = provides
 | 
					        self.provides = provides
 | 
				
			||||||
 | 
					        """Class or other callable that provides object for creation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | callable
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.args = _parse_args_injections(args)
 | 
					        self.args = _parse_args_injections(args)
 | 
				
			||||||
 | 
					        """Tuple of positional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.kwargs = _parse_kwargs_injections(args, kwargs)
 | 
					        self.kwargs = _parse_kwargs_injections(args, kwargs)
 | 
				
			||||||
 | 
					        """Tuple of keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.attributes = tuple(injection
 | 
					        self.attributes = tuple(injection
 | 
				
			||||||
                                for injection in args
 | 
					                                for injection in args
 | 
				
			||||||
                                if is_attribute_injection(injection))
 | 
					                                if is_attribute_injection(injection))
 | 
				
			||||||
 | 
					        """Tuple of attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.methods = tuple(injection
 | 
					        self.methods = tuple(injection
 | 
				
			||||||
                             for injection in args
 | 
					                             for injection in args
 | 
				
			||||||
                             if is_method_injection(injection))
 | 
					                             if is_method_injection(injection))
 | 
				
			||||||
 | 
					        """Tuple of method injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super(Factory, self).__init__()
 | 
					        super(Factory, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def injections(self):
 | 
				
			||||||
 | 
					        """Read-only tuple of all injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self.args + self.kwargs + self.attributes + self.methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def _provide(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance."""
 | 
					        """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
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        instance = self.provides(*_get_injectable_args(args, self.args),
 | 
					        instance = self.provides(*_get_injectable_args(args, self.args),
 | 
				
			||||||
                                 **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
					                                 **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
				
			||||||
        for attribute in self.attributes:
 | 
					        for attribute in self.attributes:
 | 
				
			||||||
| 
						 | 
					@ -131,11 +266,6 @@ class Factory(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return instance
 | 
					        return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def injections(self):
 | 
					 | 
				
			||||||
        """Return tuple of all injections."""
 | 
					 | 
				
			||||||
        return self.args + self.kwargs + self.attributes + self.methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Singleton(Provider):
 | 
					class Singleton(Provider):
 | 
				
			||||||
    """Singleton provider.
 | 
					    """Singleton provider.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,3 +4,4 @@
 | 
				
			||||||
.. automodule:: dependency_injector.providers
 | 
					.. automodule:: dependency_injector.providers
 | 
				
			||||||
   :members:
 | 
					   :members:
 | 
				
			||||||
   :member-order: bysource
 | 
					   :member-order: bysource
 | 
				
			||||||
 | 
					   :inherited-members:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user