Author: cito
Date: Fri Nov 27 10:22:56 2015
New Revision: 645
Log:
Fixed small issue with large object
When an object was already unlinked, getting its attributes would
return without error, but leave an error indicator set. Also fixed
a similar issue with the destructor.
Modified:
branches/4.x/module/pgmodule.c
branches/4.x/module/tests/test_classic_largeobj.py
trunk/module/pgmodule.c
trunk/module/tests/test_classic_largeobj.py
Modified: branches/4.x/module/pgmodule.c
==============================================================================
--- branches/4.x/module/pgmodule.c Fri Nov 27 08:10:58 2015 (r644)
+++ branches/4.x/module/pgmodule.c Fri Nov 27 10:22:56 2015 (r645)
@@ -1245,7 +1245,7 @@
static void
pglarge_dealloc(pglargeobject *self)
{
- if (self->lo_fd >= 0 && check_cnx_obj(self->pgcnx))
+ if (self->lo_fd >= 0 && self->pgcnx->valid)
lo_close(self->pgcnx->cnx, self->lo_fd);
Py_XDECREF(self->pgcnx);
@@ -1612,7 +1612,7 @@
Py_INCREF(self->pgcnx);
return (PyObject *) (self->pgcnx);
}
-
+ PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
@@ -1622,7 +1622,7 @@
{
if (check_lo_obj(self, 0))
return PyInt_FromLong(self->lo_oid);
-
+ PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
Modified: branches/4.x/module/tests/test_classic_largeobj.py
==============================================================================
--- branches/4.x/module/tests/test_classic_largeobj.py Fri Nov 27 08:10:58
2015 (r644)
+++ branches/4.x/module/tests/test_classic_largeobj.py Fri Nov 27 10:22:56
2015 (r645)
@@ -15,8 +15,9 @@
import unittest2 as unittest # for Python < 2.7
except ImportError:
import unittest
-import sys
import tempfile
+import os
+import sys
import pg # the module under test
@@ -31,6 +32,8 @@
except ImportError:
pass
+windows = os.name == 'nt'
+
def connect():
"""Create a basic pg connection to the test database."""
@@ -60,7 +63,7 @@
self.c.query('begin')
def tearDown(self):
- self.c.query('end')
+ self.c.query('rollback')
self.c.close()
def assertIsLargeObject(self, obj):
@@ -110,17 +113,30 @@
large_object.unlink()
finally:
del large_object
+ self.assertIsInstance(r, str)
self.assertEqual(r, data)
def testLoImport(self):
- f = tempfile.NamedTemporaryFile()
+ if windows:
+ # NamedTemporaryFiles don't work well here
+ fname = 'temp_test_pg_largeobj_import.txt'
+ f = open(fname, 'wb')
+ else:
+ f = tempfile.NamedTemporaryFile()
+ fname = f.name
data = 'some data to be imported'
f.write(data)
- f.flush()
- f.seek(0)
+ if windows:
+ f.close()
+ f = open(fname, 'rb')
+ else:
+ f.flush()
+ f.seek(0)
large_object = self.c.loimport(f.name)
try:
f.close()
+ if windows:
+ os.remove(fname)
self.assertIsLargeObject(large_object)
large_object.open(pg.INV_READ)
large_object.seek(0, pg.SEEK_SET)
@@ -148,14 +164,17 @@
if self.obj.oid:
try:
self.obj.close()
- except IOError:
+ except (SystemError, IOError):
pass
try:
self.obj.unlink()
- except IOError:
+ except (SystemError, IOError):
pass
del self.obj
- self.pgcnx.query('end')
+ try:
+ self.pgcnx.query('rollback')
+ except SystemError:
+ pass
self.pgcnx.close()
def testOid(self):
@@ -245,18 +264,23 @@
self.obj.open(pg.INV_READ)
seek(0, pg.SEEK_SET)
r = self.obj.read(9)
+ self.assertIsInstance(r, str)
self.assertEqual(r, 'some data')
seek(4, pg.SEEK_CUR)
r = self.obj.read(2)
+ self.assertIsInstance(r, str)
self.assertEqual(r, 'be')
seek(-10, pg.SEEK_CUR)
r = self.obj.read(4)
+ self.assertIsInstance(r, str)
self.assertEqual(r, 'data')
seek(0, pg.SEEK_SET)
r = self.obj.read(4)
+ self.assertIsInstance(r, str)
self.assertEqual(r, 'some')
seek(-6, pg.SEEK_END)
r = self.obj.read(4)
+ self.assertIsInstance(r, str)
self.assertEqual(r, 'seek')
def testTell(self):
@@ -287,23 +311,13 @@
self.assertRaises(TypeError, unlink, 0)
# unlinking when object is still open
self.obj.open(pg.INV_WRITE)
+ self.assertIsNotNone(self.obj.oid)
+ self.assertNotEqual(0, self.obj.oid)
self.assertRaises(IOError, unlink)
data = 'some data to be sold'
self.obj.write(data)
self.obj.close()
- oid = self.obj.oid
- self.assertIsInstance(oid, int)
- self.assertNotEqual(oid, 0)
- obj = self.pgcnx.getlo(oid)
- try:
- self.assertIsNot(obj, self.obj)
- self.assertEqual(obj.oid, oid)
- obj.open(pg.INV_READ)
- r = obj.read(80)
- obj.close()
- self.assertEqual(r, data)
- finally:
- del obj
+ # unlinking after object has been closed
unlink()
self.assertIsNone(self.obj.oid)
@@ -354,14 +368,20 @@
self.assertRaises(TypeError, export)
self.assertRaises(TypeError, export, 0)
self.assertRaises(TypeError, export, 'invalid', 0)
- f = tempfile.NamedTemporaryFile()
+ if windows:
+ # NamedTemporaryFiles don't work well here
+ fname = 'temp_test_pg_largeobj_export.txt'
+ f = open(fname, 'wb')
+ else:
+ f = tempfile.NamedTemporaryFile()
+ fname = f.name
data = 'some data to be exported'
self.obj.open(pg.INV_WRITE)
self.obj.write(data)
# exporting when object is not yet closed
self.assertRaises(IOError, export, f.name)
self.obj.close()
- export(f.name)
+ export(fname)
r = f.read()
f.close()
self.assertEqual(r, data)
Modified: trunk/module/pgmodule.c
==============================================================================
--- trunk/module/pgmodule.c Fri Nov 27 08:10:58 2015 (r644)
+++ trunk/module/pgmodule.c Fri Nov 27 10:22:56 2015 (r645)
@@ -603,7 +603,7 @@
static void
largeDealloc(largeObject *self)
{
- if (self->lo_fd >= 0 && check_cnx_obj(self->pgcnx))
+ if (self->lo_fd >= 0 && self->pgcnx->valid)
lo_close(self->pgcnx->cnx, self->lo_fd);
Py_XDECREF(self->pgcnx);
@@ -986,7 +986,7 @@
Py_INCREF(self->pgcnx);
return (PyObject *) (self->pgcnx);
}
-
+ PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
@@ -996,7 +996,7 @@
{
if (check_lo_obj(self, 0))
return PyInt_FromLong(self->lo_oid);
-
+ PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
Modified: trunk/module/tests/test_classic_largeobj.py
==============================================================================
--- trunk/module/tests/test_classic_largeobj.py Fri Nov 27 08:10:58 2015
(r644)
+++ trunk/module/tests/test_classic_largeobj.py Fri Nov 27 10:22:56 2015
(r645)
@@ -362,29 +362,15 @@
self.assertRaises(TypeError, unlink, 0)
# unlinking when object is still open
self.obj.open(pg.INV_WRITE)
+ self.assertIsNotNone(self.obj.oid)
+ self.assertNotEqual(0, self.obj.oid)
self.assertRaises(IOError, unlink)
data = b'some data to be sold'
self.obj.write(data)
self.obj.close()
- oid = self.obj.oid
- self.assertIsInstance(oid, int)
- self.assertNotEqual(oid, 0)
- obj = self.pgcnx.getlo(oid)
- try:
- self.assertIsNot(obj, self.obj)
- self.assertEqual(obj.oid, oid)
- obj.open(pg.INV_READ)
- r = obj.read(80)
- obj.close()
- self.assertIsInstance(r, bytes)
- self.assertEqual(r, data)
- finally:
- del obj
+ # unlinking after object has been closed
unlink()
- try:
- self.assertIsNone(self.obj.oid)
- except SystemError:
- pass
+ self.assertIsNone(self.obj.oid)
def testSize(self):
size = self.obj.size
_______________________________________________
PyGreSQL mailing list
[email protected]
https://mail.vex.net/mailman/listinfo.cgi/pygresql