Skip to content

[Python] RuntimeError: no running event loop when using Python 3.14.0b1 #39507

Closed

Description

@parthea

What version of gRPC and what language are you using?

1.71.0
Python

What operating system (Linux, Windows,...) and version?

Linux (ubuntu, rodete)

What runtime / compiler are you using (e.g. python version or version of gcc)

Python 3.14.0b1
gcc version 14.2.0 (Debian 14.2.0-19+build4)

What did you do?

Please provide either 1) A unit test for reproducing the bug or 2) Specific steps for us to follow to reproduce the bug. If there’s not enough information to debug the problem, gRPC team may close the issue at their discretion. You’re welcome to re-open the issue once you have a reproduction.

Install Python 3.14.0b1 from https://www.python.org/downloads/release/python-3140b1/

Observe the error below

partheniou@partheniou-vm-3:~/Python-3.14.0b1$ python3.14
Python 3.14.0b1 (main, May  7 2025, 19:23:10) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import grpc
>>> from grpc import aio
>>> print(grpc.__version__)
1.71.0
>>> aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) 
Traceback (most recent call last):
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi", line 184, in grpc._cython.cygrpc.get_working_loop
RuntimeError: no running event loop

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi", line 190, in grpc._cython.cygrpc.get_working_loop
  File "/usr/local/lib/python3.14/asyncio/events.py", line 805, in get_event_loop_policy
    warnings._deprecated('asyncio.get_event_loop_policy', remove=(3, 16))
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/_py_warnings.py", line 830, in _deprecated
    _wm.warn(msg, DeprecationWarning, stacklevel=3)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DeprecationWarning: 'asyncio.get_event_loop_policy' is deprecated and slated for removal in Python 3.16

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/google/home/partheniou/.local/lib/python3.14/site-packages/grpc/aio/_channel.py", line 621, in secure_channel
    return Channel(
        target,
    ...<3 lines>...
        interceptors,
    )
  File "/usr/local/google/home/partheniou/.local/lib/python3.14/site-packages/grpc/aio/_channel.py", line 367, in __init__
    self._loop = cygrpc.get_working_loop()
                 ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi", line 186, in grpc._cython.cygrpc.get_working_loop
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi", line 194, in grpc._cython.cygrpc.get_working_loop
  File "/usr/local/lib/python3.14/asyncio/events.py", line 805, in get_event_loop_policy
    warnings._deprecated('asyncio.get_event_loop_policy', remove=(3, 16))
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/_py_warnings.py", line 830, in _deprecated
    _wm.warn(msg, DeprecationWarning, stacklevel=3)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DeprecationWarning: 'asyncio.get_event_loop_policy' is deprecated and slated for removal in Python 3.16
>>> 

What did you expect to see?

I expected aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) to succeed

What did you see instead?

I saw

>>> aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) 
Traceback (most recent call last):
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi", line 184, in grpc._cython.cygrpc.get_working_loop
RuntimeError: no running event loop

Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).

See TROUBLESHOOTING.md for how to diagnose problems better.

Anything else we should know about your project / environment?

