mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-16 03:20:50 +03:00
Implement lazy initialization and improve copying for MethodCaller provder
This commit is contained in:
parent
773a7d86f7
commit
052413d3f4
|
@ -1430,12 +1430,12 @@ struct __pyx_obj_19dependency_injector_9providers_ItemGetter {
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* cdef class MethodCaller(Provider): # <<<<<<<<<<<<<<
|
* cdef class MethodCaller(Provider): # <<<<<<<<<<<<<<
|
||||||
* cdef Provider __provider
|
* cdef object __provides
|
||||||
* cdef tuple __args
|
* cdef tuple __args
|
||||||
*/
|
*/
|
||||||
struct __pyx_obj_19dependency_injector_9providers_MethodCaller {
|
struct __pyx_obj_19dependency_injector_9providers_MethodCaller {
|
||||||
struct __pyx_obj_19dependency_injector_9providers_Provider __pyx_base;
|
struct __pyx_obj_19dependency_injector_9providers_Provider __pyx_base;
|
||||||
struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx___provider;
|
PyObject *__pyx___provides;
|
||||||
PyObject *__pyx___args;
|
PyObject *__pyx___args;
|
||||||
int __pyx___args_len;
|
int __pyx___args_len;
|
||||||
PyObject *__pyx___kwargs;
|
PyObject *__pyx___kwargs;
|
||||||
|
@ -2186,7 +2186,7 @@ static struct __pyx_vtabstruct_19dependency_injector_9providers_ItemGetter *__py
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* cdef class MethodCaller(Provider): # <<<<<<<<<<<<<<
|
* cdef class MethodCaller(Provider): # <<<<<<<<<<<<<<
|
||||||
* cdef Provider __provider
|
* cdef object __provides
|
||||||
* cdef tuple __args
|
* cdef tuple __args
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -255,7 +255,7 @@ cdef class ItemGetter(Provider):
|
||||||
|
|
||||||
|
|
||||||
cdef class MethodCaller(Provider):
|
cdef class MethodCaller(Provider):
|
||||||
cdef Provider __provider
|
cdef object __provides
|
||||||
cdef tuple __args
|
cdef tuple __args
|
||||||
cdef int __args_len
|
cdef int __args_len
|
||||||
cdef tuple __kwargs
|
cdef tuple __kwargs
|
||||||
|
|
|
@ -447,7 +447,7 @@ class ItemGetter(Provider, ProvidedInstanceFluentInterface):
|
||||||
|
|
||||||
|
|
||||||
class MethodCaller(Provider, ProvidedInstanceFluentInterface):
|
class MethodCaller(Provider, ProvidedInstanceFluentInterface):
|
||||||
def __init__(self, provider: Provider, *args: Injection, **kwargs: Injection) -> None: ...
|
def __init__(self, provides: Optional[Provider] = None, *args: Injection, **kwargs: Injection) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class OverridingContext(Generic[T]):
|
class OverridingContext(Generic[T]):
|
||||||
|
|
|
@ -3948,7 +3948,7 @@ cdef class AttributeGetter(Provider):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{self.__class__.__name__}(\'{self.__name}\')'
|
return f'{self.__class__.__name__}(\'{self.name}\')'
|
||||||
|
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
copied = memo.get(id(self))
|
copied = memo.get(id(self))
|
||||||
|
@ -4099,35 +4099,33 @@ cdef class MethodCaller(Provider):
|
||||||
You should not create this provider directly. See :py:class:`ProvidedInstance` instead.
|
You should not create this provider directly. See :py:class:`ProvidedInstance` instead.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, provider, *args, **kwargs):
|
def __init__(self, provides=None, *args, **kwargs):
|
||||||
self.__provider = provider
|
self.__provides = None
|
||||||
|
self.set_provides(provides)
|
||||||
|
|
||||||
self.__args = parse_positional_injections(args)
|
self.__args = tuple()
|
||||||
self.__args_len = len(self.__args)
|
self.__args_len = 0
|
||||||
|
self.set_args(*args)
|
||||||
|
|
||||||
self.__kwargs = parse_named_injections(kwargs)
|
self.__kwargs = tuple()
|
||||||
self.__kwargs_len = len(self.__kwargs)
|
self.__kwargs_len = 0
|
||||||
|
self.set_kwargs(**kwargs)
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{self.__class__.__name__}({self.__provider})'
|
return f'{self.__class__.__name__}({self.provides})'
|
||||||
|
|
||||||
def __deepcopy__(self, memo=None):
|
|
||||||
cdef MethodCaller copied
|
|
||||||
|
|
||||||
|
def __deepcopy__(self, memo):
|
||||||
copied = memo.get(id(self))
|
copied = memo.get(id(self))
|
||||||
if copied is not None:
|
if copied is not None:
|
||||||
return copied
|
return copied
|
||||||
|
|
||||||
copied = self.__class__(deepcopy(self.__provider, memo))
|
copied = _memorized_duplicate(self, memo)
|
||||||
copied.__args = deepcopy(self.__args, memo)
|
copied.set_provides(_copy_if_provider(self.provides, memo))
|
||||||
copied.__args_len = self.__args_len
|
copied.set_args(*deepcopy(self.args, memo))
|
||||||
copied.__kwargs = deepcopy(self.__kwargs, memo)
|
copied.set_kwargs(**deepcopy(self.kwargs, memo))
|
||||||
copied.__kwargs_len = self.__kwargs_len
|
|
||||||
|
|
||||||
self._copy_overridings(copied, memo)
|
self._copy_overridings(copied, memo)
|
||||||
|
|
||||||
return copied
|
return copied
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
|
@ -4136,10 +4134,18 @@ cdef class MethodCaller(Provider):
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return ItemGetter(self, item)
|
return ItemGetter(self, item)
|
||||||
|
|
||||||
|
def call(self, *args, **kwargs):
|
||||||
|
return MethodCaller(self, *args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def provides(self):
|
def provides(self):
|
||||||
"""Return provider."""
|
"""Return provider's provides."""
|
||||||
return self.__provider
|
return self.__provides
|
||||||
|
|
||||||
|
def set_provides(self, provides):
|
||||||
|
"""Set provider's provides."""
|
||||||
|
self.__provides = provides
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def args(self):
|
def args(self):
|
||||||
|
@ -4154,6 +4160,17 @@ cdef class MethodCaller(Provider):
|
||||||
args.append(arg.__value)
|
args.append(arg.__value)
|
||||||
return tuple(args)
|
return tuple(args)
|
||||||
|
|
||||||
|
def set_args(self, *args):
|
||||||
|
"""Set positional argument injections.
|
||||||
|
|
||||||
|
Existing positional argument injections are dropped.
|
||||||
|
|
||||||
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self.__args = parse_positional_injections(args)
|
||||||
|
self.__args_len = len(self.__args)
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kwargs(self):
|
def kwargs(self):
|
||||||
"""Return keyword argument injections."""
|
"""Return keyword argument injections."""
|
||||||
|
@ -4167,19 +4184,28 @@ cdef class MethodCaller(Provider):
|
||||||
kwargs[kwarg.__name] = kwarg.__value
|
kwargs[kwarg.__name] = kwarg.__value
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def call(self, *args, **kwargs):
|
def set_kwargs(self, **kwargs):
|
||||||
return MethodCaller(self, *args, **kwargs)
|
"""Set keyword argument injections.
|
||||||
|
|
||||||
|
Existing keyword argument injections are dropped.
|
||||||
|
|
||||||
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self.__kwargs = parse_named_injections(kwargs)
|
||||||
|
self.__kwargs_len = len(self.__kwargs)
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def related(self):
|
def related(self):
|
||||||
"""Return related providers generator."""
|
"""Return related providers generator."""
|
||||||
yield self.__provider
|
if is_provider(self.provides):
|
||||||
|
yield self.provides
|
||||||
yield from filter(is_provider, self.args)
|
yield from filter(is_provider, self.args)
|
||||||
yield from filter(is_provider, self.kwargs.values())
|
yield from filter(is_provider, self.kwargs.values())
|
||||||
yield from super().related
|
yield from super().related
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
call = self.__provider()
|
call = self.provides()
|
||||||
if __is_future_or_coroutine(call):
|
if __is_future_or_coroutine(call):
|
||||||
future_result = asyncio.Future()
|
future_result = asyncio.Future()
|
||||||
call = asyncio.ensure_future(call)
|
call = asyncio.ensure_future(call)
|
||||||
|
|
|
@ -155,6 +155,14 @@ class LazyInitTests(unittest.TestCase):
|
||||||
self.assertIs(provider.set_provides(providers.Provider()), provider)
|
self.assertIs(provider.set_provides(providers.Provider()), provider)
|
||||||
self.assertIs(provider.set_name('foo'), provider)
|
self.assertIs(provider.set_name('foo'), provider)
|
||||||
|
|
||||||
|
def test_method_caller(self):
|
||||||
|
provides = providers.Object(lambda: 42)
|
||||||
|
provider = providers.MethodCaller()
|
||||||
|
provider.set_provides(provides)
|
||||||
|
self.assertIs(provider.provides, provides)
|
||||||
|
self.assertEqual(provider(), 42)
|
||||||
|
self.assertIs(provider.set_provides(providers.Provider()), provider)
|
||||||
|
|
||||||
|
|
||||||
class ProvidedInstancePuzzleTests(unittest.TestCase):
|
class ProvidedInstancePuzzleTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user