diff --git a/src/easynetwork/lowlevel/api_async/endpoints/stream.py b/src/easynetwork/lowlevel/api_async/endpoints/stream.py index be669167..e4bda095 100644 --- a/src/easynetwork/lowlevel/api_async/endpoints/stream.py +++ b/src/easynetwork/lowlevel/api_async/endpoints/stream.py @@ -102,14 +102,15 @@ def __init__( msg = f"The transport implementation {transport!r} does not implement AsyncBufferedStreamReadTransport interface" if manual_buffer_allocation == "try": warnings.warn( - msg, + f'{msg}. Consider explicitly setting the "manual_buffer_allocation" strategy to "no".', category=ManualBufferAllocationWarning, stacklevel=manual_buffer_allocation_warning_stacklevel, ) raise UnsupportedOperation(msg) self.__receiver = _BufferedReceiverImpl(transport, buffered_consumer) - except UnsupportedOperation: + except UnsupportedOperation as exc: if manual_buffer_allocation == "force": + exc.add_note('Consider setting the "manual_buffer_allocation" strategy to "no"') raise self.__receiver = _DataReceiverImpl(transport, _stream.StreamDataConsumer(protocol), max_recv_size) case "no": diff --git a/src/easynetwork/lowlevel/api_async/servers/stream.py b/src/easynetwork/lowlevel/api_async/servers/stream.py index f1927517..cf8c0411 100644 --- a/src/easynetwork/lowlevel/api_async/servers/stream.py +++ b/src/easynetwork/lowlevel/api_async/servers/stream.py @@ -174,14 +174,19 @@ async def __client_coroutine( if not isinstance(transport, transports.AsyncBufferedStreamReadTransport): msg = f"The transport implementation {transport!r} does not implement AsyncBufferedStreamReadTransport interface" if manual_buffer_allocation == "try": - warnings.warn(msg, category=ManualBufferAllocationWarning, stacklevel=1) + warnings.warn( + f'{msg}. Consider explicitly setting the "manual_buffer_allocation" strategy to "no".', + category=ManualBufferAllocationWarning, + stacklevel=1, + ) raise UnsupportedOperation(msg) request_receiver = _BufferedRequestReceiver( transport=transport, consumer=consumer, ) - except UnsupportedOperation: + except UnsupportedOperation as exc: if manual_buffer_allocation == "force": + exc.add_note('Consider setting the "manual_buffer_allocation" strategy to "no"') raise consumer = _stream.StreamDataConsumer(self.__protocol) request_receiver = _RequestReceiver( diff --git a/src/easynetwork/lowlevel/api_sync/endpoints/stream.py b/src/easynetwork/lowlevel/api_sync/endpoints/stream.py index 372fbc0c..b5c807b3 100644 --- a/src/easynetwork/lowlevel/api_sync/endpoints/stream.py +++ b/src/easynetwork/lowlevel/api_sync/endpoints/stream.py @@ -99,14 +99,15 @@ def __init__( msg = f"The transport implementation {transport!r} does not implement BufferedStreamReadTransport interface" if manual_buffer_allocation == "try": warnings.warn( - msg, + f'{msg}. Consider explicitly setting the "manual_buffer_allocation" strategy to "no".', category=ManualBufferAllocationWarning, stacklevel=manual_buffer_allocation_warning_stacklevel, ) raise UnsupportedOperation(msg) self.__receiver = _BufferedReceiverImpl(transport, buffered_consumer) - except UnsupportedOperation: + except UnsupportedOperation as exc: if manual_buffer_allocation == "force": + exc.add_note('Consider setting the "manual_buffer_allocation" strategy to "no"') raise self.__receiver = _DataReceiverImpl(transport, _stream.StreamDataConsumer(protocol), max_recv_size) case "no": diff --git a/tests/unit_test/test_async/test_lowlevel_api/test_endpoints/test_stream.py b/tests/unit_test/test_async/test_lowlevel_api/test_endpoints/test_stream.py index 79385c85..5ce5e30b 100644 --- a/tests/unit_test/test_async/test_lowlevel_api/test_endpoints/test_stream.py +++ b/tests/unit_test/test_async/test_lowlevel_api/test_endpoints/test_stream.py @@ -626,7 +626,7 @@ async def test____manual_buffer_allocation____try____but_stream_transport_does_n # Act & Assert with pytest.warns( ManualBufferAllocationWarning, - match=r"^The transport implementation .+ does not implement AsyncBufferedStreamReadTransport interface$", + match=r'^The transport implementation .+ does not implement AsyncBufferedStreamReadTransport interface\. Consider explicitly setting the "manual_buffer_allocation" strategy to "no"\.$', ): _ = AsyncStreamEndpoint(mock_stream_transport, mock_stream_protocol, max_recv_size, manual_buffer_allocation="try") @@ -671,12 +671,16 @@ async def test____manual_buffer_allocation____force____but_stream_protocol_does_ # Act & Assert with ( - pytest.raises(UnsupportedOperation, match=r"^This protocol does not support the buffer API$"), + pytest.raises(UnsupportedOperation, match=r"^This protocol does not support the buffer API$") as exc_info, warnings.catch_warnings(), ): warnings.simplefilter("error", ManualBufferAllocationWarning) _ = AsyncStreamEndpoint(mock_stream_transport, mock_stream_protocol, max_recv_size, manual_buffer_allocation="force") + assert exc_info.value.__notes__ == [ + 'Consider setting the "manual_buffer_allocation" strategy to "no"', + ] + @pytest.mark.parametrize("mock_stream_transport", [AsyncStreamReadTransport], indirect=True) @pytest.mark.parametrize("stream_protocol_mode", ["buffer"], indirect=True) async def test____manual_buffer_allocation____force____but_stream_transport_does_not_support_it( @@ -692,8 +696,12 @@ async def test____manual_buffer_allocation____force____but_stream_transport_does pytest.raises( UnsupportedOperation, match=r"^The transport implementation .+ does not implement AsyncBufferedStreamReadTransport interface$", - ), + ) as exc_info, warnings.catch_warnings(), ): warnings.simplefilter("error", ManualBufferAllocationWarning) _ = AsyncStreamEndpoint(mock_stream_transport, mock_stream_protocol, max_recv_size, manual_buffer_allocation="force") + + assert exc_info.value.__notes__ == [ + 'Consider setting the "manual_buffer_allocation" strategy to "no"', + ] diff --git a/tests/unit_test/test_async/test_lowlevel_api/test_servers/test_stream.py b/tests/unit_test/test_async/test_lowlevel_api/test_servers/test_stream.py index 61bd60b7..f6060ca2 100644 --- a/tests/unit_test/test_async/test_lowlevel_api/test_servers/test_stream.py +++ b/tests/unit_test/test_async/test_lowlevel_api/test_servers/test_stream.py @@ -427,7 +427,13 @@ async def client_connected_cb(_: Any) -> AsyncGenerator[None, Any]: # Act async with TaskGroup() as tg: - with pytest.raises(asyncio.CancelledError, match=r"^serve_side_effect$"), pytest.warns(ManualBufferAllocationWarning): + with ( + pytest.raises(asyncio.CancelledError, match=r"^serve_side_effect$"), + pytest.warns( + ManualBufferAllocationWarning, + match=r'^The transport implementation .+ does not implement AsyncBufferedStreamReadTransport interface\. Consider explicitly setting the "manual_buffer_allocation" strategy to "no"\.$', + ), + ): await server.serve(client_connected_cb, tg) # Assert @@ -501,7 +507,7 @@ async def client_connected_cb(_: Any) -> AsyncGenerator[None, Any]: # Act async with TaskGroup() as tg: with ( - pytest.raises(UnsupportedOperation, match=r"^This protocol does not support the buffer API$"), + pytest.raises(UnsupportedOperation, match=r"^This protocol does not support the buffer API$") as exc_info, warnings.catch_warnings(), ): warnings.simplefilter("error", ManualBufferAllocationWarning) @@ -513,6 +519,9 @@ async def client_connected_cb(_: Any) -> AsyncGenerator[None, Any]: if hasattr(mock_stream_transport, "recv_into"): mock_stream_transport.recv_into.assert_not_called() packet_received.assert_not_called() + assert exc_info.value.__notes__ == [ + 'Consider setting the "manual_buffer_allocation" strategy to "no"', + ] @pytest.mark.parametrize("mock_stream_transport", [AsyncStreamTransport], indirect=True) @pytest.mark.parametrize("stream_protocol_mode", ["buffer"], indirect=True) @@ -546,7 +555,7 @@ async def client_connected_cb(_: Any) -> AsyncGenerator[None, Any]: pytest.raises( UnsupportedOperation, match=r"^The transport implementation .+ does not implement AsyncBufferedStreamReadTransport interface$", - ), + ) as exc_info, warnings.catch_warnings(), ): warnings.simplefilter("error", ManualBufferAllocationWarning) @@ -556,3 +565,6 @@ async def client_connected_cb(_: Any) -> AsyncGenerator[None, Any]: client_connected_cb.assert_not_called() mock_stream_transport.recv.assert_not_called() packet_received.assert_not_called() + assert exc_info.value.__notes__ == [ + 'Consider setting the "manual_buffer_allocation" strategy to "no"', + ] diff --git a/tests/unit_test/test_sync/test_lowlevel_api/test_endpoints/test_stream.py b/tests/unit_test/test_sync/test_lowlevel_api/test_endpoints/test_stream.py index aee81a0f..d0d0dd10 100644 --- a/tests/unit_test/test_sync/test_lowlevel_api/test_endpoints/test_stream.py +++ b/tests/unit_test/test_sync/test_lowlevel_api/test_endpoints/test_stream.py @@ -754,7 +754,7 @@ def test____manual_buffer_allocation____try____but_stream_transport_does_not_sup # Act & Assert with pytest.warns( ManualBufferAllocationWarning, - match=r"^The transport implementation .+ does not implement BufferedStreamReadTransport interface$", + match=r'^The transport implementation .+ does not implement BufferedStreamReadTransport interface\. Consider explicitly setting the "manual_buffer_allocation" strategy to "no"\.$', ): _ = StreamEndpoint(mock_stream_transport, mock_stream_protocol, max_recv_size, manual_buffer_allocation="try") @@ -794,12 +794,16 @@ def test____manual_buffer_allocation____force____but_stream_protocol_does_not_su # Act & Assert with ( - pytest.raises(UnsupportedOperation, match=r"^This protocol does not support the buffer API$"), + pytest.raises(UnsupportedOperation, match=r"^This protocol does not support the buffer API$") as exc_info, warnings.catch_warnings(), ): warnings.simplefilter("error", ManualBufferAllocationWarning) _ = StreamEndpoint(mock_stream_transport, mock_stream_protocol, max_recv_size, manual_buffer_allocation="force") + assert exc_info.value.__notes__ == [ + 'Consider setting the "manual_buffer_allocation" strategy to "no"', + ] + @pytest.mark.parametrize("mock_stream_transport", [StreamReadTransport], indirect=True) @pytest.mark.parametrize("stream_protocol_mode", ["buffer"], indirect=True) def test____manual_buffer_allocation____force____but_stream_transport_does_not_support_it( @@ -815,8 +819,12 @@ def test____manual_buffer_allocation____force____but_stream_transport_does_not_s pytest.raises( UnsupportedOperation, match=r"^The transport implementation .+ does not implement BufferedStreamReadTransport interface$", - ), + ) as exc_info, warnings.catch_warnings(), ): warnings.simplefilter("error", ManualBufferAllocationWarning) _ = StreamEndpoint(mock_stream_transport, mock_stream_protocol, max_recv_size, manual_buffer_allocation="force") + + assert exc_info.value.__notes__ == [ + 'Consider setting the "manual_buffer_allocation" strategy to "no"', + ]