diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 115 | ||||
-rw-r--r-- | Modules/_sqlite/cursor.c | 6 | ||||
-rw-r--r-- | Modules/_sqlite/row.c | 28 | ||||
-rw-r--r-- | Modules/_sqlite/statement.c | 7 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 19 | ||||
-rw-r--r-- | Modules/mathmodule.c | 1 |
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)) |