mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-22 09:36:48 +03:00
Consolidate providers into single cython module
This commit is contained in:
parent
01e145bd60
commit
5b3dbae572
29
setup.py
29
setup.py
|
@ -41,38 +41,13 @@ setup(name='dependency-injector',
|
||||||
packages=[
|
packages=[
|
||||||
'dependency_injector',
|
'dependency_injector',
|
||||||
'dependency_injector.containers',
|
'dependency_injector.containers',
|
||||||
'dependency_injector.providers',
|
|
||||||
],
|
],
|
||||||
package_dir={
|
package_dir={
|
||||||
'': 'src',
|
'': 'src',
|
||||||
},
|
},
|
||||||
ext_modules=[
|
ext_modules=[
|
||||||
Extension('dependency_injector.providers.base',
|
Extension('dependency_injector.providers',
|
||||||
['src/dependency_injector/providers/base.c'],
|
['src/dependency_injector/providers.c'],
|
||||||
define_macros=defined_macros,
|
|
||||||
extra_compile_args=['-O2']),
|
|
||||||
Extension('dependency_injector.providers.configuration',
|
|
||||||
['src/dependency_injector/providers/configuration.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',
|
|
||||||
['src/dependency_injector/providers/injections.c'],
|
|
||||||
define_macros=defined_macros,
|
|
||||||
extra_compile_args=['-O2']),
|
|
||||||
Extension('dependency_injector.providers.utils',
|
|
||||||
['src/dependency_injector/providers/utils.c'],
|
|
||||||
define_macros=defined_macros,
|
define_macros=defined_macros,
|
||||||
extra_compile_args=['-O2']),
|
extra_compile_args=['-O2']),
|
||||||
],
|
],
|
||||||
|
|
25899
src/dependency_injector/providers.c
Normal file
25899
src/dependency_injector/providers.c
Normal file
File diff suppressed because it is too large
Load Diff
250
src/dependency_injector/providers.pxd
Normal file
250
src/dependency_injector/providers.pxd
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
"""Dependency injector providers.
|
||||||
|
|
||||||
|
Powered by Cython.
|
||||||
|
"""
|
||||||
|
|
||||||
|
cimport cython
|
||||||
|
|
||||||
|
|
||||||
|
# Base providers
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
# Callable providers
|
||||||
|
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 class DelegatedCallable(Callable):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Configuration providers
|
||||||
|
cdef class Configuration(Provider):
|
||||||
|
cdef str __name
|
||||||
|
cdef object __value
|
||||||
|
cdef dict __children
|
||||||
|
|
||||||
|
cpdef str get_name(self)
|
||||||
|
cpdef object update(self, object value)
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
cpdef str _get_child_name(self, str child_name)
|
||||||
|
|
||||||
|
|
||||||
|
# Factory providers
|
||||||
|
cdef class Factory(Provider):
|
||||||
|
cdef Callable __instantiator
|
||||||
|
|
||||||
|
cdef tuple __attributes
|
||||||
|
cdef int __attributes_len
|
||||||
|
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
cdef class DelegatedFactory(Factory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Singleton providers
|
||||||
|
cdef class BaseSingleton(Provider):
|
||||||
|
cdef Factory __instantiator
|
||||||
|
|
||||||
|
|
||||||
|
cdef class Singleton(BaseSingleton):
|
||||||
|
cdef object __storage
|
||||||
|
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
cdef class DelegatedSingleton(Singleton):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
cdef class ThreadSafeSingleton(BaseSingleton):
|
||||||
|
cdef object __storage
|
||||||
|
cdef object __lock
|
||||||
|
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
cdef class ThreadLocalSingleton(BaseSingleton):
|
||||||
|
cdef object __storage
|
||||||
|
|
||||||
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Injections
|
||||||
|
cdef class Injection(object):
|
||||||
|
cdef object __value
|
||||||
|
cdef int __is_provider
|
||||||
|
cdef int __is_delegated
|
||||||
|
cdef int __call
|
||||||
|
|
||||||
|
|
||||||
|
cdef class PositionalInjection(Injection):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
cdef class NamedInjection(Injection):
|
||||||
|
cdef object __name
|
||||||
|
|
||||||
|
|
||||||
|
cpdef tuple parse_positional_injections(tuple args)
|
||||||
|
|
||||||
|
|
||||||
|
cpdef tuple parse_named_injections(dict kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# Utils
|
||||||
|
cdef object CLASS_TYPES
|
||||||
|
|
||||||
|
|
||||||
|
cpdef bint is_provider(object instance)
|
||||||
|
|
||||||
|
|
||||||
|
cpdef object ensure_is_provider(object instance)
|
||||||
|
|
||||||
|
|
||||||
|
cpdef bint is_delegated(object instance)
|
||||||
|
|
||||||
|
|
||||||
|
cpdef str represent_provider(object provider, object provides)
|
||||||
|
|
||||||
|
|
||||||
|
cpdef object deepcopy(object instance, dict memo=*)
|
||||||
|
|
||||||
|
|
||||||
|
# Inline helper functions
|
||||||
|
cdef inline object __get_name(NamedInjection self):
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
|
||||||
|
cdef inline object __get_value(Injection self):
|
||||||
|
if self.__call == 0:
|
||||||
|
return self.__value
|
||||||
|
return self.__value()
|
||||||
|
|
||||||
|
|
||||||
|
@cython.boundscheck(False)
|
||||||
|
@cython.wraparound(False)
|
||||||
|
cdef inline tuple __provide_positional_args(tuple args,
|
||||||
|
tuple inj_args,
|
||||||
|
int inj_args_len):
|
||||||
|
cdef int index
|
||||||
|
cdef list positional_args
|
||||||
|
cdef PositionalInjection injection
|
||||||
|
|
||||||
|
if inj_args_len == 0:
|
||||||
|
return args
|
||||||
|
|
||||||
|
positional_args = list()
|
||||||
|
for index in range(inj_args_len):
|
||||||
|
injection = <PositionalInjection>inj_args[index]
|
||||||
|
positional_args.append(__get_value(injection))
|
||||||
|
positional_args.extend(args)
|
||||||
|
|
||||||
|
return tuple(positional_args)
|
||||||
|
|
||||||
|
|
||||||
|
@cython.boundscheck(False)
|
||||||
|
@cython.wraparound(False)
|
||||||
|
cdef inline dict __provide_keyword_args(dict kwargs,
|
||||||
|
tuple inj_kwargs,
|
||||||
|
int inj_kwargs_len):
|
||||||
|
cdef int index
|
||||||
|
cdef object name
|
||||||
|
cdef NamedInjection kw_injection
|
||||||
|
|
||||||
|
if len(kwargs) == 0:
|
||||||
|
for index in range(inj_kwargs_len):
|
||||||
|
kw_injection = <NamedInjection>inj_kwargs[index]
|
||||||
|
name = __get_name(kw_injection)
|
||||||
|
kwargs[name] = __get_value(kw_injection)
|
||||||
|
else:
|
||||||
|
for index in range(inj_kwargs_len):
|
||||||
|
kw_injection = <NamedInjection>inj_kwargs[index]
|
||||||
|
name = __get_name(kw_injection)
|
||||||
|
if name not in kwargs:
|
||||||
|
kwargs[name] = __get_value(kw_injection)
|
||||||
|
|
||||||
|
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,
|
||||||
|
__get_name(attr_injection),
|
||||||
|
__get_value(attr_injection))
|
||||||
|
|
||||||
|
|
||||||
|
cdef inline object __callable_call(Callable 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 inline object __factory_call(Factory self, tuple args, dict kwargs):
|
||||||
|
cdef object instance
|
||||||
|
|
||||||
|
instance = __callable_call(self.__instantiator, args, kwargs)
|
||||||
|
|
||||||
|
if self.__attributes_len > 0:
|
||||||
|
__inject_attributes(instance,
|
||||||
|
self.__attributes,
|
||||||
|
self.__attributes_len)
|
||||||
|
|
||||||
|
return instance
|
1521
src/dependency_injector/providers.pyx
Normal file
1521
src/dependency_injector/providers.pyx
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1,82 +0,0 @@
|
||||||
"""Dependency injector providers."""
|
|
||||||
|
|
||||||
from .base import (
|
|
||||||
Provider,
|
|
||||||
Object,
|
|
||||||
Delegate,
|
|
||||||
ExternalDependency,
|
|
||||||
OverridingContext,
|
|
||||||
)
|
|
||||||
from .configuration import (
|
|
||||||
Configuration,
|
|
||||||
)
|
|
||||||
from .callables import (
|
|
||||||
Callable,
|
|
||||||
DelegatedCallable,
|
|
||||||
)
|
|
||||||
from .factories import (
|
|
||||||
Factory,
|
|
||||||
DelegatedFactory,
|
|
||||||
)
|
|
||||||
from .singletons import (
|
|
||||||
BaseSingleton,
|
|
||||||
|
|
||||||
Singleton,
|
|
||||||
DelegatedSingleton,
|
|
||||||
|
|
||||||
ThreadSafeSingleton,
|
|
||||||
DelegatedThreadSafeSingleton,
|
|
||||||
|
|
||||||
ThreadLocalSingleton,
|
|
||||||
DelegatedThreadLocalSingleton,
|
|
||||||
)
|
|
||||||
from .injections import (
|
|
||||||
Injection,
|
|
||||||
PositionalInjection,
|
|
||||||
NamedInjection,
|
|
||||||
)
|
|
||||||
from .utils import (
|
|
||||||
is_provider,
|
|
||||||
ensure_is_provider,
|
|
||||||
is_delegated,
|
|
||||||
represent_provider,
|
|
||||||
deepcopy,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
|
||||||
'Provider',
|
|
||||||
'Object',
|
|
||||||
'Delegate',
|
|
||||||
'ExternalDependency',
|
|
||||||
'OverridingContext',
|
|
||||||
|
|
||||||
'Configuration',
|
|
||||||
|
|
||||||
'Callable',
|
|
||||||
'DelegatedCallable',
|
|
||||||
|
|
||||||
'Factory',
|
|
||||||
'DelegatedFactory',
|
|
||||||
|
|
||||||
'BaseSingleton',
|
|
||||||
|
|
||||||
'Singleton',
|
|
||||||
'DelegatedSingleton',
|
|
||||||
|
|
||||||
'ThreadSafeSingleton',
|
|
||||||
'DelegatedThreadSafeSingleton',
|
|
||||||
|
|
||||||
'ThreadLocalSingleton',
|
|
||||||
'DelegatedThreadLocalSingleton',
|
|
||||||
|
|
||||||
'Injection',
|
|
||||||
'PositionalInjection',
|
|
||||||
'NamedInjection',
|
|
||||||
|
|
||||||
'is_provider',
|
|
||||||
'ensure_is_provider',
|
|
||||||
'is_delegated',
|
|
||||||
'represent_provider',
|
|
||||||
'deepcopy',
|
|
||||||
)
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,31 +0,0 @@
|
||||||
"""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,394 +0,0 @@
|
||||||
"""Dependency injector base providers.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
cimport cython
|
|
||||||
|
|
||||||
from dependency_injector.errors import Error
|
|
||||||
|
|
||||||
from .utils cimport (
|
|
||||||
CLASS_TYPES,
|
|
||||||
is_provider,
|
|
||||||
ensure_is_provider,
|
|
||||||
represent_provider,
|
|
||||||
deepcopy,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Provider(object):
|
|
||||||
"""Base provider class.
|
|
||||||
|
|
||||||
:py:class:`Provider` is callable (implements ``__call__`` method). Every
|
|
||||||
call to provider object returns provided result, according to the providing
|
|
||||||
strategy of particular provider. This ``callable`` functionality is a
|
|
||||||
regular part of providers API and it should be the same for all provider's
|
|
||||||
subclasses.
|
|
||||||
|
|
||||||
Implementation of particular providing strategy should be done in
|
|
||||||
:py:meth:`Provider._provide` of :py:class:`Provider` subclass. Current
|
|
||||||
method is called every time when not overridden provider is called.
|
|
||||||
|
|
||||||
:py:class:`Provider` implements provider overriding logic that should be
|
|
||||||
also common for all providers:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
provider1 = Factory(SomeClass)
|
|
||||||
provider2 = Factory(ChildSomeClass)
|
|
||||||
|
|
||||||
provider1.override(provider2)
|
|
||||||
|
|
||||||
some_instance = provider1()
|
|
||||||
assert isinstance(some_instance, ChildSomeClass)
|
|
||||||
|
|
||||||
Also :py:class:`Provider` implements helper function for creating its
|
|
||||||
delegates:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
provider = Factory(object)
|
|
||||||
delegate = provider.delegate()
|
|
||||||
|
|
||||||
delegated = delegate()
|
|
||||||
|
|
||||||
assert provider is delegated
|
|
||||||
|
|
||||||
All providers should extend this class.
|
|
||||||
|
|
||||||
.. py:attribute:: overridden
|
|
||||||
|
|
||||||
Tuple of overriding providers, if any.
|
|
||||||
|
|
||||||
:type: tuple[:py:class:`Provider`] | None
|
|
||||||
"""
|
|
||||||
|
|
||||||
__IS_PROVIDER__ = True
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""Initializer."""
|
|
||||||
self.__overridden = tuple()
|
|
||||||
self.__overridden_len = 0
|
|
||||||
super(Provider, self).__init__()
|
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
|
||||||
"""Return provided object.
|
|
||||||
|
|
||||||
Callable interface implementation.
|
|
||||||
"""
|
|
||||||
if self.__overridden_len != 0:
|
|
||||||
return self._call_last_overriding(args, kwargs)
|
|
||||||
return self._provide(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__()
|
|
||||||
|
|
||||||
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=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):
|
|
||||||
"""Override provider with another provider.
|
|
||||||
|
|
||||||
:param provider: Overriding provider.
|
|
||||||
:type provider: :py:class:`Provider`
|
|
||||||
|
|
||||||
:raise: :py:exc:`dependency_injector.errors.Error`
|
|
||||||
|
|
||||||
:return: Overriding context.
|
|
||||||
:rtype: :py:class:`OverridingContext`
|
|
||||||
"""
|
|
||||||
if provider is self:
|
|
||||||
raise Error('Provider {0} could not be overridden '
|
|
||||||
'with itself'.format(self))
|
|
||||||
|
|
||||||
if not is_provider(provider):
|
|
||||||
provider = Object(provider)
|
|
||||||
|
|
||||||
self.__overridden += (provider,)
|
|
||||||
self.__overridden_len += 1
|
|
||||||
|
|
||||||
return OverridingContext(self, provider)
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
|
||||||
@cython.wraparound(False)
|
|
||||||
def reset_last_overriding(self):
|
|
||||||
"""Reset last overriding provider.
|
|
||||||
|
|
||||||
:raise: :py:exc:`dependency_injector.errors.Error` if provider is not
|
|
||||||
overridden.
|
|
||||||
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
if self.__overridden_len == 0:
|
|
||||||
raise Error('Provider {0} is not overridden'.format(str(self)))
|
|
||||||
|
|
||||||
self.__overridden = self.__overridden[:self.__overridden_len - 1]
|
|
||||||
self.__overridden_len -= 1
|
|
||||||
|
|
||||||
def reset_override(self):
|
|
||||||
"""Reset all overriding providers.
|
|
||||||
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
self.__overridden = tuple()
|
|
||||||
self.__overridden_len = 0
|
|
||||||
|
|
||||||
def delegate(self):
|
|
||||||
"""Return provider's delegate.
|
|
||||||
|
|
||||||
:rtype: :py:class:`Delegate`
|
|
||||||
"""
|
|
||||||
return Delegate(self)
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
|
||||||
"""Providing strategy implementation.
|
|
||||||
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
@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)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Object(Provider):
|
|
||||||
"""Object provider returns provided instance "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
|
|
||||||
"""
|
|
||||||
self.__provides = provides
|
|
||||||
super(Object, 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__(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.
|
|
||||||
|
|
||||||
: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.__provides
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
"""
|
|
||||||
super(Delegate, self).__init__(ensure_is_provider(provides))
|
|
||||||
|
|
||||||
|
|
||||||
cdef class ExternalDependency(Provider):
|
|
||||||
""":py:class:`ExternalDependency` provider describes dependency interface.
|
|
||||||
|
|
||||||
This provider is used for description of dependency interface. That might
|
|
||||||
be useful when dependency could be provided in the client's code only,
|
|
||||||
but it's interface is known. Such situations could happen when required
|
|
||||||
dependency has non-determenistic list of dependencies itself.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
database_provider = ExternalDependency(sqlite3.dbapi2.Connection)
|
|
||||||
database_provider.override(Factory(sqlite3.connect, ':memory:'))
|
|
||||||
|
|
||||||
database = database_provider()
|
|
||||||
|
|
||||||
.. py:attribute:: instance_of
|
|
||||||
|
|
||||||
Class of required dependency.
|
|
||||||
|
|
||||||
:type: type
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, type instance_of):
|
|
||||||
"""Initializer."""
|
|
||||||
self.__instance_of = instance_of
|
|
||||||
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):
|
|
||||||
"""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]
|
|
||||||
|
|
||||||
:raise: :py:exc:`dependency_injector.errors.Error`
|
|
||||||
|
|
||||||
:rtype: object
|
|
||||||
"""
|
|
||||||
cdef object instance
|
|
||||||
|
|
||||||
if self.__overridden_len == 0:
|
|
||||||
raise Error('Dependency is not defined')
|
|
||||||
|
|
||||||
instance = self._call_last_overriding(args, kwargs)
|
|
||||||
|
|
||||||
if not isinstance(instance, self.instance_of):
|
|
||||||
raise Error('{0} is not an '.format(instance) +
|
|
||||||
'instance of {0}'.format(self.instance_of))
|
|
||||||
|
|
||||||
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):
|
|
||||||
"""Set external dependency provider.
|
|
||||||
|
|
||||||
:param provider: Provider that provides required dependency.
|
|
||||||
:type provider: :py:class:`Provider`
|
|
||||||
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
return self.override(provider)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class OverridingContext(object):
|
|
||||||
"""Provider overriding context.
|
|
||||||
|
|
||||||
:py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
|
|
||||||
implemeting ``with`` contexts. When :py:class:`OverridingContext` is
|
|
||||||
closed, overriding that was created in this context is dropped also.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
with provider.override(another_provider):
|
|
||||||
assert provider.overridden
|
|
||||||
assert not provider.overridden
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, Provider overridden, Provider overriding):
|
|
||||||
"""Initializer.
|
|
||||||
|
|
||||||
:param overridden: Overridden provider.
|
|
||||||
:type overridden: :py:class:`Provider`
|
|
||||||
|
|
||||||
:param overriding: Overriding provider.
|
|
||||||
:type overriding: :py:class:`Provider`
|
|
||||||
"""
|
|
||||||
self.__overridden = overridden
|
|
||||||
self.__overriding = overriding
|
|
||||||
super(OverridingContext, self).__init__()
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
"""Do nothing."""
|
|
||||||
return self.__overriding
|
|
||||||
|
|
||||||
def __exit__(self, *_):
|
|
||||||
"""Exit overriding context."""
|
|
||||||
self.__overridden.reset_last_overriding()
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,43 +0,0 @@
|
||||||
"""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 class DelegatedCallable(Callable):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
cdef inline object __callable_call(Callable 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)
|
|
|
@ -1,208 +0,0 @@
|
||||||
"""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 __callable_call(self, 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
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +0,0 @@
|
||||||
"""Dependency injector configuration providers.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .base cimport (
|
|
||||||
Provider,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Configuration(Provider):
|
|
||||||
cdef str __name
|
|
||||||
cdef object __value
|
|
||||||
cdef dict __children
|
|
||||||
|
|
||||||
cpdef str get_name(self)
|
|
||||||
cpdef object update(self, object value)
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
|
||||||
cpdef str _get_child_name(self, str child_name)
|
|
|
@ -1,126 +0,0 @@
|
||||||
"""Dependency injector configuration providers.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .base cimport (
|
|
||||||
Provider,
|
|
||||||
)
|
|
||||||
from .utils cimport (
|
|
||||||
represent_provider,
|
|
||||||
deepcopy,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Configuration(Provider):
|
|
||||||
"""Configuration provider.
|
|
||||||
|
|
||||||
Configuration provider helps with implementing late static binding of
|
|
||||||
configuration options - use first, define later.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
config = Configuration('config')
|
|
||||||
|
|
||||||
print(config.section1.option1()) # None
|
|
||||||
print(config.section1.option2()) # None
|
|
||||||
|
|
||||||
config.update({'section1': {'option1': 1,
|
|
||||||
'option2': 2}})
|
|
||||||
|
|
||||||
print(config.section1.option1()) # 1
|
|
||||||
print(config.section1.option2()) # 2
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name):
|
|
||||||
"""Initializer.
|
|
||||||
|
|
||||||
:param name: Name of configuration unit.
|
|
||||||
:type name: str
|
|
||||||
"""
|
|
||||||
self.__name = name
|
|
||||||
self.__value = None
|
|
||||||
self.__children = dict()
|
|
||||||
super(Configuration, 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.__name)
|
|
||||||
copied.update(deepcopy(self.__value))
|
|
||||||
|
|
||||||
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.__name)
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
"""Return child configuration provider."""
|
|
||||||
cdef Configuration child_provider
|
|
||||||
cdef object value
|
|
||||||
|
|
||||||
child_provider = self.__children.get(name)
|
|
||||||
|
|
||||||
if child_provider is None:
|
|
||||||
child_provider = self.__class__(self._get_child_name(name))
|
|
||||||
|
|
||||||
if isinstance(self.__value, dict):
|
|
||||||
child_provider.update(self.__value.get(name))
|
|
||||||
|
|
||||||
self.__children[name] = child_provider
|
|
||||||
|
|
||||||
return child_provider
|
|
||||||
|
|
||||||
cpdef str get_name(self):
|
|
||||||
"""Name of configuration unit."""
|
|
||||||
return self.__name
|
|
||||||
|
|
||||||
cpdef object update(self, value):
|
|
||||||
"""Set configuration options.
|
|
||||||
|
|
||||||
:param value: Value of configuration option.
|
|
||||||
:type value: object | dict
|
|
||||||
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
cdef Configuration child_provider
|
|
||||||
cdef object child_value
|
|
||||||
|
|
||||||
self.__value = value
|
|
||||||
|
|
||||||
if not isinstance(self.__value, dict):
|
|
||||||
return
|
|
||||||
|
|
||||||
for name in self.__value:
|
|
||||||
child_provider = self.__children.get(name)
|
|
||||||
|
|
||||||
if child_provider is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
child_provider.update(self.__value.get(name))
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
|
||||||
"""Return result of provided callable's call."""
|
|
||||||
return self.__value
|
|
||||||
|
|
||||||
cpdef str _get_child_name(self, str child_name):
|
|
||||||
cdef str child_full_name
|
|
||||||
|
|
||||||
child_full_name = ''
|
|
||||||
|
|
||||||
if self.__name:
|
|
||||||
child_full_name += self.__name + '.'
|
|
||||||
|
|
||||||
child_full_name += child_name
|
|
||||||
|
|
||||||
return child_full_name
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,37 +0,0 @@
|
||||||
"""Dependency injector factory providers.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .base cimport Provider
|
|
||||||
from .callables cimport (
|
|
||||||
Callable,
|
|
||||||
__callable_call,
|
|
||||||
)
|
|
||||||
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 class DelegatedFactory(Factory):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
cdef inline object __factory_call(Factory self, tuple args, dict kwargs):
|
|
||||||
cdef object instance
|
|
||||||
|
|
||||||
instance = __callable_call(self.__instantiator, args, kwargs)
|
|
||||||
|
|
||||||
if self.__attributes_len > 0:
|
|
||||||
__inject_attributes(instance,
|
|
||||||
self.__attributes,
|
|
||||||
self.__attributes_len)
|
|
||||||
|
|
||||||
return instance
|
|
|
@ -1,271 +0,0 @@
|
||||||
"""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.add_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 __factory_call(self, 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
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,95 +0,0 @@
|
||||||
"""Dependency injector injections.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
cimport cython
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Injection(object):
|
|
||||||
cdef object __value
|
|
||||||
cdef int __is_provider
|
|
||||||
cdef int __is_delegated
|
|
||||||
cdef int __call
|
|
||||||
|
|
||||||
|
|
||||||
cdef class PositionalInjection(Injection):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
cdef class NamedInjection(Injection):
|
|
||||||
cdef object __name
|
|
||||||
|
|
||||||
|
|
||||||
cdef inline object __get_name(NamedInjection self):
|
|
||||||
return self.__name
|
|
||||||
|
|
||||||
|
|
||||||
cdef inline object __get_value(Injection self):
|
|
||||||
if self.__call == 0:
|
|
||||||
return self.__value
|
|
||||||
return self.__value()
|
|
||||||
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
|
||||||
@cython.wraparound(False)
|
|
||||||
cdef inline tuple __provide_positional_args(tuple args,
|
|
||||||
tuple inj_args,
|
|
||||||
int inj_args_len):
|
|
||||||
cdef int index
|
|
||||||
cdef list positional_args
|
|
||||||
cdef PositionalInjection injection
|
|
||||||
|
|
||||||
if inj_args_len == 0:
|
|
||||||
return args
|
|
||||||
|
|
||||||
positional_args = list()
|
|
||||||
for index in range(inj_args_len):
|
|
||||||
injection = <PositionalInjection>inj_args[index]
|
|
||||||
positional_args.append(__get_value(injection))
|
|
||||||
positional_args.extend(args)
|
|
||||||
|
|
||||||
return tuple(positional_args)
|
|
||||||
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
|
||||||
@cython.wraparound(False)
|
|
||||||
cdef inline dict __provide_keyword_args(dict kwargs,
|
|
||||||
tuple inj_kwargs,
|
|
||||||
int inj_kwargs_len):
|
|
||||||
cdef int index
|
|
||||||
cdef object name
|
|
||||||
cdef NamedInjection kw_injection
|
|
||||||
|
|
||||||
if len(kwargs) == 0:
|
|
||||||
for index in range(inj_kwargs_len):
|
|
||||||
kw_injection = <NamedInjection>inj_kwargs[index]
|
|
||||||
name = __get_name(kw_injection)
|
|
||||||
kwargs[name] = __get_value(kw_injection)
|
|
||||||
else:
|
|
||||||
for index in range(inj_kwargs_len):
|
|
||||||
kw_injection = <NamedInjection>inj_kwargs[index]
|
|
||||||
name = __get_name(kw_injection)
|
|
||||||
if name not in kwargs:
|
|
||||||
kwargs[name] = __get_value(kw_injection)
|
|
||||||
|
|
||||||
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,
|
|
||||||
__get_name(attr_injection),
|
|
||||||
__get_value(attr_injection))
|
|
||||||
|
|
||||||
|
|
||||||
cpdef tuple parse_positional_injections(tuple args)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef tuple parse_named_injections(dict kwargs)
|
|
|
@ -1,118 +0,0 @@
|
||||||
"""Dependency injector injections.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
cimport cython
|
|
||||||
|
|
||||||
from .injections cimport (
|
|
||||||
__get_name,
|
|
||||||
__get_value,
|
|
||||||
)
|
|
||||||
from .utils cimport (
|
|
||||||
is_provider,
|
|
||||||
is_delegated,
|
|
||||||
deepcopy,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Injection(object):
|
|
||||||
"""Abstract injection class."""
|
|
||||||
|
|
||||||
|
|
||||||
cdef class PositionalInjection(Injection):
|
|
||||||
"""Positional injection class."""
|
|
||||||
|
|
||||||
def __init__(self, value):
|
|
||||||
"""Initializer."""
|
|
||||||
self.__value = value
|
|
||||||
self.__is_provider = <int>is_provider(value)
|
|
||||||
self.__is_delegated = <int>is_delegated(value)
|
|
||||||
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):
|
|
||||||
"""Return injection value."""
|
|
||||||
return __get_value(self)
|
|
||||||
|
|
||||||
def get_original_value(self):
|
|
||||||
"""Return original value."""
|
|
||||||
return self.__value
|
|
||||||
|
|
||||||
|
|
||||||
cdef class NamedInjection(Injection):
|
|
||||||
"""Keyword injection class."""
|
|
||||||
|
|
||||||
def __init__(self, name, value):
|
|
||||||
"""Initializer."""
|
|
||||||
self.__name = name
|
|
||||||
self.__value = value
|
|
||||||
self.__is_provider = <int>is_provider(value)
|
|
||||||
self.__is_delegated = <int>is_delegated(value)
|
|
||||||
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):
|
|
||||||
"""Return injection value."""
|
|
||||||
return __get_name(self)
|
|
||||||
|
|
||||||
def get_value(self):
|
|
||||||
"""Return injection value."""
|
|
||||||
return __get_value(self)
|
|
||||||
|
|
||||||
def get_original_value(self):
|
|
||||||
"""Return original value."""
|
|
||||||
return self.__value
|
|
||||||
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
|
||||||
@cython.wraparound(False)
|
|
||||||
cpdef tuple parse_positional_injections(tuple args):
|
|
||||||
"""Parse positional injections."""
|
|
||||||
cdef list injections = list()
|
|
||||||
cdef int args_len = len(args)
|
|
||||||
|
|
||||||
cdef int index
|
|
||||||
cdef object arg
|
|
||||||
cdef PositionalInjection injection
|
|
||||||
|
|
||||||
for index in range(args_len):
|
|
||||||
arg = args[index]
|
|
||||||
injection = PositionalInjection(arg)
|
|
||||||
injections.append(injection)
|
|
||||||
|
|
||||||
return tuple(injections)
|
|
||||||
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
|
||||||
@cython.wraparound(False)
|
|
||||||
cpdef tuple parse_named_injections(dict kwargs):
|
|
||||||
"""Parse named injections."""
|
|
||||||
cdef list injections = list()
|
|
||||||
|
|
||||||
cdef object name
|
|
||||||
cdef object arg
|
|
||||||
cdef NamedInjection injection
|
|
||||||
|
|
||||||
for name, arg in kwargs.items():
|
|
||||||
injection = NamedInjection(name, arg)
|
|
||||||
injections.append(injection)
|
|
||||||
|
|
||||||
return tuple(injections)
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,42 +0,0 @@
|
||||||
"""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 class DelegatedSingleton(Singleton):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
cdef class ThreadSafeSingleton(BaseSingleton):
|
|
||||||
cdef object __storage
|
|
||||||
cdef object __lock
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
cdef class ThreadLocalSingleton(BaseSingleton):
|
|
||||||
cdef object __storage
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
|
|
||||||
pass
|
|
|
@ -1,411 +0,0 @@
|
||||||
"""Dependency injector singleton providers.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import threading
|
|
||||||
|
|
||||||
from dependency_injector.errors import Error
|
|
||||||
|
|
||||||
from .base cimport Provider
|
|
||||||
from .factories cimport (
|
|
||||||
Factory,
|
|
||||||
__factory_call,
|
|
||||||
)
|
|
||||||
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."""
|
|
||||||
if self.__storage is None:
|
|
||||||
self.__storage = __factory_call(self.__instantiator,
|
|
||||||
args, kwargs)
|
|
||||||
return self.__storage
|
|
||||||
|
|
||||||
|
|
||||||
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."""
|
|
||||||
with self.__lock:
|
|
||||||
if self.__storage is None:
|
|
||||||
self.__storage = __factory_call(self.__instantiator,
|
|
||||||
args, kwargs)
|
|
||||||
return self.__storage
|
|
||||||
|
|
||||||
|
|
||||||
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."""
|
|
||||||
cdef object instance
|
|
||||||
|
|
||||||
try:
|
|
||||||
instance = self.__storage.instance
|
|
||||||
except AttributeError:
|
|
||||||
instance = __factory_call(self.__instantiator, args, kwargs)
|
|
||||||
self.__storage.instance = instance
|
|
||||||
finally:
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,21 +0,0 @@
|
||||||
"""Dependency injector provider utils.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef object CLASS_TYPES
|
|
||||||
|
|
||||||
|
|
||||||
cpdef bint is_provider(object instance)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef object ensure_is_provider(object instance)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef bint is_delegated(object instance)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef str represent_provider(object provider, object provides)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef object deepcopy(object instance, dict memo=*)
|
|
|
@ -1,86 +0,0 @@
|
||||||
"""Dependency injector provider utils.
|
|
||||||
|
|
||||||
Powered by Cython.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import copy
|
|
||||||
import sys
|
|
||||||
import types
|
|
||||||
import threading
|
|
||||||
|
|
||||||
from dependency_injector.errors import Error
|
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[0] == 3: # pragma: no cover
|
|
||||||
CLASS_TYPES = (type,)
|
|
||||||
else: # pragma: no cover
|
|
||||||
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):
|
|
||||||
"""Check if instance is provider instance.
|
|
||||||
|
|
||||||
:param instance: Instance to be checked.
|
|
||||||
:type instance: object
|
|
||||||
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return (not isinstance(instance, CLASS_TYPES) and
|
|
||||||
getattr(instance, '__IS_PROVIDER__', False) is True)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef object ensure_is_provider(object instance):
|
|
||||||
"""Check if instance is provider instance and return it.
|
|
||||||
|
|
||||||
:param instance: Instance to be checked.
|
|
||||||
:type instance: object
|
|
||||||
|
|
||||||
:raise: :py:exc:`dependency_injector.errors.Error` if provided instance is
|
|
||||||
not provider.
|
|
||||||
|
|
||||||
:rtype: :py:class:`dependency_injector.providers.Provider`
|
|
||||||
"""
|
|
||||||
if not is_provider(instance):
|
|
||||||
raise Error('Expected provider instance, '
|
|
||||||
'got {0}'.format(str(instance)))
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
cpdef bint is_delegated(object instance):
|
|
||||||
"""Check if instance is delegated provider.
|
|
||||||
|
|
||||||
:param instance: Instance to be checked.
|
|
||||||
:type instance: object
|
|
||||||
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return (not isinstance(instance, CLASS_TYPES) and
|
|
||||||
getattr(instance, '__IS_DELEGATED__', False) is True)
|
|
||||||
|
|
||||||
|
|
||||||
cpdef str represent_provider(object provider, object provides):
|
|
||||||
"""Return string representation of provider.
|
|
||||||
|
|
||||||
:param provider: Provider object
|
|
||||||
:type provider: :py:class:`dependency_injector.providers.Provider`
|
|
||||||
|
|
||||||
:param provides: Object that provider provides
|
|
||||||
:type provider: object
|
|
||||||
|
|
||||||
:return: String representation of provider
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
return '<{provider}({provides}) at {address}>'.format(
|
|
||||||
provider='.'.join((provider.__class__.__module__,
|
|
||||||
provider.__class__.__name__)),
|
|
||||||
provides=repr(provides) if provides is not None else '',
|
|
||||||
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)
|
|
|
@ -114,7 +114,7 @@ class ProviderTests(unittest.TestCase):
|
||||||
|
|
||||||
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.'
|
||||||
'Provider() at {0}>'.format(hex(id(self.provider))))
|
'Provider() at {0}>'.format(hex(id(self.provider))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ class ObjectProviderTests(unittest.TestCase):
|
||||||
some_object = object()
|
some_object = object()
|
||||||
provider = providers.Object(some_object)
|
provider = providers.Object(some_object)
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.base.'
|
'<dependency_injector.providers.'
|
||||||
'Object({0}) at {1}>'.format(
|
'Object({0}) at {1}>'.format(
|
||||||
repr(some_object),
|
repr(some_object),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -197,7 +197,7 @@ class DelegateTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
self.assertEqual(repr(self.delegate),
|
self.assertEqual(repr(self.delegate),
|
||||||
'<dependency_injector.providers.base.'
|
'<dependency_injector.providers.'
|
||||||
'Delegate({0}) at {1}>'.format(
|
'Delegate({0}) at {1}>'.format(
|
||||||
repr(self.delegated),
|
repr(self.delegated),
|
||||||
hex(id(self.delegate))))
|
hex(id(self.delegate))))
|
||||||
|
@ -259,7 +259,7 @@ class ExternalDependencyTests(unittest.TestCase):
|
||||||
|
|
||||||
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.'
|
||||||
'ExternalDependency({0}) at {1}>'.format(
|
'ExternalDependency({0}) at {1}>'.format(
|
||||||
repr(list),
|
repr(list),
|
||||||
hex(id(self.provider))))
|
hex(id(self.provider))))
|
||||||
|
|
|
@ -170,7 +170,7 @@ class CallableTests(unittest.TestCase):
|
||||||
provider = providers.Callable(self.example)
|
provider = providers.Callable(self.example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.callables.'
|
'<dependency_injector.providers.'
|
||||||
'Callable({0}) at {1}>'.format(
|
'Callable({0}) at {1}>'.format(
|
||||||
repr(self.example),
|
repr(self.example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -189,3 +189,12 @@ class DelegatedCallableTests(unittest.TestCase):
|
||||||
def test_is_delegated_provider(self):
|
def test_is_delegated_provider(self):
|
||||||
provider = providers.DelegatedCallable(len)
|
provider = providers.DelegatedCallable(len)
|
||||||
self.assertTrue(providers.is_delegated(provider))
|
self.assertTrue(providers.is_delegated(provider))
|
||||||
|
|
||||||
|
def test_repr(self):
|
||||||
|
provider = providers.DelegatedCallable(len)
|
||||||
|
|
||||||
|
self.assertEqual(repr(provider),
|
||||||
|
'<dependency_injector.providers.'
|
||||||
|
'DelegatedCallable({0}) at {1}>'.format(
|
||||||
|
repr(len),
|
||||||
|
hex(id(provider))))
|
||||||
|
|
|
@ -96,14 +96,14 @@ class ConfigTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
self.assertEqual(repr(self.config),
|
self.assertEqual(repr(self.config),
|
||||||
'<dependency_injector.providers.configuration.'
|
'<dependency_injector.providers.'
|
||||||
'Configuration({0}) at {1}>'.format(
|
'Configuration({0}) at {1}>'.format(
|
||||||
repr('config'),
|
repr('config'),
|
||||||
hex(id(self.config))))
|
hex(id(self.config))))
|
||||||
|
|
||||||
def test_repr_child(self):
|
def test_repr_child(self):
|
||||||
self.assertEqual(repr(self.config.a.b.c),
|
self.assertEqual(repr(self.config.a.b.c),
|
||||||
'<dependency_injector.providers.configuration.'
|
'<dependency_injector.providers.'
|
||||||
'Configuration({0}) at {1}>'.format(
|
'Configuration({0}) at {1}>'.format(
|
||||||
repr('config.a.b.c'),
|
repr('config.a.b.c'),
|
||||||
hex(id(self.config.a.b.c))))
|
hex(id(self.config.a.b.c))))
|
||||||
|
|
|
@ -325,7 +325,7 @@ class FactoryTests(unittest.TestCase):
|
||||||
provider = providers.Factory(Example)
|
provider = providers.Factory(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.factories.'
|
'<dependency_injector.providers.'
|
||||||
'Factory({0}) at {1}>'.format(
|
'Factory({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -344,3 +344,12 @@ class DelegatedFactoryTests(unittest.TestCase):
|
||||||
def test_is_delegated_provider(self):
|
def test_is_delegated_provider(self):
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
providers.is_delegated(providers.DelegatedFactory(object)))
|
providers.is_delegated(providers.DelegatedFactory(object)))
|
||||||
|
|
||||||
|
def test_repr(self):
|
||||||
|
provider = providers.DelegatedFactory(Example)
|
||||||
|
|
||||||
|
self.assertEqual(repr(provider),
|
||||||
|
'<dependency_injector.providers.'
|
||||||
|
'DelegatedFactory({0}) at {1}>'.format(
|
||||||
|
repr(Example),
|
||||||
|
hex(id(provider))))
|
||||||
|
|
|
@ -344,7 +344,7 @@ class SingletonTests(_BaseSingletonTestCase, unittest.TestCase):
|
||||||
provider = self.singleton_cls(Example)
|
provider = self.singleton_cls(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.singletons.'
|
'<dependency_injector.providers.'
|
||||||
'Singleton({0}) at {1}>'.format(
|
'Singleton({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -362,7 +362,7 @@ class DelegatedSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
|
||||||
provider = self.singleton_cls(Example)
|
provider = self.singleton_cls(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.singletons.'
|
'<dependency_injector.providers.'
|
||||||
'DelegatedSingleton({0}) at {1}>'.format(
|
'DelegatedSingleton({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -376,7 +376,7 @@ class ThreadLocalSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
|
||||||
provider = providers.ThreadLocalSingleton(Example)
|
provider = providers.ThreadLocalSingleton(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.singletons.'
|
'<dependency_injector.providers.'
|
||||||
'ThreadLocalSingleton({0}) at {1}>'.format(
|
'ThreadLocalSingleton({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -395,7 +395,7 @@ class DelegatedThreadLocalSingletonTests(_BaseSingletonTestCase,
|
||||||
provider = self.singleton_cls(Example)
|
provider = self.singleton_cls(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.singletons.'
|
'<dependency_injector.providers.'
|
||||||
'DelegatedThreadLocalSingleton({0}) at {1}>'.format(
|
'DelegatedThreadLocalSingleton({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -409,7 +409,7 @@ class ThreadSafeSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
|
||||||
provider = self.singleton_cls(Example)
|
provider = self.singleton_cls(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.singletons.'
|
'<dependency_injector.providers.'
|
||||||
'ThreadSafeSingleton({0}) at {1}>'.format(
|
'ThreadSafeSingleton({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
@ -428,7 +428,7 @@ class DelegatedThreadSafeSingletonTests(_BaseSingletonTestCase,
|
||||||
provider = self.singleton_cls(Example)
|
provider = self.singleton_cls(Example)
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.singletons.'
|
'<dependency_injector.providers.'
|
||||||
'DelegatedThreadSafeSingleton({0}) at {1}>'.format(
|
'DelegatedThreadSafeSingleton({0}) at {1}>'.format(
|
||||||
repr(Example),
|
repr(Example),
|
||||||
hex(id(provider))))
|
hex(id(provider))))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user