Skip to content

Test failures with Python 3.11 pre-release (3.11b3) #279

@musicinmybrain

Description

@musicinmybrain

Describe the bug
Several tests fail when testing Python 3.11 beta 3 for Fedora Linux 37. The development version of Fedora will start to use a pre-release of Python 3.11 soon, and Fedora 37 will be released with Python 3.11 this fall.

Downstream bug report

To Reproduce
Steps to reproduce the behavior:

  1. Check out current main.
  2. Edit tox.ini to add a Python 3.11 environment:
diff --git a/tox.ini b/tox.ini
index 146ccad..7a0766d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist=flake8,py37,py38,py39,py310,pypy3,docs
+envlist=flake8,py37,py38,py39,py310,py311,pypy3,docs
 skip_missing_interpreters=True
 
 [gh-actions]
  1. Make sure the appropriate interpreter is available. (On Fedora Linux 36: sudo dnf install python3.11 python3.11-devel)
  2. Run tox. (Or tox -e py311.)

Unfortunately, this isn’t quite enough to reproduce what we’re seeing, because you’ll be blocked by problems with dependencies that we’ve worked around downstream. Hopefully the fixes will soon be available in the upstream releases of those dependencies.

Expected behavior
All tests pass in all environments. (In my local environment, something breaks on pypy3 that I haven’t looked into, but that’s not relevant here.)

Logs

=================================== FAILURES ===================================
____________________ TestAsyncServer.test_connect_bad_poll _____________________

self = <tests.asyncio.test_asyncio_server.TestAsyncServer testMethod=test_connect_bad_poll>
import_module = <MagicMock name='import_module' id='140656792811152'>
AsyncSocket = <MagicMock name='AsyncSocket' id='140656792810384'>

    @mock.patch('engineio.asyncio_socket.AsyncSocket')
    @mock.patch('importlib.import_module')
    def test_connect_bad_poll(self, import_module, AsyncSocket):
        a = self.get_async_mock()
        import_module.side_effect = [a]
        AsyncSocket.return_value = self._get_mock_socket()
        AsyncSocket.return_value.poll.side_effect = [exceptions.QueueEmpty]
        s = asyncio_server.AsyncServer()
        _run(s.handle_request('request'))
        assert a._async['make_response'].call_count == 1
>       assert a._async['make_response'].call_args[0][0] == '400 BAD REQUEST'
E       AssertionError: assert '200 OK' == '400 BAD REQUEST'
E         - 400 BAD REQUEST
E         + 200 OK

tests/asyncio/test_asyncio_server.py:291: AssertionError
_______________ TestAsyncServer.test_connect_transport_websocket _______________

self = <tests.asyncio.test_asyncio_server.TestAsyncServer testMethod=test_connect_transport_websocket>
import_module = <MagicMock name='import_module' id='140656788334672'>
AsyncSocket = <MagicMock name='AsyncSocket' id='140656788328912'>

    @mock.patch('engineio.asyncio_socket.AsyncSocket')
    @mock.patch('importlib.import_module')
    def test_connect_transport_websocket(self, import_module, AsyncSocket):
        a = self.get_async_mock(
            {
                'REQUEST_METHOD': 'GET',
                'QUERY_STRING': 'transport=websocket',
                'HTTP_UPGRADE': 'websocket',
            }
        )
        import_module.side_effect = [a]
        AsyncSocket.return_value = self._get_mock_socket()
        s = asyncio_server.AsyncServer()
        s.generate_id = mock.MagicMock(return_value='123')
        # force socket to stay open, so that we can check it later
        AsyncSocket().closed = False
        _run(s.handle_request('request'))
        assert (
            s.sockets['123'].send.mock.call_args[0][0].packet_type
            == packet.OPEN
>       )
E       AttributeError: 'function' object has no attribute 'mock'

tests/asyncio/test_asyncio_server.py:313: AttributeError
___________ TestAsyncServer.test_connect_transport_websocket_closed ____________

self = <tests.asyncio.test_asyncio_server.TestAsyncServer testMethod=test_connect_transport_websocket_closed>
import_module = <MagicMock name='import_module' id='140656791298256'>
AsyncSocket = <MagicMock name='AsyncSocket' id='140656791305040'>

    @mock.patch('engineio.asyncio_socket.AsyncSocket')
    @mock.patch('importlib.import_module')
    def test_connect_transport_websocket_closed(
        self, import_module, AsyncSocket
    ):
        a = self.get_async_mock(
            {
                'REQUEST_METHOD': 'GET',
                'QUERY_STRING': 'transport=websocket',
                'HTTP_UPGRADE': 'websocket'
            }
        )
        import_module.side_effect = [a]
        AsyncSocket.return_value = self._get_mock_socket()
        s = asyncio_server.AsyncServer()
        s.generate_id = mock.MagicMock(return_value='123')
    
        # this mock handler just closes the socket, as it would happen on a
        # real websocket exchange
        async def mock_handle(environ):
            s.sockets['123'].closed = True
    
        AsyncSocket().handle_get_request = mock_handle
        _run(s.handle_request('request'))
