Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion python/loopmini/loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,13 @@ def _remove_writer(self, fd): return self.remove_writer(fd)
sock_connect,_sock_connect,_sock_connect_cb = _SelLoop.sock_connect,_SelLoop._sock_connect,_SelLoop._sock_connect_cb

def _make_socket_transport(self, sock, protocol, waiter=None, *, extra=None, server=None, context=None):
return SockTransport(self, sock, protocol, waiter, extra, server, context)
# The accept path (gh: _accept_connection2) swallows transport-creation errors
# outside debug mode; report before re-raising so server-side bugs are never silent
try: return SockTransport(self, sock, protocol, waiter, extra, server, context)
except (SystemExit, KeyboardInterrupt): raise
except BaseException as e:
if server is not None: self.call_exception_handler(dict(message='loopmini: error creating server-side transport', exception=e, socket=sock))
raise

def _make_ssl_transport(self, sock, protocol, sslcontext, waiter=None, *, server_side=False, server_hostname=None, extra=None, server=None,
ssl_handshake_timeout=None, ssl_shutdown_timeout=None, call_connection_made=True, context=None):
Expand Down
7 changes: 4 additions & 3 deletions python/loopmini/transports.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"Socket transports for the Rust-reactor loop, feeding stock asyncio protocols."
import asyncio, socket
import asyncio, socket, sys
_server_takes_transport = sys.version_info >= (3, 13) # Server._attach/_detach gained the transport arg in 3.13 (gh-113538)
from asyncio import constants, futures, transports

class _TransportLifecycle:
Expand Down Expand Up @@ -40,7 +41,7 @@ def __init__(self, loop, sock, protocol, waiter=None, extra=None, server=None, c
except OSError: pass
self._buffer = bytearray()
self._closing = self._reading = self._eof = self._lost = False
if server is not None: server._attach(self)
if server is not None: server._attach(self) if _server_takes_transport else server._attach()
loop.call_soon(protocol.connection_made, self, context=context)
loop.call_soon(self.resume_reading, context=context)
if waiter is not None: loop.call_soon(futures._set_result_unless_cancelled, waiter, None)
Expand Down Expand Up @@ -137,7 +138,7 @@ def _force_close(self, exc):
def _close_resource(self):
self._sock.close()
if self._server is not None:
self._server._detach(self)
self._server._detach(self) if _server_takes_transport else self._server._detach()
self._server = None

class DatagramTransport(_TransportLifecycle, asyncio.DatagramTransport):
Expand Down
3 changes: 2 additions & 1 deletion tests/test_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import asyncio, contextvars, ctypes, os, pytest, random, signal, socket, sys, threading, time
import loopmini

def run(coro): return asyncio.run(coro, loop_factory=loopmini.new_event_loop)
def run(coro):
with asyncio.Runner(loop_factory=loopmini.new_event_loop) as r: return r.run(coro)

def test_cancelled_timer_released():
"""A cancelled timer must leave the reactor's timer map at once.
Expand Down