aiohttp icon indicating copy to clipboard operation
aiohttp copied to clipboard

Tests with Python 3.11.0b1: RuntimeError: no running event loop / There is no current event loop in thread 'MainThread'

Open hroncok opened this issue 2 years ago • 10 comments

Describe the bug

Hello, in Fedora, we build all Python packages with pre-releases of Python 3.11. With Python 3.11.0b1, we see test failures of aiohttp 3.8.1, I can reproduce them with the current master barnch.

To Reproduce

  1. git clone yarl (@ v1.7.2) , frozenlist (@ v1.3.0) and aiohttp (@ master)
  2. python3.11 -m venv venv and . venv/bin/activate
  3. In yarl and frozenlist, make cythonize with the recent cython version, then pip install .
  4. In aiohttp I had to do some changes to make it build
    1. I replaced cython==0.29.27 with cython==0.29.30 or just cython in requirements/*
    2. I replaced the git-submodule copy of llhttp with the system one (6.0.6) as I was unable to make the nodejs build thing work, sorry
    3. I removed the coverage pytest options, as coverage makes pytest fail immediately
  5. make cythonize
  6. pip install . pytest pytest-mock
  7. run pytest, I've used pytest tests/test_client_functional.py tests/test_client_request.py tests/test_loop.py tests/test_test_utils.py as that is enough to get the failures
diff --git a/aiohttp/_cparser.pxd b/aiohttp/_cparser.pxd
index 165dd61d..49055d6a 100644
--- a/aiohttp/_cparser.pxd
+++ b/aiohttp/_cparser.pxd
@@ -10,7 +10,7 @@ from libc.stdint cimport (
 )
 
 
-cdef extern from "../vendor/llhttp/build/llhttp.h":
+cdef extern from "llhttp.h":
 
     struct llhttp__internal_s:
         int32_t _index
diff --git a/requirements/constraints.txt b/requirements/constraints.txt
index e1f6351b..26eed534 100644
--- a/requirements/constraints.txt
+++ b/requirements/constraints.txt
@@ -60,7 +60,7 @@ cryptography==36.0.1 ; platform_machine != "i686"
     #   -r requirements/test.txt
     #   pyjwt
     #   trustme
-cython==0.29.27
+cython==0.29.30
     # via -r requirements/cython.txt
 distlib==0.3.3
     # via virtualenv
diff --git a/requirements/cython.txt b/requirements/cython.txt
index 5cacc7e0..0a5b24bc 100644
--- a/requirements/cython.txt
+++ b/requirements/cython.txt
@@ -1,3 +1,3 @@
 -r multidict.txt
 -r typing-extensions.txt  # required for parsing aiohttp/hdrs.py by tools/gen.py
-cython==0.29.27
+cython
diff --git a/setup.cfg b/setup.cfg
index e6dd14bc..e254f490 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -123,10 +123,6 @@ addopts =
     # show values of the local vars in errors:
     --showlocals
 
-    # `pytest-cov`:
-    --cov=aiohttp
-    --cov=tests/
-
     # run tests that are not marked with dev_mode
     -m "not dev_mode"
 filterwarnings =
diff --git a/setup.py b/setup.py
index b27a54d6..0d70b1a7 100644
--- a/setup.py
+++ b/setup.py
@@ -33,12 +33,8 @@ extensions = [
         [
             "aiohttp/_http_parser.c",
             "aiohttp/_find_header.c",
-            "vendor/llhttp/build/c/llhttp.c",
-            "vendor/llhttp/src/native/api.c",
-            "vendor/llhttp/src/native/http.c",
         ],
-        define_macros=[("LLHTTP_STRICT_MODE", 0)],
-        include_dirs=["vendor/llhttp/build"],
+        libraries=["llhttp"],
     ),
     Extension("aiohttp._helpers", ["aiohttp/_helpers.c"]),
     Extension("aiohttp._http_writer", ["aiohttp/_http_writer.c"]),

Expected behavior

Tests pass.

Logs/tracebacks

See the next comment, the log was too long to paste here.

Python Version

$ python --version
Python 3.11.0b1

aiohttp Version

$ python -m pip show aiohttp
Name: aiohttp
Version: 4.0.0a1
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: 
Author-email: 
License: Apache 2
Location: /home/churchyard/rpmbuild/fedora-scm/python-aiohttp/aiohttp/__venv__/lib64/python3.11/site-packages
Requires: aiosignal, async-timeout, charset-normalizer, frozenlist, multidict, typing-extensions, yarl
Required-by:

multidict Version

$ python -m pip show multidict
Name: multidict
Version: 5.2.0
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /home/churchyard/rpmbuild/fedora-scm/python-aiohttp/aiohttp/__venv__/lib64/python3.11/site-packages
Requires: 
Required-by: aiohttp, yarl

yarl Version

$ python -m pip show yarl
Name: yarl
Version: 1.7.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /home/churchyard/rpmbuild/fedora-scm/python-aiohttp/aiohttp/__venv__/lib64/python3.11/site-packages
Requires: idna, multidict
Required-by: aiohttp

OS

Fedora Linux 35 or 37

Related component

Client

Additional context

We plan to update Fedora 37 to Python 3.11 after the second beta. Fedora 37 is the development version of Fedora. While testing things, we need to do that in dependency order. Unfortunately, this blocks us from testing many other packages, as this is quite a popular library.

Code of Conduct

  • [X] I agree to follow the aio-libs Code of Conduct

hroncok avatar May 19 '22 11:05 hroncok

Logs from pytest:

============================= test session starts ==============================
platform linux -- Python 3.11.0b1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- .../aiohttp/venv/bin/python
cachedir: .pytest_cache
rootdir: .../aiohttp, configfile: setup.cfg
plugins: cov-3.0.0, mock-3.7.0
collecting ... collected 330 items

tests/test_client_functional.py::test_keepalive_two_requests_success[pyloop] PASSED [  0%]
tests/test_client_functional.py::test_keepalive_after_head_requests_success[pyloop] PASSED [  0%]
tests/test_client_functional.py::test_keepalive_response_released[pyloop] PASSED [  0%]
tests/test_client_functional.py::test_keepalive_server_force_close_connection[pyloop] PASSED [  1%]
tests/test_client_functional.py::test_release_early[pyloop] PASSED       [  1%]
tests/test_client_functional.py::test_HTTP_304[pyloop] PASSED            [  1%]
tests/test_client_functional.py::test_HTTP_304_WITH_BODY[pyloop] PASSED  [  2%]
tests/test_client_functional.py::test_auto_header_user_agent[pyloop] PASSED [  2%]
tests/test_client_functional.py::test_skip_auto_headers_user_agent[pyloop] PASSED [  2%]
tests/test_client_functional.py::test_skip_default_auto_headers_user_agent[pyloop] PASSED [  3%]
tests/test_client_functional.py::test_skip_auto_headers_content_type[pyloop] PASSED [  3%]
tests/test_client_functional.py::test_post_data_bytesio[pyloop] PASSED   [  3%]
tests/test_client_functional.py::test_post_data_with_bytesio_file[pyloop] PASSED [  3%]
tests/test_client_functional.py::test_post_data_stringio[pyloop] PASSED  [  4%]
tests/test_client_functional.py::test_post_data_textio_encoding[pyloop] PASSED [  4%]
tests/test_client_functional.py::test_ssl_client[pyloop] XFAIL (trus...) [  4%]
tests/test_client_functional.py::test_tcp_connector_fingerprint_ok[pyloop] XFAIL [  5%]
tests/test_client_functional.py::test_tcp_connector_fingerprint_fail[pyloop] XFAIL [  5%]
tests/test_client_functional.py::test_format_task_get[pyloop] PASSED     [  5%]
tests/test_client_functional.py::test_str_params[pyloop] PASSED          [  6%]
tests/test_client_functional.py::test_drop_params_on_redirect[pyloop] PASSED [  6%]
tests/test_client_functional.py::test_drop_fragment_on_redirect[pyloop] PASSED [  6%]
tests/test_client_functional.py::test_drop_fragment[pyloop] PASSED       [  6%]
tests/test_client_functional.py::test_history[pyloop] PASSED             [  7%]
tests/test_client_functional.py::test_keepalive_closed_by_server[pyloop] PASSED [  7%]
tests/test_client_functional.py::test_wait_for[pyloop] PASSED            [  7%]
tests/test_client_functional.py::test_raw_headers[pyloop] PASSED         [  8%]
tests/test_client_functional.py::test_host_header_first[pyloop] PASSED   [  8%]
tests/test_client_functional.py::test_empty_header_values[pyloop] PASSED [  8%]
tests/test_client_functional.py::test_204_with_gzipped_content_encoding[pyloop] PASSED [  9%]
tests/test_client_functional.py::test_timeout_on_reading_headers[pyloop] FAILED [  9%]
tests/test_client_functional.py::test_timeout_on_conn_reading_headers[pyloop] FAILED [  9%]
tests/test_client_functional.py::test_timeout_on_session_read_timeout[pyloop] PASSED [ 10%]
tests/test_client_functional.py::test_read_timeout_between_chunks[pyloop] PASSED [ 10%]
tests/test_client_functional.py::test_read_timeout_on_reading_chunks[pyloop] PASSED [ 10%]
tests/test_client_functional.py::test_timeout_on_reading_data[pyloop] PASSED [ 10%]
tests/test_client_functional.py::test_timeout_none[pyloop] PASSED        [ 11%]
tests/test_client_functional.py::test_readline_error_on_conn_close[pyloop] PASSED [ 11%]
tests/test_client_functional.py::test_no_error_on_conn_close_if_eof[pyloop] PASSED [ 11%]
tests/test_client_functional.py::test_error_not_overwrote_on_conn_close[pyloop] PASSED [ 12%]
tests/test_client_functional.py::test_HTTP_200_OK_METHOD[pyloop] PASSED  [ 12%]
tests/test_client_functional.py::test_HTTP_200_OK_METHOD_connector[pyloop] PASSED [ 12%]
tests/test_client_functional.py::test_HTTP_302_REDIRECT_GET[pyloop] PASSED [ 13%]
tests/test_client_functional.py::test_HTTP_302_REDIRECT_HEAD[pyloop] PASSED [ 13%]
tests/test_client_functional.py::test_HTTP_302_REDIRECT_NON_HTTP[pyloop] PASSED [ 13%]
tests/test_client_functional.py::test_HTTP_302_REDIRECT_POST[pyloop] PASSED [ 13%]
tests/test_client_functional.py::test_HTTP_302_REDIRECT_POST_with_content_length_hdr[pyloop] PASSED [ 14%]
tests/test_client_functional.py::test_HTTP_307_REDIRECT_POST[pyloop] PASSED [ 14%]
tests/test_client_functional.py::test_HTTP_308_PERMANENT_REDIRECT_POST[pyloop] PASSED [ 14%]
tests/test_client_functional.py::test_HTTP_302_max_redirects[pyloop] PASSED [ 15%]
tests/test_client_functional.py::test_HTTP_200_GET_WITH_PARAMS[pyloop] PASSED [ 15%]
tests/test_client_functional.py::test_HTTP_200_GET_WITH_MultiDict_PARAMS[pyloop] PASSED [ 15%]
tests/test_client_functional.py::test_HTTP_200_GET_WITH_MIXED_PARAMS[pyloop] PASSED [ 16%]
tests/test_client_functional.py::test_POST_DATA[pyloop] PASSED           [ 16%]
tests/test_client_functional.py::test_POST_DATA_with_explicit_formdata[pyloop] PASSED [ 16%]
tests/test_client_functional.py::test_POST_DATA_with_charset[pyloop] PASSED [ 16%]
tests/test_client_functional.py::test_POST_DATA_formdats_with_charset[pyloop] PASSED [ 17%]
tests/test_client_functional.py::test_POST_DATA_with_charset_post[pyloop] PASSED [ 17%]
tests/test_client_functional.py::test_POST_DATA_with_context_transfer_encoding[pyloop] PASSED [ 17%]
tests/test_client_functional.py::test_POST_DATA_with_content_type_context_transfer_encoding[pyloop] PASSED [ 18%]
tests/test_client_functional.py::test_POST_MultiDict[pyloop] PASSED      [ 18%]
tests/test_client_functional.py::test_POST_DATA_DEFLATE[pyloop] PASSED   [ 18%]
tests/test_client_functional.py::test_POST_FILES[pyloop] PASSED          [ 19%]
tests/test_client_functional.py::test_POST_FILES_DEFLATE[pyloop] PASSED  [ 19%]
tests/test_client_functional.py::test_POST_bytes[pyloop] PASSED          [ 19%]
tests/test_client_functional.py::test_POST_bytes_too_large[pyloop] PASSED [ 20%]
tests/test_client_functional.py::test_POST_FILES_STR[pyloop] PASSED      [ 20%]
tests/test_client_functional.py::test_POST_FILES_STR_SIMPLE[pyloop] PASSED [ 20%]
tests/test_client_functional.py::test_POST_FILES_LIST[pyloop] PASSED     [ 20%]
tests/test_client_functional.py::test_POST_FILES_CT[pyloop] PASSED       [ 21%]
tests/test_client_functional.py::test_POST_FILES_SINGLE[pyloop] PASSED   [ 21%]
tests/test_client_functional.py::test_POST_FILES_SINGLE_content_disposition[pyloop] PASSED [ 21%]
tests/test_client_functional.py::test_POST_FILES_SINGLE_BINARY[pyloop] PASSED [ 22%]
tests/test_client_functional.py::test_POST_FILES_IO[pyloop] PASSED       [ 22%]
tests/test_client_functional.py::test_POST_FILES_IO_WITH_PARAMS[pyloop] PASSED [ 22%]
tests/test_client_functional.py::test_POST_FILES_WITH_DATA[pyloop] PASSED [ 23%]
tests/test_client_functional.py::test_POST_STREAM_DATA[pyloop] PASSED    [ 23%]
tests/test_client_functional.py::test_json[pyloop] PASSED                [ 23%]
tests/test_client_functional.py::test_json_custom[pyloop] PASSED         [ 23%]
tests/test_client_functional.py::test_expect_continue[pyloop] PASSED     [ 24%]
tests/test_client_functional.py::test_encoding_deflate[pyloop] PASSED    [ 24%]
tests/test_client_functional.py::test_encoding_deflate_nochunk[pyloop] PASSED [ 24%]
tests/test_client_functional.py::test_encoding_gzip[pyloop] PASSED       [ 25%]
tests/test_client_functional.py::test_encoding_gzip_write_by_chunks[pyloop] PASSED [ 25%]
tests/test_client_functional.py::test_encoding_gzip_nochunk[pyloop] PASSED [ 25%]
tests/test_client_functional.py::test_bad_payload_compression[pyloop] PASSED [ 26%]
tests/test_client_functional.py::test_bad_payload_chunked_encoding[pyloop] PASSED [ 26%]
tests/test_client_functional.py::test_bad_payload_content_length[pyloop] PASSED [ 26%]
tests/test_client_functional.py::test_payload_content_length_by_chunks[pyloop] PASSED [ 26%]
tests/test_client_functional.py::test_chunked[pyloop] PASSED             [ 27%]
tests/test_client_functional.py::test_shortcuts[pyloop] PASSED           [ 27%]
tests/test_client_functional.py::test_cookies[pyloop] PASSED             [ 27%]
tests/test_client_functional.py::test_cookies_per_request[pyloop] PASSED [ 28%]
tests/test_client_functional.py::test_cookies_redirect[pyloop] PASSED    [ 28%]
tests/test_client_functional.py::test_cookies_on_empty_session_jar[pyloop] PASSED [ 28%]
tests/test_client_functional.py::test_morsel_with_attributes[pyloop] PASSED [ 29%]
tests/test_client_functional.py::test_set_cookies[pyloop] PASSED         [ 29%]
tests/test_client_functional.py::test_set_cookies_expired[pyloop] PASSED [ 29%]
tests/test_client_functional.py::test_set_cookies_max_age[pyloop] PASSED [ 30%]
tests/test_client_functional.py::test_set_cookies_max_age_overflow[pyloop] PASSED [ 30%]
tests/test_client_functional.py::test_request_conn_error PASSED          [ 30%]
tests/test_client_functional.py::test_broken_connection[pyloop] XFAIL    [ 30%]
tests/test_client_functional.py::test_broken_connection_2[pyloop] PASSED [ 31%]
tests/test_client_functional.py::test_custom_headers[pyloop] PASSED      [ 31%]
tests/test_client_functional.py::test_redirect_to_absolute_url[pyloop] PASSED [ 31%]
tests/test_client_functional.py::test_redirect_without_location_header[pyloop] PASSED [ 32%]
tests/test_client_functional.py::test_ok_from_status[pyloop-200-True] PASSED [ 32%]
tests/test_client_functional.py::test_ok_from_status[pyloop-201-True] PASSED [ 32%]
tests/test_client_functional.py::test_ok_from_status[pyloop-301-True] PASSED [ 33%]
tests/test_client_functional.py::test_ok_from_status[pyloop-400-False] PASSED [ 33%]
tests/test_client_functional.py::test_ok_from_status[pyloop-403-False] PASSED [ 33%]
tests/test_client_functional.py::test_ok_from_status[pyloop-500-False] PASSED [ 33%]
tests/test_client_functional.py::test_raise_for_status[pyloop] PASSED    [ 34%]
tests/test_client_functional.py::test_raise_for_status_per_request[pyloop] PASSED [ 34%]
tests/test_client_functional.py::test_raise_for_status_disable_per_request[pyloop] PASSED [ 34%]
tests/test_client_functional.py::test_request_raise_for_status_default[pyloop] PASSED [ 35%]
tests/test_client_functional.py::test_request_raise_for_status_disabled[pyloop] PASSED [ 35%]
tests/test_client_functional.py::test_request_raise_for_status_enabled[pyloop] PASSED [ 35%]
tests/test_client_functional.py::test_session_raise_for_status_coro[pyloop] PASSED [ 36%]
tests/test_client_functional.py::test_request_raise_for_status_coro[pyloop] PASSED [ 36%]
tests/test_client_functional.py::test_invalid_idna PASSED                [ 36%]
tests/test_client_functional.py::test_creds_in_auth_and_url PASSED       [ 36%]
tests/test_client_functional.py::test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts] XFAIL [ 37%]
tests/test_client_functional.py::test_drop_auth_on_redirect_to_other_host[pyloop-http -> https] XFAIL [ 37%]
tests/test_client_functional.py::test_drop_auth_on_redirect_to_other_host[pyloop-https -> http] XFAIL [ 37%]
tests/test_client_functional.py::test_async_with_session PASSED          [ 38%]
tests/test_client_functional.py::test_session_close_awaitable PASSED     [ 38%]
tests/test_client_functional.py::test_close_resp_on_error_async_with_session[pyloop] PASSED [ 38%]
tests/test_client_functional.py::test_release_resp_on_normal_exit_from_cm[pyloop] PASSED [ 39%]
tests/test_client_functional.py::test_non_close_detached_session_on_error_cm[pyloop] PASSED [ 39%]
tests/test_client_functional.py::test_close_detached_session_on_non_existing_addr PASSED [ 39%]
tests/test_client_functional.py::test_aiohttp_request_context_manager[pyloop] PASSED [ 40%]
tests/test_client_functional.py::test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop] XFAIL [ 40%]
tests/test_client_functional.py::test_aiohttp_request_ctx_manager_not_found PASSED [ 40%]
tests/test_client_functional.py::test_aiohttp_request_coroutine[pyloop] PASSED [ 40%]
tests/test_client_functional.py::test_yield_from_in_session_request[pyloop] PASSED [ 41%]
tests/test_client_functional.py::test_close_context_manager[pyloop] PASSED [ 41%]
tests/test_client_functional.py::test_session_auth[pyloop] PASSED        [ 41%]
tests/test_client_functional.py::test_session_auth_override[pyloop] PASSED [ 42%]
tests/test_client_functional.py::test_session_auth_header_conflict[pyloop] PASSED [ 42%]
tests/test_client_functional.py::test_session_headers[pyloop] PASSED     [ 42%]
tests/test_client_functional.py::test_session_headers_merge[pyloop] PASSED [ 43%]
tests/test_client_functional.py::test_multidict_headers[pyloop] PASSED   [ 43%]
tests/test_client_functional.py::test_request_conn_closed[pyloop] PASSED [ 43%]
tests/test_client_functional.py::test_dont_close_explicit_connector[pyloop] PASSED [ 43%]
tests/test_client_functional.py::test_server_close_keepalive_connection PASSED [ 44%]
tests/test_client_functional.py::test_handle_keepalive_on_closed_connection PASSED [ 44%]
tests/test_client_functional.py::test_error_in_performing_request[pyloop] XFAIL [ 44%]
tests/test_client_functional.py::test_await_after_cancelling[pyloop] PASSED [ 45%]
tests/test_client_functional.py::test_async_payload_generator[pyloop] PASSED [ 45%]
tests/test_client_functional.py::test_read_from_closed_response[pyloop] PASSED [ 45%]
tests/test_client_functional.py::test_read_from_closed_response2[pyloop] PASSED [ 46%]
tests/test_client_functional.py::test_read_from_closed_content[pyloop] PASSED [ 46%]
tests/test_client_functional.py::test_read_timeout[pyloop] PASSED        [ 46%]
tests/test_client_functional.py::test_read_timeout_on_prepared_response[pyloop] PASSED [ 46%]
tests/test_client_functional.py::test_read_bufsize_session_default[pyloop] PASSED [ 47%]
tests/test_client_functional.py::test_read_bufsize_explicit[pyloop] PASSED [ 47%]
tests/test_client_functional.py::test_http_empty_data_text[pyloop] PASSED [ 47%]
tests/test_client_request.py::test_method1[pyloop] PASSED                [ 48%]
tests/test_client_request.py::test_method2[pyloop] PASSED                [ 48%]
tests/test_client_request.py::test_method3[pyloop] PASSED                [ 48%]
tests/test_client_request.py::test_method_invalid[pyloop] PASSED         [ 49%]
tests/test_client_request.py::test_version_1_0[pyloop] PASSED            [ 49%]
tests/test_client_request.py::test_version_default[pyloop] PASSED        [ 49%]
tests/test_client_request.py::test_request_info[pyloop] PASSED           [ 50%]
tests/test_client_request.py::test_request_info_with_fragment[pyloop] PASSED [ 50%]
tests/test_client_request.py::test_version_err[pyloop] PASSED            [ 50%]
tests/test_client_request.py::test_keep_alive[pyloop] PASSED             [ 50%]
tests/test_client_request.py::test_host_port_default_http[pyloop] PASSED [ 51%]
tests/test_client_request.py::test_host_port_default_https[pyloop] PASSED [ 51%]
tests/test_client_request.py::test_host_port_nondefault_http[pyloop] PASSED [ 51%]
tests/test_client_request.py::test_host_port_nondefault_https[pyloop] PASSED [ 52%]
tests/test_client_request.py::test_host_port_default_ws[pyloop] PASSED   [ 52%]
tests/test_client_request.py::test_host_port_default_wss[pyloop] PASSED  [ 52%]
tests/test_client_request.py::test_host_port_nondefault_ws[pyloop] PASSED [ 53%]
tests/test_client_request.py::test_host_port_nondefault_wss[pyloop] PASSED [ 53%]
tests/test_client_request.py::test_host_port_none_port[pyloop] PASSED    [ 53%]
tests/test_client_request.py::test_host_port_err[pyloop] PASSED          [ 53%]
tests/test_client_request.py::test_hostname_err[pyloop] PASSED           [ 54%]
tests/test_client_request.py::test_host_header_host_first[pyloop] PASSED [ 54%]
tests/test_client_request.py::test_host_header_host_without_port[pyloop] PASSED [ 54%]
tests/test_client_request.py::test_host_header_host_with_default_port[pyloop] PASSED [ 55%]
tests/test_client_request.py::test_host_header_host_with_nondefault_port[pyloop] PASSED [ 55%]
tests/test_client_request.py::test_host_header_host_idna_encode[pyloop] PASSED [ 55%]
tests/test_client_request.py::test_host_header_host_unicode[pyloop] PASSED [ 56%]
tests/test_client_request.py::test_host_header_explicit_host[pyloop] PASSED [ 56%]
tests/test_client_request.py::test_host_header_explicit_host_with_port[pyloop] PASSED [ 56%]
tests/test_client_request.py::test_host_header_ipv4[pyloop] PASSED       [ 56%]
tests/test_client_request.py::test_host_header_ipv6[pyloop] PASSED       [ 57%]
tests/test_client_request.py::test_host_header_ipv4_with_port[pyloop] PASSED [ 57%]
tests/test_client_request.py::test_host_header_ipv6_with_port[pyloop] PASSED [ 57%]
tests/test_client_request.py::test_default_headers_useragent[pyloop] PASSED [ 58%]
tests/test_client_request.py::test_default_headers_useragent_custom[pyloop] PASSED [ 58%]
tests/test_client_request.py::test_skip_default_useragent_header[pyloop] PASSED [ 58%]
tests/test_client_request.py::test_headers[pyloop] FAILED                [ 59%]
tests/test_client_request.py::test_headers_list[pyloop] PASSED           [ 59%]
tests/test_client_request.py::test_headers_default[pyloop] PASSED        [ 59%]
tests/test_client_request.py::test_invalid_url[pyloop] PASSED            [ 60%]
tests/test_client_request.py::test_no_path[pyloop] PASSED                [ 60%]
tests/test_client_request.py::test_ipv6_default_http_port[pyloop] PASSED [ 60%]
tests/test_client_request.py::test_ipv6_default_https_port[pyloop] PASSED [ 60%]
tests/test_client_request.py::test_ipv6_nondefault_http_port[pyloop] PASSED [ 61%]
tests/test_client_request.py::test_ipv6_nondefault_https_port[pyloop] PASSED [ 61%]
tests/test_client_request.py::test_basic_auth[pyloop] PASSED             [ 61%]
tests/test_client_request.py::test_basic_auth_utf8[pyloop] PASSED        [ 62%]
tests/test_client_request.py::test_basic_auth_tuple_forbidden[pyloop] PASSED [ 62%]
tests/test_client_request.py::test_basic_auth_from_url[pyloop] PASSED    [ 62%]
tests/test_client_request.py::test_basic_auth_from_url_overridden[pyloop] PASSED [ 63%]
tests/test_client_request.py::test_path_is_not_double_encoded1[pyloop] PASSED [ 63%]
tests/test_client_request.py::test_path_is_not_double_encoded2[pyloop] PASSED [ 63%]
tests/test_client_request.py::test_path_is_not_double_encoded3[pyloop] PASSED [ 63%]
tests/test_client_request.py::test_path_safe_chars_preserved[pyloop] PASSED [ 64%]
tests/test_client_request.py::test_params_are_added_before_fragment1[pyloop] PASSED [ 64%]
tests/test_client_request.py::test_params_are_added_before_fragment2[pyloop] PASSED [ 64%]
tests/test_client_request.py::test_path_not_contain_fragment1[pyloop] PASSED [ 65%]
tests/test_client_request.py::test_path_not_contain_fragment2[pyloop] PASSED [ 65%]
tests/test_client_request.py::test_cookies[pyloop] PASSED                [ 65%]
tests/test_client_request.py::test_cookies_is_quoted_with_special_characters[pyloop] PASSED [ 66%]
tests/test_client_request.py::test_cookies_merge_with_headers[pyloop] PASSED [ 66%]
tests/test_client_request.py::test_query_multivalued_param[pyloop] PASSED [ 66%]
tests/test_client_request.py::test_query_str_param[pyloop] PASSED        [ 66%]
tests/test_client_request.py::test_query_bytes_param_raises[pyloop] PASSED [ 67%]
tests/test_client_request.py::test_query_str_param_is_not_encoded[pyloop] PASSED [ 67%]
tests/test_client_request.py::test_params_update_path_and_url[pyloop] PASSED [ 67%]
tests/test_client_request.py::test_params_empty_path_and_url[pyloop] PASSED [ 68%]
tests/test_client_request.py::test_gen_netloc_all[pyloop] PASSED         [ 68%]
tests/test_client_request.py::test_gen_netloc_no_port[pyloop] PASSED     [ 68%]
tests/test_client_request.py::test_connection_header[pyloop] PASSED      [ 69%]
tests/test_client_request.py::test_no_content_length[pyloop] PASSED      [ 69%]
tests/test_client_request.py::test_no_content_length_head[pyloop] PASSED [ 69%]
tests/test_client_request.py::test_content_type_auto_header_get[pyloop] PASSED [ 70%]
tests/test_client_request.py::test_content_type_auto_header_form[pyloop] PASSED [ 70%]
tests/test_client_request.py::test_content_type_auto_header_bytes[pyloop] PASSED [ 70%]
tests/test_client_request.py::test_content_type_skip_auto_header_bytes[pyloop] PASSED [ 70%]
tests/test_client_request.py::test_content_type_skip_auto_header_form[pyloop] PASSED [ 71%]
tests/test_client_request.py::test_content_type_auto_header_content_length_no_skip[pyloop] PASSED [ 71%]
tests/test_client_request.py::test_urlencoded_formdata_charset[pyloop] PASSED [ 71%]
tests/test_client_request.py::test_formdata_boundary_from_headers[pyloop] PASSED [ 72%]
tests/test_client_request.py::test_post_data[pyloop] PASSED              [ 72%]
tests/test_client_request.py::test_pass_falsy_data[pyloop] PASSED        [ 72%]
tests/test_client_request.py::test_pass_falsy_data_file[pyloop] PASSED   [ 73%]
tests/test_client_request.py::test_get_with_data[pyloop] PASSED          [ 73%]
tests/test_client_request.py::test_bytes_data[pyloop] PASSED             [ 73%]
tests/test_client_request.py::test_content_encoding[pyloop] PASSED       [ 73%]
tests/test_client_request.py::test_content_encoding_dont_set_headers_if_no_body[pyloop] PASSED [ 74%]
tests/test_client_request.py::test_content_encoding_header[pyloop] PASSED [ 74%]
tests/test_client_request.py::test_compress_and_content_encoding[pyloop] PASSED [ 74%]
tests/test_client_request.py::test_chunked[pyloop] PASSED                [ 75%]
tests/test_client_request.py::test_chunked2[pyloop] PASSED               [ 75%]
tests/test_client_request.py::test_chunked_explicit[pyloop] PASSED       [ 75%]
tests/test_client_request.py::test_chunked_length[pyloop] PASSED         [ 76%]
tests/test_client_request.py::test_chunked_transfer_encoding[pyloop] PASSED [ 76%]
tests/test_client_request.py::test_file_upload_not_chunked[pyloop] PASSED [ 76%]
tests/test_client_request.py::test_precompressed_data_stays_intact[pyloop] PASSED [ 76%]
tests/test_client_request.py::test_file_upload_not_chunked_seek[pyloop] PASSED [ 77%]
tests/test_client_request.py::test_file_upload_force_chunked[pyloop] PASSED [ 77%]
tests/test_client_request.py::test_expect100[pyloop] PASSED              [ 77%]
tests/test_client_request.py::test_expect_100_continue_header[pyloop] PASSED [ 78%]
tests/test_client_request.py::test_data_stream[pyloop] PASSED            [ 78%]
tests/test_client_request.py::test_data_file[pyloop] PASSED              [ 78%]
tests/test_client_request.py::test_data_stream_exc[pyloop] PASSED        [ 79%]
tests/test_client_request.py::test_data_stream_exc_chain[pyloop] PASSED  [ 79%]
tests/test_client_request.py::test_data_stream_continue[pyloop] PASSED   [ 79%]
tests/test_client_request.py::test_data_continue[pyloop] PASSED          [ 80%]
tests/test_client_request.py::test_close[pyloop] PASSED                  [ 80%]
tests/test_client_request.py::test_custom_response_class[pyloop] PASSED  [ 80%]
tests/test_client_request.py::test_oserror_on_write_bytes[pyloop] PASSED [ 80%]
tests/test_client_request.py::test_terminate[pyloop] PASSED              [ 81%]
tests/test_client_request.py::test_terminate_with_closed_loop[pyloop] PASSED [ 81%]
tests/test_client_request.py::test_terminate_without_writer[pyloop] PASSED [ 81%]
tests/test_client_request.py::test_custom_req_rep[pyloop] PASSED         [ 82%]
tests/test_client_request.py::test_bad_fingerprint[pyloop] PASSED        [ 82%]
tests/test_client_request.py::test_insecure_fingerprint_md5[pyloop] PASSED [ 82%]
tests/test_client_request.py::test_insecure_fingerprint_sha1[pyloop] PASSED [ 83%]
tests/test_client_request.py::test_loose_cookies_types[pyloop] PASSED    [ 83%]
tests/test_client_request.py::test_gen_default_accept_encoding[False-gzip, deflate] PASSED [ 83%]
tests/test_client_request.py::test_gen_default_accept_encoding[True-gzip, deflate, br] PASSED [ 83%]
tests/test_loop.py::test_subprocess_co[pyloop] PASSED                    [ 84%]
tests/test_loop.py::TestCase::test_default_loop FAILED                   [ 84%]
tests/test_loop.py::TestCase::test_on_startup_hook FAILED                [ 84%]
tests/test_loop.py::test_default_loop[pyloop] PASSED                     [ 85%]
tests/test_loop.py::test_setup_loop_non_main_thread PASSED               [ 85%]
tests/test_test_utils.py::test_aiohttp_client_close_is_idempotent PASSED [ 85%]
tests/test_test_utils.py::TestAioHTTPTestCase::test_example_with_loop FAILED [ 86%]
tests/test_test_utils.py::TestAioHTTPTestCase::test_example_without_explicit_loop FAILED [ 86%]
tests/test_test_utils.py::TestAioHTTPTestCase::test_inner_example FAILED [ 86%]
tests/test_test_utils.py::TestAioHTTPTestCase::test_inner_example_without_explicit_loop FAILED [ 86%]
tests/test_test_utils.py::test_get_route PASSED                          [ 87%]
tests/test_test_utils.py::test_client_websocket PASSED                   [ 87%]
tests/test_test_utils.py::test_client_cookie PASSED                      [ 87%]
tests/test_test_utils.py::test_test_client_methods[get] PASSED           [ 88%]
tests/test_test_utils.py::test_test_client_methods[post0] PASSED         [ 88%]
tests/test_test_utils.py::test_test_client_methods[options] PASSED       [ 88%]
tests/test_test_utils.py::test_test_client_methods[post1] PASSED         [ 89%]
tests/test_test_utils.py::test_test_client_methods[put] PASSED           [ 89%]
tests/test_test_utils.py::test_test_client_methods[patch] PASSED         [ 89%]
tests/test_test_utils.py::test_test_client_methods[delete] PASSED        [ 90%]
tests/test_test_utils.py::test_test_client_head PASSED                   [ 90%]
tests/test_test_utils.py::test_make_mocked_request[headers0] PASSED      [ 90%]
tests/test_test_utils.py::test_make_mocked_request[headers1] PASSED      [ 90%]
tests/test_test_utils.py::test_make_mocked_request[headers2] PASSED      [ 91%]
tests/test_test_utils.py::test_make_mocked_request_sslcontext PASSED     [ 91%]
tests/test_test_utils.py::test_make_mocked_request_unknown_extra_info PASSED [ 91%]
tests/test_test_utils.py::test_make_mocked_request_app PASSED            [ 92%]
tests/test_test_utils.py::test_make_mocked_request_app_can_store_values PASSED [ 92%]
tests/test_test_utils.py::test_make_mocked_request_app_access_non_existing PASSED [ 92%]
tests/test_test_utils.py::test_make_mocked_request_match_info PASSED     [ 93%]
tests/test_test_utils.py::test_make_mocked_request_content PASSED        [ 93%]
tests/test_test_utils.py::test_make_mocked_request_transport PASSED      [ 93%]
tests/test_test_utils.py::test_test_client_props PASSED                  [ 93%]
tests/test_test_utils.py::test_test_client_raw_server_props PASSED       [ 94%]
tests/test_test_utils.py::test_test_server_context_manager PASSED        [ 94%]
tests/test_test_utils.py::test_client_unsupported_arg PASSED             [ 94%]
tests/test_test_utils.py::test_server_make_url_yarl_compatibility PASSED [ 95%]
tests/test_test_utils.py::test_testcase_no_app PASSED                    [ 95%]
tests/test_test_utils.py::test_server_context_manager PASSED             [ 95%]
tests/test_test_utils.py::test_client_context_manager_response[head] PASSED [ 96%]
tests/test_test_utils.py::test_client_context_manager_response[get] PASSED [ 96%]
tests/test_test_utils.py::test_client_context_manager_response[post0] PASSED [ 96%]
tests/test_test_utils.py::test_client_context_manager_response[options] PASSED [ 96%]
tests/test_test_utils.py::test_client_context_manager_response[post1] PASSED [ 97%]
tests/test_test_utils.py::test_client_context_manager_response[put] PASSED [ 97%]
tests/test_test_utils.py::test_client_context_manager_response[patch] PASSED [ 97%]
tests/test_test_utils.py::test_client_context_manager_response[delete] PASSED [ 98%]
tests/test_test_utils.py::test_custom_port PASSED                        [ 98%]
tests/test_test_utils.py::test_test_server_hostnames[127.0.0.1-127.0.0.1] PASSED [ 98%]
tests/test_test_utils.py::test_test_server_hostnames[localhost-127.0.0.1] PASSED [ 99%]
tests/test_test_utils.py::test_test_server_hostnames[::1-::1] PASSED     [ 99%]
tests/test_test_utils.py::test_base_test_server_socket_factory[TestServer] PASSED [ 99%]
tests/test_test_utils.py::test_base_test_server_socket_factory[RawTestServer] PASSED [100%]

=================================== FAILURES ===================================
___________________ test_timeout_on_reading_headers[pyloop] ____________________

self = <aiohttp.client.ClientSession object at 0x7f45f3c1a260>, method = 'GET'
str_or_url = URL('http://127.0.0.1:44237/')

    async def _request(
        self,
        method: str,
        str_or_url: StrOrURL,
        *,
        params: Optional[Mapping[str, str]] = None,
        data: Any = None,
        json: Any = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        allow_redirects: bool = True,
        max_redirects: int = 10,
        compress: Optional[str] = None,
        chunked: Optional[bool] = None,
        expect100: bool = False,
        raise_for_status: Union[
            None, bool, Callable[[ClientResponse], Awaitable[None]]
        ] = None,
        read_until_eof: bool = True,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,
        ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        trace_request_ctx: Optional[SimpleNamespace] = None,
        read_bufsize: Optional[int] = None,
    ) -> ClientResponse:
    
        # NOTE: timeout clamps existing connect and read timeouts.  We cannot
        # set the default to None because we need to detect if the user wants
        # to use the existing timeouts by setting timeout to None.
    
        if self.closed:
            raise RuntimeError("Session is closed")
    
        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, bool, Fingerprint, "
                "or None, got {!r} instead.".format(ssl)
            )
    
        if data is not None and json is not None:
            raise ValueError(
                "data and json parameters can not be used at the same time"
            )
        elif json is not None:
            data = payload.JsonPayload(json, dumps=self._json_serialize)
    
        redirects = 0
        history = []
        version = self._version
    
        # Merge with default headers and transform to CIMultiDict
        headers = self._prepare_headers(headers)
        proxy_headers = self._prepare_headers(proxy_headers)
    
        try:
            url = self._build_url(str_or_url)
        except ValueError as e:
            raise InvalidURL(str_or_url) from e
    
        skip_headers = set(self._skip_auto_headers)
        if skip_auto_headers is not None:
            for i in skip_auto_headers:
                skip_headers.add(istr(i))
    
        if proxy is not None:
            try:
                proxy = URL(proxy)
            except ValueError as e:
                raise InvalidURL(proxy) from e
    
        if timeout is sentinel or timeout is None:
            real_timeout: ClientTimeout = self._timeout
        else:
            real_timeout = timeout
        # timeout is cumulative for all request operations
        # (request, redirects, responses, data consuming)
        tm = TimeoutHandle(
            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold
        )
        handle = tm.start()
    
        if read_bufsize is None:
            read_bufsize = self._read_bufsize
    
        traces = [
            Trace(
                self,
                trace_config,
                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
            )
            for trace_config in self._trace_configs
        ]
    
        for trace in traces:
            await trace.send_request_start(method, url.update_query(params), headers)
    
        timer = tm.timer()
        try:
            with timer:
                while True:
                    url, auth_from_url = strip_auth_from_url(url)
                    if auth and auth_from_url:
                        raise ValueError(
                            "Cannot combine AUTH argument with "
                            "credentials encoded in URL"
                        )
    
                    if auth is None:
                        auth = auth_from_url
                    if auth is None:
                        auth = self._default_auth
                    # It would be confusing if we support explicit
                    # Authorization header with auth argument
                    if (
                        headers is not None
                        and auth is not None
                        and hdrs.AUTHORIZATION in headers
                    ):
                        raise ValueError(
                            "Cannot combine AUTHORIZATION header "
                            "with AUTH argument or credentials "
                            "encoded in URL"
                        )
    
                    all_cookies = self._cookie_jar.filter_cookies(url)
    
                    if cookies is not None:
                        tmp_cookie_jar = CookieJar()
                        tmp_cookie_jar.update_cookies(cookies)
                        req_cookies = tmp_cookie_jar.filter_cookies(url)
                        if req_cookies:
                            all_cookies.load(req_cookies)
    
                    if proxy is not None:
                        proxy = URL(proxy)
                    elif self._trust_env:
                        with suppress(LookupError):
                            proxy, proxy_auth = get_env_proxy_for_url(url)
    
                    req = self._request_class(
                        method,
                        url,
                        params=params,
                        headers=headers,
                        skip_auto_headers=skip_headers,
                        data=data,
                        cookies=all_cookies,
                        auth=auth,
                        version=version,
                        compress=compress,
                        chunked=chunked,
                        expect100=expect100,
                        loop=self._loop,
                        response_class=self._response_class,
                        proxy=proxy,
                        proxy_auth=proxy_auth,
                        timer=timer,
                        session=self,
                        ssl=ssl,
                        proxy_headers=proxy_headers,
                        traces=traces,
                    )
    
                    # connection timeout
                    try:
                        async with ceil_timeout(
                            real_timeout.connect,
                            ceil_threshold=real_timeout.ceil_threshold,
                        ):
                            assert self._connector is not None
                            conn = await self._connector.connect(
                                req, traces=traces, timeout=real_timeout
                            )
                    except asyncio.TimeoutError as exc:
                        raise ServerTimeoutError(
                            f"Connection timeout to host {url}"
                        ) from exc
    
                    assert conn.transport is not None
    
                    assert conn.protocol is not None
                    conn.protocol.set_response_params(
                        timer=timer,
                        skip_payload=method.upper() == "HEAD",
                        read_until_eof=read_until_eof,
                        auto_decompress=self._auto_decompress,
                        read_timeout=real_timeout.sock_read,
                        read_bufsize=read_bufsize,
                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
                    )
    
                    try:
                        try:
                            resp = await req.send(conn)
                            try:
>                               await resp.start(conn)

all_cookies = <SimpleCookie: >
allow_redirects = True
auth       = None
auth_from_url = None
chunked    = None
compress   = None
conn       = Connection<ConnectionKey(host='127.0.0.1', port=44237, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
cookies    = None
data       = None
expect100  = False
handle     = None
headers    = <CIMultiDict()>
history    = []
json       = None
max_redirects = 10
method     = 'GET'
params     = None
proxy      = None
proxy_auth = None
proxy_headers = <CIMultiDict()>
raise_for_status = None
read_bufsize = 65536
read_until_eof = True
real_timeout = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
redirects  = 0
req        = <aiohttp.client_reqrep.ClientRequest object at 0x7f45f3aa9fd0>
resp       = <ClientResponse(http://127.0.0.1:44237/) [None None]>
None

self       = <aiohttp.client.ClientSession object at 0x7f45f3c1a260>
skip_auto_headers = None
skip_headers = set()
ssl        = None
str_or_url = URL('http://127.0.0.1:44237/')
timeout    = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
timer      = <aiohttp.helpers.TimerContext object at 0x7f45f3aab710>
tm         = <aiohttp.helpers.TimeoutHandle object at 0x7f45f3aaa790>
trace_request_ctx = None
traces     = []
url        = URL('http://127.0.0.1:44237/')
version    = HttpVersion(major=1, minor=1)

venv/lib64/python3.11/site-packages/aiohttp/client.py:525: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <ClientResponse(http://127.0.0.1:44237/) [None None]>
None

connection = Connection<ConnectionKey(host='127.0.0.1', port=44237, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>

    async def start(self, connection: "Connection") -> "ClientResponse":
        """Start response processing."""
        self._closed = False
        self._protocol = connection.protocol
        self._connection = connection
    
>       with self._timer:

connection = Connection<ConnectionKey(host='127.0.0.1', port=44237, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
protocol   = <aiohttp.client_proto.ResponseHandler object at 0x7f45f3a4f690>
self       = <ClientResponse(http://127.0.0.1:44237/) [None None]>
None


venv/lib64/python3.11/site-packages/aiohttp/client_reqrep.py:837: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <aiohttp.helpers.TimerContext object at 0x7f45f3aab710>
exc_type = <class 'asyncio.exceptions.CancelledError'>
exc_val = CancelledError(), exc_tb = <traceback object at 0x7f45f3aa94c0>

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> Optional[bool]:
        if self._tasks:
            self._tasks.pop()
    
        if exc_type is asyncio.CancelledError and self._cancelled:
>           raise asyncio.TimeoutError from None
E           TimeoutError

exc_tb     = <traceback object at 0x7f45f3aa94c0>
exc_type   = <class 'asyncio.exceptions.CancelledError'>
exc_val    = CancelledError()
self       = <aiohttp.helpers.TimerContext object at 0x7f45f3aab710>

venv/lib64/python3.11/site-packages/aiohttp/helpers.py:709: TimeoutError

The above exception was the direct cause of the following exception:

aiohttp_client = <function aiohttp_client.<locals>.go at 0x7f45f3a41bc0>
mocker = <pytest_mock.plugin.MockerFixture object at 0x7f45f3a234d0>

    async def test_timeout_on_reading_headers(aiohttp_client: Any, mocker: Any) -> None:
        async def handler(request):
            resp = web.StreamResponse()
            await asyncio.sleep(0.1)
            await resp.prepare(request)
            return resp
    
        app = web.Application()
        app.router.add_route("GET", "/", handler)
        client = await aiohttp_client(app)
    
        with pytest.raises(asyncio.TimeoutError):
>           await client.get("/", timeout=aiohttp.ClientTimeout(total=0.01))

aiohttp_client = <function aiohttp_client.<locals>.go at 0x7f45f3a41bc0>
app        = <Application 0x7f45f3a4aa30>
client     = <aiohttp.test_utils.TestClient object at 0x7f45f3a20a90>
handler    = <function test_timeout_on_reading_headers.<locals>.handler at 0x7f45f3a42d40>
mocker     = <pytest_mock.plugin.MockerFixture object at 0x7f45f3a234d0>

tests/test_client_functional.py:583: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:311: in _request
    resp = await self._session.request(method, self.make_url(path), **kwargs)
        kwargs     = {'timeout': ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)}
        method     = 'GET'
        path       = '/'
        self       = <aiohttp.test_utils.TestClient object at 0x7f45f3a20a90>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <aiohttp.client.ClientSession object at 0x7f45f3c1a260>, method = 'GET'
str_or_url = URL('http://127.0.0.1:44237/')

    async def _request(
        self,
        method: str,
        str_or_url: StrOrURL,
        *,
        params: Optional[Mapping[str, str]] = None,
        data: Any = None,
        json: Any = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        allow_redirects: bool = True,
        max_redirects: int = 10,
        compress: Optional[str] = None,
        chunked: Optional[bool] = None,
        expect100: bool = False,
        raise_for_status: Union[
            None, bool, Callable[[ClientResponse], Awaitable[None]]
        ] = None,
        read_until_eof: bool = True,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,
        ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        trace_request_ctx: Optional[SimpleNamespace] = None,
        read_bufsize: Optional[int] = None,
    ) -> ClientResponse:
    
        # NOTE: timeout clamps existing connect and read timeouts.  We cannot
        # set the default to None because we need to detect if the user wants
        # to use the existing timeouts by setting timeout to None.
    
        if self.closed:
            raise RuntimeError("Session is closed")
    
        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, bool, Fingerprint, "
                "or None, got {!r} instead.".format(ssl)
            )
    
        if data is not None and json is not None:
            raise ValueError(
                "data and json parameters can not be used at the same time"
            )
        elif json is not None:
            data = payload.JsonPayload(json, dumps=self._json_serialize)
    
        redirects = 0
        history = []
        version = self._version
    
        # Merge with default headers and transform to CIMultiDict
        headers = self._prepare_headers(headers)
        proxy_headers = self._prepare_headers(proxy_headers)
    
        try:
            url = self._build_url(str_or_url)
        except ValueError as e:
            raise InvalidURL(str_or_url) from e
    
        skip_headers = set(self._skip_auto_headers)
        if skip_auto_headers is not None:
            for i in skip_auto_headers:
                skip_headers.add(istr(i))
    
        if proxy is not None:
            try:
                proxy = URL(proxy)
            except ValueError as e:
                raise InvalidURL(proxy) from e
    
        if timeout is sentinel or timeout is None:
            real_timeout: ClientTimeout = self._timeout
        else:
            real_timeout = timeout
        # timeout is cumulative for all request operations
        # (request, redirects, responses, data consuming)
        tm = TimeoutHandle(
            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold
        )
        handle = tm.start()
    
        if read_bufsize is None:
            read_bufsize = self._read_bufsize
    
        traces = [
            Trace(
                self,
                trace_config,
                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
            )
            for trace_config in self._trace_configs
        ]
    
        for trace in traces:
            await trace.send_request_start(method, url.update_query(params), headers)
    
        timer = tm.timer()
        try:
            with timer:
                while True:
                    url, auth_from_url = strip_auth_from_url(url)
                    if auth and auth_from_url:
                        raise ValueError(
                            "Cannot combine AUTH argument with "
                            "credentials encoded in URL"
                        )
    
                    if auth is None:
                        auth = auth_from_url
                    if auth is None:
                        auth = self._default_auth
                    # It would be confusing if we support explicit
                    # Authorization header with auth argument
                    if (
                        headers is not None
                        and auth is not None
                        and hdrs.AUTHORIZATION in headers
                    ):
                        raise ValueError(
                            "Cannot combine AUTHORIZATION header "
                            "with AUTH argument or credentials "
                            "encoded in URL"
                        )
    
                    all_cookies = self._cookie_jar.filter_cookies(url)
    
                    if cookies is not None:
                        tmp_cookie_jar = CookieJar()
                        tmp_cookie_jar.update_cookies(cookies)
                        req_cookies = tmp_cookie_jar.filter_cookies(url)
                        if req_cookies:
                            all_cookies.load(req_cookies)
    
                    if proxy is not None:
                        proxy = URL(proxy)
                    elif self._trust_env:
                        with suppress(LookupError):
                            proxy, proxy_auth = get_env_proxy_for_url(url)
    
                    req = self._request_class(
                        method,
                        url,
                        params=params,
                        headers=headers,
                        skip_auto_headers=skip_headers,
                        data=data,
                        cookies=all_cookies,
                        auth=auth,
                        version=version,
                        compress=compress,
                        chunked=chunked,
                        expect100=expect100,
                        loop=self._loop,
                        response_class=self._response_class,
                        proxy=proxy,
                        proxy_auth=proxy_auth,
                        timer=timer,
                        session=self,
                        ssl=ssl,
                        proxy_headers=proxy_headers,
                        traces=traces,
                    )
    
                    # connection timeout
                    try:
                        async with ceil_timeout(
                            real_timeout.connect,
                            ceil_threshold=real_timeout.ceil_threshold,
                        ):
                            assert self._connector is not None
                            conn = await self._connector.connect(
                                req, traces=traces, timeout=real_timeout
                            )
                    except asyncio.TimeoutError as exc:
                        raise ServerTimeoutError(
                            f"Connection timeout to host {url}"
                        ) from exc
    
                    assert conn.transport is not None
    
                    assert conn.protocol is not None
                    conn.protocol.set_response_params(
                        timer=timer,
                        skip_payload=method.upper() == "HEAD",
                        read_until_eof=read_until_eof,
                        auto_decompress=self._auto_decompress,
                        read_timeout=real_timeout.sock_read,
                        read_bufsize=read_bufsize,
                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
                    )
    
                    try:
                        try:
                            resp = await req.send(conn)
                            try:
                                await resp.start(conn)
                            except BaseException:
                                resp.close()
                                raise
                        except BaseException:
                            conn.close()
                            raise
                    except ClientError:
                        raise
                    except OSError as exc:
>                       raise ClientOSError(*exc.args) from exc
E                       aiohttp.client_exceptions.ClientOSError

all_cookies = <SimpleCookie: >
allow_redirects = True
auth       = None
auth_from_url = None
chunked    = None
compress   = None
conn       = Connection<ConnectionKey(host='127.0.0.1', port=44237, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
cookies    = None
data       = None
expect100  = False
handle     = None
headers    = <CIMultiDict()>
history    = []
json       = None
max_redirects = 10
method     = 'GET'
params     = None
proxy      = None
proxy_auth = None
proxy_headers = <CIMultiDict()>
raise_for_status = None
read_bufsize = 65536
read_until_eof = True
real_timeout = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
redirects  = 0
req        = <aiohttp.client_reqrep.ClientRequest object at 0x7f45f3aa9fd0>
resp       = <ClientResponse(http://127.0.0.1:44237/) [None None]>
None

self       = <aiohttp.client.ClientSession object at 0x7f45f3c1a260>
skip_auto_headers = None
skip_headers = set()
ssl        = None
str_or_url = URL('http://127.0.0.1:44237/')
timeout    = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
timer      = <aiohttp.helpers.TimerContext object at 0x7f45f3aab710>
tm         = <aiohttp.helpers.TimeoutHandle object at 0x7f45f3aaa790>
trace_request_ctx = None
traces     = []
url        = URL('http://127.0.0.1:44237/')
version    = HttpVersion(major=1, minor=1)

venv/lib64/python3.11/site-packages/aiohttp/client.py:535: ClientOSError
---------------------------- Captured log teardown -----------------------------
ERROR    aiohttp.server:web_protocol.py:431 Error handling request
Traceback (most recent call last):
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_protocol.py", line 462, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_app.py", line 393, in _handle
    resp = await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/tests/test_client_functional.py", line 575, in handler
    await resp.prepare(request)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_response.py", line 348, in prepare
    return await self._start(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_response.py", line 356, in _start
    await self._write_headers()
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_response.py", line 427, in _write_headers
    await writer.write_headers(status_line, self._headers)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/http_writer.py", line 131, in write_headers
    self._write(buf)
    ^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/http_writer.py", line 76, in _write
    raise ConnectionResetError("Cannot write to closing transport")
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ConnectionResetError: Cannot write to closing transport
_________________ test_timeout_on_conn_reading_headers[pyloop] _________________

self = <aiohttp.client.ClientSession object at 0x7f45f299bb90>, method = 'GET'
str_or_url = URL('http://127.0.0.1:34923/')

    async def _request(
        self,
        method: str,
        str_or_url: StrOrURL,
        *,
        params: Optional[Mapping[str, str]] = None,
        data: Any = None,
        json: Any = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        allow_redirects: bool = True,
        max_redirects: int = 10,
        compress: Optional[str] = None,
        chunked: Optional[bool] = None,
        expect100: bool = False,
        raise_for_status: Union[
            None, bool, Callable[[ClientResponse], Awaitable[None]]
        ] = None,
        read_until_eof: bool = True,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,
        ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        trace_request_ctx: Optional[SimpleNamespace] = None,
        read_bufsize: Optional[int] = None,
    ) -> ClientResponse:
    
        # NOTE: timeout clamps existing connect and read timeouts.  We cannot
        # set the default to None because we need to detect if the user wants
        # to use the existing timeouts by setting timeout to None.
    
        if self.closed:
            raise RuntimeError("Session is closed")
    
        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, bool, Fingerprint, "
                "or None, got {!r} instead.".format(ssl)
            )
    
        if data is not None and json is not None:
            raise ValueError(
                "data and json parameters can not be used at the same time"
            )
        elif json is not None:
            data = payload.JsonPayload(json, dumps=self._json_serialize)
    
        redirects = 0
        history = []
        version = self._version
    
        # Merge with default headers and transform to CIMultiDict
        headers = self._prepare_headers(headers)
        proxy_headers = self._prepare_headers(proxy_headers)
    
        try:
            url = self._build_url(str_or_url)
        except ValueError as e:
            raise InvalidURL(str_or_url) from e
    
        skip_headers = set(self._skip_auto_headers)
        if skip_auto_headers is not None:
            for i in skip_auto_headers:
                skip_headers.add(istr(i))
    
        if proxy is not None:
            try:
                proxy = URL(proxy)
            except ValueError as e:
                raise InvalidURL(proxy) from e
    
        if timeout is sentinel or timeout is None:
            real_timeout: ClientTimeout = self._timeout
        else:
            real_timeout = timeout
        # timeout is cumulative for all request operations
        # (request, redirects, responses, data consuming)
        tm = TimeoutHandle(
            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold
        )
        handle = tm.start()
    
        if read_bufsize is None:
            read_bufsize = self._read_bufsize
    
        traces = [
            Trace(
                self,
                trace_config,
                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
            )
            for trace_config in self._trace_configs
        ]
    
        for trace in traces:
            await trace.send_request_start(method, url.update_query(params), headers)
    
        timer = tm.timer()
        try:
            with timer:
                while True:
                    url, auth_from_url = strip_auth_from_url(url)
                    if auth and auth_from_url:
                        raise ValueError(
                            "Cannot combine AUTH argument with "
                            "credentials encoded in URL"
                        )
    
                    if auth is None:
                        auth = auth_from_url
                    if auth is None:
                        auth = self._default_auth
                    # It would be confusing if we support explicit
                    # Authorization header with auth argument
                    if (
                        headers is not None
                        and auth is not None
                        and hdrs.AUTHORIZATION in headers
                    ):
                        raise ValueError(
                            "Cannot combine AUTHORIZATION header "
                            "with AUTH argument or credentials "
                            "encoded in URL"
                        )
    
                    all_cookies = self._cookie_jar.filter_cookies(url)
    
                    if cookies is not None:
                        tmp_cookie_jar = CookieJar()
                        tmp_cookie_jar.update_cookies(cookies)
                        req_cookies = tmp_cookie_jar.filter_cookies(url)
                        if req_cookies:
                            all_cookies.load(req_cookies)
    
                    if proxy is not None:
                        proxy = URL(proxy)
                    elif self._trust_env:
                        with suppress(LookupError):
                            proxy, proxy_auth = get_env_proxy_for_url(url)
    
                    req = self._request_class(
                        method,
                        url,
                        params=params,
                        headers=headers,
                        skip_auto_headers=skip_headers,
                        data=data,
                        cookies=all_cookies,
                        auth=auth,
                        version=version,
                        compress=compress,
                        chunked=chunked,
                        expect100=expect100,
                        loop=self._loop,
                        response_class=self._response_class,
                        proxy=proxy,
                        proxy_auth=proxy_auth,
                        timer=timer,
                        session=self,
                        ssl=ssl,
                        proxy_headers=proxy_headers,
                        traces=traces,
                    )
    
                    # connection timeout
                    try:
                        async with ceil_timeout(
                            real_timeout.connect,
                            ceil_threshold=real_timeout.ceil_threshold,
                        ):
                            assert self._connector is not None
                            conn = await self._connector.connect(
                                req, traces=traces, timeout=real_timeout
                            )
                    except asyncio.TimeoutError as exc:
                        raise ServerTimeoutError(
                            f"Connection timeout to host {url}"
                        ) from exc
    
                    assert conn.transport is not None
    
                    assert conn.protocol is not None
                    conn.protocol.set_response_params(
                        timer=timer,
                        skip_payload=method.upper() == "HEAD",
                        read_until_eof=read_until_eof,
                        auto_decompress=self._auto_decompress,
                        read_timeout=real_timeout.sock_read,
                        read_bufsize=read_bufsize,
                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
                    )
    
                    try:
                        try:
                            resp = await req.send(conn)
                            try:
>                               await resp.start(conn)

all_cookies = <SimpleCookie: >
allow_redirects = True
auth       = None
auth_from_url = None
chunked    = None
compress   = None
conn       = Connection<ConnectionKey(host='127.0.0.1', port=34923, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
cookies    = None
data       = None
expect100  = False
handle     = None
headers    = <CIMultiDict()>
history    = []
json       = None
max_redirects = 10
method     = 'GET'
params     = None
proxy      = None
proxy_auth = None
proxy_headers = <CIMultiDict()>
raise_for_status = None
read_bufsize = 65536
read_until_eof = True
real_timeout = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
redirects  = 0
req        = <aiohttp.client_reqrep.ClientRequest object at 0x7f45f3988c10>
resp       = <ClientResponse(http://127.0.0.1:34923/) [None None]>
None

self       = <aiohttp.client.ClientSession object at 0x7f45f299bb90>
skip_auto_headers = None
skip_headers = set()
ssl        = None
str_or_url = URL('http://127.0.0.1:34923/')
timeout    = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
timer      = <aiohttp.helpers.TimerContext object at 0x7f45f3989050>
tm         = <aiohttp.helpers.TimeoutHandle object at 0x7f45f2b209d0>
trace_request_ctx = None
traces     = []
url        = URL('http://127.0.0.1:34923/')
version    = HttpVersion(major=1, minor=1)

venv/lib64/python3.11/site-packages/aiohttp/client.py:525: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <ClientResponse(http://127.0.0.1:34923/) [None None]>
None

connection = Connection<ConnectionKey(host='127.0.0.1', port=34923, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>

    async def start(self, connection: "Connection") -> "ClientResponse":
        """Start response processing."""
        self._closed = False
        self._protocol = connection.protocol
        self._connection = connection
    
>       with self._timer:

connection = Connection<ConnectionKey(host='127.0.0.1', port=34923, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
protocol   = <aiohttp.client_proto.ResponseHandler object at 0x7f45f2c4f3f0>
self       = <ClientResponse(http://127.0.0.1:34923/) [None None]>
None


venv/lib64/python3.11/site-packages/aiohttp/client_reqrep.py:837: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <aiohttp.helpers.TimerContext object at 0x7f45f3989050>
exc_type = <class 'asyncio.exceptions.CancelledError'>
exc_val = CancelledError(), exc_tb = <traceback object at 0x7f45f2adbc00>

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> Optional[bool]:
        if self._tasks:
            self._tasks.pop()
    
        if exc_type is asyncio.CancelledError and self._cancelled:
>           raise asyncio.TimeoutError from None
E           TimeoutError

exc_tb     = <traceback object at 0x7f45f2adbc00>
exc_type   = <class 'asyncio.exceptions.CancelledError'>
exc_val    = CancelledError()
self       = <aiohttp.helpers.TimerContext object at 0x7f45f3989050>

venv/lib64/python3.11/site-packages/aiohttp/helpers.py:709: TimeoutError

The above exception was the direct cause of the following exception:

aiohttp_client = <function aiohttp_client.<locals>.go at 0x7f45f3a437e0>
mocker = <pytest_mock.plugin.MockerFixture object at 0x7f45f398a310>

    async def test_timeout_on_conn_reading_headers(
        aiohttp_client: Any, mocker: Any
    ) -> None:
        # tests case where user did not set a connection timeout
    
        async def handler(request):
            resp = web.StreamResponse()
            await asyncio.sleep(0.1)
            await resp.prepare(request)
            return resp
    
        app = web.Application()
        app.router.add_route("GET", "/", handler)
    
        conn = aiohttp.TCPConnector()
        client = await aiohttp_client(app, connector=conn)
    
        with pytest.raises(asyncio.TimeoutError):
>           await client.get("/", timeout=aiohttp.ClientTimeout(total=0.01))

aiohttp_client = <function aiohttp_client.<locals>.go at 0x7f45f3a437e0>
app        = <Application 0x7f45f3a4b3d0>
client     = <aiohttp.test_utils.TestClient object at 0x7f45f3988ed0>
conn       = <aiohttp.connector.TCPConnector object at 0x7f45f3989350>
handler    = <function test_timeout_on_conn_reading_headers.<locals>.handler at 0x7f45f3a43100>
mocker     = <pytest_mock.plugin.MockerFixture object at 0x7f45f398a310>

tests/test_client_functional.py:604: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:311: in _request
    resp = await self._session.request(method, self.make_url(path), **kwargs)
        kwargs     = {'timeout': ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)}
        method     = 'GET'
        path       = '/'
        self       = <aiohttp.test_utils.TestClient object at 0x7f45f3988ed0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <aiohttp.client.ClientSession object at 0x7f45f299bb90>, method = 'GET'
str_or_url = URL('http://127.0.0.1:34923/')

    async def _request(
        self,
        method: str,
        str_or_url: StrOrURL,
        *,
        params: Optional[Mapping[str, str]] = None,
        data: Any = None,
        json: Any = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        allow_redirects: bool = True,
        max_redirects: int = 10,
        compress: Optional[str] = None,
        chunked: Optional[bool] = None,
        expect100: bool = False,
        raise_for_status: Union[
            None, bool, Callable[[ClientResponse], Awaitable[None]]
        ] = None,
        read_until_eof: bool = True,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,
        ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        trace_request_ctx: Optional[SimpleNamespace] = None,
        read_bufsize: Optional[int] = None,
    ) -> ClientResponse:
    
        # NOTE: timeout clamps existing connect and read timeouts.  We cannot
        # set the default to None because we need to detect if the user wants
        # to use the existing timeouts by setting timeout to None.
    
        if self.closed:
            raise RuntimeError("Session is closed")
    
        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, bool, Fingerprint, "
                "or None, got {!r} instead.".format(ssl)
            )
    
        if data is not None and json is not None:
            raise ValueError(
                "data and json parameters can not be used at the same time"
            )
        elif json is not None:
            data = payload.JsonPayload(json, dumps=self._json_serialize)
    
        redirects = 0
        history = []
        version = self._version
    
        # Merge with default headers and transform to CIMultiDict
        headers = self._prepare_headers(headers)
        proxy_headers = self._prepare_headers(proxy_headers)
    
        try:
            url = self._build_url(str_or_url)
        except ValueError as e:
            raise InvalidURL(str_or_url) from e
    
        skip_headers = set(self._skip_auto_headers)
        if skip_auto_headers is not None:
            for i in skip_auto_headers:
                skip_headers.add(istr(i))
    
        if proxy is not None:
            try:
                proxy = URL(proxy)
            except ValueError as e:
                raise InvalidURL(proxy) from e
    
        if timeout is sentinel or timeout is None:
            real_timeout: ClientTimeout = self._timeout
        else:
            real_timeout = timeout
        # timeout is cumulative for all request operations
        # (request, redirects, responses, data consuming)
        tm = TimeoutHandle(
            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold
        )
        handle = tm.start()
    
        if read_bufsize is None:
            read_bufsize = self._read_bufsize
    
        traces = [
            Trace(
                self,
                trace_config,
                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
            )
            for trace_config in self._trace_configs
        ]
    
        for trace in traces:
            await trace.send_request_start(method, url.update_query(params), headers)
    
        timer = tm.timer()
        try:
            with timer:
                while True:
                    url, auth_from_url = strip_auth_from_url(url)
                    if auth and auth_from_url:
                        raise ValueError(
                            "Cannot combine AUTH argument with "
                            "credentials encoded in URL"
                        )
    
                    if auth is None:
                        auth = auth_from_url
                    if auth is None:
                        auth = self._default_auth
                    # It would be confusing if we support explicit
                    # Authorization header with auth argument
                    if (
                        headers is not None
                        and auth is not None
                        and hdrs.AUTHORIZATION in headers
                    ):
                        raise ValueError(
                            "Cannot combine AUTHORIZATION header "
                            "with AUTH argument or credentials "
                            "encoded in URL"
                        )
    
                    all_cookies = self._cookie_jar.filter_cookies(url)
    
                    if cookies is not None:
                        tmp_cookie_jar = CookieJar()
                        tmp_cookie_jar.update_cookies(cookies)
                        req_cookies = tmp_cookie_jar.filter_cookies(url)
                        if req_cookies:
                            all_cookies.load(req_cookies)
    
                    if proxy is not None:
                        proxy = URL(proxy)
                    elif self._trust_env:
                        with suppress(LookupError):
                            proxy, proxy_auth = get_env_proxy_for_url(url)
    
                    req = self._request_class(
                        method,
                        url,
                        params=params,
                        headers=headers,
                        skip_auto_headers=skip_headers,
                        data=data,
                        cookies=all_cookies,
                        auth=auth,
                        version=version,
                        compress=compress,
                        chunked=chunked,
                        expect100=expect100,
                        loop=self._loop,
                        response_class=self._response_class,
                        proxy=proxy,
                        proxy_auth=proxy_auth,
                        timer=timer,
                        session=self,
                        ssl=ssl,
                        proxy_headers=proxy_headers,
                        traces=traces,
                    )
    
                    # connection timeout
                    try:
                        async with ceil_timeout(
                            real_timeout.connect,
                            ceil_threshold=real_timeout.ceil_threshold,
                        ):
                            assert self._connector is not None
                            conn = await self._connector.connect(
                                req, traces=traces, timeout=real_timeout
                            )
                    except asyncio.TimeoutError as exc:
                        raise ServerTimeoutError(
                            f"Connection timeout to host {url}"
                        ) from exc
    
                    assert conn.transport is not None
    
                    assert conn.protocol is not None
                    conn.protocol.set_response_params(
                        timer=timer,
                        skip_payload=method.upper() == "HEAD",
                        read_until_eof=read_until_eof,
                        auto_decompress=self._auto_decompress,
                        read_timeout=real_timeout.sock_read,
                        read_bufsize=read_bufsize,
                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
                    )
    
                    try:
                        try:
                            resp = await req.send(conn)
                            try:
                                await resp.start(conn)
                            except BaseException:
                                resp.close()
                                raise
                        except BaseException:
                            conn.close()
                            raise
                    except ClientError:
                        raise
                    except OSError as exc:
>                       raise ClientOSError(*exc.args) from exc
E                       aiohttp.client_exceptions.ClientOSError

all_cookies = <SimpleCookie: >
allow_redirects = True
auth       = None
auth_from_url = None
chunked    = None
compress   = None
conn       = Connection<ConnectionKey(host='127.0.0.1', port=34923, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
cookies    = None
data       = None
expect100  = False
handle     = None
headers    = <CIMultiDict()>
history    = []
json       = None
max_redirects = 10
method     = 'GET'
params     = None
proxy      = None
proxy_auth = None
proxy_headers = <CIMultiDict()>
raise_for_status = None
read_bufsize = 65536
read_until_eof = True
real_timeout = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
redirects  = 0
req        = <aiohttp.client_reqrep.ClientRequest object at 0x7f45f3988c10>
resp       = <ClientResponse(http://127.0.0.1:34923/) [None None]>
None

self       = <aiohttp.client.ClientSession object at 0x7f45f299bb90>
skip_auto_headers = None
skip_headers = set()
ssl        = None
str_or_url = URL('http://127.0.0.1:34923/')
timeout    = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)
timer      = <aiohttp.helpers.TimerContext object at 0x7f45f3989050>
tm         = <aiohttp.helpers.TimeoutHandle object at 0x7f45f2b209d0>
trace_request_ctx = None
traces     = []
url        = URL('http://127.0.0.1:34923/')
version    = HttpVersion(major=1, minor=1)

venv/lib64/python3.11/site-packages/aiohttp/client.py:535: ClientOSError
---------------------------- Captured log teardown -----------------------------
ERROR    aiohttp.server:web_protocol.py:431 Error handling request
Traceback (most recent call last):
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_protocol.py", line 462, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_app.py", line 393, in _handle
    resp = await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/tests/test_client_functional.py", line 594, in handler
    await resp.prepare(request)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_response.py", line 348, in prepare
    return await self._start(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_response.py", line 356, in _start
    await self._write_headers()
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/web_response.py", line 427, in _write_headers
    await writer.write_headers(status_line, self._headers)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/http_writer.py", line 131, in write_headers
    self._write(buf)
    ^^^^^^^^^^^^^^^^
  File ".../aiohttp/venv/lib64/python3.11/site-packages/aiohttp/http_writer.py", line 76, in _write
    raise ConnectionResetError("Cannot write to closing transport")
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ConnectionResetError: Cannot write to closing transport
_____________________________ test_headers[pyloop] _____________________________

make_request = <function make_request.<locals>.maker at 0x7f45f2f772e0>

    def test_headers(make_request: Any) -> None:
        req = make_request(
            "post", "http://python.org/", headers={"Content-Type": "text/plain"}
        )
    
        assert "CONTENT-TYPE" in req.headers
        assert req.headers["CONTENT-TYPE"] == "text/plain"
>       assert req.headers["ACCEPT-ENCODING"] == "gzip, deflate, br"
E       AssertionError: assert 'gzip, deflate' == 'gzip, deflate, br'
E         - gzip, deflate, br
E         ?              ----
E         + gzip, deflate

make_request = <function make_request.<locals>.maker at 0x7f45f2f772e0>
req        = <aiohttp.client_reqrep.ClientRequest object at 0x7f45f2f94310>

tests/test_client_request.py:313: AssertionError
__________________________ TestCase.test_default_loop __________________________

self = <test_loop.TestCase testMethod=test_default_loop>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_loop.TestCase testMethod=test_default_loop>

venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib64/python3.11/unittest/async_case.py:62: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_loop.TestCase testMethod=test_default_loop>
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_loop.TestCase testMethod=test_default_loop>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2f3ab10>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2f3ab10>

/usr/lib64/python3.11/asyncio/events.py:677: RuntimeError
________________________ TestCase.test_on_startup_hook _________________________

self = <test_loop.TestCase testMethod=test_on_startup_hook>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_loop.TestCase testMethod=test_on_startup_hook>

venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib64/python3.11/unittest/async_case.py:62: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_loop.TestCase testMethod=test_on_startup_hook>
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_loop.TestCase testMethod=test_on_startup_hook>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2f3ab10>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2f3ab10>

/usr/lib64/python3.11/asyncio/events.py:677: RuntimeError
__________________ TestAioHTTPTestCase.test_example_with_loop __________________

self = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_with_loop>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_with_loop>

venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib64/python3.11/unittest/async_case.py:62: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_with_loop>
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_with_loop>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

/usr/lib64/python3.11/asyncio/events.py:677: RuntimeError
____________ TestAioHTTPTestCase.test_example_without_explicit_loop ____________

self = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_without_explicit_loop>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_without_explicit_loop>

venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib64/python3.11/unittest/async_case.py:62: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_without_explicit_loop>
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_example_without_explicit_loop>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

/usr/lib64/python3.11/asyncio/events.py:677: RuntimeError
____________________ TestAioHTTPTestCase.test_inner_example ____________________

self = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example>

venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib64/python3.11/unittest/async_case.py:62: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example>
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

/usr/lib64/python3.11/asyncio/events.py:677: RuntimeError
_________ TestAioHTTPTestCase.test_inner_example_without_explicit_loop _________

self = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example_without_explicit_loop>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example_without_explicit_loop>

venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib64/python3.11/unittest/async_case.py:62: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example_without_explicit_loop>
venv/lib64/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_test_utils.TestAioHTTPTestCase testMethod=test_inner_example_without_explicit_loop>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f45f2fa8d90>

/usr/lib64/python3.11/asyncio/events.py:677: RuntimeError
============================= slowest 10 durations =============================
4.92s teardown tests/test_client_functional.py::test_read_timeout[pyloop]
4.92s teardown tests/test_client_functional.py::test_read_timeout_on_prepared_response[pyloop]
2.00s call     tests/test_client_functional.py::test_read_timeout_between_chunks[pyloop]
2.00s call     tests/test_client_functional.py::test_set_cookies_max_age[pyloop]
1.00s call     tests/test_client_functional.py::test_readline_error_on_conn_close[pyloop]
1.00s call     tests/test_client_functional.py::test_timeout_on_reading_data[pyloop]
0.81s teardown tests/test_client_functional.py::test_read_timeout_on_reading_chunks[pyloop]
0.50s call     tests/test_client_functional.py::test_no_error_on_conn_close_if_eof[pyloop]
0.20s call     tests/test_client_functional.py::test_read_timeout_on_reading_chunks[pyloop]
0.13s call     tests/test_test_utils.py::test_testcase_no_app
=========================== short test summary info ============================
XFAIL tests/test_client_functional.py::test_ssl_client[pyloop]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_tcp_connector_fingerprint_ok[pyloop]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_tcp_connector_fingerprint_fail[pyloop]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_broken_connection[pyloop]
XFAIL tests/test_client_functional.py::test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_drop_auth_on_redirect_to_other_host[pyloop-http -> https]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_drop_auth_on_redirect_to_other_host[pyloop-https -> http]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop]
  reason: trustme is not supported
XFAIL tests/test_client_functional.py::test_error_in_performing_request[pyloop]
  reason: trustme is not supported
FAILED tests/test_client_functional.py::test_timeout_on_reading_headers[pyloop]
FAILED tests/test_client_functional.py::test_timeout_on_conn_reading_headers[pyloop]
FAILED tests/test_client_request.py::test_headers[pyloop] - AssertionError: a...
FAILED tests/test_loop.py::TestCase::test_default_loop - RuntimeError: There ...
FAILED tests/test_loop.py::TestCase::test_on_startup_hook - RuntimeError: The...
FAILED tests/test_test_utils.py::TestAioHTTPTestCase::test_example_with_loop
FAILED tests/test_test_utils.py::TestAioHTTPTestCase::test_example_without_explicit_loop
FAILED tests/test_test_utils.py::TestAioHTTPTestCase::test_inner_example - Ru...
FAILED tests/test_test_utils.py::TestAioHTTPTestCase::test_inner_example_without_explicit_loop
================== 9 failed, 312 passed, 9 xfailed in 24.35s ===================

hroncok avatar May 19 '22 11:05 hroncok

Hopefully someone will take a look at getting 3.11 working soon (the CI for 3.11 doesn't even get through the install step yet), as I'm not so familiar with these parts.

But, you should probably be building from 3.8/3.9 branch, master (v4) is very unlikely to be deemed stable by the time of your next release.

Dreamsorcerer avatar May 19 '22 16:05 Dreamsorcerer

Same failures happen with the 3.8.1 release. I've just tested if it's still present on master.

hroncok avatar May 19 '22 16:05 hroncok

Fair enough, just wanted to be sure you weren't planning to ship that version.

Dreamsorcerer avatar May 19 '22 17:05 Dreamsorcerer

BTW The install step on the CI is likely to fail do to the 2 dependencies having pregenerated C sources with an old Cython version. If the cythinizing step happened on demand during install from sdist (with the newest stable Cython), it would probably work. At least that is what I had to workaround manually.

hroncok avatar May 19 '22 17:05 hroncok

Hello, I bisected Python to find that this change introduces the issue in test_loop.py: https://github.com/python/cpython/pull/31799/files#diff-1f2ae0f6c6010caf9d5f1c80cd6033a796ffe2b60554f5df84f554f4a08e622b

Here, I'm a bit out of my depth (and also out of time this week). Does this look like a Python bug (which would be great to identify/fix in the beta period), or an issue in aiohttp?

encukou avatar Jun 02 '22 16:06 encukou

@encukou this looks like it might be because asyncio.run and AsyncTestCase (via asyncio.Runner) no longer calls asyncio.set_event_loop?

graingert avatar Jun 16 '22 06:06 graingert

@encukou this test only fails when run after tests/test_loop.py::test_subprocess_co[pyloop] - when you run it in isolation it passes:

✘  graingert@superjacent  venv  ~/projects/aiohttp   patch-6757  pytest 'tests/test_loop.py::test_subprocess_co[pyloop]' tests/test_loop.py::TestCase::test_default_loop
=========================================================================================== test session starts ===========================================================================================
platform linux -- Python 3.11.0b3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /home/graingert/projects/aiohttp/venv/bin/python
cachedir: .pytest_cache
rootdir: /home/graingert/projects/aiohttp, configfile: setup.cfg
plugins: cov-3.0.0, mock-3.7.0
collected 2 items                                                                                                                                                                                         

tests/test_loop.py::test_subprocess_co[pyloop] PASSED                                                                                                                                               [ 50%]
tests/test_loop.py::TestCase::test_default_loop FAILED                                                                                                                                              [100%]

================================================================================================ FAILURES =================================================================================================
_______________________________________________________________________________________ TestCase.test_default_loop ________________________________________________________________________________________

self = <test_loop.TestCase testMethod=test_default_loop>

    def setUp(self) -> None:
        try:
>           self.loop = asyncio.get_running_loop()
E           RuntimeError: no running event loop

self       = <test_loop.TestCase testMethod=test_default_loop>

venv/lib/python3.11/site-packages/aiohttp/test_utils.py:434: RuntimeError

During handling of the above exception, another exception occurred:
/usr/lib/python3.11/unittest/async_case.py:82: in _callSetUp
    self._asyncioTestContext.run(self.setUp)
        self       = <test_loop.TestCase testMethod=test_default_loop>
venv/lib/python3.11/site-packages/aiohttp/test_utils.py:436: in setUp
    self.loop = asyncio.get_event_loop_policy().get_event_loop()
        self       = <test_loop.TestCase testMethod=test_default_loop>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f8a01eef250>

    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                threading.current_thread() is threading.main_thread()):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.

self       = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f8a01eef250>

/usr/lib/python3.11/asyncio/events.py:677: RuntimeError
========================================================================================== slowest 10 durations ===========================================================================================
0.02s teardown tests/test_loop.py::test_subprocess_co[pyloop]

(5 durations < 0.005s hidden.  Use -vv to show these durations.)
========================================================================================= short test summary info =========================================================================================
FAILED tests/test_loop.py::TestCase::test_default_loop - RuntimeError: There is no current event loop in thread 'MainThread'.
======================================================================================= 1 failed, 1 passed in 0.12s =======================================================================================

passing in isolation:

 ✘  graingert@superjacent  venv  ~/projects/aiohttp   patch-6757  pytest tests/test_loop.py::TestCase::test_default_loop                                                 
=========================================================================================== test session starts ===========================================================================================
platform linux -- Python 3.11.0b3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /home/graingert/projects/aiohttp/venv/bin/python
cachedir: .pytest_cache
rootdir: /home/graingert/projects/aiohttp, configfile: setup.cfg
plugins: cov-3.0.0, mock-3.7.0
collected 1 item                                                                                                                                                                                          

tests/test_loop.py::TestCase::test_default_loop PASSED                                                                                                                                              [100%]

========================================================================================== slowest 10 durations ===========================================================================================

(3 durations < 0.005s hidden.  Use -vv to show these durations.)
============================================================================================ 1 passed in 0.01s ============================================================================================

graingert avatar Jun 16 '22 09:06 graingert

yep it's the missing calls to set_event_loop() this patch fixes both test_default_loop and tests/test_loop.py::TestCase::test_on_startup_hook for me:

https://github.com/aio-libs/aiohttp/blob/19d8c96aea383b7856e46cd285e52428a56a207b/aiohttp/test_utils.py#L415-L424

graingert avatar Jun 16 '22 10:06 graingert

looks like this is still happening - it seems because the call to set_event_loop is deferred to asyncio.Runner.run https://github.com/python/cpython/issues/95736

graingert avatar Aug 06 '22 08:08 graingert