From 68072de5054ab7746704e7815d317e3681b922d1 Mon Sep 17 00:00:00 2001 From: Yaniv Michael Kaul Date: Thu, 26 Mar 2026 18:27:26 +0200 Subject: [PATCH] (fix) cluster: handle None control_connection_timeout in wait_for_schema_agreement min(self._timeout, total_timeout - elapsed) raises TypeError when control_connection_timeout is set to None, which is explicitly documented as a supported value (meaning no timeout). Guard the min() call so that when self._timeout is None, we use only the remaining schema agreement wait time. --- cassandra/cluster.py | 3 ++- tests/unit/test_control_connection.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cassandra/cluster.py b/cassandra/cluster.py index 8da9df6a55..9eace8810d 100644 --- a/cassandra/cluster.py +++ b/cassandra/cluster.py @@ -4117,7 +4117,8 @@ def wait_for_schema_agreement(self, connection=None, preloaded_results=None, wai local_query = QueryMessage(query=maybe_add_timeout_to_query(self._SELECT_SCHEMA_LOCAL, self._metadata_request_timeout), consistency_level=cl) try: - timeout = min(self._timeout, total_timeout - elapsed) + remaining = total_timeout - elapsed + timeout = min(self._timeout, remaining) if self._timeout is not None else remaining peers_result, local_result = connection.wait_for_responses( peers_query, local_query, timeout=timeout) except OperationTimedOut as timeout: diff --git a/tests/unit/test_control_connection.py b/tests/unit/test_control_connection.py index d759e12332..037d4a8888 100644 --- a/tests/unit/test_control_connection.py +++ b/tests/unit/test_control_connection.py @@ -287,6 +287,20 @@ def test_wait_for_schema_agreement_rpc_lookup(self): assert not self.control_connection.wait_for_schema_agreement() assert self.time.clock >= self.cluster.max_schema_agreement_wait + + def test_wait_for_schema_agreement_none_timeout(self): + """ + When control_connection_timeout is None, wait_for_schema_agreement + should not raise a TypeError on the min() call. + """ + cc = ControlConnection(self.cluster, timeout=None, + schema_event_refresh_window=0, + topology_event_refresh_window=0, + status_event_refresh_window=0) + cc._connection = self.connection + cc._time = self.time + assert cc.wait_for_schema_agreement() + def test_refresh_nodes_and_tokens(self): self.control_connection.refresh_node_list_and_token_map() meta = self.cluster.metadata