summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--NEWS-2.31
-rw-r--r--psycopg/adapter_pdecimal.c40
3 files changed, 30 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index fe80d8a..11b6fc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,9 @@
* psycopg/microprotocols.c: use the adapter of an object superclass if
available.
+ * psycopg/adapter_pdecimal.c: fixed crash in pdecimal_str with Python
+ 2.5.x releases in which is_finite() is not available.
+
2010-11-06 Daniele Varrazzo <daniele.varrazzo@gmail.com>
* lib/extras.py: added NamedTupleCursor.
diff --git a/NEWS-2.3 b/NEWS-2.3
index a504fe2..4ddfc92 100644
--- a/NEWS-2.3
+++ b/NEWS-2.3
@@ -25,6 +25,7 @@ psycopg 2.3 aims to expose some new features introduced in PostgreSQL 9.0.
- Fixed use of `PQfreemem` instead of `free` in binary typecaster.
- Fixed access to freed memory in `conn_get_isolation_level()`.
+ - Fixed crash during Decimal adaptation with a few 2.5.x Python versions.
What's new in psycopg 2.2.2
diff --git a/psycopg/adapter_pdecimal.c b/psycopg/adapter_pdecimal.c
index 3112b8f..c11e753 100644
--- a/psycopg/adapter_pdecimal.c
+++ b/psycopg/adapter_pdecimal.c
@@ -43,29 +43,41 @@ static PyObject *
pdecimal_str(pdecimalObject *self)
{
PyObject *check, *res = NULL;
-#if PY_VERSION_HEX < 0x02050000
- check = PyObject_CallMethod(self->wrapped, "_isnan", NULL);
- if (PyInt_AsLong(check) == 1) {
+ check = PyObject_CallMethod(self->wrapped, "is_finite", NULL);
+ if (check == Py_True) {
+ res = PyObject_Str(self->wrapped);
+ goto end;
+ }
+ else if (check) {
+ res = PyString_FromString("'NaN'::numeric");
+ goto end;
+ }
+
+ /* is_finite() was introduced 2.5.1 < somewhere <= 2.5.4.
+ * We assume we are here because we didn't find the method. */
+ PyErr_Clear();
+
+ if (!(check = PyObject_CallMethod(self->wrapped, "_isnan", NULL))) {
+ goto end;
+ }
+ if (PyObject_IsTrue(check)) {
res = PyString_FromString("'NaN'::numeric");
goto end;
}
+
Py_DECREF(check);
- check = PyObject_CallMethod(self->wrapped, "_isinfinity", NULL);
- if (abs(PyInt_AsLong(check)) == 1) {
+ if (!(check = PyObject_CallMethod(self->wrapped, "_isinfinity", NULL))) {
+ goto end;
+ }
+ if (PyObject_IsTrue(check)) {
res = PyString_FromString("'NaN'::numeric");
goto end;
}
+
res = PyObject_Str(self->wrapped);
-#else
- check = PyObject_CallMethod(self->wrapped, "is_finite", NULL);
- if (check == Py_True)
- res = PyObject_Str(self->wrapped);
- else
- res = PyString_FromString("'NaN'::numeric");
-#endif
- end:
- Py_DECREF(check);
+end:
+ Py_XDECREF(check);
return res;
}