mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +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 Provider __provider
 | 
			
		||||
 *     cdef object __provides
 | 
			
		||||
 *     cdef tuple __args
 | 
			
		||||
 */
 | 
			
		||||
struct __pyx_obj_19dependency_injector_9providers_MethodCaller {
 | 
			
		||||
  struct __pyx_obj_19dependency_injector_9providers_Provider __pyx_base;
 | 
			
		||||
  struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx___provider;
 | 
			
		||||
  PyObject *__pyx___provides;
 | 
			
		||||
  PyObject *__pyx___args;
 | 
			
		||||
  int __pyx___args_len;
 | 
			
		||||
  PyObject *__pyx___kwargs;
 | 
			
		||||
| 
						 | 
				
			
			@ -2186,7 +2186,7 @@ static struct __pyx_vtabstruct_19dependency_injector_9providers_ItemGetter *__py
 | 
			
		|||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 * cdef class MethodCaller(Provider):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *     cdef Provider __provider
 | 
			
		||||
 *     cdef object __provides
 | 
			
		||||
 *     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 Provider __provider
 | 
			
		||||
    cdef object __provides
 | 
			
		||||
    cdef tuple __args
 | 
			
		||||
    cdef int __args_len
 | 
			
		||||
    cdef tuple __kwargs
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -447,7 +447,7 @@ class ItemGetter(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]):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3948,7 +3948,7 @@ cdef class AttributeGetter(Provider):
 | 
			
		|||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'{self.__class__.__name__}(\'{self.__name}\')'
 | 
			
		||||
        return f'{self.__class__.__name__}(\'{self.name}\')'
 | 
			
		||||
 | 
			
		||||
    def __deepcopy__(self, memo):
 | 
			
		||||
        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.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, provider, *args, **kwargs):
 | 
			
		||||
        self.__provider = provider
 | 
			
		||||
    def __init__(self, provides=None, *args, **kwargs):
 | 
			
		||||
        self.__provides = None
 | 
			
		||||
        self.set_provides(provides)
 | 
			
		||||
 | 
			
		||||
        self.__args = parse_positional_injections(args)
 | 
			
		||||
        self.__args_len = len(self.__args)
 | 
			
		||||
        self.__args = tuple()
 | 
			
		||||
        self.__args_len = 0
 | 
			
		||||
        self.set_args(*args)
 | 
			
		||||
 | 
			
		||||
        self.__kwargs = parse_named_injections(kwargs)
 | 
			
		||||
        self.__kwargs_len = len(self.__kwargs)
 | 
			
		||||
        self.__kwargs = tuple()
 | 
			
		||||
        self.__kwargs_len = 0
 | 
			
		||||
        self.set_kwargs(**kwargs)
 | 
			
		||||
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'{self.__class__.__name__}({self.__provider})'
 | 
			
		||||
 | 
			
		||||
    def __deepcopy__(self, memo=None):
 | 
			
		||||
        cdef MethodCaller copied
 | 
			
		||||
        return f'{self.__class__.__name__}({self.provides})'
 | 
			
		||||
 | 
			
		||||
    def __deepcopy__(self, memo):
 | 
			
		||||
        copied = memo.get(id(self))
 | 
			
		||||
        if copied is not None:
 | 
			
		||||
            return copied
 | 
			
		||||
 | 
			
		||||
        copied = self.__class__(deepcopy(self.__provider, memo))
 | 
			
		||||
        copied.__args = deepcopy(self.__args, memo)
 | 
			
		||||
        copied.__args_len = self.__args_len
 | 
			
		||||
        copied.__kwargs = deepcopy(self.__kwargs, memo)
 | 
			
		||||
        copied.__kwargs_len = self.__kwargs_len
 | 
			
		||||
 | 
			
		||||
        copied = _memorized_duplicate(self, memo)
 | 
			
		||||
        copied.set_provides(_copy_if_provider(self.provides, memo))
 | 
			
		||||
        copied.set_args(*deepcopy(self.args, memo))
 | 
			
		||||
        copied.set_kwargs(**deepcopy(self.kwargs, memo))
 | 
			
		||||
        self._copy_overridings(copied, memo)
 | 
			
		||||
 | 
			
		||||
        return copied
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, item):
 | 
			
		||||
| 
						 | 
				
			
			@ -4136,10 +4134,18 @@ cdef class MethodCaller(Provider):
 | 
			
		|||
    def __getitem__(self, item):
 | 
			
		||||
        return ItemGetter(self, item)
 | 
			
		||||
 | 
			
		||||
    def call(self, *args, **kwargs):
 | 
			
		||||
        return MethodCaller(self, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def provides(self):
 | 
			
		||||
        """Return provider."""
 | 
			
		||||
        return self.__provider
 | 
			
		||||
        """Return provider's provides."""
 | 
			
		||||
        return self.__provides
 | 
			
		||||
 | 
			
		||||
    def set_provides(self, provides):
 | 
			
		||||
        """Set provider's provides."""
 | 
			
		||||
        self.__provides = provides
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def args(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -4154,6 +4160,17 @@ cdef class MethodCaller(Provider):
 | 
			
		|||
            args.append(arg.__value)
 | 
			
		||||
        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
 | 
			
		||||
    def kwargs(self):
 | 
			
		||||
        """Return keyword argument injections."""
 | 
			
		||||
| 
						 | 
				
			
			@ -4167,19 +4184,28 @@ cdef class MethodCaller(Provider):
 | 
			
		|||
            kwargs[kwarg.__name] = kwarg.__value
 | 
			
		||||
        return kwargs
 | 
			
		||||
 | 
			
		||||
    def call(self, *args, **kwargs):
 | 
			
		||||
        return MethodCaller(self, *args, **kwargs)
 | 
			
		||||
    def set_kwargs(self, **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
 | 
			
		||||
    def related(self):
 | 
			
		||||
        """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.kwargs.values())
 | 
			
		||||
        yield from super().related
 | 
			
		||||
 | 
			
		||||
    cpdef object _provide(self, tuple args, dict kwargs):
 | 
			
		||||
        call = self.__provider()
 | 
			
		||||
        call = self.provides()
 | 
			
		||||
        if __is_future_or_coroutine(call):
 | 
			
		||||
            future_result = asyncio.Future()
 | 
			
		||||
            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_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):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user