Cythonize MethodCaller

This commit is contained in:
Roman Mogylatov 2020-08-19 21:46:21 -04:00
parent 68eed5db33
commit 789d35e59b
4 changed files with 4158 additions and 2865 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -197,6 +197,17 @@ cdef class Selector(Provider):
cpdef object _provide(self, tuple args, dict kwargs) cpdef object _provide(self, tuple args, dict kwargs)
# Provided attributes
cdef class MethodCaller(Provider):
cdef Provider __provider
cdef tuple __args
cdef int __args_len
cdef tuple __kwargs
cdef int __kwargs_len
cpdef object _provide(self, tuple args, dict kwargs)
# Injections # Injections
cdef class Injection(object): cdef class Injection(object):
@ -352,18 +363,42 @@ cdef inline object __inject_attributes(
__get_value(attr_injection)) __get_value(attr_injection))
cdef inline object __callable_call(Callable self, tuple args, dict kwargs): cdef inline object __call(
object call,
tuple context_args,
tuple injection_args,
int injection_args_len,
dict kwargs,
tuple injection_kwargs,
int injection_kwargs_len,
):
cdef tuple positional_args cdef tuple positional_args
cdef dict keyword_args cdef dict keyword_args
positional_args = __provide_positional_args(args, positional_args = __provide_positional_args(
self.__args, context_args,
self.__args_len) injection_args,
keyword_args = __provide_keyword_args(kwargs, injection_args_len,
self.__kwargs, )
self.__kwargs_len) keyword_args = __provide_keyword_args(
kwargs,
injection_kwargs,
injection_kwargs_len,
)
return self.__provides(*positional_args, **keyword_args) return call(*positional_args, **keyword_args)
cdef inline object __callable_call(Callable self, tuple args, dict kwargs):
return __call(
self.__provides,
args,
self.__args,
self.__args_len,
kwargs,
self.__kwargs,
self.__kwargs_len,
)
cdef inline object __factory_call(Factory self, tuple args, dict kwargs): cdef inline object __factory_call(Factory self, tuple args, dict kwargs):

View File

@ -2589,6 +2589,9 @@ class ProvidedAttributes(Provider):
return f'ProvidedAttributes({self._provider})' return f'ProvidedAttributes({self._provider})'
def __deepcopy__(self, memo=None): def __deepcopy__(self, memo=None):
copied = memo.get(id(self))
if copied is not None:
return copied
return self.__class__(deepcopy(self._provider, memo)) return self.__class__(deepcopy(self._provider, memo))
def __getattr__(self, item): def __getattr__(self, item):
@ -2615,6 +2618,9 @@ class AttributeGetter(Provider):
return f'AttributeGetter({self._attribute})' return f'AttributeGetter({self._attribute})'
def __deepcopy__(self, memo=None): def __deepcopy__(self, memo=None):
copied = memo.get(id(self))
if copied is not None:
return copied
return self.__class__(deepcopy(self._provider, memo), self._attribute) return self.__class__(deepcopy(self._provider, memo), self._attribute)
def __getattr__(self, item): def __getattr__(self, item):
@ -2642,6 +2648,9 @@ class ItemGetter(Provider):
return f'ItemGetter({self._item})' return f'ItemGetter({self._item})'
def __deepcopy__(self, memo=None): def __deepcopy__(self, memo=None):
copied = memo.get(id(self))
if copied is not None:
return copied
return self.__class__(deepcopy(self._provider, memo), self._item) return self.__class__(deepcopy(self._provider, memo), self._item)
def __getattr__(self, item): def __getattr__(self, item):
@ -2658,23 +2667,38 @@ class ItemGetter(Provider):
return provided[self._item] return provided[self._item]
class MethodCaller(Provider): cdef class MethodCaller(Provider):
def __init__(self, provider, *args, **kwargs): def __init__(self, provider, *args, **kwargs):
self._provider = provider self.__provider = provider
self._args = args
self._kwargs = kwargs self.__args = parse_positional_injections(args)
self.__args_len = len(self.__args)
self.__kwargs = parse_named_injections(kwargs)
self.__kwargs_len = len(self.__kwargs)
super().__init__() super().__init__()
def __repr__(self): def __repr__(self):
return f'MethodCaller({self._provider})' return f'MethodCaller({self.__provider})'
def __deepcopy__(self, memo=None): def __deepcopy__(self, memo=None):
return self.__class__( cdef MethodCaller copied
deepcopy(self._provider, memo),
*deepcopy(self._args, memo), copied = memo.get(id(self))
**deepcopy(self._kwargs, memo), 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
self._copy_overridings(copied, memo)
return copied
def __getattr__(self, item): def __getattr__(self, item):
return AttributeGetter(self, item) return AttributeGetter(self, item)
@ -2685,10 +2709,17 @@ class MethodCaller(Provider):
def call(self, *args, **kwargs): def call(self, *args, **kwargs):
return MethodCaller(self, *args, **kwargs) return MethodCaller(self, *args, **kwargs)
def _provide(self, args, kwargs): cpdef object _provide(self, tuple args, dict kwargs):
provided = self._provider(*args, **kwargs) call = self.__provider()
# TODO: add proper handling of injections return __call(
return provided(*self._args, **self._kwargs) call,
args,
self.__args,
self.__args_len,
kwargs,
self.__kwargs,
self.__kwargs_len,
)
cdef class Injection(object): cdef class Injection(object):