Skip to content

Commit 206d9d2

Browse files
Merge pull request #8 from kammala/py37
OPT python3.7 support
2 parents 176cdf8 + 93433c2 commit 206d9d2

File tree

7 files changed

+49
-45
lines changed

7 files changed

+49
-45
lines changed

fqn_decorators/async.py

+7-25
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,9 @@
1-
"""This module implements an async-aware decorator.
1+
import warnings
22

3-
For backwards compatibility with Python 2.x, it needs to remain separate from
4-
the rest of the codebase, since it uses Python 3.5 syntax (``async def``, ``await``).
5-
"""
6-
import sys
3+
warnings.warn(
4+
'This module was renamed to `asynchronous` due to adding `async`'
5+
' keyword in python 3.7',
6+
PendingDeprecationWarning
7+
)
78

8-
from .decorators import Decorator
9-
10-
11-
class AsyncDecorator(Decorator):
12-
async def __call__(self, *args, **kwargs):
13-
self.fqn = self.get_fqn()
14-
self.args = args
15-
self.kwargs = kwargs
16-
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
9+
from .asynchronous import * # isort:skip

fqn_decorators/asynchronous.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""This module implements an async-aware decorator.
2+
3+
For backwards compatibility with Python 2.x, it needs to remain separate from
4+
the rest of the codebase, since it uses Python 3.5 syntax (``async def``, ``await``).
5+
"""
6+
import sys
7+
8+
from .decorators import Decorator
9+
10+
11+
class AsyncDecorator(Decorator):
12+
async def __call__(self, *args, **kwargs):
13+
self.fqn = self.get_fqn()
14+
self.args = args
15+
self.kwargs = kwargs
16+
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

requirements/requirements-testing.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pkgversion
66
# PyTest for running the tests.
77
pytest
88
pytest-cov
9+
pytest-asyncio; python_version >= '3.5'
910

1011
# docs
1112
sphinx

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
'Programming Language :: Python :: 3',
1313
'Programming Language :: Python :: 3.5',
1414
'Programming Language :: Python :: 3.6',
15+
'Programming Language :: Python :: 3.7',
1516
'Topic :: Internet :: WWW/HTTP'],
1617
'description': 'Easily create multi-purpose decorators that have access to '
1718
'the FQN of the original function.',

setup_gen.py

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
'Programming Language :: Python :: 3',
2828
'Programming Language :: Python :: 3.5',
2929
'Programming Language :: Python :: 3.6',
30+
'Programming Language :: Python :: 3.7',
3031
'Topic :: Internet :: WWW/HTTP',
3132
]
3233
)

tests/test_fqn_decorators_async.py renamed to tests/test_fqn_decorators_asynchronous.py

+11-14
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
11
import mock
22
import pytest
33
from fqn_decorators import get_fqn
4-
from fqn_decorators.async import AsyncDecorator
5-
6-
# All test functions in this module will be treated as coroutines.
7-
# This avoids having to decorate every function with ``@pytest.mark.asyncio``.
8-
pytestmark = pytest.mark.asyncio
4+
from fqn_decorators.asynchronous import AsyncDecorator
95

106

117
class TestFqnAsync:
12-
async def test_class_async(self):
8+
def test_class_async(self):
139
assert get_fqn(AsyncDecorator) == \
14-
'fqn_decorators.async.AsyncDecorator'
10+
'fqn_decorators.asynchronous.AsyncDecorator'
1511

16-
async def test_method_async(self):
12+
def test_method_async(self):
1713
assert get_fqn(AsyncDecorator().before) == \
18-
'fqn_decorators.async.AsyncDecorator.before'
14+
'fqn_decorators.asynchronous.AsyncDecorator.before'
1915

20-
async def test_decorated_method_async(self):
16+
def test_decorated_method_async(self):
2117
assert get_fqn(AsyncDecorator().before) == \
22-
'fqn_decorators.async.AsyncDecorator.before'
18+
'fqn_decorators.asynchronous.AsyncDecorator.before'
2319

24-
async def test_decorated_method(self):
20+
def test_decorated_method(self):
2521
class User:
2622
@AsyncDecorator
2723
async def method(self, a):
2824
return a
2925

3026
assert get_fqn(User().method) == \
31-
'tests.test_fqn_decorators_async.User.method'
27+
'tests.test_fqn_decorators_asynchronous.User.method'
3228

3329

30+
@pytest.mark.asyncio
3431
class TestAsyncDecorator:
3532
async def test_getattr_async(self):
3633
class Decorator(AsyncDecorator):
@@ -105,7 +102,7 @@ class User:
105102
def check_permission(self):
106103
raise RuntimeError('Permission denied')
107104

108-
with mock.patch('fqn_decorators.async.AsyncDecorator.exception') as mocked_method:
105+
with mock.patch('fqn_decorators.asynchronous.AsyncDecorator.exception') as mocked_method:
109106
with pytest.raises(RuntimeError):
110107
await User().check_permission()
111108
assert mocked_method.called is True

tox.ini

+1-6
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,10 @@ deps =
1515

1616
[testenv:py27]
1717
setenv =
18-
PYTEST_ADDOPTS = --ignore tests/test_fqn_decorators_async.py
18+
PYTEST_ADDOPTS = --ignore tests/test_fqn_decorators_asynchronous.py
1919
deps =
2020
{[testenv]deps}
2121

22-
[testenv:py35]
23-
deps =
24-
{[testenv]deps}
25-
pytest-asyncio==0.6.0
26-
2722
[testenv:lint]
2823
basepython = python3.5
2924
commands = flake8 decorators tests --exclude=fqn_decorators/__init__.py

0 commit comments

Comments
 (0)