--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/MySQL-python-1.2.3-python3.patch Fri Nov 25 18:17:27 2011 +0100
@@ -0,0 +1,2074 @@
+Python3 patch for MySQL-python-1.2.3.
+Based on https://github.com/davispuh/MySQL-for-Python-3
+Removed incompatible (and absolutely unnecessary) changes.
+diff -ru MySQL-python-1.2.3/_mysql.c MySQL-Python-1.2.3-python3/_mysql.c
+--- MySQL-python-1.2.3/_mysql.c 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/_mysql.c 2011-10-05 12:49:58.000000000 +0200
+@@ -31,33 +31,17 @@
+ #if defined(MS_WINDOWS)
+ #include <winsock2.h>
+ #include <windows.h>
+-#include <config-win.h>
+-#else
+-#include "my_config.h"
+ #endif
++#include "my_config.h"
+ #include "mysql.h"
+ #include "mysqld_error.h"
+ #include "errmsg.h"
+
+-#if PY_VERSION_HEX < 0x02020000
+-# define MyTuple_Resize(t,n,d) _PyTuple_Resize(t, n, d)
+-# define MyMember(a,b,c,d,e) {a,b,c,d}
+-# define MyMemberlist(x) struct memberlist x
+-# define MyAlloc(s,t) PyObject_New(s,&t)
+-# define MyFree(o) PyObject_Del(o)
+-#else
+ # define MyTuple_Resize(t,n,d) _PyTuple_Resize(t, n)
+ # define MyMember(a,b,c,d,e) {a,b,c,d,e}
+ # define MyMemberlist(x) struct PyMemberDef x
+ # define MyAlloc(s,t) (s *) t.tp_alloc(&t,0)
+-# define MyFree(ob) ob->ob_type->tp_free((PyObject *)ob)
+-#endif
+-
+-#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
++# define MyFree(ob) ob->ob_base.ob_type->tp_free((PyObject *)ob)
+
+ static PyObject *_mysql_MySQLError;
+ static PyObject *_mysql_Warning;
+@@ -86,7 +70,7 @@
+
+ typedef struct {
+ PyObject_HEAD
+- PyObject *conn;
++ _mysql_ConnectionObject *conn;
+ MYSQL_RES *result;
+ int nfields;
+ int use;
+@@ -102,17 +86,16 @@
+ #define check_server_init(x) if (!_mysql_server_init_done) _mysql_server_init_done = 1
+ #endif
+
+-PyObject *
+-_mysql_Exception(_mysql_ConnectionObject *c)
++PyObject * _mysql_Exception(_mysql_ConnectionObject *c)
+ {
+- PyObject *t, *e;
++ PyObject *t, *e, *code, *message;
+ int merr;
+
+ if (!(t = PyTuple_New(2))) return NULL;
+ if (!_mysql_server_init_done) {
+ e = _mysql_InternalError;
+- PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L));
+- PyTuple_SET_ITEM(t, 1, PyString_FromString("server not initialized"));
++ PyTuple_SET_ITEM(t, 0, PyLong_FromLong(-1L));
++ PyTuple_SET_ITEM(t, 1, PyUnicode_FromString("server not initialized"));
+ PyErr_SetObject(e, t);
+ Py_DECREF(t);
+ return NULL;
+@@ -121,8 +104,8 @@
+ if (!merr)
+ e = _mysql_InterfaceError;
+ else if (merr > CR_MAX_ERROR) {
+- PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L));
+- PyTuple_SET_ITEM(t, 1, PyString_FromString("error totally whack"));
++ PyTuple_SET_ITEM(t, 0, PyLong_FromLong(-1L));
++ PyTuple_SET_ITEM(t, 1, PyUnicode_FromString("error totally whack"));
+ PyErr_SetObject(_mysql_InterfaceError, t);
+ Py_DECREF(t);
+ return NULL;
+@@ -209,8 +192,12 @@
+ e = _mysql_OperationalError;
+ break;
+ }
+- PyTuple_SET_ITEM(t, 0, PyInt_FromLong((long)merr));
+- PyTuple_SET_ITEM(t, 1, PyString_FromString(mysql_error(&(c->connection))));
++ code = PyLong_FromLong((long)merr);
++ message = PyUnicode_FromString(mysql_error(&(c->connection)));
++ PyTuple_SET_ITEM(t, 0, code );
++ PyTuple_SET_ITEM(t, 1, message );
++ PyObject_SetAttrString(e, "code", code );
++ PyObject_SetAttrString(e, "message", message );
+ PyErr_SetObject(e, t);
+ Py_DECREF(t);
+ return NULL;
+@@ -259,7 +246,7 @@
+ cmd_args_c = (char **) PyMem_Malloc(cmd_argc*sizeof(char *));
+ for (i=0; i< cmd_argc; i++) {
+ item = PySequence_GetItem(cmd_args, i);
+- s = PyString_AsString(item);
++ s = PyBytes_AsString(item);
+ Py_DECREF(item);
+ if (!s) {
+ PyErr_SetString(PyExc_TypeError,
+@@ -284,7 +271,7 @@
+ groups_c = (char **) PyMem_Malloc((1+groupc)*sizeof(char *));
+ for (i=0; i< groupc; i++) {
+ item = PySequence_GetItem(groups, i);
+- s = PyString_AsString(item);
++ s = PyBytes_AsString(item);
+ Py_DECREF(item);
+ if (!s) {
+ PyErr_SetString(PyExc_TypeError,
+@@ -339,7 +326,7 @@
+ PyObject *flag;
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_server_init(NULL);
+- if (!(flag=PyInt_FromLong((long)mysql_thread_safe()))) return NULL;
++ if (!(flag=PyLong_FromLong((long)mysql_thread_safe()))) return NULL;
+ return flag;
+ }
+ #endif
+@@ -372,7 +359,7 @@
+ return -1;
+ if (!conv) conv = PyDict_New();
+ if (!conv) return -1;
+- self->conn = (PyObject *) conn;
++ self->conn = conn;
+ Py_INCREF(conn);
+ self->use = use;
+ Py_BEGIN_ALLOW_THREADS ;
+@@ -392,7 +379,7 @@
+ fields = mysql_fetch_fields(result);
+ for (i=0; i<n; i++) {
+ PyObject *tmp, *fun;
+- tmp = PyInt_FromLong((long) fields[i].type);
++ tmp = PyLong_FromLong((long) fields[i].type);
+ if (!tmp) return -1;
+ fun = PyObject_GetItem(conv, tmp);
+ Py_DECREF(tmp);
+@@ -413,8 +400,8 @@
+ PyObject *pmask=NULL;
+ pmask = PyTuple_GET_ITEM(t, 0);
+ fun2 = PyTuple_GET_ITEM(t, 1);
+- if (PyInt_Check(pmask)) {
+- mask = PyInt_AS_LONG(pmask);
++ if (PyNumber_Check(pmask)) {
++ mask = PyLong_AS_LONG(pmask);
+ if (mask & fields[i].flags) {
+ Py_DECREF(t);
+ break;
+@@ -440,7 +427,6 @@
+ return 0;
+ }
+
+-#if PY_VERSION_HEX >= 0x02020000
+ static int _mysql_ResultObject_traverse(
+ _mysql_ResultObject *self,
+ visitproc visit,
+@@ -451,10 +437,9 @@
+ if (!(r = visit(self->converter, arg))) return r;
+ }
+ if (self->conn)
+- return visit(self->conn, arg);
++ return visit((PyObject *)self->conn, arg);
+ return 0;
+ }
+-#endif
+
+ static int _mysql_ResultObject_clear(
+ _mysql_ResultObject *self)
+@@ -515,7 +500,7 @@
+ return -1;
+
+ #define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\
+- if(t){d=PyString_AsString(t);Py_DECREF(t);}\
++ if(t){d=PyBytes_AsString(t);Py_DECREF(t);}\
+ PyErr_Clear();}
+
+ if (ssl) {
+@@ -663,7 +648,6 @@
+ return (PyObject *) c;
+ }
+
+-#if PY_VERSION_HEX >= 0x02020000
+ static int _mysql_ConnectionObject_traverse(
+ _mysql_ConnectionObject *self,
+ visitproc visit,
+@@ -673,7 +657,7 @@
+ return visit(self->converter, arg);
+ return 0;
+ }
+-#endif
++
+
+ static int _mysql_ConnectionObject_clear(
+ _mysql_ConnectionObject *self)
+@@ -862,7 +846,7 @@
+ #endif
+ Py_END_ALLOW_THREADS
+ if (err > 0) return _mysql_Exception(self);
+- return PyInt_FromLong(err);
++ return PyLong_FromLong(err);
+ }
+
+ #if MYSQL_VERSION_ID >= 40100
+@@ -885,7 +869,7 @@
+ err = mysql_set_server_option(&(self->connection), flags);
+ Py_END_ALLOW_THREADS
+ if (err) return _mysql_Exception(self);
+- return PyInt_FromLong(err);
++ return PyLong_FromLong(err);
+ }
+
+ static char _mysql_ConnectionObject_sqlstate__doc__[] =
+@@ -906,7 +890,7 @@
+ PyObject *args)
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+- return PyString_FromString(mysql_sqlstate(&(self->connection)));
++ return PyUnicode_FromString(mysql_sqlstate(&(self->connection)));
+ }
+
+ static char _mysql_ConnectionObject_warning_count__doc__[] =
+@@ -921,7 +905,7 @@
+ PyObject *args)
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+- return PyInt_FromLong(mysql_warning_count(&(self->connection)));
++ return PyLong_FromLong(mysql_warning_count(&(self->connection)));
+ }
+
+ #endif
+@@ -939,7 +923,7 @@
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+- return PyInt_FromLong((long)mysql_errno(&(self->connection)));
++ return PyLong_FromLong((long)mysql_errno(&(self->connection)));
+ }
+
+ static char _mysql_ConnectionObject_error__doc__[] =
+@@ -955,7 +939,7 @@
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+- return PyString_FromString(mysql_error(&(self->connection)));
++ return PyUnicode_FromString(mysql_error(&(self->connection)));
+ }
+
+ static char _mysql_escape_string__doc__[] =
+@@ -966,18 +950,14 @@
+ probably better off using connection.escape(o) instead, since\n\
+ it will escape entire sequences as well as strings.";
+
+-static PyObject *
+-_mysql_escape_string(
+- _mysql_ConnectionObject *self,
+- PyObject *args)
++static PyObject *_mysql_ConnectionObject_escape_string( _mysql_ConnectionObject *self, PyObject *args)
+ {
+ PyObject *str;
+ char *in, *out;
+ int len, size;
+ if (!PyArg_ParseTuple(args, "s#:escape_string", &in, &size)) return NULL;
+- str = PyString_FromStringAndSize((char *) NULL, size*2+1);
+- if (!str) return PyErr_NoMemory();
+- out = PyString_AS_STRING(str);
++ out = PyMem_New(char, size*2+1);
++ if (!out) return PyErr_NoMemory();
+ #if MYSQL_VERSION_ID < 32321
+ len = mysql_escape_string(out, in, size);
+ #else
+@@ -987,10 +967,16 @@
+ else
+ len = mysql_escape_string(out, in, size);
+ #endif
+- if (_PyString_Resize(&str, len) < 0) return NULL;
++ str = PyUnicode_FromString(out);
++ PyMem_Del(out);
+ return (str);
+ }
+
++static PyObject *_mysql_escape_string( PyObject *self, PyObject *args)
++{
++ return _mysql_ConnectionObject_escape_string(NULL, args);
++}
++
+ static char _mysql_string_literal__doc__[] =
+ "string_literal(obj) -- converts object obj into a SQL string literal.\n\
+ This means, any special SQL characters are escaped, and it is enclosed\n\
+@@ -1001,43 +987,50 @@
+ Use connection.string_literal(obj), if you use it at all.\n\
+ _mysql.string_literal(obj) cannot handle character sets.";
+
+-static PyObject *
+-_mysql_string_literal(
+- _mysql_ConnectionObject *self,
+- PyObject *args)
++static PyObject *_mysql_ConnectionObject_string_literal(_mysql_ConnectionObject *self, PyObject *args)
+ {
+- PyObject *str, *s, *o, *d;
++ PyObject *str, *s, *s2, *o, *d;
+ char *in, *out;
+ int len, size;
+ if (!PyArg_ParseTuple(args, "O|O:string_literal", &o, &d)) return NULL;
+ s = PyObject_Str(o);
+ if (!s) return NULL;
+- in = PyString_AsString(s);
+- size = PyString_GET_SIZE(s);
+- str = PyString_FromStringAndSize((char *) NULL, size*2+3);
+- if (!str) return PyErr_NoMemory();
+- out = PyString_AS_STRING(str);
++ s2 = PyUnicode_AsUTF8String(s);
++ if (!s2) return NULL;
++ in = PyBytes_AsString(s2);
++ if (!in) return NULL;
++ size = PyBytes_GET_SIZE(s2);
++ out = PyMem_New(char, size*2+3);
++ if (!out) return PyErr_NoMemory();
+ #if MYSQL_VERSION_ID < 32321
+ len = mysql_escape_string(out+1, in, size);
+ #else
+ check_server_init(NULL);
+- if (self && self->open)
++ if (self && self->open )
++ {
+ len = mysql_real_escape_string(&(self->connection), out+1, in, size);
+- else
++ } else
++ {
+ len = mysql_escape_string(out+1, in, size);
++ };
+ #endif
+ *out = *(out+len+1) = '\'';
+- if (_PyString_Resize(&str, len+2) < 0) return NULL;
++ *(out+len+2) = '\0';
++ str = PyUnicode_FromString(out);
++ PyMem_Del(out);
++ Py_DECREF(s2);
+ Py_DECREF(s);
+ return (str);
+ }
+
++static PyObject *_mysql_string_literal(PyObject *self, PyObject *args)
++{
++ return _mysql_ConnectionObject_string_literal(NULL, args);
++}
++
+ static PyObject *_mysql_NULL;
+
+-static PyObject *
+-_escape_item(
+- PyObject *item,
+- PyObject *d)
++static PyObject *_escape_item( PyObject *item, PyObject *d)
+ {
+ PyObject *quoted=NULL, *itemtype, *itemconv;
+ if (!(itemtype = PyObject_Type(item)))
+@@ -1047,11 +1040,11 @@
+ if (!itemconv) {
+ PyErr_Clear();
+ itemconv = PyObject_GetItem(d,
+- (PyObject *) &PyString_Type);
++ (PyObject *) &PyUnicode_Type);
+ }
+ if (!itemconv) {
+ PyErr_SetString(PyExc_TypeError,
+- "no default type converter defined");
++ "no default type converter defined");
+ goto error;
+ }
+ quoted = PyObject_CallFunction(itemconv, "OO", item, d);
+@@ -1064,32 +1057,33 @@
+ "escape(obj, dict) -- escape any special characters in object obj\n\
+ using mapping dict to provide quoting functions for each type.\n\
+ Returns a SQL literal string.";
+-static PyObject *
+-_mysql_escape(
+- PyObject *self,
+- PyObject *args)
++static PyObject *_mysql_ConnectionObject_escape( _mysql_ConnectionObject *self, PyObject *args)
+ {
+ PyObject *o=NULL, *d=NULL;
+ if (!PyArg_ParseTuple(args, "O|O:escape", &o, &d))
+ return NULL;
+ if (d) {
+ if (!PyMapping_Check(d)) {
+- PyErr_SetString(PyExc_TypeError,
+- "argument 2 must be a mapping");
++ PyErr_SetString(PyExc_TypeError, "argument 2 must be a mapping");
+ return NULL;
+ }
+ return _escape_item(o, d);
+- } else {
+- if (!self) {
+- PyErr_SetString(PyExc_TypeError,
+- "argument 2 must be a mapping");
++ } else
++ {
++ if (!self)
++ {
++ PyErr_SetString(PyExc_TypeError, "argument 2 must be a mapping");
+ return NULL;
+ }
+- return _escape_item(o,
+- ((_mysql_ConnectionObject *) self)->converter);
++ return _escape_item(o, self->converter);
+ }
+ }
+
++static PyObject *_mysql_escape( PyObject *self, PyObject *args)
++{
++ return _mysql_ConnectionObject_escape(NULL, args);
++}
++
+ static char _mysql_escape_sequence__doc__[] =
+ "escape_sequence(seq, dict) -- escape any special characters in sequence\n\
+ seq using mapping dict to provide quoting functions for each type.\n\
+@@ -1160,20 +1154,28 @@
+ the Cursor.description attribute.\n\
+ ";
+
+-static PyObject *
+-_mysql_ResultObject_describe(
+- _mysql_ResultObject *self,
+- PyObject *args)
++static PyObject * _mysql_ResultObject_describe ( _mysql_ResultObject *self, PyObject *args)
+ {
+- PyObject *d;
++ PyObject *d = NULL;
+ MYSQL_FIELD *fields;
+ unsigned int i, n;
+- if (!PyArg_ParseTuple(args, "")) return NULL;
++
++ if ( !PyArg_ParseTuple(args, ""))
++ {
++ return NULL;
++ };
++
+ check_result_connection(self);
++
+ n = mysql_num_fields(self->result);
+ fields = mysql_fetch_fields(self->result);
+- if (!(d = PyTuple_New(n))) return NULL;
+- for (i=0; i<n; i++) {
++ d = PyTuple_New(n);
++ if ( d == NULL )
++ {
++ return NULL;
++ };
++ for (i = 0; i < n; i++)
++ {
+ PyObject *t;
+ t = Py_BuildValue("(siiiiii)",
+ fields[i].name,
+@@ -1183,13 +1185,16 @@
+ (long) fields[i].length,
+ (long) fields[i].decimals,
+ (long) !(IS_NOT_NULL(fields[i].flags)));
+- if (!t) goto error;
++ if (t == NULL)
++ {
++ Py_XDECREF(d);
++ d = NULL;
++ break;
++ };
+ PyTuple_SET_ITEM(d, i, t);
+- }
++ };
++
+ return d;
+- error:
+- Py_XDECREF(d);
+- return NULL;
+ }
+
+ static char _mysql_ResultObject_field_flags__doc__[] =
+@@ -1211,7 +1216,7 @@
+ if (!(d = PyTuple_New(n))) return NULL;
+ for (i=0; i<n; i++) {
+ PyObject *f;
+- if (!(f = PyInt_FromLong((long)fields[i].flags))) goto error;
++ if (!(f = PyLong_FromLong((long)fields[i].flags))) goto error;
+ PyTuple_SET_ITEM(d, i, f);
+ }
+ return d;
+@@ -1221,27 +1226,44 @@
+ }
+
+ static PyObject *
+-_mysql_field_to_python(
+- PyObject *converter,
+- char *rowitem,
+- unsigned long length)
++_mysql_field_to_python(PyObject *converter, char *rowitem, unsigned long length, const char *charset)
+ {
+ PyObject *v;
+- if (rowitem) {
+- if (converter != Py_None)
+- v = PyObject_CallFunction(converter,
+- "s#",
+- rowitem,
+- (int)length);
+- else
+- v = PyString_FromStringAndSize(rowitem,
+- (int)length);
+- if (!v)
+- return NULL;
+- } else {
++ if (rowitem)
++ {
++ if (charset)
++ {
++ PyObject *rowitem_unicode = PyUnicode_Decode(rowitem, (int)length, charset, "replace");
++ if (rowitem_unicode == NULL)
++ {
++ return NULL;
++ } else
++ {
++ if (converter != Py_None)
++ {
++ v = PyObject_CallFunction(converter, "O", rowitem_unicode);
++ Py_XDECREF(rowitem_unicode);
++ } else
++ {
++ v = rowitem_unicode;
++ };
++ };
++ } else
++ {
++ if (converter != Py_None)
++ {
++ v = PyObject_CallFunction(converter, "s#", rowitem, (int)length);
++ } else
++ {
++ v = PyUnicode_FromStringAndSize(rowitem, (int)length);
++ if (!v) return NULL;
++ };
++ };
++ } else
++ {
+ Py_INCREF(Py_None);
+ v = Py_None;
+- }
++ };
+ return v;
+ }
+
+@@ -1253,14 +1275,22 @@
+ unsigned int n, i;
+ unsigned long *length;
+ PyObject *r, *c;
++ const char *charset;
+
+ n = mysql_num_fields(self->result);
+ if (!(r = PyTuple_New(n))) return NULL;
+ length = mysql_fetch_lengths(self->result);
++
++#if MYSQL_VERSION_ID >= 32321
++ charset = mysql_character_set_name(&(self->conn->connection));
++#else
++ charset = "latin1";
++#endif
++
+ for (i=0; i<n; i++) {
+ PyObject *v;
+ c = PyTuple_GET_ITEM(self->converter, i);
+- v = _mysql_field_to_python(c, row[i], length[i]);
++ v = _mysql_field_to_python(c, row[i], length[i], charset);
+ if (!v) goto error;
+ PyTuple_SET_ITEM(r, i, v);
+ }
+@@ -1278,16 +1308,24 @@
+ unsigned int n, i;
+ unsigned long *length;
+ PyObject *r, *c;
+- MYSQL_FIELD *fields;
++ MYSQL_FIELD *fields;
++ const char *charset;
+
+ n = mysql_num_fields(self->result);
+ if (!(r = PyDict_New())) return NULL;
+ length = mysql_fetch_lengths(self->result);
+ fields = mysql_fetch_fields(self->result);
++
++#if MYSQL_VERSION_ID >= 32321
++ charset = mysql_character_set_name(&(self->conn->connection));
++#else
++ charset = "latin1";
++#endif
++
+ for (i=0; i<n; i++) {
+ PyObject *v;
+ c = PyTuple_GET_ITEM(self->converter, i);
+- v = _mysql_field_to_python(c, row[i], length[i]);
++ v = _mysql_field_to_python(c, row[i], length[i], charset);
+ if (!v) goto error;
+ if (!PyMapping_HasKeyString(r, fields[i].name)) {
+ PyMapping_SetItemString(r, fields[i].name, v);
+@@ -1317,16 +1355,24 @@
+ unsigned int n, i;
+ unsigned long *length;
+ PyObject *r, *c;
+- MYSQL_FIELD *fields;
++ MYSQL_FIELD *fields;
++ const char *charset;
+
+ n = mysql_num_fields(self->result);
+ if (!(r = PyDict_New())) return NULL;
+ length = mysql_fetch_lengths(self->result);
+ fields = mysql_fetch_fields(self->result);
++
++#if MYSQL_VERSION_ID >= 32321
++ charset = mysql_character_set_name(&(self->conn->connection));
++#else
++ charset = "latin1";
++#endif
++
+ for (i=0; i<n; i++) {
+ PyObject *v;
+ c = PyTuple_GET_ITEM(self->converter, i);
+- v = _mysql_field_to_python(c, row[i], length[i]);
++ v = _mysql_field_to_python(c, row[i], length[i], charset);
+ if (!v) goto error;
+ {
+ int len=0;
+@@ -1354,8 +1400,8 @@
+ _mysql__fetch_row(
+ _mysql_ResultObject *self,
+ PyObject **r,
+- int skiprows,
+- int maxrows,
++ unsigned int skiprows,
++ unsigned int maxrows,
+ _PYFUNC *convert_row)
+ {
+ unsigned int i;
+@@ -1516,7 +1562,7 @@
+ #else
+ s = "latin1";
+ #endif
+- return PyString_FromString(s);
++ return PyUnicode_FromString(s);
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+@@ -1578,15 +1624,15 @@
+ mysql_get_character_set_info(&(self->connection), &cs);
+ if (!(result = PyDict_New())) return NULL;
+ if (cs.csname)
+- PyDict_SetItemString(result, "name", PyString_FromString(cs.csname));
++ PyDict_SetItemString(result, "name", PyUnicode_FromString(cs.csname));
+ if (cs.name)
+- PyDict_SetItemString(result, "collation", PyString_FromString(cs.name));
++ PyDict_SetItemString(result, "collation", PyUnicode_FromString(cs.name));
+ if (cs.comment)
+- PyDict_SetItemString(result, "comment", PyString_FromString(cs.comment));
++ PyDict_SetItemString(result, "comment", PyUnicode_FromString(cs.comment));
+ if (cs.dir)
+- PyDict_SetItemString(result, "dir", PyString_FromString(cs.dir));
+- PyDict_SetItemString(result, "mbminlen", PyInt_FromLong(cs.mbminlen));
+- PyDict_SetItemString(result, "mbmaxlen", PyInt_FromLong(cs.mbmaxlen));
++ PyDict_SetItemString(result, "dir", PyUnicode_FromString(cs.dir));
++ PyDict_SetItemString(result, "mbminlen", PyLong_FromLong(cs.mbminlen));
++ PyDict_SetItemString(result, "mbmaxlen", PyLong_FromLong(cs.mbmaxlen));
+ return result;
+ }
+ #endif
+@@ -1596,12 +1642,12 @@
+ the client library version.";
+ static PyObject *
+ _mysql_get_client_info(
+- PyObject *self,
+- PyObject *args)
++ PyObject *self,
++ PyObject *args)
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_server_init(NULL);
+- return PyString_FromString(mysql_get_client_info());
++ return PyUnicode_FromString(mysql_get_client_info());
+ }
+
+ static char _mysql_ConnectionObject_get_host_info__doc__[] =
+@@ -1616,7 +1662,7 @@
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+- return PyString_FromString(mysql_get_host_info(&(self->connection)));
++ return PyUnicode_FromString(mysql_get_host_info(&(self->connection)));
+ }
+
+ static char _mysql_ConnectionObject_get_proto_info__doc__[] =
+@@ -1631,7 +1677,7 @@
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+- return PyInt_FromLong((long)mysql_get_proto_info(&(self->connection)));
++ return PyLong_FromLong((long)mysql_get_proto_info(&(self->connection)));
+ }
+
+ static char _mysql_ConnectionObject_get_server_info__doc__[] =
+@@ -1646,7 +1692,7 @@
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+- return PyString_FromString(mysql_get_server_info(&(self->connection)));
++ return PyUnicode_FromString(mysql_get_server_info(&(self->connection)));
+ }
+
+ static char _mysql_ConnectionObject_info__doc__[] =
+@@ -1664,7 +1710,7 @@
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+ s = mysql_info(&(self->connection));
+- if (s) return PyString_FromString(s);
++ if (s) return PyUnicode_FromString(s);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+@@ -1739,9 +1785,9 @@
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_connection(self);
+ #if MYSQL_VERSION_ID < 32224
+- return PyInt_FromLong((long)mysql_num_fields(&(self->connection)));
++ return PyNumber_FromLong((long)mysql_num_fields(&(self->connection)));
+ #else
+- return PyInt_FromLong((long)mysql_field_count(&(self->connection)));
++ return PyLong_FromLong((long)mysql_field_count(&(self->connection)));
+ #endif
+ }
+
+@@ -1755,7 +1801,7 @@
+ {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+ check_result_connection(self);
+- return PyInt_FromLong((long)mysql_num_fields(self->result));
++ return PyLong_FromLong((long)mysql_num_fields(self->result));
+ }
+
+ static char _mysql_ResultObject_num_rows__doc__[] =
+@@ -1907,7 +1953,7 @@
+ s = mysql_stat(&(self->connection));
+ Py_END_ALLOW_THREADS
+ if (!s) return _mysql_Exception(self);
+- return PyString_FromString(s);
++ return PyUnicode_FromString(s);
+ }
+
+ static char _mysql_ConnectionObject_store_result__doc__[] =
+@@ -1968,7 +2014,7 @@
+ Py_BEGIN_ALLOW_THREADS
+ pid = mysql_thread_id(&(self->connection));
+ Py_END_ALLOW_THREADS
+- return PyInt_FromLong((long)pid);
++ return PyLong_FromLong((long)pid);
+ }
+
+ static char _mysql_ConnectionObject_use_result__doc__[] =
+@@ -2033,7 +2079,7 @@
+ else
+ sprintf(buf, "<_mysql.connection closed at %lx>",
+ (long)self);
+- return PyString_FromString(buf);
++ return PyUnicode_FromString(buf);
+ }
+
+ static char _mysql_ResultObject_data_seek__doc__[] =
+@@ -2089,7 +2135,7 @@
+ return NULL;
+ }
+ r = mysql_row_tell(self->result);
+- return PyInt_FromLong(r-self->result->data->data);
++ return PyLong_FromLong(r-self->result->data->data);
+ }
+
+ static void
+@@ -2109,7 +2155,7 @@
+ char buf[300];
+ sprintf(buf, "<_mysql.result object at %lx>",
+ (long)self);
+- return PyString_FromString(buf);
++ return PyUnicode_FromString(buf);
+ }
+
+ static PyMethodDef _mysql_ConnectionObject_methods[] = {
+@@ -2207,13 +2253,13 @@
+ },
+ {
+ "escape",
+- (PyCFunction)_mysql_escape,
++ (PyCFunction)_mysql_ConnectionObject_escape,
+ METH_VARARGS,
+ _mysql_escape__doc__
+ },
+ {
+ "escape_string",
+- (PyCFunction)_mysql_escape_string,
++ (PyCFunction)_mysql_ConnectionObject_escape_string,
+ METH_VARARGS,
+ _mysql_escape_string__doc__
+ },
+@@ -2309,7 +2355,7 @@
+ },
+ {
+ "string_literal",
+- (PyCFunction)_mysql_string_literal,
++ (PyCFunction)_mysql_ConnectionObject_string_literal,
+ METH_VARARGS,
+ _mysql_string_literal__doc__},
+ {
+@@ -2332,7 +2378,7 @@
+ "open",
+ T_INT,
+ offsetof(_mysql_ConnectionObject,open),
+- RO,
++ READONLY,
+ "True if connection is open"
+ ),
+ MyMember(
+@@ -2346,20 +2392,20 @@
+ "server_capabilities",
+ T_UINT,
+ offsetof(_mysql_ConnectionObject,connection.server_capabilities),
+- RO,
++ READONLY,
+ "Capabilites of server; consult MySQLdb.constants.CLIENT"
+ ),
+ MyMember(
+ "port",
+ T_UINT,
+ offsetof(_mysql_ConnectionObject,connection.port),
+- RO,
++ READONLY,
+ "TCP/IP port of the server connection"
+ ),
+ MyMember(
+ "client_flag",
+ T_UINT,
+- RO,
++ READONLY,
+ offsetof(_mysql_ConnectionObject,connection.client_flag),
+ "Client flags; refer to MySQLdb.constants.CLIENT"
+ ),
+@@ -2423,127 +2469,22 @@
+ "converter",
+ T_OBJECT,
+ offsetof(_mysql_ResultObject,converter),
+- RO,
++ READONLY,
+ "Type conversion mapping"
+ ),
+ {NULL} /* Sentinel */
+ };
+-
+-static PyObject *
+-_mysql_ConnectionObject_getattr(
+- _mysql_ConnectionObject *self,
+- char *name)
+-{
+- PyObject *res;
+-
+- res = Py_FindMethod(_mysql_ConnectionObject_methods, (PyObject *)self, name);
+- if (res != NULL)
+- return res;
+- PyErr_Clear();
+- if (strcmp(name, "closed") == 0)
+- return PyInt_FromLong((long)!(self->open));
+-#if PY_VERSION_HEX < 0x02020000
+- return PyMember_Get((char *)self, _mysql_ConnectionObject_memberlist, name);
+-#else
+- {
+- MyMemberlist(*l);
+- for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) {
+- if (strcmp(l->name, name) == 0)
+- return PyMember_GetOne((char *)self, l);
+- }
+- PyErr_SetString(PyExc_AttributeError, name);
+- return NULL;
+- }
+-#endif
+-}
+-
+-static PyObject *
+-_mysql_ResultObject_getattr(
+- _mysql_ResultObject *self,
+- char *name)
+-{
+- PyObject *res;
+-
+- res = Py_FindMethod(_mysql_ResultObject_methods, (PyObject *)self, name);
+- if (res != NULL)
+- return res;
+- PyErr_Clear();
+-#if PY_VERSION_HEX < 0x02020000
+- return PyMember_Get((char *)self, _mysql_ResultObject_memberlist, name);
+-#else
+- {
+- MyMemberlist(*l);
+- for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) {
+- if (strcmp(l->name, name) == 0)
+- return PyMember_GetOne((char *)self, l);
+- }
+- PyErr_SetString(PyExc_AttributeError, name);
+- return NULL;
+- }
+-#endif
+-}
+-
+-static int
+-_mysql_ConnectionObject_setattr(
+- _mysql_ConnectionObject *self,
+- char *name,
+- PyObject *v)
+-{
+- if (v == NULL) {
+- PyErr_SetString(PyExc_AttributeError,
+- "can't delete connection attributes");
+- return -1;
+- }
+-#if PY_VERSION_HEX < 0x02020000
+- return PyMember_Set((char *)self, _mysql_ConnectionObject_memberlist, name, v);
+-#else
+- {
+- MyMemberlist(*l);
+- for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++)
+- if (strcmp(l->name, name) == 0)
+- return PyMember_SetOne((char *)self, l, v);
+- }
+- PyErr_SetString(PyExc_AttributeError, name);
+- return -1;
+-#endif
+-}
+-
+-static int
+-_mysql_ResultObject_setattr(
+- _mysql_ResultObject *self,
+- char *name,
+- PyObject *v)
+-{
+- if (v == NULL) {
+- PyErr_SetString(PyExc_AttributeError,
+- "can't delete connection attributes");
+- return -1;
+- }
+-#if PY_VERSION_HEX < 0x02020000
+- return PyMember_Set((char *)self, _mysql_ResultObject_memberlist, name, v);
+-#else
+- {
+- MyMemberlist(*l);
+- for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++)
+- if (strcmp(l->name, name) == 0)
+- return PyMember_SetOne((char *)self, l, v);
+- }
+- PyErr_SetString(PyExc_AttributeError, name);
+- return -1;
+-#endif
+-}
+
+ PyTypeObject _mysql_ConnectionObject_Type = {
+- PyObject_HEAD_INIT(NULL)
+- 0,
++ PyVarObject_HEAD_INIT(NULL, 0)
+ "_mysql.connection", /* (char *)tp_name For printing */
+ sizeof(_mysql_ConnectionObject),
+ 0,
+ (destructor)_mysql_ConnectionObject_dealloc, /* tp_dealloc */
+- 0, /*tp_print*/
+- (getattrfunc)_mysql_ConnectionObject_getattr, /* tp_getattr */
+- (setattrfunc)_mysql_ConnectionObject_setattr, /* tp_setattr */
+- 0, /*tp_compare*/
++ 0, /* tp_print*/
++ 0, /* tp_getattr */
++ 0, /* tp_setattr */
++ 0, /* tp_compare*/
+ (reprfunc)_mysql_ConnectionObject_repr, /* tp_repr */
+
+ /* Method suites for standard classes */
+@@ -2564,33 +2505,20 @@
+ 0, /* (PyBufferProcs *) tp_as_buffer */
+
+ /* Flags to define presence of optional/expanded features */
+-#if PY_VERSION_HEX < 0x02020000
+- Py_TPFLAGS_DEFAULT, /* (long) tp_flags */
+-#else
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
+-#endif
+ _mysql_connect__doc__, /* (char *) tp_doc Documentation string */
+-#if PY_VERSION_HEX >= 0x02000000
+ /* Assigned meaning in release 2.0 */
+-#if PY_VERSION_HEX >= 0x02020000
+ /* call function for all accessible objects */
+ (traverseproc) _mysql_ConnectionObject_traverse, /* tp_traverse */
+
+ /* delete references to contained objects */
+ (inquiry) _mysql_ConnectionObject_clear, /* tp_clear */
+-#else
+- /* not supporting pre-2.2 GC */
+- 0,
+- 0,
+-#endif
+-#if PY_VERSION_HEX >= 0x02010000
+ /* Assigned meaning in release 2.1 */
+ /* rich comparisons */
+ 0, /* (richcmpfunc) tp_richcompare */
+
+ /* weak reference enabler */
+ 0, /* (long) tp_weaklistoffset */
+-#if PY_VERSION_HEX >= 0x02020000
+ /* Added in release 2.2 */
+ /* Iterators */
+ 0, /* (getiterfunc) tp_iter */
+@@ -2612,22 +2540,18 @@
+ 0, /* (PyObject *) tp_bases */
+ 0, /* (PyObject *) tp_mro method resolution order */
+ 0, /* (PyObject *) tp_defined */
+-#endif /* python 2.2 */
+-#endif /* python 2.1 */
+-#endif /* python 2.0 */
+ } ;
+
+ PyTypeObject _mysql_ResultObject_Type = {
+- PyObject_HEAD_INIT(NULL)
+- 0,
++ PyVarObject_HEAD_INIT(NULL, 0)
+ "_mysql.result",
+ sizeof(_mysql_ResultObject),
+ 0,
+ (destructor)_mysql_ResultObject_dealloc, /* tp_dealloc */
+- 0, /*tp_print*/
+- (getattrfunc)_mysql_ResultObject_getattr, /* tp_getattr */
+- (setattrfunc)_mysql_ResultObject_setattr, /* tp_setattr */
+- 0, /*tp_compare*/
++ 0, /* tp_print */
++ 0, /* tp_getattr */
++ 0, /* tp_setattr */
++ 0, /* tp_compare */
+ (reprfunc)_mysql_ResultObject_repr, /* tp_repr */
+
+ /* Method suites for standard classes */
+@@ -2648,34 +2572,20 @@
+ 0, /* (PyBufferProcs *) tp_as_buffer */
+
+ /* Flags to define presence of optional/expanded features */
+-#if PY_VERSION_HEX < 0x02020000
+- Py_TPFLAGS_DEFAULT, /* (long) tp_flags */
+-#else
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
+-#endif
+-
+ _mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */
+-#if PY_VERSION_HEX >= 0x02000000
+ /* Assigned meaning in release 2.0 */
+-#if PY_VERSION_HEX >= 0x02020000
+ /* call function for all accessible objects */
+ (traverseproc) _mysql_ResultObject_traverse, /* tp_traverse */
+
+ /* delete references to contained objects */
+ (inquiry) _mysql_ResultObject_clear, /* tp_clear */
+-#else
+- /* not supporting pre-2.2 GC */
+- 0,
+- 0,
+-#endif
+-#if PY_VERSION_HEX >= 0x02010000
+ /* Assigned meaning in release 2.1 */
+ /* rich comparisons */
+ 0, /* (richcmpfunc) tp_richcompare */
+
+ /* weak reference enabler */
+ 0, /* (long) tp_weaklistoffset */
+-#if PY_VERSION_HEX >= 0x02020000
+ /* Added in release 2.2 */
+ /* Iterators */
+ 0, /* (getiterfunc) tp_iter */
+@@ -2697,13 +2607,9 @@
+ 0, /* (PyObject *) tp_bases */
+ 0, /* (PyObject *) tp_mro method resolution order */
+ 0, /* (PyObject *) tp_defined */
+-#endif /* python 2.2 */
+-#endif /* python 2.1 */
+-#endif /* python 2.0 */
+ };
+
+-static PyMethodDef
+-_mysql_methods[] = {
++static PyMethodDef _mysql_methods[] = {
+ {
+ "connect",
+ (PyCFunction)_mysql_connect,
+@@ -2775,16 +2681,11 @@
+ {NULL, NULL} /* sentinel */
+ };
+
+-static PyObject *
+-_mysql_NewException(
+- PyObject *dict,
+- PyObject *edict,
+- char *name)
++static PyObject *_mysql_NewException( PyObject *dict, PyObject *edict, char *name)
+ {
+ PyObject *e;
+
+- if (!(e = PyDict_GetItemString(edict, name)))
+- return NULL;
++ if (!(e = PyDict_GetItemString(edict, name))) return NULL;
+ if (PyDict_SetItemString(dict, name, e)) return NULL;
+ return e;
+ }
+@@ -2806,85 +2707,111 @@
+ (as of 3.23) are NOT implemented.\n\
+ ";
+
+-DL_EXPORT(void)
+-init_mysql(void)
++/* module definition */
++static struct PyModuleDef mysqlModule = {
++ PyModuleDef_HEAD_INIT,
++ "_mysql", /* name of module */
++ _mysql___doc__, /* module documentation */
++ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
++ _mysql_methods,
++ NULL,
++ NULL,
++ NULL,
++ NULL
++};
++
++int CheckError()
++{
++ if ( PyErr_Occurred() )
++ {
++ PyErr_Print();
++ PyErr_SetString(PyExc_ImportError, "_mysql: init failed");
++ PyErr_Print();
++ return -1;
++ };
++ return 0;
++};
++
++PyMODINIT_FUNC PyInit__mysql(void)
+ {
+ PyObject *dict, *module, *emod, *edict;
+- module = Py_InitModule4("_mysql", _mysql_methods, _mysql___doc__,
+- (PyObject *)NULL, PYTHON_API_VERSION);
+- if (!module) return; /* this really should never happen */
+- _mysql_ConnectionObject_Type.ob_type = &PyType_Type;
+- _mysql_ResultObject_Type.ob_type = &PyType_Type;
+-#if PY_VERSION_HEX >= 0x02020000
++
++ _mysql_ConnectionObject_Type.ob_base.ob_base.ob_type = &PyType_Type;
++ _mysql_ResultObject_Type.ob_base.ob_base.ob_type = &PyType_Type;
+ _mysql_ConnectionObject_Type.tp_alloc = PyType_GenericAlloc;
+ _mysql_ConnectionObject_Type.tp_new = PyType_GenericNew;
+- _mysql_ConnectionObject_Type.tp_free = _PyObject_GC_Del;
++ _mysql_ConnectionObject_Type.tp_free = PyObject_GC_Del;
+ _mysql_ResultObject_Type.tp_alloc = PyType_GenericAlloc;
+ _mysql_ResultObject_Type.tp_new = PyType_GenericNew;
+- _mysql_ResultObject_Type.tp_free = _PyObject_GC_Del;
+-#endif
++ _mysql_ResultObject_Type.tp_free = PyObject_GC_Del;
+
+- if (!(dict = PyModule_GetDict(module))) goto error;
+- if (PyDict_SetItemString(dict, "version_info",
+- PyRun_String(QUOTE(version_info), Py_eval_input,
+- dict, dict)))
+- goto error;
+- if (PyDict_SetItemString(dict, "__version__",
+- PyString_FromString(QUOTE(__version__))))
+- goto error;
+- if (PyDict_SetItemString(dict, "connection",
+- (PyObject *)&_mysql_ConnectionObject_Type))
+- goto error;
+- Py_INCREF(&_mysql_ConnectionObject_Type);
+- if (PyDict_SetItemString(dict, "result",
+- (PyObject *)&_mysql_ResultObject_Type))
+- goto error;
+- Py_INCREF(&_mysql_ResultObject_Type);
+- if (!(emod = PyImport_ImportModule("_mysql_exceptions")))
+- goto error;
+- if (!(edict = PyModule_GetDict(emod))) goto error;
+- if (!(_mysql_MySQLError =
+- _mysql_NewException(dict, edict, "MySQLError")))
+- goto error;
+- if (!(_mysql_Warning =
+- _mysql_NewException(dict, edict, "Warning")))
+- goto error;
+- if (!(_mysql_Error =
+- _mysql_NewException(dict, edict, "Error")))
+- goto error;
+- if (!(_mysql_InterfaceError =
+- _mysql_NewException(dict, edict, "InterfaceError")))
+- goto error;
+- if (!(_mysql_DatabaseError =
+- _mysql_NewException(dict, edict, "DatabaseError")))
+- goto error;
+- if (!(_mysql_DataError =
+- _mysql_NewException(dict, edict, "DataError")))
+- goto error;
+- if (!(_mysql_OperationalError =
+- _mysql_NewException(dict, edict, "OperationalError")))
+- goto error;
+- if (!(_mysql_IntegrityError =
+- _mysql_NewException(dict, edict, "IntegrityError")))
+- goto error;
+- if (!(_mysql_InternalError =
+- _mysql_NewException(dict, edict, "InternalError")))
+- goto error;
+- if (!(_mysql_ProgrammingError =
+- _mysql_NewException(dict, edict, "ProgrammingError")))
+- goto error;
+- if (!(_mysql_NotSupportedError =
+- _mysql_NewException(dict, edict, "NotSupportedError")))
+- goto error;
+- Py_DECREF(emod);
+- if (!(_mysql_NULL = PyString_FromString("NULL")))
+- goto error;
+- if (PyDict_SetItemString(dict, "NULL", _mysql_NULL)) goto error;
+- error:
+- if (PyErr_Occurred())
+- PyErr_SetString(PyExc_ImportError,
+- "_mysql: init failed");
+- return;
++ if (PyType_Ready(&_mysql_ConnectionObject_Type) < 0) return NULL;
++ if (PyType_Ready(&_mysql_ResultObject_Type) < 0) return NULL;
++
++ module = PyModule_Create2(&mysqlModule,PYTHON_API_VERSION);
++
++ if (module == NULL)
++ {
++ return NULL;
++ };
++
++ dict = PyModule_GetDict(module);
++ if (PyDict_SetItemString(dict, "version_info", PyRun_String(QUOTE(version_info), Py_eval_input, dict, dict)) == -1)
++ {
++ } else if (PyDict_SetItemString(dict, "__version__",
++ PyUnicode_FromString(QUOTE(__version__))) == -1 )
++ {
++ } else if (PyDict_SetItemString(dict, "connection",
++ (PyObject *)&_mysql_ConnectionObject_Type) == -1 )
++ {
++
++ } else
++ {
++ Py_INCREF(&_mysql_ConnectionObject_Type);
++ if ( PyDict_SetItemString(dict, "result",(PyObject *)&_mysql_ResultObject_Type) == -1 )
++ {
++
++ } else
++ {
++ Py_INCREF(&_mysql_ResultObject_Type);
++ emod = PyImport_ImportModule("_mysql_exceptions");
++ if (emod != NULL )
++ {
++ edict = PyModule_GetDict(emod);
++ _mysql_MySQLError = _mysql_NewException(dict, edict, "MySQLError");
++ if (_mysql_MySQLError != NULL)
++ {
++ _mysql_Warning = _mysql_NewException(dict, edict, "Warning");
++ _mysql_Error = _mysql_NewException(dict, edict, "Error");
++ _mysql_InterfaceError = _mysql_NewException(dict, edict, "InterfaceError");
++ _mysql_DatabaseError = _mysql_NewException(dict, edict, "DatabaseError");
++ _mysql_DataError = _mysql_NewException(dict, edict, "DataError");
++ _mysql_OperationalError = _mysql_NewException(dict, edict, "OperationalError");
++ _mysql_IntegrityError = _mysql_NewException(dict, edict, "IntegrityError");
++ _mysql_InternalError = _mysql_NewException(dict, edict, "InternalError");
++ _mysql_ProgrammingError = _mysql_NewException(dict, edict, "ProgrammingError");
++ _mysql_NotSupportedError = _mysql_NewException(dict, edict, "NotSupportedError");
++ if ( _mysql_Warning != NULL && _mysql_Error != NULL && _mysql_InterfaceError != NULL &&
++ _mysql_DatabaseError != NULL && _mysql_DataError != NULL && _mysql_OperationalError != NULL &&
++ _mysql_IntegrityError != NULL && _mysql_InternalError != NULL &&
++ _mysql_ProgrammingError != NULL && _mysql_NotSupportedError != NULL
++ )
++ {
++ Py_DECREF(emod);
++ _mysql_NULL = PyUnicode_FromString("NULL");
++ PyDict_SetItemString(dict, "NULL", _mysql_NULL);
++ };
++ };
++ };
++ };
++ };
++
++ if ( CheckError() == -1 )
++ {
++ return NULL;
++ };
++
++ return module;
+ }
+
+
+diff -ru MySQL-python-1.2.3/MySQLdb/connections.py MySQL-Python-1.2.3-python3/MySQLdb/connections.py
+--- MySQL-python-1.2.3/MySQLdb/connections.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/MySQLdb/connections.py 2011-11-25 16:44:27.000000000 +0100
+@@ -6,7 +6,7 @@
+ override Connection.default_cursor with a non-standard Cursor class.
+
+ """
+-import cursors
++import MySQLdb.cursors
+ from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
+ DatabaseError, OperationalError, IntegrityError, InternalError, \
+ NotSupportedError, ProgrammingError
+@@ -33,7 +33,7 @@
+ connection.messages.append(error)
+ del cursor
+ del connection
+- raise errorclass, errorvalue
++ raise errorclass(errorvalue)
+
+ re_numeric_part = re.compile(r"^(\d+)")
+
+@@ -57,7 +57,7 @@
+
+ """MySQL Database Connection Object"""
+
+- default_cursor = cursors.Cursor
++ default_cursor = MySQLdb.cursors.Cursor
+
+ def __init__(self, *args, **kwargs):
+ """
+@@ -109,17 +109,9 @@
+ cursorclass
+ class object, used to create cursors (keyword only)
+
+- use_unicode
+- If True, text-like columns are returned as unicode objects
+- using the connection's character set. Otherwise, text-like
+- columns are returned as strings. columns are returned as
+- normal strings. Unicode objects will always be encoded to
+- the connection's character set regardless of this setting.
+-
+ charset
+ If supplied, the connection character set will be changed
+- to this character set (MySQL-4.1 and newer). This implies
+- use_unicode=True.
++ to this character set (MySQL-4.1 and newer).
+
+ sql_mode
+ If supplied, the session SQL mode will be changed to this
+@@ -143,15 +135,15 @@
+ documentation for the MySQL C API for some hints on what they do.
+
+ """
+- from constants import CLIENT, FIELD_TYPE
+- from converters import conversions
++ from .constants import CLIENT, FIELD_TYPE
++ from .converters import conversions
+ from weakref import proxy, WeakValueDictionary
+
+ import types
+
+ kwargs2 = kwargs.copy()
+
+- if kwargs.has_key('conv'):
++ if 'conv' in kwargs:
+ conv = kwargs['conv']
+ else:
+ conv = conversions
+@@ -165,14 +157,8 @@
+ kwargs2['conv'] = conv2
+
+ self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
+- charset = kwargs2.pop('charset', '')
++ charset = kwargs2.pop('charset', 'utf8')
+
+- if charset:
+- use_unicode = True
+- else:
+- use_unicode = False
+-
+- use_unicode = kwargs2.pop('use_unicode', use_unicode)
+ sql_mode = kwargs2.pop('sql_mode', '')
+
+ client_flag = kwargs.get('client_flag', 0)
+@@ -197,19 +183,13 @@
+ return db.string_literal(obj)
+ return string_literal
+
+- def _get_unicode_literal():
+- def unicode_literal(u, dummy=None):
+- return db.literal(u.encode(unicode_literal.charset))
+- return unicode_literal
+-
+- def _get_string_decoder():
+- def string_decoder(s):
+- return s.decode(string_decoder.charset)
+- return string_decoder
+-
++ def _get_bytes_literal():
++ def bytes_literal(u, dummy=None):
++ return db.literal(u.decode(bytes_literal.charset))
++ return bytes_literal
++
+ string_literal = _get_string_literal()
+- self.unicode_literal = unicode_literal = _get_unicode_literal()
+- self.string_decoder = string_decoder = _get_string_decoder()
++ self.bytes_literal = bytes_literal = _get_bytes_literal()
+ if not charset:
+ charset = self.character_set_name()
+ self.set_character_set(charset)
+@@ -217,14 +197,9 @@
+ if sql_mode:
+ self.set_sql_mode(sql_mode)
+
+- if use_unicode:
+- self.converter[FIELD_TYPE.STRING].append((None, string_decoder))
+- self.converter[FIELD_TYPE.VAR_STRING].append((None, string_decoder))
+- self.converter[FIELD_TYPE.VARCHAR].append((None, string_decoder))
+- self.converter[FIELD_TYPE.BLOB].append((None, string_decoder))
+-
+- self.encoders[types.StringType] = string_literal
+- self.encoders[types.UnicodeType] = unicode_literal
++ self.encoders[str] = string_literal
++ self.encoders[bytes] = bytes_literal
++
+ self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
+ if self._transactional:
+ # PEP-249 requires autocommit to be initially off
+@@ -297,8 +272,7 @@
+ raise NotSupportedError("server is too old to set charset")
+ self.query('SET NAMES %s' % charset)
+ self.store_result()
+- self.string_decoder.charset = charset
+- self.unicode_literal.charset = charset
++ self.bytes_literal.charset = charset
+
+ def set_sql_mode(self, sql_mode):
+ """Set the connection sql_mode. See MySQL documentation for
+Pouze v MySQL-python-1.2.3/MySQLdb/constants: .cvsignore
+Pouze v MySQL-Python-1.2.3-python3/MySQLdb/constants: __pycache__
+diff -ru MySQL-python-1.2.3/MySQLdb/converters.py MySQL-Python-1.2.3-python3/MySQLdb/converters.py
+--- MySQL-python-1.2.3/MySQLdb/converters.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/MySQLdb/converters.py 2011-10-05 12:49:58.000000000 +0200
+@@ -33,9 +33,9 @@
+ """
+
+ from _mysql import string_literal, escape_sequence, escape_dict, escape, NULL
+-from constants import FIELD_TYPE, FLAG
+-from times import *
+-import types
++from .constants import FIELD_TYPE, FLAG
++from .times import *
++import datetime
+ import array
+
+ try:
+@@ -55,16 +55,16 @@
+ """Convert something into a string via str()."""
+ return str(s)
+
+-def Unicode2Str(s, d):
+- """Convert a unicode object to a string using the default encoding.
++def Bytes2Str(s, d):
++ """Convert a bytes object to a string using the default encoding.
+ This is only used as a placeholder for the real function, which
+ is connection-dependent."""
+- return s.encode()
++ return s.decode()
+
+ Long2Int = Thing2Str
+
+ def Float2Str(o, d):
+- return '%.15g' % o
++ return '{:f}'.format(o)
+
+ def None2NULL(o, d):
+ """Convert None to NULL."""
+@@ -115,30 +115,30 @@
+ return Thing2Literal(o.tostring(), d)
+
+ conversions = {
+- types.IntType: Thing2Str,
+- types.LongType: Long2Int,
+- types.FloatType: Float2Str,
+- types.NoneType: None2NULL,
+- types.TupleType: escape_sequence,
+- types.ListType: escape_sequence,
+- types.DictType: escape_dict,
+- types.InstanceType: Instance2Str,
++ int: Long2Int,
++ float: Float2Str,
++ type(None): None2NULL,
++ tuple: escape_sequence,
++ list: escape_sequence,
++ dict: escape_dict,
++ object: Instance2Str,
+ array.ArrayType: array2Str,
+- types.StringType: Thing2Literal, # default
+- types.UnicodeType: Unicode2Str,
+- types.ObjectType: Instance2Str,
+- types.BooleanType: Bool2Str,
+- DateTimeType: DateTime2literal,
+- DateTimeDeltaType: DateTimeDelta2literal,
++ str: Thing2Literal, # default
++ bytes: Bytes2Str,
++ bool: Bool2Str,
++ datetime.date: DateTime2literal,
++ datetime.time: DateTime2literal,
++ datetime.datetime: DateTime2literal,
++ datetime.timedelta: DateTimeDelta2literal,
+ set: Set2Str,
+ FIELD_TYPE.TINY: int,
+ FIELD_TYPE.SHORT: int,
+- FIELD_TYPE.LONG: long,
++ FIELD_TYPE.LONG: int,
+ FIELD_TYPE.FLOAT: float,
+ FIELD_TYPE.DOUBLE: float,
+ FIELD_TYPE.DECIMAL: float,
+ FIELD_TYPE.NEWDECIMAL: float,
+- FIELD_TYPE.LONGLONG: long,
++ FIELD_TYPE.LONGLONG: int,
+ FIELD_TYPE.INT24: int,
+ FIELD_TYPE.YEAR: int,
+ FIELD_TYPE.SET: Str2Set,
+diff -ru MySQL-python-1.2.3/MySQLdb/cursors.py MySQL-Python-1.2.3-python3/MySQLdb/cursors.py
+--- MySQL-python-1.2.3/MySQLdb/cursors.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/MySQLdb/cursors.py 2011-11-25 16:53:26.000000000 +0100
+@@ -7,7 +7,6 @@
+
+ import re
+ import sys
+-from types import ListType, TupleType, UnicodeType
+
+
+ restr = (r"\svalues\s*"
+@@ -153,13 +152,19 @@
+ del self.messages[:]
+ db = self._get_db()
+ charset = db.character_set_name()
+- if isinstance(query, unicode):
+- query = query.encode(charset)
++
+ if args is not None:
++ if isinstance(query, bytes):
++ query = query.decode();
++
+ query = query % db.literal(args)
++
++ if isinstance(query, str):
++ query = query.encode(charset);
++
+ try:
+ r = self._query(query)
+- except TypeError, m:
++ except TypeError as m:
+ if m.args[0] in ("not enough arguments for format string",
+ "not all arguments converted"):
+ self.messages.append((ProgrammingError, m.args[0]))
+@@ -197,8 +202,6 @@
+ del self.messages[:]
+ db = self._get_db()
+ if not args: return
+- charset = db.character_set_name()
+- if isinstance(query, unicode): query = query.encode(charset)
+ m = insert_values.search(query)
+ if not m:
+ r = 0
+@@ -210,7 +213,7 @@
+ qv = m.group(1)
+ try:
+ q = [ qv % db.literal(a) for a in args ]
+- except TypeError, msg:
++ except TypeError as msg:
+ if msg.args[0] in ("not enough arguments for format string",
+ "not all arguments converted"):
+ self.errorhandler(self, ProgrammingError, msg.args[0])
+@@ -259,7 +262,7 @@
+ for index, arg in enumerate(args):
+ q = "SET @_%s_%d=%s" % (procname, index,
+ db.literal(arg))
+- if isinstance(q, unicode):
++ if isinstance(q, str):
+ q = q.encode(charset)
+ self._query(q)
+ self.nextset()
+@@ -267,7 +270,7 @@
+ q = "CALL %s(%s)" % (procname,
+ ','.join(['@_%s_%d' % (procname, i)
+ for i in range(len(args))]))
+- if type(q) is UnicodeType:
++ if type(q) is str:
+ q = q.encode(charset)
+ self._query(q)
+ self._executed = q
+@@ -363,7 +366,7 @@
+ r = value
+ else:
+ self.errorhandler(self, ProgrammingError,
+- "unknown scroll mode %s" % `mode`)
++ "unknown scroll mode %r" % mode)
+ if r < 0 or r >= len(self._rows):
+ self.errorhandler(self, IndexError, "out of range")
+ self.rownumber = r
+Pouze v MySQL-python-1.2.3/MySQLdb: .cvsignore
+diff -ru MySQL-python-1.2.3/MySQLdb/__init__.py MySQL-Python-1.2.3-python3/MySQLdb/__init__.py
+--- MySQL-python-1.2.3/MySQLdb/__init__.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/MySQLdb/__init__.py 2011-10-05 12:49:58.000000000 +0200
+@@ -14,7 +14,7 @@
+ """
+
+ __revision__ = """$Revision: 603 $"""[11:-2]
+-from release import __version__, version_info, __author__
++from .release import __version__, version_info, __author__
+
+ import _mysql
+
+@@ -77,7 +77,7 @@
+
+ def Connect(*args, **kwargs):
+ """Factory function for connections.Connection."""
+- from connections import Connection
++ from .connections import Connection
+ return Connection(*args, **kwargs)
+
+ connect = Connection = Connect
+diff -ru MySQL-python-1.2.3/_mysql_exceptions.py MySQL-Python-1.2.3-python3/_mysql_exceptions.py
+--- MySQL-python-1.2.3/_mysql_exceptions.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/_mysql_exceptions.py 2011-10-05 12:49:58.000000000 +0200
+@@ -5,9 +5,8 @@
+ http://www.python.org/topics/database/DatabaseAPI-2.0.html
+ """
+
+-from exceptions import Exception, StandardError, Warning
+
+-class MySQLError(StandardError):
++class MySQLError(Exception):
+
+ """Exception related to operation with MySQL."""
+
+@@ -80,4 +79,3 @@
+ has transactions turned off."""
+
+
+-del Exception, StandardError
+diff -ru MySQL-python-1.2.3/MySQL_python.egg-info/SOURCES.txt MySQL-Python-1.2.3-python3/MySQL_python.egg-info/SOURCES.txt
+--- MySQL-python-1.2.3/MySQL_python.egg-info/SOURCES.txt 2010-06-17 09:22:07.000000000 +0200
++++ MySQL-Python-1.2.3-python3/MySQL_python.egg-info/SOURCES.txt 2011-11-25 16:54:24.000000000 +0100
+@@ -1,4 +1,3 @@
+-.cvsignore
+ HISTORY
+ MANIFEST.in
+ README
+@@ -17,14 +16,12 @@
+ MySQL_python.egg-info/SOURCES.txt
+ MySQL_python.egg-info/dependency_links.txt
+ MySQL_python.egg-info/top_level.txt
+-MySQLdb/.cvsignore
+ MySQLdb/__init__.py
+ MySQLdb/connections.py
+ MySQLdb/converters.py
+ MySQLdb/cursors.py
+ MySQLdb/release.py
+ MySQLdb/times.py
+-MySQLdb/constants/.cvsignore
+ MySQLdb/constants/CLIENT.py
+ MySQLdb/constants/CR.py
+ MySQLdb/constants/ER.py
+@@ -32,7 +29,6 @@
+ MySQLdb/constants/FLAG.py
+ MySQLdb/constants/REFRESH.py
+ MySQLdb/constants/__init__.py
+-doc/.cvsignore
+ doc/FAQ.txt
+ doc/MySQLdb.txt
+ tests/capabilities.py
+diff -ru MySQL-python-1.2.3/README MySQL-Python-1.2.3-python3/README
+--- MySQL-python-1.2.3/README 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/README 2011-10-05 12:49:58.000000000 +0200
+@@ -8,22 +8,18 @@
+ Prerequisites
+ -------------
+
+-+ Python 2.3.4 or higher
+++ Python 3.2 or higher
+
+ * http://www.python.org/
+
+- * Versions lower than 2.3 WON'T WORK.
+-
+- * 2.4 is the primary test environment.
+-
+ * Red Hat Linux:
+
+ - Make sure you have the Python development headers and libraries
+ (python-devel).
+
+-+ setuptools
+++ distribute
+
+- * http://pypi.python.org/pypi/setuptools
++ * http://pypi.python.org/pypi/distribute/
+
+ + MySQL 3.23.32 or higher
+
+diff -ru MySQL-python-1.2.3/setup_common.py MySQL-Python-1.2.3-python3/setup_common.py
+--- MySQL-python-1.2.3/setup_common.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/setup_common.py 2011-10-05 12:49:58.000000000 +0200
+@@ -1,4 +1,4 @@
+-from ConfigParser import SafeConfigParser
++from configparser import SafeConfigParser
+
+ def get_metadata_and_options():
+ config = SafeConfigParser()
+@@ -7,8 +7,8 @@
+ metadata = dict(config.items('metadata'))
+ options = dict(config.items('options'))
+
+- metadata['py_modules'] = filter(None, metadata['py_modules'].split('\n'))
+- metadata['classifiers'] = filter(None, metadata['classifiers'].split('\n'))
++ metadata['py_modules'] = list(filter(None, metadata['py_modules'].split('\n')))
++ metadata['classifiers'] = list(filter(None, metadata['classifiers'].split('\n')))
+
+ return metadata, options
+
+@@ -30,3 +30,4 @@
+ __version__ = "%(version)s"
+ """ % metadata)
+ rel.close()
++
+diff -ru MySQL-python-1.2.3/setup_posix.py MySQL-Python-1.2.3-python3/setup_posix.py
+--- MySQL-python-1.2.3/setup_posix.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/setup_posix.py 2011-11-25 17:13:11.000000000 +0100
+@@ -1,4 +1,4 @@
+-from ConfigParser import SafeConfigParser
++from configparser import SafeConfigParser
+
+ # This dequote() business is required for some older versions
+ # of mysql_config
+@@ -98,5 +98,5 @@
+ return metadata, ext_options
+
+ if __name__ == "__main__":
+- print """You shouldn't be running this directly; it is used by setup.py."""
++ print("""You shouldn't be running this directly; it is used by setup.py.""")
+
+diff -ru MySQL-python-1.2.3/setup.py MySQL-Python-1.2.3-python3/setup.py
+--- MySQL-python-1.2.3/setup.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/setup.py 2011-10-05 12:49:58.000000000 +0200
+@@ -4,8 +4,8 @@
+ import sys
+ from setuptools import setup, Extension
+
+-if not hasattr(sys, "hexversion") or sys.hexversion < 0x02030000:
+- raise Error("Python 2.3 or newer is required")
++if not hasattr(sys, "hexversion") or sys.hexversion < 0x03000000:
++ raise Exception("Python 3.0 or newer is required")
+
+ if os.name == "posix":
+ from setup_posix import get_config
+diff -ru MySQL-python-1.2.3/setup_windows.py MySQL-Python-1.2.3-python3/setup_windows.py
+--- MySQL-python-1.2.3/setup_windows.py 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/setup_windows.py 2011-10-05 12:49:58.000000000 +0200
+@@ -1,11 +1,11 @@
+ def get_config():
+- import os, sys, _winreg
++ import os, sys, winreg
+ from setup_common import get_metadata_and_options, enabled, create_release_file
+
+ metadata, options = get_metadata_and_options()
+
+- serverKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, options['registry_key'])
+- mysql_root, dummy = _winreg.QueryValueEx(serverKey,'Location')
++ serverKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, options['registry_key'])
++ mysql_root, dummy = winreg.QueryValueEx(serverKey,options['location'])
+
+ extra_objects = []
+ static = enabled(options, 'static')
+@@ -15,7 +15,7 @@
+ else:
+ client = "mysqlclient"
+
+- library_dirs = [ os.path.join(mysql_root, r'lib\opt') ]
++ library_dirs = [ os.path.join(mysql_root, r'lib') ]
+ libraries = [ 'kernel32', 'advapi32', 'wsock32', client ]
+ include_dirs = [ os.path.join(mysql_root, r'include') ]
+ extra_compile_args = [ '/Zl' ]
+@@ -43,5 +43,5 @@
+ return metadata, ext_options
+
+ if __name__ == "__main__":
+- print """You shouldn't be running this directly; it is used by setup.py."""
++ print ("""You shouldn't be running this directly; it is used by setup.py.""")
+
+diff -ru MySQL-python-1.2.3/site.cfg MySQL-Python-1.2.3-python3/site.cfg
+--- MySQL-python-1.2.3/site.cfg 2010-06-17 09:21:56.000000000 +0200
++++ MySQL-Python-1.2.3-python3/site.cfg 2011-10-05 12:49:58.000000000 +0200
+@@ -15,4 +15,6 @@
+ # The Windows registry key for MySQL.
+ # This has to be set for Windows builds to work.
+ # Only change this if you have a different version.
+-registry_key = SOFTWARE\MySQL AB\MySQL Server 5.0
++registry_key = SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{2DB39FB6-161E-44E7-B2A1-B654C85EFBC1}
++location = InstallLocation
++
+diff -ru MySQL-python-1.2.3/tests/capabilities.py MySQL-Python-1.2.3-python3/tests/capabilities.py
+--- MySQL-python-1.2.3/tests/capabilities.py 2010-06-17 09:21:55.000000000 +0200
++++ MySQL-Python-1.2.3-python3/tests/capabilities.py 2011-10-05 12:49:58.000000000 +0200
+@@ -25,7 +25,7 @@
+ self.connection = db
+ self.cursor = db.cursor()
+ self.BLOBText = ''.join([chr(i) for i in range(256)] * 100);
+- self.BLOBUText = u''.join([unichr(i) for i in range(16384)])
++ self.BLOBUText = ''.join([chr(i) for i in range(16384)])
+ self.BLOBBinary = self.db_module.Binary(''.join([chr(i) for i in range(256)] * 16))
+
+ leak_test = True
+@@ -35,11 +35,11 @@
+ import gc
+ del self.cursor
+ orphans = gc.collect()
+- self.failIf(orphans, "%d orphaned objects found after deleting cursor" % orphans)
++ self.assertFalse(orphans, "%d orphaned objects found after deleting cursor" % orphans)
+
+ del self.connection
+ orphans = gc.collect()
+- self.failIf(orphans, "%d orphaned objects found after deleting connection" % orphans)
++ self.assertFalse(orphans, "%d orphaned objects found after deleting connection" % orphans)
+
+ def table_exists(self, name):
+ try:
+@@ -81,18 +81,18 @@
+ self.create_table(columndefs)
+ insert_statement = ('INSERT INTO %s VALUES (%s)' %
+ (self.table,
+- ','.join(['%s'] * len(columndefs))))
++ ','.join(['{!s}'] * len(columndefs))))
+ data = [ [ generator(i,j) for j in range(len(columndefs)) ]
+ for i in range(self.rows) ]
+ if self.debug:
+- print data
++ print(data)
+ self.cursor.executemany(insert_statement, data)
+ self.connection.commit()
+ # verify
+ self.cursor.execute('select * from %s' % self.table)
+ l = self.cursor.fetchall()
+ if self.debug:
+- print l
++ print(l)
+ self.assertEquals(len(l), self.rows)
+ try:
+ for i in range(self.rows):
+@@ -110,7 +110,7 @@
+ self.create_table(columndefs)
+ insert_statement = ('INSERT INTO %s VALUES (%s)' %
+ (self.table,
+- ','.join(['%s'] * len(columndefs))))
++ ','.join(['{!s}'] * len(columndefs))))
+ data = [ [ generator(i,j) for j in range(len(columndefs)) ]
+ for i in range(self.rows) ]
+ self.cursor.executemany(insert_statement, data)
+@@ -122,33 +122,33 @@
+ for i in range(self.rows):
+ for j in range(len(columndefs)):
+ self.assertEquals(l[i][j], generator(i,j))
+- delete_statement = 'delete from %s where col1=%%s' % self.table
++ delete_statement = 'delete from %s where col1={!s}' % self.table
+ self.cursor.execute(delete_statement, (0,))
+ self.cursor.execute('select col1 from %s where col1=%s' % \
+ (self.table, 0))
+ l = self.cursor.fetchall()
+- self.failIf(l, "DELETE didn't work")
++ self.assertFalse(l, "DELETE didn't work")
+ self.connection.rollback()
+ self.cursor.execute('select col1 from %s where col1=%s' % \
+ (self.table, 0))
+ l = self.cursor.fetchall()
+- self.failUnless(len(l) == 1, "ROLLBACK didn't work")
++ self.assertTrue(len(l) == 1, "ROLLBACK didn't work")
+ self.cursor.execute('drop table %s' % (self.table))
+
+ def test_truncation(self):
+ columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
+ def generator(row, col):
+ if col == 0: return row
+- else: return ('%i' % (row%10))*((255-self.rows/2)+row)
++ else: return ('{:d}'.format(row%10))*(round(255-self.rows/2)+row)
+ self.create_table(columndefs)
+ insert_statement = ('INSERT INTO %s VALUES (%s)' %
+ (self.table,
+- ','.join(['%s'] * len(columndefs))))
++ ','.join(['{!s}'] * len(columndefs))))
+
+ try:
+ self.cursor.execute(insert_statement, (0, '0'*256))
+ except Warning:
+- if self.debug: print self.cursor.messages
++ if self.debug: print(self.cursor.messages)
+ except self.connection.DataError:
+ pass
+ else:
+@@ -163,7 +163,7 @@
+ data.append(generator(i,j))
+ self.cursor.execute(insert_statement,tuple(data))
+ except Warning:
+- if self.debug: print self.cursor.messages
++ if self.debug: print(self.cursor.messages)
+ except self.connection.DataError:
+ pass
+ else:
+@@ -176,7 +176,7 @@
+ for i in range(self.rows) ]
+ self.cursor.executemany(insert_statement, data)
+ except Warning:
+- if self.debug: print self.cursor.messages
++ if self.debug: print(self.cursor.messages)
+ except self.connection.DataError:
+ pass
+ else:
+diff -ru MySQL-python-1.2.3/tests/dbapi20.py MySQL-Python-1.2.3-python3/tests/dbapi20.py
+--- MySQL-python-1.2.3/tests/dbapi20.py 2010-06-17 09:21:55.000000000 +0200
++++ MySQL-Python-1.2.3-python3/tests/dbapi20.py 2011-10-05 12:49:58.000000000 +0200
+@@ -177,8 +177,8 @@
+ def test_Exceptions(self):
+ # Make sure required exceptions exist, and are in the
+ # defined heirarchy.
+- self.failUnless(issubclass(self.driver.Warning,StandardError))
+- self.failUnless(issubclass(self.driver.Error,StandardError))
++ self.failUnless(issubclass(self.driver.Warning,Exception))
++ self.failUnless(issubclass(self.driver.Error,Exception))
+ self.failUnless(
+ issubclass(self.driver.InterfaceError,self.driver.Error)
+ )
+@@ -382,27 +382,27 @@
+
+ if self.driver.paramstyle == 'qmark':
+ cur.execute(
+- 'insert into %sbooze values (?)' % self.table_prefix,
++ 'insert into %sbooze values ({!s})' % self.table_prefix,
+ ("Cooper's",)
+ )
+ elif self.driver.paramstyle == 'numeric':
+ cur.execute(
+- 'insert into %sbooze values (:1)' % self.table_prefix,
++ 'insert into %sbooze values ({:1})' % self.table_prefix,
+ ("Cooper's",)
+ )
+ elif self.driver.paramstyle == 'named':
+ cur.execute(
+- 'insert into %sbooze values (:beer)' % self.table_prefix,
++ 'insert into %sbooze values ({beer})' % self.table_prefix,
+ {'beer':"Cooper's"}
+ )
+ elif self.driver.paramstyle == 'format':
+ cur.execute(
+- 'insert into %sbooze values (%%s)' % self.table_prefix,
++ 'insert into %sbooze values ({!s})' % self.table_prefix,
+ ("Cooper's",)
+ )
+ elif self.driver.paramstyle == 'pyformat':
+ cur.execute(
+- 'insert into %sbooze values (%%(beer)s)' % self.table_prefix,
++ 'insert into %sbooze values ({beer})' % self.table_prefix,
+ {'beer':"Cooper's"}
+ )
+ else:
+@@ -432,27 +432,27 @@
+ margs = [ {'beer': "Cooper's"}, {'beer': "Boag's"} ]
+ if self.driver.paramstyle == 'qmark':
+ cur.executemany(
+- 'insert into %sbooze values (?)' % self.table_prefix,
++ 'insert into %sbooze values ({!s})' % self.table_prefix,
+ largs
+ )
+ elif self.driver.paramstyle == 'numeric':
+ cur.executemany(
+- 'insert into %sbooze values (:1)' % self.table_prefix,
++ 'insert into %sbooze values ({:1})' % self.table_prefix,
+ largs
+ )
+ elif self.driver.paramstyle == 'named':
+ cur.executemany(
+- 'insert into %sbooze values (:beer)' % self.table_prefix,
++ 'insert into %sbooze values ({beer})' % self.table_prefix,
+ margs
+ )
+ elif self.driver.paramstyle == 'format':
+ cur.executemany(
+- 'insert into %sbooze values (%%s)' % self.table_prefix,
++ 'insert into %sbooze values ({!s})' % self.table_prefix,
+ largs
+ )
+ elif self.driver.paramstyle == 'pyformat':
+ cur.executemany(
+- 'insert into %sbooze values (%%(beer)s)' % (
++ 'insert into %sbooze values ({beer})' % (
+ self.table_prefix
+ ),
+ margs
+@@ -706,7 +706,7 @@
+ that returns two result sets, first the
+ number of rows in booze then "name from booze"
+ '''
+- raise NotImplementedError,'Helper not implemented'
++ raise NotImplementedError('Helper not implemented')
+ #sql="""
+ # create procedure deleteme as
+ # begin
+@@ -718,7 +718,7 @@
+
+ def help_nextset_tearDown(self,cur):
+ 'If cleaning up is needed after nextSetTest'
+- raise NotImplementedError,'Helper not implemented'
++ raise NotImplementedError('Helper not implemented')
+ #cur.execute("drop procedure deleteme")
+
+ def test_nextset(self):
+@@ -751,7 +751,7 @@
+ con.close()
+
+ def test_nextset(self):
+- raise NotImplementedError,'Drivers need to override this test'
++ raise NotImplementedError('Drivers need to override this test')
+
+ def test_arraysize(self):
+ # Not much here - rest of the tests for this are in test_fetchmany
+@@ -786,7 +786,7 @@
+
+ def test_setoutputsize(self):
+ # Real test for setoutputsize is driver dependant
+- raise NotImplementedError,'Driver need to override this test'
++ raise NotImplementedError('Driver need to override this test')
+
+ def test_None(self):
+ con = self._connect()
+diff -ru MySQL-python-1.2.3/tests/test_MySQLdb_capabilities.py MySQL-Python-1.2.3-python3/tests/test_MySQLdb_capabilities.py
+--- MySQL-python-1.2.3/tests/test_MySQLdb_capabilities.py 2010-06-17 09:21:55.000000000 +0200
++++ MySQL-Python-1.2.3-python3/tests/test_MySQLdb_capabilities.py 2011-10-05 12:49:58.000000000 +0200
+@@ -41,8 +41,7 @@
+ db = self.connection
+ c = self.cursor
+ self.create_table(('pos INT', 'tree CHAR(20)'))
+- c.executemany("INSERT INTO %s (pos,tree) VALUES (%%s,%%s)" % self.table,
+- list(enumerate('ash birch cedar larch pine'.split())))
++ c.executemany("INSERT INTO %s (pos,tree) VALUES ({!s},{!s})" % self.table, list(enumerate('ash birch cedar larch pine'.split())) )
+ db.commit()
+
+ c.execute("""
+@@ -77,9 +76,9 @@
+ from MySQLdb.constants import ER
+ try:
+ self.cursor.execute("describe some_non_existent_table");
+- except self.connection.ProgrammingError, msg:
+- self.failUnless(msg[0] == ER.NO_SUCH_TABLE)
+-
++ except self.connection.ProgrammingError as msg:
++ self.assertTrue(msg.code == ER.NO_SUCH_TABLE)
++
+ def test_ping(self):
+ self.connection.ping()
+
+@@ -90,4 +89,4 @@
+ gc.enable()
+ gc.set_debug(gc.DEBUG_LEAK)
+ unittest.main()
+- print '''"Huh-huh, he said 'unit'." -- Butthead'''
++ print ('''"Huh-huh, he said 'unit'." -- Butthead''')
+diff -ru MySQL-python-1.2.3/tests/test_MySQLdb_dbapi20.py MySQL-Python-1.2.3-python3/tests/test_MySQLdb_dbapi20.py
+--- MySQL-python-1.2.3/tests/test_MySQLdb_dbapi20.py 2010-06-17 09:21:55.000000000 +0200
++++ MySQL-Python-1.2.3-python3/tests/test_MySQLdb_dbapi20.py 2011-10-05 12:49:58.000000000 +0200
+@@ -202,4 +202,4 @@
+
+ if __name__ == '__main__':
+ unittest.main()
+- print '''"Huh-huh, he said 'unit'." -- Butthead'''
++ print ('''"Huh-huh, he said 'unit'." -- Butthead''')