Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support python 3.7 and 3.8 in travis CI #493

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ language: python

python:
- 3.6
- 3.7
- 3.8

env:
matrix:
Expand Down
12 changes: 12 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@
uvloop = None


@pytest.fixture
def disable_gc():
gc_enabled = gc.isenabled()
if gc_enabled:
gc.disable()
gc.collect()
yield
if gc_enabled:
gc.collect()
gc.enable()


@pytest.fixture(scope='session')
def unused_port():
def f():
Expand Down
33 changes: 20 additions & 13 deletions tests/test_async_with.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ async def test_create_pool_deprecations(mysql_params, loop):
warnings.simplefilter("always")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this test closer, we could probably just suppress all the warnings except for the DeprecationWarning instead of trying to guess on what position it'll be under the next Python version.
Ref: https://docs.python.org/3/library/warnings.html#overriding-the-default-filter.

@MateuszCzubak WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@webknjaz I think that makes a lot of sense but it will look weird to limit to DeprecationWarning just in this one place and not in the others. Maybe it would be better to switch all related tests like this in a "refactoring commit", before the actual p3.7/p3.8 compatibility commit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm actually the are only 2 invokations of warnings.simplefilter("always") - I think it should be enough to change them both within the same commit - WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if you want to switch all, this needs to go into a separate PR. Let me merge this one and then we can do a follow-up.

async with pool.get() as conn:
pass
assert issubclass(w[-1].category, DeprecationWarning)
# The first warning emitted is expected to be DeprecationWarning:
# in the past, we used to check for the last one but this assumption
# breaks under Python 3.7 that also emits a `ResourceWarning` when
# executed with `PYTHONASYNCIODEBUG=1`.
assert issubclass(w[0].category, DeprecationWarning)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this important?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary for tests to pass on P3.7 with PYTHONASYNCIODEBUG=1, for which there are two warnings emitted:

(Pdb) print([x.category for x in w])
[<class 'DeprecationWarning'>, <class 'ResourceWarning'>]

It doesn't happen on P3.8 though. Here's related build result:
https://travis-ci.com/github/aio-libs/aiomysql/jobs/341264313

Copy link
Contributor Author

@MateuszCzubak MateuszCzubak May 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ResourceWarning msg:

ResourceWarning('unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=True>')

coming from asyncio/base_events.py line 623 (def __del__(self))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, in this case, we should add a code comment explaining this magic of choosing which element to compare.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a code comment. I have also added some explanation in the commit msg.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly that ResourceWarning is a bug that may mean that our tests don't close the loop properly, upon teardown. Does this happen under Python 3.8?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this happens only under 3.7

assert conn.closed

async with create_pool(loop=loop, **mysql_params) as pool:
Expand All @@ -149,9 +153,10 @@ async def test_sa_connection(table, mysql_params, loop):
connection = await engine.acquire()
assert not connection.closed
async with connection:
ret = []
async for i in connection.execute(tbl.select()):
ret.append(i)
async with connection.execute(tbl.select()) as cursor:
ret = []
async for i in cursor:
ret.append(i)
assert [(1, 'a'), (2, 'b'), (3, 'c')] == ret
assert connection.closed

Expand Down Expand Up @@ -194,21 +199,23 @@ async def test_sa_transaction_rollback(loop, mysql_params, table):
async def test_create_engine(loop, mysql_params, table):
async with sa.create_engine(loop=loop, **mysql_params) as engine:
async with engine.acquire() as conn:
ret = []
async for i in conn.execute(tbl.select()):
ret.append(i)
assert [(1, 'a'), (2, 'b'), (3, 'c')] == ret
async with conn.execute(tbl.select()) as cursor:
ret = []
async for i in cursor:
ret.append(i)
assert [(1, 'a'), (2, 'b'), (3, 'c')] == ret


@pytest.mark.run_loop
async def test_engine(loop, mysql_params, table):
engine = await sa.create_engine(loop=loop, **mysql_params)
async with engine:
async with engine.acquire() as conn:
ret = []
async for i in conn.execute(tbl.select()):
ret.append(i)
assert [(1, 'a'), (2, 'b'), (3, 'c')] == ret
async with conn.execute(tbl.select()) as cursor:
ret = []
async for i in cursor:
ret.append(i)
assert [(1, 'a'), (2, 'b'), (3, 'c')] == ret


@pytest.mark.run_loop
Expand All @@ -218,7 +225,7 @@ async def test_transaction_context_manager(loop, mysql_params, table):
async with conn.begin() as tr:
async with conn.execute(tbl.select()) as cursor:
ret = []
async for i in conn.execute(tbl.select()):
async for i in cursor:
ret.append(i)
assert [(1, 'a'), (2, 'b'), (3, 'c')] == ret
assert cursor.closed
Expand Down
1 change: 1 addition & 0 deletions tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ async def test_connection_double_ensure_closed(connection_creator):


@pytest.mark.run_loop
@pytest.mark.usefixtures("disable_gc")
async def test___del__(connection_creator):
conn = await connection_creator()
with pytest.warns(ResourceWarning):
Expand Down