Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#771 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

@graingert ci sta già lavorando.

Dal 5/10/2026.

  • #772 di @graingert — aperta

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
networking

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

  • 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.

Lingua principale
Cython
Stelle
11.9k
Fork
616
Merge medio
4h 43m
PR unite (30g)
3

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di MagicStack/uvloop

Tutte le issue di MagicStack/uvloop

Issue simili

Altre issue su Networking

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.