diff --git a/ChangeLog b/ChangeLog index 00346cb1..f4fad03d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-04-10 Federico Di Gregorio + + * Applied super-patch from David Rushby to fix Python 2.5 and 64 + bit problems (all of them, kudos!) + 2007-02-22 Federico Di Gregorio * Added support for per-connection and per-cursor typecasters. diff --git a/MANIFEST.in b/MANIFEST.in index b895628a..9f436a88 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,8 +6,8 @@ recursive-include psycopg2da * recursive-include examples *.py somehackers.jpg whereareyou.jpg recursive-include debian * recursive-include doc TODO HACKING SUCCESS ChangeLog-1.x async.txt +recursive-include doc *.rst *.css *.html recursive-include scripts *.py *.sh include scripts/maketypes.sh scripts/buildtypes.py include AUTHORS README INSTALL LICENSE ChangeLog include PKG-INFO MANIFEST.in MANIFEST setup.py setup.cfg -recursive-include doc *.rst *.css *.html diff --git a/psycopg/adapter_asis.c b/psycopg/adapter_asis.c index 75ee0e49..2da0b5fb 100644 --- a/psycopg/adapter_asis.c +++ b/psycopg/adapter_asis.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -55,14 +56,14 @@ PyObject * asis_conform(asisObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -90,14 +91,18 @@ static PyMethodDef asisObject_methods[] = { static int asis_setup(asisObject *self, PyObject *obj) { - Dprintf("asis_setup: init asis object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("asis_setup: init asis object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); self->wrapped = obj; Py_INCREF(self->wrapped); - - Dprintf("asis_setup: good asis object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("asis_setup: good asis object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -107,10 +112,12 @@ asis_dealloc(PyObject* obj) asisObject *self = (asisObject *)obj; Py_XDECREF(self->wrapped); - - Dprintf("asis_dealloc: deleted asis object at %p, refcnt = %d", - obj, obj->ob_refcnt); - + + Dprintf("asis_dealloc: deleted asis object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); + obj->ob_type->tp_free(obj); } @@ -118,7 +125,7 @@ static int asis_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *o; - + if (!PyArg_ParseTuple(args, "O", &o)) return -1; @@ -127,7 +134,7 @@ asis_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * asis_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -159,7 +166,7 @@ PyTypeObject asisType = { 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -171,14 +178,14 @@ PyTypeObject asisType = { 0, /*tp_call*/ (reprfunc)asis_str, /*tp_str*/ - + 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ asisType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -195,11 +202,11 @@ PyTypeObject asisType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + asis_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ asis_new, /*tp_new*/ @@ -219,9 +226,9 @@ PyObject * psyco_AsIs(PyObject *module, PyObject *args) { PyObject *obj; - + if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; - + return PyObject_CallFunction((PyObject *)&asisType, "O", obj); } diff --git a/psycopg/adapter_asis.h b/psycopg/adapter_asis.h index 789dc41d..3a0ff80f 100644 --- a/psycopg/adapter_asis.h +++ b/psycopg/adapter_asis.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_ASIS_H #define PSYCOPG_ASIS_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -39,7 +40,7 @@ typedef struct { } asisObject; /* functions exported to psycopgmodule.c */ - + extern PyObject *psyco_AsIs(PyObject *module, PyObject *args); #define psyco_AsIs_doc \ "AsIs(obj) -> new AsIs wrapper object" diff --git a/psycopg/adapter_binary.c b/psycopg/adapter_binary.c index 030447b2..35c3d7f4 100644 --- a/psycopg/adapter_binary.c +++ b/psycopg/adapter_binary.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -38,8 +39,8 @@ #ifndef PSYCOPG_OWN_QUOTING static unsigned char * -binary_escape(unsigned char *from, unsigned int from_length, - unsigned int *to_length, PGconn *conn) +binary_escape(unsigned char *from, size_t from_length, + size_t *to_length, PGconn *conn) { #if PG_MAJOR_VERSION > 8 || \ (PG_MAJOR_VERSION == 8 && PG_MINOR_VERSION > 1) || \ @@ -52,11 +53,11 @@ binary_escape(unsigned char *from, unsigned int from_length, } #else static unsigned char * -binary_escape(unsigned char *from, unsigned int from_length, - unsigned int *to_length, PGconn *conn) +binary_escape(unsigned char *from, size_t from_length, + size_t *to_length, PGconn *conn) { - unsigneed char *quoted, *chptr, *newptr; - int i, space, new_space; + unsigned char *quoted, *chptr, *newptr; + size_t i, space, new_space; space = from_length + 2; @@ -67,7 +68,7 @@ binary_escape(unsigned char *from, unsigned int from_length, chptr = quoted; - for (i=0; i < len; i++) { + for (i = 0; i < from_length; i++) { if (chptr - quoted > space - 6) { new_space = space * ((space) / (i + 1)) + 2 + 6; if (new_space - space < 1024) space += 1024; @@ -102,7 +103,7 @@ binary_escape(unsigned char *from, unsigned int from_length, } else { unsigned char c; - + /* escape to octal notation \nnn */ *chptr++ = '\\'; *chptr++ = '\\'; @@ -122,7 +123,7 @@ binary_escape(unsigned char *from, unsigned int from_length, Py_END_ALLOW_THREADS; - *to_size = chptr - quoted + 1; + *to_length = chptr - quoted + 1; return quoted; } #endif @@ -142,26 +143,26 @@ binary_quote(binaryObject *self) /* escape and build quoted buffer */ PyObject_AsCharBuffer(self->wrapped, &buffer, &buffer_len); - to = (char *)binary_escape((unsigned char*)buffer, buffer_len, &len, - self->conn ? ((connectionObject*)self->conn)->pgconn : NULL); + to = (char *)binary_escape((unsigned char*)buffer, (size_t) buffer_len, + &len, self->conn ? ((connectionObject*)self->conn)->pgconn : NULL); if (to == NULL) { PyErr_NoMemory(); return NULL; } - if (len > 0) - self->buffer = PyString_FromFormat("'%s'", to); - else - self->buffer = PyString_FromString("''"); + if (len > 0) + self->buffer = PyString_FromFormat("'%s'", to); + else + self->buffer = PyString_FromString("''"); PQfreemem(to); } - - /* if the wrapped object is not a string or a buffer, this is an error */ + + /* if the wrapped object is not a string or a buffer, this is an error */ else { PyErr_SetString(PyExc_TypeError, "can't escape non-string object"); return NULL; } - + return self->buffer; } @@ -206,14 +207,14 @@ PyObject * binary_conform(binaryObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -244,16 +245,19 @@ static PyMethodDef binaryObject_methods[] = { static int binary_setup(binaryObject *self, PyObject *str) { - Dprintf("binary_setup: init binary object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("binary_setup: init binary object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); self->buffer = NULL; self->conn = NULL; self->wrapped = str; Py_INCREF(self->wrapped); - - Dprintf("binary_setup: good binary object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("binary_setup: good binary object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt); return 0; } @@ -265,10 +269,12 @@ binary_dealloc(PyObject* obj) Py_XDECREF(self->wrapped); Py_XDECREF(self->buffer); Py_XDECREF(self->conn); - - Dprintf("binary_dealloc: deleted binary object at %p, refcnt = %d", - obj, obj->ob_refcnt); - + + Dprintf("binary_dealloc: deleted binary object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); + obj->ob_type->tp_free(obj); } @@ -276,7 +282,7 @@ static int binary_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *str; - + if (!PyArg_ParseTuple(args, "O", &str)) return -1; @@ -285,7 +291,7 @@ binary_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -315,7 +321,7 @@ PyTypeObject binaryType = { binary_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)binary_repr, /*tp_repr*/ @@ -333,7 +339,7 @@ PyTypeObject binaryType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ binaryType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -350,11 +356,11 @@ PyTypeObject binaryType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + binary_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ binary_new, /*tp_new*/ @@ -374,9 +380,9 @@ PyObject * psyco_Binary(PyObject *module, PyObject *args) { PyObject *str; - + if (!PyArg_ParseTuple(args, "O", &str)) return NULL; - + return PyObject_CallFunction((PyObject *)&binaryType, "O", str); } diff --git a/psycopg/adapter_binary.h b/psycopg/adapter_binary.h index 5f2c7812..ea2e010e 100644 --- a/psycopg/adapter_binary.h +++ b/psycopg/adapter_binary.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_BINARY_H #define PSYCOPG_BINARY_H 1 +#define PY_SSIZE_T_CLEAN #include #include @@ -40,7 +41,7 @@ typedef struct { } binaryObject; /* functions exported to psycopgmodule.c */ - + extern PyObject *psyco_Binary(PyObject *module, PyObject *args); #define psyco_Binary_doc \ "Binary(buffer) -> new binary object\n\n" \ diff --git a/psycopg/adapter_datetime.c b/psycopg/adapter_datetime.c index fa00011f..449745b7 100644 --- a/psycopg/adapter_datetime.c +++ b/psycopg/adapter_datetime.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -62,11 +63,11 @@ pydatetime_str(pydatetimeObject *self) } else { PyDateTime_Delta *obj = (PyDateTime_Delta*)self->wrapped; - + char buffer[8]; int i; int a = obj->microseconds; - + for (i=0; i < 6 ; i++) { buffer[5-i] = '0' + (a % 10); a /= 10; @@ -89,14 +90,14 @@ PyObject * pydatetime_conform(pydatetimeObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -125,15 +126,19 @@ static PyMethodDef pydatetimeObject_methods[] = { static int pydatetime_setup(pydatetimeObject *self, PyObject *obj, int type) { - Dprintf("pydatetime_setup: init datetime object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("pydatetime_setup: init datetime object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); self->type = type; self->wrapped = obj; Py_INCREF(self->wrapped); - - Dprintf("pydatetime_setup: good pydatetime object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("pydatetime_setup: good pydatetime object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -143,10 +148,10 @@ pydatetime_dealloc(PyObject* obj) pydatetimeObject *self = (pydatetimeObject *)obj; Py_XDECREF(self->wrapped); - + Dprintf("mpydatetime_dealloc: deleted pydatetime object at %p, " - "refcnt = %d", obj, obj->ob_refcnt); - + "refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, obj->ob_refcnt); + obj->ob_type->tp_free(obj); } @@ -155,7 +160,7 @@ pydatetime_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *dt; int type = -1; /* raise an error if type was not passed! */ - + if (!PyArg_ParseTuple(args, "O|i", &dt, &type)) return -1; @@ -164,7 +169,7 @@ pydatetime_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * pydatetime_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -195,7 +200,7 @@ PyTypeObject pydatetimeType = { pydatetime_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)pydatetime_repr, /*tp_repr*/ @@ -213,7 +218,7 @@ PyTypeObject pydatetimeType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ pydatetimeType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -230,11 +235,11 @@ PyTypeObject pydatetimeType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + pydatetime_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ pydatetime_new, /*tp_new*/ @@ -253,15 +258,15 @@ PyTypeObject pydatetimeType = { #ifdef PSYCOPG_DEFAULT_PYDATETIME PyObject * -psyco_Date(PyObject *self, PyObject *args) +psyco_Date(PyObject *self, PyObject *args) { - PyObject *res = NULL; - int year, month, day; + PyObject *res = NULL; + int year, month, day; PyObject* obj = NULL; - - if (!PyArg_ParseTuple(args, "iii", &year, &month, &day)) - return NULL; + + if (!PyArg_ParseTuple(args, "iii", &year, &month, &day)) + return NULL; obj = PyObject_CallFunction(pyDateTypeP, "iii", year, month, day); @@ -275,18 +280,18 @@ psyco_Date(PyObject *self, PyObject *args) } PyObject * -psyco_Time(PyObject *self, PyObject *args) +psyco_Time(PyObject *self, PyObject *args) { PyObject *res = NULL; PyObject *tzinfo = NULL; int hours, minutes=0; double micro, second=0.0; - + PyObject* obj = NULL; if (!PyArg_ParseTuple(args, "iid|O", &hours, &minutes, &second, &tzinfo)) - return NULL; + return NULL; micro = (second - floor(second)) * 1000000.0; second = floor(second); @@ -297,7 +302,7 @@ psyco_Time(PyObject *self, PyObject *args) else obj = PyObject_CallFunction(pyTimeTypeP, "iiiiO", hours, minutes, (int)second, (int)round(micro), tzinfo); - + if (obj) { res = PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, PSYCO_DATETIME_TIME); @@ -308,7 +313,7 @@ psyco_Time(PyObject *self, PyObject *args) } PyObject * -psyco_Timestamp(PyObject *self, PyObject *args) +psyco_Timestamp(PyObject *self, PyObject *args) { PyObject *res = NULL; PyObject *tzinfo = NULL; @@ -317,10 +322,10 @@ psyco_Timestamp(PyObject *self, PyObject *args) double micro, second=0.0; PyObject* obj = NULL; - + if (!PyArg_ParseTuple(args, "lii|iidO", &year, &month, &day, &hour, &minute, &second, &tzinfo)) - return NULL; + return NULL; micro = (second - floor(second)) * 1000000.0; second = floor(second); @@ -333,13 +338,13 @@ psyco_Timestamp(PyObject *self, PyObject *args) obj = PyObject_CallFunction(pyDateTimeTypeP, "iiiiiiiO", year, month, day, hour, minute, (int)second, (int)round(micro), tzinfo); - + if (obj) { res = PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, PSYCO_DATETIME_TIMESTAMP); Py_DECREF(obj); } - + return res; } @@ -361,8 +366,8 @@ psyco_DateFromTicks(PyObject *self, PyObject *args) res = psyco_Date(self, args); Py_DECREF(args); } - } - return res; + } + return res; } PyObject * @@ -380,13 +385,13 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args) ticks -= (double)t; if (localtime_r(&t, &tm)) { args = Py_BuildValue("iid", tm.tm_hour, tm.tm_min, - (double)tm.tm_sec + ticks); + (double)tm.tm_sec + ticks); if (args) { res = psyco_Time(self, args); Py_DECREF(args); } - } - return res; + } + return res; } PyObject * @@ -399,21 +404,21 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args,"d", &ticks)) return NULL; - + t = (time_t)round(ticks); ticks -= (double)t; if (localtime_r(&t, &tm)) { args = Py_BuildValue("iiiiidO", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, - (double)tm.tm_sec + ticks, + (double)tm.tm_sec + ticks, pyPsycopgTzLOCAL); if (args) { res = psyco_Timestamp(self, args); Py_DECREF(args); } - } - return res; + } + return res; } #endif @@ -425,7 +430,7 @@ psyco_DateFromPy(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", pyDateTypeP, &obj)) return NULL; - + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, PSYCO_DATETIME_DATE); } @@ -437,7 +442,7 @@ psyco_TimeFromPy(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", pyTimeTypeP, &obj)) return NULL; - + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, PSYCO_DATETIME_TIME); } @@ -449,7 +454,7 @@ psyco_TimestampFromPy(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", pyDateTimeTypeP, &obj)) return NULL; - + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, PSYCO_DATETIME_TIMESTAMP); } @@ -461,7 +466,7 @@ psyco_IntervalFromPy(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", pyDeltaTypeP, &obj)) return NULL; - + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, PSYCO_DATETIME_INTERVAL); } diff --git a/psycopg/adapter_datetime.h b/psycopg/adapter_datetime.h index 0827fe3a..4530b9a9 100644 --- a/psycopg/adapter_datetime.h +++ b/psycopg/adapter_datetime.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_DATETIME_H #define PSYCOPG_DATETIME_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -38,14 +39,14 @@ typedef struct { #define PSYCO_DATETIME_TIME 0 #define PSYCO_DATETIME_DATE 1 #define PSYCO_DATETIME_TIMESTAMP 2 -#define PSYCO_DATETIME_INTERVAL 3 - +#define PSYCO_DATETIME_INTERVAL 3 + } pydatetimeObject; - - + + /* functions exported to psycopgmodule.c */ #ifdef PSYCOPG_DEFAULT_PYDATETIME - + extern PyObject *psyco_Date(PyObject *module, PyObject *args); #define psyco_Date_doc \ "Date(year, month, day) -> new date\n\n" \ @@ -99,7 +100,7 @@ extern PyObject *psyco_TimestampFromPy(PyObject *module, PyObject *args); extern PyObject *psyco_IntervalFromPy(PyObject *module, PyObject *args); #define psyco_IntervalFromPy_doc \ "IntervalFromPy(datetime.timedelta) -> new wrapper" - + #ifdef __cplusplus } #endif diff --git a/psycopg/adapter_list.c b/psycopg/adapter_list.c index 37a3b933..f65247d4 100644 --- a/psycopg/adapter_list.c +++ b/psycopg/adapter_list.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -43,20 +44,20 @@ list_quote(listObject *self) Py_ssize_t i, len; len = PyList_GET_SIZE(self->wrapped); - + /* empty arrays are converted to NULLs (still searching for a way to insert an empty array in postgresql */ if (len == 0) return PyString_FromString("'{}'"); - + tmp = PyTuple_New(len); - + for (i=0; iwrapped, i); - if (wrapped == Py_None) - quoted = PyString_FromString("NULL"); - else - quoted = microprotocol_getquoted(wrapped, + PyObject *wrapped = PyList_GET_ITEM(self->wrapped, i); + if (wrapped == Py_None) + quoted = PyString_FromString("NULL"); + else + quoted = microprotocol_getquoted(wrapped, (connectionObject*)self->connection); if (quoted == NULL) goto error; @@ -73,7 +74,7 @@ list_quote(listObject *self) if (joined == NULL) goto error; res = PyString_FromFormat("ARRAY[%s]", PyString_AsString(joined)); - + error: Py_XDECREF(tmp); Py_XDECREF(str); @@ -110,7 +111,7 @@ list_prepare(listObject *self, PyObject *args) Py_XDECREF(self->connection); self->connection = (PyObject*)conn; Py_INCREF(self->connection); - + Py_INCREF(Py_None); return Py_None; } @@ -119,14 +120,14 @@ PyObject * list_conform(listObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -146,7 +147,7 @@ static PyMethodDef listObject_methods[] = { {"getquoted", (PyCFunction)list_getquoted, METH_VARARGS, "getquoted() -> wrapped object value as SQL date/time"}, {"prepare", (PyCFunction)list_prepare, METH_VARARGS, - "prepare(conn) -> set encoding to conn->encoding"}, + "prepare(conn) -> set encoding to conn->encoding"}, {"__conform__", (PyCFunction)list_conform, METH_VARARGS, NULL}, {NULL} /* Sentinel */ }; @@ -156,8 +157,10 @@ static PyMethodDef listObject_methods[] = { static int list_setup(listObject *self, PyObject *obj, char *enc) { - Dprintf("list_setup: init list object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("list_setup: init list object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); if (!PyList_Check(obj)) return -1; @@ -168,9 +171,11 @@ list_setup(listObject *self, PyObject *obj, char *enc) self->connection = NULL; self->wrapped = obj; Py_INCREF(self->wrapped); - - Dprintf("list_setup: good list object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("list_setup: good list object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -182,10 +187,10 @@ list_dealloc(PyObject* obj) Py_XDECREF(self->wrapped); Py_XDECREF(self->connection); if (self->encoding) free(self->encoding); - + Dprintf("list_dealloc: deleted list object at %p, " - "refcnt = %d", obj, obj->ob_refcnt); - + "refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, obj->ob_refcnt); + obj->ob_type->tp_free(obj); } @@ -194,7 +199,7 @@ list_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *l; char *enc = "latin-1"; /* default encoding as in Python */ - + if (!PyArg_ParseTuple(args, "O|s", &l, &enc)) return -1; @@ -203,7 +208,7 @@ list_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * list_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -233,7 +238,7 @@ PyTypeObject listType = { list_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)list_repr, /*tp_repr*/ @@ -251,7 +256,7 @@ PyTypeObject listType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ listType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -268,11 +273,11 @@ PyTypeObject listType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + list_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ list_new, /*tp_new*/ @@ -293,9 +298,9 @@ psyco_List(PyObject *module, PyObject *args) { PyObject *str; char *enc = "latin-1"; /* default encoding as in Python */ - + if (!PyArg_ParseTuple(args, "O|s", &str, &enc)) return NULL; - + return PyObject_CallFunction((PyObject *)&listType, "Os", str, enc); } diff --git a/psycopg/adapter_list.h b/psycopg/adapter_list.h index 22a41b1f..9ffc52eb 100644 --- a/psycopg/adapter_list.h +++ b/psycopg/adapter_list.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_LIST_H #define PSYCOPG_LIST_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus diff --git a/psycopg/adapter_mxdatetime.c b/psycopg/adapter_mxdatetime.c index f4374353..2d3d1e87 100644 --- a/psycopg/adapter_mxdatetime.c +++ b/psycopg/adapter_mxdatetime.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -68,23 +69,23 @@ mxdatetime_str(mxdatetimeObject *self) /* given the limitation of the mx.DateTime module that uses the same type for both time and delta values we need to do some black magic and make sure we're not using an adapt()ed interval as a simple - time */ + time */ if (PyString_Size(str) > 8 && PyString_AsString(str)[8] == ':') { mxDateTimeDeltaObject *obj = (mxDateTimeDeltaObject*)self->wrapped; - + char buffer[8]; int i, j, x; - + double ss = obj->hour*3600.0 + obj->minute*60.0 + obj->second; int us = (int)((ss - floor(ss))*1000000); - + for (i=1000000, j=0; i > 0 ; i /= 10) { x = us/i; us -= x*i; buffer[j++] = '0'+x; } buffer[j] = '\0'; - + res = PyString_FromFormat("'%ld days %d.%s seconds'", obj->day, (int)round(ss), buffer); } @@ -94,7 +95,7 @@ mxdatetime_str(mxdatetimeObject *self) if (str != NULL && res == NULL) { res = PyString_FromFormat("'%s'", PyString_AsString(str)); } - Py_XDECREF(str); + Py_XDECREF(str); return res; } @@ -110,14 +111,14 @@ PyObject * mxdatetime_conform(mxdatetimeObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -146,15 +147,19 @@ static PyMethodDef mxdatetimeObject_methods[] = { static int mxdatetime_setup(mxdatetimeObject *self, PyObject *obj, int type) { - Dprintf("mxdatetime_setup: init mxdatetime object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("mxdatetime_setup: init mxdatetime object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); self->type = type; self->wrapped = obj; Py_INCREF(self->wrapped); - - Dprintf("mxdatetime_setup: good mxdatetime object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("mxdatetime_setup: good mxdatetime object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -164,10 +169,12 @@ mxdatetime_dealloc(PyObject* obj) mxdatetimeObject *self = (mxdatetimeObject *)obj; Py_XDECREF(self->wrapped); - - Dprintf("mxdatetime_dealloc: deleted mxdatetime object at %p, refcnt = %d", - obj, obj->ob_refcnt); - + + Dprintf("mxdatetime_dealloc: deleted mxdatetime object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); + obj->ob_type->tp_free(obj); } @@ -176,7 +183,7 @@ mxdatetime_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *mx; int type = -1; /* raise an error if type was not passed! */ - + if (!PyArg_ParseTuple(args, "O|i", &mx, &type)) return -1; @@ -185,7 +192,7 @@ mxdatetime_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * mxdatetime_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -216,7 +223,7 @@ PyTypeObject mxdatetimeType = { mxdatetime_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)mxdatetime_repr, /*tp_repr*/ @@ -234,7 +241,7 @@ PyTypeObject mxdatetimeType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ mxdatetimeType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -251,11 +258,11 @@ PyTypeObject mxdatetimeType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + mxdatetime_init, /*tp_init*/ 0, /*tp_alloc*/ mxdatetime_new, /*tp_new*/ @@ -274,15 +281,15 @@ PyTypeObject mxdatetimeType = { #ifdef PSYCOPG_DEFAULT_MXDATETIME PyObject * -psyco_Date(PyObject *self, PyObject *args) +psyco_Date(PyObject *self, PyObject *args) { - PyObject *res, *mx; - int year, month, day; - - if (!PyArg_ParseTuple(args, "iii", &year, &month, &day)) - return NULL; - - mx = mxDateTimeP->DateTime_FromDateAndTime(year, month, day, 0, 0, 0.0); + PyObject *res, *mx; + int year, month, day; + + if (!PyArg_ParseTuple(args, "iii", &year, &month, &day)) + return NULL; + + mx = mxDateTimeP->DateTime_FromDateAndTime(year, month, day, 0, 0, 0.0); if (mx == NULL) return NULL; res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, @@ -292,35 +299,35 @@ psyco_Date(PyObject *self, PyObject *args) } PyObject * -psyco_Time(PyObject *self, PyObject *args) +psyco_Time(PyObject *self, PyObject *args) { - PyObject *res, *mx; + PyObject *res, *mx; int hours, minutes=0; - double seconds=0.0; + double seconds=0.0; if (!PyArg_ParseTuple(args, "iid", &hours, &minutes, &seconds)) - return NULL; - - mx = mxDateTimeP->DateTimeDelta_FromTime(hours, minutes, seconds); + return NULL; + + mx = mxDateTimeP->DateTimeDelta_FromTime(hours, minutes, seconds); if (mx == NULL) return NULL; res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_TIME); Py_DECREF(mx); - return res; + return res; } PyObject * -psyco_Timestamp(PyObject *self, PyObject *args) +psyco_Timestamp(PyObject *self, PyObject *args) { - PyObject *res, *mx; + PyObject *res, *mx; int year, month, day; - int hour=0, minute=0; /* default to midnight */ - double second=0.0; - + int hour=0, minute=0; /* default to midnight */ + double second=0.0; + if (!PyArg_ParseTuple(args, "lii|iid", &year, &month, &day, &hour, &minute, &second)) - return NULL; + return NULL; mx = mxDateTimeP->DateTime_FromDateAndTime(year, month, day, hour, minute, second); @@ -329,7 +336,7 @@ psyco_Timestamp(PyObject *self, PyObject *args) res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_TIMESTAMP); Py_DECREF(mx); - return res; + return res; } PyObject * @@ -340,14 +347,14 @@ psyco_DateFromTicks(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args,"d", &ticks)) return NULL; - + if (!(mx = mxDateTimeP->DateTime_FromTicks(ticks))) return NULL; - + res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_DATE); Py_DECREF(mx); - return res; + return res; } PyObject * @@ -358,7 +365,7 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args,"d", &ticks)) return NULL; - + if (!(dt = mxDateTimeP->DateTime_FromTicks(ticks))) return NULL; @@ -373,7 +380,7 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args) res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_TIME); Py_DECREF(mx); - return res; + return res; } PyObject * @@ -384,14 +391,14 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "d", &ticks)) return NULL; - + if (!(mx = mxDateTimeP->DateTime_FromTicks(ticks))) return NULL; res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_TIMESTAMP); Py_DECREF(mx); - return res; + return res; } #endif @@ -403,7 +410,7 @@ psyco_DateFromMx(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTime_Type, &mx)) return NULL; - + return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_DATE); } @@ -415,7 +422,7 @@ psyco_TimeFromMx(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTimeDelta_Type, &mx)) return NULL; - + return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_TIME); } @@ -427,7 +434,7 @@ psyco_TimestampFromMx(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTime_Type, &mx)) return NULL; - + return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_TIMESTAMP); } @@ -439,7 +446,7 @@ psyco_IntervalFromMx(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTime_Type, &mx)) return NULL; - + return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx, PSYCO_MXDATETIME_INTERVAL); } diff --git a/psycopg/adapter_mxdatetime.h b/psycopg/adapter_mxdatetime.h index 4811d535..c8cc2d80 100644 --- a/psycopg/adapter_mxdatetime.h +++ b/psycopg/adapter_mxdatetime.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_MXDATETIME_H #define PSYCOPG_MXDATETIME_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -38,13 +39,13 @@ typedef struct { #define PSYCO_MXDATETIME_TIME 0 #define PSYCO_MXDATETIME_DATE 1 #define PSYCO_MXDATETIME_TIMESTAMP 2 -#define PSYCO_MXDATETIME_INTERVAL 3 - +#define PSYCO_MXDATETIME_INTERVAL 3 + } mxdatetimeObject; - + /* functions exported to psycopgmodule.c */ #ifdef PSYCOPG_DEFAULT_MXDATETIME - + extern PyObject *psyco_Date(PyObject *module, PyObject *args); #define psyco_Date_doc \ "Date(year, month, day) -> new date" @@ -56,7 +57,7 @@ extern PyObject *psyco_Time(PyObject *module, PyObject *args); extern PyObject *psyco_Timestamp(PyObject *module, PyObject *args); #define psyco_Timestamp_doc \ "Time(year, month, day, hour, minutes, seconds) -> new timestamp" - + extern PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args); #define psyco_DateFromTicks_doc \ "DateFromTicks(ticks) -> new date" @@ -86,7 +87,7 @@ extern PyObject *psyco_TimestampFromMx(PyObject *module, PyObject *args); extern PyObject *psyco_IntervalFromMx(PyObject *module, PyObject *args); #define psyco_IntervalFromMx_doc \ "IntervalFromMx(mx) -> new interval" - + #ifdef __cplusplus } #endif diff --git a/psycopg/adapter_pboolean.c b/psycopg/adapter_pboolean.c index fa70ad03..405da4a6 100644 --- a/psycopg/adapter_pboolean.c +++ b/psycopg/adapter_pboolean.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -65,14 +66,14 @@ PyObject * pboolean_conform(pbooleanObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -100,14 +101,18 @@ static PyMethodDef pbooleanObject_methods[] = { static int pboolean_setup(pbooleanObject *self, PyObject *obj) { - Dprintf("pboolean_setup: init pboolean object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("pboolean_setup: init pboolean object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); self->wrapped = obj; Py_INCREF(self->wrapped); - - Dprintf("pboolean_setup: good pboolean object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("pboolean_setup: good pboolean object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -117,10 +122,12 @@ pboolean_dealloc(PyObject* obj) pbooleanObject *self = (pbooleanObject *)obj; Py_XDECREF(self->wrapped); - - Dprintf("pboolean_dealloc: deleted pboolean object at %p, refcnt = %d", - obj, obj->ob_refcnt); - + + Dprintf("pboolean_dealloc: deleted pboolean object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); + obj->ob_type->tp_free(obj); } @@ -128,7 +135,7 @@ static int pboolean_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *o; - + if (!PyArg_ParseTuple(args, "O", &o)) return -1; @@ -137,7 +144,7 @@ pboolean_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * pboolean_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -170,7 +177,7 @@ PyTypeObject pbooleanType = { 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -182,14 +189,14 @@ PyTypeObject pbooleanType = { 0, /*tp_call*/ (reprfunc)pboolean_str, /*tp_str*/ - + 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ pbooleanType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -206,11 +213,11 @@ PyTypeObject pbooleanType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + pboolean_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ pboolean_new, /*tp_new*/ @@ -230,9 +237,9 @@ PyObject * psyco_Boolean(PyObject *module, PyObject *args) { PyObject *obj; - + if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; - + return PyObject_CallFunction((PyObject *)&pbooleanType, "O", obj); } diff --git a/psycopg/adapter_pboolean.h b/psycopg/adapter_pboolean.h index d50b767b..4349ddc4 100644 --- a/psycopg/adapter_pboolean.h +++ b/psycopg/adapter_pboolean.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_PBOOLEAN_H #define PSYCOPG_PBOOLEAN_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -39,7 +40,7 @@ typedef struct { } pbooleanObject; /* functions exported to psycopgmodule.c */ - + extern PyObject *psyco_Boolean(PyObject *module, PyObject *args); #define psyco_Boolean_doc \ "Boolean(obj) -> new boolean value" diff --git a/psycopg/adapter_qstring.c b/psycopg/adapter_qstring.c index 90775dc4..bb21ad84 100644 --- a/psycopg/adapter_qstring.c +++ b/psycopg/adapter_qstring.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -100,7 +101,7 @@ qstring_quote(qstringObject *self) /* TODO: we need a real translation table from postgres encoding names to python ones here */ - + Dprintf("qstring_quote: encoding to %s", self->encoding); if (PyUnicode_Check(self->wrapped) && self->encoding) { @@ -129,8 +130,8 @@ qstring_quote(qstringObject *self) /* INCREF to make it ref-wise identical to unicode one */ Py_INCREF(str); } - - /* if the wrapped object is not a string, this is an error */ + + /* if the wrapped object is not a string, this is an error */ else { PyErr_SetString(PyExc_TypeError, "can't quote non-string object (or missing encoding)"); @@ -139,7 +140,7 @@ qstring_quote(qstringObject *self) /* encode the string into buffer */ PyString_AsStringAndSize(str, &s, &len); - + buffer = (char *)PyMem_Malloc((len*2+3) * sizeof(char)); if (buffer == NULL) { Py_DECREF(str); @@ -152,11 +153,11 @@ qstring_quote(qstringObject *self) self->conn ? ((connectionObject*)self->conn)->pgconn : NULL); buffer[0] = '\'' ; buffer[len+1] = '\''; Py_END_ALLOW_THREADS; - + self->buffer = PyString_FromStringAndSize(buffer, len+2); PyMem_Free(buffer); Py_DECREF(str); - + return self->buffer; } @@ -204,19 +205,19 @@ qstring_prepare(qstringObject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } - + PyObject * qstring_conform(qstringObject *self, PyObject *args) { PyObject *res, *proto; - + if (!PyArg_ParseTuple(args, "O", &proto)) return NULL; if (proto == (PyObject*)&isqlquoteType) res = (PyObject*)self; else res = Py_None; - + Py_INCREF(res); return res; } @@ -248,20 +249,24 @@ static PyMethodDef qstringObject_methods[] = { static int qstring_setup(qstringObject *self, PyObject *str, char *enc) { - Dprintf("qstring_setup: init qstring object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("qstring_setup: init qstring object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); self->buffer = NULL; self->conn = NULL; /* FIXME: remove this orrible strdup */ if (enc) self->encoding = strdup(enc); - + self->wrapped = str; Py_INCREF(self->wrapped); - - Dprintf("qstring_setup: good qstring object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("qstring_setup: good qstring object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -275,10 +280,12 @@ qstring_dealloc(PyObject* obj) Py_XDECREF(self->conn); if (self->encoding) free(self->encoding); - - Dprintf("qstring_dealloc: deleted qstring object at %p, refcnt = %d", - obj, obj->ob_refcnt); - + + Dprintf("qstring_dealloc: deleted qstring object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); + obj->ob_type->tp_free(obj); } @@ -287,7 +294,7 @@ qstring_init(PyObject *obj, PyObject *args, PyObject *kwds) { PyObject *str; char *enc = "latin-1"; /* default encoding as in Python */ - + if (!PyArg_ParseTuple(args, "O|s", &str, &enc)) return -1; @@ -296,7 +303,7 @@ qstring_init(PyObject *obj, PyObject *args, PyObject *kwds) static PyObject * qstring_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ return type->tp_alloc(type, 0); } @@ -309,7 +316,7 @@ qstring_del(PyObject* self) static PyObject * qstring_repr(qstringObject *self) { - return PyString_FromFormat("", + return PyString_FromFormat("", self); } @@ -327,7 +334,7 @@ PyTypeObject qstringType = { qstring_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)qstring_repr, /*tp_repr*/ @@ -345,7 +352,7 @@ PyTypeObject qstringType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ qstringType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -362,11 +369,11 @@ PyTypeObject qstringType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + qstring_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ qstring_new, /*tp_new*/ @@ -387,9 +394,9 @@ psyco_QuotedString(PyObject *module, PyObject *args) { PyObject *str; char *enc = "latin-1"; /* default encoding as in Python */ - + if (!PyArg_ParseTuple(args, "O|s", &str, &enc)) return NULL; - + return PyObject_CallFunction((PyObject *)&qstringType, "Os", str, enc); } diff --git a/psycopg/adapter_qstring.h b/psycopg/adapter_qstring.h index 61c1a8ae..572a2a58 100644 --- a/psycopg/adapter_qstring.h +++ b/psycopg/adapter_qstring.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_QSTRING_H #define PSYCOPG_QSTRING_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -39,9 +40,9 @@ typedef struct { PyObject *conn; } qstringObject; - + /* functions exported to psycopgmodule.c */ - + extern PyObject *psyco_QuotedString(PyObject *module, PyObject *args); #define psyco_QuotedString_doc \ "QuotedString(str, enc) -> new quoted string" diff --git a/psycopg/config.h b/psycopg/config.h index 649fee8b..e21e8190 100644 --- a/psycopg/config.h +++ b/psycopg/config.h @@ -28,7 +28,7 @@ #include #include #define Dprintf(fmt, args...) \ - fprintf(stderr, "[%d] " fmt "\n", getpid() , ## args) + fprintf(stderr, "[%d] " fmt "\n", (int) getpid() , ## args) #else #define Dprintf(fmt, args...) #endif diff --git a/psycopg/connection.h b/psycopg/connection.h index fed10c14..baed6a2b 100644 --- a/psycopg/connection.h +++ b/psycopg/connection.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_CONNECTION_H #define PSYCOPG_CONNECTION_H 1 +#define PY_SSIZE_T_CLEAN #include #include @@ -34,7 +35,7 @@ extern "C" { #define CONN_STATUS_BEGIN 2 #define CONN_STATUS_SYNC 3 #define CONN_STATUS_ASYNC 4 - + extern PyTypeObject connectionType; typedef struct { @@ -45,17 +46,17 @@ typedef struct { char *dsn; /* data source name */ char *critical; /* critical error on this connection */ char *encoding; /* current backend encoding */ - + long int closed; /* 2 means connection has been closed */ long int isolation_level; /* isolation level for this connection */ - long int mark; /* number of commits/rollbacks done so far */ + long int mark; /* number of commits/rollbacks done so far */ int status; /* status of the connection */ int protocol; /* protocol version */ - + PGconn *pgconn; /* the postgresql connection */ PyObject *async_cursor; - + /* notice processing */ PyObject *notice_list; PyObject *notice_filter; @@ -80,20 +81,20 @@ typedef struct { PyObject *binary_types; /* a set of typecasters for binary types */ } connectionObject; - + /* C-callable functions in connection_int.c and connection_ext.c */ extern int conn_connect(connectionObject *self); extern void conn_close(connectionObject *self); extern int conn_commit(connectionObject *self); extern int conn_rollback(connectionObject *self); extern int conn_switch_isolation_level(connectionObject *self, int level); -extern int conn_set_client_encoding(connectionObject *self, char *enc); +extern int conn_set_client_encoding(connectionObject *self, char *enc); /* exception-raising macros */ #define EXC_IF_CONN_CLOSED(self) if ((self)->closed > 0) { \ PyErr_SetString(InterfaceError, "connection already closed"); \ return NULL; } - + #ifdef __cplusplus } #endif diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index e3386468..5c4a02f3 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include @@ -55,22 +56,22 @@ conn_connect(connectionObject *self) PGresult *pgres; char *data, *tmp; int i; - + /* we need the initial date style to be ISO, for typecasters; if the user later change it, she must know what she's doing... */ const char *datestyle = "SET DATESTYLE TO 'ISO'"; const char *encoding = "SHOW client_encoding"; const char *isolevel = "SHOW default_transaction_isolation"; - + const char *lvl1a = "read uncommitted"; const char *lvl1b = "read committed"; const char *lvl2a = "repeatable read"; const char *lvl2b = "serializable"; - + Py_BEGIN_ALLOW_THREADS; pgconn = PQconnectdb(self->dsn); Py_END_ALLOW_THREADS; - + Dprintf("conn_connect: new postgresql connection at %p", pgconn); if (pgconn == NULL) @@ -118,12 +119,12 @@ conn_connect(connectionObject *self) PQfinish(pgconn); IFCLEARPGRES(pgres); return -1; - } + } for (i=0 ; i < strlen(tmp) ; i++) self->encoding[i] = toupper(tmp[i]); self->encoding[i] = '\0'; CLEARPGRES(pgres); - + Py_BEGIN_ALLOW_THREADS; pgres = PQexec(pgconn, isolevel); Py_END_ALLOW_THREADS; @@ -159,7 +160,7 @@ conn_connect(connectionObject *self) self->protocol = 2; #endif Dprintf("conn_connect: using protocol %d", self->protocol); - + self->pgconn = pgconn; return 0; } @@ -178,7 +179,7 @@ conn_close(connectionObject *self) self->closed = 1; /* execute a forced rollback on the connection (but don't check the - result, we're going to close the pq connection anyway */ + result, we're going to close the pq connection anyway */ if (self->pgconn) { pq_abort(self); PQfinish(self->pgconn); @@ -203,7 +204,7 @@ conn_commit(connectionObject *self) res = pq_commit(self); self->mark++; - + pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; @@ -222,7 +223,7 @@ conn_rollback(connectionObject *self) res = pq_abort(self); self->mark++; - + pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; @@ -241,7 +242,7 @@ conn_switch_isolation_level(connectionObject *self, int level) Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); - + /* if the current isolation level is > 0 we need to abort the current transaction before changing; that all folks! */ if (self->isolation_level != level && self->isolation_level > 0) { @@ -249,13 +250,13 @@ conn_switch_isolation_level(connectionObject *self, int level) } self->isolation_level = level; self->mark++; - + Dprintf("conn_switch_isolation_level: switched to level %d", level); - + pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; - return res; + return res; } /* conn_set_client_encoding - switch client encoding on connection */ @@ -266,16 +267,16 @@ conn_set_client_encoding(connectionObject *self, char *enc) PGresult *pgres; char query[48]; int res = 0; - + /* If the current encoding is equal to the requested one we don't issue any query to the backend */ if (strcmp(self->encoding, enc) == 0) return 0; /* TODO: check for async query here and raise error if necessary */ - + Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); - + /* set encoding, no encoding string is longer than 24 bytes */ PyOS_snprintf(query, 47, "SET client_encoding = '%s'", enc); @@ -297,14 +298,14 @@ conn_set_client_encoding(connectionObject *self, char *enc) IFCLEARPGRES(pgres); } - + Dprintf("conn_set_client_encoding: set encoding to %s", self->encoding); - + pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; if (res == -1) PyErr_Format(OperationalError, "can't set encoding to %s", enc); - - return res; + + return res; } diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 026d9bf7..3e3448b7 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -52,7 +53,7 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds) PyObject *obj, *factory = NULL; static char *kwlist[] = {"name", "cursor_factory", NULL}; - + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sO", kwlist, &name, &factory)) { return NULL; @@ -62,10 +63,10 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds) Dprintf("psyco_conn_cursor: new cursor for connection at %p", self); Dprintf("psyco_conn_cursor: parameters: name = %s", name); - + if (factory == NULL) factory = (PyObject *)&cursorType; if (name) - obj = PyObject_CallFunction(factory, "Os", self, name); + obj = PyObject_CallFunction(factory, "Os", self, name); else obj = PyObject_CallFunction(factory, "O", self); @@ -76,9 +77,11 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds) Py_DECREF(obj); return NULL; } - - Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = %d", - obj, obj->ob_refcnt); + + Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); return obj; } @@ -93,7 +96,7 @@ psyco_conn_close(connectionObject *self, PyObject *args) EXC_IF_CONN_CLOSED(self); if (!PyArg_ParseTuple(args, "")) return NULL; - + Dprintf("psyco_conn_close: closing connection at %p", self); conn_close(self); Dprintf("psyco_conn_close: connection at %p closed", self); @@ -152,7 +155,7 @@ static PyObject * psyco_conn_set_isolation_level(connectionObject *self, PyObject *args) { int level = 1; - + EXC_IF_CONN_CLOSED(self); if (!PyArg_ParseTuple(args, "i", &level)) return NULL; @@ -162,7 +165,7 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args) "isolation level out of bounds (0,3)"); return NULL; } - + /* FIXME: check return status? */ conn_switch_isolation_level(self, level); @@ -186,19 +189,19 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args) EXC_IF_CONN_CLOSED(self); if (!PyArg_ParseTuple(args, "s", &enc)) return NULL; - + /* convert to upper case and remove '-' and '_' from string */ buffer = PyMem_Malloc(strlen(enc)); for (i=j=0 ; i < strlen(enc) ; i++) { if (enc[i] == '_' || enc[i] == '-') - continue; - else - buffer[j++] = toupper(enc[i]); + continue; + else + buffer[j++] = toupper(enc[i]); } buffer[j] = '\0'; if (conn_set_client_encoding(self, buffer) == 0) { - PyMem_Free(buffer); + PyMem_Free(buffer); Py_INCREF(Py_None); return Py_None; } @@ -228,8 +231,8 @@ static struct PyMethodDef connectionObject_methods[] = { {"set_isolation_level", (PyCFunction)psyco_conn_set_isolation_level, METH_VARARGS, psyco_conn_set_isolation_level_doc}, {"set_client_encoding", (PyCFunction)psyco_conn_set_client_encoding, - METH_VARARGS, psyco_conn_set_client_encoding_doc}, -#endif + METH_VARARGS, psyco_conn_set_client_encoding_doc}, +#endif {NULL} }; @@ -237,9 +240,9 @@ static struct PyMethodDef connectionObject_methods[] = { static struct PyMemberDef connectionObject_members[] = { /* DBAPI-2.0 extensions (exception objects) */ - {"Error", T_OBJECT, + {"Error", T_OBJECT, offsetof(connectionObject, exc_Error), RO, Error_doc}, - {"Warning", + {"Warning", T_OBJECT, offsetof(connectionObject, exc_Warning), RO, Warning_doc}, {"InterfaceError", T_OBJECT, offsetof(connectionObject, exc_InterfaceError), RO, @@ -262,7 +265,7 @@ static struct PyMemberDef connectionObject_members[] = { {"NotSupportedError", T_OBJECT, offsetof(connectionObject, exc_NotSupportedError), RO, NotSupportedError_doc}, -#ifdef PSYCOPG_EXTENSIONS +#ifdef PSYCOPG_EXTENSIONS {"closed", T_LONG, offsetof(connectionObject, closed), RO, "True if the connection is closed."}, {"isolation_level", T_LONG, @@ -274,14 +277,14 @@ static struct PyMemberDef connectionObject_members[] = { {"notifies", T_OBJECT, offsetof(connectionObject, notifies), RO}, {"dsn", T_STRING, offsetof(connectionObject, dsn), RO, "The current connection string."}, - {"status", T_LONG, + {"status", T_INT, offsetof(connectionObject, status), RO, - "The current transaction status."}, + "The current transaction status."}, {"string_types", T_OBJECT, offsetof(connectionObject, string_types), RO, "A set of typecasters to convert textual values."}, {"binary_types", T_OBJECT, offsetof(connectionObject, binary_types), RO, "A set of typecasters to convert binary values."}, -#endif +#endif {NULL} }; @@ -293,9 +296,11 @@ connection_setup(connectionObject *self, char *dsn) char *pos; int res; - Dprintf("connection_setup: init connection object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); - + Dprintf("connection_setup: init connection object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); + self->dsn = strdup(dsn); self->notice_list = PyList_New(0); self->notifies = PyList_New(0); @@ -305,21 +310,23 @@ connection_setup(connectionObject *self, char *dsn) self->async_cursor = NULL; self->pgconn = NULL; self->mark = 0; - self->string_types = PyDict_New(); + self->string_types = PyDict_New(); self->binary_types = PyDict_New(); pthread_mutex_init(&(self->lock), NULL); - + if (conn_connect(self) != 0) { Dprintf("connection_init: FAILED"); res = -1; } else { - Dprintf("connection_setup: good connection object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + Dprintf("connection_setup: good connection object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); res = 0; } - + /* here we obfuscate the password even if there was a connection error */ pos = strstr(self->dsn, "password"); if (pos != NULL) { @@ -336,21 +343,23 @@ connection_dealloc(PyObject* obj) connectionObject *self = (connectionObject *)obj; if (self->closed == 0) conn_close(self); - + if (self->dsn) free(self->dsn); if (self->encoding) PyMem_Free(self->encoding); if (self->critical) free(self->critical); - + Py_XDECREF(self->notice_list); Py_XDECREF(self->notifies); Py_XDECREF(self->async_cursor); Py_XDECREF(self->string_types); Py_XDECREF(self->binary_types); - + pthread_mutex_destroy(&(self->lock)); - Dprintf("connection_dealloc: deleted connection object at %p, refcnt = %d", - obj, obj->ob_refcnt); + Dprintf("connection_dealloc: deleted connection object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); obj->ob_type->tp_free(obj); } @@ -403,7 +412,7 @@ PyTypeObject connectionType = { sizeof(connectionObject), 0, connection_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -421,7 +430,7 @@ PyTypeObject connectionType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ connectionType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -438,11 +447,11 @@ PyTypeObject connectionType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + connection_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ connection_new, /*tp_new*/ diff --git a/psycopg/cursor.h b/psycopg/cursor.h index be5d9289..8fb04898 100644 --- a/psycopg/cursor.h +++ b/psycopg/cursor.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_CURSOR_H #define PSYCOPG_CURSOR_H 1 +#define PY_SSIZE_T_CLEAN #include #include @@ -41,7 +42,7 @@ typedef struct { int closed:1; /* 1 if the cursor is closed */ int notuples:1; /* 1 if the command was not a SELECT query */ int needsfetch:1; /* 1 if a call to pq_fetch is pending */ - + long int rowcount; /* number of rows affected by last execute */ long int columns; /* number of columns fetched from the db */ long int arraysize; /* how many rows should fetchmany() return */ @@ -58,28 +59,28 @@ typedef struct { PyObject *casts; /* an array (tuple) of typecast functions */ PyObject *caster; /* the current typecaster object */ - + PyObject *copyfile; /* file-like used during COPY TO/FROM ops */ - long int copysize; /* size of the copy buffer during COPY TO/FROM ops */ + Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */ #define DEFAULT_COPYSIZE 16384 - + PyObject *tuple_factory; /* factory for result tuples */ PyObject *tzinfo_factory; /* factory for tzinfo objects */ - + PyObject *query; /* last query executed */ - + char *qattr; /* quoting attr, used when quoting strings */ char *notice; /* a notice from the backend */ char *name; /* this cursor name */ - + PyObject *string_types; /* a set of typecasters for string types */ PyObject *binary_types; /* a set of typecasters for binary types */ } cursorObject; - + /* C-callable functions in cursor_int.c and cursor_ext.c */ extern void curs_reset(cursorObject *self); - + /* exception-raising macros */ #define EXC_IF_CURS_CLOSED(self) \ if ((self)->closed || ((self)->conn && (self)->conn->closed)) { \ @@ -90,7 +91,7 @@ if ((self)->closed || ((self)->conn && (self)->conn->closed)) { \ if ((self)->notuples && (self)->name == NULL) { \ PyErr_SetString(ProgrammingError, "no results to fetch"); \ return NULL; } - + #define EXC_IF_NO_MARK(self) \ if ((self)->mark != (self)->conn->mark) { \ PyErr_SetString(ProgrammingError, "named cursor isn't valid anymore"); \ diff --git a/psycopg/cursor_int.c b/psycopg/cursor_int.c index 8036268b..483e2c44 100644 --- a/psycopg/cursor_int.c +++ b/psycopg/cursor_int.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 2953a15c..26c53c6f 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -49,12 +50,12 @@ static PyObject * psyco_curs_close(cursorObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - + EXC_IF_CURS_CLOSED(self); - + if (self->name != NULL) { char buffer[128]; - + EXC_IF_NO_MARK(self); PyOS_snprintf(buffer, 127, "CLOSE %s", self->name); if (pq_execute(self, buffer, 0) == -1) return NULL; @@ -91,7 +92,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) if (c[0] == '%' && c[1] == '%') { c+=2; force = 1; } - + /* if we find '%(' then this is a dictionary, we: 1/ find the matching ')' and extract the key name 2/ locate the value in the dictionary (or return an error) @@ -107,7 +108,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) key = PyString_FromStringAndSize(c+2, d-c-2); value = PyObject_GetItem(var, key); /* key has refcnt 1, value the original value + 1 */ - + /* if value is NULL we did not find the key (or this is not a dictionary): let python raise a KeyError */ if (value == NULL) { @@ -116,12 +117,13 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) return -1; } - Dprintf("_mogrify: value refcnt: %d (+1)", value->ob_refcnt); - + Dprintf("_mogrify: value refcnt: " + FORMAT_CODE_PY_SSIZE_T " (+1)", value->ob_refcnt); + if (n == NULL) { n = PyDict_New(); } - + if ((item = PyObject_GetItem(n, key)) == NULL) { PyObject *t = NULL; @@ -134,7 +136,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) t = PyString_FromString("NULL"); PyDict_SetItem(n, key, t); /* t is a new object, refcnt = 1, key is at 2 */ - + /* if the value is None we need to substitute the formatting char with 's' (FIXME: this should not be necessary if we drop support for formats other than @@ -151,7 +153,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) } else { /* no adapter found, raise a BIG exception */ - Py_XDECREF(value); + Py_XDECREF(value); Py_DECREF(n); return -1; } @@ -160,26 +162,29 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) Py_XDECREF(t); /* t dies here */ /* after the DECREF value has the original refcnt plus 1 if it was added to the dictionary directly; good */ - Py_XDECREF(value); + Py_XDECREF(value); } else { /* we have an item with one extra refcnt here, zap! */ Py_DECREF(item); } Py_DECREF(key); /* key has the original refcnt now */ - Dprintf("_mogrify: after value refcnt: %d",value->ob_refcnt); + Dprintf("_mogrify: after value refcnt: " + FORMAT_CODE_PY_SSIZE_T, + value->ob_refcnt + ); } c = d; } - + else if (c[0] == '%' && c[1] != '(') { /* this is a format that expects a tuple; it is much easier, because we don't need to check the old/new dictionary for keys */ - + value = PySequence_GetItem(var, index); /* value has refcnt inc'ed by 1 here */ - + /* if value is NULL this is not a sequence or the index is wrong; anyway we let python set its own exception */ if (value == NULL) { @@ -190,10 +195,10 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) if (n == NULL) { n = PyTuple_New(PyObject_Length(var)); } - + /* let's have d point just after the '%' */ d = c+1; - + if (value == Py_None) { PyTuple_SET_ITEM(n, index, PyString_FromString("NULL")); while (*d && !isalpha(*d)) d++; @@ -224,10 +229,10 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new) if (force && n == NULL) n = PyTuple_New(0); *new = n; - + return 0; } - + #define psyco_curs_execute_doc \ "execute(query, vars=None, async=0) -- Execute query with bound vars." @@ -237,7 +242,7 @@ _psyco_curs_execute(cursorObject *self, { int res; PyObject *fquery, *cvt = NULL, *uoperation = NULL; - + pthread_mutex_lock(&(self->conn->lock)); if (self->conn->async_cursor != NULL && self->conn->async_cursor != (PyObject*)self) { @@ -247,18 +252,18 @@ _psyco_curs_execute(cursorObject *self, return 0; } pthread_mutex_unlock(&(self->conn->lock)); - + if (!PyObject_IsTrue(operation)) { psyco_set_error(ProgrammingError, (PyObject*)self, "can't execute an empty query", NULL, NULL); - return 0; + return 0; } - + if (PyUnicode_Check(operation)) { PyObject *enc = PyDict_GetItemString(psycoEncodings, self->conn->encoding); /* enc is a borrowed reference, we won't decref it */ - + if (enc) { operation = PyUnicode_AsEncodedString( operation, PyString_AsString(enc), NULL); @@ -267,7 +272,7 @@ _psyco_curs_execute(cursorObject *self, target encoding we just let the exception propagate */ if (operation == NULL) return 0; - /* we clone operation in uoperation to be sure to free it later */ + /* we clone operation in uoperation to be sure to free it later */ uoperation = operation; } else { @@ -282,20 +287,20 @@ _psyco_curs_execute(cursorObject *self, "argument 1 must be a string or unicode object"); return 0; } - + IFCLEARPGRES(self->pgres); if (self->query) { Py_DECREF(self->query); self->query = NULL; } - + Dprintf("psyco_curs_execute: starting execution of new query"); /* here we are, and we have a sequence or a dictionary filled with objects to be substituted (bound variables). we try to be smart and do the right thing (i.e., what the user expects) */ - + if (vars && vars != Py_None) { if(_mogrify(vars, operation, self->conn, &cvt) == -1) { @@ -315,13 +320,13 @@ _psyco_curs_execute(cursorObject *self, and return the appropriate ProgrammingError. we do that by grabbing the curren exception (we will later restore it if the type or the strings do not match.) */ - + if (!(fquery = PyString_Format(operation, cvt))) { PyObject *err, *arg, *trace; int pe = 0; PyErr_Fetch(&err, &arg, &trace); - + if (err && PyErr_GivenExceptionMatches(err, PyExc_TypeError)) { Dprintf("psyco_curs_execute: TypeError exception catched"); PyErr_NormalizeException(&err, &arg, &trace); @@ -356,7 +361,7 @@ _psyco_curs_execute(cursorObject *self, Py_XDECREF(uoperation); return 0; } - + if (self->name != NULL) { self->query = PyString_FromFormat( "DECLARE %s CURSOR WITHOUT HOLD FOR %s", @@ -366,8 +371,9 @@ _psyco_curs_execute(cursorObject *self, else { self->query = fquery; } - - Dprintf("psyco_curs_execute: cvt->refcnt = %d", cvt->ob_refcnt); + + Dprintf("psyco_curs_execute: cvt->refcnt = " FORMAT_CODE_PY_SSIZE_T, + cvt->ob_refcnt); Py_DECREF(cvt); } else { @@ -381,25 +387,25 @@ _psyco_curs_execute(cursorObject *self, self->query = operation; } } - + res = pq_execute(self, PyString_AS_STRING(self->query), async); - + Dprintf("psyco_curs_execute: res = %d, pgres = %p", res, self->pgres); Py_XDECREF(uoperation); - + return res == -1 ? 0 : 1; } static PyObject * psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs) -{ +{ long int async = 0; PyObject *vars = NULL, *operation = NULL; - + static char *kwlist[] = {"query", "vars", "async", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ol", kwlist, &operation, &vars, &async)) { return NULL; } @@ -414,7 +420,7 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs) if (self->conn->isolation_level == 0) { psyco_set_error(ProgrammingError, (PyObject*)self, "can't use a named cursor outside of transactions", NULL, NULL); - return NULL; + return NULL; } if (self->conn->mark != self->mark) { psyco_set_error(ProgrammingError, (PyObject*)self, @@ -424,7 +430,7 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs) } EXC_IF_CURS_CLOSED(self); - + if (_psyco_curs_execute(self, operation, vars, async)) { Py_INCREF(Py_None); return Py_None; @@ -442,7 +448,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs) { PyObject *operation = NULL, *vars = NULL; PyObject *v, *iter = NULL; - + static char *kwlist[] = {"query", "vars_list", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, @@ -451,18 +457,18 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs) } EXC_IF_CURS_CLOSED(self); - + if (self->name != NULL) { psyco_set_error(ProgrammingError, (PyObject*)self, "can't call .executemany() on named cursors", NULL, NULL); return NULL; - } + } if (!PyIter_Check(vars)) { vars = iter = PyObject_GetIter(vars); if (iter == NULL) return NULL; } - + while ((v = PyIter_Next(vars)) != NULL) { if (_psyco_curs_execute(self, operation, v, 0) == 0) { Py_DECREF(v); @@ -473,7 +479,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs) } } Py_XDECREF(iter); - + Py_INCREF(Py_None); return Py_None; } @@ -485,10 +491,10 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs) static PyObject * psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs) -{ +{ PyObject *vars = NULL, *cvt = NULL, *operation = NULL; PyObject *fquery; - + static char *kwlist[] = {"query", "vars", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, @@ -501,7 +507,7 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs) "unicode queries not yet supported"); return NULL; } - + EXC_IF_CURS_CLOSED(self); IFCLEARPGRES(self->pgres); @@ -516,13 +522,13 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs) if(_mogrify(vars, operation, self->conn, &cvt) == -1) return NULL; } - if (vars && cvt) { + if (vars && cvt) { if (!(fquery = PyString_Format(operation, cvt))) { PyObject *err, *arg, *trace; int pe = 0; PyErr_Fetch(&err, &arg, &trace); - + if (err && PyErr_GivenExceptionMatches(err, PyExc_TypeError)) { Dprintf("psyco_curs_execute: TypeError exception catched"); PyErr_NormalizeException(&err, &arg, &trace); @@ -557,8 +563,10 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs) return NULL; } - Dprintf("psyco_curs_execute: cvt->refcnt = %d, fquery->refcnt = %d", - cvt->ob_refcnt, fquery->ob_refcnt); + Dprintf("psyco_curs_execute: cvt->refcnt = " FORMAT_CODE_PY_SSIZE_T + ", fquery->refcnt = " FORMAT_CODE_PY_SSIZE_T, + cvt->ob_refcnt, fquery->ob_refcnt + ); Py_DECREF(cvt); } else { @@ -583,7 +591,7 @@ static int _psyco_curs_prefetch(cursorObject *self) { int i = 0; - + /* check if the fetching cursor is the one that did the asynchronous query and raise an exception if not */ pthread_mutex_lock(&(self->conn->lock)); @@ -595,7 +603,7 @@ _psyco_curs_prefetch(cursorObject *self) return -2; } pthread_mutex_unlock(&(self->conn->lock)); - + if (self->pgres == NULL || self->needsfetch) { self->needsfetch = 0; Dprintf("_psyco_curs_prefetch: trying to fetch data"); @@ -616,7 +624,7 @@ _psyco_curs_buildrow_fill(cursorObject *self, PyObject *res, int i, len; unsigned char *str; PyObject *val; - + for (i=0; i < n; i++) { if (PQgetisnull(self->pgres, row, i)) { str = NULL; @@ -634,7 +642,10 @@ _psyco_curs_buildrow_fill(cursorObject *self, PyObject *res, (PyObject*)self); if (val) { - Dprintf("_psyco_curs_buildrow: val->refcnt = %d", val->ob_refcnt); + Dprintf("_psyco_curs_buildrow: val->refcnt = " + FORMAT_CODE_PY_SSIZE_T, + val->ob_refcnt + ); if (istuple) { PyTuple_SET_ITEM(res, i, val); } @@ -659,7 +670,7 @@ static PyObject * _psyco_curs_buildrow(cursorObject *self, int row) { int n; - + n = PQnfields(self->pgres); return _psyco_curs_buildrow_fill(self, PyTuple_New(n), row, n, 1); } @@ -681,24 +692,24 @@ PyObject * psyco_curs_fetchone(cursorObject *self, PyObject *args) { PyObject *res; - + if (args && !PyArg_ParseTuple(args, "")) return NULL; - + EXC_IF_CURS_CLOSED(self) if (_psyco_curs_prefetch(self) < 0) return NULL; EXC_IF_NO_TUPLES(self); - + if (self->name != NULL) { char buffer[128]; - + EXC_IF_NO_MARK(self); PyOS_snprintf(buffer, 127, "FETCH FORWARD 1 FROM %s", self->name); if (pq_execute(self, buffer, 0) == -1) return NULL; if (_psyco_curs_prefetch(self) < 0) return NULL; } - + Dprintf("psyco_curs_fetchone: fetching row %ld", self->row); - Dprintf("psyco_curs_fetchone: rowcount = %ld", self->rowcount); + Dprintf("psyco_curs_fetchone: rowcount = %ld", self->rowcount); if (self->row >= self->rowcount) { /* we exausted available data: return None */ @@ -710,7 +721,7 @@ psyco_curs_fetchone(cursorObject *self, PyObject *args) res = _psyco_curs_buildrow(self, self->row); else res = _psyco_curs_buildrow_with_factory(self, self->row); - + self->row++; /* move the counter to next line */ /* if the query was async aggresively free pgres, to allow @@ -736,10 +747,10 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords) { int i; PyObject *list, *res; - + long int size = self->arraysize; static char *kwlist[] = {"size", NULL}; - + if (!PyArg_ParseTupleAndKeywords(args, kwords, "|l", kwlist, &size)) { return NULL; } @@ -750,7 +761,7 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords) if (self->name != NULL) { char buffer[128]; - + EXC_IF_NO_MARK(self); PyOS_snprintf(buffer, 127, "FETCH FORWARD %d FROM %s", (int)size, self->name); @@ -764,19 +775,19 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords) } Dprintf("psyco_curs_fetchmany: size = %ld", size); - + if (size <= 0) { return PyList_New(0); } - + list = PyList_New(size); - + for (i = 0; i < size; i++) { if (self->tuple_factory == Py_None) res = _psyco_curs_buildrow(self, self->row); else res = _psyco_curs_buildrow_with_factory(self, self->row); - + self->row++; if (res == NULL) { @@ -792,7 +803,7 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords) if (self->row >= self->rowcount && self->conn->async_cursor == (PyObject*)self) IFCLEARPGRES(self->pgres); - + return list; } @@ -819,10 +830,10 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args) EXC_IF_CURS_CLOSED(self); if (_psyco_curs_prefetch(self) < 0) return NULL; EXC_IF_NO_TUPLES(self); - + if (self->name != NULL) { char buffer[128]; - + EXC_IF_NO_MARK(self); PyOS_snprintf(buffer, 127, "FETCH FORWARD ALL FROM %s", self->name); if (pq_execute(self, buffer, 0) == -1) return NULL; @@ -830,19 +841,19 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args) } size = self->rowcount - self->row; - + if (size <= 0) { return PyList_New(0); } - + list = PyList_New(size); - + for (i = 0; i < size; i++) { if (self->tuple_factory == Py_None) res = _psyco_curs_buildrow(self, self->row); else res = _psyco_curs_buildrow_with_factory(self, self->row); - + self->row++; if (res == NULL) { @@ -858,7 +869,7 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args) if (self->row >= self->rowcount && self->conn->async_cursor == (PyObject*)self) IFCLEARPGRES(self->pgres); - + return list; } @@ -878,7 +889,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs) PyObject *operation = NULL; PyObject *res = NULL; - if (!PyArg_ParseTuple(args, "s|Oi", &procname, ¶meters, &async)) { + if (!PyArg_ParseTuple(args, "s|Ol", &procname, ¶meters, &async)) { return NULL; } @@ -888,28 +899,28 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs) psyco_set_error(ProgrammingError, (PyObject*)self, "can't call .callproc() on named cursors", NULL, NULL); return NULL; - } + } if(parameters && parameters != Py_None) { nparameters = PyObject_Length(parameters); - if (nparameters < 0) nparameters = 0; + if (nparameters < 0) nparameters = 0; } /* allocate some memory, build the SQL and create a PyString from it */ sl = strlen(procname) + 17 + nparameters*3 - (nparameters ? 1 : 0); sql = (char*)PyMem_Malloc(sl); if (sql == NULL) return NULL; - + sprintf(sql, "SELECT * FROM %s(", procname); for(i=0; i= self->rowcount ) { psyco_set_error(ProgrammingError, (PyObject*)self, "scroll destination out of bounds", NULL, NULL); return NULL; } - + self->row = newpos; } - + else { char buffer[128]; - + EXC_IF_NO_MARK(self); - + if (strcmp(mode, "absolute") == 0) { PyOS_snprintf(buffer, 127, "MOVE ABSOLUTE %d FROM %s", value, self->name); @@ -1064,7 +1075,7 @@ _psyco_curs_has_read_check(PyObject* o, void* var) PyErr_SetString(PyExc_TypeError, "argument 1 must have both .read() and .readline() methods"); return 0; - } + } } static PyObject * @@ -1073,20 +1084,22 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs) char query[1024]; char *table_name; char *sep = "\t", *null = NULL; - long int bufsize = DEFAULT_COPYSIZE; + Py_ssize_t bufsize = DEFAULT_COPYSIZE; PyObject *file, *columns = NULL, *res = NULL; char columnlist[1024] = ""; - static char *kwlist[] = {"file", "table", "sep", "null", "size", + static char *kwlist[] = {"file", "table", "sep", "null", "size", "columns", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|ssiO", kwlist, - _psyco_curs_has_read_check, &file, - &table_name, &sep, &null, &bufsize, - &columns)) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&s|ss" CONV_CODE_PY_SSIZE_T "O", kwlist, + _psyco_curs_has_read_check, &file, &table_name, &sep, &null, &bufsize, + &columns) + ) + { return NULL; } - + if (columns != NULL && columns != Py_None) { PyObject* collistiter = PyObject_GetIter(columns); PyObject* col; @@ -1102,7 +1115,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs) Py_DECREF(col); Py_DECREF(collistiter); PyErr_SetString(PyExc_ValueError, - "Elements in column list must be strings"); + "Elements in column list must be strings"); return NULL; } PyString_AsStringAndSize(col, &colname, &colitemlen); @@ -1152,7 +1165,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs) } self->copyfile =NULL; - + return res; } @@ -1171,7 +1184,7 @@ _psyco_curs_has_write_check(PyObject* o, void* var) PyErr_SetString(PyExc_TypeError, "argument 1 must have a .write() method"); return 0; - } + } } static PyObject * @@ -1189,7 +1202,7 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs) &table_name, &sep, &null)) { return NULL; } - + EXC_IF_CURS_CLOSED(self); if (null) { @@ -1206,13 +1219,13 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs) if (pq_execute(self, query, 0) == 1) { res = Py_None; - Py_INCREF(Py_None); + Py_INCREF(Py_None); } - + self->copyfile = NULL; - + return res; -} +} /* extension: fileno - return the file descripor of the connection */ #define psyco_curs_fileno_doc \ @@ -1222,7 +1235,7 @@ static PyObject * psyco_curs_fileno(cursorObject *self, PyObject *args) { long int socket; - + if (!PyArg_ParseTuple(args, "")) return NULL; EXC_IF_CURS_CLOSED(self); @@ -1252,7 +1265,7 @@ psyco_curs_isready(cursorObject *self, PyObject *args) /* pq_is_busy does its own locking, we don't need anything special but if the cursor is ready we need to fetch the result and free the connection for the next query. */ - + if (pq_is_busy(self->conn)) { Py_INCREF(Py_False); return Py_False; @@ -1351,7 +1364,7 @@ static struct PyMemberDef cursorObject_members[] = { /* DBAPI-2.0 basics */ {"rowcount", T_LONG, OFFSETOF(rowcount), RO, "Number of rows read from the backend in the last command."}, - {"arraysize", T_LONG, OFFSETOF(arraysize), 0, + {"arraysize", T_LONG, OFFSETOF(arraysize), 0, "Number of records `fetchmany()` must fetch if not explicitely " \ "specified."}, {"description", T_OBJECT, OFFSETOF(description), RO, @@ -1361,7 +1374,7 @@ static struct PyMemberDef cursorObject_members[] = { /* DBAPI-2.0 extensions */ {"rownumber", T_LONG, OFFSETOF(row), RO, "The current row position."}, - {"connection", T_OBJECT, OFFSETOF(conn), RO, + {"connection", T_OBJECT, OFFSETOF(conn), RO, "The connection where the cursor comes from."}, #ifdef PSYCOPG_EXTENSIONS {"name", T_STRING, OFFSETOF(name), RO}, @@ -1385,7 +1398,7 @@ cursor_setup(cursorObject *self, connectionObject *conn, char *name) { Dprintf("cursor_setup: init cursor object at %p", self); Dprintf("cursor_setup: parameters: name = %s, conn = %p", name, conn); - + if (name) { self->name = PyMem_Malloc(strlen(name)+1); if (self->name == NULL) return 1; @@ -1401,21 +1414,21 @@ cursor_setup(cursorObject *self, connectionObject *conn, char *name) } */ self->conn = conn; Py_INCREF((PyObject*)self->conn); - + self->closed = 0; self->mark = conn->mark; - self->pgres = NULL; + self->pgres = NULL; self->notuples = 1; self->arraysize = 1; self->rowcount = -1; self->lastoid = InvalidOid; - + self->casts = NULL; self->notice = NULL; - + self->string_types = NULL; self->binary_types = NULL; - + self->description = Py_None; Py_INCREF(Py_None); self->pgstatus = Py_None; @@ -1424,13 +1437,15 @@ cursor_setup(cursorObject *self, connectionObject *conn, char *name) Py_INCREF(Py_None); self->query = Py_None; Py_INCREF(Py_None); - + /* default tzinfo factory */ self->tzinfo_factory = pyPsycopgTzFixedOffsetTimezone; Py_INCREF(self->tzinfo_factory); - - Dprintf("cursor_setup: good cursor object at %p, refcnt = %d", - self, ((PyObject *)self)->ob_refcnt); + + Dprintf("cursor_setup: good cursor object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + self, ((PyObject *)self)->ob_refcnt + ); return 0; } @@ -1440,7 +1455,7 @@ cursor_dealloc(PyObject* obj) cursorObject *self = (cursorObject *)obj; if (self->name) PyMem_Free(self->name); - + Py_XDECREF((PyObject*)self->conn); Py_XDECREF(self->casts); Py_XDECREF(self->description); @@ -1450,11 +1465,13 @@ cursor_dealloc(PyObject* obj) Py_XDECREF(self->query); Py_XDECREF(self->string_types); Py_XDECREF(self->binary_types); - + IFCLEARPGRES(self->pgres); - - Dprintf("cursor_dealloc: deleted cursor object at %p, refcnt = %d", - obj, obj->ob_refcnt); + + Dprintf("cursor_dealloc: deleted cursor object at %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt + ); obj->ob_type->tp_free(obj); } @@ -1464,7 +1481,7 @@ cursor_init(PyObject *obj, PyObject *args, PyObject *kwds) { char *name = NULL; PyObject *conn; - + if (!PyArg_ParseTuple(args, "O|s", &conn, &name)) return -1; @@ -1503,7 +1520,7 @@ PyTypeObject cursorType = { sizeof(cursorObject), 0, cursor_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -1521,7 +1538,7 @@ PyTypeObject cursorType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ cursorType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -1538,11 +1555,11 @@ PyTypeObject cursorType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + cursor_init, /*tp_init*/ 0, /*tp_alloc Will be set to PyType_GenericAlloc in module init*/ cursor_new, /*tp_new*/ diff --git a/psycopg/microprotocols.c b/psycopg/microprotocols.c index 73abbfc7..4232fd4d 100644 --- a/psycopg/microprotocols.c +++ b/psycopg/microprotocols.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include @@ -44,10 +45,10 @@ microprotocols_init(PyObject *dict) /* create adapters dictionary and put it in module namespace */ if ((psyco_adapters = PyDict_New()) == NULL) { return -1; - } + } PyDict_SetItemString(dict, "adapters", psyco_adapters); - + return 0; } @@ -79,7 +80,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) quotable object to be its instance */ Dprintf("microprotocols_adapt: trying to adapt %s", obj->ob_type->tp_name); - + /* look for an adapter in the registry */ key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto); adapter = PyDict_GetItem(psyco_adapters, key); @@ -98,7 +99,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) return NULL; } - /* and finally try to have the object adapt itself */ + /* and finally try to have the object adapt itself */ if (PyObject_HasAttrString(obj, "__conform__")) { PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto); if (adapted && adapted != Py_None) return adapted; @@ -106,7 +107,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; } - + /* else set the right exception and return NULL */ psyco_set_error(ProgrammingError, NULL, "can't adapt", NULL, NULL); return NULL; @@ -120,7 +121,7 @@ microprotocol_getquoted(PyObject *obj, connectionObject *conn) PyObject *res = NULL; PyObject *tmp = microprotocols_adapt( obj, (PyObject*)&isqlquoteType, NULL); - + if (tmp != NULL) { Dprintf("microprotocol_getquoted: adapted to %s", tmp->ob_type->tp_name); diff --git a/psycopg/microprotocols.h b/psycopg/microprotocols.h index 5501a7c6..1924df67 100644 --- a/psycopg/microprotocols.h +++ b/psycopg/microprotocols.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_MICROPROTOCOLS_H #define PSYCOPG_MICROPROTOCOLS_H 1 +#define PY_SSIZE_T_CLEAN #include #include "psycopg/connection.h" #include "psycopg/cursor.h" @@ -46,15 +47,15 @@ extern PyObject *psyco_adapters; extern int microprotocols_init(PyObject *dict); extern int microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); - + extern PyObject *microprotocols_adapt( PyObject *obj, PyObject *proto, PyObject *alt); extern PyObject *microprotocol_getquoted( PyObject *obj, connectionObject *conn); - + extern PyObject * - psyco_microprotocols_adapt(cursorObject *self, PyObject *args); + psyco_microprotocols_adapt(cursorObject *self, PyObject *args); #define psyco_microprotocols_adapt_doc \ "adapt(obj, protocol, alternate) -> object -- adapt obj to given protocol" - + #endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ diff --git a/psycopg/microprotocols_proto.c b/psycopg/microprotocols_proto.c index 72c3a7eb..7acef18d 100644 --- a/psycopg/microprotocols_proto.c +++ b/psycopg/microprotocols_proto.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include #include @@ -44,7 +45,7 @@ static PyObject * psyco_isqlquote_getquoted(isqlquoteObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - + Py_INCREF(Py_None); return Py_None; } @@ -58,7 +59,7 @@ static PyObject * psyco_isqlquote_getbinary(isqlquoteObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - + Py_INCREF(Py_None); return Py_None; } @@ -72,7 +73,7 @@ static PyObject * psyco_isqlquote_getbuffer(isqlquoteObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - + Py_INCREF(Py_None); return Py_None; } @@ -119,9 +120,9 @@ static void isqlquote_dealloc(PyObject* obj) { isqlquoteObject *self = (isqlquoteObject *)obj; - + Py_XDECREF(self->wrapped); - + obj->ob_type->tp_free(obj); } @@ -163,7 +164,7 @@ PyTypeObject isqlquoteType = { sizeof(isqlquoteObject), 0, isqlquote_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -181,7 +182,7 @@ PyTypeObject isqlquoteType = { Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ isqlquoteType_doc, /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -198,11 +199,11 @@ PyTypeObject isqlquoteType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + isqlquote_init, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ isqlquote_new, /*tp_new*/ diff --git a/psycopg/microprotocols_proto.h b/psycopg/microprotocols_proto.h index c9203ee9..45de4cc4 100644 --- a/psycopg/microprotocols_proto.h +++ b/psycopg/microprotocols_proto.h @@ -22,22 +22,23 @@ #ifndef PSYCOPG_ISQLQUOTE_H #define PSYCOPG_ISQLQUOTE_H 1 +#define PY_SSIZE_T_CLEAN #include #include #ifdef __cplusplus extern "C" { #endif - + extern PyTypeObject isqlquoteType; typedef struct { PyObject_HEAD PyObject *wrapped; - + } isqlquoteObject; - + #ifdef __cplusplus } #endif diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index 7e44ead9..3e3a1d36 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -25,6 +25,7 @@ connection. */ +#define PY_SSIZE_T_CLEAN #include #include @@ -47,17 +48,17 @@ void pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) { PyObject *pgc = (PyObject*)curs; - + char *err = NULL; char *err2 = NULL; char *code = NULL; char *buf = NULL; - + if ((conn == NULL && curs == NULL) || (curs != NULL && conn == NULL)) { PyErr_SetString(Error, "psycopg went psycotic and raised a null error"); return; } - + if (curs && curs->pgres) { err = PQresultErrorMessage(curs->pgres); #ifdef HAVE_PQPROTOCOL3 @@ -76,7 +77,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) PyErr_SetString(Error, "psycopg went psycotic without error set"); return; } - + /* if exc is NULL, analyze the message and try to deduce the right exception kind (only if we have a pgres, obviously) */ if (exc == NULL) { @@ -93,7 +94,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) } } } - + /* if exc is still NULL psycopg was not built with HAVE_PQPROTOCOL3 or the connection is using protocol 2: in both cases we default to comparing error messages */ @@ -105,7 +106,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) else exc = ProgrammingError; } - + /* try to remove the initial "ERROR: " part from the postgresql error */ if (err && strlen(err) > 8) err2 = &(err[8]); else err2 = err; @@ -126,9 +127,9 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) } } else { - psyco_set_error(exc, pgc, err2, err, code); + psyco_set_error(exc, pgc, err2, err, code); } - + if (buf != NULL) PyMem_Free(buf); } @@ -144,7 +145,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) void pq_set_critical(connectionObject *conn, const char *msg) { - if (msg == NULL) + if (msg == NULL) msg = PQerrorMessage(conn->pgconn); if (conn->critical) free(conn->critical); if (msg && msg[0] != '\0') conn->critical = strdup(msg); @@ -155,7 +156,7 @@ PyObject * pq_resolve_critical(connectionObject *conn, int close) { Dprintf("pq_resolve_critical: resolving %s", conn->critical); - + if (conn->critical) { char *msg = &(conn->critical[6]); Dprintf("pq_resolve_critical: error = %s", msg); @@ -163,7 +164,7 @@ pq_resolve_critical(connectionObject *conn, int close) from the connection, so we just raise an OperationalError with the critical message */ PyErr_SetString(OperationalError, msg); - + /* we don't want to destroy this connection but just close it */ if (close == 1) conn_close(conn); } @@ -175,7 +176,7 @@ pq_resolve_critical(connectionObject *conn, int close) note that this function does block because it needs to wait for the full result sets of the previous query to clear them. - + this function does not call any Py_*_ALLOW_THREADS macros */ void @@ -201,7 +202,7 @@ pq_begin(connectionObject *conn) NULL, "BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED", "BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"}; - + int pgstatus, retvalue = -1; PGresult *pgres = NULL; @@ -324,7 +325,7 @@ pq_abort(connectionObject *conn) } /* pq_is_busy - consume input and return connection status - + a status of 1 means that a call to pq_fetch will block, while a status of 0 means that there is data available to be collected. -1 means an error, the exception will be set accordingly. @@ -336,7 +337,7 @@ int pq_is_busy(connectionObject *conn) { PGnotify *pgn; - + Dprintf("pq_is_busy: consuming input"); Py_BEGIN_ALLOW_THREADS; @@ -352,13 +353,13 @@ pq_is_busy(connectionObject *conn) pthread_mutex_unlock(&(conn->lock)); Py_END_ALLOW_THREADS; - + /* now check for notifies */ while ((pgn = PQnotifies(conn->pgconn)) != NULL) { PyObject *notify; - + Dprintf("curs_is_busy: got NOTIFY from pid %d, msg = %s", - pgn->be_pid, pgn->relname); + (int) pgn->be_pid, pgn->relname); notify = PyTuple_New(2); PyTuple_SET_ITEM(notify, 0, PyInt_FromLong((long)pgn->be_pid)); @@ -366,7 +367,7 @@ pq_is_busy(connectionObject *conn) PyList_Append(conn->notifies, notify); free(pgn); } - + return PQisBusy(conn->pgconn); } @@ -410,10 +411,10 @@ pq_execute(cursorObject *curs, const char *query, int async) not what should we do? just block and discard data or execute another query? */ pq_clear_async(curs->conn); - + Dprintf("pq_execute: executing ASYNC query:"); Dprintf(" %-.200s", query); - + /* then we can go on and send a new query without fear */ IFCLEARPGRES(curs->pgres); if (PQsendQuery(curs->conn->pgconn, query) == 0) { @@ -425,10 +426,10 @@ pq_execute(cursorObject *curs, const char *query, int async) } Dprintf("pq_execute: async query sent to backend"); } - + pthread_mutex_unlock(&(curs->conn->lock)); Py_END_ALLOW_THREADS; - + /* if the execute was sync, we call pq_fetch() immediately, to respect the old DBAPI-2.0 compatible behaviour */ if (async == 0) { @@ -438,7 +439,7 @@ pq_execute(cursorObject *curs, const char *query, int async) else { curs->conn->async_cursor = (PyObject*)curs; } - + return 1-async; } @@ -470,7 +471,7 @@ _pq_fetch_tuples(cursorObject *curs) curs->description = PyTuple_New(pgnfields); curs->casts = PyTuple_New(pgnfields); curs->columns = pgnfields; - + /* calculate the display size for each column (cpu intensive, can be switched off at configuration time) */ #ifdef PSYCOPG_DISPLAY_SIZE @@ -494,13 +495,13 @@ _pq_fetch_tuples(cursorObject *curs) Oid ftype = PQftype(curs->pgres, i); int fsize = PQfsize(curs->pgres, i); int fmod = PQfmod(curs->pgres, i); - + PyObject *dtitem = PyTuple_New(7); PyObject *type = PyInt_FromLong(ftype); PyObject *cast = NULL; - + PyTuple_SET_ITEM(curs->description, i, dtitem); - + /* fill the right cast function by accessing three different dictionaries: - the per-cursor dictionary, if available (can be NULL or None) - the per-connection dictionary (always exists but can be null) @@ -521,7 +522,7 @@ _pq_fetch_tuples(cursorObject *curs) Dprintf("_pq_fetch_tuples: global dict: %p", cast); } if (cast == NULL) cast = psyco_default_cast; - + /* else if we got binary tuples and if we got a field that is binary use the default cast FIXME: what the hell am I trying to do here? This just can't work.. @@ -538,7 +539,7 @@ _pq_fetch_tuples(cursorObject *curs) PQftype(curs->pgres,i)); Py_INCREF(cast); PyTuple_SET_ITEM(curs->casts, i, cast); - + /* 1/ fill the other fields */ PyTuple_SET_ITEM(dtitem, 0, PyString_FromString(PQfname(curs->pgres, i))); @@ -584,7 +585,7 @@ _pq_fetch_tuples(cursorObject *curs) Py_INCREF(Py_None); PyTuple_SET_ITEM(dtitem, 6, Py_None); } - + if (dsize) PyMem_Free(dsize); } @@ -598,14 +599,16 @@ _pq_copy_in_v3(cursorObject *curs) PyObject *o; Py_ssize_t length = 0; int error = 0; - + while (1) { - o = PyObject_CallMethod(curs->copyfile, "read", "i", curs->copysize); + o = PyObject_CallMethod(curs->copyfile, "read", + CONV_CODE_PY_SSIZE_T, curs->copysize + ); if (!o || !PyString_Check(o) || (length = PyString_Size(o)) == -1) { error = 1; } if (length == 0 || error == 1) break; - + Py_BEGIN_ALLOW_THREADS; if (PQputCopyData(curs->conn->pgconn, PyString_AS_STRING(o), length) == -1) { @@ -614,12 +617,12 @@ _pq_copy_in_v3(cursorObject *curs) Py_END_ALLOW_THREADS; if (error == 2) break; - + Py_DECREF(o); } - + Py_XDECREF(o); - + Dprintf("_pq_copy_in_v3: error = %d", error); if (error == 0 || error == 2) @@ -682,13 +685,13 @@ _pq_copy_out_v3(cursorObject *curs) PyObject *tmp = NULL; char *buffer; - int len; - + Py_ssize_t len; + while (1) { Py_BEGIN_ALLOW_THREADS; len = PQgetCopyData(curs->conn->pgconn, &buffer, 0); Py_END_ALLOW_THREADS; - + if (len > 0 && buffer) { tmp = PyObject_CallMethod(curs->copyfile, "write", "s#", buffer, len); @@ -703,7 +706,7 @@ _pq_copy_out_v3(cursorObject *curs) postgresql authors :/) */ else if (len <= 0) break; } - + if (len == -2) { pq_raise(curs->conn, NULL, NULL, NULL); return -1; @@ -726,8 +729,9 @@ _pq_copy_out(cursorObject *curs) PyObject *tmp = NULL; char buffer[4096]; - int status, len, ll=0; - + int status, ll=0; + Py_ssize_t len; + while (1) { Py_BEGIN_ALLOW_THREADS; status = PQgetline(curs->conn->pgconn, buffer, 4096); @@ -735,7 +739,7 @@ _pq_copy_out(cursorObject *curs) if (status == 0) { if (!ll && buffer[0] == '\\' && buffer[1] == '.') break; - len = strlen(buffer); + len = (Py_ssize_t) strlen(buffer); buffer[len++] = '\n'; ll = 0; } @@ -746,7 +750,7 @@ _pq_copy_out(cursorObject *curs) else { return -1; } - + tmp = PyObject_CallMethod(curs->copyfile, "write", "s#", buffer, len); if (tmp == NULL) return -1; @@ -757,7 +761,7 @@ _pq_copy_out(cursorObject *curs) status = 1; if (PQendcopy(curs->conn->pgconn) != 0) status = -1; - + /* if for some reason we're using a protocol 3 libpq to connect to a protocol 2 backend we still need to cycle on the result set */ IFCLEARPGRES(curs->pgres); @@ -777,14 +781,14 @@ pq_fetch(cursorObject *curs) /* even if we fail, we remove any information about the previous query */ curs_reset(curs); - + /* we check the result from the previous execute; if the result is not already there, we need to consume some input and go to sleep until we get something edible to eat */ if (!curs->pgres) { - + Dprintf("pq_fetch: no data: entering polling loop"); - + while (pq_is_busy(curs->conn) > 0) { fd_set rfds; struct timeval tv; @@ -830,9 +834,9 @@ pq_fetch(cursorObject *curs) } } */ - + if (curs->pgres == NULL) return 0; - + pgstatus = PQresultStatus(curs->pgres); Dprintf("pq_fetch: pgstatus = %s", PQresStatus(pgstatus)); @@ -863,11 +867,11 @@ pq_fetch(cursorObject *curs) if (PyErr_Occurred()) ex = -1; IFCLEARPGRES(curs->pgres); break; - + case PGRES_COPY_IN: Dprintf("pq_fetch: data from a COPY FROM (no tuples)"); #ifdef HAVE_PQPROTOCOL3 - if (curs->conn->protocol == 3) + if (curs->conn->protocol == 3) ex = _pq_copy_in_v3(curs); else #endif @@ -877,14 +881,14 @@ pq_fetch(cursorObject *curs) if (PyErr_Occurred()) ex = -1; IFCLEARPGRES(curs->pgres); break; - + case PGRES_TUPLES_OK: Dprintf("pq_fetch: data from a SELECT (got tuples)"); curs->rowcount = PQntuples(curs->pgres); _pq_fetch_tuples(curs); ex = 0; /* don't clear curs->pgres, because it contains the results! */ break; - + default: Dprintf("pq_fetch: uh-oh, something FAILED"); pq_raise(curs->conn, curs, NULL, NULL); @@ -894,7 +898,7 @@ pq_fetch(cursorObject *curs) } Dprintf("pq_fetch: fetching done; check for critical errors"); - + /* error checking, close the connection if necessary (some critical errors are not really critical, like a COPY FROM error: if that's the case we raise the exception but we avoid to close the connection) */ @@ -907,6 +911,6 @@ pq_fetch(cursorObject *curs) } return -1; } - + return ex; } diff --git a/psycopg/psycopg.h b/psycopg/psycopg.h index 5ee3a46a..15ce8bbc 100644 --- a/psycopg/psycopg.h +++ b/psycopg/psycopg.h @@ -1,4 +1,4 @@ -/* psycopg.h - definitions for the psycopg python module +/* psycopg.h - definitions for the psycopg python module * * Copyright (C) 2003 Federico Di Gregorio * @@ -22,35 +22,60 @@ #ifndef PSYCOPG_H #define PSYCOPG_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus extern "C" { #endif -/* Python 2.5 ssize_t compatibility */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -#define PY_SSIZE_T_MAX INT_MAX -#define PY_SSIZE_T_MIN INT_MIN +/* 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 "d" + + 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 #define PARAMSTYLE "pyformat" - + /* C API functions */ #define psyco_errors_fill_NUM 0 #define psyco_errors_fill_RETURN void -#define psyco_errors_fill_PROTO (PyObject *dict) +#define psyco_errors_fill_PROTO (PyObject *dict) #define psyco_errors_set_NUM 1 #define psyco_errors_set_RETURN void #define psyco_errors_set_PROTO (PyObject *type) - + /* Total number of C API pointers */ #define PSYCOPG_API_pointers 2 - + #ifdef PSYCOPG_MODULE /** This section is used when compiling psycopgmodule.c & co. **/ extern psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO; @@ -65,7 +90,7 @@ extern PyObject *Error, *Warning, *InterfaceError, *DatabaseError, #ifndef PyMODINIT_FUNC #define PyMODINIT_FUNC void #endif - + #else /** This section is used in modules that use psycopg's C API **/ @@ -77,7 +102,7 @@ static void **PSYCOPG_API; #define psyco_errors_set \ (*(psyco_errors_set_RETURN (*)psyco_errors_set_PROTO) \ PSYCOPG_API[psyco_errors_set_NUM]) - + /* Return -1 and set exception on error, 0 on success. */ static int import_psycopg(void) @@ -98,19 +123,19 @@ import_psycopg(void) /* postgresql<->python encoding map */ extern PyObject *psycoEncodings; - + typedef struct { char *pgenc; char *pyenc; } encodingPair; -/* the Decimal type, used by the DECIMAL typecaster */ +/* the Decimal type, used by the DECIMAL typecaster */ extern PyObject *decimalType; /* some utility functions */ -extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg, +extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg, char *pgerror, char *pgcode); - + /* Exceptions docstrings */ #define Error_doc \ "Base class for error exceptions." diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index 5079fc88..aa5b8471 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #define PSYCOPG_MODULE @@ -127,16 +128,16 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) { PyObject *conn, *factory = NULL; PyObject *pyport = NULL; - + int idsn=-1, iport=-1; char *dsn=NULL, *database=NULL, *user=NULL, *password=NULL; char *host=NULL, *sslmode=NULL; char port[16]; - + static char *kwlist[] = {"dsn", "database", "host", "port", "user", "password", "sslmode", "connection_factory", NULL}; - + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssOsssO", kwlist, &dsn, &database, &host, &pyport, &user, &password, &sslmode, &factory)) { @@ -144,16 +145,16 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) } if (pyport && PyString_Check(pyport)) { - PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10); - if (!pyint) return NULL; - iport = PyInt_AsLong(pyint); + PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10); + if (!pyint) return NULL; + iport = PyInt_AsLong(pyint); } else if (pyport && PyInt_Check(pyport)) { - iport = PyInt_AsLong(pyport); + iport = PyInt_AsLong(pyport); } else if (pyport != NULL) { - PyErr_SetString(PyExc_TypeError, "port must be a string or int"); - return NULL; + PyErr_SetString(PyExc_TypeError, "port must be a string or int"); + return NULL; } if (iport > 0) @@ -168,7 +169,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) if (user) l += strlen(user); if (password) l += strlen(password); if (sslmode) l += strlen(sslmode); - + dsn = malloc(l*sizeof(char)); if (dsn == NULL) { PyErr_SetString(InterfaceError, "dynamic dsn allocation failed"); @@ -188,7 +189,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) idsn = _psyco_connect_fill_dsn(dsn, " password=", password, idsn); if (sslmode) idsn = _psyco_connect_fill_dsn(dsn, " sslmode=", sslmode, idsn); - + if (idsn > 0) { dsn[idsn] = '\0'; memmove(dsn, &dsn[1], idsn); @@ -206,7 +207,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds) if (factory == NULL) factory = (PyObject *)&connectionType; conn = PyObject_CallFunction(factory, "s", dsn); if (conn) _psyco_connect_fill_exc((connectionObject*)conn); - + return conn; } @@ -239,7 +240,7 @@ _psyco_register_type_set(PyObject **dict, PyObject *type) static PyObject * psyco_register_type(PyObject *self, PyObject *args) { - PyObject *type, *obj; + PyObject *type, *obj = NULL; if (!PyArg_ParseTuple(args, "O!|O", &typecastType, &type, &obj)) { return NULL; @@ -273,16 +274,16 @@ static void psyco_adapters_init(PyObject *mod) { PyObject *call; - + microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&asisType); microprotocols_add(&PyInt_Type, NULL, (PyObject*)&asisType); microprotocols_add(&PyLong_Type, NULL, (PyObject*)&asisType); - + 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); - + #ifdef HAVE_MXDATETIME /* the module has already been initialized, so we can obtain the callable objects directly from its dictionary :) */ @@ -303,7 +304,7 @@ psyco_adapters_init(PyObject *mod) call = PyMapping_GetItemString(mod, "IntervalFromPy"); microprotocols_add((PyTypeObject*)pyDeltaTypeP, NULL, call); #endif - + #ifdef HAVE_PYBOOL microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType); #endif @@ -314,19 +315,19 @@ psyco_adapters_init(PyObject *mod) } /* psyco_encodings_fill - + Fill the module's postgresql<->python encoding table */ static encodingPair encodings[] = { {"SQL_ASCII", "ascii"}, {"LATIN1", "iso8859_1"}, - {"LATIN2", "iso8859_2"}, - {"LATIN3", "iso8859_3"}, - {"LATIN4", "iso8859_4"}, - {"LATIN5", "iso8859_9"}, - {"LATIN6", "iso8859_10"}, - {"LATIN7", "iso8859_13"}, - {"LATIN8", "iso8859_14"}, + {"LATIN2", "iso8859_2"}, + {"LATIN3", "iso8859_3"}, + {"LATIN4", "iso8859_4"}, + {"LATIN5", "iso8859_9"}, + {"LATIN6", "iso8859_10"}, + {"LATIN7", "iso8859_13"}, + {"LATIN8", "iso8859_14"}, {"LATIN9", "iso8859_15"}, {"ISO88591", "iso8859_1"}, {"ISO88592", "iso8859_2"}, @@ -359,7 +360,7 @@ static encodingPair encodings[] = { {"ShiftJIS", "cp932"}, {"WIN932", "cp932"}, {"Windows932", "cp932"}, - {"UHC", "cp949"}, + {"UHC", "cp949"}, {"WIN949", "cp949"}, {"Windows949", "cp949"}, {"WIN866", "cp866"}, @@ -385,7 +386,7 @@ static encodingPair encodings[] = { /* {"EUC_TW", "?"}, */ /* {"LATIN10", "?"}, */ /* {"ISO885916", "?"}, */ -/* {"MULE_INTERNAL", "?"}, */ +/* {"MULE_INTERNAL", "?"}, */ {NULL, NULL} }; @@ -421,14 +422,14 @@ static struct { { "psycopg2.InterfaceError", &InterfaceError, &Error, InterfaceError_doc }, { "psycopg2.DatabaseError", &DatabaseError, &Error, DatabaseError_doc }, { "psycopg2.InternalError", &InternalError, &DatabaseError, InternalError_doc }, - { "psycopg2.OperationalError", &OperationalError, &DatabaseError, + { "psycopg2.OperationalError", &OperationalError, &DatabaseError, OperationalError_doc }, - { "psycopg2.ProgrammingError", &ProgrammingError, &DatabaseError, + { "psycopg2.ProgrammingError", &ProgrammingError, &DatabaseError, ProgrammingError_doc }, - { "psycopg2.IntegrityError", &IntegrityError, &DatabaseError, + { "psycopg2.IntegrityError", &IntegrityError, &DatabaseError, IntegrityError_doc }, { "psycopg2.DataError", &DataError, &DatabaseError, DataError_doc }, - { "psycopg2.NotSupportedError", &NotSupportedError, &DatabaseError, + { "psycopg2.NotSupportedError", &NotSupportedError, &DatabaseError, NotSupportedError_doc }, {NULL} /* Sentinel */ }; @@ -439,7 +440,7 @@ psyco_errors_init(void) /* the names of the exceptions here reflect the oranization of the psycopg2 module and not the fact the the original error objects live in _psycopg */ - + int i; PyObject *dict; PyObject *base; @@ -474,7 +475,7 @@ psyco_errors_fill(PyObject *dict) PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError); PyDict_SetItemString(dict, "IntegrityError", IntegrityError); PyDict_SetItemString(dict, "DataError", DataError); - PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError); + PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError); } void @@ -493,17 +494,17 @@ psyco_errors_set(PyObject *type) } /* psyco_error_new - + Create a new error of the given type with extra attributes. */ - + void -psyco_set_error(PyObject *exc, PyObject *curs, char *msg, +psyco_set_error(PyObject *exc, PyObject *curs, char *msg, char *pgerror, char *pgcode) { PyObject *t; - + PyObject *err = PyObject_CallFunction(exc, "s", msg); - + if (err) { if (pgerror) { t = PyString_FromString(pgerror); @@ -522,16 +523,16 @@ psyco_set_error(PyObject *exc, PyObject *curs, char *msg, } PyObject_SetAttrString(err, "pgcode", t); Py_DECREF(t); - + if (curs) PyObject_SetAttrString(err, "cursor", curs); else PyObject_SetAttrString(err, "cursor", Py_None); PyErr_SetObject(exc, err); - Py_DECREF(err); + Py_DECREF(err); } -} +} /* psyco_decimal_init @@ -589,7 +590,7 @@ static PyMethodDef psycopgMethods[] = { METH_VARARGS, psyco_TimestampFromTicks_doc}, {"List", (PyCFunction)psyco_List, METH_VARARGS, psyco_List_doc}, - + #ifdef HAVE_MXDATETIME {"DateFromMx", (PyCFunction)psyco_DateFromMx, METH_VARARGS, psyco_DateFromMx_doc}, @@ -598,7 +599,7 @@ static PyMethodDef psycopgMethods[] = { {"TimestampFromMx", (PyCFunction)psyco_TimestampFromMx, METH_VARARGS, psyco_TimestampFromMx_doc}, {"IntervalFromMx", (PyCFunction)psyco_IntervalFromMx, - METH_VARARGS, psyco_IntervalFromMx_doc}, + METH_VARARGS, psyco_IntervalFromMx_doc}, #endif #ifdef HAVE_PYDATETIME @@ -609,7 +610,7 @@ static PyMethodDef psycopgMethods[] = { {"TimestampFromPy", (PyCFunction)psyco_TimestampFromPy, METH_VARARGS, psyco_TimestampFromPy_doc}, {"IntervalFromPy", (PyCFunction)psyco_IntervalFromPy, - METH_VARARGS, psyco_IntervalFromPy_doc}, + METH_VARARGS, psyco_IntervalFromPy_doc}, #endif {NULL, NULL, 0, NULL} /* Sentinel */ @@ -619,7 +620,7 @@ PyMODINIT_FUNC init_psycopg(void) { static void *PSYCOPG_API[PSYCOPG_API_pointers]; - + PyObject *module, *dict; PyObject *c_api_object; @@ -635,7 +636,7 @@ init_psycopg(void) asisType.ob_type = &PyType_Type; listType.ob_type = &PyType_Type; chunkType.ob_type = &PyType_Type; - + if (PyType_Ready(&connectionType) == -1) return; if (PyType_Ready(&cursorType) == -1) return; if (PyType_Ready(&typecastType) == -1) return; @@ -645,18 +646,18 @@ init_psycopg(void) if (PyType_Ready(&asisType) == -1) return; if (PyType_Ready(&listType) == -1) return; if (PyType_Ready(&chunkType) == -1) return; - + #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; if (PyType_Ready(&mxdatetimeType) == -1) return; if (mxDateTime_ImportModuleAndAPI() != 0) { - Dprintf("initpsycopg: why marc hide mx.DateTime again?!"); + Dprintf("initpsycopg: why marc hide mx.DateTime again?!"); PyErr_SetString(PyExc_ImportError, "can't import mx.DateTime module"); return; } @@ -667,7 +668,7 @@ init_psycopg(void) #ifdef HAVE_PYDATETIME pyDateTimeModuleP = PyImport_ImportModule("datetime"); if (pyDateTimeModuleP == NULL) { - Dprintf("initpsycopg: can't import datetime module"); + Dprintf("initpsycopg: can't import datetime module"); PyErr_SetString(PyExc_ImportError, "can't import datetime module"); return; } @@ -680,20 +681,20 @@ init_psycopg(void) pyTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "time"); pyDateTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "datetime"); pyDeltaTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "timedelta"); -#endif +#endif /* import psycopg2.tz anyway (TODO: replace with C-level module?) */ pyPsycopgTzModule = PyImport_ImportModule("psycopg2.tz"); if (pyPsycopgTzModule == NULL) { - Dprintf("initpsycopg: can't import psycopg2.tz module"); + Dprintf("initpsycopg: can't import psycopg2.tz module"); PyErr_SetString(PyExc_ImportError, "can't import psycopg2.tz module"); - return; + return; } - pyPsycopgTzLOCAL = - PyObject_GetAttrString(pyPsycopgTzModule, "LOCAL"); - pyPsycopgTzFixedOffsetTimezone = + pyPsycopgTzLOCAL = + PyObject_GetAttrString(pyPsycopgTzModule, "LOCAL"); + pyPsycopgTzFixedOffsetTimezone = PyObject_GetAttrString(pyPsycopgTzModule, "FixedOffsetTimezone"); - + /* initialize the module and grab module's dictionary */ module = Py_InitModule("_psycopg", psycopgMethods); dict = PyModule_GetDict(module); @@ -710,33 +711,33 @@ init_psycopg(void) psycoEncodings = PyDict_New(); psyco_encodings_fill(psycoEncodings); psyco_decimal_init(); - + /* set some module's parameters */ PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION); PyModule_AddStringConstant(module, "__doc__", "psycopg PostgreSQL driver"); PyModule_AddObject(module, "apilevel", PyString_FromString(APILEVEL)); PyModule_AddObject(module, "threadsafety", PyInt_FromLong(THREADSAFETY)); PyModule_AddObject(module, "paramstyle", PyString_FromString(PARAMSTYLE)); - + /* put new types in module dictionary */ PyModule_AddObject(module, "connection", (PyObject*)&connectionType); PyModule_AddObject(module, "cursor", (PyObject*)&cursorType); PyModule_AddObject(module, "ISQLQuote", (PyObject*)&isqlquoteType); - + /* encodings dictionary in module dictionary */ PyModule_AddObject(module, "encodings", psycoEncodings); - + /* initialize default set of typecasters */ typecast_init(dict); /* initialize microprotocols layer */ microprotocols_init(dict); psyco_adapters_init(dict); - + /* create a standard set of exceptions and add them to the module's dict */ psyco_errors_init(); psyco_errors_fill(dict); - + /* Solve win32 build issue about non-constant initializer element */ cursorType.tp_alloc = PyType_GenericAlloc; binaryType.tp_alloc = PyType_GenericAlloc; @@ -747,7 +748,7 @@ init_psycopg(void) qstringType.tp_alloc = PyType_GenericAlloc; listType.tp_alloc = PyType_GenericAlloc; chunkType.tp_alloc = PyType_GenericAlloc; - + #ifdef HAVE_PYDATETIME pydatetimeType.tp_alloc = PyType_GenericAlloc; #endif diff --git a/psycopg/python.h b/psycopg/python.h index 1c2b96d4..84bacaa2 100644 --- a/psycopg/python.h +++ b/psycopg/python.h @@ -22,12 +22,13 @@ #ifndef PSYCOPG_PYTHON_H #define PSYCOPG_PYTHON_H 1 +#define PY_SSIZE_T_CLEAN #include #include /* python < 2.2 does not have PyMemeberDef */ #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 -#define PyMemberDef memberlist +#define PyMemberDef memberlist #endif /* PyObject_TypeCheck introduced in 2.2 */ diff --git a/psycopg/typecast.c b/psycopg/typecast.c index 09473021..f720a1a4 100644 --- a/psycopg/typecast.c +++ b/psycopg/typecast.c @@ -19,6 +19,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PY_SSIZE_T_CLEAN #include #include @@ -52,9 +53,9 @@ typecast_parse_date(char* s, char** t, int* len, int* year, int* month, int* day) { int acc = -1, cz = 0; - + Dprintf("typecast_parse_date: len = %d, s = %s", *len, s); - + while (cz < 3 && *len > 0 && *s) { switch (*s) { case '-': @@ -67,7 +68,7 @@ typecast_parse_date(char* s, char** t, int* len, break; default: acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0'); - break; + break; } s++; (*len)--; @@ -77,7 +78,7 @@ typecast_parse_date(char* s, char** t, int* len, *day = acc; cz += 1; } - if (t != NULL) *t = s; + if (t != NULL) *t = s; return cz; } @@ -89,12 +90,12 @@ typecast_parse_time(char* s, char** t, int* len, int acc = -1, cz = 0; int tzs = 1, tzhh = 0, tzmm = 0; int usd = 0; - + /* sets microseconds and timezone to 0 because they may be missing */ *us = *tz = 0; - + Dprintf("typecast_parse_time: len = %d, s = %s", *len, s); - + while (cz < 6 && *len > 0 && *s) { switch (*s) { case ':': @@ -123,7 +124,7 @@ typecast_parse_time(char* s, char** t, int* len, default: acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0'); if (cz == 3) usd += 1; - break; + break; } s++; (*len)--; @@ -136,13 +137,13 @@ typecast_parse_time(char* s, char** t, int* len, else if (cz == 5) tzmm = acc; } if (t != NULL) *t = s; - + *tz = tzs * tzhh*60 + tzmm; - + if (*us != 0.0) { while (usd++ < 6) *us *= 10.0; } - + return cz; } @@ -168,7 +169,7 @@ typecastObject_initlist typecast_pydatetime[] = { {"PYDATETIME", typecast_DATETIME_types, typecast_PYDATETIME_cast}, {"PYTIME", typecast_TIME_types, typecast_PYTIME_cast}, {"PYDATE", typecast_DATE_types, typecast_PYDATE_cast}, - {"PYINTERVAL", typecast_INTERVAL_types, typecast_PYINTERVAL_cast}, + {"PYINTERVAL", typecast_INTERVAL_types, typecast_PYINTERVAL_cast}, {NULL, NULL, NULL} }; #endif @@ -179,7 +180,7 @@ typecastObject_initlist typecast_mxdatetime[] = { {"MXDATETIME", typecast_DATETIME_types, typecast_MXDATE_cast}, {"MXTIME", typecast_TIME_types, typecast_MXTIME_cast}, {"MXDATE", typecast_DATE_types, typecast_MXDATE_cast}, - {"MXINTERVAL", typecast_INTERVAL_types, typecast_MXINTERVAL_cast}, + {"MXINTERVAL", typecast_INTERVAL_types, typecast_MXINTERVAL_cast}, {NULL, NULL, NULL} }; #endif @@ -203,20 +204,20 @@ int typecast_init(PyObject *dict) { int i; - + /* create type dictionary and put it in module namespace */ psyco_types = PyDict_New(); psyco_binary_types = PyDict_New(); - + if (!psyco_types || !psyco_binary_types) { Py_XDECREF(psyco_types); Py_XDECREF(psyco_binary_types); return -1; - } + } PyDict_SetItemString(dict, "string_types", psyco_types); PyDict_SetItemString(dict, "binary_types", psyco_binary_types); - + /* insert the cast types into the 'types' dictionary and register them in the module dictionary */ for (i = 0; typecast_builtins[i].name != NULL; i++) { @@ -235,7 +236,7 @@ typecast_init(PyObject *dict) psyco_default_binary_cast = (PyObject *)t; } } - + /* create and save a default cast object (but does not register it) */ psyco_default_cast = typecast_from_c(&typecast_default, dict); @@ -258,7 +259,7 @@ typecast_init(PyObject *dict) PyDict_SetItem(dict, t->name, (PyObject *)t); } #endif - + return 0; } @@ -270,9 +271,11 @@ typecast_add(PyObject *obj, PyObject *dict, int binary) Py_ssize_t len, i; typecastObject *type = (typecastObject *)obj; - - Dprintf("typecast_add: object at %p, values refcnt = %d", - obj, type->values->ob_refcnt); + + Dprintf("typecast_add: object at %p, values refcnt = " + FORMAT_CODE_PY_SSIZE_T, + obj, type->values->ob_refcnt + ); if (dict == NULL) dict = (binary ? psyco_binary_types : psyco_types); @@ -302,7 +305,7 @@ typecast_cmp(PyObject *obj1, PyObject* obj2) PyObject *number = NULL; Py_ssize_t i, j; int res = -1; - + if (PyObject_TypeCheck(obj2, &typecastType)) { other = (typecastObject*)obj2; } @@ -311,25 +314,25 @@ typecast_cmp(PyObject *obj1, PyObject* obj2) } Dprintf("typecast_cmp: other = %p, number = %p", other, number); - + for (i=0; i < PyObject_Length(self->values) && res == -1; i++) { long int val = PyInt_AsLong(PyTuple_GET_ITEM(self->values, i)); - + if (other != NULL) { for (j=0; j < PyObject_Length(other->values); j++) { if (PyInt_AsLong(PyTuple_GET_ITEM(other->values, j)) == val) { - res = 0; break; + res = 0; break; } } } - + else if (number != NULL) { if (PyInt_AsLong(number) == val) { res = 0; break; } } } - + Py_XDECREF(number); return res; } @@ -339,29 +342,29 @@ typecast_richcompare(PyObject *obj1, PyObject* obj2, int opid) { PyObject *result = NULL; int res = typecast_cmp(obj1, obj2); - + if (PyErr_Occurred()) return NULL; - + if ((opid == Py_EQ && res == 0) || (opid != Py_EQ && res != 0)) result = Py_True; else result = Py_False; - + Py_INCREF(result); return result; } - + static struct PyMemberDef typecastObject_members[] = { {"name", T_OBJECT, OFFSETOF(name), RO}, {"values", T_OBJECT, OFFSETOF(values), RO}, {NULL} }; - + static void typecast_dealloc(PyObject *obj) { typecastObject *self = (typecastObject*)obj; - + Py_XDECREF(self->values); Py_XDECREF(self->name); Py_XDECREF(self->pcast); @@ -371,9 +374,9 @@ typecast_dealloc(PyObject *obj) static PyObject * typecast_call(PyObject *obj, PyObject *args, PyObject *kwargs) -{ +{ PyObject *string, *cursor; - + if (!PyArg_ParseTuple(args, "OO", &string, &cursor)) { return NULL; } @@ -389,9 +392,9 @@ PyTypeObject typecastType = { "psycopg2._psycopg.type", sizeof(typecastObject), 0, - + typecast_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ typecast_cmp, /*tp_compare*/ @@ -409,7 +412,7 @@ PyTypeObject typecastType = { Py_TPFLAGS_HAVE_RICHCOMPARE, /*tp_flags*/ "psycopg type-casting object", /*tp_doc*/ - + 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -426,11 +429,11 @@ PyTypeObject typecastType = { 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ - + 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - + 0, /*tp_init*/ 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ 0, /*tp_new*/ @@ -451,11 +454,12 @@ typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base) obj = PyObject_NEW(typecastObject, &typecastType); if (obj == NULL) return NULL; - Dprintf("typecast_new: new type at = %p, refcnt = %d", obj, obj->ob_refcnt); - + Dprintf("typecast_new: new type at = %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, + obj, obj->ob_refcnt); + Py_INCREF(values); obj->values = values; - + if (name) { Py_INCREF(name); obj->name = name; @@ -476,26 +480,26 @@ typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base) Py_INCREF(cast); obj->pcast = cast; } - + Dprintf("typecast_new: typecast object created at %p", obj); - + return (PyObject *)obj; } PyObject * typecast_from_python(PyObject *self, PyObject *args, PyObject *keywds) { - PyObject *v, *name, *cast = NULL, *base = NULL; + PyObject *v, *name = NULL, *cast = NULL, *base = NULL; static char *kwlist[] = {"values", "name", "castobj", "baseobj", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|O!OO", kwlist, + + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|O!OO", kwlist, &PyTuple_Type, &v, &PyString_Type, &name, &cast, &base)) { return NULL; } - + return typecast_new(name, v, cast, base); } @@ -517,18 +521,18 @@ typecast_from_c(typecastObject_initlist *type, PyObject *dict) } while (type->values[len] != 0) len++; - + tuple = PyTuple_New(len); if (!tuple) return NULL; - + for (i = 0; i < len ; i++) { PyTuple_SET_ITEM(tuple, i, PyInt_FromLong(type->values[i])); } - + obj = (typecastObject *) typecast_new(PyString_FromString(type->name), tuple, NULL, base); - + if (obj) { obj->ccast = type->cast; obj->pcast = NULL; @@ -545,7 +549,7 @@ typecast_cast(PyObject *obj, char *str, Py_ssize_t len, PyObject *curs) /* we don't incref, the caster *can't* die at this point */ old = ((cursorObject*)curs)->caster; ((cursorObject*)curs)->caster = obj; - + if (self->ccast) { res = self->ccast(str, len, curs); } diff --git a/psycopg/typecast.h b/psycopg/typecast.h index 87355b40..0e55fb8e 100644 --- a/psycopg/typecast.h +++ b/psycopg/typecast.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_TYPECAST_H #define PSYCOPG_TYPECAST_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -60,7 +61,7 @@ typedef struct { /* the type dictionary, much faster to access it globally */ extern PyObject *psyco_types; extern PyObject *psyco_binary_types; - + /* the default casting objects, used when no other objects are available */ extern PyObject *psyco_default_cast; extern PyObject *psyco_default_binary_cast; @@ -81,5 +82,5 @@ extern PyObject *typecast_from_python( /* the function used to dispatch typecasting calls */ extern PyObject *typecast_cast( PyObject *self, char *str, Py_ssize_t len, PyObject *curs); - + #endif /* !defined(PSYCOPG_TYPECAST_H) */ diff --git a/psycopg/typecast_array.c b/psycopg/typecast_array.c index 8d6cf09a..383beb12 100644 --- a/psycopg/typecast_array.c +++ b/psycopg/typecast_array.c @@ -27,9 +27,9 @@ static int typecast_array_cleanup(char **str, int *len) { int i, depth = 1; - + if ((*str)[0] != '[') return -1; - + for (i=1 ; depth > 0 && i < *len ; i++) { if ((*str)[i] == '[') depth += 1; @@ -37,7 +37,7 @@ typecast_array_cleanup(char **str, int *len) depth -= 1; } if ((*str)[i] != '=') return -1; - + *str = &((*str)[i+1]); *len = *len - i - 1; return 0; @@ -83,7 +83,7 @@ typecast_array_tokenize(char *str, int strlength, q = 0; /* if q is odd we're inside quotes */ b = 0; /* if b is 1 we just encountered a backslash */ res = ASCAN_TOKEN; - + for (i = *pos ; i < strlength ; i++) { switch (str[i]) { case '"': @@ -122,21 +122,21 @@ typecast_array_tokenize(char *str, int strlength, if (str[*pos] == '"') { *pos += 1; l -= 2; - *quotes = 1; + *quotes = 1; } - if (res == ASCAN_QUOTED) { + if (res == ASCAN_QUOTED) { char *buffer = PyMem_Malloc(l+1); if (buffer == NULL) return ASCAN_ERROR; *token = buffer; - + for (j = *pos; j < *pos+l; j++) { if (str[j] != '\\' || (j > *pos && str[j-1] == '\\')) *(buffer++) = str[j]; } - + *buffer = '\0'; *length = buffer - *token; } @@ -146,7 +146,7 @@ typecast_array_tokenize(char *str, int strlength, } *pos = i; - + /* skip the comma and set position to the start of next token */ if (str[i] == ',') *pos += 1; @@ -162,22 +162,22 @@ typecast_array_scan(char *str, int strlength, PyObject *stack[MAX_DIMENSIONS]; int stack_index = 0; - + while (1) { token = NULL; - state = typecast_array_tokenize(str, strlength, - &pos, &token, &length, "es); + state = typecast_array_tokenize(str, strlength, + &pos, &token, &length, "es); Dprintf("typecast_array_scan: state = %d, length = %d, token = '%s'", state, length, token); if (state == ASCAN_TOKEN || state == ASCAN_QUOTED) { PyObject *obj; - if (!quotes && length == 4 - && (token[0] == 'n' || token[0] == 'N') - && (token[1] == 'u' || token[1] == 'U') - && (token[2] == 'l' || token[2] == 'L') - && (token[3] == 'l' || token[3] == 'L')) - obj = typecast_cast(base, NULL, 0, curs); - else + if (!quotes && length == 4 + && (token[0] == 'n' || token[0] == 'N') + && (token[1] == 'u' || token[1] == 'U') + && (token[2] == 'l' || token[2] == 'L') + && (token[3] == 'l' || token[3] == 'L')) + obj = typecast_cast(base, NULL, 0, curs); + else obj = typecast_cast(base, token, length, curs); /* before anything else we free the memory */ @@ -189,7 +189,7 @@ typecast_array_scan(char *str, int strlength, } else if (state == ASCAN_BEGIN) { - PyObject *sub = PyList_New(0); + PyObject *sub = PyList_New(0); if (sub == NULL) return 0; PyList_Append(array, sub); @@ -201,7 +201,7 @@ typecast_array_scan(char *str, int strlength, stack[stack_index++] = array; array = sub; } - + else if (state == ASCAN_ERROR) { return 0; } @@ -222,13 +222,13 @@ typecast_array_scan(char *str, int strlength, /** GENERIC - a generic typecaster that can be used when no special actions have to be taken on the single items **/ - + static PyObject * typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs) { PyObject *obj = NULL; PyObject *base = ((typecastObject*)((cursorObject*)curs)->caster)->bcast; - + Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s', len = %d", str, len); if (str == NULL) {Py_INCREF(Py_None); return Py_None;} @@ -240,7 +240,7 @@ typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs) } Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s', len = %d", str, len); - + obj = PyList_New(0); /* scan the array skipping the first level of {} */ @@ -248,7 +248,7 @@ typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs) Py_DECREF(obj); obj = NULL; } - + return obj; } diff --git a/psycopg/typecast_binary.c b/psycopg/typecast_binary.c index d490bc70..63c5c22f 100644 --- a/psycopg/typecast_binary.c +++ b/psycopg/typecast_binary.c @@ -33,8 +33,10 @@ static void chunk_dealloc(chunkObject *self) { - Dprintf("chunk_dealloc: deallocating memory at %p, size %d", - self->base, self->len); + Dprintf("chunk_dealloc: deallocating memory at %p, size " + FORMAT_CODE_PY_SSIZE_T, + self->base, self->len + ); free(self->base); self->ob_type->tp_free((PyObject *) self); } @@ -42,12 +44,14 @@ chunk_dealloc(chunkObject *self) static PyObject * chunk_repr(chunkObject *self) { - return PyString_FromFormat("", - self->base, self->len); + return PyString_FromFormat( + "", + self->base, self->len + ); } -static int -chunk_getreadbuffer(chunkObject *self, int segment, void **ptr) +static Py_ssize_t +chunk_getreadbuffer(chunkObject *self, Py_ssize_t segment, void **ptr) { if (segment != 0) { @@ -59,8 +63,8 @@ chunk_getreadbuffer(chunkObject *self, int segment, void **ptr) return self->len; } -static int -chunk_getsegcount(chunkObject *self, int *lenp) +static Py_ssize_t +chunk_getsegcount(chunkObject *self, Py_ssize_t *lenp) { if (lenp != NULL) *lenp = self->len; @@ -69,10 +73,10 @@ chunk_getsegcount(chunkObject *self, int *lenp) static PyBufferProcs chunk_as_buffer = { - (getreadbufferproc) chunk_getreadbuffer, - (getwritebufferproc) NULL, - (getsegcountproc) chunk_getsegcount, - (getcharbufferproc) NULL + (readbufferproc) chunk_getreadbuffer, + (writebufferproc) NULL, + (segcountproc) chunk_getsegcount, + (charbufferproc) NULL }; #define chunk_doc "memory chunk" @@ -120,7 +124,7 @@ typecast_BINARY_cast_unescape(unsigned char *str, size_t *to_length) if (dststr == NULL) return NULL; Py_BEGIN_ALLOW_THREADS; - + for (i = 0; i < len; i++) { if (str[i] == '\\') { if ( ++i < len) { @@ -140,17 +144,17 @@ typecast_BINARY_cast_unescape(unsigned char *str, size_t *to_length) } dstptr++; } - + Py_END_ALLOW_THREADS; *to_length = (size_t)(dstptr-dststr); - + return dststr; } #define PQunescapeBytea typecast_BINARY_cast_unescape #endif - + static PyObject * typecast_BINARY_cast(char *s, int l, PyObject *curs) { @@ -172,12 +176,13 @@ typecast_BINARY_cast(char *s, int l, PyObject *curs) s = buffer; } str = (char*)PQunescapeBytea((unsigned char*)s, &len); - Dprintf("typecast_BINARY_cast: unescaped %d bytes", len); + Dprintf("typecast_BINARY_cast: unescaped " FORMAT_CODE_SIZE_T " bytes", + len); if (buffer) PyMem_Free(buffer); chunk = (chunkObject *) PyObject_New(chunkObject, &chunkType); if (chunk == NULL) return NULL; - + chunk->base = str; chunk->len = len; if ((res = PyBuffer_FromObject((PyObject *)chunk, 0, len)) == NULL) diff --git a/psycopg/typecast_binary.h b/psycopg/typecast_binary.h index cf985bb0..fa026201 100644 --- a/psycopg/typecast_binary.h +++ b/psycopg/typecast_binary.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_TYPECAST_BINARY_H #define PSYCOPG_TYPECAST_BINARY_H 1 +#define PY_SSIZE_T_CLEAN #include #ifdef __cplusplus @@ -36,7 +37,7 @@ typedef struct { PyObject_HEAD void *base; /* Pointer to the memory chunk. */ - int len; /* Size in bytes of the memory chunk. */ + Py_ssize_t len; /* Size in bytes of the memory chunk. */ } chunkObject; diff --git a/psycopg/typecast_datetime.c b/psycopg/typecast_datetime.c index a3919b30..81a71a46 100644 --- a/psycopg/typecast_datetime.c +++ b/psycopg/typecast_datetime.c @@ -38,9 +38,9 @@ typecast_PYDATE_cast(char *str, int len, PyObject *curs) { PyObject* obj = NULL; int n, y=0, m=0, d=0; - + if (str == NULL) {Py_INCREF(Py_None); return Py_None;} - + if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) { if (str[0] == '-') { obj = PyObject_GetAttrString(pyDateTypeP, "min"); @@ -59,7 +59,7 @@ typecast_PYDATE_cast(char *str, int len, PyObject *curs) PyErr_SetString(DataError, "unable to parse date"); } else { - if (y > 9999) y = 9999; + if (y > 9999) y = 9999; obj = PyObject_CallFunction(pyDateTypeP, "iii", y, m, d); } } @@ -75,9 +75,9 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) int n, y=0, m=0, d=0; int hh=0, mm=0, ss=0, us=0, tz=0; char *tp = NULL; - + if (str == NULL) {Py_INCREF(Py_None); return Py_None;} - + /* check for infinity */ if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) { if (str[0] == '-') { @@ -93,11 +93,11 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) n = typecast_parse_date(str, &tp, &len, &y, &m, &d); Dprintf("typecast_PYDATE_cast: tp = %p " "n = %d, len = %d, y = %d, m = %d, d = %d", - tp, n, len, y, m, d); + tp, n, len, y, m, d); if (n != 3) { PyErr_SetString(DataError, "unable to parse date"); } - + if (len > 0) { n = typecast_parse_time(tp, NULL, &len, &hh, &mm, &ss, &us, &tz); Dprintf("typecast_PYDATETIME_cast: n = %d, len = %d, " @@ -107,13 +107,13 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) PyErr_SetString(DataError, "unable to parse time"); } } - + if (ss > 59) { mm += 1; ss -= 60; } if (y > 9999) - y = 9999; + y = 9999; if (n == 5 && ((cursorObject*)curs)->tzinfo_factory != Py_None) { /* we have a time zone, calculate minutes and create @@ -124,8 +124,10 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs) ((cursorObject*)curs)->tzinfo_factory, "i", tz); obj = PyObject_CallFunction(pyDateTimeTypeP, "iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo); - Dprintf("typecast_PYDATETIME_cast: tzinfo: %p, refcnt = %d", - tzinfo, tzinfo->ob_refcnt); + Dprintf("typecast_PYDATETIME_cast: tzinfo: %p, refcnt = " + FORMAT_CODE_PY_SSIZE_T, + tzinfo, tzinfo->ob_refcnt + ); Py_XDECREF(tzinfo); } else { @@ -143,14 +145,14 @@ typecast_PYTIME_cast(char *str, int len, PyObject *curs) { PyObject* obj = NULL; int n, hh=0, mm=0, ss=0, us=0, tz=0; - + if (str == NULL) {Py_INCREF(Py_None); return Py_None;} - + n = typecast_parse_time(str, NULL, &len, &hh, &mm, &ss, &us, &tz); Dprintf("typecast_PYTIME_cast: n = %d, len = %d, " "hh = %d, mm = %d, ss = %d, us = %d, tz = %d", n, len, hh, mm, ss, us, tz); - + if (n < 3 || n > 5) { PyErr_SetString(DataError, "unable to parse time"); } @@ -161,7 +163,7 @@ typecast_PYTIME_cast(char *str, int len, PyObject *curs) } obj = PyObject_CallFunction(pyTimeTypeP, "iiii", hh, mm, ss, us); } - return obj; + return obj; } /** INTERVAL - parse an interval into a timedelta object **/ @@ -178,7 +180,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs) if (str == NULL) {Py_INCREF(Py_None); return Py_None;} Dprintf("typecast_PYINTERVAL_cast: s = %s", str); - + while (len-- > 0 && *str) { switch (*str) { @@ -234,12 +236,12 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs) seconds = v; v = 0.0; part = 6; } - break; + break; default: break; } - + str++; } @@ -254,7 +256,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs) hundredths = v; hundredths = hundredths/denominator; } - + /* calculates seconds */ if (sign < 0.0) { seconds = - (hundredths + seconds + minutes*60 + hours*3600); @@ -263,7 +265,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs) seconds += hundredths + minutes*60 + hours*3600; } - /* calculates days */ + /* calculates days */ days += years*365 + months*30; micro = (seconds - floor(seconds)) * 1000000.0; @@ -274,7 +276,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs) /* psycopg defaults to using python datetime types */ -#ifdef PSYCOPG_DEFAULT_PYDATETIME +#ifdef PSYCOPG_DEFAULT_PYDATETIME #define typecast_DATE_cast typecast_PYDATE_cast #define typecast_TIME_cast typecast_PYTIME_cast #define typecast_INTERVAL_cast typecast_PYINTERVAL_cast