mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 18:07:44 +03:00 
			
		
		
		
	Update callable provider docs, including API, and examples
This commit is contained in:
		
							parent
							
								
									cea843160c
								
							
						
					
					
						commit
						a65155ed1c
					
				| 
						 | 
				
			
			@ -293,7 +293,18 @@ class Singleton(Provider):
 | 
			
		|||
    __slots__ = ('instance', 'factory')
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
        """
 | 
			
		||||
        self.instance = None
 | 
			
		||||
        """Read-only reference to singleton's instance.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -492,33 +503,78 @@ class Value(StaticProvider):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Callable(Provider):
 | 
			
		||||
    """Callable provider.
 | 
			
		||||
    """:py:class:`Callable` provider calls wrapped callable on every call.
 | 
			
		||||
 | 
			
		||||
    Callable provider provides callable that is called on every provider call
 | 
			
		||||
    with some predefined dependency injections.
 | 
			
		||||
    :py:class:`Callable` provider provides callable that is called on every
 | 
			
		||||
    provider call with some predefined dependency injections.
 | 
			
		||||
 | 
			
		||||
    :py:class:`Callable` syntax of passing injections is the same like
 | 
			
		||||
    :py:class:`Factory` one:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        some_function = Callable(some_function, 'arg1', 'arg2', arg3=3, arg4=4)
 | 
			
		||||
        result = some_function()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('callback', 'args', 'kwargs')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, callback, *args, **kwargs):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param callback: wrapped callable.
 | 
			
		||||
        :type callback: callable
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of injections.
 | 
			
		||||
        :type args: tuple
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of injections.
 | 
			
		||||
        :type kwargs: dict
 | 
			
		||||
        """
 | 
			
		||||
        if not callable(callback):
 | 
			
		||||
            raise Error('Callable expected, got {0}'.format(str(callback)))
 | 
			
		||||
        self.callback = callback
 | 
			
		||||
        self.args = _parse_args_injections(args)
 | 
			
		||||
        self.kwargs = _parse_kwargs_injections(args, kwargs)
 | 
			
		||||
        super(Callable, self).__init__()
 | 
			
		||||
        """Wrapped callable.
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        return self.callback(*_get_injectable_args(args, self.args),
 | 
			
		||||
                             **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
			
		||||
        :type: callable
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
        """Tuple of keyword argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(Callable, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def injections(self):
 | 
			
		||||
        """Return tuple of all injections."""
 | 
			
		||||
        """Read-only tuple of all injections.
 | 
			
		||||
 | 
			
		||||
        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.args + self.kwargs
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
        """
 | 
			
		||||
        return self.callback(*_get_injectable_args(args, self.args),
 | 
			
		||||
                             **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Config(Provider):
 | 
			
		||||
    """Config provider.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 82 KiB  | 
| 
						 | 
				
			
			@ -1,40 +1,43 @@
 | 
			
		|||
Callable providers
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
``di.Callable`` provider is a provider that wraps particular callable with
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
:py:class:`Callable` provider is a provider that wraps particular callable with
 | 
			
		||||
some injections. Every call of this provider returns result of call of initial
 | 
			
		||||
callable.
 | 
			
		||||
 | 
			
		||||
Callable providers and injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Callable`` takes a various number of positional and keyword arguments 
 | 
			
		||||
that are used as decorated callable injections. Every time, when 
 | 
			
		||||
``di.Callable`` is called, positional and keyword argument injections would be 
 | 
			
		||||
passed as an callable arguments.
 | 
			
		||||
:py:class:`Callable` takes a various number of positional and keyword 
 | 
			
		||||
arguments that are used as decorated callable injections. Every time, when 
 | 
			
		||||
:py:class:`Callable` is called, positional and keyword argument injections 
 | 
			
		||||
would be passed as an callable arguments.
 | 
			
		||||
 | 
			
		||||
Such behaviour is very similar to the standard Python ``functools.partial`` 
 | 
			
		||||
object, except of one thing: all injectable values are provided 
 | 
			
		||||
*"as is"*, except of providers (subclasses of ``di.Provider``). Providers 
 | 
			
		||||
*"as is"*, except of providers (subclasses of :py:class:`Provider`). Providers 
 | 
			
		||||
will be called every time, when injection needs to be done. For example, 
 | 
			
		||||
if injectable value of injection is a ``di.Factory``, it will provide new one 
 | 
			
		||||
instance (as a result of its call) every time, when injection needs to be done.
 | 
			
		||||
if injectable value of injection is a :py:class:`Factory`, it will provide 
 | 
			
		||||
new one instance (as a result of its call) every time, when injection needs 
 | 
			
		||||
to be done.
 | 
			
		||||
 | 
			
		||||
``di.Callable`` behaviour with context positional and keyword arguments is 
 | 
			
		||||
very like a standard Python ``functools.partial``:
 | 
			
		||||
:py:class:`Callable` behaviour with context positional and keyword arguments 
 | 
			
		||||
is very like a standard Python ``functools.partial``:
 | 
			
		||||
 | 
			
		||||
- Positional context arguments will be appended after ``di.Callable`` 
 | 
			
		||||
- Positional context arguments will be appended after :py:class:`Callable` 
 | 
			
		||||
  positional injections.
 | 
			
		||||
- Keyword context arguments have priority on ``di.Callable`` keyword 
 | 
			
		||||
- Keyword context arguments have priority on :py:class:`Callable` keyword 
 | 
			
		||||
  injections and will be merged over them.
 | 
			
		||||
 | 
			
		||||
Example that shows usage of ``di.Callable`` with positional argument 
 | 
			
		||||
Example that shows usage of :py:class:`Callable` with positional argument 
 | 
			
		||||
injections:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/callable_args.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Next one example shows usage of ``di.Callable`` with keyword argument 
 | 
			
		||||
Next one example shows usage of :py:class:`Callable` with keyword argument 
 | 
			
		||||
injections:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/callable.png
 | 
			
		||||
| 
						 | 
				
			
			@ -47,13 +50,13 @@ injections:
 | 
			
		|||
Callable providers delegation
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Callable`` provider could be delegated to any other provider via any kind 
 | 
			
		||||
of injection. Delegation of ``di.Callable`` providers is the same as 
 | 
			
		||||
``di.Factory`` and ``di.Singleton`` providers delegation, please follow 
 | 
			
		||||
*Factory providers delegation* section for example.
 | 
			
		||||
:py:class:`Callable` provider could be delegated to any other provider via any 
 | 
			
		||||
kind of injection. Delegation of :py:class:`Callable` providers is the same as 
 | 
			
		||||
:py:class:`Factory` and :py:class:`Singleton` providers delegation, please 
 | 
			
		||||
follow *Factory providers delegation* section for example.
 | 
			
		||||
 | 
			
		||||
``di.Callable`` delegate could be created obviously using 
 | 
			
		||||
``di.Delegate(di.Callable())`` or by calling ``di.Callable.delegate()`` method.
 | 
			
		||||
:py:class:`Callable` delegate could be created obviously using 
 | 
			
		||||
``Delegate(Callable(...))`` or by calling ``Callable(...).delegate()`` method.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
"""`di.Callable` providers with positional arguments example."""
 | 
			
		||||
"""`Callable` providers with positional arguments example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating even and odd filter providers:
 | 
			
		||||
even_filter = di.Callable(filter, lambda x: x % 2 == 0)
 | 
			
		||||
odd_filter = di.Callable(filter, lambda x: x % 2 != 0)
 | 
			
		||||
even_filter = providers.Callable(filter, lambda x: x % 2 == 0)
 | 
			
		||||
odd_filter = providers.Callable(filter, lambda x: x % 2 != 0)
 | 
			
		||||
 | 
			
		||||
# Creating even and odd ranges using xrange() and filter providers:
 | 
			
		||||
even_range = even_filter(xrange(1, 10))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,14 @@
 | 
			
		|||
"""`di.Callable` providers delegation example."""
 | 
			
		||||
"""`Callable` providers delegation example."""
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some callable provider and few delegates of it:
 | 
			
		||||
callable_provider = di.Callable(sys.exit)
 | 
			
		||||
callable_provider = providers.Callable(sys.exit)
 | 
			
		||||
callable_provider_delegate1 = callable_provider.delegate()
 | 
			
		||||
callable_provider_delegate2 = di.Delegate(callable_provider)
 | 
			
		||||
callable_provider_delegate2 = providers.Delegate(callable_provider)
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert callable_provider_delegate1() is callable_provider
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,16 @@
 | 
			
		|||
"""`di.Callable` providers with keyword arguments example."""
 | 
			
		||||
"""`Callable` providers with keyword arguments example."""
 | 
			
		||||
 | 
			
		||||
import passlib.hash
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Password hasher and verifier providers (hash function could be changed
 | 
			
		||||
# anytime (for example, to sha512) without any changes in client's code):
 | 
			
		||||
password_hasher = di.Callable(passlib.hash.sha256_crypt.encrypt,
 | 
			
		||||
                              salt_size=16,
 | 
			
		||||
                              rounds=10000)
 | 
			
		||||
password_verifier = di.Callable(passlib.hash.sha256_crypt.verify)
 | 
			
		||||
password_hasher = providers.Callable(passlib.hash.sha256_crypt.encrypt,
 | 
			
		||||
                                     salt_size=16,
 | 
			
		||||
                                     rounds=10000)
 | 
			
		||||
password_verifier = providers.Callable(passlib.hash.sha256_crypt.verify)
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
hashed_password = password_hasher('super secret')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user