summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_ctypes/_ctypes.c115
-rw-r--r--Modules/_sqlite/cursor.c6
-rw-r--r--Modules/_sqlite/row.c28
-rw-r--r--Modules/_sqlite/statement.c7
-rw-r--r--Modules/_testcapimodule.c19
-rw-r--r--Modules/mathmodule.c1
6 files changed, 166 insertions, 10 deletions
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 9631808..79fc6c8 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -409,6 +409,115 @@ CDataType_from_address(PyObject *type, PyObject *value)
return CData_AtAddress(type, buf);
}
+static char from_buffer_doc[] =
+"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer";
+
+static int
+KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
+
+static PyObject *
+CDataType_from_buffer(PyObject *type, PyObject *args)
+{
+ void *buffer;
+ Py_ssize_t buffer_len;
+ Py_ssize_t offset = 0;
+ PyObject *obj, *result;
+ StgDictObject *dict = PyType_stgdict(type);
+ assert (dict);
+
+ if (!PyArg_ParseTuple(args,
+#if (PY_VERSION_HEX < 0x02050000)
+ "O|i:from_buffer",
+#else
+ "O|n:from_buffer",
+#endif
+ &obj, &offset))
+ return NULL;
+
+ if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
+ return NULL;
+
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset cannit be negative");
+ return NULL;
+ }
+ if (dict->size > buffer_len - offset) {
+ PyErr_Format(PyExc_ValueError,
+#if (PY_VERSION_HEX < 0x02050000)
+ "Buffer size too small (%d instead of at least %d bytes)",
+#else
+ "Buffer size too small (%zd instead of at least %zd bytes)",
+#endif
+ buffer_len, dict->size + offset);
+ return NULL;
+ }
+
+ result = CData_AtAddress(type, (char *)buffer + offset);
+ if (result == NULL)
+ return NULL;
+
+ Py_INCREF(obj);
+ if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ return result;
+}
+
+static char from_buffer_copy_doc[] =
+"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer";
+
+static PyObject *
+GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+CDataType_from_buffer_copy(PyObject *type, PyObject *args)
+{
+ void *buffer;
+ Py_ssize_t buffer_len;
+ Py_ssize_t offset = 0;
+ PyObject *obj, *result;
+ StgDictObject *dict = PyType_stgdict(type);
+ assert (dict);
+
+ if (!PyArg_ParseTuple(args,
+#if (PY_VERSION_HEX < 0x02050000)
+ "O|i:from_buffer",
+#else
+ "O|n:from_buffer",
+#endif
+ &obj, &offset))
+ return NULL;
+
+ if (-1 == PyObject_AsReadBuffer(obj, &buffer, &buffer_len))
+ return NULL;
+
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset cannit be negative");
+ return NULL;
+ }
+
+ if (dict->size > buffer_len - offset) {
+ PyErr_Format(PyExc_ValueError,
+#if (PY_VERSION_HEX < 0x02050000)
+ "Buffer size too small (%d instead of at least %d bytes)",
+#else
+ "Buffer size too small (%zd instead of at least %zd bytes)",
+#endif
+ buffer_len, dict->size + offset);
+ return NULL;
+ }
+
+ result = GenericCData_new((PyTypeObject *)type, NULL, NULL);
+ if (result == NULL)
+ return NULL;
+ memcpy(((CDataObject *)result)->b_ptr,
+ (char *)buffer+offset, dict->size);
+ return result;
+}
+
static char in_dll_doc[] =
"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
@@ -513,6 +622,8 @@ CDataType_from_param(PyObject *type, PyObject *value)
static PyMethodDef CDataType_methods[] = {
{ "from_param", CDataType_from_param, METH_O, from_param_doc },
{ "from_address", CDataType_from_address, METH_O, from_address_doc },
+ { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
+ { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
{ "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
{ NULL, NULL },
};
@@ -849,6 +960,8 @@ PointerType_from_param(PyObject *type, PyObject *value)
static PyMethodDef PointerType_methods[] = {
{ "from_address", CDataType_from_address, METH_O, from_address_doc },
+ { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
+ { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
{ "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
{ "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc},
{ "set_type", (PyCFunction)PointerType_set_type, METH_O },
@@ -1920,6 +2033,8 @@ SimpleType_from_param(PyObject *type, PyObject *value)
static PyMethodDef SimpleType_methods[] = {
{ "from_param", SimpleType_from_param, METH_O, from_param_doc },
{ "from_address", CDataType_from_address, METH_O, from_address_doc },
+ { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
+ { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
{ "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
{ NULL, NULL },
};
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index 8efa812..10ce2e1 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -202,7 +202,11 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
decltype = sqlite3_column_decltype(self->statement->st, i);
if (decltype) {
for (pos = decltype;;pos++) {
- if (*pos == ' ' || *pos == 0) {
+ /* Converter names are split at '(' and blanks.
+ * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and
+ * 'NUMBER(10)' to be treated as 'NUMBER', for example.
+ * In other words, it will work as people expect it to work.*/
+ if (*pos == ' ' || *pos == '(' || *pos == 0) {
py_decltype = PyUnicode_FromStringAndSize(decltype, pos - decltype);
if (!py_decltype) {
return -1;
diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c
index 47b91ed..008f19e 100644
--- a/Modules/_sqlite/row.c
+++ b/Modules/_sqlite/row.c
@@ -164,6 +164,30 @@ static PyObject* pysqlite_iter(pysqlite_Row* self)
return PyObject_GetIter(self->data);
}
+static long pysqlite_row_hash(pysqlite_Row *self)
+{
+ return PyObject_Hash(self->description) ^ PyObject_Hash(self->data);
+}
+
+static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
+{
+ if (opid != Py_EQ && opid != Py_NE) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
+ pysqlite_Row *other = (pysqlite_Row *)_other;
+ PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
+ if (opid == Py_EQ && res == Py_True
+ || opid == Py_NE && res == Py_False) {
+ Py_DECREF(res);
+ return PyObject_RichCompare(self->data, other->data, opid);
+ }
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
PyMappingMethods pysqlite_row_as_mapping = {
/* mp_length */ (lenfunc)pysqlite_row_length,
/* mp_subscript */ (binaryfunc)pysqlite_row_subscript,
@@ -191,7 +215,7 @@ PyTypeObject pysqlite_RowType = {
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
- 0, /* tp_hash */
+ (hashfunc)pysqlite_row_hash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
@@ -201,7 +225,7 @@ PyTypeObject pysqlite_RowType = {
0, /* tp_doc */
(traverseproc)0, /* tp_traverse */
0, /* tp_clear */
- 0, /* tp_richcompare */
+ (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc)pysqlite_iter, /* tp_iter */
0, /* tp_iternext */
diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c
index 66adff3..ebf948b 100644
--- a/Modules/_sqlite/statement.c
+++ b/Modules/_sqlite/statement.c
@@ -89,10 +89,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars)
{
int rc = SQLITE_OK;
- long longval;
-#ifdef HAVE_LONG_LONG
PY_LONG_LONG longlongval;
-#endif
const char* buffer;
char* string;
Py_ssize_t buflen;
@@ -136,12 +133,8 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
switch (paramtype) {
case TYPE_LONG:
/* in the overflow error case, longval/longlongval is -1, and an exception is set */
-#ifdef HAVE_LONG_LONG
longlongval = PyLong_AsLongLong(parameter);
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
-#else
- rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
-#endif
break;
case TYPE_FLOAT:
rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 45184c6..cdee975 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -900,6 +900,24 @@ profile_int(PyObject *self, PyObject* args)
}
#endif
+/* To test the format of tracebacks as printed out. */
+static PyObject *
+traceback_print(PyObject *self, PyObject *args)
+{
+ PyObject *file;
+ PyObject *traceback;
+ int result;
+
+ if (!PyArg_ParseTuple(args, "OO:traceback_print",
+ &traceback, &file))
+ return NULL;
+
+ result = PyTraceBack_Print(traceback, file);
+ if (result < 0)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"test_config", (PyCFunction)test_config, METH_NOARGS},
@@ -942,6 +960,7 @@ static PyMethodDef TestMethods[] = {
#ifdef HAVE_GETTIMEOFDAY
{"profile_int", profile_int, METH_NOARGS},
#endif
+ {"traceback_print", traceback_print, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 99af899..6fc7bb8 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -653,6 +653,7 @@ math_pow(PyObject *self, PyObject *args)
/* deal directly with IEEE specials, to cope with problems on various
platforms whose semantics don't exactly match C99 */
+ r = 0.; /* silence compiler warning */
if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) {
errno = 0;
if (Py_IS_NAN(x))