mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 18:07:44 +03:00 
			
		
		
		
	Merge pull request #143 from ets-labs/138_cython_providers_v3
Cython providers
This commit is contained in:
		
						commit
						8259de6dd7
					
				| 
						 | 
					@ -16,6 +16,9 @@ dependency injection pattern in formal, pretty, Pythonic way.
 | 
				
			||||||
+ Documentation.
 | 
					+ Documentation.
 | 
				
			||||||
+ Semantic versioning.
 | 
					+ Semantic versioning.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Dependency Injector* providers are implemented as C extension types using 
 | 
				
			||||||
 | 
					Cython.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Status
 | 
					Status
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,5 +7,4 @@ API Documentation
 | 
				
			||||||
    top_level
 | 
					    top_level
 | 
				
			||||||
    providers
 | 
					    providers
 | 
				
			||||||
    containers
 | 
					    containers
 | 
				
			||||||
    utils
 | 
					 | 
				
			||||||
    errors
 | 
					    errors
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,6 @@
 | 
				
			||||||
``dependency_injector.providers``
 | 
					``dependency_injector.providers``
 | 
				
			||||||
---------------------------------
 | 
					---------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. image:: /images/providers/providers_class_diagram.png
 | 
					 | 
				
			||||||
    :width: 100%
 | 
					 | 
				
			||||||
    :align: center
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. automodule:: dependency_injector.providers
 | 
					.. automodule:: dependency_injector.providers
 | 
				
			||||||
   :members:
 | 
					   :members:
 | 
				
			||||||
   :inherited-members:
 | 
					   :inherited-members:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ Also, for both of these and some other cases, it might be useful to attach
 | 
				
			||||||
some init / shutdown functionality or something else, that deals with group 
 | 
					some init / shutdown functionality or something else, that deals with group 
 | 
				
			||||||
of providers.
 | 
					of providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Containers module API docs - :py:mod:`dependency_injector.containers`.
 | 
					Containers package API docs - :py:mod:`dependency_injector.containers`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
..  toctree::
 | 
					..  toctree::
 | 
				
			||||||
    :maxdepth: 2
 | 
					    :maxdepth: 2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 139 KiB  | 
| 
						 | 
					@ -8,7 +8,14 @@ Dependency Injector --- Dependency injection microframework for Python
 | 
				
			||||||
   :description: Dependency Injector is a dependency injection microframework 
 | 
					   :description: Dependency Injector is a dependency injection microframework 
 | 
				
			||||||
                 for Python. It was designed to be unified, developer-friendly 
 | 
					                 for Python. It was designed to be unified, developer-friendly 
 | 
				
			||||||
                 tool that helps to implement dependency injection pattern in 
 | 
					                 tool that helps to implement dependency injection pattern in 
 | 
				
			||||||
                 formal, pretty, Pythonic way.
 | 
					                 formal, pretty, Pythonic way. Dependency Injector framework 
 | 
				
			||||||
 | 
					                 key features are: Easy, smart, pythonic style; Obvious, clear 
 | 
				
			||||||
 | 
					                 structure; Extensibility and flexibility; High performance; 
 | 
				
			||||||
 | 
					                 Memory efficiency; Thread safety; Documentation; Semantic 
 | 
				
			||||||
 | 
					                 versioning; Dependency Injector providers are implemented as 
 | 
				
			||||||
 | 
					                 C extension types using Cython.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _index:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*Dependency Injector* is a dependency injection microframework for Python. 
 | 
					*Dependency Injector* is a dependency injection microframework for Python. 
 | 
				
			||||||
It was designed to be unified, developer-friendly tool that helps to implement 
 | 
					It was designed to be unified, developer-friendly tool that helps to implement 
 | 
				
			||||||
| 
						 | 
					@ -19,11 +26,15 @@ dependency injection pattern in formal, pretty, Pythonic way.
 | 
				
			||||||
+ Easy, smart, pythonic style.
 | 
					+ Easy, smart, pythonic style.
 | 
				
			||||||
+ Obvious, clear structure.
 | 
					+ Obvious, clear structure.
 | 
				
			||||||
+ Extensibility and flexibility.
 | 
					+ Extensibility and flexibility.
 | 
				
			||||||
 | 
					+ High performance.
 | 
				
			||||||
+ Memory efficiency.
 | 
					+ Memory efficiency.
 | 
				
			||||||
+ Thread safety.
 | 
					+ Thread safety.
 | 
				
			||||||
+ Documentation.
 | 
					+ Documentation.
 | 
				
			||||||
+ Semantic versioning.
 | 
					+ Semantic versioning.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Dependency Injector* providers are implemented as C extension types using 
 | 
				
			||||||
 | 
					Cython.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Status
 | 
					Status
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,7 +121,7 @@ code for specification of dependencies. Nevertheless, this disadvantage could
 | 
				
			||||||
be easily avoided by creating inversion of control container (IoC container).
 | 
					be easily avoided by creating inversion of control container (IoC container).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example of creation of several inversion of control containers (IoC containers)
 | 
					Example of creation of several inversion of control containers (IoC containers)
 | 
				
			||||||
using *Dependency Injector*:
 | 
					using :doc:`Dependency Injector <../index>`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. literalinclude:: ../../examples/miniapps/engines_cars/example_ioc_containers.py
 | 
					.. literalinclude:: ../../examples/miniapps/engines_cars/example_ioc_containers.py
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,16 +9,40 @@ follows `Semantic versioning`_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Development version
 | 
					Development version
 | 
				
			||||||
-------------------
 | 
					-------------------
 | 
				
			||||||
- Add ``dependency_injector.injections`` module (C extension).
 | 
					- **Providers**
 | 
				
			||||||
- Transfer ``dependency_injector.utils`` module to Cython (C extension).
 | 
					 | 
				
			||||||
- Transfer ``dependency_injector.errors`` module to Cython (C extension).
 | 
					 | 
				
			||||||
- Remove ``@inject`` decorator.
 | 
					 | 
				
			||||||
- Add makefile (``clean``, ``test``, ``build``, ``install``, ``uninstall`` 
 | 
					 | 
				
			||||||
  & ``publish`` commands).
 | 
					 | 
				
			||||||
- Update repository structure:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - Sources are moved under ``src``.
 | 
					  1. All providers from ``dependency_injector.providers`` package are 
 | 
				
			||||||
    - Tests are moved under ``tests/unit``.
 | 
					     implemented as C extension types using Cython.
 | 
				
			||||||
 | 
					  2. Add ``BaseSingleton`` super class for all singleton providers.
 | 
				
			||||||
 | 
					  3. Make ``Singleton`` provider not thread-safe. It makes performance of 
 | 
				
			||||||
 | 
					     ``Singleton`` provider  10x times faster.
 | 
				
			||||||
 | 
					  4. Add ``ThreadSafeSingleton`` provider - thread-safe version of 
 | 
				
			||||||
 | 
					     ``Singleton`` provider.
 | 
				
			||||||
 | 
					  5. Add ``ThreadLocalSingleton`` provider - ``Singleton`` provider that uses 
 | 
				
			||||||
 | 
					     thread-local storage.
 | 
				
			||||||
 | 
					  6. Remove ``provides`` attribute from ``Factory`` and ``Singleton`` 
 | 
				
			||||||
 | 
					     providers.
 | 
				
			||||||
 | 
					  7. Add ``set_args()`` and ``clear_args()`` methods for ``Callable``, 
 | 
				
			||||||
 | 
					     ``Factory`` and ``Singleton`` providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Containers**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  1. Module ``dependency_injector.containers`` was splitted into submodules 
 | 
				
			||||||
 | 
					     without any functional changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Utils**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  1. Module ``dependency_injector.utils`` is splitted into 
 | 
				
			||||||
 | 
					     ``dependency_injector.containers`` and ``dependency_injector.providers``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Miscellaneous**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  1. Remove ``@inject`` decorator.
 | 
				
			||||||
 | 
					  2. Add makefile (``clean``, ``test``, ``build``, ``install``, ``uninstall`` 
 | 
				
			||||||
 | 
					     & ``publish`` commands).
 | 
				
			||||||
 | 
					  3. Update repository structure:
 | 
				
			||||||
 | 
					    1. Sources are moved under ``src/`` folder.
 | 
				
			||||||
 | 
					    2. Tests are moved under ``tests/unit/`` folder.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. - No features.
 | 
					.. - No features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,12 @@ framework can be installed from PyPi_:
 | 
				
			||||||
    pip install dependency_injector
 | 
					    pip install dependency_injector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Installing particular version:
 | 
					    # Installing particular version:
 | 
				
			||||||
    pip install dependency_injector==2.0.0
 | 
					    pip install dependency-injector==3.0.0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					.. note::
 | 
				
			||||||
 | 
					    Some components of *Dependency Injector* are implemented as C extension types. 
 | 
				
			||||||
 | 
					    *Dependency Injector* is distributed as an archive with a source code, so 
 | 
				
			||||||
 | 
					    C compiler and Python header files are required for the installation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sources can be cloned from GitHub_:
 | 
					Sources can be cloned from GitHub_:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +35,7 @@ Verification of currently installed version could be done using
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> from dependency_injector import VERSION
 | 
					    >>> from dependency_injector import VERSION
 | 
				
			||||||
    >>> VERSION
 | 
					    >>> VERSION
 | 
				
			||||||
    '2.0.0'
 | 
					    '3.0.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
					.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
				
			||||||
.. _GitHub: https://github.com/ets-labs/python-dependency-injector
 | 
					.. _GitHub: https://github.com/ets-labs/python-dependency-injector
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,16 +12,7 @@ Current documentation section consists from description of standard providers
 | 
				
			||||||
library and some useful information like overriding of providers and writing 
 | 
					library and some useful information like overriding of providers and writing 
 | 
				
			||||||
of custom providers.
 | 
					of custom providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
All providers are validated in multithreading environment and considered to 
 | 
					Providers package API docs - :py:mod:`dependency_injector.providers`
 | 
				
			||||||
be thread safe.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
+ Base providers class is: :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
+ Providers module API docs: :py:mod:`dependency_injector.providers`
 | 
					 | 
				
			||||||
+ Providers class diagram:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. image:: /images/providers/providers_class_diagram.png
 | 
					 | 
				
			||||||
    :width: 100%
 | 
					 | 
				
			||||||
    :align: center
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
..  toctree::
 | 
					..  toctree::
 | 
				
			||||||
    :maxdepth: 2
 | 
					    :maxdepth: 2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ Singleton providers resetting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Created and memorized by :py:class:`Singleton` instance can be reset. Reset of
 | 
					Created and memorized by :py:class:`Singleton` instance can be reset. Reset of
 | 
				
			||||||
:py:class:`Singleton`'s memorized instance is done by clearing reference to 
 | 
					:py:class:`Singleton`'s memorized instance is done by clearing reference to 
 | 
				
			||||||
it.  Further lifecycle of memorized instance is out of :py:class:`Singleton` 
 | 
					it. Further lifecycle of memorized instance is out of :py:class:`Singleton` 
 | 
				
			||||||
provider's control and dependes on garbage collection strategy.
 | 
					provider's control and dependes on garbage collection strategy.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
| 
						 | 
					@ -33,15 +33,15 @@ Example:
 | 
				
			||||||
Singleton providers and injections
 | 
					Singleton providers and injections
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Singleton` provider extends :py:class:`Factory` provider, so, all 
 | 
					:py:class:`Singleton` provider has same interface as :py:class:`Factory` 
 | 
				
			||||||
of the rules about injections are the same, as for :py:class:`Factory` 
 | 
					provider, so, all of the rules about injections are the same, as for 
 | 
				
			||||||
provider.
 | 
					:py:class:`Factory` provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. note::
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Due that :py:class:`Singleton` provider creates specified class instance 
 | 
					    Due that :py:class:`Singleton` provider creates specified class instance 
 | 
				
			||||||
    only on the first call, all injections are done once, during the first 
 | 
					    only on the first call, all injections are done once, during the first 
 | 
				
			||||||
    call, also.  Every next call, while instance has been already created 
 | 
					    call. Every next call, while instance has been already created 
 | 
				
			||||||
    and memorized, no injections are done, :py:class:`Singleton` provider just 
 | 
					    and memorized, no injections are done, :py:class:`Singleton` provider just 
 | 
				
			||||||
    returns memorized earlier instance.
 | 
					    returns memorized earlier instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,10 +81,12 @@ Specialization of :py:class:`Singleton` providers is the same as
 | 
				
			||||||
Singleton providers and multi-threading
 | 
					Singleton providers and multi-threading
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Singleton` provider is thread-safe and could be used in 
 | 
					:py:class:`Singleton` provider is NOT thread-safe and should be used in  
 | 
				
			||||||
multi-threading applications without any negative impact. Race condition on 
 | 
					multi-threading applications with manually controlled locking.
 | 
				
			||||||
singleton's initialization is escaped by using a global reentrant mutex - 
 | 
					
 | 
				
			||||||
:py:obj:`dependency_injector.utils.GLOBAL_LOCK`.
 | 
					:py:class:`ThreadSafeSingleton` is a thread-safe version of 
 | 
				
			||||||
 | 
					:py:class:`Singleton` and could be used in multi-threading applications 
 | 
				
			||||||
 | 
					without any additional locking.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Also there could be a need to use thread-scoped singletons and there is a 
 | 
					Also there could be a need to use thread-scoped singletons and there is a 
 | 
				
			||||||
