Skip to content

Commit 069476f

Browse files
author
James William Pye
committed
Partial correction for __del__ inhibiting GC.
1 parent 3c917de commit 069476f

1 file changed

Lines changed: 19 additions & 20 deletions

File tree

postgresql/driver/pq3.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import sys
99
import os
1010
import warnings
11+
import weakref
1112

1213
import errno
1314
import 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):
907911
class 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

Comments
 (0)