2929from itertools import groupby , count , chain
3030import json
3131import logging
32+ from typing import NamedTuple , Type , Optional
3233from warnings import warn
3334from random import random
3435import re
5051from cassandra .connection import (ConnectionException , ConnectionShutdown ,
5152 ConnectionHeartbeat , ProtocolVersionUnsupported ,
5253 EndPoint , DefaultEndPoint , DefaultEndPointFactory ,
53- ContinuousPagingState , SniEndPointFactory , ConnectionBusy )
54+ ContinuousPagingState , SniEndPointFactory , ConnectionBusy , Connection )
5455from cassandra .cqltypes import UserType
5556import cassandra .cqltypes as types
5657from cassandra .encoder import Encoder
103104
104105try :
105106 from cassandra .io .eventletreactor import EventletConnection
106- except ( ImportError , AttributeError ) :
107+ except DependencyException :
107108 # AttributeError was add for handling python 3.12 https://github.com/eventlet/eventlet/issues/812
108109 # TODO: remove it when eventlet issue would be fixed
109110 EventletConnection = None
114115 from cassandra .util import WeakSet # NOQA
115116
116117
118+ class ClassImportResult (NamedTuple ):
119+ name : str
120+ exception : Optional [Exception ]
121+ connection_class : Optional [Type [Connection ]]
122+
123+
117124def _is_gevent_monkey_patched ():
118125 if 'gevent.monkey' not in sys .modules :
119126 return False
120- import gevent .socket
121- return socket .socket is gevent .socket .socket
122-
127+ try :
128+ import gevent .socket
129+ return socket .socket is gevent .socket .socket
130+ except (ModuleNotFoundError , ImportError , AttributeError ):
131+ return False
123132
124133def _try_gevent_import ():
125134 if _is_gevent_monkey_patched ():
126- from cassandra .io .geventreactor import GeventConnection
127- return (GeventConnection ,None )
135+ try :
136+ from cassandra .io .geventreactor import GeventConnection
137+ return ClassImportResult (name = "GeventConnection" , connection_class = GeventConnection , exception = None )
138+ except DependencyException as e :
139+ return ClassImportResult (name = "GeventConnection" , connection_class = None , exception = e )
128140 else :
129- return ( None , None )
141+ return ClassImportResult ( name = "GeventConnection" , connection_class = None , exception = DependencyException ( "gevent is not patched" ) )
130142
131143
132144def _is_eventlet_monkey_patched ():
@@ -140,77 +152,56 @@ def _is_eventlet_monkey_patched():
140152 # TODO: remove it when eventlet issue would be fixed
141153 return False
142154
143-
144- def _is_gevent_monkey_patched ():
145- if 'gevent.monkey' not in sys .modules :
146- return False
147- try :
148- import eventlet .patcher
149- return eventlet .patcher .is_monkey_patched ('socket' )
150- # Another case related to PYTHON-1364
151- except AttributeError :
152- return False
153-
154-
155155def _try_eventlet_import ():
156- if _is_eventlet_monkey_patched () :
156+ try :
157157 from cassandra .io .eventletreactor import EventletConnection
158- return (EventletConnection ,None )
159- else :
160- return (None ,None )
158+ except DependencyException as e :
159+ return ClassImportResult (name = "EventletConnection" , connection_class = None , exception = e )
160+ if _is_eventlet_monkey_patched ():
161+ return ClassImportResult (name = "EventletConnection" , connection_class = EventletConnection , exception = None )
162+ return ClassImportResult (name = "EventletConnection" , connection_class = None , exception = DependencyException ("eventlet is not patched" ))
161163
162164def _try_libev_import ():
163165 try :
164166 from cassandra .io .libevreactor import LibevConnection
165- return ( LibevConnection , None )
167+ return ClassImportResult ( name = " LibevConnection" , connection_class = LibevConnection , exception = None )
166168 except DependencyException as e :
167- return ( None , e )
169+ return ClassImportResult ( name = "LibevConnection" , connection_class = None , exception = e )
168170
169171def _try_asyncore_import ():
170172 try :
171173 from cassandra .io .asyncorereactor import AsyncoreConnection
172- return ( AsyncoreConnection , None )
174+ return ClassImportResult ( name = " AsyncoreConnection" , connection_class = AsyncoreConnection , exception = None )
173175 except DependencyException as e :
174- return ( None , e )
176+ return ClassImportResult ( name = "AsyncoreConnection" , connection_class = None , exception = e )
175177
176178def _try_twisted_import ():
177179 try :
178180 from cassandra .io .twistedreactor import TwistedConnection
179- return TwistedConnection , None
181+ return ClassImportResult ( name = " TwistedConnection" , connection_class = TwistedConnection , exception = None )
180182 except DependencyException as e :
181- return None , e
182-
183- def _connection_reduce_fn (val ,import_fn ):
184- (rv , excs ) = val
185- # If we've already found a workable Connection class return immediately
186- if rv :
187- return val
188- (import_result , exc ) = import_fn ()
189- if exc :
190- excs .append (exc )
191- return (rv or import_result , excs )
183+ return ClassImportResult (name = "TwistedConnection" , connection_class = None , exception = e )
184+
192185
193186log = logging .getLogger (__name__ )
194187
195- def get_all_supported_connections_classes ():
196- classes = []
197- excs = []
188+
189+ def load_all_connections_classes ():
190+ results = []
198191 for try_fn in (_try_gevent_import , _try_eventlet_import , _try_libev_import , _try_asyncore_import , _try_twisted_import ):
199- conn , exc = try_fn ()
200- if conn is not None :
201- classes .append (conn )
202- else :
203- excs .append (exc )
204- return tuple (classes ), tuple (excs )
192+ results .append (try_fn ())
193+ return tuple (results )
194+
195+ def get_all_supported_connections_classes ():
196+ return [res .connection_class for res in load_all_connections_classes () if res .connection_class ]
205197
206198def get_default_connection_class ():
207199 excs = []
208200 for try_fn in (_try_gevent_import , _try_eventlet_import , _try_libev_import , _try_asyncore_import , _try_twisted_import ):
209- conn , exc = try_fn ()
210- if conn is not None :
211- return conn , None
212- else :
213- excs .append (exc )
201+ res = try_fn ()
202+ if res .connection_class :
203+ return res .connection_class , excs
204+ excs .append (res .exception )
214205 return None , tuple (excs )
215206
216207
0 commit comments