8000 Do not close internally used cursors at all. · wulczer/txpostgres@7ecefe5 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7ecefe5

Browse files
committed
Do not close internally used cursors at all.
The only reason for closing a psycopg2 cursor is to prevent its further usage. Cursors created internally when using runQuery and runOperation are never surfaced to the user, so there's no need to explicitly close them. Issue #35 spurred an effort to make sure all generated cursors are always closed, but it now seems that it's not the right way to go about the problem. There's no benefit to forcing psycopg2 cursors to be closed and if the cursor (or connection) are in a bad state, it risks throwing suprious errors. Leave it to psycopg2 to deal with cursors going away and simply fix runInteraction's docstring to explicitly say that the user should not close the cursor they got passed.
1 parent 77b5380 commit 7ecefe5

File tree

3 files changed

+10
-25
lines changed

3 files changed

+10
-25
lines changed

NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
What's new in txpostgres 1.4.0
2+
------------------------------
3+
4+
- internally used cursors are no longer explicitly closed, although
5+
it should not cause any user-visible changes
6+
17
What's new in txpostgres 1.3.0
28
------------------------------
39

test/test_txpostgres.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -643,18 +643,14 @@ def test_runErrorInteraction(self):
643643
Interactions that produce errors are rolled back and the correct error
644644
is reported.
645645
"""
646-
keepCursor = []
647-
648646
def interaction(c):
649-
keepCursor.append(c)
650647
d = c.execute("insert into simple values (1)")
651648
return d.addCallback(
652649
lambda c: c.execute("select * from nope_not_here"))
653650

654651
d = self.conn.runInteraction(interaction)
655652
d = self.assertFailure(d, psycopg2.ProgrammingError)
656653

657-
d.addCallback(lambda _: self.assertTrue(keepCursor[0].closed))
658654
d.addCallback(lambda _: self.conn.runQuery(
659655
"select count(*) from simple"))
660656
return d.addCallback(self.assertEquals, [(0, )])
@@ -665,10 +661,7 @@ def test_errorOnRollback(self):
665661
L{txpostgres.RollbackFailed} failure that has references to the faulty
666662
connection and the original failure that cause all that trouble.
667663
"""
668-
keepCursor = []
669-
670664
def interaction(c):
671-
keepCursor.append(c)
672665
d = c.execute("insert into simple values (1)")
673666
return d.addCallback(
674667
lambda c: c.execute("select * from nope_not_here"))
@@ -691,7 +684,6 @@ def checkError(f):
691684
errors = self.flushLoggedErrors()
692685
self.assertEquals(len(errors), 1)
693686
self.assertEquals(errors[0].value.args[0], "boom")
694-
self.assertTrue(keepCursor[0].closed)
695687
# restore or we won't be able to clean up the mess
696688
mp.restore()
697689
d.addErrback(checkError)

txpostgres/txpostgres.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,7 @@ def runQuery(self, *args, **kwargs):
517517
def _runQuery(self, *args, **kwargs):
518518
c = self.cursor()
519519
d = c.execute(*args, **kwargs)
520-
d.addCallback(lambda c: c.fetchall())
521-
return d.addCallback(lambda ret: (c.close(), ret)[1])
520+
return d.addCallback(lambda c: c.fetchall())
522521

523522
def runOperation(self, *args, **kwargs):
524523
"""
@@ -539,8 +538,7 @@ def runOperation(self, *args, **kwargs):
539538
def _runOperation(self, *args, **kwargs):
540539
c = self.cursor()
541540
d = c.execute(*args, **kwargs)
542-
d.addCallback(lambda _: None)
543-
return d.addCallback(lambda ret: (c.close(), ret)[1])
541+
return d.addCallback(lambda _: None)
544542

545543
def runInteraction(self, interaction, *args, **kwargs):
546544
"""
@@ -551,7 +549,8 @@ def runInteraction(self, interaction, *args, **kwargs):
551549
:obj:`interaction` a new transaction will be started, so the callable
552550
can assume to be running all its commands in a transaction. If
553551
:obj:`interaction` returns a :d:`Deferred` processing will wait for it
554-
to fire before proceeding.
552+
to fire before proceeding. You should not close the provided
553+
:class:`~txpostgres.txpostgres.Cursor`.
555554
556555
After :obj:`interaction` finishes work the transaction will be
557556
automatically committed. If it raises an exception or returns a
@@ -571,9 +570,6 @@ def runInteraction(self, interaction, *args, **kwargs):
571570
just close it, because an open transaction might have been left open in
572571
the database.
573572
574-
Regardless of the result of :obj:`interaction`, the provided
575-
:class:`~txpostgres.txpostgres.Cursor` will be automatically closed.
576-
577573
It is safe to call this method multiple times without waiting for the
578574
first query to complete.
579575
@@ -609,17 +605,8 @@ def justPanic(rf):
609605
# otherwise reraise the original failure
610606
return e.addCallback(lambda _: f)
611607

612-
def closeCursorAndPassthrough(ret, cursor):
613-
try:
614-
cursor.close()
615-
except:
616-
log.err()
617-
618-
return ret
619-
620608
d.addCallback(commitAndPassthrough, c)
621609
d.addErrback(rollbackAndPassthrough, c)
622-
d.addBoth(closeCursorAndPassthrough, c)
623610

624611
return d
625612

0 commit comments

Comments
 (0)
0