diff --git a/dependency_injector/providers/callable.py b/dependency_injector/providers/callable.py index 62be51df..0c85a231 100644 --- a/dependency_injector/providers/callable.py +++ b/dependency_injector/providers/callable.py @@ -15,9 +15,6 @@ from dependency_injector.errors import Error class Callable(Provider): r""":py:class:`Callable` provider calls wrapped callable on every call. - :py:class:`Callable` provider provides callable that is called on every - provider call with some predefined dependency injections. - :py:class:`Callable` supports positional and keyword argument injections: .. code-block:: python diff --git a/docs/api/providers.rst b/docs/api/providers.rst index b5f3ecc1..c86ca0c3 100644 --- a/docs/api/providers.rst +++ b/docs/api/providers.rst @@ -1,6 +1,10 @@ ``dependency_injector.providers`` --------------------------------- +.. image:: /images/providers/providers_class_diagram.png + :width: 100% + :align: center + .. automodule:: dependency_injector.providers :members: :inherited-members: diff --git a/docs/images/providers/callable.png b/docs/images/providers/callable.png index 76271ad3..f34b2a6a 100644 Binary files a/docs/images/providers/callable.png and b/docs/images/providers/callable.png differ diff --git a/docs/images/providers/providers_class_diagram.png b/docs/images/providers/providers_class_diagram.png new file mode 100644 index 00000000..d932ad83 Binary files /dev/null and b/docs/images/providers/providers_class_diagram.png differ diff --git a/docs/providers/callable.rst b/docs/providers/callable.rst index 76bd5faa..15857ca4 100644 --- a/docs/providers/callable.rst +++ b/docs/providers/callable.rst @@ -3,37 +3,26 @@ Callable providers .. currentmodule:: 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. +:py:class:`Callable` provider calls wrapped callable on every call. Callable providers and injections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -: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. +:py:class:`Callable` provider takes a various number of positional and keyword +arguments that are used as wrapped callable injections. Every time, when +:py:class:`Callable` provider 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 with several more things: +Injections are done according to the next rules: + All providers (instances of :py:class:`Provider`) are called every time when injection needs to be done. + Providers could be injected "as is" (delegated), if it is defined obviously. - Check out `Callable providers delegation`_. -+ All other injectable values are provided *"as is"* - -For example, 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. - -: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 :py:class:`Callable` + Check out :ref:`callable_providers_delegation`. ++ All other injectable values are provided *"as is"*. ++ Positional context arguments will be appended after :py:class:`Callable` positional injections. -- Keyword context arguments have priority on :py:class:`Callable` keyword ++ Keyword context arguments have priority on :py:class:`Callable` keyword injections and will be merged over them. Example that shows usage of :py:class:`Callable` with positional argument @@ -54,31 +43,16 @@ injections: :language: python :linenos: -.. _callable_delegation: +.. _callable_providers_delegation: Callable providers delegation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -: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. +:py:class:`Callable` provider could be delegated to any other provider via +any kind of injection. -:py:class:`Callable` delegate could be created obviously using -``Delegate(Callable(...))`` or by calling ``Callable(...).delegate()`` method. - -Example: - -.. literalinclude:: ../../examples/providers/callable_delegation.py - :language: python - :linenos: - -Alternative way of doing :py:class:`Callable` delegation is an usage of -:py:class:`DelegatedCallable`. :py:class:`DelegatedCallable` is a -:py:class:`Callable` that is always injected "as is". - -Example: - -.. literalinclude:: ../../examples/providers/delegated_callable.py - :language: python - :linenos: +Delegation of :py:class:`Callable` providers is the same as +:py:class:`Factory` providers delegation, please follow +:ref:`factory_providers_delegation` section for examples (with exception +about using :py:class:`DelegatedCallable` instead of +:py:class:`DelegatedFactory`). diff --git a/docs/providers/index.rst b/docs/providers/index.rst index 87ecc6db..dbf548aa 100644 --- a/docs/providers/index.rst +++ b/docs/providers/index.rst @@ -19,6 +19,12 @@ be thread safe. Providers module API docs - :py:mod:`dependency_injector.providers` +Providers class diagram: + +.. image:: /images/providers/providers_class_diagram.png + :width: 100% + :align: center + .. toctree:: :maxdepth: 2 diff --git a/examples/providers/callable_delegation.py b/examples/providers/callable_delegation.py deleted file mode 100644 index 6a982ca6..00000000 --- a/examples/providers/callable_delegation.py +++ /dev/null @@ -1,14 +0,0 @@ -"""`Callable` providers delegation example.""" - -import sys -import dependency_injector.providers as providers - - -# Creating some callable provider and few delegates of it: -callable_provider = providers.Callable(sys.exit) -callable_provider_delegate1 = callable_provider.delegate() -callable_provider_delegate2 = providers.Delegate(callable_provider) - -# Making some asserts: -assert callable_provider_delegate1() is callable_provider -assert callable_provider_delegate2() is callable_provider diff --git a/examples/providers/callable_kwargs.py b/examples/providers/callable_kwargs.py index 01c1d4c8..a6b89990 100644 --- a/examples/providers/callable_kwargs.py +++ b/examples/providers/callable_kwargs.py @@ -1,11 +1,11 @@ """`Callable` providers with keyword arguments example.""" import passlib.hash + import dependency_injector.providers as 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 and verifier providers: password_hasher = providers.Callable(passlib.hash.sha256_crypt.encrypt, salt_size=16, rounds=10000) diff --git a/examples/providers/delegated_callable.py b/examples/providers/delegated_callable.py deleted file mode 100644 index 36e4639c..00000000 --- a/examples/providers/delegated_callable.py +++ /dev/null @@ -1,22 +0,0 @@ -"""`DelegatedCallable` providers example.""" - -import dependency_injector.providers as providers - - -def command1(config): - """Some example command.""" - return config['some_value'] * 5 - - -def command2(command1): - """Some example command.""" - return command1() / 2 - -# Creating callable providers for commands: -command1_provider = providers.DelegatedCallable(command1, - config={'some_value': 4}) -command2_provider = providers.DelegatedCallable(command2, - command1=command1_provider) - -# Making some asserts: -assert command2_provider() == 10