3434import contextlib
3535import datetime
3636import threading
37+ import warnings
3738import weakref
39+
3840from collections import defaultdict
3941
4042from bson .codec_options import DEFAULT_CODEC_OPTIONS
@@ -358,7 +360,7 @@ def __init__(
358360
359361 self .__default_database_name = dbase
360362 self .__lock = threading .Lock ()
361- self .__cursor_manager = CursorManager ( self )
363+ self .__cursor_manager = None
362364 self .__kill_cursors_queue = []
363365
364366 self ._event_listeners = options .pool_options .event_listeners
@@ -712,7 +714,7 @@ def close(self):
712714 self ._topology .close ()
713715
714716 def set_cursor_manager (self , manager_class ):
715- """Set this client's cursor manager.
717+ """DEPRECATED - Set this client's cursor manager.
716718
717719 Raises :class:`TypeError` if `manager_class` is not a subclass of
718720 :class:`~pymongo.cursor_manager.CursorManager`. A cursor manager
@@ -723,9 +725,16 @@ def set_cursor_manager(self, manager_class):
723725 :Parameters:
724726 - `manager_class`: cursor manager to use
725727
728+ .. versionchanged:: 3.3
729+ Deprecated, for real this time.
730+
726731 .. versionchanged:: 3.0
727732 Undeprecated.
728733 """
734+ warnings .warn (
735+ "set_cursor_manager is Deprecated" ,
736+ DeprecationWarning ,
737+ stacklevel = 2 )
729738 manager = manager_class (self )
730739 if not isinstance (manager , CursorManager ):
731740 raise TypeError ("manager_class must be a subclass of "
@@ -920,12 +929,17 @@ def __getitem__(self, name):
920929 return database .Database (self , name )
921930
922931 def close_cursor (self , cursor_id , address = None ):
923- """Close a single database cursor .
932+ """Send a kill cursors message soon with the given id .
924933
925934 Raises :class:`TypeError` if `cursor_id` is not an instance of
926935 ``(int, long)``. What closing the cursor actually means
927936 depends on this client's cursor manager.
928937
938+ This method may be called from a :class:`~pymongo.cursor.Cursor`
939+ destructor during garbage collection, so it isn't safe to take a
940+ lock or do network I/O. Instead, we schedule the cursor to be closed
941+ soon on a background thread.
942+
929943 :Parameters:
930944 - `cursor_id`: id of cursor to close
931945 - `address` (optional): (host, port) pair of the cursor's server.
@@ -938,30 +952,36 @@ def close_cursor(self, cursor_id, address=None):
938952 if not isinstance (cursor_id , integer_types ):
939953 raise TypeError ("cursor_id must be an instance of (int, long)" )
940954
941- self .__cursor_manager .close (cursor_id , address )
955+ if self .__cursor_manager is not None :
956+ self .__cursor_manager .close (cursor_id , address )
957+ else :
958+ self .__kill_cursors_queue .append ((address , [cursor_id ]))
942959
943960 def kill_cursors (self , cursor_ids , address = None ):
944- """Send a kill cursors message soon with the given ids.
961+ """DEPRECATED - Send a kill cursors message soon with the given ids.
945962
946963 Raises :class:`TypeError` if `cursor_ids` is not an instance of
947964 ``list``.
948965
949- This method may be called from a :class:`~pymongo.cursor.Cursor`
950- destructor during garbage collection, so it isn't safe to take a
951- lock or do network I/O. Instead, we schedule the cursor to be closed
952- soon on a background thread.
953-
954966 :Parameters:
955967 - `cursor_ids`: list of cursor ids to kill
956968 - `address` (optional): (host, port) pair of the cursor's server.
957969 If it is not provided, the client attempts to close the cursor on
958970 the primary or standalone, or a mongos server.
959971
972+ .. versionchanged:: 3.3
973+ Deprecated.
974+
960975 .. versionchanged:: 3.0
961976 Now accepts an `address` argument. Schedules the cursors to be
962977 closed on a background thread instead of sending the message
963978 immediately.
964979 """
980+ warnings .warn (
981+ "kill_cursors is deprecated." ,
982+ DeprecationWarning ,
983+ stacklevel = 2 )
984+
965985 if not isinstance (cursor_ids , list ):
966986 raise TypeError ("cursor_ids must be a list" )
967987
0 commit comments