>       assert '123' not in s.sockets  # socket should close on its own
E       AssertionError: assert '123' not in {'123': <engineio.asyncio_socket.AsyncSocket object at 0x7fed364c6810>}
E        +  where {'123': <engineio.asyncio_socket.AsyncSocket object at 0x7fed364c6810>} = <engineio.asyncio_server.AsyncServer object at 0x7fed35ff0c90>.sockets

tests/asyncio/test_asyncio_server.py:361: AssertionError
_____________________ TestAsyncServer.test_disconnect_all ______________________

self = <tests.asyncio.test_asyncio_server.TestAsyncServer testMethod=test_disconnect_all>

    def test_disconnect_all(self):
        s = asyncio_server.AsyncServer()
        s.sockets['foo'] = mock_foo = self._get_mock_socket()
        s.sockets['bar'] = mock_bar = self._get_mock_socket()
>       _run(s.disconnect())

tests/asyncio/test_asyncio_server.py:157: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/asyncio/test_asyncio_server.py:33: in _run
    return asyncio.get_event_loop().run_until_complete(coro)
/usr/lib64/python3.11/asyncio/base_events.py:650: in run_until_complete
    return future.result()
../../BUILDROOT/python-engineio-4.3.2-1.fc37.x86_64/usr/lib/python3.11/site-packages/engineio/asyncio_server.py:178: in disconnect
    await asyncio.wait([client.close()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

fs = {<coroutine object AsyncMock.<locals>.mock_coro at 0x7fed361f0e50>, <coroutine object AsyncMock.<locals>.mock_coro at 0x7fed361f05e0>}

    async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED):
        """Wait for the Futures or Tasks given by fs to complete.
    
        The fs iterable must not be empty.
    
        Coroutines will be wrapped in Tasks.
    
        Returns two sets of Future: (done, pending).
    
        Usage:
    
            done, pending = await asyncio.wait(fs)
    
        Note: This does not raise TimeoutError! Futures that aren't done
        when the timeout occurs are returned in the second set.
        """
        if futures.isfuture(fs) or coroutines.iscoroutine(fs):
            raise TypeError(f"expect a list of futures, not {type(fs).__name__}")
        if not fs:
            raise ValueError('Set of Tasks/Futures is empty.')
        if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED):
            raise ValueError(f'Invalid return_when value: {return_when}')
    
        fs = set(fs)
    
        if any(coroutines.iscoroutine(f) for f in fs):
>           raise TypeError("Passing coroutines is forbidden, use tasks explicitly.")
E           TypeError: Passing coroutines is forbidden, use tasks explicitly.

/usr/lib64/python3.11/asyncio/tasks.py:424: TypeError
______________ TestAsyncServer.test_http_upgrade_case_insensitive ______________

self = <tests.asyncio.test_asyncio_server.TestAsyncServer testMethod=test_http_upgrade_case_insensitive>
import_module = <MagicMock name='import_module' id='140656789877840'>
AsyncSocket = <MagicMock name='AsyncSocket' id='140656789870800'>

    @mock.patch('engineio.asyncio_socket.AsyncSocket')
    @mock.patch('importlib.import_module')
    def test_http_upgrade_case_insensitive(self, import_module, AsyncSocket):
        a = self.get_async_mock(
            {
                'REQUEST_METHOD': 'GET',
                'QUERY_STRING': 'transport=websocket',
                'HTTP_UPGRADE': 'WebSocket',
            }
        )
        import_module.side_effect = [a]
        AsyncSocket.return_value = self._get_mock_socket()
        s = asyncio_server.AsyncServer()
        s.generate_id = mock.MagicMock(return_value='123')
        # force socket to stay open, so that we can check it later
        AsyncSocket().closed = False
        _run(s.handle_request('request'))
        assert (
            s.sockets['123'].send.mock.call_args[0][0].packet_type
            == packet.OPEN
>       )
E       AttributeError: 'function' object has no attribute 'mock'

tests/asyncio/test_asyncio_server.py:335: AttributeError
=============================== warnings summary ===============================
../../../../usr/lib/python3.11/site-packages/eventlet/support/greenlets.py:6
  /usr/lib/python3.11/site-packages/eventlet/support/greenlets.py:6: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
    preserves_excinfo = (distutils.version.LooseVersion(greenlet.__version__)

../../../../usr/lib/python3.11/site-packages/eventlet/support/greenlets.py:7
  /usr/lib/python3.11/site-packages/eventlet/support/greenlets.py:7: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
    >= distutils.version.LooseVersion('0.3.2'))

