Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Tests pass, but staggered_race spews RuntimeError: coroutine ignored GeneratorExit #97

Open
musicinmybrain opened this issue Sep 27, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@musicinmybrain
Copy link
Contributor

Describe the bug
A clear and concise description of what the bug is.

When running tests for v2.4.2, the tests pass, but staggered_race spews a traceback RuntimeError: coroutine ignored GeneratorExit. Maybe this is OK, and is just a minor issue with test teardown, but it looks concerning.

To Reproduce
Steps to reproduce the behavior:

$ gh repo clone aio-libs/aiohappyeyeballs
$ cd aiohappyeyeballs
$ git checkout v2.4.2
$ python3.12 -m venv _e
$ . _e/bin/activate
(_e) $ pip install -e .
(_e) $ pip install pytest pytest-cov pytest-asyncio
(_e) $ python -m pytest

I’m also able to reproduce this on other CPython versions – I tried 3.10, 3.11, and 3.13.

Additional context

================================================================================== 26 passed, 1 skipped, 1 xfailed in 0.70s ===================================================================================
Exception ignored in: <coroutine object test_handling_system_exit at 0x7f0f23a9a570>
Traceback (most recent call last):
  File "/usr/lib64/python3.12/unittest/mock.py", line 1410, in patched
    return await func(*newargs, **newkeywargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/tests/test_impl.py", line 1440, in test_handling_system_exit
    await start_connection(
  File "/home/ben/src/forks/aiohappyeyeballs/src/aiohappyeyeballs/impl.py", line 88, in start_connection
    sock, _, _ = await staggered.staggered_race(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: coroutine ignored GeneratorExit   
Task was destroyed but it is pending!
task: <Task pending name='Task-55' coro=<test_handling_system_exit() done, defined at /usr/lib64/python3.12/unittest/mock.py:1405> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Task exception was never retrieved
future: <Task finished name='Task-56' coro=<staggered_race.<locals>.run_one_coro() done, defined at /home/ben/src/forks/aiohappyeyeballs/src/aiohappyeyeballs/_staggered.py:70> exception=SystemExit()>
Traceback (most recent call last):
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/runner.py", line 341, in from_call
    result: TResult | None = func()
                             ^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/runner.py", line 242, in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 182, in _multicall
    return outcome.get_result()
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_result.py", line 100, in get_result
    raise exc.with_traceback(exc.__traceback__) 
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 167, in _multicall
    teardown.throw(outcome._exception)
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/threadexception.py", line 92, in pytest_runtest_call
    yield from thread_exception_runtest_hook()  
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/threadexception.py", line 68, in thread_exception_runtest_hook
    yield
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 167, in _multicall
    teardown.throw(outcome._exception)
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/unraisableexception.py", line 95, in pytest_runtest_call
    yield from unraisable_exception_runtest_hook()
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/unraisableexception.py", line 70, in unraisable_exception_runtest_hook
    yield
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 167, in _multicall
    teardown.throw(outcome._exception)
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/logging.py", line 846, in pytest_runtest_call
    yield from self._runtest_for(item, "call")  
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/logging.py", line 829, in _runtest_for
    yield
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 167, in _multicall
    teardown.throw(outcome._exception)
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/capture.py", line 880, in pytest_runtest_call
    return (yield)
            ^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 167, in _multicall
    teardown.throw(outcome._exception)
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/skipping.py", line 257, in pytest_runtest_call
    return (yield)
            ^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/runner.py", line 174, in pytest_runtest_call
    item.runtest()
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pytest_asyncio/plugin.py", line 457, in runtest
    super().runtest()
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/python.py", line 1627, in runtest
    self.ihook.pytest_pyfunc_call(pyfuncitem=self)
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 182, in _multicall
    return outcome.get_result()
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_result.py", line 100, in get_result
    raise exc.with_traceback(exc.__traceback__) 
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/_pytest/python.py", line 159, in pytest_pyfunc_call
    result = testfunction(**testargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/_e/lib64/python3.12/site-packages/pytest_asyncio/plugin.py", line 929, in inner
    _loop.run_until_complete(task)
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 674, in run_until_complete
    self.run_forever()
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 641, in run_forever
    self._run_once()
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 1986, in _run_once
    handle._run()
  File "/usr/lib64/python3.12/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/home/ben/src/forks/aiohappyeyeballs/src/aiohappyeyeballs/_staggered.py", line 76, in run_one_coro
    result = await coro_fn()
             ^^^^^^^^^^^^^^^
  File "/home/ben/src/forks/aiohappyeyeballs/src/aiohappyeyeballs/impl.py", line 165, in _connect_sock
    await loop.sock_connect(sock, address)
  File "/home/ben/src/forks/aiohappyeyeballs/tests/test_impl.py", line 1395, in _sock_connect
    raise SystemExit
SystemExit
@bdraco
Copy link
Member

bdraco commented Sep 27, 2024

We are using the new staggered_race implementation in cpython main since cpython is debating if they are going to break compatibility in the next 3.12 patch release in python/cpython#124639

When we vendored the staggered_race code, and I added tests for it throwing SystemExit since we noticed the coverage was missing.

I marked the test as xfail because it fails on all versions of staggered_race, and since it is not a regression I left it to be investigated so we can come up with a minimal reproducer and determine if its a problem with our testing or open a cpython bug report

@musicinmybrain
Copy link
Contributor Author

I don’t see the RuntimeError anymore in 2.4.3 with #101. All I have now is:

tests/test_staggered_cpython.py::StaggeredTests::test_first_error_second_successful
  /usr/lib64/python3.12/asyncio/base_events.py:726: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=False>
    _warn(f"unclosed event loop {self!r}", ResourceWarning, source=self)
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants