mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-07-15 02:32:24 +03:00
Drop support for EOL Python 2.7
This commit is contained in:
parent
b05a581931
commit
6c48b63ae4
|
@ -19,8 +19,6 @@ environment:
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "37", PY_ARCH: "64"}
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "37", PY_ARCH: "64"}
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "32"}
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "32"}
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "64"}
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "64"}
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "27", PY_ARCH: "32"}
|
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "27", PY_ARCH: "64"}
|
|
||||||
|
|
||||||
OPENSSL_VERSION: "1_1_1h"
|
OPENSSL_VERSION: "1_1_1h"
|
||||||
POSTGRES_VERSION: "11_4"
|
POSTGRES_VERSION: "11_4"
|
||||||
|
|
|
@ -13,10 +13,6 @@ python:
|
||||||
- 3.7
|
- 3.7
|
||||||
- 3.8
|
- 3.8
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- python: 2.7
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- sudo apt-get install -y bc
|
- sudo apt-get install -y bc
|
||||||
- pip install -U pip setuptools wheel
|
- pip install -U pip setuptools wheel
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
from psycopg2.extensions import (
|
from psycopg2.extensions import (
|
||||||
new_type, new_array_type, register_type, register_adapter, QuotedString)
|
new_type, new_array_type, register_type, register_adapter, QuotedString)
|
||||||
from psycopg2.compat import text_type
|
|
||||||
|
|
||||||
# The module is imported on register_ipaddress
|
# The module is imported on register_ipaddress
|
||||||
ipaddress = None
|
ipaddress = None
|
||||||
|
@ -78,13 +77,13 @@ def cast_interface(s, cur=None):
|
||||||
if s is None:
|
if s is None:
|
||||||
return None
|
return None
|
||||||
# Py2 version force the use of unicode. meh.
|
# Py2 version force the use of unicode. meh.
|
||||||
return ipaddress.ip_interface(text_type(s))
|
return ipaddress.ip_interface(str(s))
|
||||||
|
|
||||||
|
|
||||||
def cast_network(s, cur=None):
|
def cast_network(s, cur=None):
|
||||||
if s is None:
|
if s is None:
|
||||||
return None
|
return None
|
||||||
return ipaddress.ip_network(text_type(s))
|
return ipaddress.ip_network(str(s))
|
||||||
|
|
||||||
|
|
||||||
def adapt_ipaddress(obj):
|
def adapt_ipaddress(obj):
|
||||||
|
|
|
@ -32,7 +32,6 @@ import json
|
||||||
|
|
||||||
from psycopg2._psycopg import ISQLQuote, QuotedString
|
from psycopg2._psycopg import ISQLQuote, QuotedString
|
||||||
from psycopg2._psycopg import new_type, new_array_type, register_type
|
from psycopg2._psycopg import new_type, new_array_type, register_type
|
||||||
from psycopg2.compat import PY2
|
|
||||||
|
|
||||||
|
|
||||||
# oids from PostgreSQL 9.2
|
# oids from PostgreSQL 9.2
|
||||||
|
@ -82,12 +81,8 @@ class Json(object):
|
||||||
qs.prepare(self._conn)
|
qs.prepare(self._conn)
|
||||||
return qs.getquoted()
|
return qs.getquoted()
|
||||||
|
|
||||||
if PY2:
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.getquoted()
|
# getquoted is binary
|
||||||
else:
|
|
||||||
def __str__(self):
|
|
||||||
# getquoted is binary in Py3
|
|
||||||
return self.getquoted().decode('ascii', 'replace')
|
return self.getquoted().decode('ascii', 'replace')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ import re
|
||||||
from psycopg2._psycopg import ProgrammingError, InterfaceError
|
from psycopg2._psycopg import ProgrammingError, InterfaceError
|
||||||
from psycopg2.extensions import ISQLQuote, adapt, register_adapter
|
from psycopg2.extensions import ISQLQuote, adapt, register_adapter
|
||||||
from psycopg2.extensions import new_type, new_array_type, register_type
|
from psycopg2.extensions import new_type, new_array_type, register_type
|
||||||
from psycopg2.compat import string_types
|
|
||||||
|
|
||||||
|
|
||||||
class Range(object):
|
class Range(object):
|
||||||
|
@ -315,7 +314,7 @@ class RangeCaster(object):
|
||||||
# an implementation detail and is not documented. It is currently used
|
# an implementation detail and is not documented. It is currently used
|
||||||
# for the numeric ranges.
|
# for the numeric ranges.
|
||||||
self.adapter = None
|
self.adapter = None
|
||||||
if isinstance(pgrange, string_types):
|
if isinstance(pgrange, str):
|
||||||
self.adapter = type(pgrange, (RangeAdapter,), {})
|
self.adapter = type(pgrange, (RangeAdapter,), {})
|
||||||
self.adapter.name = pgrange
|
self.adapter.name = pgrange
|
||||||
else:
|
else:
|
||||||
|
@ -332,7 +331,7 @@ class RangeCaster(object):
|
||||||
|
|
||||||
self.range = None
|
self.range = None
|
||||||
try:
|
try:
|
||||||
if isinstance(pyrange, string_types):
|
if isinstance(pyrange, str):
|
||||||
self.range = type(pyrange, (Range,), {})
|
self.range = type(pyrange, (Range,), {})
|
||||||
if issubclass(pyrange, Range) and pyrange is not Range:
|
if issubclass(pyrange, Range) and pyrange is not Range:
|
||||||
self.range = pyrange
|
self.range = pyrange
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
__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
|
|
|
@ -38,7 +38,7 @@ from psycopg2 import extensions as _ext
|
||||||
from .extensions import cursor as _cursor
|
from .extensions import cursor as _cursor
|
||||||
from .extensions import connection as _connection
|
from .extensions import connection as _connection
|
||||||
from .extensions import adapt as _A, quote_ident
|
from .extensions import adapt as _A, quote_ident
|
||||||
from .compat import PY2, PY3, lru_cache
|
from functools import lru_cache
|
||||||
|
|
||||||
from psycopg2._psycopg import ( # noqa
|
from psycopg2._psycopg import ( # noqa
|
||||||
REPLICATION_PHYSICAL, REPLICATION_LOGICAL,
|
REPLICATION_PHYSICAL, REPLICATION_LOGICAL,
|
||||||
|
@ -210,21 +210,6 @@ class DictRow(list):
|
||||||
self[:] = data[0]
|
self[:] = data[0]
|
||||||
self._index = data[1]
|
self._index = data[1]
|
||||||
|
|
||||||
if PY2:
|
|
||||||
iterkeys = keys
|
|
||||||
itervalues = values
|
|
||||||
iteritems = items
|
|
||||||
has_key = __contains__
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return list(self.iterkeys())
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
return tuple(self.itervalues())
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return list(self.iteritems())
|
|
||||||
|
|
||||||
|
|
||||||
class RealDictConnection(_connection):
|
class RealDictConnection(_connection):
|
||||||
"""A connection that uses `RealDictCursor` automatically."""
|
"""A connection that uses `RealDictCursor` automatically."""
|
||||||
|
@ -436,7 +421,7 @@ class LoggingConnection(_connection):
|
||||||
def _logtofile(self, msg, curs):
|
def _logtofile(self, msg, curs):
|
||||||
msg = self.filter(msg, curs)
|
msg = self.filter(msg, curs)
|
||||||
if msg:
|
if msg:
|
||||||
if PY3 and isinstance(msg, bytes):
|
if isinstance(msg, bytes):
|
||||||
msg = msg.decode(_ext.encodings[self.encoding], 'replace')
|
msg = msg.decode(_ext.encodings[self.encoding], 'replace')
|
||||||
self._logobj.write(msg + _os.linesep)
|
self._logobj.write(msg + _os.linesep)
|
||||||
|
|
||||||
|
@ -490,7 +475,7 @@ class MinTimeLoggingConnection(LoggingConnection):
|
||||||
def filter(self, msg, curs):
|
def filter(self, msg, curs):
|
||||||
t = (_time.time() - curs.timestamp) * 1000
|
t = (_time.time() - curs.timestamp) * 1000
|
||||||
if t > self._mintime:
|
if t > self._mintime:
|
||||||
if PY3 and isinstance(msg, bytes):
|
if isinstance(msg, bytes):
|
||||||
msg = msg.decode(_ext.encodings[self.encoding], 'replace')
|
msg = msg.decode(_ext.encodings[self.encoding], 'replace')
|
||||||
return msg + _os.linesep + " (execution time: %d ms)" % t
|
return msg + _os.linesep + " (execution time: %d ms)" % t
|
||||||
|
|
||||||
|
@ -993,12 +978,7 @@ def register_hstore(conn_or_curs, globally=False, unicode=False,
|
||||||
array_oid = tuple([x for x in array_oid if x])
|
array_oid = tuple([x for x in array_oid if x])
|
||||||
|
|
||||||
# create and register the typecaster
|
# create and register the typecaster
|
||||||
if PY2 and unicode:
|
HSTORE = _ext.new_type(oid, "HSTORE", HstoreAdapter.parse)
|
||||||
cast = HstoreAdapter.parse_unicode
|
|
||||||
else:
|
|
||||||
cast = HstoreAdapter.parse
|
|
||||||
|
|
||||||
HSTORE = _ext.new_type(oid, "HSTORE", cast)
|
|
||||||
_ext.register_type(HSTORE, not globally and conn_or_curs or None)
|
_ext.register_type(HSTORE, not globally and conn_or_curs or None)
|
||||||
_ext.register_adapter(dict, HstoreAdapter)
|
_ext.register_adapter(dict, HstoreAdapter)
|
||||||
|
|
||||||
|
|
11
lib/sql.py
11
lib/sql.py
|
@ -27,7 +27,6 @@
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from psycopg2 import extensions as ext
|
from psycopg2 import extensions as ext
|
||||||
from psycopg2.compat import PY3, string_types
|
|
||||||
|
|
||||||
|
|
||||||
_formatter = string.Formatter()
|
_formatter = string.Formatter()
|
||||||
|
@ -148,7 +147,7 @@ class Composed(Composable):
|
||||||
"foo", "bar"
|
"foo", "bar"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(joiner, string_types):
|
if isinstance(joiner, str):
|
||||||
joiner = SQL(joiner)
|
joiner = SQL(joiner)
|
||||||
elif not isinstance(joiner, SQL):
|
elif not isinstance(joiner, SQL):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
@ -180,7 +179,7 @@ class SQL(Composable):
|
||||||
select "foo", "bar" from "table"
|
select "foo", "bar" from "table"
|
||||||
"""
|
"""
|
||||||
def __init__(self, string):
|
def __init__(self, string):
|
||||||
if not isinstance(string, string_types):
|
if not isinstance(string, str):
|
||||||
raise TypeError("SQL values must be strings")
|
raise TypeError("SQL values must be strings")
|
||||||
super(SQL, self).__init__(string)
|
super(SQL, self).__init__(string)
|
||||||
|
|
||||||
|
@ -324,7 +323,7 @@ class Identifier(Composable):
|
||||||
raise TypeError("Identifier cannot be empty")
|
raise TypeError("Identifier cannot be empty")
|
||||||
|
|
||||||
for s in strings:
|
for s in strings:
|
||||||
if not isinstance(s, string_types):
|
if not isinstance(s, str):
|
||||||
raise TypeError("SQL identifier parts must be strings")
|
raise TypeError("SQL identifier parts must be strings")
|
||||||
|
|
||||||
super(Identifier, self).__init__(strings)
|
super(Identifier, self).__init__(strings)
|
||||||
|
@ -392,7 +391,7 @@ class Literal(Composable):
|
||||||
a.prepare(conn)
|
a.prepare(conn)
|
||||||
|
|
||||||
rv = a.getquoted()
|
rv = a.getquoted()
|
||||||
if PY3 and isinstance(rv, bytes):
|
if isinstance(rv, bytes):
|
||||||
rv = rv.decode(ext.encodings[conn.encoding])
|
rv = rv.decode(ext.encodings[conn.encoding])
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
@ -426,7 +425,7 @@ class Placeholder(Composable):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name=None):
|
def __init__(self, name=None):
|
||||||
if isinstance(name, string_types):
|
if isinstance(name, str):
|
||||||
if ')' in name:
|
if ')' in name:
|
||||||
raise ValueError("invalid name: %r" % name)
|
raise ValueError("invalid name: %r" % name)
|
||||||
|
|
||||||
|
|
|
@ -45,14 +45,12 @@ asis_getquoted(asisObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rv = PyObject_Str(self->wrapped);
|
rv = PyObject_Str(self->wrapped);
|
||||||
#if PY_3
|
/* unicode to bytes */
|
||||||
/* unicode to bytes in Py3 */
|
|
||||||
if (rv) {
|
if (rv) {
|
||||||
PyObject *tmp = PyUnicode_AsUTF8String(rv);
|
PyObject *tmp = PyUnicode_AsUTF8String(rv);
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
rv = tmp;
|
rv = tmp;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -76,15 +76,6 @@ binary_quote(binaryObject *self)
|
||||||
buffer_len = view.len;
|
buffer_len = view.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_2
|
|
||||||
if (!buffer && (Bytes_Check(self->wrapped) || PyBuffer_Check(self->wrapped))) {
|
|
||||||
if (PyObject_AsReadBuffer(self->wrapped, (const void **)&buffer,
|
|
||||||
&buffer_len) < 0) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,8 +81,7 @@ pdecimal_getquoted(pdecimalObject *self, PyObject *args)
|
||||||
/* res may be unicode and may suffer for issue #57 */
|
/* res may be unicode and may suffer for issue #57 */
|
||||||
output:
|
output:
|
||||||
|
|
||||||
#if PY_3
|
/* unicode to bytes */
|
||||||
/* unicode to bytes in Py3 */
|
|
||||||
{
|
{
|
||||||
PyObject *tmp = PyUnicode_AsUTF8String(res);
|
PyObject *tmp = PyUnicode_AsUTF8String(res);
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
|
@ -90,7 +89,6 @@ output:
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ('-' == Bytes_AS_STRING(res)[0]) {
|
if ('-' == Bytes_AS_STRING(res)[0]) {
|
||||||
/* Prepend a space in front of negative numbers (ticket #57) */
|
/* Prepend a space in front of negative numbers (ticket #57) */
|
||||||
|
|
|
@ -54,8 +54,7 @@ pfloat_getquoted(pfloatObject *self, PyObject *args)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_3
|
/* unicode to bytes */
|
||||||
/* unicode to bytes in Py3 */
|
|
||||||
{
|
{
|
||||||
PyObject *tmp = PyUnicode_AsUTF8String(rv);
|
PyObject *tmp = PyUnicode_AsUTF8String(rv);
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
|
@ -63,7 +62,6 @@ pfloat_getquoted(pfloatObject *self, PyObject *args)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ('-' == Bytes_AS_STRING(rv)[0]) {
|
if ('-' == Bytes_AS_STRING(rv)[0]) {
|
||||||
/* Prepend a space in front of negative numbers (ticket #57) */
|
/* Prepend a space in front of negative numbers (ticket #57) */
|
||||||
|
|
|
@ -40,11 +40,7 @@ pint_getquoted(pintObject *self, PyObject *args)
|
||||||
|
|
||||||
/* Convert subclass to int to handle IntEnum and other subclasses
|
/* Convert subclass to int to handle IntEnum and other subclasses
|
||||||
* whose str() is not the number. */
|
* whose str() is not the number. */
|
||||||
if (PyLong_CheckExact(self->wrapped)
|
if (PyLong_CheckExact(self->wrapped)) {
|
||||||
#if PY_2
|
|
||||||
|| PyInt_CheckExact(self->wrapped)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
res = PyObject_Str(self->wrapped);
|
res = PyObject_Str(self->wrapped);
|
||||||
} else {
|
} else {
|
||||||
PyObject *tmp;
|
PyObject *tmp;
|
||||||
|
@ -60,8 +56,7 @@ pint_getquoted(pintObject *self, PyObject *args)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_3
|
/* unicode to bytes */
|
||||||
/* unicode to bytes in Py3 */
|
|
||||||
{
|
{
|
||||||
PyObject *tmp = PyUnicode_AsUTF8String(res);
|
PyObject *tmp = PyUnicode_AsUTF8String(res);
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
|
@ -69,7 +64,6 @@ pint_getquoted(pintObject *self, PyObject *args)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ('-' == Bytes_AS_STRING(res)[0]) {
|
if ('-' == Bytes_AS_STRING(res)[0]) {
|
||||||
/* Prepend a space in front of negative numbers (ticket #57) */
|
/* Prepend a space in front of negative numbers (ticket #57) */
|
||||||
|
|
|
@ -85,11 +85,7 @@ _lobject_parse_mode(const char *mode)
|
||||||
pos += 1;
|
pos += 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#if PY_2
|
|
||||||
rv |= LOBJECT_BINARY;
|
|
||||||
#else
|
|
||||||
rv |= LOBJECT_TEXT;
|
rv |= LOBJECT_TEXT;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,11 +92,7 @@ _get_superclass_adapter(PyObject *obj, PyObject *proto)
|
||||||
Py_ssize_t i, ii;
|
Py_ssize_t i, ii;
|
||||||
|
|
||||||
type = Py_TYPE(obj);
|
type = Py_TYPE(obj);
|
||||||
if (!(
|
if (!(type->tp_mro)) {
|
||||||
#if PY_2
|
|
||||||
(Py_TPFLAGS_HAVE_CLASS & type->tp_flags) &&
|
|
||||||
#endif
|
|
||||||
type->tp_mro)) {
|
|
||||||
/* has no mro */
|
/* has no mro */
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,11 +309,6 @@ adapters_init(PyObject *module)
|
||||||
if (0 > microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) {
|
if (0 > microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
#if PY_2
|
|
||||||
if (0 > microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (0 > microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) {
|
if (0 > microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -322,25 +317,14 @@ adapters_init(PyObject *module)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* strings */
|
/* strings */
|
||||||
#if PY_2
|
|
||||||
if (0 > microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (0 > microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) {
|
if (0 > microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* binary */
|
/* binary */
|
||||||
#if PY_2
|
|
||||||
if (0 > microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (0 > microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) {
|
if (0 > microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (0 > microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) {
|
if (0 > microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -1049,7 +1033,6 @@ static PyMethodDef psycopgMethods[] = {
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PY_3
|
|
||||||
static struct PyModuleDef psycopgmodule = {
|
static struct PyModuleDef psycopgmodule = {
|
||||||
PyModuleDef_HEAD_INIT,
|
PyModuleDef_HEAD_INIT,
|
||||||
"_psycopg",
|
"_psycopg",
|
||||||
|
@ -1061,7 +1044,6 @@ static struct PyModuleDef psycopgmodule = {
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
|
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
|
||||||
#define PyMODINIT_FUNC void
|
#define PyMODINIT_FUNC void
|
||||||
|
@ -1095,11 +1077,7 @@ INIT_MODULE(_psycopg)(void)
|
||||||
if (!(psyco_null = Bytes_FromString("NULL"))) { goto exit; }
|
if (!(psyco_null = Bytes_FromString("NULL"))) { goto exit; }
|
||||||
|
|
||||||
/* initialize the module */
|
/* initialize the module */
|
||||||
#if PY_2
|
|
||||||
module = Py_InitModule("_psycopg", psycopgMethods);
|
|
||||||
#else
|
|
||||||
module = PyModule_Create(&psycopgmodule);
|
module = PyModule_Create(&psycopgmodule);
|
||||||
#endif
|
|
||||||
if (!module) { goto exit; }
|
if (!module) { goto exit; }
|
||||||
|
|
||||||
if (0 > add_module_constants(module)) { goto exit; }
|
if (0 > add_module_constants(module)) { goto exit; }
|
||||||
|
@ -1115,9 +1093,5 @@ INIT_MODULE(_psycopg)(void)
|
||||||
Dprintf("psycopgmodule: module initialization complete");
|
Dprintf("psycopgmodule: module initialization complete");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
#if PY_3
|
|
||||||
return module;
|
return module;
|
||||||
#else
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,30 +27,11 @@
|
||||||
#ifndef PSYCOPG_PYTHON_H
|
#ifndef PSYCOPG_PYTHON_H
|
||||||
#define PSYCOPG_PYTHON_H 1
|
#define PSYCOPG_PYTHON_H 1
|
||||||
|
|
||||||
#define PY_2 (PY_MAJOR_VERSION == 2)
|
#if PY_VERSION_HEX < 0x03060000
|
||||||
#define PY_3 (PY_MAJOR_VERSION == 3)
|
|
||||||
|
|
||||||
#if PY_2 && PY_VERSION_HEX < 0x02070000
|
|
||||||
#error "psycopg requires Python 2.7"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PY_3 && PY_VERSION_HEX < 0x03060000
|
|
||||||
#error "psycopg requires Python 3.6"
|
#error "psycopg requires Python 3.6"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <structmember.h>
|
#include <structmember.h>
|
||||||
#if PY_2
|
|
||||||
#include <stringobject.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* hash() return size changed around version 3.2a4 on 64bit platforms. Before
|
|
||||||
* this, the return size was always a long, regardless of arch. ~3.2
|
|
||||||
* introduced the Py_hash_t & Py_uhash_t typedefs with the resulting sizes
|
|
||||||
* based upon arch. */
|
|
||||||
#if PY_VERSION_HEX < 0x030200A4
|
|
||||||
typedef long Py_hash_t;
|
|
||||||
typedef unsigned long Py_uhash_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Since Py_TYPE() is changed to the inline static function,
|
/* Since Py_TYPE() is changed to the inline static function,
|
||||||
* Py_TYPE(obj) = new_type must be replaced with Py_SET_TYPE(obj, new_type)
|
* Py_TYPE(obj) = new_type must be replaced with Py_SET_TYPE(obj, new_type)
|
||||||
|
@ -72,43 +53,6 @@ typedef unsigned long Py_uhash_t;
|
||||||
#define FORMAT_CODE_SIZE_T "%zu"
|
#define FORMAT_CODE_SIZE_T "%zu"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
#define Bytes_Type PyString_Type
|
|
||||||
#define Bytes_Check PyString_Check
|
|
||||||
#define Bytes_CheckExact PyString_CheckExact
|
|
||||||
#define Bytes_AS_STRING PyString_AS_STRING
|
|
||||||
#define Bytes_GET_SIZE PyString_GET_SIZE
|
|
||||||
#define Bytes_Size PyString_Size
|
|
||||||
#define Bytes_AsString PyString_AsString
|
|
||||||
#define Bytes_AsStringAndSize PyString_AsStringAndSize
|
|
||||||
#define Bytes_FromString PyString_FromString
|
|
||||||
#define Bytes_FromStringAndSize PyString_FromStringAndSize
|
|
||||||
#define Bytes_FromFormat PyString_FromFormat
|
|
||||||
#define Bytes_ConcatAndDel PyString_ConcatAndDel
|
|
||||||
#define _Bytes_Resize _PyString_Resize
|
|
||||||
|
|
||||||
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
|
|
||||||
#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds)
|
|
||||||
#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds)
|
|
||||||
|
|
||||||
#define INIT_MODULE(m) init ## m
|
|
||||||
|
|
||||||
/* fix #961, but don't change all types to longs. Sure someone will complain. */
|
|
||||||
#define PyLong_FromOid(x) (((x) & 0x80000000) ? \
|
|
||||||
PyLong_FromUnsignedLong((unsigned long)(x)) : \
|
|
||||||
PyInt_FromLong((x)))
|
|
||||||
|
|
||||||
#endif /* PY_2 */
|
|
||||||
|
|
||||||
#if PY_3
|
|
||||||
|
|
||||||
#define Text_Type PyUnicode_Type
|
#define Text_Type PyUnicode_Type
|
||||||
#define Text_Check(s) PyUnicode_Check(s)
|
#define Text_Check(s) PyUnicode_Check(s)
|
||||||
#define Text_Format(f,a) PyUnicode_Format(f,a)
|
#define Text_Format(f,a) PyUnicode_Format(f,a)
|
||||||
|
@ -149,8 +93,6 @@ typedef unsigned long Py_uhash_t;
|
||||||
|
|
||||||
#define PyLong_FromOid(x) (PyLong_FromUnsignedLong((unsigned long)(x)))
|
#define PyLong_FromOid(x) (PyLong_FromUnsignedLong((unsigned long)(x)))
|
||||||
|
|
||||||
#endif /* PY_3 */
|
|
||||||
|
|
||||||
/* expose Oid attributes in Python C objects */
|
/* expose Oid attributes in Python C objects */
|
||||||
#define T_OID T_UINT
|
#define T_OID T_UINT
|
||||||
|
|
||||||
|
|
|
@ -475,11 +475,7 @@ PyTypeObject typecastType = {
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
0, /*tp_getattr*/
|
0, /*tp_getattr*/
|
||||||
0, /*tp_setattr*/
|
0, /*tp_setattr*/
|
||||||
#if PY_VERSION_HEX < 0x03000000
|
|
||||||
typecast_cmp, /*tp_compare*/
|
|
||||||
#else
|
|
||||||
0, /*tp_reserved*/
|
0, /*tp_reserved*/
|
||||||
#endif
|
|
||||||
typecast_repr, /*tp_repr*/
|
typecast_repr, /*tp_repr*/
|
||||||
0, /*tp_as_number*/
|
0, /*tp_as_number*/
|
||||||
0, /*tp_as_sequence*/
|
0, /*tp_as_sequence*/
|
||||||
|
@ -651,11 +647,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
|
* Notice that this way it is about impossible to create a python
|
||||||
* typecaster on a binary type. */
|
* typecaster on a binary type. */
|
||||||
if (str) {
|
if (str) {
|
||||||
#if PY_2
|
|
||||||
s = PyString_FromStringAndSize(str, len);
|
|
||||||
#else
|
|
||||||
s = conn_decode(((cursorObject *)curs)->conn, str, len);
|
s = conn_decode(((cursorObject *)curs)->conn, str, len);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
|
|
|
@ -26,22 +26,7 @@
|
||||||
|
|
||||||
/** INTEGER - cast normal integers (4 bytes) to python int **/
|
/** INTEGER - cast normal integers (4 bytes) to python int **/
|
||||||
|
|
||||||
#if PY_2
|
|
||||||
static PyObject *
|
|
||||||
typecast_INTEGER_cast(const char *s, Py_ssize_t len, PyObject *curs)
|
|
||||||
{
|
|
||||||
char buffer[12];
|
|
||||||
|
|
||||||
if (s == NULL) { Py_RETURN_NONE; }
|
|
||||||
if (s[len] != '\0') {
|
|
||||||
strncpy(buffer, s, (size_t) len); buffer[len] = '\0';
|
|
||||||
s = buffer;
|
|
||||||
}
|
|
||||||
return PyInt_FromString((char *)s, NULL, 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define typecast_INTEGER_cast typecast_LONGINTEGER_cast
|
#define typecast_INTEGER_cast typecast_LONGINTEGER_cast
|
||||||
#endif
|
|
||||||
|
|
||||||
/** LONGINTEGER - cast long integers (8 bytes) to python long **/
|
/** LONGINTEGER - cast long integers (8 bytes) to python long **/
|
||||||
|
|
||||||
|
@ -67,11 +52,7 @@ typecast_FLOAT_cast(const char *s, Py_ssize_t len, PyObject *curs)
|
||||||
|
|
||||||
if (s == NULL) { Py_RETURN_NONE; }
|
if (s == NULL) { Py_RETURN_NONE; }
|
||||||
if (!(str = Text_FromUTF8AndSize(s, len))) { return NULL; }
|
if (!(str = Text_FromUTF8AndSize(s, len))) { return NULL; }
|
||||||
#if PY_2
|
|
||||||
flo = PyFloat_FromString(str, NULL);
|
|
||||||
#else
|
|
||||||
flo = PyFloat_FromString(str);
|
flo = PyFloat_FromString(str);
|
||||||
#endif
|
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
return flo;
|
return flo;
|
||||||
}
|
}
|
||||||
|
@ -103,11 +84,7 @@ typecast_UNICODE_cast(const char *s, Py_ssize_t len, PyObject *curs)
|
||||||
|
|
||||||
/** STRING - cast strings of any type to python string **/
|
/** STRING - cast strings of any type to python string **/
|
||||||
|
|
||||||
#if PY_2
|
|
||||||
#define typecast_STRING_cast typecast_BYTES_cast
|
|
||||||
#else
|
|
||||||
#define typecast_STRING_cast typecast_UNICODE_cast
|
#define typecast_STRING_cast typecast_UNICODE_cast
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/** BOOLEAN - cast boolean value into right python object **/
|
/** BOOLEAN - cast boolean value into right python object **/
|
||||||
|
|
|
@ -54,39 +54,6 @@ chunk_repr(chunkObject *self)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_2
|
|
||||||
|
|
||||||
static Py_ssize_t
|
|
||||||
chunk_getreadbuffer(chunkObject *self, Py_ssize_t segment, void **ptr)
|
|
||||||
{
|
|
||||||
if (segment != 0)
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_SystemError,
|
|
||||||
"accessing non-existant buffer segment");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*ptr = self->base;
|
|
||||||
return self->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Py_ssize_t
|
|
||||||
chunk_getsegcount(chunkObject *self, Py_ssize_t *lenp)
|
|
||||||
{
|
|
||||||
if (lenp != NULL)
|
|
||||||
*lenp = self->len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyBufferProcs chunk_as_buffer =
|
|
||||||
{
|
|
||||||
(readbufferproc) chunk_getreadbuffer,
|
|
||||||
(writebufferproc) NULL,
|
|
||||||
(segcountproc) chunk_getsegcount,
|
|
||||||
(charbufferproc) NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* 3.0 buffer interface */
|
/* 3.0 buffer interface */
|
||||||
int chunk_getbuffer(PyObject *_self, Py_buffer *view, int flags)
|
int chunk_getbuffer(PyObject *_self, Py_buffer *view, int flags)
|
||||||
{
|
{
|
||||||
|
@ -105,8 +72,6 @@ static PyBufferProcs chunk_as_buffer =
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define chunk_doc "memory chunk"
|
#define chunk_doc "memory chunk"
|
||||||
|
|
||||||
PyTypeObject chunkType = {
|
PyTypeObject chunkType = {
|
||||||
|
@ -183,13 +148,8 @@ typecast_BINARY_cast(const char *s, Py_ssize_t l, PyObject *curs)
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
chunk->len = (Py_ssize_t)len;
|
chunk->len = (Py_ssize_t)len;
|
||||||
|
|
||||||
#if PY_2
|
|
||||||
if ((res = PyBuffer_FromObject((PyObject *)chunk, 0, chunk->len)) == NULL)
|
|
||||||
goto exit;
|
|
||||||
#else
|
|
||||||
if ((res = PyMemoryView_FromObject((PyObject*)chunk)) == NULL)
|
if ((res = PyMemoryView_FromObject((PyObject*)chunk)) == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
#endif
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF((PyObject *)chunk);
|
Py_XDECREF((PyObject *)chunk);
|
||||||
|
|
|
@ -190,7 +190,7 @@ psyco_ensure_bytes(PyObject *obj)
|
||||||
|
|
||||||
/* Take a Python object and return text from it.
|
/* Take a Python object and return text from it.
|
||||||
*
|
*
|
||||||
* On Py3 this means converting bytes to unicode. On Py2 bytes are fine.
|
* This means converting bytes to unicode.
|
||||||
*
|
*
|
||||||
* The function is ref neutral: steals a ref from obj and adds one to the
|
* The function is ref neutral: steals a ref from obj and adds one to the
|
||||||
* return value. It is safe to call it on NULL.
|
* return value. It is safe to call it on NULL.
|
||||||
|
@ -198,9 +198,6 @@ psyco_ensure_bytes(PyObject *obj)
|
||||||
STEALS(1) PyObject *
|
STEALS(1) PyObject *
|
||||||
psyco_ensure_text(PyObject *obj)
|
psyco_ensure_text(PyObject *obj)
|
||||||
{
|
{
|
||||||
#if PY_2
|
|
||||||
return obj;
|
|
||||||
#else
|
|
||||||
if (obj) {
|
if (obj) {
|
||||||
/* bytes to unicode in Py3 */
|
/* bytes to unicode in Py3 */
|
||||||
PyObject *rv = PyUnicode_FromEncodedObject(obj, "utf8", "replace");
|
PyObject *rv = PyUnicode_FromEncodedObject(obj, "utf8", "replace");
|
||||||
|
@ -210,7 +207,6 @@ psyco_ensure_text(PyObject *obj)
|
||||||
else {
|
else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if a file derives from TextIOBase.
|
/* Check if a file derives from TextIOBase.
|
||||||
|
@ -309,24 +305,13 @@ exit:
|
||||||
|
|
||||||
/* Convert a C string into Python Text using a specified codec.
|
/* Convert a C string into Python Text using a specified codec.
|
||||||
*
|
*
|
||||||
* The codec is the python function codec.getdecoder(enc). It is only used on
|
* The codec is the python function codec.getdecoder(enc).
|
||||||
* Python 3 to return unicode: in Py2 the function returns a string.
|
|
||||||
*
|
*
|
||||||
* len is optional: use -1 to have it calculated by the function.
|
* len is optional: use -1 to have it calculated by the function.
|
||||||
*/
|
*/
|
||||||
PyObject *
|
PyObject *
|
||||||
psyco_text_from_chars_safe(const char *str, Py_ssize_t len, PyObject *decoder)
|
psyco_text_from_chars_safe(const char *str, Py_ssize_t len, PyObject *decoder)
|
||||||
{
|
{
|
||||||
#if PY_2
|
|
||||||
|
|
||||||
if (!str) { Py_RETURN_NONE; }
|
|
||||||
|
|
||||||
if (len < 0) { len = strlen(str); }
|
|
||||||
|
|
||||||
return PyString_FromStringAndSize(str, len);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static PyObject *replace = NULL;
|
static PyObject *replace = NULL;
|
||||||
PyObject *rv = NULL;
|
PyObject *rv = NULL;
|
||||||
PyObject *b = NULL;
|
PyObject *b = NULL;
|
||||||
|
@ -356,8 +341,6 @@ exit:
|
||||||
Py_XDECREF(t);
|
Py_XDECREF(t);
|
||||||
Py_XDECREF(b);
|
Py_XDECREF(b);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
38
setup.py
38
setup.py
|
@ -26,8 +26,6 @@ UPDATEs. psycopg2 also provide full asynchronous operations and support
|
||||||
for coroutine libraries.
|
for coroutine libraries.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Note: The setup.py must be compatible with both Python 2 and 3
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -38,7 +36,6 @@ from distutils.command.build_ext import build_ext
|
||||||
from distutils.sysconfig import get_python_inc
|
from distutils.sysconfig import get_python_inc
|
||||||
from distutils.ccompiler import get_default_compiler
|
from distutils.ccompiler import get_default_compiler
|
||||||
from distutils.errors import CompileError
|
from distutils.errors import CompileError
|
||||||
from distutils.util import get_platform
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import configparser
|
import configparser
|
||||||
|
@ -58,13 +55,12 @@ Development Status :: 5 - Production/Stable
|
||||||
Intended Audience :: Developers
|
Intended Audience :: Developers
|
||||||
License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
|
License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
|
||||||
Programming Language :: Python
|
Programming Language :: Python
|
||||||
Programming Language :: Python :: 2
|
|
||||||
Programming Language :: Python :: 2.7
|
|
||||||
Programming Language :: Python :: 3
|
Programming Language :: Python :: 3
|
||||||
Programming Language :: Python :: 3.6
|
Programming Language :: Python :: 3.6
|
||||||
Programming Language :: Python :: 3.7
|
Programming Language :: Python :: 3.7
|
||||||
Programming Language :: Python :: 3.8
|
Programming Language :: Python :: 3.8
|
||||||
Programming Language :: Python :: 3.9
|
Programming Language :: Python :: 3.9
|
||||||
|
Programming Language :: Python :: 3 :: Only
|
||||||
Programming Language :: Python :: Implementation :: CPython
|
Programming Language :: Python :: Implementation :: CPython
|
||||||
Programming Language :: C
|
Programming Language :: C
|
||||||
Programming Language :: SQL
|
Programming Language :: SQL
|
||||||
|
@ -201,12 +197,6 @@ For further information please check the 'doc/src/install.rst' file (also at
|
||||||
if not os.path.exists(pg_config_path):
|
if not os.path.exists(pg_config_path):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Support unicode paths, if this version of Python provides the
|
|
||||||
# necessary infrastructure:
|
|
||||||
if sys.version_info[0] < 3:
|
|
||||||
pg_config_path = pg_config_path.encode(
|
|
||||||
sys.getfilesystemencoding())
|
|
||||||
|
|
||||||
return pg_config_path
|
return pg_config_path
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,30 +297,6 @@ For further information please check the 'doc/src/install.rst' file (also at
|
||||||
""")
|
""")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
sysVer = sys.version_info[:2]
|
|
||||||
|
|
||||||
# For Python versions that use MSVC compiler 2008, re-insert the
|
|
||||||
# manifest into the resulting .pyd file.
|
|
||||||
if self.compiler_is_msvc() and sysVer == (2, 7):
|
|
||||||
platform = get_platform()
|
|
||||||
# Default to the x86 manifest
|
|
||||||
manifest = '_psycopg.vc9.x86.manifest'
|
|
||||||
if platform == 'win-amd64':
|
|
||||||
manifest = '_psycopg.vc9.amd64.manifest'
|
|
||||||
try:
|
|
||||||
ext_path = self.get_ext_fullpath(extension.name)
|
|
||||||
except AttributeError:
|
|
||||||
ext_path = os.path.join(self.build_lib,
|
|
||||||
'psycopg2', '_psycopg.pyd')
|
|
||||||
# Make sure spawn() will work if compile() was never
|
|
||||||
# called. https://github.com/psycopg/psycopg2/issues/380
|
|
||||||
if not self.compiler.initialized:
|
|
||||||
self.compiler.initialize()
|
|
||||||
self.compiler.spawn(
|
|
||||||
['mt.exe', '-nologo', '-manifest',
|
|
||||||
os.path.join('psycopg', manifest),
|
|
||||||
'-outputresource:%s;2' % ext_path])
|
|
||||||
|
|
||||||
def finalize_win32(self):
|
def finalize_win32(self):
|
||||||
"""Finalize build system configuration on win32 platform."""
|
"""Finalize build system configuration on win32 platform."""
|
||||||
|
|
||||||
|
@ -598,7 +564,7 @@ setup(name="psycopg2",
|
||||||
url="https://psycopg.org/",
|
url="https://psycopg.org/",
|
||||||
license="LGPL with exceptions",
|
license="LGPL with exceptions",
|
||||||
platforms=["any"],
|
platforms=["any"],
|
||||||
python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*',
|
python_requires='>=3.6',
|
||||||
description=readme.split("\n")[0],
|
description=readme.split("\n")[0],
|
||||||
long_description="\n".join(readme.split("\n")[2:]).lstrip(),
|
long_description="\n".join(readme.split("\n")[2:]).lstrip(),
|
||||||
classifiers=[x for x in classifiers.split("\n") if x],
|
classifiers=[x for x in classifiers.split("\n") if x],
|
||||||
|
|
|
@ -58,9 +58,6 @@ from . import test_types_basic
|
||||||
from . import test_types_extras
|
from . import test_types_extras
|
||||||
from . import test_with
|
from . import test_with
|
||||||
|
|
||||||
if sys.version_info[:2] < (3, 6):
|
|
||||||
from . import test_async_keyword
|
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
# If connection to test db fails, bail out early.
|
# If connection to test db fails, bail out early.
|
||||||
|
@ -76,8 +73,6 @@ def test_suite():
|
||||||
|
|
||||||
suite = unittest.TestSuite()
|
suite = unittest.TestSuite()
|
||||||
suite.addTest(test_async.test_suite())
|
suite.addTest(test_async.test_suite())
|
||||||
if sys.version_info[:2] < (3, 6):
|
|
||||||
suite.addTest(test_async_keyword.test_suite())
|
|
||||||
suite.addTest(test_bugX000.test_suite())
|
suite.addTest(test_bugX000.test_suite())
|
||||||
suite.addTest(test_bug_gc.test_suite())
|
suite.addTest(test_bug_gc.test_suite())
|
||||||
suite.addTest(test_cancel.test_suite())
|
suite.addTest(test_cancel.test_suite())
|
||||||
|
|
|
@ -185,13 +185,8 @@ class DatabaseAPI20Test(unittest.TestCase):
|
||||||
def test_Exceptions(self):
|
def test_Exceptions(self):
|
||||||
# Make sure required exceptions exist, and are in the
|
# Make sure required exceptions exist, and are in the
|
||||||
# defined hierarchy.
|
# defined hierarchy.
|
||||||
if sys.version[0] == '3': #under Python 3 StardardError no longer exists
|
|
||||||
self.failUnless(issubclass(self.driver.Warning,Exception))
|
self.failUnless(issubclass(self.driver.Warning,Exception))
|
||||||
self.failUnless(issubclass(self.driver.Error,Exception))
|
self.failUnless(issubclass(self.driver.Error,Exception))
|
||||||
else:
|
|
||||||
self.failUnless(issubclass(self.driver.Warning,StandardError))
|
|
||||||
self.failUnless(issubclass(self.driver.Error,StandardError))
|
|
||||||
|
|
||||||
self.failUnless(
|
self.failUnless(
|
||||||
issubclass(self.driver.InterfaceError,self.driver.Error)
|
issubclass(self.driver.InterfaceError,self.driver.Error)
|
||||||
)
|
)
|
||||||
|
|
|
@ -42,7 +42,7 @@ import psycopg2.extras
|
||||||
from psycopg2 import extensions as ext
|
from psycopg2 import extensions as ext
|
||||||
|
|
||||||
from .testutils import (
|
from .testutils import (
|
||||||
PY2, unittest, skip_if_no_superuser, skip_before_postgres,
|
unittest, skip_if_no_superuser, skip_before_postgres,
|
||||||
skip_after_postgres, skip_before_libpq, skip_after_libpq,
|
skip_after_postgres, skip_before_libpq, skip_after_libpq,
|
||||||
ConnectingTestCase, skip_if_tpc_disabled, skip_if_windows, slow,
|
ConnectingTestCase, skip_if_tpc_disabled, skip_if_windows, slow,
|
||||||
skip_if_crdb, crdb_version)
|
skip_if_crdb, crdb_version)
|
||||||
|
@ -466,9 +466,6 @@ class ParseDsnTestCase(ConnectingTestCase):
|
||||||
def test_unicode_value(self):
|
def test_unicode_value(self):
|
||||||
snowman = u"\u2603"
|
snowman = u"\u2603"
|
||||||
d = ext.parse_dsn('dbname=' + snowman)
|
d = ext.parse_dsn('dbname=' + snowman)
|
||||||
if PY2:
|
|
||||||
self.assertEqual(d['dbname'], snowman.encode('utf8'))
|
|
||||||
else:
|
|
||||||
self.assertEqual(d['dbname'], snowman)
|
self.assertEqual(d['dbname'], snowman)
|
||||||
|
|
||||||
def test_unicode_key(self):
|
def test_unicode_key(self):
|
||||||
|
|
|
@ -34,7 +34,7 @@ from subprocess import Popen, PIPE
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import psycopg2.extensions
|
import psycopg2.extensions
|
||||||
from .testutils import skip_copy_if_green, PY2, TextIOBase
|
from .testutils import skip_copy_if_green, TextIOBase
|
||||||
from .testconfig import dsn
|
from .testconfig import dsn
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,11 +133,6 @@ class CopyTests(ConnectingTestCase):
|
||||||
self.conn.set_client_encoding('latin1')
|
self.conn.set_client_encoding('latin1')
|
||||||
self._create_temp_table() # the above call closed the xn
|
self._create_temp_table() # the above call closed the xn
|
||||||
|
|
||||||
if PY2:
|
|
||||||
abin = ''.join(map(chr, range(32, 127) + range(160, 256)))
|
|
||||||
about = abin.decode('latin1').replace('\\', '\\\\')
|
|
||||||
|
|
||||||
else:
|
|
||||||
abin = bytes(list(range(32, 127))
|
abin = bytes(list(range(32, 127))
|
||||||
+ list(range(160, 256))).decode('latin1')
|
+ list(range(160, 256))).decode('latin1')
|
||||||
about = abin.replace('\\', '\\\\')
|
about = abin.replace('\\', '\\\\')
|
||||||
|
@ -155,10 +150,6 @@ class CopyTests(ConnectingTestCase):
|
||||||
self.conn.set_client_encoding('latin1')
|
self.conn.set_client_encoding('latin1')
|
||||||
self._create_temp_table() # the above call closed the xn
|
self._create_temp_table() # the above call closed the xn
|
||||||
|
|
||||||
if PY2:
|
|
||||||
abin = ''.join(map(chr, range(32, 127) + range(160, 255)))
|
|
||||||
about = abin.replace('\\', '\\\\')
|
|
||||||
else:
|
|
||||||
abin = bytes(list(range(32, 127))
|
abin = bytes(list(range(32, 127))
|
||||||
+ list(range(160, 255))).decode('latin1')
|
+ list(range(160, 255))).decode('latin1')
|
||||||
about = abin.replace('\\', '\\\\').encode('latin1')
|
about = abin.replace('\\', '\\\\').encode('latin1')
|
||||||
|
@ -176,12 +167,6 @@ class CopyTests(ConnectingTestCase):
|
||||||
self.conn.set_client_encoding('latin1')
|
self.conn.set_client_encoding('latin1')
|
||||||
self._create_temp_table() # the above call closed the xn
|
self._create_temp_table() # the above call closed the xn
|
||||||
|
|
||||||
if PY2:
|
|
||||||
abin = ''.join(map(chr, range(32, 127) + range(160, 256)))
|
|
||||||
abin = abin.decode('latin1')
|
|
||||||
about = abin.replace('\\', '\\\\')
|
|
||||||
|
|
||||||
else:
|
|
||||||
abin = bytes(list(range(32, 127))
|
abin = bytes(list(range(32, 127))
|
||||||
+ list(range(160, 256))).decode('latin1')
|
+ list(range(160, 256))).decode('latin1')
|
||||||
about = abin.replace('\\', '\\\\')
|
about = abin.replace('\\', '\\\\')
|
||||||
|
|
|
@ -39,7 +39,6 @@ from .testutils import (ConnectingTestCase, skip_before_postgres,
|
||||||
skip_if_windows, skip_if_crdb, crdb_version)
|
skip_if_windows, skip_if_crdb, crdb_version)
|
||||||
|
|
||||||
import psycopg2.extras
|
import psycopg2.extras
|
||||||
from psycopg2.compat import text_type
|
|
||||||
|
|
||||||
|
|
||||||
class CursorTests(ConnectingTestCase):
|
class CursorTests(ConnectingTestCase):
|
||||||
|
@ -83,7 +82,7 @@ class CursorTests(ConnectingTestCase):
|
||||||
snowman = u"\u2603"
|
snowman = u"\u2603"
|
||||||
|
|
||||||
def b(s):
|
def b(s):
|
||||||
if isinstance(s, text_type):
|
if isinstance(s, str):
|
||||||
return s.encode('utf8')
|
return s.encode('utf8')
|
||||||
else:
|
else:
|
||||||
return s
|
return s
|
||||||
|
|
|
@ -20,14 +20,14 @@ import time
|
||||||
import pickle
|
import pickle
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from psycopg2.compat import lru_cache
|
|
||||||
import psycopg2.extras
|
import psycopg2.extras
|
||||||
from psycopg2.extras import NamedTupleConnection, NamedTupleCursor
|
from psycopg2.extras import NamedTupleConnection, NamedTupleCursor
|
||||||
|
|
||||||
from .testutils import ConnectingTestCase, skip_before_postgres, \
|
from .testutils import ConnectingTestCase, skip_before_postgres, \
|
||||||
skip_before_python, skip_from_python, crdb_version, skip_if_crdb
|
crdb_version, skip_if_crdb
|
||||||
|
|
||||||
|
|
||||||
class _DictCursorBase(ConnectingTestCase):
|
class _DictCursorBase(ConnectingTestCase):
|
||||||
|
@ -179,27 +179,7 @@ class ExtrasDictCursorTests(_DictCursorBase):
|
||||||
self.assertEqual(len(rv3), 2)
|
self.assertEqual(len(rv3), 2)
|
||||||
self.assertEqual(len(rv), 2)
|
self.assertEqual(len(rv), 2)
|
||||||
|
|
||||||
@skip_from_python(3)
|
def test_iter_methods(self):
|
||||||
def test_iter_methods_2(self):
|
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
||||||
curs.execute("select 10 as a, 20 as b")
|
|
||||||
r = curs.fetchone()
|
|
||||||
self.assert_(isinstance(r.keys(), list))
|
|
||||||
self.assertEqual(len(r.keys()), 2)
|
|
||||||
self.assert_(isinstance(r.values(), tuple)) # sic?
|
|
||||||
self.assertEqual(len(r.values()), 2)
|
|
||||||
self.assert_(isinstance(r.items(), list))
|
|
||||||
self.assertEqual(len(r.items()), 2)
|
|
||||||
|
|
||||||
self.assert_(not isinstance(r.iterkeys(), list))
|
|
||||||
self.assertEqual(len(list(r.iterkeys())), 2)
|
|
||||||
self.assert_(not isinstance(r.itervalues(), list))
|
|
||||||
self.assertEqual(len(list(r.itervalues())), 2)
|
|
||||||
self.assert_(not isinstance(r.iteritems(), list))
|
|
||||||
self.assertEqual(len(list(r.iteritems())), 2)
|
|
||||||
|
|
||||||
@skip_before_python(3)
|
|
||||||
def test_iter_methods_3(self):
|
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||||
curs.execute("select 10 as a, 20 as b")
|
curs.execute("select 10 as a, 20 as b")
|
||||||
r = curs.fetchone()
|
r = curs.fetchone()
|
||||||
|
@ -226,21 +206,6 @@ class ExtrasDictCursorTests(_DictCursorBase):
|
||||||
self.assertEqual(list(r1.values()), list(r.values()))
|
self.assertEqual(list(r1.values()), list(r.values()))
|
||||||
self.assertEqual(list(r1.items()), list(r.items()))
|
self.assertEqual(list(r1.items()), list(r.items()))
|
||||||
|
|
||||||
@skip_from_python(3)
|
|
||||||
def test_order_iter(self):
|
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
||||||
curs.execute("select 5 as foo, 4 as bar, 33 as baz, 2 as qux")
|
|
||||||
r = curs.fetchone()
|
|
||||||
self.assertEqual(list(r.iterkeys()), ['foo', 'bar', 'baz', 'qux'])
|
|
||||||
self.assertEqual(list(r.itervalues()), [5, 4, 33, 2])
|
|
||||||
self.assertEqual(list(r.iteritems()),
|
|
||||||
[('foo', 5), ('bar', 4), ('baz', 33), ('qux', 2)])
|
|
||||||
|
|
||||||
r1 = pickle.loads(pickle.dumps(r))
|
|
||||||
self.assertEqual(list(r1.iterkeys()), list(r.iterkeys()))
|
|
||||||
self.assertEqual(list(r1.itervalues()), list(r.itervalues()))
|
|
||||||
self.assertEqual(list(r1.iteritems()), list(r.iteritems()))
|
|
||||||
|
|
||||||
|
|
||||||
class ExtrasDictCursorRealTests(_DictCursorBase):
|
class ExtrasDictCursorRealTests(_DictCursorBase):
|
||||||
def testRealMeansReal(self):
|
def testRealMeansReal(self):
|
||||||
|
@ -340,27 +305,7 @@ class ExtrasDictCursorRealTests(_DictCursorBase):
|
||||||
row = getter(curs)
|
row = getter(curs)
|
||||||
self.failUnless(row['foo'] == 'bar')
|
self.failUnless(row['foo'] == 'bar')
|
||||||
|
|
||||||
@skip_from_python(3)
|
def test_iter_methods(self):
|
||||||
def test_iter_methods_2(self):
|
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
||||||
curs.execute("select 10 as a, 20 as b")
|
|
||||||
r = curs.fetchone()
|
|
||||||
self.assert_(isinstance(r.keys(), list))
|
|
||||||
self.assertEqual(len(r.keys()), 2)
|
|
||||||
self.assert_(isinstance(r.values(), list))
|
|
||||||
self.assertEqual(len(r.values()), 2)
|
|
||||||
self.assert_(isinstance(r.items(), list))
|
|
||||||
self.assertEqual(len(r.items()), 2)
|
|
||||||
|
|
||||||
self.assert_(not isinstance(r.iterkeys(), list))
|
|
||||||
self.assertEqual(len(list(r.iterkeys())), 2)
|
|
||||||
self.assert_(not isinstance(r.itervalues(), list))
|
|
||||||
self.assertEqual(len(list(r.itervalues())), 2)
|
|
||||||
self.assert_(not isinstance(r.iteritems(), list))
|
|
||||||
self.assertEqual(len(list(r.iteritems())), 2)
|
|
||||||
|
|
||||||
@skip_before_python(3)
|
|
||||||
def test_iter_methods_3(self):
|
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
||||||
curs.execute("select 10 as a, 20 as b")
|
curs.execute("select 10 as a, 20 as b")
|
||||||
r = curs.fetchone()
|
r = curs.fetchone()
|
||||||
|
@ -387,21 +332,6 @@ class ExtrasDictCursorRealTests(_DictCursorBase):
|
||||||
self.assertEqual(list(r1.values()), list(r.values()))
|
self.assertEqual(list(r1.values()), list(r.values()))
|
||||||
self.assertEqual(list(r1.items()), list(r.items()))
|
self.assertEqual(list(r1.items()), list(r.items()))
|
||||||
|
|
||||||
@skip_from_python(3)
|
|
||||||
def test_order_iter(self):
|
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
||||||
curs.execute("select 5 as foo, 4 as bar, 33 as baz, 2 as qux")
|
|
||||||
r = curs.fetchone()
|
|
||||||
self.assertEqual(list(r.iterkeys()), ['foo', 'bar', 'baz', 'qux'])
|
|
||||||
self.assertEqual(list(r.itervalues()), [5, 4, 33, 2])
|
|
||||||
self.assertEqual(list(r.iteritems()),
|
|
||||||
[('foo', 5), ('bar', 4), ('baz', 33), ('qux', 2)])
|
|
||||||
|
|
||||||
r1 = pickle.loads(pickle.dumps(r))
|
|
||||||
self.assertEqual(list(r1.iterkeys()), list(r.iterkeys()))
|
|
||||||
self.assertEqual(list(r1.itervalues()), list(r.itervalues()))
|
|
||||||
self.assertEqual(list(r1.iteritems()), list(r.iteritems()))
|
|
||||||
|
|
||||||
def test_pop(self):
|
def test_pop(self):
|
||||||
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
||||||
curs.execute("select 1 as a, 2 as b, 3 as c")
|
curs.execute("select 1 as a, 2 as b, 3 as c")
|
||||||
|
@ -564,7 +494,6 @@ class NamedTupleCursorTest(ConnectingTestCase):
|
||||||
self.assertEqual(rv.f_column_, 2)
|
self.assertEqual(rv.f_column_, 2)
|
||||||
self.assertEqual(rv.f3, 3)
|
self.assertEqual(rv.f3, 3)
|
||||||
|
|
||||||
@skip_before_python(3)
|
|
||||||
@skip_before_postgres(8)
|
@skip_before_postgres(8)
|
||||||
def test_nonascii_name(self):
|
def test_nonascii_name(self):
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
from . import testutils
|
from . import testutils
|
||||||
import unittest
|
import unittest
|
||||||
from .testutils import ConnectingTestCase, skip_if_crdb, unichr, PY2
|
from .testutils import ConnectingTestCase, skip_if_crdb
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import psycopg2.extensions
|
import psycopg2.extensions
|
||||||
|
@ -79,16 +79,10 @@ class QuotingTestCase(ConnectingTestCase):
|
||||||
data = b"""some data with \000\013 binary
|
data = b"""some data with \000\013 binary
|
||||||
stuff into, 'quotes' and \\ a backslash too.
|
stuff into, 'quotes' and \\ a backslash too.
|
||||||
"""
|
"""
|
||||||
if PY2:
|
|
||||||
data += "".join(map(chr, range(256)))
|
|
||||||
else:
|
|
||||||
data += bytes(list(range(256)))
|
data += bytes(list(range(256)))
|
||||||
|
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
curs.execute("SELECT %s::bytea;", (psycopg2.Binary(data),))
|
curs.execute("SELECT %s::bytea;", (psycopg2.Binary(data),))
|
||||||
if PY2:
|
|
||||||
res = str(curs.fetchone()[0])
|
|
||||||
else:
|
|
||||||
res = curs.fetchone()[0].tobytes()
|
res = curs.fetchone()[0].tobytes()
|
||||||
|
|
||||||
if res[0] in (b'x', ord(b'x')) and self.conn.info.server_version >= 90000:
|
if res[0] in (b'x', ord(b'x')) and self.conn.info.server_version >= 90000:
|
||||||
|
@ -110,7 +104,7 @@ class QuotingTestCase(ConnectingTestCase):
|
||||||
data = u"""some data with \t chars
|
data = u"""some data with \t chars
|
||||||
to escape into, 'quotes', \u20ac euro sign and \\ a backslash too.
|
to escape into, 'quotes', \u20ac euro sign and \\ a backslash too.
|
||||||
"""
|
"""
|
||||||
data += u"".join(map(unichr, [u for u in range(1, 65536)
|
data += u"".join(map(chr, [u for u in range(1, 65536)
|
||||||
if not 0xD800 <= u <= 0xDFFF])) # surrogate area
|
if not 0xD800 <= u <= 0xDFFF])) # surrogate area
|
||||||
self.conn.set_client_encoding('UNICODE')
|
self.conn.set_client_encoding('UNICODE')
|
||||||
|
|
||||||
|
@ -125,9 +119,6 @@ class QuotingTestCase(ConnectingTestCase):
|
||||||
def test_latin1(self):
|
def test_latin1(self):
|
||||||
self.conn.set_client_encoding('LATIN1')
|
self.conn.set_client_encoding('LATIN1')
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
if PY2:
|
|
||||||
data = ''.join(map(chr, range(32, 127) + range(160, 256)))
|
|
||||||
else:
|
|
||||||
data = bytes(list(range(32, 127))
|
data = bytes(list(range(32, 127))
|
||||||
+ list(range(160, 256))).decode('latin1')
|
+ list(range(160, 256))).decode('latin1')
|
||||||
|
|
||||||
|
@ -137,23 +128,11 @@ class QuotingTestCase(ConnectingTestCase):
|
||||||
self.assertEqual(res, data)
|
self.assertEqual(res, data)
|
||||||
self.assert_(not self.conn.notices)
|
self.assert_(not self.conn.notices)
|
||||||
|
|
||||||
# as unicode
|
|
||||||
if PY2:
|
|
||||||
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE, self.conn)
|
|
||||||
data = data.decode('latin1')
|
|
||||||
|
|
||||||
curs.execute("SELECT %s::text;", (data,))
|
|
||||||
res = curs.fetchone()[0]
|
|
||||||
self.assertEqual(res, data)
|
|
||||||
self.assert_(not self.conn.notices)
|
|
||||||
|
|
||||||
@skip_if_crdb("encoding")
|
@skip_if_crdb("encoding")
|
||||||
def test_koi8(self):
|
def test_koi8(self):
|
||||||
self.conn.set_client_encoding('KOI8')
|
self.conn.set_client_encoding('KOI8')
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
if PY2:
|
|
||||||
data = ''.join(map(chr, range(32, 127) + range(128, 256)))
|
|
||||||
else:
|
|
||||||
data = bytes(list(range(32, 127))
|
data = bytes(list(range(32, 127))
|
||||||
+ list(range(128, 256))).decode('koi8_r')
|
+ list(range(128, 256))).decode('koi8_r')
|
||||||
|
|
||||||
|
@ -163,16 +142,6 @@ class QuotingTestCase(ConnectingTestCase):
|
||||||
self.assertEqual(res, data)
|
self.assertEqual(res, data)
|
||||||
self.assert_(not self.conn.notices)
|
self.assert_(not self.conn.notices)
|
||||||
|
|
||||||
# as unicode
|
|
||||||
if PY2:
|
|
||||||
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE, self.conn)
|
|
||||||
data = data.decode('koi8_r')
|
|
||||||
|
|
||||||
curs.execute("SELECT %s::text;", (data,))
|
|
||||||
res = curs.fetchone()[0]
|
|
||||||
self.assertEqual(res, data)
|
|
||||||
self.assert_(not self.conn.notices)
|
|
||||||
|
|
||||||
def test_bytes(self):
|
def test_bytes(self):
|
||||||
snowman = u"\u2603"
|
snowman = u"\u2603"
|
||||||
conn = self.connect()
|
conn = self.connect()
|
||||||
|
@ -204,9 +173,6 @@ class TestQuotedIdentifier(ConnectingTestCase):
|
||||||
def test_unicode_ident(self):
|
def test_unicode_ident(self):
|
||||||
snowman = u"\u2603"
|
snowman = u"\u2603"
|
||||||
quoted = '"' + snowman + '"'
|
quoted = '"' + snowman + '"'
|
||||||
if PY2:
|
|
||||||
self.assertEqual(quote_ident(snowman, self.conn), quoted.encode('utf8'))
|
|
||||||
else:
|
|
||||||
self.assertEqual(quote_ident(snowman, self.conn), quoted)
|
self.assertEqual(quote_ident(snowman, self.conn), quoted)
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,7 +214,6 @@ class TestStringAdapter(ConnectingTestCase):
|
||||||
self.assertEqual(a.encoding, 'utf_8')
|
self.assertEqual(a.encoding, 'utf_8')
|
||||||
self.assertQuotedEqual(a.getquoted(), b"'\xe2\x98\x83'")
|
self.assertQuotedEqual(a.getquoted(), b"'\xe2\x98\x83'")
|
||||||
|
|
||||||
@testutils.skip_before_python(3)
|
|
||||||
def test_adapt_bytes(self):
|
def test_adapt_bytes(self):
|
||||||
snowman = u"\u2603"
|
snowman = u"\u2603"
|
||||||
self.conn.set_client_encoding('utf8')
|
self.conn.set_client_encoding('utf8')
|
||||||
|
|
|
@ -31,7 +31,6 @@ from .testutils import (
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from psycopg2 import sql
|
from psycopg2 import sql
|
||||||
from psycopg2.compat import text_type
|
|
||||||
|
|
||||||
|
|
||||||
class SqlFormatTests(ConnectingTestCase):
|
class SqlFormatTests(ConnectingTestCase):
|
||||||
|
@ -62,13 +61,6 @@ class SqlFormatTests(ConnectingTestCase):
|
||||||
self.assert_(isinstance(s1, str))
|
self.assert_(isinstance(s1, str))
|
||||||
self.assertEqual(s1, 'select "field" from "table"')
|
self.assertEqual(s1, 'select "field" from "table"')
|
||||||
|
|
||||||
def test_unicode(self):
|
|
||||||
s = sql.SQL(u"select {0} from {1}").format(
|
|
||||||
sql.Identifier(u'field'), sql.Identifier('table'))
|
|
||||||
s1 = s.as_string(self.conn)
|
|
||||||
self.assert_(isinstance(s1, text_type))
|
|
||||||
self.assertEqual(s1, u'select "field" from "table"')
|
|
||||||
|
|
||||||
def test_compose_literal(self):
|
def test_compose_literal(self):
|
||||||
s = sql.SQL("select {0};").format(sql.Literal(dt.date(2016, 12, 31)))
|
s = sql.SQL("select {0};").format(sql.Literal(dt.date(2016, 12, 31)))
|
||||||
s1 = s.as_string(self.conn)
|
s1 = s.as_string(self.conn)
|
||||||
|
|
|
@ -31,7 +31,7 @@ import platform
|
||||||
|
|
||||||
from . import testutils
|
from . import testutils
|
||||||
import unittest
|
import unittest
|
||||||
from .testutils import PY2, long, text_type, ConnectingTestCase, restore_types
|
from .testutils import ConnectingTestCase, restore_types
|
||||||
from .testutils import skip_if_crdb
|
from .testutils import skip_if_crdb
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
|
@ -59,8 +59,6 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
def testNumber(self):
|
def testNumber(self):
|
||||||
s = self.execute("SELECT %s AS foo", (1971,))
|
s = self.execute("SELECT %s AS foo", (1971,))
|
||||||
self.failUnless(s == 1971, "wrong integer quoting: " + str(s))
|
self.failUnless(s == 1971, "wrong integer quoting: " + str(s))
|
||||||
s = self.execute("SELECT %s AS foo", (long(1971),))
|
|
||||||
self.failUnless(s == long(1971), "wrong integer quoting: " + str(s))
|
|
||||||
|
|
||||||
def testBoolean(self):
|
def testBoolean(self):
|
||||||
x = self.execute("SELECT %s as foo", (False,))
|
x = self.execute("SELECT %s as foo", (False,))
|
||||||
|
@ -110,12 +108,6 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
self.failUnless(str(s) == "-inf", "wrong float quoting: " + str(s))
|
self.failUnless(str(s) == "-inf", "wrong float quoting: " + str(s))
|
||||||
|
|
||||||
def testBinary(self):
|
def testBinary(self):
|
||||||
if PY2:
|
|
||||||
s = ''.join([chr(x) for x in range(256)])
|
|
||||||
b = psycopg2.Binary(s)
|
|
||||||
buf = self.execute("SELECT %s::bytea AS foo", (b,))
|
|
||||||
self.assertEqual(s, str(buf))
|
|
||||||
else:
|
|
||||||
s = bytes(range(256))
|
s = bytes(range(256))
|
||||||
b = psycopg2.Binary(s)
|
b = psycopg2.Binary(s)
|
||||||
buf = self.execute("SELECT %s::bytea AS foo", (b,))
|
buf = self.execute("SELECT %s::bytea AS foo", (b,))
|
||||||
|
@ -128,22 +120,12 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
|
|
||||||
def testBinaryEmptyString(self):
|
def testBinaryEmptyString(self):
|
||||||
# test to make sure an empty Binary is converted to an empty string
|
# test to make sure an empty Binary is converted to an empty string
|
||||||
if PY2:
|
|
||||||
b = psycopg2.Binary('')
|
|
||||||
self.assertEqual(str(b), "''::bytea")
|
|
||||||
else:
|
|
||||||
b = psycopg2.Binary(bytes([]))
|
b = psycopg2.Binary(bytes([]))
|
||||||
self.assertEqual(str(b), "''::bytea")
|
self.assertEqual(str(b), "''::bytea")
|
||||||
|
|
||||||
def testBinaryRoundTrip(self):
|
def testBinaryRoundTrip(self):
|
||||||
# test to make sure buffers returned by psycopg2 are
|
# test to make sure buffers returned by psycopg2 are
|
||||||
# understood by execute:
|
# understood by execute:
|
||||||
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,))
|
|
||||||
self.assertEqual(s, str(buf2))
|
|
||||||
else:
|
|
||||||
s = bytes(range(256))
|
s = bytes(range(256))
|
||||||
buf = self.execute("SELECT %s::bytea AS foo", (psycopg2.Binary(s),))
|
buf = self.execute("SELECT %s::bytea AS foo", (psycopg2.Binary(s),))
|
||||||
buf2 = self.execute("SELECT %s::bytea AS foo", (buf,))
|
buf2 = self.execute("SELECT %s::bytea AS foo", (buf,))
|
||||||
|
@ -227,7 +209,7 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
curs.execute("select '{a,b,c}'::text[]")
|
curs.execute("select '{a,b,c}'::text[]")
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
self.assert_(isinstance(x[0], text_type))
|
self.assert_(isinstance(x[0], str))
|
||||||
self.assertEqual(x, [u'a', u'b', u'c'])
|
self.assertEqual(x, [u'a', u'b', u'c'])
|
||||||
|
|
||||||
def testBytesArray(self):
|
def testBytesArray(self):
|
||||||
|
@ -291,27 +273,6 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
curs.execute("select %s::int[]", (a,))
|
curs.execute("select %s::int[]", (a,))
|
||||||
self.assertEqual(curs.fetchone()[0], a)
|
self.assertEqual(curs.fetchone()[0], a)
|
||||||
|
|
||||||
@testutils.skip_from_python(3)
|
|
||||||
def testTypeRoundtripBuffer(self):
|
|
||||||
o1 = buffer("".join(map(chr, range(256))))
|
|
||||||
o2 = self.execute("select %s;", (o1,))
|
|
||||||
self.assertEqual(type(o1), type(o2))
|
|
||||||
|
|
||||||
# Test with an empty buffer
|
|
||||||
o1 = buffer("")
|
|
||||||
o2 = self.execute("select %s;", (o1,))
|
|
||||||
self.assertEqual(type(o1), type(o2))
|
|
||||||
self.assertEqual(str(o1), str(o2))
|
|
||||||
|
|
||||||
@testutils.skip_from_python(3)
|
|
||||||
def testTypeRoundtripBufferArray(self):
|
|
||||||
o1 = buffer("".join(map(chr, range(256))))
|
|
||||||
o1 = [o1]
|
|
||||||
o2 = self.execute("select %s;", (o1,))
|
|
||||||
self.assertEqual(type(o1[0]), type(o2[0]))
|
|
||||||
self.assertEqual(str(o1[0]), str(o2[0]))
|
|
||||||
|
|
||||||
@testutils.skip_before_python(3)
|
|
||||||
def testTypeRoundtripBytes(self):
|
def testTypeRoundtripBytes(self):
|
||||||
o1 = bytes(range(256))
|
o1 = bytes(range(256))
|
||||||
o2 = self.execute("select %s;", (o1,))
|
o2 = self.execute("select %s;", (o1,))
|
||||||
|
@ -322,7 +283,6 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
o2 = self.execute("select %s;", (o1,))
|
o2 = self.execute("select %s;", (o1,))
|
||||||
self.assertEqual(memoryview, type(o2))
|
self.assertEqual(memoryview, type(o2))
|
||||||
|
|
||||||
@testutils.skip_before_python(3)
|
|
||||||
def testTypeRoundtripBytesArray(self):
|
def testTypeRoundtripBytesArray(self):
|
||||||
o1 = bytes(range(256))
|
o1 = bytes(range(256))
|
||||||
o1 = [o1]
|
o1 = [o1]
|
||||||
|
@ -332,12 +292,7 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
def testAdaptBytearray(self):
|
def testAdaptBytearray(self):
|
||||||
o1 = bytearray(range(256))
|
o1 = bytearray(range(256))
|
||||||
o2 = self.execute("select %s;", (o1,))
|
o2 = self.execute("select %s;", (o1,))
|
||||||
|
|
||||||
if PY2:
|
|
||||||
self.assertEqual(buffer, type(o2))
|
|
||||||
else:
|
|
||||||
self.assertEqual(memoryview, type(o2))
|
self.assertEqual(memoryview, type(o2))
|
||||||
|
|
||||||
self.assertEqual(len(o1), len(o2))
|
self.assertEqual(len(o1), len(o2))
|
||||||
for c1, c2 in zip(o1, o2):
|
for c1, c2 in zip(o1, o2):
|
||||||
self.assertEqual(c1, ord(c2))
|
self.assertEqual(c1, ord(c2))
|
||||||
|
@ -345,27 +300,17 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
# Test with an empty buffer
|
# Test with an empty buffer
|
||||||
o1 = bytearray([])
|
o1 = bytearray([])
|
||||||
o2 = self.execute("select %s;", (o1,))
|
o2 = self.execute("select %s;", (o1,))
|
||||||
|
|
||||||
self.assertEqual(len(o2), 0)
|
self.assertEqual(len(o2), 0)
|
||||||
if PY2:
|
|
||||||
self.assertEqual(buffer, type(o2))
|
|
||||||
else:
|
|
||||||
self.assertEqual(memoryview, type(o2))
|
self.assertEqual(memoryview, type(o2))
|
||||||
|
|
||||||
def testAdaptMemoryview(self):
|
def testAdaptMemoryview(self):
|
||||||
o1 = memoryview(bytearray(range(256)))
|
o1 = memoryview(bytearray(range(256)))
|
||||||
o2 = self.execute("select %s;", (o1,))
|
o2 = self.execute("select %s;", (o1,))
|
||||||
if PY2:
|
|
||||||
self.assertEqual(buffer, type(o2))
|
|
||||||
else:
|
|
||||||
self.assertEqual(memoryview, type(o2))
|
self.assertEqual(memoryview, type(o2))
|
||||||
|
|
||||||
# Test with an empty buffer
|
# Test with an empty buffer
|
||||||
o1 = memoryview(bytearray([]))
|
o1 = memoryview(bytearray([]))
|
||||||
o2 = self.execute("select %s;", (o1,))
|
o2 = self.execute("select %s;", (o1,))
|
||||||
if PY2:
|
|
||||||
self.assertEqual(buffer, type(o2))
|
|
||||||
else:
|
|
||||||
self.assertEqual(memoryview, type(o2))
|
self.assertEqual(memoryview, type(o2))
|
||||||
|
|
||||||
def testByteaHexCheckFalsePositive(self):
|
def testByteaHexCheckFalsePositive(self):
|
||||||
|
@ -382,8 +327,6 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
self.assertEqual(1, f1)
|
self.assertEqual(1, f1)
|
||||||
i1 = self.execute("select -%s;", (-1,))
|
i1 = self.execute("select -%s;", (-1,))
|
||||||
self.assertEqual(1, i1)
|
self.assertEqual(1, i1)
|
||||||
l1 = self.execute("select -%s;", (long(-1),))
|
|
||||||
self.assertEqual(1, l1)
|
|
||||||
|
|
||||||
def testGenericArray(self):
|
def testGenericArray(self):
|
||||||
a = self.execute("select '{1, 2, 3}'::int4[]")
|
a = self.execute("select '{1, 2, 3}'::int4[]")
|
||||||
|
@ -417,7 +360,6 @@ class TypesBasicTests(ConnectingTestCase):
|
||||||
a = self.execute("select '{10:20:30:40:50:60}'::macaddr[]")
|
a = self.execute("select '{10:20:30:40:50:60}'::macaddr[]")
|
||||||
self.assertEqual(a, ['10:20:30:40:50:60'])
|
self.assertEqual(a, ['10:20:30:40:50:60'])
|
||||||
|
|
||||||
@testutils.skip_before_python(3, 4)
|
|
||||||
def testIntEnum(self):
|
def testIntEnum(self):
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
|
@ -453,19 +395,6 @@ class AdaptSubclassTest(unittest.TestCase):
|
||||||
register_adapter(B, lambda b: AsIs("b"))
|
register_adapter(B, lambda b: AsIs("b"))
|
||||||
self.assertEqual(b'b', adapt(C()).getquoted())
|
self.assertEqual(b'b', adapt(C()).getquoted())
|
||||||
|
|
||||||
@testutils.skip_from_python(3)
|
|
||||||
@restore_types
|
|
||||||
def test_no_mro_no_joy(self):
|
|
||||||
class A:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class B(A):
|
|
||||||
pass
|
|
||||||
|
|
||||||
register_adapter(A, lambda a: AsIs("a"))
|
|
||||||
self.assertRaises(psycopg2.ProgrammingError, adapt, B())
|
|
||||||
|
|
||||||
@testutils.skip_before_python(3)
|
|
||||||
@restore_types
|
@restore_types
|
||||||
def test_adapt_subtype_3(self):
|
def test_adapt_subtype_3(self):
|
||||||
class A:
|
class A:
|
||||||
|
@ -512,9 +441,6 @@ class ByteaParserTest(unittest.TestCase):
|
||||||
if rv is None:
|
if rv is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if PY2:
|
|
||||||
return str(rv)
|
|
||||||
else:
|
|
||||||
return rv.tobytes()
|
return rv.tobytes()
|
||||||
|
|
||||||
def test_null(self):
|
def test_null(self):
|
||||||
|
@ -536,9 +462,6 @@ class ByteaParserTest(unittest.TestCase):
|
||||||
buf = buf.upper()
|
buf = buf.upper()
|
||||||
buf = '\\x' + buf
|
buf = '\\x' + buf
|
||||||
rv = self.cast(buf.encode('utf8'))
|
rv = self.cast(buf.encode('utf8'))
|
||||||
if PY2:
|
|
||||||
self.assertEqual(rv, ''.join(map(chr, range(256))))
|
|
||||||
else:
|
|
||||||
self.assertEqual(rv, bytes(range(256)))
|
self.assertEqual(rv, bytes(range(256)))
|
||||||
|
|
||||||
def test_full_hex_upper(self):
|
def test_full_hex_upper(self):
|
||||||
|
@ -547,9 +470,6 @@ class ByteaParserTest(unittest.TestCase):
|
||||||
def test_full_escaped_octal(self):
|
def test_full_escaped_octal(self):
|
||||||
buf = ''.join(("\\%03o" % i) for i in range(256))
|
buf = ''.join(("\\%03o" % i) for i in range(256))
|
||||||
rv = self.cast(buf.encode('utf8'))
|
rv = self.cast(buf.encode('utf8'))
|
||||||
if PY2:
|
|
||||||
self.assertEqual(rv, ''.join(map(chr, range(256))))
|
|
||||||
else:
|
|
||||||
self.assertEqual(rv, bytes(range(256)))
|
self.assertEqual(rv, bytes(range(256)))
|
||||||
|
|
||||||
def test_escaped_mixed(self):
|
def test_escaped_mixed(self):
|
||||||
|
@ -558,10 +478,6 @@ class ByteaParserTest(unittest.TestCase):
|
||||||
buf += ''.join('\\' + c for c in string.ascii_letters)
|
buf += ''.join('\\' + c for c in string.ascii_letters)
|
||||||
buf += '\\\\'
|
buf += '\\\\'
|
||||||
rv = self.cast(buf.encode('utf8'))
|
rv = self.cast(buf.encode('utf8'))
|
||||||
if PY2:
|
|
||||||
tgt = ''.join(map(chr, range(32))) \
|
|
||||||
+ string.ascii_letters * 2 + '\\'
|
|
||||||
else:
|
|
||||||
tgt = bytes(range(32)) + \
|
tgt = bytes(range(32)) + \
|
||||||
(string.ascii_letters * 2 + '\\').encode('ascii')
|
(string.ascii_letters * 2 + '\\').encode('ascii')
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ from functools import wraps
|
||||||
from pickle import dumps, loads
|
from pickle import dumps, loads
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from .testutils import (PY2, text_type, skip_if_no_uuid, skip_before_postgres,
|
from .testutils import (skip_if_no_uuid, skip_before_postgres,
|
||||||
ConnectingTestCase, py3_raises_typeerror, slow, skip_from_python,
|
ConnectingTestCase, raises_typeerror, slow,
|
||||||
restore_types, skip_if_crdb, crdb_version)
|
restore_types, skip_if_crdb, crdb_version)
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
|
@ -249,19 +249,6 @@ class HstoreTestCase(ConnectingTestCase):
|
||||||
self.assertEqual(t[1], {})
|
self.assertEqual(t[1], {})
|
||||||
self.assertEqual(t[2], {'a': 'b'})
|
self.assertEqual(t[2], {'a': 'b'})
|
||||||
|
|
||||||
@skip_if_no_hstore
|
|
||||||
@skip_from_python(3)
|
|
||||||
def test_register_unicode(self):
|
|
||||||
register_hstore(self.conn, unicode=True)
|
|
||||||
cur = self.conn.cursor()
|
|
||||||
cur.execute("select null::hstore, ''::hstore, 'a => b'::hstore")
|
|
||||||
t = cur.fetchone()
|
|
||||||
self.assert_(t[0] is None)
|
|
||||||
self.assertEqual(t[1], {})
|
|
||||||
self.assertEqual(t[2], {u'a': u'b'})
|
|
||||||
self.assert_(isinstance(t[2].keys()[0], unicode))
|
|
||||||
self.assert_(isinstance(t[2].values()[0], unicode))
|
|
||||||
|
|
||||||
@skip_if_no_hstore
|
@skip_if_no_hstore
|
||||||
@restore_types
|
@restore_types
|
||||||
def test_register_globally(self):
|
def test_register_globally(self):
|
||||||
|
@ -297,37 +284,11 @@ class HstoreTestCase(ConnectingTestCase):
|
||||||
ok({''.join(ab): ''.join(ab)})
|
ok({''.join(ab): ''.join(ab)})
|
||||||
|
|
||||||
self.conn.set_client_encoding('latin1')
|
self.conn.set_client_encoding('latin1')
|
||||||
if PY2:
|
|
||||||
ab = map(chr, range(32, 127) + range(160, 255))
|
|
||||||
else:
|
|
||||||
ab = bytes(list(range(32, 127)) + list(range(160, 255))).decode('latin1')
|
ab = bytes(list(range(32, 127)) + list(range(160, 255))).decode('latin1')
|
||||||
|
|
||||||
ok({''.join(ab): ''.join(ab)})
|
ok({''.join(ab): ''.join(ab)})
|
||||||
ok(dict(zip(ab, ab)))
|
ok(dict(zip(ab, ab)))
|
||||||
|
|
||||||
@skip_if_no_hstore
|
|
||||||
@skip_from_python(3)
|
|
||||||
def test_roundtrip_unicode(self):
|
|
||||||
register_hstore(self.conn, unicode=True)
|
|
||||||
cur = self.conn.cursor()
|
|
||||||
|
|
||||||
def ok(d):
|
|
||||||
cur.execute("select %s", (d,))
|
|
||||||
d1 = cur.fetchone()[0]
|
|
||||||
self.assertEqual(len(d), len(d1))
|
|
||||||
for k, v in d1.iteritems():
|
|
||||||
self.assert_(k in d, k)
|
|
||||||
self.assertEqual(d[k], v)
|
|
||||||
self.assert_(isinstance(k, unicode))
|
|
||||||
self.assert_(v is None or isinstance(v, unicode))
|
|
||||||
|
|
||||||
ok({})
|
|
||||||
ok({'a': 'b', 'c': None, 'd': u'\u20ac', u'\u2603': 'e'})
|
|
||||||
|
|
||||||
ab = map(unichr, range(1, 1024))
|
|
||||||
ok({u''.join(ab): u''.join(ab)})
|
|
||||||
ok(dict(zip(ab, ab)))
|
|
||||||
|
|
||||||
@skip_if_no_hstore
|
@skip_if_no_hstore
|
||||||
@restore_types
|
@restore_types
|
||||||
def test_oid(self):
|
def test_oid(self):
|
||||||
|
@ -356,9 +317,6 @@ class HstoreTestCase(ConnectingTestCase):
|
||||||
ds.append({''.join(ab): ''.join(ab)})
|
ds.append({''.join(ab): ''.join(ab)})
|
||||||
|
|
||||||
self.conn.set_client_encoding('latin1')
|
self.conn.set_client_encoding('latin1')
|
||||||
if PY2:
|
|
||||||
ab = map(chr, range(32, 127) + range(160, 255))
|
|
||||||
else:
|
|
||||||
ab = bytes(list(range(32, 127)) + list(range(160, 255))).decode('latin1')
|
ab = bytes(list(range(32, 127)) + list(range(160, 255))).decode('latin1')
|
||||||
|
|
||||||
ds.append({''.join(ab): ''.join(ab)})
|
ds.append({''.join(ab): ''.join(ab)})
|
||||||
|
@ -1238,9 +1196,9 @@ class RangeTestCase(unittest.TestCase):
|
||||||
self.assert_(not Range() < Range())
|
self.assert_(not Range() < Range())
|
||||||
self.assert_(not Range(empty=True) < Range(empty=True))
|
self.assert_(not Range(empty=True) < Range(empty=True))
|
||||||
self.assert_(not Range(1, 2) < Range(1, 2))
|
self.assert_(not Range(1, 2) < Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(1 < Range(1, 2))
|
self.assert_(1 < Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(not Range(1, 2) < 1)
|
self.assert_(not Range(1, 2) < 1)
|
||||||
|
|
||||||
def test_gt_ordering(self):
|
def test_gt_ordering(self):
|
||||||
|
@ -1253,9 +1211,9 @@ class RangeTestCase(unittest.TestCase):
|
||||||
self.assert_(not Range() > Range())
|
self.assert_(not Range() > Range())
|
||||||
self.assert_(not Range(empty=True) > Range(empty=True))
|
self.assert_(not Range(empty=True) > Range(empty=True))
|
||||||
self.assert_(not Range(1, 2) > Range(1, 2))
|
self.assert_(not Range(1, 2) > Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(not 1 > Range(1, 2))
|
self.assert_(not 1 > Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(Range(1, 2) > 1)
|
self.assert_(Range(1, 2) > 1)
|
||||||
|
|
||||||
def test_le_ordering(self):
|
def test_le_ordering(self):
|
||||||
|
@ -1268,9 +1226,9 @@ class RangeTestCase(unittest.TestCase):
|
||||||
self.assert_(Range() <= Range())
|
self.assert_(Range() <= Range())
|
||||||
self.assert_(Range(empty=True) <= Range(empty=True))
|
self.assert_(Range(empty=True) <= Range(empty=True))
|
||||||
self.assert_(Range(1, 2) <= Range(1, 2))
|
self.assert_(Range(1, 2) <= Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(1 <= Range(1, 2))
|
self.assert_(1 <= Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(not Range(1, 2) <= 1)
|
self.assert_(not Range(1, 2) <= 1)
|
||||||
|
|
||||||
def test_ge_ordering(self):
|
def test_ge_ordering(self):
|
||||||
|
@ -1283,9 +1241,9 @@ class RangeTestCase(unittest.TestCase):
|
||||||
self.assert_(Range() >= Range())
|
self.assert_(Range() >= Range())
|
||||||
self.assert_(Range(empty=True) >= Range(empty=True))
|
self.assert_(Range(empty=True) >= Range(empty=True))
|
||||||
self.assert_(Range(1, 2) >= Range(1, 2))
|
self.assert_(Range(1, 2) >= Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(not 1 >= Range(1, 2))
|
self.assert_(not 1 >= Range(1, 2))
|
||||||
with py3_raises_typeerror():
|
with raises_typeerror():
|
||||||
self.assert_(Range(1, 2) >= 1)
|
self.assert_(Range(1, 2) >= 1)
|
||||||
|
|
||||||
def test_pickling(self):
|
def test_pickling(self):
|
||||||
|
@ -1313,10 +1271,10 @@ class RangeTestCase(unittest.TestCase):
|
||||||
|
|
||||||
for bounds in ('()', '[]', '(]', '[)'):
|
for bounds in ('()', '[]', '(]', '[)'):
|
||||||
r = Range(0, 4, bounds=bounds)
|
r = Range(0, 4, bounds=bounds)
|
||||||
results.append(text_type(r))
|
results.append(str(r))
|
||||||
|
|
||||||
r = Range(empty=True)
|
r = Range(empty=True)
|
||||||
results.append(text_type(r))
|
results.append(str(r))
|
||||||
self.assertEqual(results, expected)
|
self.assertEqual(results, expected)
|
||||||
|
|
||||||
def test_str_datetime(self):
|
def test_str_datetime(self):
|
||||||
|
@ -1328,7 +1286,7 @@ class RangeTestCase(unittest.TestCase):
|
||||||
r = DateTimeTZRange(datetime(2010, 1, 1, tzinfo=tz),
|
r = DateTimeTZRange(datetime(2010, 1, 1, tzinfo=tz),
|
||||||
datetime(2011, 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)'
|
expected = u'[2010-01-01 00:00:00-05:00, 2011-01-01 00:00:00-05:00)'
|
||||||
result = text_type(r)
|
result = str(r)
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,32 +34,16 @@ import platform
|
||||||
import unittest
|
import unittest
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from ctypes.util import find_library
|
from ctypes.util import find_library
|
||||||
|
from io import StringIO # noqa
|
||||||
|
from io import TextIOBase # noqa
|
||||||
|
from importlib import reload # noqa
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import psycopg2.errors
|
import psycopg2.errors
|
||||||
import psycopg2.extensions
|
import psycopg2.extensions
|
||||||
from psycopg2.compat import PY2, PY3, string_types, text_type
|
|
||||||
|
|
||||||
from .testconfig import green, dsn, repl_dsn
|
from .testconfig import green, dsn, repl_dsn
|
||||||
|
|
||||||
# Python 2/3 compatibility
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
# Python 2
|
|
||||||
from StringIO import StringIO
|
|
||||||
TextIOBase = object
|
|
||||||
long = long
|
|
||||||
reload = reload
|
|
||||||
unichr = unichr
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Python 3
|
|
||||||
from io import StringIO # noqa
|
|
||||||
from io import TextIOBase # noqa
|
|
||||||
from importlib import reload # noqa
|
|
||||||
long = int
|
|
||||||
unichr = chr
|
|
||||||
|
|
||||||
|
|
||||||
# Silence warnings caused by the stubbornness of the Python unittest
|
# Silence warnings caused by the stubbornness of the Python unittest
|
||||||
# maintainers
|
# maintainers
|
||||||
|
@ -102,7 +86,7 @@ class ConnectingTestCase(unittest.TestCase):
|
||||||
def assertQuotedEqual(self, first, second, msg=None):
|
def assertQuotedEqual(self, first, second, msg=None):
|
||||||
"""Compare two quoted strings disregarding eventual E'' quotes"""
|
"""Compare two quoted strings disregarding eventual E'' quotes"""
|
||||||
def f(s):
|
def f(s):
|
||||||
if isinstance(s, text_type):
|
if isinstance(s, str):
|
||||||
return re.sub(r"\bE'", "'", s)
|
return re.sub(r"\bE'", "'", s)
|
||||||
elif isinstance(first, bytes):
|
elif isinstance(first, bytes):
|
||||||
return re.sub(br"\bE'", b"'", s)
|
return re.sub(br"\bE'", b"'", s)
|
||||||
|
@ -454,7 +438,7 @@ def skip_if_crdb(reason, conn=None, version=None):
|
||||||
"== 20.1.3": the test will be skipped only if the version matches.
|
"== 20.1.3": the test will be skipped only if the version matches.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not isinstance(reason, string_types):
|
if not isinstance(reason, str):
|
||||||
raise TypeError("reason should be a string, got %r instead" % reason)
|
raise TypeError("reason should be a string, got %r instead" % reason)
|
||||||
|
|
||||||
if conn is not None:
|
if conn is not None:
|
||||||
|
@ -518,12 +502,11 @@ def _crdb_match_version(version, pattern):
|
||||||
return op(version, ref)
|
return op(version, ref)
|
||||||
|
|
||||||
|
|
||||||
class py3_raises_typeerror(object):
|
class raises_typeerror(object):
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __exit__(self, type, exc, tb):
|
def __exit__(self, type, exc, tb):
|
||||||
if PY3:
|
|
||||||
assert type is TypeError
|
assert type is TypeError
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user