add setters/getters for resource, shutdown, initialized

This commit is contained in:
elina-israyelyan 2025-11-02 00:37:15 +04:00
parent bc7b4ebc37
commit 066d228ab9
2 changed files with 102 additions and 62 deletions

View File

@ -226,9 +226,9 @@ cdef class Dict(Provider):
cdef class Resource(Provider): cdef class Resource(Provider):
cdef object _provides cdef object _provides
cdef bint _initialized cdef bint __initialized
cdef object _shutdowner cdef object __shutdowner
cdef object _resource cdef object __resource
cdef tuple _args cdef tuple _args
cdef int _args_len cdef int _args_len
@ -241,6 +241,7 @@ cdef class Resource(Provider):
cdef class ContextLocalResource(Resource): cdef class ContextLocalResource(Resource):
cdef object _resource_context_var cdef object _resource_context_var
cdef object _initialized_context_var
cdef object _shutdowner_context_var cdef object _shutdowner_context_var
cpdef object _provide(self, tuple args, dict kwargs) cpdef object _provide(self, tuple args, dict kwargs)

View File

@ -3620,9 +3620,9 @@ cdef class Resource(Provider):
self._provides = None self._provides = None
self.set_provides(provides) self.set_provides(provides)
self._initialized = False self.__initialized = False
self._resource = None self.__resource = None
self._shutdowner = None self.__shutdowner = None
self._args = tuple() self._args = tuple()
self._args_len = 0 self._args_len = 0
@ -3760,6 +3760,36 @@ cdef class Resource(Provider):
self._kwargs_len = len(self._kwargs) self._kwargs_len = len(self._kwargs)
return self return self
@property
def _initialized(self):
"""Get initialized state."""
return self.__initialized
@_initialized.setter
def _initialized(self, value):
"""Set initialized state."""
self.__initialized = value
@property
def _resource(self):
"""Get resource."""
return self.__resource
@_resource.setter
def _resource(self, value):
"""Set resource."""
self.__resource = value
@property
def _shutdowner(self):
"""Get shutdowner."""
return self.__shutdowner
@_shutdowner.setter
def _shutdowner(self, value):
"""Set shutdowner."""
self.__shutdowner = value
@property @property
def initialized(self): def initialized(self):
"""Check if resource is initialized.""" """Check if resource is initialized."""
@ -3871,45 +3901,55 @@ cdef class ContextLocalResource(Resource):
_none = object() _none = object()
def __init__(self, provides=None, *args, **kwargs): def __init__(self, provides=None, *args, **kwargs):
self._initialized_context_var = ContextVar("_initialized_context_var", default=False)
self._resource_context_var = ContextVar("_resource_context_var", default=self._none) self._resource_context_var = ContextVar("_resource_context_var", default=self._none)
self._shutdowner_context_var = ContextVar("_shutdowner_context_var", default=self._none) self._shutdowner_context_var = ContextVar("_shutdowner_context_var", default=self._none)
super().__init__(provides, *args, **kwargs) super().__init__(provides, *args, **kwargs)
def __deepcopy__(self, memo): @property
"""Create and return full copy of provider.""" def _initialized(self):
copied = memo.get(id(self)) """Get initialized state."""
if copied is not None: return self._initialized_context_var.get()
return copied
if self._resource_context_var.get() != self._none: @_initialized.setter
raise Error("Can not copy initialized resource") def _initialized(self, value):
copied = _memorized_duplicate(self, memo) """Set initialized state."""
copied.set_provides(_copy_if_provider(self.provides, memo)) self._initialized_context_var.set(value)
copied.set_args(*deepcopy_args(self, self.args, memo))
copied.set_kwargs(**deepcopy_kwargs(self, self.kwargs, memo))
self._copy_overridings(copied, memo)
return copied
@property @property
def initialized(self): def _resource(self):
"""Check if resource is initialized.""" """Get resource."""
return self._resource_context_var.get() != self._none return self._resource_context_var.get()
@_resource.setter
def _resource(self, value):
"""Set resource."""
self._resource_context_var.set(value)
@property
def _shutdowner(self):
"""Get shutdowner."""
return self._shutdowner_context_var.get()
@_shutdowner.setter
def _shutdowner(self, value):
"""Set shutdowner."""
self._shutdowner_context_var.set(value)
def shutdown(self): def shutdown(self):
"""Shutdown resource.""" """Shutdown resource."""
if self._resource_context_var.get() == self._none : if not self._initialized :
self._reset_all_contex_vars() self._reset_all_contex_vars()
if self._async_mode == ASYNC_MODE_ENABLED: if self._async_mode == ASYNC_MODE_ENABLED:
return NULL_AWAITABLE return NULL_AWAITABLE
return return
if self._shutdowner_context_var.get() != self._none:
future = self._shutdowner_context_var.get()(None, None, None) if self._shutdowner != self._none:
future = self._shutdowner(None, None, None)
if __is_future_or_coroutine(future): if __is_future_or_coroutine(future):
self._reset_all_contex_vars() self._reset_all_contex_vars()
return ensure_future(self._shutdown_async(future)) return ensure_future(future)
self._reset_all_contex_vars() self._reset_all_contex_vars()
@ -3917,20 +3957,15 @@ cdef class ContextLocalResource(Resource):
return NULL_AWAITABLE return NULL_AWAITABLE
def _reset_all_contex_vars(self): def _reset_all_contex_vars(self):
self._resource_context_var.set(self._none) self._initialized=False
self._shutdowner_context_var.set(self._none) self._resource = self._none
self._shutdowner = self._none
async def _shutdown_async(self, future) -> None:
await future
async def _handle_async_cm(self, obj) -> None: async def _handle_async_cm(self, obj) -> None:
resource = await obj.__aenter__() resource = await obj.__aenter__()
return resource return resource
async def _provide_async(self, future): async def _provide_async(self, future):
try:
obj = await future obj = await future
if hasattr(obj, '__aenter__') and hasattr(obj, '__aexit__'): if hasattr(obj, '__aenter__') and hasattr(obj, '__aexit__'):
@ -3941,15 +3976,14 @@ cdef class ContextLocalResource(Resource):
shutdowner = obj.__exit__ shutdowner = obj.__exit__
else: else:
resource = obj resource = obj
shutdowner = None shutdowner = self._none
return resource, shutdowner return resource, shutdowner
except:
raise
cpdef object _provide(self, tuple args, dict kwargs): cpdef object _provide(self, tuple args, dict kwargs):
if self._resource_context_var.get() != self._none: if self._initialized:
return self._resource_context_var.get() return self._resource
obj = __call( obj = __call(
self._provides, self._provides,
args, args,
@ -3968,29 +4002,34 @@ cdef class ContextLocalResource(Resource):
return future_result return future_result
elif hasattr(obj, '__enter__') and hasattr(obj, '__exit__'): elif hasattr(obj, '__enter__') and hasattr(obj, '__exit__'):
resource = obj.__enter__() resource = obj.__enter__()
self._resource_context_var.set(resource) self._resource = resource
self._shutdowner_context_var.set(obj.__exit__) self._initialized = True
self._shutdowner = obj.__exit__
elif hasattr(obj, '__aenter__') and hasattr(obj, '__aexit__'): elif hasattr(obj, '__aenter__') and hasattr(obj, '__aexit__'):
resource = ensure_future(self._handle_async_cm(obj)) resource = ensure_future(self._handle_async_cm(obj))
self._resource_context_var.set(resource) self._resource = resource
self._shutdowner_context_var.set(obj.__aexit__) self._initialized = True
self._shutdowner = obj.__aexit__
return resource return resource
else: else:
self._resource_context_var.set(obj) self._resource = obj
self._shutdowner_context_var.set(self._none) self._initialized = True
self._shutdowner = self._none
return self._resource_context_var.get() return self._resource
def _async_init_instance(self, future_result, result): def _async_init_instance(self, future_result, result):
try: try:
resource, shutdowner = result.result() resource, shutdowner = result.result()
except Exception as exception: except Exception as exception:
self._resource_context_var.set(self._none) self._resource = self._none
self._shutdowner_context_var.set(self._none) self._shutdowner = self._none
self._initialized = False
future_result.set_exception(exception) future_result.set_exception(exception)
else: else:
self._resource_context_var.set(resource) self._resource = resource
self._shutdowner_context_var.set(shutdowner) self._initialized = True
self._shutdowner = shutdowner
future_result.set_result(resource) future_result.set_result(resource)