special provider for such case - :py:class:`ThreadLocalSingleton`.
 | 
					special provider for such case - :py:class:`ThreadLocalSingleton`.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								setup.py
									
									
									
									
									
								
							| 
						 | 
					@ -47,6 +47,22 @@ setup(name='dependency-injector',
 | 
				
			||||||
          '': 'src',
 | 
					          '': 'src',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      ext_modules=[
 | 
					      ext_modules=[
 | 
				
			||||||
 | 
					          Extension('dependency_injector.providers.base',
 | 
				
			||||||
 | 
					                    ['src/dependency_injector/providers/base.c'],
 | 
				
			||||||
 | 
					                    define_macros=defined_macros,
 | 
				
			||||||
 | 
					                    extra_compile_args=['-O2']),
 | 
				
			||||||
 | 
					          Extension('dependency_injector.providers.callables',
 | 
				
			||||||
 | 
					                    ['src/dependency_injector/providers/callables.c'],
 | 
				
			||||||
 | 
					                    define_macros=defined_macros,
 | 
				
			||||||
 | 
					                    extra_compile_args=['-O2']),
 | 
				
			||||||
 | 
					          Extension('dependency_injector.providers.factories',
 | 
				
			||||||
 | 
					                    ['src/dependency_injector/providers/factories.c'],
 | 
				
			||||||
 | 
					                    define_macros=defined_macros,
 | 
				
			||||||
 | 
					                    extra_compile_args=['-O2']),
 | 
				
			||||||
 | 
					          Extension('dependency_injector.providers.singletons',
 | 
				
			||||||
 | 
					                    ['src/dependency_injector/providers/singletons.c'],
 | 
				
			||||||
 | 
					                    define_macros=defined_macros,
 | 
				
			||||||
 | 
					                    extra_compile_args=['-O2']),
 | 
				
			||||||
          Extension('dependency_injector.providers.injections',
 | 
					          Extension('dependency_injector.providers.injections',
 | 
				
			||||||
                    ['src/dependency_injector/providers/injections.c'],
 | 
					                    ['src/dependency_injector/providers/injections.c'],
 | 
				
			||||||
                    define_macros=defined_macros,
 | 
					                    define_macros=defined_macros,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,12 @@
 | 
				
			||||||
"""Dependency injector container utils."""
 | 
					"""Dependency injector container utils."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import copy as _copy
 | 
					 | 
				
			||||||
import types
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector.providers import deepcopy
 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if six.PY2:  # pragma: no cover
 | 
					 | 
				
			||||||
    _copy._deepcopy_dispatch[types.MethodType] = \
 | 
					 | 
				
			||||||
        lambda obj, memo: type(obj)(obj.im_func,
 | 
					 | 
				
			||||||
                                    _copy.deepcopy(obj.im_self, memo),
 | 
					 | 
				
			||||||
                                    obj.im_class)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def is_container(instance):
 | 
					def is_container(instance):
 | 
				
			||||||
    """Check if instance is container instance.
 | 
					    """Check if instance is container instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,11 +66,6 @@ def copy(container):
 | 
				
			||||||
    return _decorator
 | 
					    return _decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def deepcopy(instance, memo=None):
 | 
					 | 
				
			||||||
    """Make full copy of instance."""
 | 
					 | 
				
			||||||
    return _copy.deepcopy(instance, memo)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _check_provider_type(cls, provider):
 | 
					def _check_provider_type(cls, provider):
 | 
				
			||||||
    if not isinstance(provider, cls.provider_type):
 | 
					    if not isinstance(provider, cls.provider_type):
 | 
				
			||||||
        raise Error('{0} can contain only {1} '
 | 
					        raise Error('{0} can contain only {1} '
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,46 +2,51 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .base import (
 | 
					from .base import (
 | 
				
			||||||
    Provider,
 | 
					    Provider,
 | 
				
			||||||
    Delegate,
 | 
					 | 
				
			||||||
    Object,
 | 
					    Object,
 | 
				
			||||||
 | 
					    Delegate,
 | 
				
			||||||
    ExternalDependency,
 | 
					    ExternalDependency,
 | 
				
			||||||
    OverridingContext,
 | 
					    OverridingContext,
 | 
				
			||||||
    override,
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .callable import (
 | 
					from .callables import (
 | 
				
			||||||
    Callable,
 | 
					    Callable,
 | 
				
			||||||
    DelegatedCallable,
 | 
					    DelegatedCallable,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .creational import (
 | 
					from .factories import (
 | 
				
			||||||
    Factory,
 | 
					    Factory,
 | 
				
			||||||
    DelegatedFactory,
 | 
					    DelegatedFactory,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from .singletons import (
 | 
				
			||||||
 | 
					    BaseSingleton,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Singleton,
 | 
					    Singleton,
 | 
				
			||||||
    DelegatedSingleton,
 | 
					    DelegatedSingleton,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ThreadSafeSingleton,
 | 
				
			||||||
 | 
					    DelegatedThreadSafeSingleton,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ThreadLocalSingleton,
 | 
					    ThreadLocalSingleton,
 | 
				
			||||||
    DelegatedThreadLocalSingleton,
 | 
					    DelegatedThreadLocalSingleton,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .utils import (
 | 
					 | 
				
			||||||
    GLOBAL_LOCK,
 | 
					 | 
				
			||||||
    is_provider,
 | 
					 | 
				
			||||||
    ensure_is_provider,
 | 
					 | 
				
			||||||
    is_delegated,
 | 
					 | 
				
			||||||
    represent_provider,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from .injections import (
 | 
					from .injections import (
 | 
				
			||||||
    Injection,
 | 
					    Injection,
 | 
				
			||||||
    PositionalInjection,
 | 
					    PositionalInjection,
 | 
				
			||||||
    NamedInjection,
 | 
					    NamedInjection,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from .utils import (
 | 
				
			||||||
 | 
					    is_provider,
 | 
				
			||||||
 | 
					    ensure_is_provider,
 | 
				
			||||||
 | 
					    is_delegated,
 | 
				
			||||||
 | 
					    represent_provider,
 | 
				
			||||||
 | 
					    deepcopy,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = (
 | 
					__all__ = (
 | 
				
			||||||
    'Provider',
 | 
					    'Provider',
 | 
				
			||||||
    'Delegate',
 | 
					 | 
				
			||||||
    'Object',
 | 
					    'Object',
 | 
				
			||||||
 | 
					    'Delegate',
 | 
				
			||||||
    'ExternalDependency',
 | 
					    'ExternalDependency',
 | 
				
			||||||
 | 
					 | 
				
			||||||
    'OverridingContext',
 | 
					    'OverridingContext',
 | 
				
			||||||
    'override',
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'Callable',
 | 
					    'Callable',
 | 
				
			||||||
    'DelegatedCallable',
 | 
					    'DelegatedCallable',
 | 
				
			||||||
| 
						 | 
					@ -49,19 +54,24 @@ __all__ = (
 | 
				
			||||||
    'Factory',
 | 
					    'Factory',
 | 
				
			||||||
    'DelegatedFactory',
 | 
					    'DelegatedFactory',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'BaseSingleton',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'Singleton',
 | 
					    'Singleton',
 | 
				
			||||||
    'DelegatedSingleton',
 | 
					    'DelegatedSingleton',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'ThreadSafeSingleton',
 | 
				
			||||||
 | 
					    'DelegatedThreadSafeSingleton',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'ThreadLocalSingleton',
 | 
					    'ThreadLocalSingleton',
 | 
				
			||||||
    'DelegatedThreadLocalSingleton',
 | 
					    'DelegatedThreadLocalSingleton',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'GLOBAL_LOCK',
 | 
					    'Injection',
 | 
				
			||||||
 | 
					    'PositionalInjection',
 | 
				
			||||||
 | 
					    'NamedInjection',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'is_provider',
 | 
					    'is_provider',
 | 
				
			||||||
    'ensure_is_provider',
 | 
					    'ensure_is_provider',
 | 
				
			||||||
    'is_delegated',
 | 
					    'is_delegated',
 | 
				
			||||||
    'represent_provider',
 | 
					    'represent_provider',
 | 
				
			||||||
 | 
					    'deepcopy',
 | 
				
			||||||
    'Injection',
 | 
					 | 
				
			||||||
    'PositionalInjection',
 | 
					 | 
				
			||||||
    'NamedInjection',
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/dependency_injector/providers/base.pxd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/dependency_injector/providers/base.pxd
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					"""Dependency injector base providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Provider(object):
 | 
				
			||||||
 | 
					    cdef tuple __overridden
 | 
				
			||||||
 | 
					    cdef int __overridden_len
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					    cpdef object _call_last_overriding(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Object(Provider):
 | 
				
			||||||
 | 
					    cdef object __provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Delegate(Object):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class ExternalDependency(Provider):
 | 
				
			||||||
 | 
					    cdef type __instance_of
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class OverridingContext(object):
 | 
				
			||||||
 | 
					    cdef Provider __overridden
 | 
				
			||||||
 | 
					    cdef Provider __overriding
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,22 @@
 | 
				
			||||||
"""Dependency injector base providers."""
 | 
					"""Dependency injector base providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cimport cython
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
from .utils import (
 | 
					
 | 
				
			||||||
 | 
					from .utils cimport (
 | 
				
			||||||
 | 
					    CLASS_TYPES,
 | 
				
			||||||
    is_provider,
 | 
					    is_provider,
 | 
				
			||||||
    ensure_is_provider,
 | 
					    ensure_is_provider,
 | 
				
			||||||
    represent_provider,
 | 
					    represent_provider,
 | 
				
			||||||
 | 
					    deepcopy,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					cdef class Provider(object):
 | 
				
			||||||
class Provider(object):
 | 
					 | 
				
			||||||
    """Base provider class.
 | 
					    """Base provider class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :py:class:`Provider` is callable (implements ``__call__`` method). Every
 | 
					    :py:class:`Provider` is callable (implements ``__call__`` method). Every
 | 
				
			||||||
| 
						 | 
					@ -59,38 +64,53 @@ class Provider(object):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __IS_PROVIDER__ = True
 | 
					    __IS_PROVIDER__ = True
 | 
				
			||||||
    __OPTIMIZED_CALLS__ = True
 | 
					 | 
				
			||||||
    __slots__ = ('overridden', 'provide', '__call__')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        """Initializer."""
 | 
					        """Initializer."""
 | 
				
			||||||
        self.overridden = tuple()
 | 
					        self.__overridden = tuple()
 | 
				
			||||||
 | 
					        self.__overridden_len = 0
 | 
				
			||||||
        super(Provider, self).__init__()
 | 
					        super(Provider, self).__init__()
 | 
				
			||||||
        # Enable __call__() / _provide() optimization
 | 
					 | 
				
			||||||
        if self.__class__.__OPTIMIZED_CALLS__:
 | 
					 | 
				
			||||||
            self.__call__ = self.provide = self._provide
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def __call__(self, *args, **kwargs):
 | 
				
			||||||
        """Providing strategy implementation.
 | 
					        """Return provided object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Abstract protected method that implements providing strategy of
 | 
					        Callable interface implementation.
 | 
				
			||||||
        particular provider. Current method is called every time when not
 | 
					 | 
				
			||||||
        overridden provider is called. Need to be overridden in subclasses.
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError()
 | 
					        if self.__overridden_len != 0:
 | 
				
			||||||
 | 
					            return self._call_last_overriding(args, kwargs)
 | 
				
			||||||
 | 
					        return self._provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _call_last_overriding(self, *args, **kwargs):
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
        """Call last overriding provider and return result."""
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
        return (self.overridden[-1](*args, **kwargs)
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
                if self.overridden
 | 
					        if copied is not None:
 | 
				
			||||||
                else None)
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def provide_injection(self):
 | 
					        copied = self.__class__()
 | 
				
			||||||
        """Injection strategy implementation.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: object
 | 
					        for overriding_provider in self.overridden:
 | 
				
			||||||
 | 
					            copied.override(deepcopy(overriding_provider, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self.provide()
 | 
					        return represent_provider(provider=self, provides=None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self.__str__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def overridden(self):
 | 
				
			||||||
 | 
					        """Return tuple of overriding providers."""
 | 
				
			||||||
 | 
					        return self.__overridden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def override(self, provider):
 | 
					    def override(self, provider):
 | 
				
			||||||
        """Override provider with another provider.
 | 
					        """Override provider with another provider.
 | 
				
			||||||
| 
						 | 
					@ -100,8 +120,8 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
					        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :return: Overriding provider.
 | 
					        :return: Overriding context.
 | 
				
			||||||
        :rtype: :py:class:`Provider`
 | 
					        :rtype: :py:class:`OverridingContext`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if provider is self:
 | 
					        if provider is self:
 | 
				
			||||||
            raise Error('Provider {0} could not be overridden '
 | 
					            raise Error('Provider {0} could not be overridden '
 | 
				
			||||||
| 
						 | 
					@ -110,14 +130,13 @@ class Provider(object):
 | 
				
			||||||
        if not is_provider(provider):
 | 
					        if not is_provider(provider):
 | 
				
			||||||
            provider = Object(provider)
 | 
					            provider = Object(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.overridden += (ensure_is_provider(provider),)
 | 
					        self.__overridden += (provider,)
 | 
				
			||||||
 | 
					        self.__overridden_len += 1
 | 
				
			||||||
        # Disable __call__() / _provide() optimization
 | 
					 | 
				
			||||||
        if self.__class__.__OPTIMIZED_CALLS__:
 | 
					 | 
				
			||||||
            self.__call__ = self.provide = self._call_last_overriding
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return OverridingContext(self, provider)
 | 
					        return OverridingContext(self, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @cython.boundscheck(False)
 | 
				
			||||||
 | 
					    @cython.wraparound(False)
 | 
				
			||||||
    def reset_last_overriding(self):
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
        """Reset last overriding provider.
 | 
					        """Reset last overriding provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,26 +145,19 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if not self.overridden:
 | 
					        if self.__overridden_len == 0:
 | 
				
			||||||
            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
					            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.overridden = self.overridden[:-1]
 | 
					        self.__overridden = self.__overridden[:self.__overridden_len - 1]
 | 
				
			||||||
 | 
					        self.__overridden_len -= 1
 | 
				
			||||||
        if not self.overridden:
 | 
					 | 
				
			||||||
            # Enable __call__() / _provide() optimization
 | 
					 | 
				
			||||||
            if self.__class__.__OPTIMIZED_CALLS__:
 | 
					 | 
				
			||||||
                self.__call__ = self.provide = self._provide
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset_override(self):
 | 
					    def reset_override(self):
 | 
				
			||||||
        """Reset all overriding providers.
 | 
					        """Reset all overriding providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.overridden = tuple()
 | 
					        self.__overridden = tuple()
 | 
				
			||||||
 | 
					        self.__overridden_len = 0
 | 
				
			||||||
        # Enable __call__() / _provide() optimization
 | 
					 | 
				
			||||||
        if self.__class__.__OPTIMIZED_CALLS__:
 | 
					 | 
				
			||||||
            self.__call__ = self.provide = self._provide
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delegate(self):
 | 
					    def delegate(self):
 | 
				
			||||||
        """Return provider's delegate.
 | 
					        """Return provider's delegate.
 | 
				
			||||||
| 
						 | 
					@ -154,73 +166,25 @@ class Provider(object):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return Delegate(self)
 | 
					        return Delegate(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
        """Return string representation of provider.
 | 
					        """Providing strategy implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: str
 | 
					        Abstract protected method that implements providing strategy of
 | 
				
			||||||
 | 
					        particular provider. Current method is called every time when not
 | 
				
			||||||
 | 
					        overridden provider is called. Need to be overridden in subclasses.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return represent_provider(provider=self, provides=None)
 | 
					        raise NotImplementedError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __repr__ = __str__
 | 
					    @cython.boundscheck(False)
 | 
				
			||||||
 | 
					    @cython.wraparound(False)
 | 
				
			||||||
 | 
					    cpdef object _call_last_overriding(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        """Call last overriding provider and return result."""
 | 
				
			||||||
 | 
					        return  <object>self.__overridden[self.__overridden_len - 1](*args,
 | 
				
			||||||
 | 
					                                                                     **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					cdef class Object(Provider):
 | 
				
			||||||
class Delegate(Provider):
 | 
					    """Object provider returns provided instance "as is".
 | 
				
			||||||
    """:py:class:`Delegate` provider delegates another provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider = Factory(object)
 | 
					 | 
				
			||||||
        delegate = Delegate(provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        delegated = delegate()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert provider is delegated
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: delegated
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Delegated provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: :py:class:`Provider`
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __slots__ = ('delegated',)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, delegated):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :provider delegated: Delegated provider.
 | 
					 | 
				
			||||||
        :type delegated: :py:class:`Provider`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.delegated = ensure_is_provider(delegated)
 | 
					 | 
				
			||||||
        super(Delegate, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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.delegated
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return represent_provider(provider=self, provides=self.delegated)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class Object(Provider):
 | 
					 | 
				
			||||||
    """:py:class:`Object` provider returns provided instance "as is".
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provides
 | 
					    .. py:attribute:: provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,18 +193,43 @@ class Object(Provider):
 | 
				
			||||||
        :type: object
 | 
					        :type: object
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __slots__ = ('provides',)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, provides):
 | 
					    def __init__(self, provides):
 | 
				
			||||||
        """Initializer.
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param provides: Value that have to be provided.
 | 
					        :param provides: Value that have to be provided.
 | 
				
			||||||
        :type provides: object
 | 
					        :type provides: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.provides = provides
 | 
					        self.__provides = provides
 | 
				
			||||||
        super(Object, self).__init__()
 | 
					        super(Object, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(deepcopy(self.__provides, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for overriding_provider in self.overridden:
 | 
				
			||||||
 | 
					            copied.override(deepcopy(overriding_provider, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return represent_provider(provider=self, provides=self.__provides)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self.__str__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
        """Return provided instance.
 | 
					        """Return provided instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param args: Tuple of context positional arguments.
 | 
					        :param args: Tuple of context positional arguments.
 | 
				
			||||||
| 
						 | 
					@ -251,20 +240,29 @@ class Object(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: object
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self.provides
 | 
					        return self.__provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: str
 | 
					cdef class Delegate(Object):
 | 
				
			||||||
 | 
					    """Delegate provider returns provider "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Value that have to be provided.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: object
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Value that have to be provided.
 | 
				
			||||||
 | 
					        :type provides: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return represent_provider(provider=self, provides=self.provides)
 | 
					        super(Delegate, self).__init__(ensure_is_provider(provides))
 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					cdef class ExternalDependency(Provider):
 | 
				
			||||||
class ExternalDependency(Provider):
 | 
					 | 
				
			||||||
    """:py:class:`ExternalDependency` provider describes dependency interface.
 | 
					    """:py:class:`ExternalDependency` provider describes dependency interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This provider is used for description of dependency interface. That might
 | 
					    This provider is used for description of dependency interface. That might
 | 
				
			||||||
| 
						 | 
					@ -286,18 +284,24 @@ class ExternalDependency(Provider):
 | 
				
			||||||
        :type: type
 | 
					        :type: type
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __OPTIMIZED_CALLS__ = False
 | 
					    def __init__(self, type instance_of):
 | 
				
			||||||
    __slots__ = ('instance_of',)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, instance_of):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					        """Initializer."""
 | 
				
			||||||
        if not isinstance(instance_of, six.class_types):
 | 
					        self.__instance_of = instance_of
 | 
				
			||||||
            raise Error('ExternalDependency provider expects to get class, ' +
 | 
					 | 
				
			||||||
                        'got {0} instead'.format(str(instance_of)))
 | 
					 | 
				
			||||||
        self.instance_of = instance_of
 | 
					 | 
				
			||||||
        self.provide = self.__call__
 | 
					 | 
				
			||||||
        super(ExternalDependency, self).__init__()
 | 
					        super(ExternalDependency, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self.__instance_of)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for overriding_provider in self.overridden:
 | 
				
			||||||
 | 
					            copied.override(deepcopy(overriding_provider, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, *args, **kwargs):
 | 
					    def __call__(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance.
 | 
					        """Return provided instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,10 +315,12 @@ class ExternalDependency(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: object
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if not self.overridden:
 | 
					        cdef object instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.__overridden_len == 0:
 | 
				
			||||||
            raise Error('Dependency is not defined')
 | 
					            raise Error('Dependency is not defined')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        instance = self._call_last_overriding(*args, **kwargs)
 | 
					        instance = self._call_last_overriding(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not isinstance(instance, self.instance_of):
 | 
					        if not isinstance(instance, self.instance_of):
 | 
				
			||||||
            raise Error('{0} is not an '.format(instance) +
 | 
					            raise Error('{0} is not an '.format(instance) +
 | 
				
			||||||
| 
						 | 
					@ -322,6 +328,25 @@ class ExternalDependency(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return instance
 | 
					        return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return represent_provider(provider=self, provides=self.__instance_of)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self.__str__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def instance_of(self):
 | 
				
			||||||
 | 
					        """Return class of required dependency."""
 | 
				
			||||||
 | 
					        return self.__instance_of
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def provided_by(self, provider):
 | 
					    def provided_by(self, provider):
 | 
				
			||||||
        """Set external dependency provider.
 | 
					        """Set external dependency provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -332,17 +357,8 @@ class ExternalDependency(Provider):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self.override(provider)
 | 
					        return self.override(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: str
 | 
					cdef class OverridingContext(object):
 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return represent_provider(provider=self, provides=self.instance_of)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class OverridingContext(object):
 | 
					 | 
				
			||||||
    """Provider overriding context.
 | 
					    """Provider overriding context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
 | 
					    :py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
 | 
				
			||||||
| 
						 | 
					@ -356,7 +372,7 @@ class OverridingContext(object):
 | 
				
			||||||
        assert not provider.overridden
 | 
					        assert not provider.overridden
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, overridden, overriding):
 | 
					    def __init__(self, Provider overridden, Provider overriding):
 | 
				
			||||||
        """Initializer.
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param overridden: Overridden provider.
 | 
					        :param overridden: Overridden provider.
 | 
				
			||||||
| 
						 | 
					@ -365,52 +381,14 @@ class OverridingContext(object):
 | 
				
			||||||
        :param overriding: Overriding provider.
 | 
					        :param overriding: Overriding provider.
 | 
				
			||||||
        :type overriding: :py:class:`Provider`
 | 
					        :type overriding: :py:class:`Provider`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.overridden = overridden
 | 
					        self.__overridden = overridden
 | 
				
			||||||
        self.overriding = overriding
 | 
					        self.__overriding = overriding
 | 
				
			||||||
 | 
					        super(OverridingContext, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __enter__(self):
 | 
					    def __enter__(self):
 | 
				
			||||||
        """Do nothing."""
 | 
					        """Do nothing."""
 | 
				
			||||||
        return self.overriding
 | 
					        return self.__overriding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __exit__(self, *_):
 | 
					    def __exit__(self, *_):
 | 
				
			||||||
        """Exit overriding context."""
 | 
					        """Exit overriding context."""
 | 
				
			||||||
        self.overridden.reset_last_overriding()
 | 
					        self.__overridden.reset_last_overriding()
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def override(overridden):
 | 
					 | 
				
			||||||
    """Decorator for overriding providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    This decorator overrides ``overridden`` provider by decorated one.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @Factory
 | 
					 | 
				
			||||||
        class SomeClass(object):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @override(SomeClass)
 | 
					 | 
				
			||||||
        @Factory
 | 
					 | 
				
			||||||
        class ExtendedSomeClass(SomeClass.cls):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :param overridden: Provider that should be overridden.
 | 
					 | 
				
			||||||
    :type overridden: :py:class:`Provider`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :return: Overriding provider.
 | 
					 | 
				
			||||||
    :rtype: :py:class:`Provider`
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def decorator(overriding):
 | 
					 | 
				
			||||||
        overridden.override(overriding)
 | 
					 | 
				
			||||||
        return overriding
 | 
					 | 
				
			||||||
    return decorator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _parse_positional_injections(args):
 | 
					 | 
				
			||||||
    return tuple(arg if is_provider(arg) else Object(arg)
 | 
					 | 
				
			||||||
                 for arg in args)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _parse_keyword_injections(kwargs):
 | 
					 | 
				
			||||||
    return dict((name, arg if is_provider(arg) else Object(arg))
 | 
					 | 
				
			||||||
                for name, arg in six.iteritems(kwargs))
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,127 +0,0 @@
 | 
				
			||||||
"""Dependency injector callable providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.providers.base import (
 | 
					 | 
				
			||||||
    Provider,
 | 
					 | 
				
			||||||
    _parse_positional_injections,
 | 
					 | 
				
			||||||
    _parse_keyword_injections,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from .utils import represent_provider
 | 
					 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class Callable(Provider):
 | 
					 | 
				
			||||||
    r""":py:class:`Callable` provider calls wrapped callable on every call.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`Callable` supports positional and keyword argument injections:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        some_function = Callable(some_function,
 | 
					 | 
				
			||||||
                                 'positional_arg1', 'positional_arg2',
 | 
					 | 
				
			||||||
                                 keyword_argument1=3, keyword_argument=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # or
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        some_function = Callable(some_function) \
 | 
					 | 
				
			||||||
            .add_args('positional_arg1', 'positional_arg2') \
 | 
					 | 
				
			||||||
            .add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # or
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        some_function = Callable(some_function)
 | 
					 | 
				
			||||||
        some_function.add_args('positional_arg1', 'positional_arg2')
 | 
					 | 
				
			||||||
        some_function.add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __slots__ = ('provides', 'args', 'kwargs')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, provides, *args, **kwargs):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param provides: Wrapped callable.
 | 
					 | 
				
			||||||
        :type provides: callable
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if not callable(provides):
 | 
					 | 
				
			||||||
            raise Error('Provider {0} expected to get callable, '
 | 
					 | 
				
			||||||
                        'got {0}'.format('.'.join((self.__class__.__module__,
 | 
					 | 
				
			||||||
                                                   self.__class__.__name__)),
 | 
					 | 
				
			||||||
                                         provides))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.provides = provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.args = tuple()
 | 
					 | 
				
			||||||
        self.kwargs = dict()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.add_args(*args)
 | 
					 | 
				
			||||||
        self.add_kwargs(**kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        super(Callable, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def add_args(self, *args):
 | 
					 | 
				
			||||||
        """Add postional argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param args: Tuple of injections.
 | 
					 | 
				
			||||||
        :type args: tuple
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Reference ``self``
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.args += _parse_positional_injections(args)
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def add_kwargs(self, **kwargs):
 | 
					 | 
				
			||||||
        """Add keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					 | 
				
			||||||
        :type kwargs: dict
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Reference ``self``
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.kwargs.update(_parse_keyword_injections(kwargs))
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if self.args:
 | 
					 | 
				
			||||||
            args = tuple(arg.provide_injection() for arg in self.args) + args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for name, arg in six.iteritems(self.kwargs):
 | 
					 | 
				
			||||||
            if name not in kwargs:
 | 
					 | 
				
			||||||
                kwargs[name] = arg.provide_injection()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return self.provides(*args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return represent_provider(provider=self, provides=self.provides)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedCallable(Callable):
 | 
					 | 
				
			||||||
    """:py:class:`DelegatedCallable` is a delegated :py:class:`Callable`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected
 | 
					 | 
				
			||||||
    "as is".
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def provide_injection(self):
 | 
					 | 
				
			||||||
        """Injection strategy implementation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: object
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
							
								
								
									
										42
									
								
								src/dependency_injector/providers/callables.pxd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/dependency_injector/providers/callables.pxd
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					"""Dependency injector callable providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base cimport Provider
 | 
				
			||||||
 | 
					from .injections cimport (
 | 
				
			||||||
 | 
					    PositionalInjection,
 | 
				
			||||||
 | 
					    NamedInjection,
 | 
				
			||||||
 | 
					    __provide_positional_args,
 | 
				
			||||||
 | 
					    __provide_keyword_args,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Callable(Provider):
 | 
				
			||||||
 | 
					    cdef object __provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef tuple __args
 | 
				
			||||||
 | 
					    cdef int __args_len
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef tuple __kwargs
 | 
				
			||||||
 | 
					    cdef int __kwargs_len
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef inline object __provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        cdef tuple positional_args
 | 
				
			||||||
 | 
					        cdef dict keyword_args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        positional_args = __provide_positional_args(args,
 | 
				
			||||||
 | 
					                                                    self.__args,
 | 
				
			||||||
 | 
					                                                    self.__args_len)
 | 
				
			||||||
 | 
					        keyword_args = __provide_keyword_args(kwargs,
 | 
				
			||||||
 | 
					                                              self.__kwargs,
 | 
				
			||||||
 | 
					                                              self.__kwargs_len)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.__provides(*positional_args, **keyword_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedCallable(Callable):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
							
								
								
									
										208
									
								
								src/dependency_injector/providers/callables.pyx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								src/dependency_injector/providers/callables.pyx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,208 @@
 | 
				
			||||||
 | 
					"""Dependency injector callable providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base cimport Provider
 | 
				
			||||||
 | 
					from .injections cimport (
 | 
				
			||||||
 | 
					    PositionalInjection,
 | 
				
			||||||
 | 
					    NamedInjection,
 | 
				
			||||||
 | 
					    parse_positional_injections,
 | 
				
			||||||
 | 
					    parse_named_injections,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from .utils cimport (
 | 
				
			||||||
 | 
					    represent_provider,
 | 
				
			||||||
 | 
					    deepcopy,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Callable(Provider):
 | 
				
			||||||
 | 
					    r"""Callable provider calls wrapped callable on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Callable supports positional and keyword argument injections:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        some_function = Callable(some_function,
 | 
				
			||||||
 | 
					                                 'positional_arg1', 'positional_arg2',
 | 
				
			||||||
 | 
					                                 keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        some_function = Callable(some_function) \
 | 
				
			||||||
 | 
					            .add_args('positional_arg1', 'positional_arg2') \
 | 
				
			||||||
 | 
					            .add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        some_function = Callable(some_function)
 | 
				
			||||||
 | 
					        some_function.add_args('positional_arg1', 'positional_arg2')
 | 
				
			||||||
 | 
					        some_function.add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Wrapped callable.
 | 
				
			||||||
 | 
					        :type provides: callable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of positional argument injections.
 | 
				
			||||||
 | 
					        :type args: tuple[object]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of context keyword argument injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict[str, object]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if not callable(provides):
 | 
				
			||||||
 | 
					            raise Error('Provider {0} expected to get callable, '
 | 
				
			||||||
 | 
					                        'got {0}'.format('.'.join((self.__class__.__module__,
 | 
				
			||||||
 | 
					                                                   self.__class__.__name__)),
 | 
				
			||||||
 | 
					                                         provides))
 | 
				
			||||||
 | 
					        self.__provides = provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.__args = tuple()
 | 
				
			||||||
 | 
					        self.__args_len = 0
 | 
				
			||||||
 | 
					        self.set_args(*args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.__kwargs = tuple()
 | 
				
			||||||
 | 
					        self.__kwargs_len = 0
 | 
				
			||||||
 | 
					        self.set_kwargs(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super(Callable, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self.provides,
 | 
				
			||||||
 | 
					                                *deepcopy(self.args, memo),
 | 
				
			||||||
 | 
					                                **deepcopy(self.kwargs, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for overriding_provider in self.overridden:
 | 
				
			||||||
 | 
					            copied.override(deepcopy(overriding_provider, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return represent_provider(provider=self, provides=self.__provides)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def provides(self):
 | 
				
			||||||
 | 
					        """Return wrapped callable."""
 | 
				
			||||||
 | 
					        return self.__provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def args(self):
 | 
				
			||||||
 | 
					        """Return positional argument injections."""
 | 
				
			||||||
 | 
					        cdef int index
 | 
				
			||||||
 | 
					        cdef PositionalInjection arg
 | 
				
			||||||
 | 
					        cdef list args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        args = list()
 | 
				
			||||||
 | 
					        for index in range(self.__args_len):
 | 
				
			||||||
 | 
					            arg = self.__args[index]
 | 
				
			||||||
 | 
					            args.append(arg.__value)
 | 
				
			||||||
 | 
					        return tuple(args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_args(self, *args):
 | 
				
			||||||
 | 
					        """Add postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__args += parse_positional_injections(args)
 | 
				
			||||||
 | 
					        self.__args_len = len(self.__args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_args(self, *args):
 | 
				
			||||||
 | 
					        """Set postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing positional argument injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__args = parse_positional_injections(args)
 | 
				
			||||||
 | 
					        self.__args_len = len(self.__args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_args(self):
 | 
				
			||||||
 | 
					        """Drop postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__args = tuple()
 | 
				
			||||||
 | 
					        self.__args_len = len(self.__args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def kwargs(self):
 | 
				
			||||||
 | 
					        """Return keyword argument injections."""
 | 
				
			||||||
 | 
					        cdef int index
 | 
				
			||||||
 | 
					        cdef NamedInjection kwarg
 | 
				
			||||||
 | 
					        cdef dict kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        kwargs = dict()
 | 
				
			||||||
 | 
					        for index in range(self.__kwargs_len):
 | 
				
			||||||
 | 
					            kwarg = self.__kwargs[index]
 | 
				
			||||||
 | 
					            kwargs[kwarg.__name] = kwarg.__value
 | 
				
			||||||
 | 
					        return kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Add keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__kwargs += parse_named_injections(kwargs)
 | 
				
			||||||
 | 
					        self.__kwargs_len = len(self.__kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Set keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing keyword argument injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__kwargs = parse_named_injections(kwargs)
 | 
				
			||||||
 | 
					        self.__kwargs_len = len(self.__kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_kwargs(self):
 | 
				
			||||||
 | 
					        """Drop keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__kwargs = tuple()
 | 
				
			||||||
 | 
					        self.__kwargs_len = len(self.__kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        """Return result of provided callable's call."""
 | 
				
			||||||
 | 
					        return self.__provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedCallable(Callable):
 | 
				
			||||||
 | 
					    """Callable that is injected "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DelegatedCallable is a :py:class:`Callable`, that is injected "as is".
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_DELEGATED__ = True
 | 
				
			||||||
| 
						 | 
					@ -1,342 +0,0 @@
 | 
				
			||||||
"""Dependency injector creational providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import threading
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.providers.callable import Callable
 | 
					 | 
				
			||||||
from dependency_injector.providers.base import _parse_keyword_injections
 | 
					 | 
				
			||||||
from .utils import GLOBAL_LOCK
 | 
					 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Factory(Callable):
 | 
					 | 
				
			||||||
    r""":py:class:`Factory` provider creates new instance on every call.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`Factory` supports positional & keyword argument injections,
 | 
					 | 
				
			||||||
    as well as attribute injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Positional and keyword argument injections could be defined like this:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        factory = Factory(SomeClass,
 | 
					 | 
				
			||||||
                          'positional_arg1', 'positional_arg2',
 | 
					 | 
				
			||||||
                          keyword_argument1=3, keyword_argument=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # or
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        factory = Factory(SomeClass) \
 | 
					 | 
				
			||||||
            .add_args('positional_arg1', 'positional_arg2') \
 | 
					 | 
				
			||||||
            .add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # or
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        factory = Factory(SomeClass)
 | 
					 | 
				
			||||||
        factory.add_args('positional_arg1', 'positional_arg2')
 | 
					 | 
				
			||||||
        factory.add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attribute injections are defined by using :py:meth:`Factory.attributes`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        factory = Factory(SomeClass) \
 | 
					 | 
				
			||||||
            .add_attributes(attribute1=1, attribute2=2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Retrieving of provided instance can be performed via calling
 | 
					 | 
				
			||||||
    :py:class:`Factory` object:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        factory = Factory(SomeClass)
 | 
					 | 
				
			||||||
        some_object = factory()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provided type is defined, provider checks that providing class is
 | 
					 | 
				
			||||||
        its subclass.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class that provides object.
 | 
					 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provided_type = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __slots__ = ('cls', 'attributes')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, provides, *args, **kwargs):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param provides: Class or other callable that provides object
 | 
					 | 
				
			||||||
            for creation.
 | 
					 | 
				
			||||||
        :type provides: type | callable
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if (self.__class__.provided_type and
 | 
					 | 
				
			||||||
                not issubclass(provides, self.__class__.provided_type)):
 | 
					 | 
				
			||||||
            raise Error('{0} can provide only {1} instances'.format(
 | 
					 | 
				
			||||||
                self.__class__, self.__class__.provided_type))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.attributes = dict()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        super(Factory, self).__init__(provides, *args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.cls = self.provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def add_attributes(self, **kwargs):
 | 
					 | 
				
			||||||
        """Add attribute injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					 | 
				
			||||||
        :type kwargs: dict
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Reference ``self``
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.attributes.update(_parse_keyword_injections(kwargs))
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        instance = super(Factory, self)._provide(*args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for name, arg in six.iteritems(self.attributes):
 | 
					 | 
				
			||||||
            setattr(instance, name, arg.provide_injection())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedFactory(Factory):
 | 
					 | 
				
			||||||
    """:py:class:`Factory` that is injected "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provided type is defined, provider checks that providing class is
 | 
					 | 
				
			||||||
        its subclass.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class that provides object.
 | 
					 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def provide_injection(self):
 | 
					 | 
				
			||||||
        """Injection strategy implementation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: object
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Singleton(Factory):
 | 
					 | 
				
			||||||
    """:py:class:`Singleton` provider returns same instance on every call.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`Singleton` provider creates instance once and returns it on
 | 
					 | 
				
			||||||
    every call. :py:class:`Singleton` extends :py:class:`Factory`, so, please
 | 
					 | 
				
			||||||
    follow :py:class:`Factory` documentation for getting familiar with
 | 
					 | 
				
			||||||
    injections syntax.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`Singleton` is thread-safe and could be used in multithreading
 | 
					 | 
				
			||||||
    environment without any negative impact.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Retrieving of provided instance can be performed via calling
 | 
					 | 
				
			||||||
    :py:class:`Singleton` object:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        singleton = Singleton(SomeClass)
 | 
					 | 
				
			||||||
        some_object = singleton()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provided type is defined, provider checks that providing class is
 | 
					 | 
				
			||||||
        its subclass.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class that provides object.
 | 
					 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __slots__ = ('instance',)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, provides, *args, **kwargs):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param provides: Class or other callable that provides object
 | 
					 | 
				
			||||||
            for creation.
 | 
					 | 
				
			||||||
        :type provides: type | callable
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.instance = None
 | 
					 | 
				
			||||||
        super(Singleton, self).__init__(provides, *args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def reset(self):
 | 
					 | 
				
			||||||
        """Reset cached instance, if any.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.instance = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        with GLOBAL_LOCK:
 | 
					 | 
				
			||||||
            if self.instance is None:
 | 
					 | 
				
			||||||
                self.instance = super(Singleton, self)._provide(*args,
 | 
					 | 
				
			||||||
                                                                **kwargs)
 | 
					 | 
				
			||||||
        return self.instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedSingleton(Singleton):
 | 
					 | 
				
			||||||
    """:py:class:`Singleton` that is injected "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provided type is defined, provider checks that providing class is
 | 
					 | 
				
			||||||
        its subclass.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class that provides object.
 | 
					 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def provide_injection(self):
 | 
					 | 
				
			||||||
        """Injection strategy implementation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: object
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ThreadLocalSingleton(Factory):
 | 
					 | 
				
			||||||
    """:py:class:`ThreadLocalSingleton` is singleton based on thread locals.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`ThreadLocalSingleton` provider creates instance once for each
 | 
					 | 
				
			||||||
    thread and returns it on every call. :py:class:`ThreadLocalSingleton`
 | 
					 | 
				
			||||||
    extends :py:class:`Factory`, so, please follow :py:class:`Factory`
 | 
					 | 
				
			||||||
    documentation for getting familiar with injections syntax.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`ThreadLocalSingleton` is thread-safe and could be used in
 | 
					 | 
				
			||||||
    multithreading environment without any negative impact.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Retrieving of provided instance can be performed via calling
 | 
					 | 
				
			||||||
    :py:class:`ThreadLocalSingleton` object:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        singleton = ThreadLocalSingleton(SomeClass)
 | 
					 | 
				
			||||||
        some_object = singleton()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provided type is defined, provider checks that providing class is
 | 
					 | 
				
			||||||
        its subclass.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class that provides object.
 | 
					 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __slots__ = ('local_storage',)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, provides, *args, **kwargs):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param provides: Class or other callable that provides object
 | 
					 | 
				
			||||||
            for creation.
 | 
					 | 
				
			||||||
        :type provides: type | callable
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.local_storage = threading.local()
 | 
					 | 
				
			||||||
        super(ThreadLocalSingleton, self).__init__(provides, *args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def reset(self):
 | 
					 | 
				
			||||||
        """Reset cached instance, if any.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.local_storage.instance = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            instance = self.local_storage.instance
 | 
					 | 
				
			||||||
        except AttributeError:
 | 
					 | 
				
			||||||
            instance = super(ThreadLocalSingleton, self)._provide(*args,
 | 
					 | 
				
			||||||
                                                                  **kwargs)
 | 
					 | 
				
			||||||
            self.local_storage.instance = instance
 | 
					 | 
				
			||||||
        finally:
 | 
					 | 
				
			||||||
            return instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
 | 
					 | 
				
			||||||
    """:py:class:`ThreadLocalSingleton` that is injected "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provided type is defined, provider checks that providing class is
 | 
					 | 
				
			||||||
        its subclass.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class that provides object.
 | 
					 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def provide_injection(self):
 | 
					 | 
				
			||||||
        """Injection strategy implementation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: object
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
							
								
								
									
										33
									
								
								src/dependency_injector/providers/factories.pxd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/dependency_injector/providers/factories.pxd
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					"""Dependency injector factory providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base cimport Provider
 | 
				
			||||||
 | 
					from .callables cimport Callable
 | 
				
			||||||
 | 
					from .injections cimport __inject_attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Factory(Provider):
 | 
				
			||||||
 | 
					    cdef Callable __instantiator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef tuple __attributes
 | 
				
			||||||
 | 
					    cdef int __attributes_len
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef inline object __provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        cdef object instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = self.__instantiator.__provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.__attributes_len > 0:
 | 
				
			||||||
 | 
					            __inject_attributes(instance,
 | 
				
			||||||
 | 
					                                self.__attributes,
 | 
				
			||||||
 | 
					                                self.__attributes_len)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedFactory(Factory):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
							
								
								
									
										270
									
								
								src/dependency_injector/providers/factories.pyx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/dependency_injector/providers/factories.pyx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,270 @@
 | 
				
			||||||
 | 
					"""Dependency injector factory providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base cimport Provider
 | 
				
			||||||
 | 
					from .callables cimport Callable
 | 
				
			||||||
 | 
					from .injections cimport (
 | 
				
			||||||
 | 
					    NamedInjection,
 | 
				
			||||||
 | 
					    parse_named_injections,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from .utils cimport (
 | 
				
			||||||
 | 
					    represent_provider,
 | 
				
			||||||
 | 
					    deepcopy,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Factory(Provider):
 | 
				
			||||||
 | 
					    r"""Factory provider creates new instance on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :py:class:`Factory` supports positional & keyword argument injections,
 | 
				
			||||||
 | 
					    as well as attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Positional and keyword argument injections could be defined like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass,
 | 
				
			||||||
 | 
					                          'positional_arg1', 'positional_arg2',
 | 
				
			||||||
 | 
					                          keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass) \
 | 
				
			||||||
 | 
					            .add_args('positional_arg1', 'positional_arg2') \
 | 
				
			||||||
 | 
					            .add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass)
 | 
				
			||||||
 | 
					        factory.add_args('positional_arg1', 'positional_arg2')
 | 
				
			||||||
 | 
					        factory.add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Attribute injections are defined by using :py:meth:`Factory.attributes`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=1, attribute2=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Retrieving of provided instance can be performed via calling
 | 
				
			||||||
 | 
					    :py:class:`Factory` object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass)
 | 
				
			||||||
 | 
					        some_object = factory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provided_type = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Provided type.
 | 
				
			||||||
 | 
					        :type provides: type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of positional argument injections.
 | 
				
			||||||
 | 
					        :type args: tuple[object]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of context keyword argument injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict[str, object]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if (self.__class__.provided_type and
 | 
				
			||||||
 | 
					                not issubclass(provides, self.__class__.provided_type)):
 | 
				
			||||||
 | 
					            raise Error('{0} can provide only {1} instances'.format(
 | 
				
			||||||
 | 
					                self.__class__, self.__class__.provided_type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.__instantiator = Callable(provides, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.__attributes = tuple()
 | 
				
			||||||
 | 
					        self.__attributes_len = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super(Factory, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self.cls,
 | 
				
			||||||
 | 
					                                *deepcopy(self.args, memo),
 | 
				
			||||||
 | 
					                                **deepcopy(self.kwargs, memo))
 | 
				
			||||||
 | 
					        copied.set_attributes(**deepcopy(self.attributes, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for overriding_provider in self.overridden:
 | 
				
			||||||
 | 
					            copied.override(deepcopy(overriding_provider, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return represent_provider(provider=self,
 | 
				
			||||||
 | 
					                                  provides=self.__instantiator.provides)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def cls(self):
 | 
				
			||||||
 | 
					        """Return provided type."""
 | 
				
			||||||
 | 
					        return self.__instantiator.provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def args(self):
 | 
				
			||||||
 | 
					        """Return positional argument injections."""
 | 
				
			||||||
 | 
					        return self.__instantiator.args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_args(self, *args):
 | 
				
			||||||
 | 
					        """Add __init__ postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.add_args(*args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_args(self, *args):
 | 
				
			||||||
 | 
					        """Set __init__ postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing __init__ positional argument injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.set_args(*args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_args(self):
 | 
				
			||||||
 | 
					        """Drop __init__ postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.clear_args()
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def kwargs(self):
 | 
				
			||||||
 | 
					        """Return keyword argument injections."""
 | 
				
			||||||
 | 
					        return self.__instantiator.kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Add __init__ keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.add_kwargs(**kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Set __init__ keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing __init__ keyword argument injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.set_kwargs(**kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_kwargs(self):
 | 
				
			||||||
 | 
					        """Drop __init__ keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.clear_kwargs()
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def attributes(self):
 | 
				
			||||||
 | 
					        """Return attribute injections."""
 | 
				
			||||||
 | 
					        cdef int index
 | 
				
			||||||
 | 
					        cdef NamedInjection attribute
 | 
				
			||||||
 | 
					        cdef dict attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attributes = dict()
 | 
				
			||||||
 | 
					        for index in range(self.__attributes_len):
 | 
				
			||||||
 | 
					            attribute = self.__attributes[index]
 | 
				
			||||||
 | 
					            attributes[attribute.__name] = attribute.__value
 | 
				
			||||||
 | 
					        return attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_attributes(self, **kwargs):
 | 
				
			||||||
 | 
					        """Add attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__attributes += parse_named_injections(kwargs)
 | 
				
			||||||
 | 
					        self.__attributes_len = len(self.__attributes)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_attributes(self, **kwargs):
 | 
				
			||||||
 | 
					        """Set attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing attribute injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__attributes = parse_named_injections(kwargs)
 | 
				
			||||||
 | 
					        self.__attributes_len = len(self.__attributes)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_attributes(self):
 | 
				
			||||||
 | 
					        """Drop attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__attributes = tuple()
 | 
				
			||||||
 | 
					        self.__attributes_len = len(self.__attributes)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        """Return new instance."""
 | 
				
			||||||
 | 
					        return self.__provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedFactory(Factory):
 | 
				
			||||||
 | 
					    """Factory that is injected "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Class that provides object.
 | 
				
			||||||
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_DELEGATED__ = True
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ Powered by Cython.
 | 
				
			||||||
cimport cython
 | 
					cimport cython
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Injection:
 | 
					cdef class Injection(object):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,9 +40,9 @@ cdef class NamedInjection(Injection):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@cython.boundscheck(False)
 | 
					@cython.boundscheck(False)
 | 
				
			||||||
@cython.wraparound(False)
 | 
					@cython.wraparound(False)
 | 
				
			||||||
cdef inline tuple __provide_positional_args(tuple inj_args,
 | 
					cdef inline tuple __provide_positional_args(tuple args,
 | 
				
			||||||
                                            int inj_args_len,
 | 
					                                            tuple inj_args,
 | 
				
			||||||
                                            tuple args):
 | 
					                                            int inj_args_len):
 | 
				
			||||||
    cdef int index
 | 
					    cdef int index
 | 
				
			||||||
    cdef list positional_args
 | 
					    cdef list positional_args
 | 
				
			||||||
    cdef PositionalInjection injection
 | 
					    cdef PositionalInjection injection
 | 
				
			||||||
| 
						 | 
					@ -53,29 +53,48 @@ cdef inline tuple __provide_positional_args(tuple inj_args,
 | 
				
			||||||
    positional_args = list()
 | 
					    positional_args = list()
 | 
				
			||||||
    for index in range(inj_args_len):
 | 
					    for index in range(inj_args_len):
 | 
				
			||||||
        injection = <PositionalInjection>inj_args[index]
 | 
					        injection = <PositionalInjection>inj_args[index]
 | 
				
			||||||
        positional_args.append(injection.get_value())
 | 
					        positional_args.append(injection.__get_value())
 | 
				
			||||||
    positional_args.extend(args)
 | 
					    positional_args.extend(args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return positional_args
 | 
					    return tuple(positional_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@cython.boundscheck(False)
 | 
					@cython.boundscheck(False)
 | 
				
			||||||
@cython.wraparound(False)
 | 
					@cython.wraparound(False)
 | 
				
			||||||
cdef inline dict __provide_keyword_args(tuple inj_kwargs,
 | 
					cdef inline dict __provide_keyword_args(dict kwargs,
 | 
				
			||||||
                                        int inj_kwargs_len,
 | 
					                                        tuple inj_kwargs,
 | 
				
			||||||
                                        dict kwargs):
 | 
					                                        int inj_kwargs_len):
 | 
				
			||||||
    cdef int index
 | 
					    cdef int index
 | 
				
			||||||
 | 
					    cdef object name
 | 
				
			||||||
    cdef NamedInjection kw_injection
 | 
					    cdef NamedInjection kw_injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if inj_kwargs_len == 0:
 | 
					    if len(kwargs) == 0:
 | 
				
			||||||
        return kwargs
 | 
					        for index in range(inj_kwargs_len):
 | 
				
			||||||
 | 
					            kw_injection = <NamedInjection>inj_kwargs[index]
 | 
				
			||||||
    for index in range(inj_kwargs_len):
 | 
					            name = kw_injection.__get_name()
 | 
				
			||||||
        kw_injection = <NamedInjection>inj_kwargs[index]
 | 
					            kwargs[name] = kw_injection.__get_value()
 | 
				
			||||||
        kwargs[kw_injection.get_name()] = kw_injection.get_value()
 | 
					    else:
 | 
				
			||||||
 | 
					        for index in range(inj_kwargs_len):
 | 
				
			||||||
 | 
					            kw_injection = <NamedInjection>inj_kwargs[index]
 | 
				
			||||||
 | 
					            name = kw_injection.__get_name()
 | 
				
			||||||
 | 
					            if name not in kwargs:
 | 
				
			||||||
 | 
					                kwargs[name] = kw_injection.__get_value()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return kwargs
 | 
					    return kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@cython.boundscheck(False)
 | 
				
			||||||
 | 
					@cython.wraparound(False)
 | 
				
			||||||
 | 
					cdef inline object __inject_attributes(object instance,
 | 
				
			||||||
 | 
					                                       tuple attributes,
 | 
				
			||||||
 | 
					                                       int attributes_len):
 | 
				
			||||||
 | 
					    cdef NamedInjection attr_injection
 | 
				
			||||||
 | 
					    for index in range(attributes_len):
 | 
				
			||||||
 | 
					        attr_injection = <NamedInjection>attributes[index]
 | 
				
			||||||
 | 
					        setattr(instance,
 | 
				
			||||||
 | 
					                attr_injection.__get_name(),
 | 
				
			||||||
 | 
					                attr_injection.__get_value())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cpdef tuple parse_positional_injections(tuple args)
 | 
					cpdef tuple parse_positional_injections(tuple args)
 | 
				
			||||||
cpdef tuple parse_named_injections(dict kwargs)
 | 
					cpdef tuple parse_named_injections(dict kwargs)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,10 +8,11 @@ cimport cython
 | 
				
			||||||
from .utils cimport (
 | 
					from .utils cimport (
 | 
				
			||||||
    is_provider,
 | 
					    is_provider,
 | 
				
			||||||
    is_delegated,
 | 
					    is_delegated,
 | 
				
			||||||
 | 
					    deepcopy,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Injection:
 | 
					cdef class Injection(object):
 | 
				
			||||||
    """Abstract injection class."""
 | 
					    """Abstract injection class."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +24,16 @@ cdef class PositionalInjection(Injection):
 | 
				
			||||||
        self.__value = value
 | 
					        self.__value = value
 | 
				
			||||||
        self.__is_provider = <int>is_provider(value)
 | 
					        self.__is_provider = <int>is_provider(value)
 | 
				
			||||||
        self.__is_delegated = <int>is_delegated(value)
 | 
					        self.__is_delegated = <int>is_delegated(value)
 | 
				
			||||||
        self.__call = <int>self.__is_provider == 1 and self.__is_delegated == 0
 | 
					        self.__call = <int>(self.__is_provider == 1 and
 | 
				
			||||||
 | 
					                            self.__is_delegated == 0)
 | 
				
			||||||
 | 
					        super(PositionalInjection, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					        return self.__class__(deepcopy(self.__value, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_value(self):
 | 
					    def get_value(self):
 | 
				
			||||||
        """Return injection value."""
 | 
					        """Return injection value."""
 | 
				
			||||||
| 
						 | 
					@ -43,7 +53,17 @@ cdef class NamedInjection(Injection):
 | 
				
			||||||
        self.__value = value
 | 
					        self.__value = value
 | 
				
			||||||
        self.__is_provider = <int>is_provider(value)
 | 
					        self.__is_provider = <int>is_provider(value)
 | 
				
			||||||
        self.__is_delegated = <int>is_delegated(value)
 | 
					        self.__is_delegated = <int>is_delegated(value)
 | 
				
			||||||
        self.__call = <int>self.__is_provider == 1 and self.__is_delegated == 0
 | 
					        self.__call = <int>(self.__is_provider == 1 and
 | 
				
			||||||
 | 
					                            self.__is_delegated == 0)
 | 
				
			||||||
 | 
					        super(NamedInjection, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					        return self.__class__(deepcopy(self.__name, memo),
 | 
				
			||||||
 | 
					                              deepcopy(self.__value, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_name(self):
 | 
					    def get_name(self):
 | 
				
			||||||
        """Return injection value."""
 | 
					        """Return injection value."""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										64
									
								
								src/dependency_injector/providers/singletons.pxd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/dependency_injector/providers/singletons.pxd
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					"""Dependency injector singleton providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base cimport Provider
 | 
				
			||||||
 | 
					from .factories cimport Factory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class BaseSingleton(Provider):
 | 
				
			||||||
 | 
					    cdef Factory __instantiator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Singleton(BaseSingleton):
 | 
				
			||||||
 | 
					    cdef object __storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef inline object __provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        if self.__storage is None:
 | 
				
			||||||
 | 
					            self.__storage = self.__instantiator.__provide(args, kwargs)
 | 
				
			||||||
 | 
					        return self.__storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedSingleton(Singleton):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class ThreadSafeSingleton(BaseSingleton):
 | 
				
			||||||
 | 
					    cdef object __storage
 | 
				
			||||||
 | 
					    cdef object __lock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef inline object __provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        with self.__lock:
 | 
				
			||||||
 | 
					            if self.__storage is None:
 | 
				
			||||||
 | 
					                self.__storage = self.__instantiator.__provide(args, kwargs)
 | 
				
			||||||
 | 
					        return self.__storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class ThreadLocalSingleton(BaseSingleton):
 | 
				
			||||||
 | 
					    cdef object __storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cdef inline object __provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        cdef object instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            instance = self.__storage.instance
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            instance = self.__instantiator.__provide(args, kwargs)
 | 
				
			||||||
 | 
					            self.__storage.instance = instance
 | 
				
			||||||
 | 
					        finally:
 | 
				
			||||||
 | 
					            return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
							
								
								
									
										393
									
								
								src/dependency_injector/providers/singletons.pyx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								src/dependency_injector/providers/singletons.pyx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,393 @@
 | 
				
			||||||
 | 
					"""Dependency injector singleton providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Powered by Cython.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import threading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base cimport Provider
 | 
				
			||||||
 | 
					from .factories cimport Factory
 | 
				
			||||||
 | 
					from .utils cimport (
 | 
				
			||||||
 | 
					    represent_provider,
 | 
				
			||||||
 | 
					    deepcopy,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GLOBAL_LOCK = threading.RLock()
 | 
				
			||||||
 | 
					"""Global reentrant lock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:type: :py:class:`threading.RLock`
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class BaseSingleton(Provider):
 | 
				
			||||||
 | 
					    """Base class of singleton providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provided_type = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Provided type.
 | 
				
			||||||
 | 
					        :type provides: type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of positional argument injections.
 | 
				
			||||||
 | 
					        :type args: tuple[object]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of context keyword argument injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict[str, object]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if (self.__class__.provided_type and
 | 
				
			||||||
 | 
					                not issubclass(provides, self.__class__.provided_type)):
 | 
				
			||||||
 | 
					            raise Error('{0} can provide only {1} instances'.format(
 | 
				
			||||||
 | 
					                self.__class__, self.__class__.provided_type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.__instantiator = Factory(provides, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super(BaseSingleton, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return represent_provider(provider=self,
 | 
				
			||||||
 | 
					                                  provides=self.__instantiator.cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self.cls,
 | 
				
			||||||
 | 
					                                *deepcopy(self.args, memo),
 | 
				
			||||||
 | 
					                                **deepcopy(self.kwargs, memo))
 | 
				
			||||||
 | 
					        copied.set_attributes(**deepcopy(self.attributes, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for overriding_provider in self.overridden:
 | 
				
			||||||
 | 
					            copied.override(deepcopy(overriding_provider, memo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def cls(self):
 | 
				
			||||||
 | 
					        """Return provided type."""
 | 
				
			||||||
 | 
					        return self.__instantiator.cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def args(self):
 | 
				
			||||||
 | 
					        """Return positional argument injections."""
 | 
				
			||||||
 | 
					        return self.__instantiator.args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_args(self, *args):
 | 
				
			||||||
 | 
					        """Add __init__ postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.add_args(*args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_args(self, *args):
 | 
				
			||||||
 | 
					        """Set __init__ postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing __init__ positional argument injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.set_args(*args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_args(self):
 | 
				
			||||||
 | 
					        """Drop __init__ postional argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.clear_args()
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def kwargs(self):
 | 
				
			||||||
 | 
					        """Return keyword argument injections."""
 | 
				
			||||||
 | 
					        return self.__instantiator.kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Add __init__ keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.add_kwargs(**kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Set __init__ keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing __init__ keyword argument injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.set_kwargs(**kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_kwargs(self):
 | 
				
			||||||
 | 
					        """Drop __init__ keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.clear_kwargs()
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def attributes(self):
 | 
				
			||||||
 | 
					        """Return attribute injections."""
 | 
				
			||||||
 | 
					        return self.__instantiator.attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_attributes(self, **kwargs):
 | 
				
			||||||
 | 
					        """Add attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.add_attributes(**kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_attributes(self, **kwargs):
 | 
				
			||||||
 | 
					        """Set attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Existing attribute injections are dropped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.set_attributes(**kwargs)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_attributes(self):
 | 
				
			||||||
 | 
					        """Drop attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__instantiator.clear_attributes()
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset(self):
 | 
				
			||||||
 | 
					        """Reset cached instance, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        raise NotImplementedError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Singleton(BaseSingleton):
 | 
				
			||||||
 | 
					    """Singleton provider returns same instance on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :py:class:`Singleton` provider creates instance once and returns it on
 | 
				
			||||||
 | 
					    every call. :py:class:`Singleton` extends :py:class:`Factory`, so, please
 | 
				
			||||||
 | 
					    follow :py:class:`Factory` documentation for getting familiar with
 | 
				
			||||||
 | 
					    injections syntax.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Retrieving of provided instance can be performed via calling
 | 
				
			||||||
 | 
					    :py:class:`Singleton` object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        singleton = Singleton(SomeClass)
 | 
				
			||||||
 | 
					        some_object = singleton()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Class that provides object.
 | 
				
			||||||
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Provided type.
 | 
				
			||||||
 | 
					        :type provides: type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of positional argument injections.
 | 
				
			||||||
 | 
					        :type args: tuple[object]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of context keyword argument injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict[str, object]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__storage = None
 | 
				
			||||||
 | 
					        super(Singleton, self).__init__(provides, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset(self):
 | 
				
			||||||
 | 
					        """Reset cached instance, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__storage = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        """Return single instance."""
 | 
				
			||||||
 | 
					        return self.__provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedSingleton(Singleton):
 | 
				
			||||||
 | 
					    """Delegated singleton is injected "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Class that provides object.
 | 
				
			||||||
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_DELEGATED__ = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class ThreadSafeSingleton(BaseSingleton):
 | 
				
			||||||
 | 
					    """Thread-safe singleton provider."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Provided type.
 | 
				
			||||||
 | 
					        :type provides: type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of positional argument injections.
 | 
				
			||||||
 | 
					        :type args: tuple[object]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of context keyword argument injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict[str, object]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__storage = None
 | 
				
			||||||
 | 
					        self.__lock = GLOBAL_LOCK
 | 
				
			||||||
 | 
					        super(ThreadSafeSingleton, self).__init__(provides, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset(self):
 | 
				
			||||||
 | 
					        """Reset cached instance, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__storage = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        """Return single instance."""
 | 
				
			||||||
 | 
					        return self.__provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
 | 
				
			||||||
 | 
					    """Delegated thread-safe singleton is injected "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Class that provides object.
 | 
				
			||||||
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_DELEGATED__ = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class ThreadLocalSingleton(BaseSingleton):
 | 
				
			||||||
 | 
					    """Thread-local singleton provides single objects in scope of thread.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Class that provides object.
 | 
				
			||||||
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provides: Provided type.
 | 
				
			||||||
 | 
					        :type provides: type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param args: Tuple of positional argument injections.
 | 
				
			||||||
 | 
					        :type args: tuple[object]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param kwargs: Dictionary of context keyword argument injections.
 | 
				
			||||||
 | 
					        :type kwargs: dict[str, object]
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__storage = threading.local()
 | 
				
			||||||
 | 
					        super(ThreadLocalSingleton, self).__init__(provides, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset(self):
 | 
				
			||||||
 | 
					        """Reset cached instance, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.__storage.instance = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        """Return single instance."""
 | 
				
			||||||
 | 
					        return self.__provide(args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
 | 
				
			||||||
 | 
					    """Delegated thread-local singleton is injected "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If provided type is defined, provider checks that providing class is
 | 
				
			||||||
 | 
					        its subclass.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Class that provides object.
 | 
				
			||||||
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_DELEGATED__ = True
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/dependency_injector/providers/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/dependency_injector/providers/utils.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					/* Generated by Cython 0.25.1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __PYX_HAVE__dependency_injector__providers__utils
 | 
				
			||||||
 | 
					#define __PYX_HAVE__dependency_injector__providers__utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __PYX_HAVE_API__dependency_injector__providers__utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __PYX_EXTERN_C
 | 
				
			||||||
 | 
					  #ifdef __cplusplus
 | 
				
			||||||
 | 
					    #define __PYX_EXTERN_C extern "C"
 | 
				
			||||||
 | 
					  #else
 | 
				
			||||||
 | 
					    #define __PYX_EXTERN_C extern
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef DL_IMPORT
 | 
				
			||||||
 | 
					  #define DL_IMPORT(_T) _T
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__PYX_EXTERN_C DL_IMPORT(PyObject) *__pyx_v_19dependency_injector_9providers_5utils_CLASS_TYPES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !__PYX_HAVE_API__dependency_injector__providers__utils */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if PY_MAJOR_VERSION < 3
 | 
				
			||||||
 | 
					PyMODINIT_FUNC initutils(void);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					PyMODINIT_FUNC PyInit_utils(void);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !__PYX_HAVE__dependency_injector__providers__utils */
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,11 @@
 | 
				
			||||||
Powered by Cython.
 | 
					Powered by Cython.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef public object CLASS_TYPES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cpdef bint is_provider(object instance)
 | 
					cpdef bint is_provider(object instance)
 | 
				
			||||||
cpdef object ensure_is_provider(object instance)
 | 
					cpdef object ensure_is_provider(object instance)
 | 
				
			||||||
cpdef bint is_delegated(object instance)
 | 
					cpdef bint is_delegated(object instance)
 | 
				
			||||||
cpdef str represent_provider(object provider, object provides)
 | 
					cpdef str represent_provider(object provider, object provides)
 | 
				
			||||||
 | 
					cpdef object deepcopy(object instance, dict memo=*)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,23 +3,23 @@
 | 
				
			||||||
Powered by Cython.
 | 
					Powered by Cython.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import copy
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import types
 | 
					import types
 | 
				
			||||||
 | 
					 | 
				
			||||||
import threading
 | 
					import threading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLOBAL_LOCK = threading.RLock()
 | 
					 | 
				
			||||||
"""Global reentrant lock.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
:type: :py:class:`threading.RLock`
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if sys.version_info[0] == 3:  # pragma: no cover
 | 
					if sys.version_info[0] == 3:  # pragma: no cover
 | 
				
			||||||
    _CLASS_TYPES = (type,)
 | 
					    CLASS_TYPES = (type,)
 | 
				
			||||||
else:  # pragma: no cover
 | 
					else:  # pragma: no cover
 | 
				
			||||||
    _CLASS_TYPES = (type, types.ClassType)
 | 
					    CLASS_TYPES = (type, types.ClassType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    copy._deepcopy_dispatch[types.MethodType] = \
 | 
				
			||||||
 | 
					        lambda obj, memo: type(obj)(obj.im_func,
 | 
				
			||||||
 | 
					                                    copy.deepcopy(obj.im_self, memo),
 | 
				
			||||||
 | 
					                                    obj.im_class)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cpdef bint is_provider(object instance):
 | 
					cpdef bint is_provider(object instance):
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ cpdef bint is_provider(object instance):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :rtype: bool
 | 
					    :rtype: bool
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return (not isinstance(instance, _CLASS_TYPES) and
 | 
					    return (not isinstance(instance, CLASS_TYPES) and
 | 
				
			||||||
            getattr(instance, '__IS_PROVIDER__', False) is True)
 | 
					            getattr(instance, '__IS_PROVIDER__', False) is True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,7 @@ cpdef bint is_delegated(object instance):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :rtype: bool
 | 
					    :rtype: bool
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return (not isinstance(instance, _CLASS_TYPES) and
 | 
					    return (not isinstance(instance, CLASS_TYPES) and
 | 
				
			||||||
            getattr(instance, '__IS_DELEGATED__', False) is True)
 | 
					            getattr(instance, '__IS_DELEGATED__', False) is True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,3 +80,7 @@ cpdef str represent_provider(object provider, object provides):
 | 
				
			||||||
                           provider.__class__.__name__)),
 | 
					                           provider.__class__.__name__)),
 | 
				
			||||||
        provides=repr(provides) if provides is not None else '',
 | 
					        provides=repr(provides) if provides is not None else '',
 | 
				
			||||||
        address=hex(id(provider)))
 | 
					        address=hex(id(provider)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cpdef object deepcopy(object instance, dict memo=None):
 | 
				
			||||||
 | 
					    """Return full copy of provider or container with providers."""
 | 
				
			||||||
 | 
					    return copy.deepcopy(instance, memo)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										177
									
								
								tests/performance/test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								tests/performance/test.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,177 @@
 | 
				
			||||||
 | 
					"""Test providers performance."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import gc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Tester(object):
 | 
				
			||||||
 | 
					    """Performance tester for provider module implementations."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, provider_modules, duration_factor):
 | 
				
			||||||
 | 
					        """Initializer."""
 | 
				
			||||||
 | 
					        self.provider_modules = provider_modules
 | 
				
			||||||
 | 
					        self.tests = [getattr(self, name)
 | 
				
			||||||
 | 
					                      for name in dir(self)
 | 
				
			||||||
 | 
					                      if name.startswith('test')]
 | 
				
			||||||
 | 
					        self.total_time = 0
 | 
				
			||||||
 | 
					        self.duration_factor = duration_factor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        """Run all tests for all provider modules."""
 | 
				
			||||||
 | 
					        for module in self.provider_modules:
 | 
				
			||||||
 | 
					            print('\n')
 | 
				
			||||||
 | 
					            print('Running tests for module - "{module}":'
 | 
				
			||||||
 | 
					                  .format(module=module.__name__))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            gc.disable()
 | 
				
			||||||
 | 
					            for test in self.tests:
 | 
				
			||||||
 | 
					                start_time = time.time()
 | 
				
			||||||
 | 
					                test(module)
 | 
				
			||||||
 | 
					                self.total_time = time.time() - start_time
 | 
				
			||||||
 | 
					                print('Test "{test}" took - {time}'
 | 
				
			||||||
 | 
					                      .format(test=test.__name__,
 | 
				
			||||||
 | 
					                              time=self.total_time))
 | 
				
			||||||
 | 
					                gc.collect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        gc.enable()
 | 
				
			||||||
 | 
					        print('\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#     def test_simple_object(self, providers):
 | 
				
			||||||
 | 
					#         """Test simple object's creation."""
 | 
				
			||||||
 | 
					#         class Test(object):
 | 
				
			||||||
 | 
					#             pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					#             Test()
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     def test_simple_object_factory(self, providers):
 | 
				
			||||||
 | 
					#         """Test simple object's factory."""
 | 
				
			||||||
 | 
					#         class Test(object):
 | 
				
			||||||
 | 
					#             pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         test_factory = providers.Factory(Test)
 | 
				
			||||||
 | 
					#         for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					#             test_factory()
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     def test_3_ctx_positional_injections(self, providers):
 | 
				
			||||||
 | 
					#         """Test factory with 3 context positional injections."""
 | 
				
			||||||
 | 
					#         class Test(object):
 | 
				
			||||||
 | 
					#             def __init__(self, a, b, c):
 | 
				
			||||||
 | 
					#                 pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					#             Test(1, 2, 3)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     def test_factory_3_ctx_positional_injections(self, providers):
 | 
				
			||||||
 | 
					#         """Test factory with 3 context positional injections."""
 | 
				
			||||||
 | 
					#         class Test(object):
 | 
				
			||||||
 | 
					#             def __init__(self, a, b, c):
 | 
				
			||||||
 | 
					#                 pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         test_factory = providers.Factory(Test)
 | 
				
			||||||
 | 
					#         for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					#             test_factory(1, 2, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_3_kw_injections(self, providers):
 | 
				
			||||||
 | 
					        """Test 3 keyword argument injections."""
 | 
				
			||||||
 | 
					        class A(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class B(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class C(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Test(object):
 | 
				
			||||||
 | 
					            def __init__(self, a, b, c):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					            Test(a=A(), b=B(), c=C())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_factory_3_factory_kw_injections(self, providers):
 | 
				
			||||||
 | 
					        """Test factory with 3 keyword argument injections via factories."""
 | 
				
			||||||
 | 
					        class A(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class B(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class C(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Test(object):
 | 
				
			||||||
 | 
					            def __init__(self, a, b, c):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        a_factory = providers.Factory(A)
 | 
				
			||||||
 | 
					        b_factory = providers.Factory(B)
 | 
				
			||||||
 | 
					        c_factory = providers.Factory(C)
 | 
				
			||||||
 | 
					        test_factory = providers.Factory(Test,
 | 
				
			||||||
 | 
					                                         a=a_factory,
 | 
				
			||||||
 | 
					                                         b=b_factory,
 | 
				
			||||||
 | 
					                                         c=c_factory)
 | 
				
			||||||
 | 
					        for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					            test_factory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_factory_subcls_3_factory_subcls_kw_injections(self, providers):
 | 
				
			||||||
 | 
					        """Test factory with 3 keyword argument injections via factories."""
 | 
				
			||||||
 | 
					        class MyFactory(providers.Factory):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class A(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class B(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class C(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Test(object):
 | 
				
			||||||
 | 
					            def __init__(self, a, b, c):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        a_factory = MyFactory(A)
 | 
				
			||||||
 | 
					        b_factory = MyFactory(B)
 | 
				
			||||||
 | 
					        c_factory = MyFactory(C)
 | 
				
			||||||
 | 
					        test_factory = MyFactory(Test,
 | 
				
			||||||
 | 
					                                 a=a_factory,
 | 
				
			||||||
 | 
					                                 b=b_factory,
 | 
				
			||||||
 | 
					                                 c=c_factory)
 | 
				
			||||||
 | 
					        for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					            test_factory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#     def test_singleton(self, providers):
 | 
				
			||||||
 | 
					#         """Test factory with 3 keyword argument injections via factories."""
 | 
				
			||||||
 | 
					#         class Test(object):
 | 
				
			||||||
 | 
					#             def __init__(self):
 | 
				
			||||||
 | 
					#                 pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         test_factory = providers.Singleton(Test)
 | 
				
			||||||
 | 
					#         for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					#             test_factory()
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     def test_singleton_subcls(self, providers):
 | 
				
			||||||
 | 
					#         """Test factory with 3 keyword argument injections via factories."""
 | 
				
			||||||
 | 
					#         class MySingleton(providers.Singleton):
 | 
				
			||||||
 | 
					#             pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         class Test(object):
 | 
				
			||||||
 | 
					#             pass
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         test_factory = MySingleton(Test)
 | 
				
			||||||
 | 
					#         for x in xrange(int(5000000 * self.duration_factor)):
 | 
				
			||||||
 | 
					#             test_factory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    tester = Tester(
 | 
				
			||||||
 | 
					        provider_modules=[
 | 
				
			||||||
 | 
					            dependency_injector.providers,
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        duration_factor=1)
 | 
				
			||||||
 | 
					    tester.run()
 | 
				
			||||||
| 
						 | 
					@ -80,23 +80,113 @@ class ProviderTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(self.provider.overridden, tuple())
 | 
					        self.assertEqual(self.provider.overridden, tuple())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_from_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.Provider()
 | 
				
			||||||
 | 
					        provider_copy_memo = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            provider, memo={id(provider): provider_copy_memo})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(provider_copy, provider_copy_memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.Provider()
 | 
				
			||||||
 | 
					        overriding_provider = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(overriding_provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        overriding_provider_copy = provider_copy.overridden[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(overriding_provider, overriding_provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(overriding_provider_copy, providers.Provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_repr(self):
 | 
					    def test_repr(self):
 | 
				
			||||||
        self.assertEqual(repr(self.provider),
 | 
					        self.assertEqual(repr(self.provider),
 | 
				
			||||||
                         '<dependency_injector.providers.base.'
 | 
					                         '<dependency_injector.providers.base.'
 | 
				
			||||||
                         'Provider() at {0}>'.format(hex(id(self.provider))))
 | 
					                         'Provider() at {0}>'.format(hex(id(self.provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ObjectProviderTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_provider(self):
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_provider(providers.Object(object())))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_object_provider(self):
 | 
				
			||||||
 | 
					        obj = object()
 | 
				
			||||||
 | 
					        self.assertIs(providers.Object(obj)(), obj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_overridden_object_provider(self):
 | 
				
			||||||
 | 
					        obj1 = object()
 | 
				
			||||||
 | 
					        obj2 = object()
 | 
				
			||||||
 | 
					        provider = providers.Object(obj1)
 | 
				
			||||||
 | 
					        provider.override(providers.Object(obj2))
 | 
				
			||||||
 | 
					        self.assertIs(provider(), obj2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.Object(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_from_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.Object(1)
 | 
				
			||||||
 | 
					        provider_copy_memo = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            provider, memo={id(provider): provider_copy_memo})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(provider_copy, provider_copy_memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.Object(1)
 | 
				
			||||||
 | 
					        overriding_provider = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(overriding_provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        overriding_provider_copy = provider_copy.overridden[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(overriding_provider, overriding_provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(overriding_provider_copy, providers.Provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        some_object = object()
 | 
				
			||||||
 | 
					        provider = providers.Object(some_object)
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.base.'
 | 
				
			||||||
 | 
					                         'Object({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(some_object),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DelegateTests(unittest.TestCase):
 | 
					class DelegateTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.delegated = providers.Provider()
 | 
					        self.delegated = providers.Provider()
 | 
				
			||||||
        self.delegate = providers.Delegate(delegated=self.delegated)
 | 
					        self.delegate = providers.Delegate(self.delegated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_is_provider(self):
 | 
					    def test_is_provider(self):
 | 
				
			||||||
        self.assertTrue(providers.is_provider(self.delegate))
 | 
					        self.assertTrue(providers.is_provider(self.delegate))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_init_with_not_provider(self):
 | 
					    def test_init_with_not_provider(self):
 | 
				
			||||||
        self.assertRaises(errors.Error, providers.Delegate, delegated=object())
 | 
					        self.assertRaises(errors.Error, providers.Delegate, object())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_call(self):
 | 
					    def test_call(self):
 | 
				
			||||||
        delegated1 = self.delegate()
 | 
					        delegated1 = self.delegate()
 | 
				
			||||||
| 
						 | 
					@ -119,7 +209,7 @@ class ExternalDependencyTests(unittest.TestCase):
 | 
				
			||||||
        self.provider = providers.ExternalDependency(instance_of=list)
 | 
					        self.provider = providers.ExternalDependency(instance_of=list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_init_with_not_class(self):
 | 
					    def test_init_with_not_class(self):
 | 
				
			||||||
        self.assertRaises(errors.Error, providers.ExternalDependency, object())
 | 
					        self.assertRaises(TypeError, providers.ExternalDependency, object())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_is_provider(self):
 | 
					    def test_is_provider(self):
 | 
				
			||||||
        self.assertTrue(providers.is_provider(self.provider))
 | 
					        self.assertTrue(providers.is_provider(self.provider))
 | 
				
			||||||
| 
						 | 
					@ -135,6 +225,38 @@ class ExternalDependencyTests(unittest.TestCase):
 | 
				
			||||||
    def test_call_not_overridden(self):
 | 
					    def test_call_not_overridden(self):
 | 
				
			||||||
        self.assertRaises(errors.Error, self.provider)
 | 
					        self.assertRaises(errors.Error, self.provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.ExternalDependency(int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.ExternalDependency)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_from_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.ExternalDependency(int)
 | 
				
			||||||
 | 
					        provider_copy_memo = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            provider, memo={id(provider): provider_copy_memo})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(provider_copy, provider_copy_memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.ExternalDependency(int)
 | 
				
			||||||
 | 
					        overriding_provider = providers.Provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(overriding_provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        overriding_provider_copy = provider_copy.overridden[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.ExternalDependency)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(overriding_provider, overriding_provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(overriding_provider_copy, providers.Provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_repr(self):
 | 
					    def test_repr(self):
 | 
				
			||||||
        self.assertEqual(repr(self.provider),
 | 
					        self.assertEqual(repr(self.provider),
 | 
				
			||||||
                         '<dependency_injector.providers.base.'
 | 
					                         '<dependency_injector.providers.base.'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,91 +0,0 @@
 | 
				
			||||||
"""Dependency injector callable providers unit tests."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import unittest2 as unittest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import (
 | 
					 | 
				
			||||||
    providers,
 | 
					 | 
				
			||||||
    errors,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CallableTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def example(self, arg1, arg2, arg3, arg4):
 | 
					 | 
				
			||||||
        return arg1, arg2, arg3, arg4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_callable(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.Callable(self.example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_not_callable(self):
 | 
					 | 
				
			||||||
        self.assertRaises(errors.Error, providers.Callable, 123)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(lambda: True)
 | 
					 | 
				
			||||||
        self.assertTrue(provider())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_positional_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example,
 | 
					 | 
				
			||||||
                                      1, 2, 3, 4)
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example,
 | 
					 | 
				
			||||||
                                      arg1=1, arg2=2, arg3=3, arg4=4)
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_positional_and_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example,
 | 
					 | 
				
			||||||
                                      1, 2,
 | 
					 | 
				
			||||||
                                      arg3=3, arg4=4)
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example, 1, 2)
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(3, 4), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example, arg1=1)
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(arg2=2, arg3=3, arg4=4), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args_and_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example, 1)
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(2, arg3=3, arg4=4), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_fluent_interface(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(self.example) \
 | 
					 | 
				
			||||||
            .add_args(1, 2) \
 | 
					 | 
				
			||||||
            .add_kwargs(arg3=3, arg4=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_overridden(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider.override(providers.Object((4, 3, 2, 1)))
 | 
					 | 
				
			||||||
        provider.override(providers.Object((1, 2, 3, 4)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_repr(self):
 | 
					 | 
				
			||||||
        provider = providers.Callable(self.example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(repr(provider),
 | 
					 | 
				
			||||||
                         '<dependency_injector.providers.callable.'
 | 
					 | 
				
			||||||
                         'Callable({0}) at {1}>'.format(
 | 
					 | 
				
			||||||
                             repr(self.example),
 | 
					 | 
				
			||||||
                             hex(id(provider))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedCallableTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_inheritance(self):
 | 
					 | 
				
			||||||
        self.assertIsInstance(providers.DelegatedCallable(len),
 | 
					 | 
				
			||||||
                              providers.Callable)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(
 | 
					 | 
				
			||||||
            providers.is_provider(providers.DelegatedCallable(len)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_delegated_provider(self):
 | 
					 | 
				
			||||||
        provider = providers.DelegatedCallable(len)
 | 
					 | 
				
			||||||
        self.assertIs(provider.provide_injection(), provider)
 | 
					 | 
				
			||||||
							
								
								
									
										191
									
								
								tests/unit/providers/test_callables.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								tests/unit/providers/test_callables.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,191 @@
 | 
				
			||||||
 | 
					"""Dependency injector callable providers unit tests."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest2 as unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import (
 | 
				
			||||||
 | 
					    providers,
 | 
				
			||||||
 | 
					    errors,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CallableTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def example(self, arg1, arg2, arg3, arg4):
 | 
				
			||||||
 | 
					        return arg1, arg2, arg3, arg4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_callable(self):
 | 
				
			||||||
 | 
					        self.assertTrue(providers.Callable(self.example))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_not_callable(self):
 | 
				
			||||||
 | 
					        self.assertRaises(errors.Error, providers.Callable, 123)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(lambda: True)
 | 
				
			||||||
 | 
					        self.assertTrue(provider())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_positional_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example,
 | 
				
			||||||
 | 
					                                      1, 2, 3, 4)
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_keyword_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example,
 | 
				
			||||||
 | 
					                                      arg1=1, arg2=2, arg3=3, arg4=4)
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_positional_and_keyword_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example,
 | 
				
			||||||
 | 
					                                      1, 2,
 | 
				
			||||||
 | 
					                                      arg3=3, arg4=4)
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example, 1, 2)
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(3, 4), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example, arg1=1)
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(arg2=2, arg3=3, arg4=4), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_args_and_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example, 1)
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(2, arg3=3, arg4=4), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_fluent_interface(self):
 | 
				
			||||||
 | 
					        provider = providers.Singleton(self.example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .add_kwargs(arg3=3, arg4=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .set_args(3, 4)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.args, tuple([3, 4]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .set_kwargs(init_arg3=4, init_arg4=5)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .clear_args()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.args, tuple())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .clear_kwargs()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.kwargs, dict())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(providers.Object((4, 3, 2, 1)))
 | 
				
			||||||
 | 
					        provider.override(providers.Object((1, 2, 3, 4)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTupleEqual(provider(), (1, 2, 3, 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIs(provider.provides, provider_copy.provides)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Callable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_from_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					        provider_copy_memo = providers.Callable(self.example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            provider, memo={id(provider): provider_copy_memo})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(provider_copy, provider_copy_memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					        dependent_provider1 = providers.Callable(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = providers.Callable(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_args(dependent_provider1, dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.args[0]
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.args[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.args, provider_copy.args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.provides,
 | 
				
			||||||
 | 
					                      dependent_provider_copy1.provides)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.provides,
 | 
				
			||||||
 | 
					                      dependent_provider_copy2.provides)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					        dependent_provider1 = providers.Callable(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = providers.Callable(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.kwargs['a1']
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.kwargs['a2']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.provides,
 | 
				
			||||||
 | 
					                      dependent_provider_copy1.provides)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.provides,
 | 
				
			||||||
 | 
					                      dependent_provider_copy2.provides)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					        object_provider = providers.Object(object())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(object_provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        object_provider_copy = provider_copy.overridden[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIs(provider.provides, provider_copy.provides)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Callable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(object_provider, object_provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(object_provider_copy, providers.Object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = providers.Callable(self.example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.callables.'
 | 
				
			||||||
 | 
					                         'Callable({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(self.example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DelegatedCallableTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_inheritance(self):
 | 
				
			||||||
 | 
					        self.assertIsInstance(providers.DelegatedCallable(len),
 | 
				
			||||||
 | 
					                              providers.Callable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_provider(self):
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            providers.is_provider(providers.DelegatedCallable(len)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_delegated_provider(self):
 | 
				
			||||||
 | 
					        provider = providers.DelegatedCallable(len)
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_delegated(provider))
 | 
				
			||||||
| 
						 | 
					@ -1,662 +0,0 @@
 | 
				
			||||||
"""Dependency injector creational providers unit tests."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import unittest2 as unittest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import (
 | 
					 | 
				
			||||||
    providers,
 | 
					 | 
				
			||||||
    errors,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Example(object):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None,
 | 
					 | 
				
			||||||
                 init_arg4=None):
 | 
					 | 
				
			||||||
        self.init_arg1 = init_arg1
 | 
					 | 
				
			||||||
        self.init_arg2 = init_arg2
 | 
					 | 
				
			||||||
        self.init_arg3 = init_arg3
 | 
					 | 
				
			||||||
        self.init_arg4 = init_arg4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.attribute1 = None
 | 
					 | 
				
			||||||
        self.attribute2 = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FactoryTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.is_provider(providers.Factory(Example)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_callable(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.Factory(credits))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_not_callable(self):
 | 
					 | 
				
			||||||
        self.assertRaises(errors.Error, providers.Factory, 123)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_valid_provided_type(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.Factory):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        example_provider = ExampleProvider(Example, 1, 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(example_provider(), Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_valid_provided_subtype(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.Factory):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class NewExampe(Example):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        example_provider = ExampleProvider(NewExampe, 1, 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(example_provider(), NewExampe)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_invalid_provided_type(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.Factory):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with self.assertRaises(errors.Error):
 | 
					 | 
				
			||||||
            ExampleProvider(list)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_positional_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example, 'i1', 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example, init_arg1='i1', init_arg2='i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_positional_and_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example, 'i1', init_arg2='i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_attributes(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example)
 | 
					 | 
				
			||||||
        provider.add_attributes(attribute1='a1', attribute2='a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.attribute1, 'a1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.attribute2, 'a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.attribute1, 'a1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.attribute2, 'a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example, 11, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider(33, 44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 33)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example, init_arg1=1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider(init_arg2=22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance2 = provider(init_arg1=11, init_arg2=22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args_and_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example, 11)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider(22, init_arg3=33, init_arg4=44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 33)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_fluent_interface(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example) \
 | 
					 | 
				
			||||||
            .add_args(1, 2) \
 | 
					 | 
				
			||||||
            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
					 | 
				
			||||||
            .add_attributes(attribute1=5, attribute2=6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 2)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 3)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 4)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.attribute1, 5)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.attribute2, 6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_overridden(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example)
 | 
					 | 
				
			||||||
        overriding_provider1 = providers.Factory(dict)
 | 
					 | 
				
			||||||
        overriding_provider2 = providers.Factory(list)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider.override(overriding_provider1)
 | 
					 | 
				
			||||||
        provider.override(overriding_provider2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, list)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, list)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_repr(self):
 | 
					 | 
				
			||||||
        provider = providers.Factory(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(repr(provider),
 | 
					 | 
				
			||||||
                         '<dependency_injector.providers.creational.'
 | 
					 | 
				
			||||||
                         'Factory({0}) at {1}>'.format(
 | 
					 | 
				
			||||||
                             repr(Example),
 | 
					 | 
				
			||||||
                             hex(id(provider))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedFactoryTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_inheritance(self):
 | 
					 | 
				
			||||||
        self.assertIsInstance(providers.DelegatedFactory(object),
 | 
					 | 
				
			||||||
                              providers.Factory)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(
 | 
					 | 
				
			||||||
            providers.is_provider(providers.DelegatedFactory(object)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_delegated_provider(self):
 | 
					 | 
				
			||||||
        provider = providers.DelegatedFactory(object)
 | 
					 | 
				
			||||||
        self.assertIs(provider.provide_injection(), provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SingletonTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.is_provider(providers.Singleton(Example)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_callable(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.Singleton(credits))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_not_callable(self):
 | 
					 | 
				
			||||||
        self.assertRaises(errors.Error, providers.Singleton, 123)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_valid_provided_type(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.Singleton):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        example_provider = ExampleProvider(Example, 1, 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(example_provider(), Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_valid_provided_subtype(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.Singleton):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class NewExampe(Example):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        example_provider = ExampleProvider(NewExampe, 1, 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(example_provider(), NewExampe)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_invalid_provided_type(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.Singleton):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with self.assertRaises(errors.Error):
 | 
					 | 
				
			||||||
            ExampleProvider(list)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_positional_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example, 'i1', 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example, init_arg1='i1', init_arg2='i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_positional_and_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example, 'i1', init_arg2='i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_attributes(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example)
 | 
					 | 
				
			||||||
        provider.add_attributes(attribute1='a1', attribute2='a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.attribute1, 'a1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.attribute2, 'a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.attribute1, 'a1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.attribute2, 'a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider(11, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example, init_arg1=1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider(init_arg2=22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Instance is created earlier
 | 
					 | 
				
			||||||
        instance1 = provider(init_arg1=11, init_arg2=22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args_and_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example, 11)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider(22, init_arg3=33, init_arg4=44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 33)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_fluent_interface(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example) \
 | 
					 | 
				
			||||||
            .add_args(1, 2) \
 | 
					 | 
				
			||||||
            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
					 | 
				
			||||||
            .add_attributes(attribute1=5, attribute2=6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 2)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 3)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 4)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.attribute1, 5)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.attribute2, 6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_overridden(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example)
 | 
					 | 
				
			||||||
        overriding_provider1 = providers.Singleton(dict)
 | 
					 | 
				
			||||||
        overriding_provider2 = providers.Singleton(object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider.override(overriding_provider1)
 | 
					 | 
				
			||||||
        provider.override(overriding_provider2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, object)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_reset(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider.reset()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_repr(self):
 | 
					 | 
				
			||||||
        provider = providers.Singleton(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(repr(provider),
 | 
					 | 
				
			||||||
                         '<dependency_injector.providers.creational.'
 | 
					 | 
				
			||||||
                         'Singleton({0}) at {1}>'.format(
 | 
					 | 
				
			||||||
                             repr(Example),
 | 
					 | 
				
			||||||
                             hex(id(provider))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedSingletonTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_inheritance(self):
 | 
					 | 
				
			||||||
        self.assertIsInstance(providers.DelegatedSingleton(object),
 | 
					 | 
				
			||||||
                              providers.Singleton)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(
 | 
					 | 
				
			||||||
            providers.is_provider(providers.DelegatedSingleton(object)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_delegated_provider(self):
 | 
					 | 
				
			||||||
        provider = providers.DelegatedSingleton(object)
 | 
					 | 
				
			||||||
        self.assertIs(provider.provide_injection(), provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ThreadLocalSingletonTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(
 | 
					 | 
				
			||||||
            providers.is_provider(providers.ThreadLocalSingleton(Example)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_callable(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.ThreadLocalSingleton(credits))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_not_callable(self):
 | 
					 | 
				
			||||||
        self.assertRaises(errors.Error, providers.ThreadLocalSingleton, 123)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_valid_provided_type(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.ThreadLocalSingleton):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        example_provider = ExampleProvider(Example, 1, 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(example_provider(), Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_valid_provided_subtype(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.ThreadLocalSingleton):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class NewExampe(Example):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        example_provider = ExampleProvider(NewExampe, 1, 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(example_provider(), NewExampe)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_init_with_invalid_provided_type(self):
 | 
					 | 
				
			||||||
        class ExampleProvider(providers.ThreadLocalSingleton):
 | 
					 | 
				
			||||||
            provided_type = Example
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with self.assertRaises(errors.Error):
 | 
					 | 
				
			||||||
            ExampleProvider(list)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_positional_args(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example, 'i1', 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example,
 | 
					 | 
				
			||||||
                                                  init_arg1='i1',
 | 
					 | 
				
			||||||
                                                  init_arg2='i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_init_positional_and_keyword_args(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example,
 | 
					 | 
				
			||||||
                                                  'i1',
 | 
					 | 
				
			||||||
                                                  init_arg2='i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg1, 'i1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.init_arg2, 'i2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_attributes(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example)
 | 
					 | 
				
			||||||
        provider.add_attributes(attribute1='a1', attribute2='a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.attribute1, 'a1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.attribute2, 'a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.attribute1, 'a1')
 | 
					 | 
				
			||||||
        self.assertEqual(instance2.attribute2, 'a2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, Example)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider(11, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example, init_arg1=1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider(init_arg2=22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Instance is created earlier
 | 
					 | 
				
			||||||
        instance1 = provider(init_arg1=11, init_arg2=22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance1.init_arg2, 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_with_context_args_and_kwargs(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example, 11)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider(22, init_arg3=33, init_arg4=44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 11)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 22)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 33)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 44)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_fluent_interface(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example) \
 | 
					 | 
				
			||||||
            .add_args(1, 2) \
 | 
					 | 
				
			||||||
            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
					 | 
				
			||||||
            .add_attributes(attribute1=5, attribute2=6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg1, 1)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg2, 2)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg3, 3)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.init_arg4, 4)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.attribute1, 5)
 | 
					 | 
				
			||||||
        self.assertEqual(instance.attribute2, 6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_overridden(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example)
 | 
					 | 
				
			||||||
        overriding_provider1 = providers.ThreadLocalSingleton(dict)
 | 
					 | 
				
			||||||
        overriding_provider2 = providers.ThreadLocalSingleton(object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider.override(overriding_provider1)
 | 
					 | 
				
			||||||
        provider.override(overriding_provider2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIs(instance1, instance2)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, object)
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance2, object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_reset(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance1 = provider()
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        provider.reset()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance2 = provider()
 | 
					 | 
				
			||||||
        self.assertIsInstance(instance1, object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_repr(self):
 | 
					 | 
				
			||||||
        provider = providers.ThreadLocalSingleton(Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(repr(provider),
 | 
					 | 
				
			||||||
                         '<dependency_injector.providers.creational.'
 | 
					 | 
				
			||||||
                         'ThreadLocalSingleton({0}) at {1}>'.format(
 | 
					 | 
				
			||||||
                             repr(Example),
 | 
					 | 
				
			||||||
                             hex(id(provider))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DelegatedThreadLocalSingletonTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_inheritance(self):
 | 
					 | 
				
			||||||
        self.assertIsInstance(providers.DelegatedThreadLocalSingleton(object),
 | 
					 | 
				
			||||||
                              providers.ThreadLocalSingleton)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(
 | 
					 | 
				
			||||||
            providers.is_provider(
 | 
					 | 
				
			||||||
                providers.DelegatedThreadLocalSingleton(object)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_delegated_provider(self):
 | 
					 | 
				
			||||||
        provider = providers.DelegatedThreadLocalSingleton(object)
 | 
					 | 
				
			||||||
        self.assertIs(provider.provide_injection(), provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FactoryAsDecoratorTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_decoration_and_overriding(self):
 | 
					 | 
				
			||||||
        @providers.Factory
 | 
					 | 
				
			||||||
        class AuthService(object):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @providers.override(AuthService)
 | 
					 | 
				
			||||||
        @providers.Factory
 | 
					 | 
				
			||||||
        class ExtAuthService(AuthService.cls):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auth_service = AuthService()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertIsInstance(auth_service, ExtAuthService.cls)
 | 
					 | 
				
			||||||
							
								
								
									
										346
									
								
								tests/unit/providers/test_factories.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								tests/unit/providers/test_factories.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,346 @@
 | 
				
			||||||
 | 
					"""Dependency injector factory providers unit tests."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest2 as unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import (
 | 
				
			||||||
 | 
					    providers,
 | 
				
			||||||
 | 
					    errors,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Example(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None,
 | 
				
			||||||
 | 
					                 init_arg4=None):
 | 
				
			||||||
 | 
					        self.init_arg1 = init_arg1
 | 
				
			||||||
 | 
					        self.init_arg2 = init_arg2
 | 
				
			||||||
 | 
					        self.init_arg3 = init_arg3
 | 
				
			||||||
 | 
					        self.init_arg4 = init_arg4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.attribute1 = None
 | 
				
			||||||
 | 
					        self.attribute2 = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FactoryTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_provider(self):
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_provider(providers.Factory(Example)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_callable(self):
 | 
				
			||||||
 | 
					        self.assertTrue(providers.Factory(credits))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_not_callable(self):
 | 
				
			||||||
 | 
					        self.assertRaises(errors.Error, providers.Factory, 123)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_valid_provided_type(self):
 | 
				
			||||||
 | 
					        class ExampleProvider(providers.Factory):
 | 
				
			||||||
 | 
					            provided_type = Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        example_provider = ExampleProvider(Example, 1, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsInstance(example_provider(), Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_valid_provided_subtype(self):
 | 
				
			||||||
 | 
					        class ExampleProvider(providers.Factory):
 | 
				
			||||||
 | 
					            provided_type = Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class NewExampe(Example):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        example_provider = ExampleProvider(NewExampe, 1, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsInstance(example_provider(), NewExampe)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_invalid_provided_type(self):
 | 
				
			||||||
 | 
					        class ExampleProvider(providers.Factory):
 | 
				
			||||||
 | 
					            provided_type = Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with self.assertRaises(errors.Error):
 | 
				
			||||||
 | 
					            ExampleProvider(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_init_positional_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example, 'i1', 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_init_keyword_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example, init_arg1='i1', init_arg2='i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_init_positional_and_keyword_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example, 'i1', init_arg2='i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_attributes(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        provider.add_attributes(attribute1='a1', attribute2='a2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.attribute1, 'a1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.attribute2, 'a2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.attribute1, 'a1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.attribute2, 'a2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example, 11, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = provider(33, 44)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg1, 11)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg2, 22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg3, 33)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg4, 44)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example, init_arg1=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider(init_arg2=22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 1)
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance2 = provider(init_arg1=11, init_arg2=22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 11)
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_args_and_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example, 11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = provider(22, init_arg3=33, init_arg4=44)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg1, 11)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg2, 22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg3, 33)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg4, 44)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_fluent_interface(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=5, attribute2=6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg1, 1)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg2, 2)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg3, 3)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg4, 4)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.attribute1, 5)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.attribute2, 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .set_args(3, 4)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.args, tuple([3, 4]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .set_kwargs(init_arg3=4, init_arg4=5)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_attributes(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=5, attribute2=6) \
 | 
				
			||||||
 | 
					            .set_attributes(attribute1=6, attribute2=7)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.attributes, dict(attribute1=6, attribute2=7))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .clear_args()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.args, tuple())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .clear_kwargs()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.kwargs, dict())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_attributes(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=5, attribute2=6) \
 | 
				
			||||||
 | 
					            .clear_attributes()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.attributes, dict())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        overriding_provider1 = providers.Factory(dict)
 | 
				
			||||||
 | 
					        overriding_provider2 = providers.Factory(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(overriding_provider1)
 | 
				
			||||||
 | 
					        provider.override(overriding_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, list)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIs(provider.cls, provider_copy.cls)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Factory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_from_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        provider_copy_memo = providers.Factory(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            provider, memo={id(provider): provider_copy_memo})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(provider_copy, provider_copy_memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_args(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        dependent_provider1 = providers.Factory(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = providers.Factory(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_args(dependent_provider1, dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.args[0]
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.args[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.args, provider_copy.args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_kwargs(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        dependent_provider1 = providers.Factory(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = providers.Factory(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.kwargs['a1']
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.kwargs['a2']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_attributes(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        dependent_provider1 = providers.Factory(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = providers.Factory(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.attributes['a1']
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.attributes['a2']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.attributes, provider_copy.attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_overridden(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					        object_provider = providers.Object(object())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(object_provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        object_provider_copy = provider_copy.overridden[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIs(provider.cls, provider_copy.cls)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, providers.Factory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(object_provider, object_provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(object_provider_copy, providers.Object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.factories.'
 | 
				
			||||||
 | 
					                         'Factory({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DelegatedFactoryTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_inheritance(self):
 | 
				
			||||||
 | 
					        self.assertIsInstance(providers.DelegatedFactory(object),
 | 
				
			||||||
 | 
					                              providers.Factory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_provider(self):
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            providers.is_provider(providers.DelegatedFactory(object)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_delegated_provider(self):
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            providers.is_delegated(providers.DelegatedFactory(object)))
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,33 @@ class PositionalInjectionTests(unittest.TestCase):
 | 
				
			||||||
        self.assertIs(type(obj2), object)
 | 
					        self.assertIs(type(obj2), object)
 | 
				
			||||||
        self.assertIsNot(obj1, obj2)
 | 
					        self.assertIsNot(obj1, obj2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_original_value(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(object)
 | 
				
			||||||
 | 
					        injection = providers.PositionalInjection(provider)
 | 
				
			||||||
 | 
					        self.assertIs(injection.get_original_value(), provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(object)
 | 
				
			||||||
 | 
					        injection = providers.PositionalInjection(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        injection_copy = providers.deepcopy(injection)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(injection_copy, injection)
 | 
				
			||||||
 | 
					        self.assertIsNot(injection_copy.get_original_value(),
 | 
				
			||||||
 | 
					                         injection.get_original_value())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(object)
 | 
				
			||||||
 | 
					        injection = providers.PositionalInjection(provider)
 | 
				
			||||||
 | 
					        injection_copy_orig = providers.PositionalInjection(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        injection_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            injection, {id(injection): injection_copy_orig})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(injection_copy, injection_copy_orig)
 | 
				
			||||||
 | 
					        self.assertIs(injection_copy.get_original_value(),
 | 
				
			||||||
 | 
					                      injection.get_original_value())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NamedInjectionTests(unittest.TestCase):
 | 
					class NamedInjectionTests(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,3 +77,30 @@ class NamedInjectionTests(unittest.TestCase):
 | 
				
			||||||
        self.assertIs(type(obj1), object)
 | 
					        self.assertIs(type(obj1), object)
 | 
				
			||||||
        self.assertIs(type(obj2), object)
 | 
					        self.assertIs(type(obj2), object)
 | 
				
			||||||
        self.assertIsNot(obj1, obj2)
 | 
					        self.assertIsNot(obj1, obj2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_original_value(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(object)
 | 
				
			||||||
 | 
					        injection = providers.NamedInjection('name', provider)
 | 
				
			||||||
 | 
					        self.assertIs(injection.get_original_value(), provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(object)
 | 
				
			||||||
 | 
					        injection = providers.NamedInjection('name', provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        injection_copy = providers.deepcopy(injection)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(injection_copy, injection)
 | 
				
			||||||
 | 
					        self.assertIsNot(injection_copy.get_original_value(),
 | 
				
			||||||
 | 
					                         injection.get_original_value())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_memo(self):
 | 
				
			||||||
 | 
					        provider = providers.Factory(object)
 | 
				
			||||||
 | 
					        injection = providers.NamedInjection('name', provider)
 | 
				
			||||||
 | 
					        injection_copy_orig = providers.NamedInjection('name', provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        injection_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            injection, {id(injection): injection_copy_orig})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(injection_copy, injection_copy_orig)
 | 
				
			||||||
 | 
					        self.assertIs(injection_copy.get_original_value(),
 | 
				
			||||||
 | 
					                      injection.get_original_value())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										434
									
								
								tests/unit/providers/test_singletons.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								tests/unit/providers/test_singletons.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,434 @@
 | 
				
			||||||
 | 
					"""Dependency injector singleton providers unit tests."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest2 as unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import (
 | 
				
			||||||
 | 
					    providers,
 | 
				
			||||||
 | 
					    errors,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Example(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None,
 | 
				
			||||||
 | 
					                 init_arg4=None):
 | 
				
			||||||
 | 
					        self.init_arg1 = init_arg1
 | 
				
			||||||
 | 
					        self.init_arg2 = init_arg2
 | 
				
			||||||
 | 
					        self.init_arg3 = init_arg3
 | 
				
			||||||
 | 
					        self.init_arg4 = init_arg4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.attribute1 = None
 | 
				
			||||||
 | 
					        self.attribute2 = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _BaseSingletonTestCase(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_provider(self):
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_provider(self.singleton_cls(Example)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_callable(self):
 | 
				
			||||||
 | 
					        self.assertTrue(self.singleton_cls(credits))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_not_callable(self):
 | 
				
			||||||
 | 
					        self.assertRaises(errors.Error, self.singleton_cls, 123)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_valid_provided_type(self):
 | 
				
			||||||
 | 
					        class ExampleProvider(self.singleton_cls):
 | 
				
			||||||
 | 
					            provided_type = Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        example_provider = ExampleProvider(Example, 1, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsInstance(example_provider(), Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_valid_provided_subtype(self):
 | 
				
			||||||
 | 
					        class ExampleProvider(self.singleton_cls):
 | 
				
			||||||
 | 
					            provided_type = Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class NewExampe(Example):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        example_provider = ExampleProvider(NewExampe, 1, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsInstance(example_provider(), NewExampe)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_init_with_invalid_provided_type(self):
 | 
				
			||||||
 | 
					        class ExampleProvider(self.singleton_cls):
 | 
				
			||||||
 | 
					            provided_type = Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with self.assertRaises(errors.Error):
 | 
				
			||||||
 | 
					            ExampleProvider(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_init_positional_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example, 'i1', 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_init_keyword_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example, init_arg1='i1', init_arg2='i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_init_positional_and_keyword_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example, 'i1', init_arg2='i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg1, 'i1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.init_arg2, 'i2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_attributes(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        provider.add_attributes(attribute1='a1', attribute2='a2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.attribute1, 'a1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.attribute2, 'a2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.attribute1, 'a1')
 | 
				
			||||||
 | 
					        self.assertEqual(instance2.attribute2, 'a2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, Example)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = provider(11, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg1, 11)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg2, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_kwargs(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example, init_arg1=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider(init_arg2=22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 1)
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Instance is created earlier
 | 
				
			||||||
 | 
					        instance1 = provider(init_arg1=11, init_arg2=22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg1, 1)
 | 
				
			||||||
 | 
					        self.assertEqual(instance1.init_arg2, 22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_with_context_args_and_kwargs(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example, 11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = provider(22, init_arg3=33, init_arg4=44)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg1, 11)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg2, 22)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg3, 33)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg4, 44)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_fluent_interface(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=5, attribute2=6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg1, 1)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg2, 2)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg3, 3)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.init_arg4, 4)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.attribute1, 5)
 | 
				
			||||||
 | 
					        self.assertEqual(instance.attribute2, 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .set_args(3, 4)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.args, tuple([3, 4]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_kwargs(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .set_kwargs(init_arg3=4, init_arg4=5)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_attributes(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=5, attribute2=6) \
 | 
				
			||||||
 | 
					            .set_attributes(attribute1=6, attribute2=7)
 | 
				
			||||||
 | 
					        self.assertEqual(provider.attributes, dict(attribute1=6, attribute2=7))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_args(1, 2) \
 | 
				
			||||||
 | 
					            .clear_args()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.args, tuple())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_kwargs(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_kwargs(init_arg3=3, init_arg4=4) \
 | 
				
			||||||
 | 
					            .clear_kwargs()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.kwargs, dict())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_clear_attributes(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=5, attribute2=6) \
 | 
				
			||||||
 | 
					            .clear_attributes()
 | 
				
			||||||
 | 
					        self.assertEqual(provider.attributes, dict())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_call_overridden(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        overriding_provider1 = self.singleton_cls(dict)
 | 
				
			||||||
 | 
					        overriding_provider2 = self.singleton_cls(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(overriding_provider1)
 | 
				
			||||||
 | 
					        provider.override(overriding_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(instance1, instance2)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, list)
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance2, list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIs(provider.cls, provider_copy.cls)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, self.singleton_cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_from_memo(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        provider_copy_memo = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(
 | 
				
			||||||
 | 
					            provider, memo={id(provider): provider_copy_memo})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(provider_copy, provider_copy_memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_args(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        dependent_provider1 = self.singleton_cls(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = self.singleton_cls(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_args(dependent_provider1, dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.args[0]
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.args[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.args, provider_copy.args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_kwargs(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        dependent_provider1 = self.singleton_cls(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = self.singleton_cls(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.kwargs['a1']
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.kwargs['a2']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_attributes(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        dependent_provider1 = self.singleton_cls(list)
 | 
				
			||||||
 | 
					        dependent_provider2 = self.singleton_cls(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        dependent_provider_copy1 = provider_copy.attributes['a1']
 | 
				
			||||||
 | 
					        dependent_provider_copy2 = provider_copy.attributes['a2']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertNotEqual(provider.attributes, provider_copy.attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider1, dependent_provider_copy1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
 | 
				
			||||||
 | 
					        self.assertIsNot(dependent_provider2, dependent_provider_copy2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deepcopy_overridden(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					        object_provider = providers.Object(object())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.override(object_provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider_copy = providers.deepcopy(provider)
 | 
				
			||||||
 | 
					        object_provider_copy = provider_copy.overridden[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(provider, provider_copy)
 | 
				
			||||||
 | 
					        self.assertIs(provider.cls, provider_copy.cls)
 | 
				
			||||||
 | 
					        self.assertIsInstance(provider, self.singleton_cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(object_provider, object_provider_copy)
 | 
				
			||||||
 | 
					        self.assertIsInstance(object_provider_copy, providers.Object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.reset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					        self.assertIsInstance(instance1, object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = providers.Singleton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.singletons.'
 | 
				
			||||||
 | 
					                         'Singleton({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DelegatedSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = providers.DelegatedSingleton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_delegated_provider(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(object)
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_delegated(provider))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.singletons.'
 | 
				
			||||||
 | 
					                         'DelegatedSingleton({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ThreadLocalSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = providers.ThreadLocalSingleton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = providers.ThreadLocalSingleton(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.singletons.'
 | 
				
			||||||
 | 
					                         'ThreadLocalSingleton({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DelegatedThreadLocalSingletonTests(_BaseSingletonTestCase,
 | 
				
			||||||
 | 
					                                         unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = providers.DelegatedThreadLocalSingleton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_delegated_provider(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(object)
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_delegated(provider))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.singletons.'
 | 
				
			||||||
 | 
					                         'DelegatedThreadLocalSingleton({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ThreadSafeSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = providers.ThreadSafeSingleton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.singletons.'
 | 
				
			||||||
 | 
					                         'ThreadSafeSingleton({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DelegatedThreadSafeSingletonTests(_BaseSingletonTestCase,
 | 
				
			||||||
 | 
					                                        unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    singleton_cls = providers.DelegatedThreadSafeSingleton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_delegated_provider(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(object)
 | 
				
			||||||
 | 
					        self.assertTrue(providers.is_delegated(provider))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_repr(self):
 | 
				
			||||||
 | 
					        provider = self.singleton_cls(Example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(repr(provider),
 | 
				
			||||||
 | 
					                         '<dependency_injector.providers.singletons.'
 | 
				
			||||||
 | 
					                         'DelegatedThreadSafeSingleton({0}) at {1}>'.format(
 | 
				
			||||||
 | 
					                             repr(Example),
 | 
				
			||||||
 | 
					                             hex(id(provider))))
 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
"""Dependency injector static providers unit tests."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import unittest2 as unittest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ObjectProviderTests(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_is_provider(self):
 | 
					 | 
				
			||||||
        self.assertTrue(providers.is_provider(providers.Object(object())))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_object_provider(self):
 | 
					 | 
				
			||||||
        obj = object()
 | 
					 | 
				
			||||||
        self.assertIs(providers.Object(obj)(), obj)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_call_overridden_object_provider(self):
 | 
					 | 
				
			||||||
        obj1 = object()
 | 
					 | 
				
			||||||
        obj2 = object()
 | 
					 | 
				
			||||||
        provider = providers.Object(obj1)
 | 
					 | 
				
			||||||
        provider.override(providers.Object(obj2))
 | 
					 | 
				
			||||||
        self.assertIs(provider(), obj2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_repr(self):
 | 
					 | 
				
			||||||
        some_object = object()
 | 
					 | 
				
			||||||
        provider = providers.Object(some_object)
 | 
					 | 
				
			||||||
        self.assertEqual(repr(provider),
 | 
					 | 
				
			||||||
                         '<dependency_injector.providers.base.'
 | 
					 | 
				
			||||||
                         'Object({0}) at {1}>'.format(
 | 
					 | 
				
			||||||
                             repr(some_object),
 | 
					 | 
				
			||||||
                             hex(id(provider))))
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user