tests/asyncio/test_async_asgi.py: 46 warnings
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_async_asgi.py:23: DeprecationWarning: There is no current event loop
    return asyncio.get_event_loop().run_until_complete(coro)

tests/asyncio/test_async_tornado.py::TornadoTests::test_translate_request
tests/asyncio/test_async_tornado.py::TornadoTests::test_translate_request
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_async_tornado.py:16: DeprecationWarning: There is no current event loop
    return asyncio.get_event_loop().run_until_complete(coro)

tests/asyncio/test_asyncio_client.py: 83 warnings
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:33: DeprecationWarning: There is no current event loop
    return asyncio.get_event_loop().run_until_complete(coro)

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_background_tasks
  /builddir/build/BUILDROOT/python-engineio-4.3.2-1.fc37.x86_64/usr/lib/python3.11/site-packages/engineio/asyncio_client.py:177: DeprecationWarning: There is no current event loop
    return asyncio.ensure_future(target(*args, **kwargs))

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_background_tasks
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:238: DeprecationWarning: There is no current event loop
    pending = asyncio.all_tasks(loop=asyncio.get_event_loop()) \

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_background_tasks
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:240: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(asyncio.wait(pending))

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_disconnect_polling_abort
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:212: RuntimeWarning: coroutine 'AsyncMock.<locals>.mock_coro' was never awaited
    assert c not in client.connected_clients
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_disconnect_websocket_abort
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:228: RuntimeWarning: coroutine 'AsyncMock.<locals>.mock_coro' was never awaited
    assert c not in client.connected_clients
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_signal_handler
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:1456: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(test())

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_trigger_event_coroutine_async
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:943: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_trigger_event_coroutine_async_error
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:971: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_trigger_event_function_async
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:930: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_trigger_event_function_async_error
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_client.py:957: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_websocket_connection_no_open_packet
tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_websocket_connection_with_cookies
tests/asyncio/test_asyncio_client.py::TestAsyncClient::test_websocket_upgrade_no_pong
tests/common/test_client.py::TestClient::test_signal_handler
tests/common/test_client.py::TestClient::test_signal_handler
tests/common/test_client.py::TestClient::test_signal_handler
  /builddir/build/BUILDROOT/python-engineio-4.3.2-1.fc37.x86_64/usr/lib/python3.11/site-packages/engineio/asyncio_client.py:200: DeprecationWarning: There is no current event loop
    loop = asyncio.get_event_loop()

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_background_tasks
  /builddir/build/BUILDROOT/python-engineio-4.3.2-1.fc37.x86_64/usr/lib/python3.11/site-packages/engineio/asyncio_server.py:332: DeprecationWarning: There is no current event loop
    return asyncio.ensure_future(target(*args, **kwargs))

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_background_tasks
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:1012: DeprecationWarning: There is no current event loop
    pending = asyncio.all_tasks(loop=asyncio.get_event_loop()) \

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_background_tasks
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:1014: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(asyncio.wait(pending))

tests/asyncio/test_asyncio_server.py: 68 warnings
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:33: DeprecationWarning: There is no current event loop
    return asyncio.get_event_loop().run_until_complete(coro)

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_trigger_event_coroutine_async
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:1094: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_trigger_event_coroutine_async_error
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:1122: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_trigger_event_function_async
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:1081: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_trigger_event_function_async_error
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_server.py:1108: DeprecationWarning: There is no current event loop
    asyncio.get_event_loop().run_until_complete(fut)

tests/asyncio/test_asyncio_socket.py: 50 warnings
  /builddir/build/BUILD/python-engineio-4.3.2/tests/asyncio/test_asyncio_socket.py:28: DeprecationWarning: There is no current event loop
    return asyncio.get_event_loop().run_until_complete(coro)

tests/common/test_client.py::TestClient::test_read_loop_websocket_disconnected
  /usr/lib64/python3.11/inspect.py:3081: RuntimeWarning: coroutine 'AsyncMock.<locals>.mock_coro' was never awaited
    arg_val = next(arg_vals)
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_connect_bad_poll
FAILED tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_connect_transport_websocket
FAILED tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_connect_transport_websocket_closed
FAILED tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_disconnect_all
FAILED tests/asyncio/test_asyncio_server.py::TestAsyncServer::test_http_upgrade_case_insensitive
================= 5 failed, 475 passed, 275 warnings in 5.66s ==================

Additional context

I’m not sure it will be trivial for me to prepare a PR to fix these, but I will be happy to do any experiments that might be helpful, and to test any candidate fixes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions