summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Di Gregorio <fog@initd.org>2009-01-10 18:51:45 +0100
committerFederico Di Gregorio <fog@initd.org>2009-01-10 18:51:45 +0100
commit78c0765367d2a02f2ba5079ef2b600316e7d9003 (patch)
tree4cc3bb47eabb631950374f2963b35957b7b8ce25
parentf5ec67656665f27bcf6f1a72c312564fed58cb23 (diff)
parent83b03e5e3691baa45d49f6bee0e115203be01707 (diff)
downloadpsycopg2-78c0765367d2a02f2ba5079ef2b600316e7d9003.tar.gz
Merge from public trunk
-rw-r--r--psycopg/psycopg.h32
-rw-r--r--psycopg/psycopgmodule.c71
-rw-r--r--psycopg/python.h54
-rw-r--r--psycopg/typecast.c9
-rw-r--r--psycopg/typecast_basic.c4
-rw-r--r--setup.cfg6
-rw-r--r--setup.py55
7 files changed, 64 insertions, 167 deletions
diff --git a/psycopg/psycopg.h b/psycopg/psycopg.h
index b0734a6..8818ee5 100644
--- a/psycopg/psycopg.h
+++ b/psycopg/psycopg.h
@@ -27,42 +27,12 @@
#include <libpq-fe.h>
#include "psycopg/config.h"
+#include "psycopg/python.h"
#ifdef __cplusplus
extern "C" {
#endif
-/* Python 2.5+ Py_ssize_t compatibility: */
-#ifndef PY_FORMAT_SIZE_T
- #define PY_FORMAT_SIZE_T ""
-#endif
-
-/* FORMAT_CODE_SIZE_T is for plain size_t, not for Py_ssize_t: */
-#ifdef _MSC_VER
- /* For MSVC: */
- #define FORMAT_CODE_SIZE_T "%Iu"
-#else
- /* C99 standard format code: */
- #define FORMAT_CODE_SIZE_T "%zu"
-#endif
-/* FORMAT_CODE_PY_SSIZE_T is for Py_ssize_t: */
-#define FORMAT_CODE_PY_SSIZE_T "%" PY_FORMAT_SIZE_T "d"
-
-#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 5
- #define CONV_CODE_PY_SSIZE_T "n"
-#else
- #define CONV_CODE_PY_SSIZE_T "i"
-
- typedef int Py_ssize_t;
- #define PY_SSIZE_T_MIN INT_MIN
- #define PY_SSIZE_T_MAX INT_MAX
-
- #define readbufferproc getreadbufferproc
- #define writebufferproc getwritebufferproc
- #define segcountproc getsegcountproc
- #define charbufferproc getcharbufferproc
-#endif
-
/* DBAPI compliance parameters */
#define APILEVEL "2.0"
#define THREADSAFETY 2
diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c
index 6c658fc..43e0402 100644
--- a/psycopg/psycopgmodule.c
+++ b/psycopg/psycopgmodule.c
@@ -47,7 +47,6 @@ HIDDEN mxDateTimeModule_APIObject *mxDateTimeP = NULL;
#endif
/* some module-level variables, like the datetime module */
-#ifdef HAVE_PYDATETIME
#include <datetime.h>
#include "psycopg/adapter_datetime.h"
HIDDEN PyObject *pyDateTimeModuleP = NULL;
@@ -55,7 +54,6 @@ HIDDEN PyObject *pyDateTypeP = NULL;
HIDDEN PyObject *pyTimeTypeP = NULL;
HIDDEN PyObject *pyDateTimeTypeP = NULL;
HIDDEN PyObject *pyDeltaTypeP = NULL;
-#endif
/* pointers to the psycopg.tz classes */
HIDDEN PyObject *pyPsycopgTzModule = NULL;
@@ -276,23 +274,17 @@ psyco_adapters_init(PyObject *mod)
microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&asisType);
microprotocols_add(&PyInt_Type, NULL, (PyObject*)&asisType);
microprotocols_add(&PyLong_Type, NULL, (PyObject*)&asisType);
+ microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType);
microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType);
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType);
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType);
microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType);
+ microprotocols_add((PyTypeObject*)psyco_GetDecimalType(),
+ NULL, (PyObject*)&asisType);
-#ifdef HAVE_MXDATETIME
/* the module has already been initialized, so we can obtain the callable
objects directly from its dictionary :) */
- call = PyMapping_GetItemString(mod, "TimestampFromMx");
- microprotocols_add(mxDateTimeP->DateTime_Type, NULL, call);
- call = PyMapping_GetItemString(mod, "TimeFromMx");
- microprotocols_add(mxDateTimeP->DateTimeDelta_Type, NULL, call);
-#endif
-
-#ifdef HAVE_PYDATETIME
- /* as above, we use the callable objects from the psycopg module */
call = PyMapping_GetItemString(mod, "DateFromPy");
microprotocols_add((PyTypeObject*)pyDateTypeP, NULL, call);
call = PyMapping_GetItemString(mod, "TimeFromPy");
@@ -301,15 +293,13 @@ psyco_adapters_init(PyObject *mod)
microprotocols_add((PyTypeObject*)pyDateTimeTypeP, NULL, call);
call = PyMapping_GetItemString(mod, "IntervalFromPy");
microprotocols_add((PyTypeObject*)pyDeltaTypeP, NULL, call);
-#endif
-
-#ifdef HAVE_PYBOOL
- microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType);
-#endif
-#ifdef HAVE_DECIMAL
- microprotocols_add((PyTypeObject*)psyco_GetDecimalType(),
- NULL, (PyObject*)&asisType);
+#ifdef HAVE_MXDATETIME
+ /* as above, we use the callable objects from the psycopg module */
+ call = PyMapping_GetItemString(mod, "TimestampFromMx");
+ microprotocols_add(mxDateTimeP->DateTime_Type, NULL, call);
+ call = PyMapping_GetItemString(mod, "TimeFromMx");
+ microprotocols_add(mxDateTimeP->DateTimeDelta_Type, NULL, call);
#endif
}
@@ -590,9 +580,7 @@ psyco_GetDecimalType(void)
{
PyObject *decimalType = NULL;
static PyObject *cachedType = NULL;
-
-#ifdef HAVE_DECIMAL
- PyObject *decimal = PyImport_ImportModule("decimal");
+ PyObject *decimal;
/* Use the cached object if running from the main interpreter. */
int can_cache = psyco_is_main_interp();
@@ -602,6 +590,7 @@ psyco_GetDecimalType(void)
}
/* Get a new reference to the Decimal type. */
+ decimal = PyImport_ImportModule("decimal");
if (decimal) {
decimalType = PyObject_GetAttrString(decimal, "Decimal");
Py_DECREF(decimal);
@@ -614,11 +603,10 @@ psyco_GetDecimalType(void)
/* Store the object from future uses. */
if (can_cache && !cachedType) {
+ Py_INCREF(decimalType);
cachedType = decimalType;
}
-#endif /* HAVE_DECIMAL */
-
return decimalType;
}
@@ -659,6 +647,15 @@ static PyMethodDef psycopgMethods[] = {
{"List", (PyCFunction)psyco_List,
METH_VARARGS, psyco_List_doc},
+ {"DateFromPy", (PyCFunction)psyco_DateFromPy,
+ METH_VARARGS, psyco_DateFromPy_doc},
+ {"TimeFromPy", (PyCFunction)psyco_TimeFromPy,
+ METH_VARARGS, psyco_TimeFromPy_doc},
+ {"TimestampFromPy", (PyCFunction)psyco_TimestampFromPy,
+ METH_VARARGS, psyco_TimestampFromPy_doc},
+ {"IntervalFromPy", (PyCFunction)psyco_IntervalFromPy,
+ METH_VARARGS, psyco_IntervalFromPy_doc},
+
#ifdef HAVE_MXDATETIME
{"DateFromMx", (PyCFunction)psyco_DateFromMx,
METH_VARARGS, psyco_DateFromMx_doc},
@@ -670,17 +667,6 @@ static PyMethodDef psycopgMethods[] = {
METH_VARARGS, psyco_IntervalFromMx_doc},
#endif
-#ifdef HAVE_PYDATETIME
- {"DateFromPy", (PyCFunction)psyco_DateFromPy,
- METH_VARARGS, psyco_DateFromPy_doc},
- {"TimeFromPy", (PyCFunction)psyco_TimeFromPy,
- METH_VARARGS, psyco_TimeFromPy_doc},
- {"TimestampFromPy", (PyCFunction)psyco_TimestampFromPy,
- METH_VARARGS, psyco_TimestampFromPy_doc},
- {"IntervalFromPy", (PyCFunction)psyco_IntervalFromPy,
- METH_VARARGS, psyco_IntervalFromPy_doc},
-#endif
-
{NULL, NULL, 0, NULL} /* Sentinel */
};
@@ -694,7 +680,7 @@ init_psycopg(void)
#ifdef PSYCOPG_DEBUG
if (getenv("PSYCOPG_DEBUG"))
- psycopg_debug_enabled = 1;
+ psycopg_debug_enabled = 1;
#endif
Dprintf("initpsycopg: initializing psycopg %s", PSYCOPG_VERSION);
@@ -706,6 +692,7 @@ init_psycopg(void)
qstringType.ob_type = &PyType_Type;
binaryType.ob_type = &PyType_Type;
isqlquoteType.ob_type = &PyType_Type;
+ pbooleanType.ob_type = &PyType_Type;
asisType.ob_type = &PyType_Type;
listType.ob_type = &PyType_Type;
chunkType.ob_type = &PyType_Type;
@@ -716,6 +703,7 @@ init_psycopg(void)
if (PyType_Ready(&qstringType) == -1) return;
if (PyType_Ready(&binaryType) == -1) return;
if (PyType_Ready(&isqlquoteType) == -1) return;
+ if (PyType_Ready(&pbooleanType) == -1) return;
if (PyType_Ready(&asisType) == -1) return;
if (PyType_Ready(&listType) == -1) return;
if (PyType_Ready(&chunkType) == -1) return;
@@ -725,11 +713,6 @@ init_psycopg(void)
if (PyType_Ready(&lobjectType) == -1) return;
#endif
-#ifdef HAVE_PYBOOL
- pbooleanType.ob_type = &PyType_Type;
- if (PyType_Ready(&pbooleanType) == -1) return;
-#endif
-
/* import mx.DateTime module, if necessary */
#ifdef HAVE_MXDATETIME
mxdatetimeType.ob_type = &PyType_Type;
@@ -743,7 +726,6 @@ init_psycopg(void)
#endif
/* import python builtin datetime module, if available */
-#ifdef HAVE_PYDATETIME
pyDateTimeModuleP = PyImport_ImportModule("datetime");
if (pyDateTimeModuleP == NULL) {
Dprintf("initpsycopg: can't import datetime module");
@@ -759,7 +741,6 @@ init_psycopg(void)
pyTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "time");
pyDateTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "datetime");
pyDeltaTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "timedelta");
-#endif
/* import psycopg2.tz anyway (TODO: replace with C-level module?) */
pyPsycopgTzModule = PyImport_ImportModule("psycopg2.tz");
@@ -828,14 +809,12 @@ init_psycopg(void)
qstringType.tp_alloc = PyType_GenericAlloc;
listType.tp_alloc = PyType_GenericAlloc;
chunkType.tp_alloc = PyType_GenericAlloc;
+ pydatetimeType.tp_alloc = PyType_GenericAlloc;
#ifdef PSYCOPG_EXTENSIONS
lobjectType.tp_alloc = PyType_GenericAlloc;
#endif
-#ifdef HAVE_PYDATETIME
- pydatetimeType.tp_alloc = PyType_GenericAlloc;
-#endif
#ifdef HAVE_MXDATETIME
mxdatetimeType.tp_alloc = PyType_GenericAlloc;
diff --git a/psycopg/python.h b/psycopg/python.h
index 13d6ce7..22cae4a 100644
--- a/psycopg/python.h
+++ b/psycopg/python.h
@@ -26,42 +26,36 @@
#include <Python.h>
#include <structmember.h>
-/* python < 2.2 does not have PyMemeberDef */
-#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
-#define PyMemberDef memberlist
+#if PY_VERSION_HEX < 0x02040000
+# error "psycopg requires Python >= 2.4"
#endif
-/* PyObject_TypeCheck introduced in 2.2 */
-#ifndef PyObject_TypeCheck
-#define PyObject_TypeCheck(o, t) ((o)->ob_type == (t))
-#endif
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+ typedef int Py_ssize_t;
+ #define PY_SSIZE_T_MIN INT_MIN
+ #define PY_SSIZE_T_MAX INT_MAX
+ #define PY_FORMAT_SIZE_T ""
-/* python 2.2 does not have freefunc (it has destructor instead) */
-#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 3
-#define freefunc destructor
-#endif
+ #define readbufferproc getreadbufferproc
+ #define writebufferproc getwritebufferproc
+ #define segcountproc getsegcountproc
+ #define charbufferproc getcharbufferproc
-/* Py_VISIT and Py_CLEAR introduced in Python 2.4 */
-#ifndef Py_VISIT
-#define Py_VISIT(op) \
- do { \
- if (op) { \
- int vret = visit((op), arg); \
- if (vret) \
- return vret; \
- } \
- } while (0)
+ #define CONV_CODE_PY_SSIZE_T "i"
+#else
+ #define CONV_CODE_PY_SSIZE_T "n"
#endif
-#ifndef Py_CLEAR
-#define Py_CLEAR(op) \
- do { \
- if (op) { \
- PyObject *tmp = (PyObject *)(op); \
- (op) = NULL; \
- Py_DECREF(tmp); \
- } \
- } while (0)
+/* FORMAT_CODE_PY_SSIZE_T is for Py_ssize_t: */
+#define FORMAT_CODE_PY_SSIZE_T "%" PY_FORMAT_SIZE_T "d"
+
+/* FORMAT_CODE_SIZE_T is for plain size_t, not for Py_ssize_t: */
+#ifdef _MSC_VER
+ /* For MSVC: */
+ #define FORMAT_CODE_SIZE_T "%Iu"
+#else
+ /* C99 standard format code: */
+ #define FORMAT_CODE_SIZE_T "%zu"
#endif
#endif /* !defined(PSYCOPG_PYTHON_H) */
diff --git a/psycopg/typecast.c b/psycopg/typecast.c
index f786960..dcd9b37 100644
--- a/psycopg/typecast.c
+++ b/psycopg/typecast.c
@@ -167,21 +167,17 @@ typecast_parse_time(const char* s, const char** t, Py_ssize_t* len,
/** include casting objects **/
#include "psycopg/typecast_basic.c"
#include "psycopg/typecast_binary.c"
+#include "psycopg/typecast_datetime.c"
#ifdef HAVE_MXDATETIME
#include "psycopg/typecast_mxdatetime.c"
#endif
-#ifdef HAVE_PYDATETIME
-#include "psycopg/typecast_datetime.c"
-#endif
-
#include "psycopg/typecast_array.c"
#include "psycopg/typecast_builtins.c"
/* a list of initializers, used to make the typecasters accessible anyway */
-#ifdef HAVE_PYDATETIME
static typecastObject_initlist typecast_pydatetime[] = {
{"PYDATETIME", typecast_DATETIME_types, typecast_PYDATETIME_cast},
{"PYTIME", typecast_TIME_types, typecast_PYTIME_cast},
@@ -189,7 +185,6 @@ static typecastObject_initlist typecast_pydatetime[] = {
{"PYINTERVAL", typecast_INTERVAL_types, typecast_PYINTERVAL_cast},
{NULL, NULL, NULL}
};
-#endif
/* a list of initializers, used to make the typecasters accessible anyway */
#ifdef HAVE_MXDATETIME
@@ -267,7 +262,6 @@ typecast_init(PyObject *dict)
PyDict_SetItem(dict, t->name, (PyObject *)t);
}
#endif
-#ifdef HAVE_PYDATETIME
for (i = 0; typecast_pydatetime[i].name != NULL; i++) {
typecastObject *t;
Dprintf("typecast_init: initializing %s", typecast_pydatetime[i].name);
@@ -275,7 +269,6 @@ typecast_init(PyObject *dict)
if (t == NULL) return -1;
PyDict_SetItem(dict, t->name, (PyObject *)t);
}
-#endif
return 0;
}
diff --git a/psycopg/typecast_basic.c b/psycopg/typecast_basic.c
index c4f3cf6..5d91e3c 100644
--- a/psycopg/typecast_basic.c
+++ b/psycopg/typecast_basic.c
@@ -115,7 +115,6 @@ typecast_BOOLEAN_cast(const char *s, Py_ssize_t len, PyObject *curs)
/** DECIMAL - cast any kind of number into a Python Decimal object **/
-#ifdef HAVE_DECIMAL
static PyObject *
typecast_DECIMAL_cast(const char *s, Py_ssize_t len, PyObject *curs)
{
@@ -135,9 +134,6 @@ typecast_DECIMAL_cast(const char *s, Py_ssize_t len, PyObject *curs)
return res;
}
-#else
-#define typecast_DECIMAL_cast typecast_FLOAT_cast
-#endif
/* some needed aliases */
#define typecast_NUMBER_cast typecast_FLOAT_cast
diff --git a/setup.cfg b/setup.cfg
index 77247f3..1d6b215 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -12,12 +12,6 @@ define=PSYCOPG_EXTENSIONS,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3,PS
# Set to 1 to use Python datatime objects for default date/time representation
use_pydatetime=1
-# Set to 1 if you want to enable "Decimal" type on python 2.3.
-# If the "decimal" module is found in the PYTHONPATH it will be used, else
-# fall back on the float type (this is disabled by default to be compatible
-# with old versions of psycopg 1 and pre-beta versions of psycopg 2.)
-use_decimal=0
-
# If the build system does not find the mx.DateTime headers, try
# uncommenting the following line and setting its value to the right path.
#mx_include_dir=
diff --git a/setup.py b/setup.py
index 79a9093..10a0445 100644
--- a/setup.py
+++ b/setup.py
@@ -46,7 +46,7 @@ Operating System :: Unix
import os
import os.path
import sys
-import popen2
+import subprocess
import ConfigParser
from distutils.core import setup, Extension
from distutils.errors import DistutilsFileError
@@ -55,23 +55,19 @@ from distutils.sysconfig import get_python_inc
from distutils.ccompiler import get_default_compiler
PSYCOPG_VERSION = '2.0.8'
-version_flags = []
+version_flags = ['dt', 'dec']
PLATFORM_IS_WINDOWS = sys.platform.lower().startswith('win')
-# to work around older distutil limitations
-if sys.version < '2.2.3':
- from distutils.dist import DistributionMetadata
- DistributionMetadata.classifiers = None
- DistributionMetadata.download_url = None
-
def get_pg_config(kind, pg_config="pg_config"):
- if ' ' in pg_config:
- pg_config = '"'+pg_config+'"'
- p = popen2.popen3(pg_config + " --" + kind)
- r = p[0].readline().strip()
+ p = subprocess.Popen([pg_config, "--" + kind],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ p.stdin.close()
+ r = p.stdout.readline().strip()
if not r:
- raise Warning(p[2].readline())
+ raise Warning(p.stderr.readline())
return r
class psycopg_build_ext(build_ext):
@@ -90,14 +86,12 @@ class psycopg_build_ext(build_ext):
"Use Python datatime objects for date and time representation."),
('pg-config=', None,
"The name of the pg_config binary and/or full path to find it"),
- ('use-decimal', None,
- "Use Decimal type even on Python 2.3 if the module is provided."),
('have-ssl', None,
"Compile with OpenSSL built PostgreSQL libraries (Windows only)."),
])
boolean_options = build_ext.boolean_options[:]
- boolean_options.extend(('use-pydatetime', 'use-decimal', 'have-ssl'))
+ boolean_options.extend(('use-pydatetime', 'have-ssl'))
DEFAULT_PG_CONFIG = "pg_config"
@@ -311,14 +305,6 @@ class psycopg_build_ext(build_ext):
define_macros = []
include_dirs = []
-# python version
-define_macros.append(('PY_MAJOR_VERSION', str(sys.version_info[0])))
-define_macros.append(('PY_MINOR_VERSION', str(sys.version_info[1])))
-
-# some macros related to python versions and features
-if sys.version_info[0] >= 2 and sys.version_info[1] >= 3:
- define_macros.append(('HAVE_PYBOOL','1'))
-
# gather information to build the extension module
ext = [] ; data_files = []
@@ -330,20 +316,13 @@ sources = [
'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
'lobject_type.c', 'lobject_int.c',
'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c',
- 'adapter_asis.c', 'adapter_list.c', 'utils.c']
+ 'adapter_asis.c', 'adapter_list.c', 'adapter_datetime.c', 'utils.c']
parser = ConfigParser.ConfigParser()
parser.read('setup.cfg')
-# Choose if to use Decimal type
-use_decimal = int(parser.get('build_ext', 'use_decimal'))
-if sys.version_info[0] >= 2 and (
- sys.version_info[1] >= 4 or (sys.version_info[1] == 3 and use_decimal)):
- define_macros.append(('HAVE_DECIMAL','1'))
- version_flags.append('dec')
-
# Choose a datetime module
-have_pydatetime = False
+have_pydatetime = True
have_mxdatetime = False
use_pydatetime = int(parser.get('build_ext', 'use_pydatetime'))
@@ -359,16 +338,8 @@ if os.path.exists(mxincludedir):
have_mxdatetime = True
version_flags.append('mx')
-# check for python datetime package
-if os.path.exists(os.path.join(get_python_inc(plat_specific=1),"datetime.h")):
- define_macros.append(('HAVE_PYDATETIME','1'))
- sources.append('adapter_datetime.c')
- have_pydatetime = True
- version_flags.append('dt')
-
# now decide which package will be the default for date/time typecasts
-if have_pydatetime and use_pydatetime \
- or have_pydatetime and not have_mxdatetime:
+if have_pydatetime and (use_pydatetime or not have_mxdatetime):
define_macros.append(('PSYCOPG_DEFAULT_PYDATETIME','1'))
elif have_mxdatetime:
define_macros.append(('PSYCOPG_DEFAULT_MXDATETIME','1'))