Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

UDPTransport.abort() with a queued datagram reports a fatal write error and a resume_writing() AttributeError

Abierto
#771 0 comentarios 0 reacciones 0 asignados Ver en GitHub

@graingert ya está trabajando en esto.

Desde el 5/10/2026.

  • #772 de @graingert — abierto

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
68/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
networking

Línea de trabajo

Start by reproducing the issue with the provided script, then trace UDPTransport.abort() and UVBaseTransport._maybe_resume_protocol to see how queued-send cancellation and protocol detachment interact. Compare the exception-handler output with vanilla asyncio; done means abort discards the queued datagram without reporting either error, while connection_lost(None) still occurs.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

  • uvloop version: 0.23.0 (also 0.22.1)
  • Python version: 3.12.3
  • Platform: Linux (x86_64, glibc 2.39)
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?: Yes
  • Does uvloop behave differently from vanilla asyncio? How?: Yes. With vanilla asyncio, abort() silently discards the queued datagram and calls connection_lost(None). With uvloop, connection_lost(None) is called too, but two errors are also passed to the loop's exception handler.

Calling abort() on a UDPTransport while a datagram is still queued (because the OS refused it with EAGAIN) reports two errors to the loop's exception handler:

  1. Fatal error on transport UDPTransport (Fatal write error on datagram transport), with exception=CancelledError(). The queued send is cancelled because we aborted, so this is not an error.
  2. protocol.resume_writing() failed, with AttributeError("'NoneType' object has no attribute 'resume_writing'"), raised from UVBaseTransport._maybe_resume_protocol after the protocol has already been detached.

A UNIX datagram socket is used to make the OS refuse datagrams, because UDP on loopback never exerts back-pressure. The peer never reads, so the send buffer fills up.

import asyncio
import socket
import sys
import tempfile

import uvloop


class Protocol(asyncio.DatagramProtocol):
    def connection_made(self, transport):
        transport.set_write_buffer_limits(0)

    def connection_lost(self, exc):
        print("connection_lost", exc)


async def main():
    loop = asyncio.get_running_loop()
    errors = []
    loop.set_exception_handler(lambda loop, context: errors.append(context))

    path = f"{tempfile.mkdtemp()}/peer.sock"
    peer = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    peer.bind(path)  # never read from

    sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    sock.connect(path)
    sock.setblocking(False)
    transport, _ = await loop.create_datagram_endpoint(Protocol, sock=sock)

    # Send until the OS refuses a datagram and the transport has to queue it
    while not transport.get_write_buffer_size():
        transport.sendto(b"x" * 64)

    transport.abort()
    await asyncio.sleep(0.1)
    for context in errors:
        print("exception handler:", context["message"], repr(context.get("exception")))


if sys.argv[1:] == ["uvloop"]:
    uvloop.run(main())
else:
    asyncio.run(main())

Output with python repro.py:

connection_lost None

Output with python repro.py uvloop:

connection_lost None

exception handler: Fatal error on transport UDPTransport (Fatal write error on datagram transport) CancelledError()
exception handler: protocol.resume_writing() failed AttributeError("'NoneType' object has no attribute 'resume_writing'")

Expected: the same as vanilla asyncio, i.e. the queued datagram is silently discarded and nothing is reported to the exception handler.

Found via anyio, whose UDP socket aclose() aborts the transport.

Lenguaje dominante
Cython
Estrellas
11.9k
Forks
616
Merge medio
4 h 43 min
PR fusionados (30 d)
3

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de MagicStack/uvloop

Todos los issues de MagicStack/uvloop

Issues similares

Más issues de Networking

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.