Diff
Modified: branches/5.0.x/docs/contents/changelog.rst (963 => 964)
--- branches/5.0.x/docs/contents/changelog.rst 2019-01-05 11:59:18 UTC (rev 963)
+++ branches/5.0.x/docs/contents/changelog.rst 2019-01-05 13:51:23 UTC (rev 964)
@@ -5,6 +5,8 @@
-------------------------
- This version officially supports the new PostgreSQL 11.
- Fixed a bug in parsing array subscript ranges (reported by Justin Pryzby).
+- Fixed an issue when deleting a DB wrapper object with the underlying
+ connection already closed (bug report by Jacob Champion).
Vesion 5.0.6 (2018-07-29)
-------------------------
Modified: branches/5.0.x/pg.py (963 => 964)
--- branches/5.0.x/pg.py 2019-01-05 11:59:18 UTC (rev 963)
+++ branches/5.0.x/pg.py 2019-01-05 13:51:23 UTC (rev 964)
@@ -1572,9 +1572,15 @@
except AttributeError:
db = None
if db:
- db.set_cast_hook(None)
+ try:
+ db.set_cast_hook(None)
+ except TypeError:
+ pass # probably already closed
if self._closeable:
- db.close()
+ try:
+ db.close()
+ except InternalError:
+ pass # probably already closed
# Auxiliary methods
@@ -1631,7 +1637,10 @@
# Wraps shared library function so we can track state.
if self._closeable:
if self.db:
- self.db.set_cast_hook(None)
+ try:
+ self.db.set_cast_hook(None)
+ except TypeError:
+ pass # probably already closed
self.db.close()
self.db = None
else:
@@ -1662,6 +1671,7 @@
if self.db:
self.db.set_cast_hook(None)
self.db.close()
+ db.set_cast_hook(self.dbtypes.typecast)
self.db = db
def begin(self, mode=None):
Modified: branches/5.0.x/tests/test_classic_dbwrapper.py (963 => 964)
--- branches/5.0.x/tests/test_classic_dbwrapper.py 2019-01-05 11:59:18 UTC (rev 963)
+++ branches/5.0.x/tests/test_classic_dbwrapper.py 2019-01-05 13:51:23 UTC (rev 964)
@@ -374,26 +374,42 @@
def testExistingConnection(self):
db = pg.DB(self.db.db)
+ self.assertIsNotNone(db.db)
self.assertEqual(self.db.db, db.db)
- self.assertTrue(db.db)
db.close()
- self.assertTrue(db.db)
+ self.assertIsNotNone(db.db)
+ self.assertIsNotNone(self.db.db)
db.reopen()
- self.assertTrue(db.db)
+ self.assertIsNotNone(db.db)
+ self.assertEqual(self.db.db, db.db)
db.close()
- self.assertTrue(db.db)
+ self.assertIsNotNone(db.db)
db = pg.DB(self.db)
self.assertEqual(self.db.db, db.db)
db = pg.DB(db=self.db.db)
self.assertEqual(self.db.db, db.db)
- class DB2:
- pass
+ def testExistingDbApi2Connection(self):
- db2 = DB2()
- db2._cnx = self.db.db
+ class DBApi2Con:
+
+ def __init__(self, cnx):
+ self._cnx = cnx
+
+ def close(self):
+ self._cnx.close()
+
+ db2 = DBApi2Con(self.db.db)
db = pg.DB(db2)
self.assertEqual(self.db.db, db.db)
+ db.close()
+ self.assertIsNotNone(db.db)
+ db.reopen()
+ self.assertIsNotNone(db.db)
+ self.assertEqual(self.db.db, db.db)
+ db.close()
+ self.assertIsNotNone(db.db)
+ db2.close()
class TestDBClass(unittest.TestCase):
Modified: trunk/docs/contents/changelog.rst (963 => 964)
--- trunk/docs/contents/changelog.rst 2019-01-05 11:59:18 UTC (rev 963)
+++ trunk/docs/contents/changelog.rst 2019-01-05 13:51:23 UTC (rev 964)
@@ -3,12 +3,15 @@
Version 5.1 (2019-mm-dd)
------------------------
-- ...
+- DB wrapper objects based on existing connections can not be closed and
+ reopened properly (but the underlying connection will not be affected).
Vesion 5.0.7 (2019-mm-dd)
-------------------------
- This version officially supports the new PostgreSQL 11.
- Fixed a bug in parsing array subscript ranges (reported by Justin Pryzby).
+- Fixed an issue when deleting a DB wrapper object with the underlying
+ connection already closed (bug report by Jacob Champion).
Vesion 5.0.6 (2018-07-29)
-------------------------
Modified: trunk/pg.py (963 => 964)
--- trunk/pg.py 2019-01-05 11:59:18 UTC (rev 963)
+++ trunk/pg.py 2019-01-05 13:51:23 UTC (rev 964)
@@ -1502,8 +1502,10 @@
pass
if not db or not hasattr(db, 'db') or not hasattr(db, 'query'):
db = connect(*args, **kw)
+ self._db_args = args, kw
self._closeable = True
else:
+ self._db_args = db
self._closeable = False
self.db = db
self.dbname = db.db
@@ -1511,7 +1513,6 @@
self._attnames = {}
self._pkeys = {}
self._privileges = {}
- self._args = args, kw
self.adapter = Adapter(self)
self.dbtypes = DbTypes(self)
if db.server_version < 80400:
@@ -1572,9 +1573,15 @@
except AttributeError:
db = None
if db:
- db.set_cast_hook(None)
+ try:
+ db.set_cast_hook(None)
+ except TypeError:
+ pass # probably already closed
if self._closeable:
- db.close()
+ try:
+ db.close()
+ except InternalError:
+ pass # probably already closed
# Auxiliary methods
@@ -1629,13 +1636,17 @@
def close(self):
"""Close the database connection."""
# Wraps shared library function so we can track state.
- if self._closeable:
- if self.db:
- self.db.set_cast_hook(None)
- self.db.close()
- self.db = None
- else:
- raise _int_error('Connection already closed')
+ db = self.db
+ if db:
+ try:
+ db.set_cast_hook(None)
+ except TypeError:
+ pass # probably already closed
+ if self._closeable:
+ db.close()
+ self.db = None
+ else:
+ raise _int_error('Connection already closed')
def reset(self):
"""Reset connection with current parameters.
@@ -1658,11 +1669,14 @@
"""
# There is no such shared library function.
if self._closeable:
- db = connect(*self._args[0], **self._args[1])
+ db = connect(*self._db_args[0], **self._db_args[1])
if self.db:
self.db.set_cast_hook(None)
self.db.close()
+ db.set_cast_hook(self.dbtypes.typecast)
self.db = db
+ else:
+ self.db = self._db_args
def begin(self, mode=None):
"""Begin a transaction."""
Modified: trunk/tests/test_classic_dbwrapper.py (963 => 964)
--- trunk/tests/test_classic_dbwrapper.py 2019-01-05 11:59:18 UTC (rev 963)
+++ trunk/tests/test_classic_dbwrapper.py 2019-01-05 13:51:23 UTC (rev 964)
@@ -375,26 +375,42 @@
def testExistingConnection(self):
db = pg.DB(self.db.db)
+ self.assertIsNotNone(db.db)
self.assertEqual(self.db.db, db.db)
- self.assertTrue(db.db)
db.close()
- self.assertTrue(db.db)
+ self.assertIsNone(db.db)
+ self.assertIsNotNone(self.db.db)
db.reopen()
- self.assertTrue(db.db)
+ self.assertIsNotNone(db.db)
+ self.assertEqual(self.db.db, db.db)
db.close()
- self.assertTrue(db.db)
+ self.assertIsNone(db.db)
db = pg.DB(self.db)
self.assertEqual(self.db.db, db.db)
db = pg.DB(db=self.db.db)
self.assertEqual(self.db.db, db.db)
- class DB2:
- pass
+ def testExistingDbApi2Connection(self):
- db2 = DB2()
- db2._cnx = self.db.db
+ class DBApi2Con:
+
+ def __init__(self, cnx):
+ self._cnx = cnx
+
+ def close(self):
+ self._cnx.close()
+
+ db2 = DBApi2Con(self.db.db)
db = pg.DB(db2)
self.assertEqual(self.db.db, db.db)
+ db.close()
+ self.assertIsNone(db.db)
+ db.reopen()
+ self.assertIsNotNone(db.db)
+ self.assertEqual(self.db.db, db.db)
+ db.close()
+ self.assertIsNone(db.db)
+ db2.close()
class TestDBClass(unittest.TestCase):