summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sqlalchemy/cextension/processors.c706
-rw-r--r--lib/sqlalchemy/cextension/resultproxy.c718
-rw-r--r--lib/sqlalchemy/cextension/utils.c225
-rw-r--r--lib/sqlalchemy/engine/result.py4
-rw-r--r--lib/sqlalchemy/engine/util.py2
-rw-r--r--lib/sqlalchemy/processors.py2
-rw-r--r--setup.py91
-rw-r--r--test/base/test_utils.py8
-rw-r--r--test/engine/test_processors.py4
-rw-r--r--test/requirements.py2
10 files changed, 21 insertions, 1741 deletions
diff --git a/lib/sqlalchemy/cextension/processors.c b/lib/sqlalchemy/cextension/processors.c
deleted file mode 100644
index d56817763..000000000
--- a/lib/sqlalchemy/cextension/processors.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
-processors.c
-Copyright (C) 2010-2014 the SQLAlchemy authors and contributors <see AUTHORS file>
-Copyright (C) 2010-2011 Gaetan de Menten gdementen@gmail.com
-
-This module is part of SQLAlchemy and is released under
-the MIT License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-#include <Python.h>
-#include <datetime.h>
-
-#define MODULE_NAME "cprocessors"
-#define MODULE_DOC "Module containing C versions of data processing functions."
-
-#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
-#endif
-
-static PyObject *
-int_to_boolean(PyObject *self, PyObject *arg)
-{
- long l = 0;
- PyObject *res;
-
- if (arg == Py_None)
- Py_RETURN_NONE;
-
-
-#if PY_MAJOR_VERSION >= 3
- l = PyLong_AsLong(arg);
-#else
- l = PyInt_AsLong(arg);
-#endif
- if (l == 0) {
- res = Py_False;
- } else if (l == 1) {
- res = Py_True;
- } else if ((l == -1) && PyErr_Occurred()) {
- /* -1 can be either the actual value, or an error flag. */
- return NULL;
- } else {
- PyErr_SetString(PyExc_ValueError,
- "int_to_boolean only accepts None, 0 or 1");
- return NULL;
- }
-
- Py_INCREF(res);
- return res;
-}
-
-static PyObject *
-to_str(PyObject *self, PyObject *arg)
-{
- if (arg == Py_None)
- Py_RETURN_NONE;
-
- return PyObject_Str(arg);
-}
-
-static PyObject *
-to_float(PyObject *self, PyObject *arg)
-{
- if (arg == Py_None)
- Py_RETURN_NONE;
-
- return PyNumber_Float(arg);
-}
-
-static PyObject *
-str_to_datetime(PyObject *self, PyObject *arg)
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *bytes;
- PyObject *err_bytes;
-#endif
- const char *str;
- int numparsed;
- unsigned int year, month, day, hour, minute, second, microsecond = 0;
- PyObject *err_repr;
-
- if (arg == Py_None)
- Py_RETURN_NONE;
-
-#if PY_MAJOR_VERSION >= 3
- bytes = PyUnicode_AsASCIIString(arg);
- if (bytes == NULL)
- str = NULL;
- else
- str = PyBytes_AS_STRING(bytes);
-#else
- str = PyString_AsString(arg);
-#endif
- if (str == NULL) {
- err_repr = PyObject_Repr(arg);
- if (err_repr == NULL)
- return NULL;
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(err_repr);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse datetime string '%.200s' "
- "- value is not a string.",
- PyBytes_AS_STRING(err_bytes));
- Py_DECREF(err_bytes);
-#else
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse datetime string '%.200s' "
- "- value is not a string.",
- PyString_AsString(err_repr));
-#endif
- Py_DECREF(err_repr);
- return NULL;
- }
-
- /* microseconds are optional */
- /*
- TODO: this is slightly less picky than the Python version which would
- not accept "2000-01-01 00:00:00.". I don't know which is better, but they
- should be coherent.
- */
- numparsed = sscanf(str, "%4u-%2u-%2u %2u:%2u:%2u.%6u", &year, &month, &day,
- &hour, &minute, &second, &microsecond);
-#if PY_MAJOR_VERSION >= 3
- Py_DECREF(bytes);
-#endif
- if (numparsed < 6) {
- err_repr = PyObject_Repr(arg);
- if (err_repr == NULL)
- return NULL;
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(err_repr);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse datetime string: %.200s",
- PyBytes_AS_STRING(err_bytes));
- Py_DECREF(err_bytes);
-#else
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse datetime string: %.200s",
- PyString_AsString(err_repr));
-#endif
- Py_DECREF(err_repr);
- return NULL;
- }
- return PyDateTime_FromDateAndTime(year, month, day,
- hour, minute, second, microsecond);
-}
-
-static PyObject *
-str_to_time(PyObject *self, PyObject *arg)
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *bytes;
- PyObject *err_bytes;
-#endif
- const char *str;
- int numparsed;
- unsigned int hour, minute, second, microsecond = 0;
- PyObject *err_repr;
-
- if (arg == Py_None)
- Py_RETURN_NONE;
-
-#if PY_MAJOR_VERSION >= 3
- bytes = PyUnicode_AsASCIIString(arg);
- if (bytes == NULL)
- str = NULL;
- else
- str = PyBytes_AS_STRING(bytes);
-#else
- str = PyString_AsString(arg);
-#endif
- if (str == NULL) {
- err_repr = PyObject_Repr(arg);
- if (err_repr == NULL)
- return NULL;
-
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(err_repr);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse time string '%.200s' - value is not a string.",
- PyBytes_AS_STRING(err_bytes));
- Py_DECREF(err_bytes);
-#else
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse time string '%.200s' - value is not a string.",
- PyString_AsString(err_repr));
-#endif
- Py_DECREF(err_repr);
- return NULL;
- }
-
- /* microseconds are optional */
- /*
- TODO: this is slightly less picky than the Python version which would
- not accept "00:00:00.". I don't know which is better, but they should be
- coherent.
- */
- numparsed = sscanf(str, "%2u:%2u:%2u.%6u", &hour, &minute, &second,
- &microsecond);
-#if PY_MAJOR_VERSION >= 3
- Py_DECREF(bytes);
-#endif
- if (numparsed < 3) {
- err_repr = PyObject_Repr(arg);
- if (err_repr == NULL)
- return NULL;
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(err_repr);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse time string: %.200s",
- PyBytes_AS_STRING(err_bytes));
- Py_DECREF(err_bytes);
-#else
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse time string: %.200s",
- PyString_AsString(err_repr));
-#endif
- Py_DECREF(err_repr);
- return NULL;
- }
- return PyTime_FromTime(hour, minute, second, microsecond);
-}
-
-static PyObject *
-str_to_date(PyObject *self, PyObject *arg)
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject *bytes;
- PyObject *err_bytes;
-#endif
- const char *str;
- int numparsed;
- unsigned int year, month, day;
- PyObject *err_repr;
-
- if (arg == Py_None)
- Py_RETURN_NONE;
-
-#if PY_MAJOR_VERSION >= 3
- bytes = PyUnicode_AsASCIIString(arg);
- if (bytes == NULL)
- str = NULL;
- else
- str = PyBytes_AS_STRING(bytes);
-#else
- str = PyString_AsString(arg);
-#endif
- if (str == NULL) {
- err_repr = PyObject_Repr(arg);
- if (err_repr == NULL)
- return NULL;
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(err_repr);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse date string '%.200s' - value is not a string.",
- PyBytes_AS_STRING(err_bytes));
- Py_DECREF(err_bytes);
-#else
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse date string '%.200s' - value is not a string.",
- PyString_AsString(err_repr));
-#endif
- Py_DECREF(err_repr);
- return NULL;
- }
-
- numparsed = sscanf(str, "%4u-%2u-%2u", &year, &month, &day);
-#if PY_MAJOR_VERSION >= 3
- Py_DECREF(bytes);
-#endif
- if (numparsed != 3) {
- err_repr = PyObject_Repr(arg);
- if (err_repr == NULL)
- return NULL;
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(err_repr);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse date string: %.200s",
- PyBytes_AS_STRING(err_bytes));
- Py_DECREF(err_bytes);
-#else
- PyErr_Format(
- PyExc_ValueError,
- "Couldn't parse date string: %.200s",
- PyString_AsString(err_repr));
-#endif
- Py_DECREF(err_repr);
- return NULL;
- }
- return PyDate_FromDate(year, month, day);
-}
-
-
-/***********
- * Structs *
- ***********/
-
-typedef struct {
- PyObject_HEAD
- PyObject *encoding;
- PyObject *errors;
-} UnicodeResultProcessor;
-
-typedef struct {
- PyObject_HEAD
- PyObject *type;
- PyObject *format;
-} DecimalResultProcessor;
-
-
-
-/**************************
- * UnicodeResultProcessor *
- **************************/
-
-static int
-UnicodeResultProcessor_init(UnicodeResultProcessor *self, PyObject *args,
- PyObject *kwds)
-{
- PyObject *encoding, *errors = NULL;
- static char *kwlist[] = {"encoding", "errors", NULL};
-
-#if PY_MAJOR_VERSION >= 3
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|U:__init__", kwlist,
- &encoding, &errors))
- return -1;
-#else
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|S:__init__", kwlist,
- &encoding, &errors))
- return -1;
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- encoding = PyUnicode_AsASCIIString(encoding);
-#else
- Py_INCREF(encoding);
-#endif
- self->encoding = encoding;
-
- if (errors) {
-#if PY_MAJOR_VERSION >= 3
- errors = PyUnicode_AsASCIIString(errors);
-#else
- Py_INCREF(errors);
-#endif
- } else {
-#if PY_MAJOR_VERSION >= 3
- errors = PyBytes_FromString("strict");
-#else
- errors = PyString_FromString("strict");
-#endif
- if (errors == NULL)
- return -1;
- }
- self->errors = errors;
-
- return 0;
-}
-
-static PyObject *
-UnicodeResultProcessor_process(UnicodeResultProcessor *self, PyObject *value)
-{
- const char *encoding, *errors;
- char *str;
- Py_ssize_t len;
-
- if (value == Py_None)
- Py_RETURN_NONE;
-
-#if PY_MAJOR_VERSION >= 3
- if (PyBytes_AsStringAndSize(value, &str, &len))
- return NULL;
-
- encoding = PyBytes_AS_STRING(self->encoding);
- errors = PyBytes_AS_STRING(self->errors);
-#else
- if (PyString_AsStringAndSize(value, &str, &len))
- return NULL;
-
- encoding = PyString_AS_STRING(self->encoding);
- errors = PyString_AS_STRING(self->errors);
-#endif
-
- return PyUnicode_Decode(str, len, encoding, errors);
-}
-
-static PyObject *
-UnicodeResultProcessor_conditional_process(UnicodeResultProcessor *self, PyObject *value)
-{
- const char *encoding, *errors;
- char *str;
- Py_ssize_t len;
-
- if (value == Py_None)
- Py_RETURN_NONE;
-
-#if PY_MAJOR_VERSION >= 3
- if (PyUnicode_Check(value) == 1) {
- Py_INCREF(value);
- return value;
- }
-
- if (PyBytes_AsStringAndSize(value, &str, &len))
- return NULL;
-
- encoding = PyBytes_AS_STRING(self->encoding);
- errors = PyBytes_AS_STRING(self->errors);
-#else
-
- if (PyUnicode_Check(value) == 1) {
- Py_INCREF(value);
- return value;
- }
-
- if (PyString_AsStringAndSize(value, &str, &len))
- return NULL;
-
-
- encoding = PyString_AS_STRING(self->encoding);
- errors = PyString_AS_STRING(self->errors);
-#endif
-
- return PyUnicode_Decode(str, len, encoding, errors);
-}
-
-static void
-UnicodeResultProcessor_dealloc(UnicodeResultProcessor *self)
-{
- Py_XDECREF(self->encoding);
- Py_XDECREF(self->errors);
-#if PY_MAJOR_VERSION >= 3
- Py_TYPE(self)->tp_free((PyObject*)self);
-#else
- self->ob_type->tp_free((PyObject*)self);
-#endif
-}
-
-static PyMethodDef UnicodeResultProcessor_methods[] = {
- {"process", (PyCFunction)UnicodeResultProcessor_process, METH_O,
- "The value processor itself."},
- {"conditional_process", (PyCFunction)UnicodeResultProcessor_conditional_process, METH_O,
- "Conditional version of the value processor."},
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject UnicodeResultProcessorType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "sqlalchemy.cprocessors.UnicodeResultProcessor", /* tp_name */
- sizeof(UnicodeResultProcessor), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnicodeResultProcessor_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- "UnicodeResultProcessor objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- UnicodeResultProcessor_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnicodeResultProcessor_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-/**************************
- * DecimalResultProcessor *
- **************************/
-
-static int
-DecimalResultProcessor_init(DecimalResultProcessor *self, PyObject *args,
- PyObject *kwds)
-{
- PyObject *type, *format;
-
-#if PY_MAJOR_VERSION >= 3
- if (!PyArg_ParseTuple(args, "OU", &type, &format))
-#else
- if (!PyArg_ParseTuple(args, "OS", &type, &format))
-#endif
- return -1;
-
- Py_INCREF(type);
- self->type = type;
-
- Py_INCREF(format);
- self->format = format;
-
- return 0;
-}
-
-static PyObject *
-DecimalResultProcessor_process(DecimalResultProcessor *self, PyObject *value)
-{
- PyObject *str, *result, *args;
-
- if (value == Py_None)
- Py_RETURN_NONE;
-
- /* Decimal does not accept float values directly */
- /* SQLite can also give us an integer here (see [ticket:2432]) */
- /* XXX: starting with Python 3.1, we could use Decimal.from_float(f),
- but the result wouldn't be the same */
-
- args = PyTuple_Pack(1, value);
- if (args == NULL)
- return NULL;
-
-#if PY_MAJOR_VERSION >= 3
- str = PyUnicode_Format(self->format, args);
-#else
- str = PyString_Format(self->format, args);
-#endif
-
- Py_DECREF(args);
- if (str == NULL)
- return NULL;
-
- result = PyObject_CallFunctionObjArgs(self->type, str, NULL);
- Py_DECREF(str);
- return result;
-}
-
-static void
-DecimalResultProcessor_dealloc(DecimalResultProcessor *self)
-{
- Py_XDECREF(self->type);
- Py_XDECREF(self->format);
-#if PY_MAJOR_VERSION >= 3
- Py_TYPE(self)->tp_free((PyObject*)self);
-#else
- self->ob_type->tp_free((PyObject*)self);
-#endif
-}
-
-static PyMethodDef DecimalResultProcessor_methods[] = {
- {"process", (PyCFunction)DecimalResultProcessor_process, METH_O,
- "The value processor itself."},
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject DecimalResultProcessorType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "sqlalchemy.DecimalResultProcessor", /* tp_name */
- sizeof(DecimalResultProcessor), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)DecimalResultProcessor_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- "DecimalResultProcessor objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- DecimalResultProcessor_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)DecimalResultProcessor_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-static PyMethodDef module_methods[] = {
- {"int_to_boolean", int_to_boolean, METH_O,
- "Convert an integer to a boolean."},
- {"to_str", to_str, METH_O,
- "Convert any value to its string representation."},
- {"to_float", to_float, METH_O,
- "Convert any value to its floating point representation."},
- {"str_to_datetime", str_to_datetime, METH_O,
- "Convert an ISO string to a datetime.datetime object."},
- {"str_to_time", str_to_time, METH_O,
- "Convert an ISO string to a datetime.time object."},
- {"str_to_date", str_to_date, METH_O,
- "Convert an ISO string to a datetime.date object."},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
-
-static struct PyModuleDef module_def = {
- PyModuleDef_HEAD_INIT,
- MODULE_NAME,
- MODULE_DOC,
- -1,
- module_methods
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC
-PyInit_cprocessors(void)
-
-#else
-
-#define INITERROR return
-
-PyMODINIT_FUNC
-initcprocessors(void)
-
-#endif
-
-{
- PyObject *m;
-
- UnicodeResultProcessorType.tp_new = PyType_GenericNew;
- if (PyType_Ready(&UnicodeResultProcessorType) < 0)
- INITERROR;
-
- DecimalResultProcessorType.tp_new = PyType_GenericNew;
- if (PyType_Ready(&DecimalResultProcessorType) < 0)
- INITERROR;
-
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&module_def);
-#else
- m = Py_InitModule3(MODULE_NAME, module_methods, MODULE_DOC);
-#endif
- if (m == NULL)
- INITERROR;
-
- PyDateTime_IMPORT;
-
- Py_INCREF(&UnicodeResultProcessorType);
- PyModule_AddObject(m, "UnicodeResultProcessor",
- (PyObject *)&UnicodeResultProcessorType);
-
- Py_INCREF(&DecimalResultProcessorType);
- PyModule_AddObject(m, "DecimalResultProcessor",
- (PyObject *)&DecimalResultProcessorType);
-
-#if PY_MAJOR_VERSION >= 3
- return m;
-#endif
-}
diff --git a/lib/sqlalchemy/cextension/resultproxy.c b/lib/sqlalchemy/cextension/resultproxy.c
deleted file mode 100644
index 218c7b807..000000000
--- a/lib/sqlalchemy/cextension/resultproxy.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
-resultproxy.c
-Copyright (C) 2010-2014 the SQLAlchemy authors and contributors <see AUTHORS file>
-Copyright (C) 2010-2011 Gaetan de Menten gdementen@gmail.com
-
-This module is part of SQLAlchemy and is released under
-the MIT License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-#include <Python.h>
-
-#define MODULE_NAME "cresultproxy"
-#define MODULE_DOC "Module containing C versions of core ResultProxy classes."
-
-#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
-typedef Py_ssize_t (*lenfunc)(PyObject *);
-#define PyInt_FromSsize_t(x) PyInt_FromLong(x)
-typedef intargfunc ssizeargfunc;
-#endif
-
-
-/***********
- * Structs *
- ***********/
-
-typedef struct {
- PyObject_HEAD
- PyObject *parent;
- PyObject *row;
- PyObject *processors;
- PyObject *keymap;
-} BaseRowProxy;
-
-/****************
- * BaseRowProxy *
- ****************/
-
-static PyObject *
-safe_rowproxy_reconstructor(PyObject *self, PyObject *args)
-{
- PyObject *cls, *state, *tmp;
- BaseRowProxy *obj;
-
- if (!PyArg_ParseTuple(args, "OO", &cls, &state))
- return NULL;
-
- obj = (BaseRowProxy *)PyObject_CallMethod(cls, "__new__", "O", cls);
- if (obj == NULL)
- return NULL;
-
- tmp = PyObject_CallMethod((PyObject *)obj, "__setstate__", "O", state);
- if (tmp == NULL) {
- Py_DECREF(obj);
- return NULL;
- }
- Py_DECREF(tmp);
-
- if (obj->parent == NULL || obj->row == NULL ||
- obj->processors == NULL || obj->keymap == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "__setstate__ for BaseRowProxy subclasses must set values "
- "for parent, row, processors and keymap");
- Py_DECREF(obj);
- return NULL;
- }
-
- return (PyObject *)obj;
-}
-
-static int
-BaseRowProxy_init(BaseRowProxy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *parent, *row, *processors, *keymap;
-
- if (!PyArg_UnpackTuple(args, "BaseRowProxy", 4, 4,
- &parent, &row, &processors, &keymap))
- return -1;
-
- Py_INCREF(parent);
- self->parent = parent;
-
- if (!PySequence_Check(row)) {
- PyErr_SetString(PyExc_TypeError, "row must be a sequence");
- return -1;
- }
- Py_INCREF(row);
- self->row = row;
-
- if (!PyList_CheckExact(processors)) {
- PyErr_SetString(PyExc_TypeError, "processors must be a list");
- return -1;
- }
- Py_INCREF(processors);
- self->processors = processors;
-
- if (!PyDict_CheckExact(keymap)) {
- PyErr_SetString(PyExc_TypeError, "keymap must be a dict");
- return -1;
- }
- Py_INCREF(keymap);
- self->keymap = keymap;
-
- return 0;
-}
-
-/* We need the reduce method because otherwise the default implementation
- * does very weird stuff for pickle protocol 0 and 1. It calls
- * BaseRowProxy.__new__(RowProxy_instance) upon *pickling*.
- */
-static PyObject *
-BaseRowProxy_reduce(PyObject *self)
-{
- PyObject *method, *state;
- PyObject *module, *reconstructor, *cls;
-
- method = PyObject_GetAttrString(self, "__getstate__");
- if (method == NULL)
- return NULL;
-
- state = PyObject_CallObject(method, NULL);
- Py_DECREF(method);
- if (state == NULL)
- return NULL;
-
- module = PyImport_ImportModule("sqlalchemy.engine.result");
- if (module == NULL)
- return NULL;
-
- reconstructor = PyObject_GetAttrString(module, "rowproxy_reconstructor");
- Py_DECREF(module);
- if (reconstructor == NULL) {
- Py_DECREF(state);
- return NULL;
- }
-
- cls = PyObject_GetAttrString(self, "__class__");
- if (cls == NULL) {
- Py_DECREF(reconstructor);
- Py_DECREF(state);
- return NULL;
- }
-
- return Py_BuildValue("(N(NN))", reconstructor, cls, state);
-}
-
-static void
-BaseRowProxy_dealloc(BaseRowProxy *self)
-{
- Py_XDECREF(self->parent);
- Py_XDECREF(self->row);
- Py_XDECREF(self->processors);
- Py_XDECREF(self->keymap);
-#if PY_MAJOR_VERSION >= 3
- Py_TYPE(self)->tp_free((PyObject *)self);
-#else
- self->ob_type->tp_free((PyObject *)self);
-#endif
-}
-
-static PyObject *
-BaseRowProxy_processvalues(PyObject *values, PyObject *processors, int astuple)
-{
- Py_ssize_t num_values, num_processors;
- PyObject **valueptr, **funcptr, **resultptr;
- PyObject *func, *result, *processed_value, *values_fastseq;
-
- num_values = PySequence_Length(values);
- num_processors = PyList_Size(processors);
- if (num_values != num_processors) {
- PyErr_Format(PyExc_RuntimeError,
- "number of values in row (%d) differ from number of column "
- "processors (%d)",
- (int)num_values, (int)num_processors);
- return NULL;
- }
-
- if (astuple) {
- result = PyTuple_New(num_values);
- } else {
- result = PyList_New(num_values);
- }
- if (result == NULL)
- return NULL;
-
- values_fastseq = PySequence_Fast(values, "row must be a sequence");
- if (values_fastseq == NULL)
- return NULL;
-
- valueptr = PySequence_Fast_ITEMS(values_fastseq);
- funcptr = PySequence_Fast_ITEMS(processors);
- resultptr = PySequence_Fast_ITEMS(result);
- while (--num_values >= 0) {
- func = *funcptr;
- if (func != Py_None) {
- processed_value = PyObject_CallFunctionObjArgs(func, *valueptr,
- NULL);
- if (processed_value == NULL) {
- Py_DECREF(values_fastseq);
- Py_DECREF(result);
- return NULL;
- }
- *resultptr = processed_value;
- } else {
- Py_INCREF(*valueptr);
- *resultptr = *valueptr;
- }
- valueptr++;
- funcptr++;
- resultptr++;
- }
- Py_DECREF(values_fastseq);
- return result;
-}
-
-static PyListObject *
-BaseRowProxy_values(BaseRowProxy *self)
-{
- return (PyListObject *)BaseRowProxy_processvalues(self->row,
- self->processors, 0);
-}
-
-static PyObject *
-BaseRowProxy_iter(BaseRowProxy *self)
-{
- PyObject *values, *result;
-
- values = BaseRowProxy_processvalues(self->row, self->processors, 1);
- if (values == NULL)
- return NULL;
-
- result = PyObject_GetIter(values);
- Py_DECREF(values);
- if (result == NULL)
- return NULL;
-
- return result;
-}
-
-static Py_ssize_t
-BaseRowProxy_length(BaseRowProxy *self)
-{
- return PySequence_Length(self->row);
-}
-
-static PyObject *
-BaseRowProxy_subscript(BaseRowProxy *self, PyObject *key)
-{
- PyObject *processors, *values;
- PyObject *processor, *value, *processed_value;
- PyObject *row, *record, *result, *indexobject;
- PyObject *exc_module, *exception, *cstr_obj;
-#if PY_MAJOR_VERSION >= 3
- PyObject *bytes;
-#endif
- char *cstr_key;
- long index;
- int key_fallback = 0;
- int tuple_check = 0;
-
-#if PY_MAJOR_VERSION < 3
- if (PyInt_CheckExact(key)) {
- index = PyInt_AS_LONG(key);
- }
-#endif
-
- if (PyLong_CheckExact(key)) {
- index = PyLong_AsLong(key);
- if ((index == -1) && PyErr_Occurred())
- /* -1 can be either the actual value, or an error flag. */
- return NULL;
- } else if (PySlice_Check(key)) {
- values = PyObject_GetItem(self->row, key);
- if (values == NULL)
- return NULL;
-
- processors = PyObject_GetItem(self->processors, key);
- if (processors == NULL) {
- Py_DECREF(values);
- return NULL;
- }
-
- result = BaseRowProxy_processvalues(values, processors, 1);
- Py_DECREF(values);
- Py_DECREF(processors);
- return result;
- } else {
- record = PyDict_GetItem((PyObject *)self->keymap, key);
- if (record == NULL) {
- record = PyObject_CallMethod(self->parent, "_key_fallback",
- "O", key);
- if (record == NULL)
- return NULL;
- key_fallback = 1;
- }
-
- indexobject = PyTuple_GetItem(record, 2);
- if (indexobject == NULL)
- return NULL;
-
- if (key_fallback) {
- Py_DECREF(record);
- }
-
- if (indexobject == Py_None) {
- exc_module = PyImport_ImportModule("sqlalchemy.exc");
- if (exc_module == NULL)
- return NULL;
-
- exception = PyObject_GetAttrString(exc_module,
- "InvalidRequestError");
- Py_DECREF(exc_module);
- if (exception == NULL)
- return NULL;
-
- // wow. this seems quite excessive.
- cstr_obj = PyObject_Str(key);
- if (cstr_obj == NULL)
- return NULL;
-
-/*
- FIXME: raise encoding error exception (in both versions below)
- if the key contains non-ascii chars, instead of an
- InvalidRequestError without any message like in the
- python version.
-*/
-#if PY_MAJOR_VERSION >= 3
- bytes = PyUnicode_AsASCIIString(cstr_obj);
- if (bytes == NULL)
- return NULL;
- cstr_key = PyBytes_AS_STRING(bytes);
-#else
- cstr_key = PyString_AsString(cstr_obj);
-#endif
- if (cstr_key == NULL) {
- Py_DECREF(cstr_obj);
- return NULL;
- }
- Py_DECREF(cstr_obj);
-
- PyErr_Format(exception,
- "Ambiguous column name '%.200s' in result set! "
- "try 'use_labels' option on select statement.", cstr_key);
- return NULL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- index = PyLong_AsLong(indexobject);
-#else
- index = PyInt_AsLong(indexobject);
-#endif
- if ((index == -1) && PyErr_Occurred())
- /* -1 can be either the actual value, or an error flag. */
- return NULL;
- }
- processor = PyList_GetItem(self->processors, index);
- if (processor == NULL)
- return NULL;
-
- row = self->row;
- if (PyTuple_CheckExact(row)) {
- value = PyTuple_GetItem(row, index);
- tuple_check = 1;
- }
- else {
- value = PySequence_GetItem(row, index);
- tuple_check = 0;
- }
-
- if (value == NULL)
- return NULL;
-
- if (processor != Py_None) {
- processed_value = PyObject_CallFunctionObjArgs(processor, value, NULL);
- if (!tuple_check) {
- Py_DECREF(value);
- }
- return processed_value;
- } else {
- if (tuple_check) {
- Py_INCREF(value);
- }
- return value;
- }
-}
-
-static PyObject *
-BaseRowProxy_getitem(PyObject *self, Py_ssize_t i)
-{
- PyObject *index;
-
-#if PY_MAJOR_VERSION >= 3
- index = PyLong_FromSsize_t(i);
-#else
- index = PyInt_FromSsize_t(i);
-#endif
- return BaseRowProxy_subscript((BaseRowProxy*)self, index);
-}
-
-static PyObject *
-BaseRowProxy_getattro(BaseRowProxy *self, PyObject *name)
-{
- PyObject *tmp;
-#if PY_MAJOR_VERSION >= 3
- PyObject *err_bytes;
-#endif
-
- if (!(tmp = PyObject_GenericGetAttr((PyObject *)self, name))) {
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))
- return NULL;
- PyErr_Clear();
- }
- else
- return tmp;
-
- tmp = BaseRowProxy_subscript(self, name);
- if (tmp == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
-
-#if PY_MAJOR_VERSION >= 3
- err_bytes = PyUnicode_AsASCIIString(name);
- if (err_bytes == NULL)
- return NULL;
- PyErr_Format(
- PyExc_AttributeError,
- "Could not locate column in row for column '%.200s'",
- PyBytes_AS_STRING(err_bytes)
- );
-#else
- PyErr_Format(
- PyExc_AttributeError,
- "Could not locate column in row for column '%.200s'",
- PyString_AsString(name)
- );
-#endif
- return NULL;
- }
- return tmp;
-}
-
-/***********************
- * getters and setters *
- ***********************/
-
-static PyObject *
-BaseRowProxy_getparent(BaseRowProxy *self, void *closure)
-{
- Py_INCREF(self->parent);
- return self->parent;
-}
-
-static int
-BaseRowProxy_setparent(BaseRowProxy *self, PyObject *value, void *closure)
-{
- PyObject *module, *cls;
-
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Cannot delete the 'parent' attribute");
- return -1;
- }
-
- module = PyImport_ImportModule("sqlalchemy.engine.result");
- if (module == NULL)
- return -1;
-
- cls = PyObject_GetAttrString(module, "ResultMetaData");
- Py_DECREF(module);
- if (cls == NULL)
- return -1;
-
- if (PyObject_IsInstance(value, cls) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "The 'parent' attribute value must be an instance of "
- "ResultMetaData");
- return -1;
- }
- Py_DECREF(cls);
- Py_XDECREF(self->parent);
- Py_INCREF(value);
- self->parent = value;
-
- return 0;
-}
-
-static PyObject *
-BaseRowProxy_getrow(BaseRowProxy *self, void *closure)
-{
- Py_INCREF(self->row);
- return self->row;
-}
-
-static int
-BaseRowProxy_setrow(BaseRowProxy *self, PyObject *value, void *closure)
-{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Cannot delete the 'row' attribute");
- return -1;
- }
-
- if (!PySequence_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The 'row' attribute value must be a sequence");
- return -1;
- }
-
- Py_XDECREF(self->row);
- Py_INCREF(value);
- self->row = value;
-
- return 0;
-}
-
-static PyObject *
-BaseRowProxy_getprocessors(BaseRowProxy *self, void *closure)
-{
- Py_INCREF(self->processors);
- return self->processors;
-}
-
-static int
-BaseRowProxy_setprocessors(BaseRowProxy *self, PyObject *value, void *closure)
-{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Cannot delete the 'processors' attribute");
- return -1;
- }
-
- if (!PyList_CheckExact(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The 'processors' attribute value must be a list");
- return -1;
- }
-
- Py_XDECREF(self->processors);
- Py_INCREF(value);
- self->processors = value;
-
- return 0;
-}
-
-static PyObject *
-BaseRowProxy_getkeymap(BaseRowProxy *self, void *closure)
-{
- Py_INCREF(self->keymap);
- return self->keymap;
-}
-
-static int
-BaseRowProxy_setkeymap(BaseRowProxy *self, PyObject *value, void *closure)
-{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Cannot delete the 'keymap' attribute");
- return -1;
- }
-
- if (!PyDict_CheckExact(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The 'keymap' attribute value must be a dict");
- return -1;
- }
-
- Py_XDECREF(self->keymap);
- Py_INCREF(value);
- self->keymap = value;
-
- return 0;
-}
-
-static PyGetSetDef BaseRowProxy_getseters[] = {
- {"_parent",
- (getter)BaseRowProxy_getparent, (setter)BaseRowProxy_setparent,
- "ResultMetaData",
- NULL},
- {"_row",
- (getter)BaseRowProxy_getrow, (setter)BaseRowProxy_setrow,
- "Original row tuple",
- NULL},
- {"_processors",
- (getter)BaseRowProxy_getprocessors, (setter)BaseRowProxy_setprocessors,
- "list of type processors",
- NULL},
- {"_keymap",
- (getter)BaseRowProxy_getkeymap, (setter)BaseRowProxy_setkeymap,
- "Key to (processor, index) dict",
- NULL},
- {NULL}
-};
-
-static PyMethodDef BaseRowProxy_methods[] = {
- {"values", (PyCFunction)BaseRowProxy_values, METH_NOARGS,
- "Return the values represented by this BaseRowProxy as a list."},
- {"__reduce__", (PyCFunction)BaseRowProxy_reduce, METH_NOARGS,
- "Pickle support method."},
- {NULL} /* Sentinel */
-};
-
-static PySequenceMethods BaseRowProxy_as_sequence = {
- (lenfunc)BaseRowProxy_length, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- (ssizeargfunc)BaseRowProxy_getitem, /* sq_item */
- 0, /* sq_slice */
- 0, /* sq_ass_item */
- 0, /* sq_ass_slice */
- 0, /* sq_contains */
- 0, /* sq_inplace_concat */
- 0, /* sq_inplace_repeat */
-};
-
-static PyMappingMethods BaseRowProxy_as_mapping = {
- (lenfunc)BaseRowProxy_length, /* mp_length */
- (binaryfunc)BaseRowProxy_subscript, /* mp_subscript */
- 0 /* mp_ass_subscript */
-};
-
-static PyTypeObject BaseRowProxyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "sqlalchemy.cresultproxy.BaseRowProxy", /* tp_name */
- sizeof(BaseRowProxy), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseRowProxy_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- &BaseRowProxy_as_sequence, /* tp_as_sequence */
- &BaseRowProxy_as_mapping, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- (getattrofunc)BaseRowProxy_getattro,/* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- "BaseRowProxy is a abstract base class for RowProxy", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)BaseRowProxy_iter, /* tp_iter */
- 0, /* tp_iternext */
- BaseRowProxy_methods, /* tp_methods */
- 0, /* tp_members */
- BaseRowProxy_getseters, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BaseRowProxy_init, /* tp_init */
- 0, /* tp_alloc */
- 0 /* tp_new */
-};
-
-static PyMethodDef module_methods[] = {
- {"safe_rowproxy_reconstructor", safe_rowproxy_reconstructor, METH_VARARGS,
- "reconstruct a RowProxy instance from its pickled form."},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
-
-static struct PyModuleDef module_def = {
- PyModuleDef_HEAD_INIT,
- MODULE_NAME,
- MODULE_DOC,
- -1,
- module_methods
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC
-PyInit_cresultproxy(void)
-
-#else
-
-#define INITERROR return
-
-PyMODINIT_FUNC
-initcresultproxy(void)
-
-#endif
-
-{
- PyObject *m;
-
- BaseRowProxyType.tp_new = PyType_GenericNew;
- if (PyType_Ready(&BaseRowProxyType) < 0)
- INITERROR;
-
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&module_def);
-#else
- m = Py_InitModule3(MODULE_NAME, module_methods, MODULE_DOC);
-#endif
- if (m == NULL)
- INITERROR;
-
- Py_INCREF(&BaseRowProxyType);
- PyModule_AddObject(m, "BaseRowProxy", (PyObject *)&BaseRowProxyType);
-
-#if PY_MAJOR_VERSION >= 3
- return m;
-#endif
-}
diff --git a/lib/sqlalchemy/cextension/utils.c b/lib/sqlalchemy/cextension/utils.c
deleted file mode 100644
index 377ba8a8d..000000000
--- a/lib/sqlalchemy/cextension/utils.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-utils.c
-Copyright (C) 2012-2014 the SQLAlchemy authors and contributors <see AUTHORS file>
-
-This module is part of SQLAlchemy and is released under
-the MIT License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-#include <Python.h>
-
-#define MODULE_NAME "cutils"
-#define MODULE_DOC "Module containing C versions of utility functions."
-
-/*
- Given arguments from the calling form *multiparams, **params,
- return a list of bind parameter structures, usually a list of
- dictionaries.
-
- In the case of 'raw' execution which accepts positional parameters,
- it may be a list of tuples or lists.
-
- */
-static PyObject *
-distill_params(PyObject *self, PyObject *args)
-{
- PyObject *multiparams, *params;
- PyObject *enclosing_list, *double_enclosing_list;
- PyObject *zero_element, *zero_element_item;
- Py_ssize_t multiparam_size, zero_element_length;
-
- if (!PyArg_UnpackTuple(args, "_distill_params", 2, 2, &multiparams, &params)) {
- return NULL;
- }
-
- if (multiparams != Py_None) {
- multiparam_size = PyTuple_Size(multiparams);
- if (multiparam_size < 0) {
- return NULL;
- }
- }
- else {
- multiparam_size = 0;
- }
-
- if (multiparam_size == 0) {
- if (params != Py_None && PyDict_Size(params) != 0) {
- enclosing_list = PyList_New(1);
- if (enclosing_list == NULL) {
- return NULL;
- }
- Py_INCREF(params);
- if (PyList_SetItem(enclosing_list, 0, params) == -1) {
- Py_DECREF(params);
- Py_DECREF(enclosing_list);
- return NULL;
- }
- }
- else {
- enclosing_list = PyList_New(0);
- if (enclosing_list == NULL) {
- return NULL;
- }
- }
- return enclosing_list;
- }
- else if (multiparam_size == 1) {
- zero_element = PyTuple_GetItem(multiparams, 0);
- if (PyTuple_Check(zero_element) || PyList_Check(zero_element)) {
- zero_element_length = PySequence_Length(zero_element);
-
- if (zero_element_length != 0) {
- zero_element_item = PySequence_GetItem(zero_element, 0);
- if (zero_element_item == NULL) {
- return NULL;
- }
- }
- else {
- zero_element_item = NULL;
- }
-
- if (zero_element_length == 0 ||
- (
- PyObject_HasAttrString(zero_element_item, "__iter__") &&
- !PyObject_HasAttrString(zero_element_item, "strip")
- )
- ) {
- /*
- * execute(stmt, [{}, {}, {}, ...])
- * execute(stmt, [(), (), (), ...])
- */
- Py_XDECREF(zero_element_item);
- Py_INCREF(zero_element);
- return zero_element;
- }
- else {
- /*
- * execute(stmt, ("value", "value"))
- */
- Py_XDECREF(zero_element_item);
- enclosing_list = PyList_New(1);
- if (enclosing_list == NULL) {
- return NULL;
- }
- Py_INCREF(zero_element);
- if (PyList_SetItem(enclosing_list, 0, zero_element) == -1) {
- Py_DECREF(zero_element);
- Py_DECREF(enclosing_list);
- return NULL;
- }
- return enclosing_list;
- }
- }
- else if (PyObject_HasAttrString(zero_element, "keys")) {
- /*
- * execute(stmt, {"key":"value"})
- */
- enclosing_list = PyList_New(1);
- if (enclosing_list == NULL) {
- return NULL;
- }
- Py_INCREF(zero_element);
- if (PyList_SetItem(enclosing_list, 0, zero_element) == -1) {
- Py_DECREF(zero_element);
- Py_DECREF(enclosing_list);
- return NULL;
- }
- return enclosing_list;
- } else {
- enclosing_list = PyList_New(1);
- if (enclosing_list == NULL) {
- return NULL;
- }
- double_enclosing_list = PyList_New(1);
- if (double_enclosing_list == NULL) {
- Py_DECREF(enclosing_list);
- return NULL;
- }
- Py_INCREF(zero_element);
- if (PyList_SetItem(enclosing_list, 0, zero_element) == -1) {
- Py_DECREF(zero_element);
- Py_DECREF(enclosing_list);
- Py_DECREF(double_enclosing_list);
- return NULL;
- }
- if (PyList_SetItem(double_enclosing_list, 0, enclosing_list) == -1) {
- Py_DECREF(zero_element);
- Py_DECREF(enclosing_list);
- Py_DECREF(double_enclosing_list);
- return NULL;
- }
- return double_enclosing_list;
- }
- }
- else {
- zero_element = PyTuple_GetItem(multiparams, 0);
- if (PyObject_HasAttrString(zero_element, "__iter__") &&
- !PyObject_HasAttrString(zero_element, "strip")
- ) {
- Py_INCREF(multiparams);
- return multiparams;
- }
- else {
- enclosing_list = PyList_New(1);
- if (enclosing_list == NULL) {
- return NULL;
- }
- Py_INCREF(multiparams);
- if (PyList_SetItem(enclosing_list, 0, multiparams) == -1) {
- Py_DECREF(multiparams);
- Py_DECREF(enclosing_list);
- return NULL;
- }
- return enclosing_list;
- }
- }
-}
-
-static PyMethodDef module_methods[] = {
- {"_distill_params", distill_params, METH_VARARGS,
- "Distill an execute() parameter structure."},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-
-static struct PyModuleDef module_def = {
- PyModuleDef_HEAD_INIT,
- MODULE_NAME,
- MODULE_DOC,
- -1,
- module_methods
- };
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
-PyMODINIT_FUNC
-PyInit_cutils(void)
-#else
-PyMODINIT_FUNC
-initcutils(void)
-#endif
-{
- PyObject *m;
-
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&module_def);
-#else
- m = Py_InitModule3(MODULE_NAME, module_methods, MODULE_DOC);
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- if (m == NULL)
- return NULL;
- return m;
-#else
- if (m == NULL)
- return;
-#endif
-}
-
diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py
index 6c98dae18..c6c124dbb 100644
--- a/lib/sqlalchemy/engine/result.py
+++ b/lib/sqlalchemy/engine/result.py
@@ -20,7 +20,7 @@ try:
# We need a different reconstructor on the C extension so that we can
# add extra checks that fields have correctly been initialized by
# __setstate__.
- from sqlalchemy.cresultproxy import safe_rowproxy_reconstructor
+ from sqlalchemy_speedups.cresultproxy import safe_rowproxy_reconstructor
# The extra function embedding is needed so that the
# reconstructor function has the same signature whether or not
@@ -34,7 +34,7 @@ except ImportError:
return obj
try:
- from sqlalchemy.cresultproxy import BaseRowProxy
+ from sqlalchemy_speedups.cresultproxy import BaseRowProxy
except ImportError:
class BaseRowProxy(object):
__slots__ = ('_parent', '_row', '_processors', '_keymap')
diff --git a/lib/sqlalchemy/engine/util.py b/lib/sqlalchemy/engine/util.py
index 6c0644be4..6d2ad175b 100644
--- a/lib/sqlalchemy/engine/util.py
+++ b/lib/sqlalchemy/engine/util.py
@@ -67,6 +67,6 @@ def py_fallback():
return locals()
try:
- from sqlalchemy.cutils import _distill_params
+ from sqlalchemy_speedups.cutils import _distill_params
except ImportError:
globals().update(py_fallback())
diff --git a/lib/sqlalchemy/processors.py b/lib/sqlalchemy/processors.py
index d0f52e42b..b96bb955a 100644
--- a/lib/sqlalchemy/processors.py
+++ b/lib/sqlalchemy/processors.py
@@ -122,7 +122,7 @@ def py_fallback():
return locals()
try:
- from sqlalchemy.cprocessors import UnicodeResultProcessor, \
+ from sqlalchemy_speedups.cprocessors import UnicodeResultProcessor, \
DecimalResultProcessor, \
to_float, to_str, int_to_boolean, \
str_to_datetime, str_to_time, \
diff --git a/setup.py b/setup.py
index f682081df..ffdf2471d 100644
--- a/setup.py
+++ b/setup.py
@@ -7,16 +7,12 @@ Please see README for basic installation instructions.
import os
import re
import sys
-from distutils.command.build_ext import build_ext
-from distutils.errors import (CCompilerError, DistutilsExecError,
- DistutilsPlatformError)
try:
- from setuptools import setup, Extension, Feature
+ from setuptools import setup
has_setuptools = True
except ImportError:
has_setuptools = False
- from distutils.core import setup, Extension
- Feature = None
+ from distutils.core import setup
cmdclass = {}
pypy = hasattr(sys, 'pypy_version_info')
@@ -28,48 +24,6 @@ if sys.version_info < (2, 6):
elif sys.version_info >= (3, 0):
py3k = True
-ext_modules = [
- Extension('sqlalchemy.cprocessors',
- sources=['lib/sqlalchemy/cextension/processors.c']),
- Extension('sqlalchemy.cresultproxy',
- sources=['lib/sqlalchemy/cextension/resultproxy.c']),
- Extension('sqlalchemy.cutils',
- sources=['lib/sqlalchemy/cextension/utils.c'])
- ]
-
-ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
-if sys.platform == 'win32':
- # 2.6's distutils.msvc9compiler can raise an IOError when failing to
- # find the compiler
- ext_errors += (IOError,)
-
-class BuildFailed(Exception):
-
- def __init__(self):
- self.cause = sys.exc_info()[1] # work around py 2/3 different syntax
-
-class ve_build_ext(build_ext):
- # This class allows C extension building to fail.
-
- def run(self):
- try:
- build_ext.run(self)
- except DistutilsPlatformError:
- raise BuildFailed()
-
- def build_extension(self, ext):
- try:
- build_ext.build_extension(self, ext)
- except ext_errors:
- raise BuildFailed()
- except ValueError:
- # this can happen on Windows 64 bit, see Python issue 7511
- if "'path'" in str(sys.exc_info()[1]): # works with both py 2/3
- raise BuildFailed()
- raise
-
-cmdclass['build_ext'] = ve_build_ext
-
def status_msgs(*msgs):
print('*' * 75)
for msg in msgs:
@@ -97,17 +51,8 @@ readme = r_file.read()
r_file.close()
-def run_setup(with_cext):
+def run_setup():
kwargs = extra.copy()
- if with_cext:
- if Feature:
- kwargs['features'] = {'cextensions': Feature(
- "optional C speed-enhancements",
- standard=True,
- ext_modules=ext_modules
- )}
- else:
- kwargs['ext_modules'] = ext_modules
setup(name="SQLAlchemy",
version=VERSION,
@@ -122,6 +67,9 @@ def run_setup(with_cext):
tests_require=['pytest >= 2.5.2', 'mock'],
test_suite="pytest.main",
long_description=readme,
+ extras_require=dict(
+ speedups=['sqlalchemy-speedups>=1.0,<2.0'],
+ ),
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
@@ -137,29 +85,4 @@ def run_setup(with_cext):
**kwargs
)
-if pypy or jython:
- run_setup(False)
- status_msgs(
- "WARNING: C extensions are not supported on " +
- "this Python platform, speedups are not enabled.",
- "Plain-Python build succeeded."
- )
-else:
- try:
- run_setup(True)
- except BuildFailed as exc:
- status_msgs(
- exc.cause,
- "WARNING: The C extension could not be compiled, " +
- "speedups are not enabled.",
- "Failure information, if any, is above.",
- "Retrying the build without the C extension now."
- )
-
- run_setup(False)
-
- status_msgs(
- "WARNING: The C extension could not be compiled, " +
- "speedups are not enabled.",
- "Plain-Python build succeeded."
- )
+run_setup()
diff --git a/test/base/test_utils.py b/test/base/test_utils.py
index 19b3aa357..4a53aa54f 100644
--- a/test/base/test_utils.py
+++ b/test/base/test_utils.py
@@ -1393,7 +1393,7 @@ class ArgInspectionTest(fixtures.TestBase):
(['self', 'x', 'y'], None, 'kw', None)
)
- @fails_if(lambda: util.pypy, "pypy inspects datetime.now correctly")
+ @fails_if(lambda: util.pypy, "pypy returns plain *arg, **kw")
def test_callable_argspec_py_builtin(self):
import datetime
assert_raises(
@@ -1401,6 +1401,7 @@ class ArgInspectionTest(fixtures.TestBase):
get_callable_argspec, datetime.datetime.now
)
+ @fails_if(lambda: util.pypy, "pypy returns plain *arg, **kw")
def test_callable_argspec_obj_init(self):
assert_raises(
TypeError,
@@ -1472,6 +1473,7 @@ class ArgInspectionTest(fixtures.TestBase):
(['x', 'y'], None, None, None)
)
+ @fails_if(lambda: util.pypy, "pypy returns plain *arg, **kw")
def test_callable_argspec_partial(self):
from functools import partial
def foo(x, y, z, **kw):
@@ -1600,6 +1602,8 @@ class TestFormatArgspec(fixtures.TestBase):
'apply_kw': 'a=a, b=b', 'apply_pos': 'a, b'},
grouped=False)
+ @testing.fails_if(lambda: util.pypy,
+ "pypy doesn't report O.__init__ as object.__init__")
def test_init_grouped(self):
object_spec = {
'args': '(self)', 'self_arg': 'self',
@@ -1615,6 +1619,8 @@ class TestFormatArgspec(fixtures.TestBase):
self._test_init(None, object_spec, wrapper_spec, custom_spec)
self._test_init(True, object_spec, wrapper_spec, custom_spec)
+ @testing.fails_if(lambda: util.pypy,
+ "pypy doesn't report O.__init__ as object.__init__")
def test_init_bare(self):
object_spec = {
'args': 'self', 'self_arg': 'self',
diff --git a/test/engine/test_processors.py b/test/engine/test_processors.py
index b1c482f09..e67666035 100644
--- a/test/engine/test_processors.py
+++ b/test/engine/test_processors.py
@@ -61,7 +61,7 @@ class CDateProcessorTest(_DateProcessorTest):
__requires__ = ('cextensions',)
@classmethod
def setup_class(cls):
- from sqlalchemy import cprocessors
+ from sqlalchemy_speedups import cprocessors
cls.module = cprocessors
@@ -164,5 +164,5 @@ class CDistillArgsTest(_DistillArgsTest):
__requires__ = ('cextensions', )
@classmethod
def setup_class(cls):
- from sqlalchemy import cutils as util
+ from sqlalchemy_speedups import cutils as util
cls.module = util
diff --git a/test/requirements.py b/test/requirements.py
index 38b445542..cb76ad5e1 100644
--- a/test/requirements.py
+++ b/test/requirements.py
@@ -727,7 +727,7 @@ class DefaultRequirements(SuiteRequirements):
def _has_cextensions(self):
try:
- from sqlalchemy import cresultproxy, cprocessors
+ import sqlalchemy_speedups
return True
except ImportError:
return False