diff --git a/lib/_json.py b/lib/_json.py index 79af8562..880084d7 100644 --- a/lib/_json.py +++ b/lib/_json.py @@ -28,10 +28,10 @@ extensions importing register_json from extras. # License for more details. import json -import sys from psycopg2._psycopg import ISQLQuote, QuotedString from psycopg2._psycopg import new_type, new_array_type, register_type +from psycopg2.compat import PY2 # oids from PostgreSQL 9.2 @@ -81,7 +81,7 @@ class Json(object): qs.prepare(self._conn) return qs.getquoted() - if sys.version_info < (3,): + if PY2: def __str__(self): return self.getquoted() else: diff --git a/lib/compat.py b/lib/compat.py index 185b8f64..54606a80 100644 --- a/lib/compat.py +++ b/lib/compat.py @@ -4,12 +4,16 @@ __all__ = ['string_types', 'text_type', 'lru_cache'] if sys.version_info[0] == 2: # Python 2 + PY2 = True + PY3 = False string_types = basestring, text_type = unicode from ._lru_cache import lru_cache else: # Python 3 + PY2 = False + PY3 = True string_types = str, text_type = str from functools import lru_cache diff --git a/lib/extras.py b/lib/extras.py index 0f471a19..ad31e8ed 100644 --- a/lib/extras.py +++ b/lib/extras.py @@ -26,7 +26,6 @@ and classes until a better place in the distribution is found. # License for more details. import os as _os -import sys as _sys import time as _time import re as _re from collections import namedtuple, OrderedDict @@ -38,7 +37,7 @@ from psycopg2 import extensions as _ext from .extensions import cursor as _cursor from .extensions import connection as _connection from .extensions import adapt as _A, quote_ident -from .compat import lru_cache +from .compat import PY2, PY3, lru_cache from psycopg2._psycopg import ( # noqa REPLICATION_PHYSICAL, REPLICATION_LOGICAL, @@ -203,7 +202,7 @@ class DictRow(list): self[:] = data[0] self._index = data[1] - if _sys.version_info[0] < 3: + if PY2: iterkeys = keys itervalues = values iteritems = items @@ -291,7 +290,7 @@ class RealDictRow(dict): def items(self): return ((k, self[k]) for k in self._column_mapping) - if _sys.version_info[0] < 3: + if PY2: iterkeys = keys itervalues = values iteritems = items @@ -438,7 +437,7 @@ class LoggingConnection(_connection): def _logtofile(self, msg, curs): msg = self.filter(msg, curs) if msg: - if _sys.version_info[0] >= 3 and isinstance(msg, bytes): + if PY3 and isinstance(msg, bytes): msg = msg.decode(_ext.encodings[self.encoding], 'replace') self._logobj.write(msg + _os.linesep) @@ -492,7 +491,7 @@ class MinTimeLoggingConnection(LoggingConnection): def filter(self, msg, curs): t = (_time.time() - curs.timestamp) * 1000 if t > self._mintime: - if _sys.version_info[0] >= 3 and isinstance(msg, bytes): + if PY3 and isinstance(msg, bytes): msg = msg.decode(_ext.encodings[self.encoding], 'replace') return msg + _os.linesep + " (execution time: %d ms)" % t @@ -992,7 +991,7 @@ def register_hstore(conn_or_curs, globally=False, unicode=False, array_oid = tuple([x for x in array_oid if x]) # create and register the typecaster - if _sys.version_info[0] < 3 and unicode: + if PY2 and unicode: cast = HstoreAdapter.parse_unicode else: cast = HstoreAdapter.parse diff --git a/lib/sql.py b/lib/sql.py index f7d2c7f3..93aa8c3e 100644 --- a/lib/sql.py +++ b/lib/sql.py @@ -23,11 +23,10 @@ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # License for more details. -import sys import string from psycopg2 import extensions as ext -from psycopg2.compat import string_types +from psycopg2.compat import PY3, string_types _formatter = string.Formatter() @@ -392,7 +391,7 @@ class Literal(Composable): a.prepare(conn) rv = a.getquoted() - if sys.version_info[0] >= 3 and isinstance(rv, bytes): + if PY3 and isinstance(rv, bytes): rv = rv.decode(ext.encodings[conn.encoding]) return rv diff --git a/psycopg/adapter_asis.c b/psycopg/adapter_asis.c index 7b6f5340..d3171228 100644 --- a/psycopg/adapter_asis.c +++ b/psycopg/adapter_asis.c @@ -44,7 +44,7 @@ asis_getquoted(asisObject *self, PyObject *args) } else { rv = PyObject_Str(self->wrapped); -#if PY_MAJOR_VERSION > 2 +#if PY_3 /* unicode to bytes in Py3 */ if (rv) { PyObject *tmp = PyUnicode_AsUTF8String(rv); diff --git a/psycopg/adapter_binary.c b/psycopg/adapter_binary.c index dfe9c66e..f0a6738e 100644 --- a/psycopg/adapter_binary.c +++ b/psycopg/adapter_binary.c @@ -45,9 +45,6 @@ binary_escape(unsigned char *from, size_t from_length, return PQescapeBytea(from, from_length, to_length); } -#define HAS_BUFFER (PY_MAJOR_VERSION < 3) -#define HAS_MEMORYVIEW (PY_MAJOR_VERSION > 2 || PY_MINOR_VERSION >= 6) - /* binary_quote - do the quote process on plain and unicode strings */ static PyObject * @@ -58,10 +55,8 @@ binary_quote(binaryObject *self) Py_ssize_t buffer_len; size_t len = 0; PyObject *rv = NULL; -#if HAS_MEMORYVIEW Py_buffer view; int got_view = 0; -#endif /* Allow Binary(None) to work */ if (self->wrapped == Py_None) { @@ -71,8 +66,6 @@ binary_quote(binaryObject *self) } /* if we got a plain string or a buffer we escape it and save the buffer */ - -#if HAS_MEMORYVIEW if (PyObject_CheckBuffer(self->wrapped)) { if (0 > PyObject_GetBuffer(self->wrapped, &view, PyBUF_CONTIG_RO)) { goto exit; @@ -81,9 +74,8 @@ binary_quote(binaryObject *self) buffer = (const char *)(view.buf); buffer_len = view.len; } -#endif -#if HAS_BUFFER +#if PY_2 if (!buffer && (Bytes_Check(self->wrapped) || PyBuffer_Check(self->wrapped))) { if (PyObject_AsReadBuffer(self->wrapped, (const void **)&buffer, &buffer_len) < 0) { @@ -114,9 +106,7 @@ binary_quote(binaryObject *self) exit: if (to) { PQfreemem(to); } -#if HAS_MEMORYVIEW if (got_view) { PyBuffer_Release(&view); } -#endif /* if the wrapped object is not bytes or a buffer, this is an error */ if (!rv && !PyErr_Occurred()) { diff --git a/psycopg/adapter_pdecimal.c b/psycopg/adapter_pdecimal.c index 2b839f7d..efd72a8f 100644 --- a/psycopg/adapter_pdecimal.c +++ b/psycopg/adapter_pdecimal.c @@ -80,7 +80,7 @@ pdecimal_getquoted(pdecimalObject *self, PyObject *args) /* res may be unicode and may suffer for issue #57 */ output: -#if PY_MAJOR_VERSION > 2 +#if PY_3 /* unicode to bytes in Py3 */ { PyObject *tmp = PyUnicode_AsUTF8String(res); diff --git a/psycopg/adapter_pfloat.c b/psycopg/adapter_pfloat.c index 3dbc8efe..5ddbe3f4 100644 --- a/psycopg/adapter_pfloat.c +++ b/psycopg/adapter_pfloat.c @@ -53,7 +53,7 @@ pfloat_getquoted(pfloatObject *self, PyObject *args) goto exit; } -#if PY_MAJOR_VERSION > 2 +#if PY_3 /* unicode to bytes in Py3 */ { PyObject *tmp = PyUnicode_AsUTF8String(rv); diff --git a/psycopg/adapter_pint.c b/psycopg/adapter_pint.c index b2b869fa..950b6557 100644 --- a/psycopg/adapter_pint.c +++ b/psycopg/adapter_pint.c @@ -40,7 +40,7 @@ pint_getquoted(pintObject *self, PyObject *args) /* Convert subclass to int to handle IntEnum and other subclasses * whose str() is not the number. */ if (PyLong_CheckExact(self->wrapped) -#if PY_MAJOR_VERSION < 2 +#if PY_2 || PyInt_CheckExact(self->wrapped) #endif ) { @@ -59,7 +59,7 @@ pint_getquoted(pintObject *self, PyObject *args) goto exit; } -#if PY_MAJOR_VERSION > 2 +#if PY_3 /* unicode to bytes in Py3 */ { PyObject *tmp = PyUnicode_AsUTF8String(res); diff --git a/psycopg/lobject_int.c b/psycopg/lobject_int.c index 765f3843..ebfd697e 100644 --- a/psycopg/lobject_int.c +++ b/psycopg/lobject_int.c @@ -87,7 +87,7 @@ _lobject_parse_mode(const char *mode) pos += 1; break; default: -#if PY_MAJOR_VERSION < 3 +#if PY_2 rv |= LOBJECT_BINARY; #else rv |= LOBJECT_TEXT; diff --git a/psycopg/microprotocols.c b/psycopg/microprotocols.c index 54ce23ed..4f4fe806 100644 --- a/psycopg/microprotocols.c +++ b/psycopg/microprotocols.c @@ -94,7 +94,7 @@ _get_superclass_adapter(PyObject *obj, PyObject *proto) type = Py_TYPE(obj); if (!( -#if PY_MAJOR_VERSION < 3 +#if PY_2 (Py_TPFLAGS_HAVE_CLASS & type->tp_flags) && #endif type->tp_mro)) { diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index 596ca31c..d4a3fde9 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -308,7 +308,7 @@ adapters_init(PyObject *module) if (0 > microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) { goto exit; } -#if PY_MAJOR_VERSION < 3 +#if PY_2 if (0 > microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) { goto exit; } @@ -321,7 +321,7 @@ adapters_init(PyObject *module) } /* strings */ -#if PY_MAJOR_VERSION < 3 +#if PY_2 if (0 > microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) { goto exit; } @@ -331,7 +331,7 @@ adapters_init(PyObject *module) } /* binary */ -#if PY_MAJOR_VERSION < 3 +#if PY_2 if (0 > microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) { goto exit; } @@ -341,16 +341,13 @@ adapters_init(PyObject *module) } #endif -#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6 if (0 > microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) { goto exit; } -#endif -#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7 + if (0 > microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) { goto exit; } -#endif if (0 > microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) { goto exit; @@ -1051,7 +1048,7 @@ static PyMethodDef psycopgMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; -#if PY_MAJOR_VERSION > 2 +#if PY_3 static struct PyModuleDef psycopgmodule = { PyModuleDef_HEAD_INIT, "_psycopg", @@ -1097,7 +1094,7 @@ INIT_MODULE(_psycopg)(void) if (!(psyco_null = Bytes_FromString("NULL"))) { goto exit; } /* initialize the module */ -#if PY_MAJOR_VERSION < 3 +#if PY_2 module = Py_InitModule("_psycopg", psycopgMethods); #else module = PyModule_Create(&psycopgmodule); @@ -1117,7 +1114,7 @@ INIT_MODULE(_psycopg)(void) Dprintf("psycopgmodule: module initialization complete"); exit: -#if PY_MAJOR_VERSION > 2 +#if PY_3 return module; #else return; diff --git a/psycopg/python.h b/psycopg/python.h index 3922f88e..521c5680 100644 --- a/psycopg/python.h +++ b/psycopg/python.h @@ -26,15 +26,20 @@ #ifndef PSYCOPG_PYTHON_H #define PSYCOPG_PYTHON_H 1 -#include -#if PY_MAJOR_VERSION < 3 -#include +#define PY_2 (PY_MAJOR_VERSION == 2) +#define PY_3 (PY_MAJOR_VERSION == 3) + +#if PY_2 && PY_VERSION_HEX < 0x02070000 +#error "psycopg requires Python 2.7" #endif -#if ((PY_VERSION_HEX < 0x02070000) \ - || ((PY_VERSION_HEX >= 0x03000000) \ - && (PY_VERSION_HEX < 0x03040000)) ) -# error "psycopg requires Python 2.7 or 3.4+" +#if PY_3 && PY_VERSION_HEX < 0x03040000 +#error "psycopg requires Python 3.4" +#endif + +#include +#if PY_2 +#include #endif /* hash() return size changed around version 3.2a4 on 64bit platforms. Before @@ -58,40 +63,14 @@ typedef unsigned long Py_uhash_t; #define FORMAT_CODE_SIZE_T "%zu" #endif -/* Abstract from text type. Only supported for ASCII and UTF-8 */ -#if PY_MAJOR_VERSION < 3 +#if PY_2 + #define Text_Type PyString_Type #define Text_Check(s) PyString_Check(s) #define Text_Format(f,a) PyString_Format(f,a) #define Text_FromUTF8(s) PyString_FromString(s) #define Text_FromUTF8AndSize(s,n) PyString_FromStringAndSize(s,n) -#else -#define Text_Type PyUnicode_Type -#define Text_Check(s) PyUnicode_Check(s) -#define Text_Format(f,a) PyUnicode_Format(f,a) -#define Text_FromUTF8(s) PyUnicode_FromString(s) -#define Text_FromUTF8AndSize(s,n) PyUnicode_FromStringAndSize(s,n) -#endif -#if PY_MAJOR_VERSION > 2 -#define PyInt_Type PyLong_Type -#define PyInt_Check PyLong_Check -#define PyInt_AsLong PyLong_AsLong -#define PyInt_FromLong PyLong_FromLong -#define PyInt_FromString PyLong_FromString -#define PyInt_FromSsize_t PyLong_FromSsize_t -#define PyExc_StandardError PyExc_Exception -#define PyString_FromFormat PyUnicode_FromFormat -#define Py_TPFLAGS_HAVE_ITER 0L -#define Py_TPFLAGS_HAVE_RICHCOMPARE 0L -#define Py_TPFLAGS_HAVE_WEAKREFS 0L -#ifndef PyNumber_Int -#define PyNumber_Int PyNumber_Long -#endif - -#endif /* PY_MAJOR_VERSION > 2 */ - -#if PY_MAJOR_VERSION < 3 #define Bytes_Type PyString_Type #define Bytes_Check PyString_Check #define Bytes_CheckExact PyString_CheckExact @@ -110,7 +89,33 @@ typedef unsigned long Py_uhash_t; #define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) #define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) -#else +#define INIT_MODULE(m) init ## m + +#endif /* PY_2 */ + +#if PY_3 + +#define Text_Type PyUnicode_Type +#define Text_Check(s) PyUnicode_Check(s) +#define Text_Format(f,a) PyUnicode_Format(f,a) +#define Text_FromUTF8(s) PyUnicode_FromString(s) +#define Text_FromUTF8AndSize(s,n) PyUnicode_FromStringAndSize(s,n) + +#define PyInt_Type PyLong_Type +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#define PyInt_FromLong PyLong_FromLong +#define PyInt_FromString PyLong_FromString +#define PyInt_FromSsize_t PyLong_FromSsize_t +#define PyExc_StandardError PyExc_Exception +#define PyString_FromFormat PyUnicode_FromFormat +#define Py_TPFLAGS_HAVE_ITER 0L +#define Py_TPFLAGS_HAVE_RICHCOMPARE 0L +#define Py_TPFLAGS_HAVE_WEAKREFS 0L + +#ifndef PyNumber_Int +#define PyNumber_Int PyNumber_Long +#endif #define Bytes_Type PyBytes_Type #define Bytes_Check PyBytes_Check @@ -126,15 +131,8 @@ typedef unsigned long Py_uhash_t; #define Bytes_ConcatAndDel PyBytes_ConcatAndDel #define _Bytes_Resize _PyBytes_Resize -#endif - -HIDDEN PyObject *Bytes_Format(PyObject *format, PyObject *args); - -/* Mangle the module name into the name of the module init function */ -#if PY_MAJOR_VERSION > 2 #define INIT_MODULE(m) PyInit_ ## m -#else -#define INIT_MODULE(m) init ## m -#endif + +#endif /* PY_3 */ #endif /* !defined(PSYCOPG_PYTHON_H) */ diff --git a/psycopg/typecast.c b/psycopg/typecast.c index b395add4..f75e046a 100644 --- a/psycopg/typecast.c +++ b/psycopg/typecast.c @@ -667,7 +667,7 @@ typecast_cast(PyObject *obj, const char *str, Py_ssize_t len, PyObject *curs) * Notice that this way it is about impossible to create a python * typecaster on a binary type. */ if (str) { -#if PY_MAJOR_VERSION < 3 +#if PY_2 s = PyString_FromStringAndSize(str, len); #else s = conn_decode(((cursorObject *)curs)->conn, str, len); diff --git a/psycopg/typecast_basic.c b/psycopg/typecast_basic.c index 319fea47..6179b1f7 100644 --- a/psycopg/typecast_basic.c +++ b/psycopg/typecast_basic.c @@ -25,7 +25,7 @@ /** INTEGER - cast normal integers (4 bytes) to python int **/ -#if PY_MAJOR_VERSION < 3 +#if PY_2 static PyObject * typecast_INTEGER_cast(const char *s, Py_ssize_t len, PyObject *curs) { @@ -66,7 +66,7 @@ typecast_FLOAT_cast(const char *s, Py_ssize_t len, PyObject *curs) if (s == NULL) { Py_RETURN_NONE; } if (!(str = Text_FromUTF8AndSize(s, len))) { return NULL; } -#if PY_MAJOR_VERSION < 3 +#if PY_2 flo = PyFloat_FromString(str, NULL); #else flo = PyFloat_FromString(str); @@ -102,7 +102,7 @@ typecast_UNICODE_cast(const char *s, Py_ssize_t len, PyObject *curs) /** STRING - cast strings of any type to python string **/ -#if PY_MAJOR_VERSION < 3 +#if PY_2 #define typecast_STRING_cast typecast_BYTES_cast #else #define typecast_STRING_cast typecast_UNICODE_cast diff --git a/psycopg/typecast_binary.c b/psycopg/typecast_binary.c index c7d2e755..16d91bc6 100644 --- a/psycopg/typecast_binary.c +++ b/psycopg/typecast_binary.c @@ -53,7 +53,7 @@ chunk_repr(chunkObject *self) ); } -#if PY_MAJOR_VERSION < 3 +#if PY_2 static Py_ssize_t chunk_getreadbuffer(chunkObject *self, Py_ssize_t segment, void **ptr) @@ -182,7 +182,7 @@ typecast_BINARY_cast(const char *s, Py_ssize_t l, PyObject *curs) buffer = NULL; chunk->len = (Py_ssize_t)len; -#if PY_MAJOR_VERSION < 3 +#if PY_2 if ((res = PyBuffer_FromObject((PyObject *)chunk, 0, chunk->len)) == NULL) goto exit; #else diff --git a/psycopg/utils.c b/psycopg/utils.c index 44e2a24e..d91283ec 100644 --- a/psycopg/utils.c +++ b/psycopg/utils.c @@ -197,7 +197,7 @@ psycopg_ensure_bytes(PyObject *obj) STEALS(1) PyObject * psycopg_ensure_text(PyObject *obj) { -#if PY_MAJOR_VERSION < 3 +#if PY_2 return obj; #else if (obj) { @@ -316,7 +316,7 @@ exit: PyObject * psycopg_text_from_chars_safe(const char *str, Py_ssize_t len, PyObject *decoder) { -#if PY_MAJOR_VERSION < 3 +#if PY_2 if (!str) { Py_RETURN_NONE; } diff --git a/psycopg/utils.h b/psycopg/utils.h index bb9f0c31..ab4aacdc 100644 --- a/psycopg/utils.h +++ b/psycopg/utils.h @@ -58,4 +58,7 @@ HIDDEN RAISES BORROWED PyObject *psyco_set_error( HIDDEN PyObject *psyco_GetDecimalType(void); +HIDDEN PyObject *Bytes_Format(PyObject *format, PyObject *args); + + #endif /* !defined(UTILS_H) */ diff --git a/tests/dbapi20.py b/tests/dbapi20.py index 212d0544..fe89bb0e 100644 --- a/tests/dbapi20.py +++ b/tests/dbapi20.py @@ -71,10 +71,6 @@ import sys # nothing # - Fix bugs in test_setoutputsize_basic and test_setinputsizes # -def str2bytes(sval): - if sys.version_info < (3,0) and isinstance(sval, str): - sval = sval.decode("latin1") - return sval.encode("latin1") class DatabaseAPI20Test(unittest.TestCase): ''' Test a database self.driver for DB API 2.0 compatibility. @@ -842,8 +838,8 @@ class DatabaseAPI20Test(unittest.TestCase): # self.assertEqual(str(t1),str(t2)) def test_Binary(self): - b = self.driver.Binary(str2bytes('Something')) - b = self.driver.Binary(str2bytes('')) + b = self.driver.Binary(b'Something') + b = self.driver.Binary(b'') def test_STRING(self): self.failUnless(hasattr(self.driver,'STRING'), diff --git a/tests/test_connection.py b/tests/test_connection.py index 0ad7d37e..77f3b29d 100755 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -39,7 +39,7 @@ import psycopg2.extras from psycopg2 import extensions as ext from .testutils import ( - unittest, skip_if_no_superuser, skip_before_postgres, + PY2, unittest, skip_if_no_superuser, skip_before_postgres, skip_after_postgres, skip_before_libpq, skip_after_libpq, ConnectingTestCase, skip_if_tpc_disabled, skip_if_windows, slow) @@ -404,7 +404,7 @@ class ParseDsnTestCase(ConnectingTestCase): def test_unicode_value(self): snowman = u"\u2603" d = ext.parse_dsn('dbname=' + snowman) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(d['dbname'], snowman.encode('utf8')) else: self.assertEqual(d['dbname'], snowman) diff --git a/tests/test_copy.py b/tests/test_copy.py index 05513f5a..b0490f54 100755 --- a/tests/test_copy.py +++ b/tests/test_copy.py @@ -32,7 +32,7 @@ from subprocess import Popen, PIPE import psycopg2 import psycopg2.extensions -from .testutils import skip_copy_if_green, TextIOBase +from .testutils import skip_copy_if_green, PY2, TextIOBase from .testconfig import dsn @@ -130,7 +130,7 @@ class CopyTests(ConnectingTestCase): self.conn.set_client_encoding('latin1') self._create_temp_table() # the above call closed the xn - if sys.version_info[0] < 3: + if PY2: abin = ''.join(map(chr, range(32, 127) + range(160, 256))) about = abin.decode('latin1').replace('\\', '\\\\') @@ -152,7 +152,7 @@ class CopyTests(ConnectingTestCase): self.conn.set_client_encoding('latin1') self._create_temp_table() # the above call closed the xn - if sys.version_info[0] < 3: + if PY2: abin = ''.join(map(chr, range(32, 127) + range(160, 255))) about = abin.replace('\\', '\\\\') else: @@ -173,7 +173,7 @@ class CopyTests(ConnectingTestCase): self.conn.set_client_encoding('latin1') self._create_temp_table() # the above call closed the xn - if sys.version_info[0] < 3: + if PY2: abin = ''.join(map(chr, range(32, 127) + range(160, 256))) abin = abin.decode('latin1') about = abin.replace('\\', '\\\\') diff --git a/tests/test_quote.py b/tests/test_quote.py index fe0b9cd8..cbba08c9 100755 --- a/tests/test_quote.py +++ b/tests/test_quote.py @@ -22,10 +22,9 @@ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # License for more details. -import sys from . import testutils import unittest -from .testutils import ConnectingTestCase, unichr +from .testutils import ConnectingTestCase, unichr, PY2 import psycopg2 import psycopg2.extensions @@ -79,14 +78,14 @@ class QuotingTestCase(ConnectingTestCase): data = b"""some data with \000\013 binary stuff into, 'quotes' and \\ a backslash too. """ - if sys.version_info[0] < 3: + if PY2: data += "".join(map(chr, range(256))) else: data += bytes(list(range(256))) curs = self.conn.cursor() curs.execute("SELECT %s::bytea;", (psycopg2.Binary(data),)) - if sys.version_info[0] < 3: + if PY2: res = str(curs.fetchone()[0]) else: res = curs.fetchone()[0].tobytes() @@ -124,7 +123,7 @@ class QuotingTestCase(ConnectingTestCase): def test_latin1(self): self.conn.set_client_encoding('LATIN1') curs = self.conn.cursor() - if sys.version_info[0] < 3: + if PY2: data = ''.join(map(chr, range(32, 127) + range(160, 256))) else: data = bytes(list(range(32, 127)) @@ -137,7 +136,7 @@ class QuotingTestCase(ConnectingTestCase): self.assert_(not self.conn.notices) # as unicode - if sys.version_info[0] < 3: + if PY2: psycopg2.extensions.register_type(psycopg2.extensions.UNICODE, self.conn) data = data.decode('latin1') @@ -149,7 +148,7 @@ class QuotingTestCase(ConnectingTestCase): def test_koi8(self): self.conn.set_client_encoding('KOI8') curs = self.conn.cursor() - if sys.version_info[0] < 3: + if PY2: data = ''.join(map(chr, range(32, 127) + range(128, 256))) else: data = bytes(list(range(32, 127)) @@ -162,7 +161,7 @@ class QuotingTestCase(ConnectingTestCase): self.assert_(not self.conn.notices) # as unicode - if sys.version_info[0] < 3: + if PY2: psycopg2.extensions.register_type(psycopg2.extensions.UNICODE, self.conn) data = data.decode('koi8_r') @@ -202,7 +201,7 @@ class TestQuotedIdentifier(ConnectingTestCase): def test_unicode_ident(self): snowman = u"\u2603" quoted = '"' + snowman + '"' - if sys.version_info[0] < 3: + if PY2: self.assertEqual(quote_ident(snowman, self.conn), quoted.encode('utf8')) else: self.assertEqual(quote_ident(snowman, self.conn), quoted) diff --git a/tests/test_types_basic.py b/tests/test_types_basic.py index 13d733fc..d0c0c919 100755 --- a/tests/test_types_basic.py +++ b/tests/test_types_basic.py @@ -28,13 +28,11 @@ import decimal import datetime import platform -import sys from . import testutils import unittest -from .testutils import ConnectingTestCase, long +from .testutils import PY2, long, text_type, ConnectingTestCase import psycopg2 -from psycopg2.compat import text_type from psycopg2.extensions import AsIs, adapt, register_adapter @@ -110,7 +108,7 @@ class TypesBasicTests(ConnectingTestCase): self.failUnless(str(s) == "-inf", "wrong float quoting: " + str(s)) def testBinary(self): - if sys.version_info[0] < 3: + if PY2: s = ''.join([chr(x) for x in range(256)]) b = psycopg2.Binary(s) buf = self.execute("SELECT %s::bytea AS foo", (b,)) @@ -128,7 +126,7 @@ class TypesBasicTests(ConnectingTestCase): def testBinaryEmptyString(self): # test to make sure an empty Binary is converted to an empty string - if sys.version_info[0] < 3: + if PY2: b = psycopg2.Binary('') self.assertEqual(str(b), "''::bytea") else: @@ -138,7 +136,7 @@ class TypesBasicTests(ConnectingTestCase): def testBinaryRoundTrip(self): # test to make sure buffers returned by psycopg2 are # understood by execute: - if sys.version_info[0] < 3: + if PY2: s = ''.join([chr(x) for x in range(256)]) buf = self.execute("SELECT %s::bytea AS foo", (psycopg2.Binary(s),)) buf2 = self.execute("SELECT %s::bytea AS foo", (buf,)) @@ -328,7 +326,7 @@ class TypesBasicTests(ConnectingTestCase): o1 = bytearray(range(256)) o2 = self.execute("select %s;", (o1,)) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(buffer, type(o2)) else: self.assertEqual(memoryview, type(o2)) @@ -342,7 +340,7 @@ class TypesBasicTests(ConnectingTestCase): o2 = self.execute("select %s;", (o1,)) self.assertEqual(len(o2), 0) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(buffer, type(o2)) else: self.assertEqual(memoryview, type(o2)) @@ -350,7 +348,7 @@ class TypesBasicTests(ConnectingTestCase): def testAdaptMemoryview(self): o1 = memoryview(bytearray(range(256))) o2 = self.execute("select %s;", (o1,)) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(buffer, type(o2)) else: self.assertEqual(memoryview, type(o2)) @@ -358,7 +356,7 @@ class TypesBasicTests(ConnectingTestCase): # Test with an empty buffer o1 = memoryview(bytearray([])) o2 = self.execute("select %s;", (o1,)) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(buffer, type(o2)) else: self.assertEqual(memoryview, type(o2)) @@ -513,7 +511,7 @@ class ByteaParserTest(unittest.TestCase): if rv is None: return None - if sys.version_info[0] < 3: + if PY2: return str(rv) else: return rv.tobytes() @@ -537,7 +535,7 @@ class ByteaParserTest(unittest.TestCase): buf = buf.upper() buf = '\\x' + buf rv = self.cast(buf.encode('utf8')) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(rv, ''.join(map(chr, range(256)))) else: self.assertEqual(rv, bytes(range(256))) @@ -548,7 +546,7 @@ class ByteaParserTest(unittest.TestCase): def test_full_escaped_octal(self): buf = ''.join(("\\%03o" % i) for i in range(256)) rv = self.cast(buf.encode('utf8')) - if sys.version_info[0] < 3: + if PY2: self.assertEqual(rv, ''.join(map(chr, range(256)))) else: self.assertEqual(rv, bytes(range(256))) @@ -559,7 +557,7 @@ class ByteaParserTest(unittest.TestCase): buf += ''.join('\\' + c for c in string.ascii_letters) buf += '\\\\' rv = self.cast(buf.encode('utf8')) - if sys.version_info[0] < 3: + if PY2: tgt = ''.join(map(chr, range(32))) \ + string.ascii_letters * 2 + '\\' else: diff --git a/tests/test_types_extras.py b/tests/test_types_extras.py index 66d4ddf0..2b24ce25 100755 --- a/tests/test_types_extras.py +++ b/tests/test_types_extras.py @@ -15,7 +15,6 @@ # License for more details. import re -import sys import json import uuid import warnings @@ -25,7 +24,7 @@ from functools import wraps from pickle import dumps, loads import unittest -from .testutils import (skip_if_no_uuid, skip_before_postgres, +from .testutils import (PY2, text_type, skip_if_no_uuid, skip_before_postgres, ConnectingTestCase, py3_raises_typeerror, slow, skip_from_python) import psycopg2 @@ -301,7 +300,7 @@ class HstoreTestCase(ConnectingTestCase): ok({''.join(ab): ''.join(ab)}) self.conn.set_client_encoding('latin1') - if sys.version_info[0] < 3: + if PY2: ab = map(chr, range(32, 127) + range(160, 255)) else: ab = bytes(list(range(32, 127)) + list(range(160, 255))).decode('latin1') @@ -363,7 +362,7 @@ class HstoreTestCase(ConnectingTestCase): ds.append({''.join(ab): ''.join(ab)}) self.conn.set_client_encoding('latin1') - if sys.version_info[0] < 3: + if PY2: ab = map(chr, range(32, 127) + range(160, 255)) else: ab = bytes(list(range(32, 127)) + list(range(160, 255))).decode('latin1') @@ -1352,14 +1351,12 @@ class RangeTestCase(unittest.TestCase): ] results = [] - converter = unicode if sys.version_info < (3, 0) else str - for bounds in ('()', '[]', '(]', '[)'): r = Range(0, 4, bounds=bounds) - results.append(converter(r)) + results.append(text_type(r)) r = Range(empty=True) - results.append(converter(r)) + results.append(text_type(r)) self.assertEqual(results, expected) def test_str_datetime(self): @@ -1367,13 +1364,11 @@ class RangeTestCase(unittest.TestCase): Date-Time ranges should return a human-readable string as well on string conversion. ''' - - converter = unicode if sys.version_info < (3, 0) else str tz = FixedOffsetTimezone(-5 * 60, "EST") r = DateTimeTZRange(datetime(2010, 1, 1, tzinfo=tz), datetime(2011, 1, 1, tzinfo=tz)) expected = u'[2010-01-01 00:00:00-05:00, 2011-01-01 00:00:00-05:00)' - result = converter(r) + result = text_type(r) self.assertEqual(result, expected) diff --git a/tests/testutils.py b/tests/testutils.py index 959b3dda..843bfdfb 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -36,13 +36,13 @@ from ctypes.util import find_library import psycopg2 import psycopg2.errors import psycopg2.extensions -from psycopg2.compat import text_type +from psycopg2.compat import PY2, PY3, text_type from .testconfig import green, dsn, repl_dsn # Python 2/3 compatibility -if sys.version_info[0] == 2: +if PY2: # Python 2 from StringIO import StringIO TextIOBase = object @@ -411,7 +411,7 @@ class py3_raises_typeerror(object): pass def __exit__(self, type, exc, tb): - if sys.version_info[0] >= 3: + if PY3: assert type is TypeError return True