Compare commits

...

1 Commits

Author SHA1 Message Date
HAL9000 9addd64f6f fix(Python 3.13): replace deprecated asyncio.get_event_loop() and datetime.utcnow() calls
Replace asyncio.get_event_loop() with asyncio.get_running_loop() in async contexts, and use try/except fallback to new_event_loop() in sync/callback contexts across source files and test steps for Python 3.13 compatibility.
2026-05-13 19:10:07 +00:00
7 changed files with 47 additions and 26 deletions
+4 -1
View File
@@ -116,7 +116,10 @@ def step_impl(context):
graph.execute = exec_with_messages
executor = bridge._create_graph_executor({"graph": "test_graph"})
loop = asyncio.get_event_loop()
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
def _run_operator(message):
results = []
@@ -29,15 +29,19 @@ def _write_config_file(data: dict[str, Any]) -> Path:
def _run_async(coro):
try:
loop = asyncio.get_event_loop()
if loop.is_closed():
raise RuntimeError
if loop.is_running():
running_loop = asyncio.get_running_loop()
except RuntimeError:
running_loop = None
if running_loop is not None and not running_loop.is_closed():
if running_loop.is_running():
return asyncio.run(coro)
except Exception: # pylint: disable=broad-except
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop.run_until_complete(coro)
return running_loop.run_until_complete(coro)
# No running loop; create a new one for single execution.
loop = asyncio.new_event_loop()
try:
return loop.run_until_complete(coro)
finally:
loop.close()
class RotatingOperators:
+16 -12
View File
@@ -153,15 +153,19 @@ def _ensure_topological_levels(graph):
def _run_async(coro):
try:
loop = asyncio.get_event_loop()
if loop.is_closed():
raise RuntimeError
if loop.is_running():
running_loop = asyncio.get_running_loop()
except RuntimeError:
running_loop = None
if running_loop is not None and not running_loop.is_closed():
if running_loop.is_running():
return asyncio.run(coro)
except Exception: # pylint: disable=broad-except
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop.run_until_complete(coro)
return running_loop.run_until_complete(coro)
# No running loop; create a new one for single execution.
loop = asyncio.new_event_loop()
try:
return loop.run_until_complete(coro)
finally:
loop.close()
@given("I have a clean test environment for route bridge")
@@ -435,7 +439,7 @@ def step_graph_route_idle_time(context):
@given("I have a graph state that has been idle too long")
def step_graph_state_idle(context):
context.graph_state = GraphState()
current_time = asyncio.get_event_loop().time()
current_time = _TEST_LOOP.time()
context.graph_state.metadata = {"last_updated": current_time - 10.0}
context.graph_state.messages = []
@@ -673,7 +677,7 @@ def step_attempt_downgrade(context):
)
return
try:
context.downgrade_result = asyncio.get_event_loop().run_until_complete(
context.downgrade_result = _TEST_LOOP.run_until_complete(
context.route_bridge.downgrade_graph_to_stream(
context.route_config, context.langgraph
)
@@ -709,7 +713,7 @@ def step_route_upgrade_downgrade(context):
@when("I perform an upgrade and then downgrade cycle")
def step_cycle_upgrade_downgrade(context):
context.langgraph = asyncio.get_event_loop().run_until_complete(
context.langgraph = _TEST_LOOP.run_until_complete(
context.route_bridge.upgrade_stream_to_graph(
context.route_config, context.stream_message
)
@@ -731,7 +735,7 @@ def step_cycle_upgrade_downgrade(context):
name=name, type=getattr(node, "type", NodeType.FUNCTION)
)
context.stream_config = asyncio.get_event_loop().run_until_complete(
context.stream_config = _TEST_LOOP.run_until_complete(
context.route_bridge.downgrade_graph_to_stream(
RouteConfig.from_graph_config(
GraphConfig(
+5 -1
View File
@@ -54,7 +54,11 @@ class Agent(ABC):
def process_message_sync(
self, message: Any, context: dict[str, Any] | None = None
) -> Any:
return asyncio.get_event_loop().run_until_complete(
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
return loop.run_until_complete(
self.process_message(message, context or {})
)
+4 -1
View File
@@ -224,7 +224,10 @@ class RxPyLangGraphBridge:
)
def create_future_task(msg: StreamMessage) -> asyncio.Future[StreamMessage]:
loop = asyncio.get_event_loop()
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
task: asyncio.Future[StreamMessage] = asyncio.ensure_future(
execute_graph(msg), loop=loop
)
+5 -2
View File
@@ -106,7 +106,7 @@ class Node: # pylint: disable=too-many-instance-attributes
async def execute(self, state: GraphState) -> dict[str, Any]: # pylint: disable=too-many-branches
self.execution_count += 1
loop = asyncio.get_event_loop()
loop = asyncio.get_running_loop()
start_time = loop.time()
try:
state_updates = {"current_node": self.name}
@@ -271,7 +271,10 @@ class Node: # pylint: disable=too-many-instance-attributes
if asyncio.iscoroutinefunction(fn):
result = await fn(state)
else:
loop = asyncio.get_event_loop()
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
result = await loop.run_in_executor(None, lambda: fn(state))
if asyncio.iscoroutine(result):
result = await result
+1 -1
View File
@@ -86,7 +86,7 @@ class RouteBridge:
last_updated = state.metadata.get("last_updated")
if (
last_updated
and (asyncio.get_event_loop().time() - last_updated) > idle_threshold
and (asyncio.get_running_loop().time() - last_updated) > idle_threshold
):
return True
if (