Skip to content

Commit 070d010

Browse files
authored
Merge pull request #11 from aikikode/master
Enable async decorator parametrization
2 parents b4807ef + 3571fe4 commit 070d010

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

fqn_decorators/asynchronous.py

+18-12
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,25 @@
99

1010

1111
class AsyncDecorator(Decorator):
12-
async def __call__(self, *args, **kwargs):
12+
# __call__ should be sync to return a decorator class object, not a coroutine
13+
def __call__(self, *args, **kwargs):
14+
if not self.func:
15+
# Decorator initialized without providing the function (parametrised decorator)
16+
return self.__class__(args[0], **self.params)
17+
1318
self.fqn = self.get_fqn()
1419
self.args = args
1520
self.kwargs = kwargs
1621

17-
self.before()
18-
try:
19-
self.result = await self.func(*self.args, **self.kwargs)
20-
except:
21-
self.exc_info = sys.exc_info()
22-
self.exception()
23-
raise
24-
finally:
25-
self.after()
26-
27-
return self.result
22+
async def async_wrapper(*args, **kwargs):
23+
self.before()
24+
try:
25+
self.result = await self.func(*self.args, **self.kwargs)
26+
except:
27+
self.exc_info = sys.exc_info()
28+
self.exception()
29+
raise
30+
finally:
31+
self.after()
32+
return self.result
33+
return async_wrapper(*args, **kwargs)

tests/test_fqn_decorators_asynchronous.py

+31
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
from fqn_decorators.asynchronous import AsyncDecorator
55

66

7+
class CustomException(Exception):
8+
pass
9+
10+
711
class TestFqnAsync:
812
def test_class_async(self):
913
assert get_fqn(AsyncDecorator) == \
@@ -109,3 +113,30 @@ def check_permission(self):
109113

110114
with pytest.raises(RuntimeError):
111115
await User().check_permission()
116+
117+
async def test_function_parametrized_decoration_expected(self):
118+
class Decorator(AsyncDecorator):
119+
def after(self):
120+
if 'decorator_param' not in self.params:
121+
raise CustomException('No decorator param')
122+
self.result = self.params['decorator_param']
123+
124+
@Decorator
125+
async def return_decorator_value():
126+
return False
127+
128+
with pytest.raises(CustomException):
129+
await return_decorator_value()
130+
131+
async def test_function_parametrized_decoration(self):
132+
class Decorator(AsyncDecorator):
133+
def after(self):
134+
if 'decorator_param' not in self.params:
135+
raise CustomException('No decorator param')
136+
self.result = self.params['decorator_param']
137+
138+
@Decorator(decorator_param='hello')
139+
async def return_decorator_value():
140+
return False
141+
142+
assert await return_decorator_value() == 'hello'

0 commit comments

Comments
 (0)