88import sys
99import os
1010import warnings
11+ import weakref
1112
1213import errno
1314import socket
@@ -278,11 +279,12 @@ def __init__(self, cursor_id, database):
278279 self ._quoted_cursor_id = '"' + self .cursor_id .replace ('"' , '""' ) + '"'
279280 self .database = database
280281 self ._pq_cursor_id = database .typio .encode (self .cursor_id )
281-
282- def __del__ (self ):
283- if not self .closed and ID (self ) == self .cursor_id :
284- self .database ._closeportals .append (
285- self .database .typio .encode (self .cursor_id )
282+ if ID (self ) == self .cursor_id :
283+ addgarbage = self .database ._closeportals .append
284+ typio = self .database .typio
285+ curid = self .cursor_id
286+ self ._del = weakref .ref (
287+ self , lambda _ : addgarbage (typio .encode (curid ))
286288 )
287289
288290 def __iter__ (self ):
@@ -346,7 +348,9 @@ def close(self):
346348 self .database ._closeportals .append (
347349 self .database .typio .encode (self .cursor_id )
348350 )
349- self .closed = True
351+ self .closed = True
352+ if hasattr (self , '_del' ):
353+ del self ._del
350354
351355 def _raise_parameter_tuple_error (self , procs , tup , itemnum ):
352356 # The element traceback will include the full list of parameters.
@@ -907,11 +911,6 @@ def _fini(self):
907911class UtilityCursor (CursorStrategy ):
908912 cursor_type = 'utility'
909913
910- def __del__ (self ):
911- # utility cursors must be finished immediately,
912- # so the cursor_id goes unused.
913- pass
914-
915914 def _init (self ):
916915 self ._xact = pq .Instruction ((
917916 pq .element .Bind (
@@ -1061,6 +1060,13 @@ def __init__(self, statement_id, database):
10611060 self ._pq_xact = None
10621061 self ._pq_statement_id = None
10631062 self .closed = None
1063+ if ID (self ) == self .statement_id :
1064+ addgarbage = self .database ._closestatements .append
1065+ typio = self .database .typio
1066+ sid = self .statement_id
1067+ self ._del = weakref .ref (
1068+ self , lambda _ : addgarbage (typio .encode (curid ))
1069+ )
10641070
10651071 def __repr__ (self ):
10661072 return '<{mod}.{name}[{ci}] {state}>' .format (
@@ -1187,6 +1193,8 @@ def close(self):
11871193 if not (self .closed is True ):
11881194 self .database ._closestatements .append (self ._pq_statement_id )
11891195 self .closed = True
1196+ if hasattr (self , '_del' ):
1197+ del self ._del
11901198
11911199 def ife_snapshot_text (self ):
11921200 s = ""
@@ -1199,15 +1207,6 @@ def ife_snapshot_text(self):
11991207 ) + os .linesep
12001208 return s
12011209
1202- def __del__ (self ):
1203- # Only close statements that have generated IDs as the ones
1204- # with explicitly created
1205- if not self .closed and ID (self ) == self .statement_id :
1206- # Always close CPSs as the way the statement_id is generated
1207- # might cause a conflict if Python were to reuse the previously
1208- # used id()[it can and has happened]. - jwp 2007
1209- self .close ()
1210-
12111210 def _init (self ):
12121211 """
12131212 Push initialization messages to the server, but don't wait for
0 commit comments