Skip to content

Commit ddeb2d1

Browse files
committed
separate sync and async omit_exception decorator for simplicity
1 parent 30d085a commit ddeb2d1

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

django_valkey/async_cache/cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
BaseValkeyCache,
55
AsyncBackendCommands,
66
decorate_all_methods,
7-
omit_exception,
7+
omit_exception_async,
88
)
99
from django_valkey.async_cache.client.default import AsyncDefaultClient
1010

1111

12-
@decorate_all_methods(omit_exception)
12+
@decorate_all_methods(omit_exception_async)
1313
class DecoratedAsyncBackendCommands(AsyncBackendCommands):
1414
pass
1515

django_valkey/base.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import inspect
55
import logging
66
from collections.abc import AsyncGenerator, Callable, Iterator
7-
from inspect import iscoroutinefunction
87
from typing import (
98
Any,
109
TypeVar,
@@ -91,6 +90,34 @@ def _generator_decorator(self, *args, **kwargs):
9190
except ConnectionInterrupted as e:
9291
yield __handle_error(self, e)
9392

93+
# sync generators (iter_keys, sscan_iter) are only generator on client class
94+
# in the backend they are just a function (that returns a generator)
95+
# so inspect.isgeneratorfunction does not work
96+
if not gen:
97+
wrapper = _decorator
98+
99+
# if method is a generator or async generator, it should be iterated over by this decorator
100+
# generators don't error by simply being called, they need to be iterated over.
101+
else:
102+
wrapper = _generator_decorator
103+
104+
return wrapper
105+
106+
107+
def omit_exception_async(
108+
method: Callable | None = None, return_value: Any | None = None, gen=False
109+
):
110+
if method is None:
111+
return functools.partial(omit_exception, return_value=return_value)
112+
113+
def __handle_error(self, e) -> Any | None:
114+
if getattr(self, "_ignore_exceptions", None):
115+
if getattr(self, "_log_ignored_exceptions", None):
116+
self.logger.exception("Exception ignored")
117+
118+
return return_value
119+
raise e.__cause__
120+
94121
@functools.wraps(method)
95122
async def _async_decorator(self, *args, **kwargs):
96123
try:
@@ -106,20 +133,12 @@ async def _async_generator_decorator(self, *args, **kwargs):
106133
except ConnectionInterrupted as e:
107134
yield __handle_error(self, e)
108135

109-
# sync generators (iter_keys, sscan_iter) are only generator on client class
110-
# in the backend they are just a function (that returns a generator)
111-
# so inspect.isgeneratorfunction does not work
112-
if not inspect.isasyncgenfunction(method) and not gen:
113-
wrapper = _async_decorator if iscoroutinefunction(method) else _decorator
114-
115-
# if method is a generator or async generator, it should be iterated over by this decorator
116-
# generators don't error by simply being called, they need to be iterated over.
136+
if inspect.isasyncgenfunction(method):
137+
# if method is a generator or async generator, it should be iterated over by this decorator
138+
# generators don't error by simply being called, they need to be iterated over.
139+
wrapper = _async_generator_decorator
117140
else:
118-
wrapper = (
119-
_async_generator_decorator
120-
if inspect.isasyncgenfunction(method)
121-
else _generator_decorator
122-
)
141+
wrapper = _async_decorator
123142

124143
return wrapper
125144

0 commit comments

Comments
 (0)