Activity

  1. changed the title [-]bug(Python): `RuntimeError: no running event loop` when using Python 3.14.0a7[/-] [+]bug(Python): `RuntimeError: no running event loop` when using Python 3.14.0b1[/+] on May 7, 2025
  2. parthea commented on May 8, 2025

    @parthea
    ContributorAuthor

    Some differences between 3.13 and 3.14

    • In 3.14, asyncio.get_event_loop_policy().get_event_loop() now raises RuntimeError: There is no current event loop in thread 'MainThread' because there is no event loop
    • In 3.14, asyncio.get_event_loop_policy() emits deprecation warning DeprecationWarning: 'asyncio.get_event_loop_policy' is deprecated and slated for removal in Python 3.16

    The code below could be changed to swallow the DeprecationWarning: There is no current event loop which appears in Python 3.12/3.13 without treating all deprecation warnings as errors. We also need to handle the new RuntimeError when there is no event loop when calling asyncio.get_event_loop_policy().get_event_loop()

    with warnings.catch_warnings():
    # Convert DeprecationWarning to errors so we can capture them with except
    warnings.simplefilter("error", DeprecationWarning)
    try:
    return asyncio.get_event_loop_policy().get_event_loop()
    # Since version 3.12, DeprecationWarning is emitted if there is no
    # current event loop.
    except DeprecationWarning:
    return asyncio.get_event_loop_policy().new_event_loop()

    Testing:

    python3.14
    Python 3.14.0b1 (main, May  7 2025, 19:23:10) [GCC 14.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> asyncio.get_running_loop()
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        asyncio.get_running_loop()
        ~~~~~~~~~~~~~~~~~~~~~~~~^^
    RuntimeError: no running event loop
    >>> asyncio.get_event_loop_policy().get_event_loop()
    <python-input-2>:1: DeprecationWarning: 'asyncio.get_event_loop_policy' is deprecated and slated for removal in Python 3.16
    Traceback (most recent call last):
      File "<python-input-2>", line 1, in <module>
        asyncio.get_event_loop_policy().get_event_loop()
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
      File "/usr/local/lib/python3.14/asyncio/events.py", line 718, in get_event_loop
        raise RuntimeError('There is no current event loop in thread %r.'
                           % threading.current_thread().name)
    RuntimeError: There is no current event loop in thread 'MainThread'.
    >>> asyncio.get_event_loop_policy().new_event_loop()
    <python-input-3>:1: DeprecationWarning: 'asyncio.get_event_loop_policy' is deprecated and slated for removal in Python 3.16
    <_UnixSelectorEventLoop running=False closed=False debug=False>
    >>> exit()
    
    (py3131) partheniou@partheniou-vm-3:~$ python3
    Python 3.13.1 (main, Apr  7 2025, 22:14:29) [GCC 14.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> asyncio.get_running_loop()
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        asyncio.get_running_loop()
        ~~~~~~~~~~~~~~~~~~~~~~~~^^
    RuntimeError: no running event loop
    >>> asyncio.get_event_loop_policy().get_event_loop()
    <python-input-2>:1: DeprecationWarning: There is no current event loop
      asyncio.get_event_loop_policy().get_event_loop()
    <_UnixSelectorEventLoop running=False closed=False debug=False>
    >>> asyncio.get_event_loop_policy().new_event_loop()
    <_UnixSelectorEventLoop running=False closed=False debug=False>
    >>> 
    
    

    We would still need to migrate off asyncio.get_event_loop_policy() prior to Python 3.16 as stated by the deprecation warning. I'll file a separate issue for that.

  3. parthea commented on May 8, 2025

    @parthea
    ContributorAuthor

    With both #39523 and #39525, testing looks good for Python 3.14.0b1

    partheniou@partheniou-vm-3:~/git/grpc$ python3.14
    Python 3.14.0b1 (main, May  7 2025, 19:23:10) [GCC 14.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import grpc
    >>> print(grpc.__version__)
    1.73.0.dev0
    >>> from grpc import aio
    >>> aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
    <grpc.aio._channel.Channel object at 0x7ff13d3e06e0>
    >>> exit
    
  4. sergiitk commented on Jul 22, 2025

    @sergiitk
    Member

    I don't think to suppressing RuntimeError when no aio loop is running (as proposed in #39523) is the right thing to do.

    Note that in the reproduction case aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) is executed outside of an async function, which would normally be executed by a runner handling the event loop creation.

    To work with awaitable objects in REPL, Python provides asyncio REPL.

    An example without asyncio REPL:

    $ python3.14
    Python 3.14.0b4 (main, Jul 12 2025, 00:59:52) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> await asyncio.sleep(1, result='hello')
      File "<python-input-1>", line 1
        await asyncio.sleep(1, result='hello')
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    SyntaxError: 'await' outside function
    Try the asyncio REPL (python3.14 -m asyncio) to use top-level 'await' and run background asyncio tasks.
    >>> asyncio.sleep(1, result='hello')
    <coroutine object sleep at 0x109bf8040>
    >>> exit
    <sys>:0: RuntimeWarning: coroutine 'sleep' was never awaited

    An example with asyncio REPL:

    $ python3.14 -m asyncio
    asyncio REPL 3.14.0b4 (main, Jul 12 2025, 00:59:52) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
    Use "await" directly instead of "asyncio.run()".
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> await asyncio.sleep(1, result='hello')
    'hello'
    >>> exit
    exiting asyncio REPL...

    Same examples using Python 3.11:

    $ python3.11
    Python 3.11.13 (main, Jun  6 2025, 23:28:53) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> await asyncio.sleep(1, result='hello')
      File "<stdin>", line 1
    SyntaxError: 'await' outside function
    >>> asyncio.sleep(1, result='hello')
    <coroutine object sleep at 0x104fd1540>
    >>> exit
    sys:1: RuntimeWarning: coroutine 'sleep' was never awaited
    RuntimeWarning: Enable tracemalloc to get the object allocation traceback
    
    $ python3.11 -m asyncio
    asyncio REPL 3.11.13 (main, Jun  6 2025, 23:28:53) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
    Use "await" directly instead of "asyncio.run()".
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> await asyncio.sleep(1, result='hello')
    'hello'
    >>> exit
    exiting asyncio REPL...

    That said, the gRPC Python team will consider what's the right way to handle the RuntimeError: no running event loop. I think we at least should start displaying a deprecation warning when gRPC aio methods are executed outside of the event loop context.

  5. sergiitk commented on Jul 23, 2025

    @sergiitk
    Member

    Found some historical context for the current behavior (create loops on demand instead of RuntimeError): #23377.
    We may have to preserve this approach after all. Will investigate further.

  6. added this to the Python 3.14 support milestone on Aug 6, 2025
  7. added a commit that references this issue on Sep 23, 2025
    6019bec
  8. added a commit that references this issue on Sep 23, 2025
    f29dac8
  9. added a commit that references this issue on Sep 23, 2025
    876e1d1
  10. changed the title [-]bug(Python): `RuntimeError: no running event loop` when using Python 3.14.0b1[/-] [+][Python] `RuntimeError: no running event loop` when using Python 3.14.0b1[/+] on Sep 23, 2025
  11. sergiitk commented on Sep 23, 2025

    @sergiitk
    Member

    Fixed by #40750.

  12. added a commit that references this issue on Oct 10, 2025
    9fcfab7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions