From 9deb16484dee86d94b2ab75868410b360e9e6d5d Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sat, 8 Jan 2011 00:17:56 +0000 Subject: [PATCH 1/4] Don't define a CObject API in Python 3.2 The API is not available: a PyCapsule should be used. Nobody seems needing it for now. --- psycopg/psycopgmodule.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index d580fa01..f91483df 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -760,10 +760,12 @@ static struct PyModuleDef psycopgmodule = { PyMODINIT_FUNC INIT_MODULE(_psycopg)(void) { +#if PY_VERSION_HEX < 0x03020000 static void *PSYCOPG_API[PSYCOPG_API_pointers]; + PyObject *c_api_object; +#endif PyObject *module = NULL, *dict; - PyObject *c_api_object; #ifdef PSYCOPG_DEBUG if (getenv("PSYCOPG_DEBUG")) @@ -861,9 +863,12 @@ INIT_MODULE(_psycopg)(void) /* PyBoxer_API[PyBoxer_Fake_NUM] = (void *)PyBoxer_Fake; */ /* Create a CObject containing the API pointer array's address */ + /* If anybody asks for a PyCapsule we'll deal with it. */ +#if PY_VERSION_HEX < 0x03020000 c_api_object = PyCObject_FromVoidPtr((void *)PSYCOPG_API, NULL); if (c_api_object != NULL) PyModule_AddObject(module, "_C_API", c_api_object); +#endif /* other mixed initializations of module-level variables */ psycoEncodings = PyDict_New(); From ac5cde8834c85eb0a7cd12812164ce562daeb32a Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sat, 8 Jan 2011 00:19:48 +0000 Subject: [PATCH 2/4] Only use absolute imports in the package In Python 3.2b2 the relative imports are not converted into explicit ones (with .). --- lib/__init__.py | 16 ++++++++-------- lib/extensions.py | 44 ++++++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lib/__init__.py b/lib/__init__.py index 065b2a70..4b9e22a2 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -66,17 +66,17 @@ from psycopg2 import tz # Import the DBAPI-2.0 stuff into top-level module. -from _psycopg import BINARY, NUMBER, STRING, DATETIME, ROWID +from psycopg2._psycopg import BINARY, NUMBER, STRING, DATETIME, ROWID -from _psycopg import Binary, Date, Time, Timestamp -from _psycopg import DateFromTicks, TimeFromTicks, TimestampFromTicks +from psycopg2._psycopg import Binary, Date, Time, Timestamp +from psycopg2._psycopg import DateFromTicks, TimeFromTicks, TimestampFromTicks -from _psycopg import Error, Warning, DataError, DatabaseError, ProgrammingError -from _psycopg import IntegrityError, InterfaceError, InternalError -from _psycopg import NotSupportedError, OperationalError +from psycopg2._psycopg import Error, Warning, DataError, DatabaseError, ProgrammingError +from psycopg2._psycopg import IntegrityError, InterfaceError, InternalError +from psycopg2._psycopg import NotSupportedError, OperationalError -from _psycopg import connect, apilevel, threadsafety, paramstyle -from _psycopg import __version__ +from psycopg2._psycopg import connect, apilevel, threadsafety, paramstyle +from psycopg2._psycopg import __version__ # Register default adapters. diff --git a/lib/extensions.py b/lib/extensions.py index 57aa9c68..82e17fa4 100644 --- a/lib/extensions.py +++ b/lib/extensions.py @@ -32,38 +32,38 @@ This module holds all the extensions to the DBAPI-2.0 provided by psycopg. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # License for more details. -from _psycopg import UNICODE, INTEGER, LONGINTEGER, BOOLEAN, FLOAT -from _psycopg import TIME, DATE, INTERVAL, DECIMAL -from _psycopg import BINARYARRAY, BOOLEANARRAY, DATEARRAY, DATETIMEARRAY -from _psycopg import DECIMALARRAY, FLOATARRAY, INTEGERARRAY, INTERVALARRAY -from _psycopg import LONGINTEGERARRAY, ROWIDARRAY, STRINGARRAY, TIMEARRAY -from _psycopg import UNICODEARRAY +from psycopg2._psycopg import UNICODE, INTEGER, LONGINTEGER, BOOLEAN, FLOAT +from psycopg2._psycopg import TIME, DATE, INTERVAL, DECIMAL +from psycopg2._psycopg import BINARYARRAY, BOOLEANARRAY, DATEARRAY, DATETIMEARRAY +from psycopg2._psycopg import DECIMALARRAY, FLOATARRAY, INTEGERARRAY, INTERVALARRAY +from psycopg2._psycopg import LONGINTEGERARRAY, ROWIDARRAY, STRINGARRAY, TIMEARRAY +from psycopg2._psycopg import UNICODEARRAY -from _psycopg import Binary, Boolean, Float, QuotedString, AsIs +from psycopg2._psycopg import Binary, Boolean, Float, QuotedString, AsIs try: - from _psycopg import MXDATE, MXDATETIME, MXINTERVAL, MXTIME - from _psycopg import MXDATEARRAY, MXDATETIMEARRAY, MXINTERVALARRAY, MXTIMEARRAY - from _psycopg import DateFromMx, TimeFromMx, TimestampFromMx - from _psycopg import IntervalFromMx -except: + from psycopg2._psycopg import MXDATE, MXDATETIME, MXINTERVAL, MXTIME + from psycopg2._psycopg import MXDATEARRAY, MXDATETIMEARRAY, MXINTERVALARRAY, MXTIMEARRAY + from psycopg2._psycopg import DateFromMx, TimeFromMx, TimestampFromMx + from psycopg2._psycopg import IntervalFromMx +except ImportError: pass try: - from _psycopg import PYDATE, PYDATETIME, PYINTERVAL, PYTIME - from _psycopg import PYDATEARRAY, PYDATETIMEARRAY, PYINTERVALARRAY, PYTIMEARRAY - from _psycopg import DateFromPy, TimeFromPy, TimestampFromPy - from _psycopg import IntervalFromPy -except: + from psycopg2._psycopg import PYDATE, PYDATETIME, PYINTERVAL, PYTIME + from psycopg2._psycopg import PYDATEARRAY, PYDATETIMEARRAY, PYINTERVALARRAY, PYTIMEARRAY + from psycopg2._psycopg import DateFromPy, TimeFromPy, TimestampFromPy + from psycopg2._psycopg import IntervalFromPy +except ImportError: pass -from _psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid -from _psycopg import string_types, binary_types, new_type, register_type -from _psycopg import ISQLQuote, Notify +from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid +from psycopg2._psycopg import string_types, binary_types, new_type, register_type +from psycopg2._psycopg import ISQLQuote, Notify -from _psycopg import QueryCanceledError, TransactionRollbackError +from psycopg2._psycopg import QueryCanceledError, TransactionRollbackError try: - from _psycopg import set_wait_callback, get_wait_callback + from psycopg2._psycopg import set_wait_callback, get_wait_callback except ImportError: pass From 43c8fce45c858e96cb1cbb24d2623d721bbbf51c Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sat, 8 Jan 2011 00:21:07 +0000 Subject: [PATCH 3/4] Silence warnings due to deprecated TestCase methods With a veiled criticism. --- tests/testutils.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/testutils.py b/tests/testutils.py index 49d26b21..67387187 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -41,6 +41,16 @@ else: unittest.TestCase.skipTest = skipTest +# Silence warnings caused by the stubborness of the Python unittest maintainers +# http://bugs.python.org/issue9424 +if not hasattr(unittest.TestCase, 'assert_') \ +or unittest.TestCase.assert_ is not unittest.TestCase.assertTrue: + # mavaff... + unittest.TestCase.assert_ = unittest.TestCase.assertTrue + unittest.TestCase.failUnless = unittest.TestCase.assertTrue + unittest.TestCase.assertEquals = unittest.TestCase.assertEqual + unittest.TestCase.failUnlessEqual = unittest.TestCase.assertEqual + def decorate_all_tests(cls, decorator): """Apply *decorator* to all the tests defined in the TestCase *cls*.""" From f8c4335f3590d8d254fcabcb7b133bd93091e8cf Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sat, 8 Jan 2011 00:40:27 +0000 Subject: [PATCH 4/4] Avoid ResourceWarning in tests in Python 3.2 --- tests/test_lobject.py | 18 +++++++++++++++--- tests/testutils.py | 6 +++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/test_lobject.py b/tests/test_lobject.py index 1c71fb4f..cc6621e4 100644 --- a/tests/test_lobject.py +++ b/tests/test_lobject.py @@ -182,7 +182,11 @@ class LargeObjectTests(LargeObjectMixin, unittest.TestCase): filename = os.path.join(self.tmpdir, "data.txt") lo.export(filename) self.assertTrue(os.path.exists(filename)) - self.assertEqual(open(filename, "rb").read(), b("some data")) + f = open(filename, "rb") + try: + self.assertEqual(f.read(), b("some data")) + finally: + f.close() def test_close_twice(self): lo = self.conn.lobject() @@ -224,7 +228,11 @@ class LargeObjectTests(LargeObjectMixin, unittest.TestCase): filename = os.path.join(self.tmpdir, "data.txt") lo.export(filename) self.assertTrue(os.path.exists(filename)) - self.assertEqual(open(filename, "rb").read(), b("some data")) + f = open(filename, "rb") + try: + self.assertEqual(f.read(), b("some data")) + finally: + f.close() def test_close_after_commit(self): lo = self.conn.lobject() @@ -279,7 +287,11 @@ class LargeObjectTests(LargeObjectMixin, unittest.TestCase): filename = os.path.join(self.tmpdir, "data.txt") lo.export(filename) self.assertTrue(os.path.exists(filename)) - self.assertEqual(open(filename, "rb").read(), b("some data")) + f = open(filename, "rb") + try: + self.assertEqual(f.read(), b("some data")) + finally: + f.close() decorate_all_tests(LargeObjectTests, skip_if_no_lo) decorate_all_tests(LargeObjectTests, skip_if_green) diff --git a/tests/testutils.py b/tests/testutils.py index 67387187..cd034e50 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -121,5 +121,9 @@ def script_to_py3(script): if main("lib2to3.fixes", ['--no-diffs', '-w', '-n', f.name]): raise Exception('py3 conversion failed') - return open(f.name).read() + f2 = open(f.name) + try: + return f2.read() + finally: + f2.close()