This commit is contained in:
INADA Naoki
2015-11-05 03:38:13 +09:00
parent b07937487d
commit 98bec5fb8c
5 changed files with 238 additions and 237 deletions

View File

@ -111,7 +111,7 @@ class BaseCursor(object):
if self._warnings: if self._warnings:
# When there is next result, fetching warnings cause "command # When there is next result, fetching warnings cause "command
# out of sync" error. # out of sync" error.
if self._result.has_next: if self._result and self._result.has_next:
msg = "There are %d MySQL warnings." % (self._warnings,) msg = "There are %d MySQL warnings." % (self._warnings,)
self.messages.append(msg) self.messages.append(msg)
warn(msg, self.Warning, 3) warn(msg, self.Warning, 3)

View File

@ -68,7 +68,7 @@ static PyObject *_mysql_IntegrityError;
static PyObject *_mysql_InternalError; static PyObject *_mysql_InternalError;
static PyObject *_mysql_ProgrammingError; static PyObject *_mysql_ProgrammingError;
static PyObject *_mysql_NotSupportedError; static PyObject *_mysql_NotSupportedError;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
MYSQL connection; MYSQL connection;
@ -227,7 +227,7 @@ _mysql_Exception(_mysql_ConnectionObject *c)
Py_DECREF(t); Py_DECREF(t);
return NULL; return NULL;
} }
static char _mysql_server_init__doc__[] = static char _mysql_server_init__doc__[] =
"Initialize embedded server. If this client is not linked against\n\ "Initialize embedded server. If this client is not linked against\n\
the embedded server library, this function does nothing.\n\ the embedded server library, this function does nothing.\n\
@ -250,7 +250,7 @@ static PyObject *_mysql_server_init(
"already initialized"); "already initialized");
return NULL; return NULL;
} }
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist,
&cmd_args, &groups)) &cmd_args, &groups))
return NULL; return NULL;
@ -349,7 +349,7 @@ static PyObject *_mysql_server_end(
} }
return _mysql_Exception(NULL); return _mysql_Exception(NULL);
} }
#if MYSQL_VERSION_ID >= 32314 #if MYSQL_VERSION_ID >= 32314
static char _mysql_thread_safe__doc__[] = static char _mysql_thread_safe__doc__[] =
"Indicates whether the client is compiled as thread-safe."; "Indicates whether the client is compiled as thread-safe.";
@ -557,7 +557,7 @@ _mysql_ConnectionObject_Initialize(
char *init_command=NULL, char *init_command=NULL,
*read_default_file=NULL, *read_default_file=NULL,
*read_default_group=NULL; *read_default_group=NULL;
self->converter = NULL; self->converter = NULL;
self->open = 0; self->open = 0;
check_server_init(-1); check_server_init(-1);
@ -741,7 +741,7 @@ _mysql_connect(
PyObject *kwargs) PyObject *kwargs)
{ {
_mysql_ConnectionObject *c=NULL; _mysql_ConnectionObject *c=NULL;
c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type); c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type);
if (c == NULL) return NULL; if (c == NULL) return NULL;
if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) { if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) {
@ -1291,7 +1291,7 @@ _mysql_escape_dict(
Py_XDECREF(r); Py_XDECREF(r);
return NULL; return NULL;
} }
static char _mysql_ResultObject_describe__doc__[] = static char _mysql_ResultObject_describe__doc__[] =
"Returns the sequence of 7-tuples required by the DB-API for\n\ "Returns the sequence of 7-tuples required by the DB-API for\n\
the Cursor.description attribute.\n\ the Cursor.description attribute.\n\
@ -1328,7 +1328,7 @@ _mysql_ResultObject_describe(
Py_XDECREF(d); Py_XDECREF(d);
return NULL; return NULL;
} }
static char _mysql_ResultObject_field_flags__doc__[] = static char _mysql_ResultObject_field_flags__doc__[] =
"Returns a tuple of field flags, one for each column in the result.\n\ "Returns a tuple of field flags, one for each column in the result.\n\
" ; " ;
@ -1736,7 +1736,7 @@ _mysql_ConnectionObject_get_character_set_info(
{ {
PyObject *result; PyObject *result;
MY_CHARSET_INFO cs; MY_CHARSET_INFO cs;
if (!PyArg_ParseTuple(args, "")) return NULL; if (!PyArg_ParseTuple(args, "")) return NULL;
check_connection(self); check_connection(self);
mysql_get_character_set_info(&(self->connection), &cs); mysql_get_character_set_info(&(self->connection), &cs);
@ -2726,44 +2726,44 @@ PyTypeObject _mysql_ConnectionObject_Type = {
0, /* tp_setattr */ 0, /* tp_setattr */
0, /*tp_compare*/ 0, /*tp_compare*/
(reprfunc)_mysql_ConnectionObject_repr, /* tp_repr */ (reprfunc)_mysql_ConnectionObject_repr, /* tp_repr */
/* Method suites for standard classes */ /* Method suites for standard classes */
0, /* (PyNumberMethods *) tp_as_number */ 0, /* (PyNumberMethods *) tp_as_number */
0, /* (PySequenceMethods *) tp_as_sequence */ 0, /* (PySequenceMethods *) tp_as_sequence */
0, /* (PyMappingMethods *) tp_as_mapping */ 0, /* (PyMappingMethods *) tp_as_mapping */
/* More standard operations (here for binary compatibility) */ /* More standard operations (here for binary compatibility) */
0, /* (hashfunc) tp_hash */ 0, /* (hashfunc) tp_hash */
0, /* (ternaryfunc) tp_call */ 0, /* (ternaryfunc) tp_call */
0, /* (reprfunc) tp_str */ 0, /* (reprfunc) tp_str */
(getattrofunc)_mysql_ConnectionObject_getattro, /* tp_getattro */ (getattrofunc)_mysql_ConnectionObject_getattro, /* tp_getattro */
(setattrofunc)_mysql_ConnectionObject_setattro, /* tp_setattro */ (setattrofunc)_mysql_ConnectionObject_setattro, /* tp_setattro */
/* Functions to access object as input/output buffer */ /* Functions to access object as input/output buffer */
0, /* (PyBufferProcs *) tp_as_buffer */ 0, /* (PyBufferProcs *) tp_as_buffer */
/* (tp_flags) Flags to define presence of optional/expanded features */ /* (tp_flags) Flags to define presence of optional/expanded features */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
_mysql_connect__doc__, /* (char *) tp_doc Documentation string */ _mysql_connect__doc__, /* (char *) tp_doc Documentation string */
/* call function for all accessible objects */ /* call function for all accessible objects */
(traverseproc) _mysql_ConnectionObject_traverse, /* tp_traverse */ (traverseproc) _mysql_ConnectionObject_traverse, /* tp_traverse */
/* delete references to contained objects */ /* delete references to contained objects */
(inquiry) _mysql_ConnectionObject_clear, /* tp_clear */ (inquiry) _mysql_ConnectionObject_clear, /* tp_clear */
/* rich comparisons */ /* rich comparisons */
0, /* (richcmpfunc) tp_richcompare */ 0, /* (richcmpfunc) tp_richcompare */
/* weak reference enabler */ /* weak reference enabler */
0, /* (long) tp_weaklistoffset */ 0, /* (long) tp_weaklistoffset */
/* Iterators */ /* Iterators */
0, /* (getiterfunc) tp_iter */ 0, /* (getiterfunc) tp_iter */
0, /* (iternextfunc) tp_iternext */ 0, /* (iternextfunc) tp_iternext */
/* Attribute descriptor and subclassing stuff */ /* Attribute descriptor and subclassing stuff */
(struct PyMethodDef *)_mysql_ConnectionObject_methods, /* tp_methods */ (struct PyMethodDef *)_mysql_ConnectionObject_methods, /* tp_methods */
(struct PyMemberDef *)_mysql_ConnectionObject_memberlist, /* tp_members */ (struct PyMemberDef *)_mysql_ConnectionObject_memberlist, /* tp_members */
@ -2798,45 +2798,45 @@ PyTypeObject _mysql_ResultObject_Type = {
0, /* tp_setattr */ 0, /* tp_setattr */
0, /*tp_compare*/ 0, /*tp_compare*/
(reprfunc)_mysql_ResultObject_repr, /* tp_repr */ (reprfunc)_mysql_ResultObject_repr, /* tp_repr */
/* Method suites for standard classes */ /* Method suites for standard classes */
0, /* (PyNumberMethods *) tp_as_number */ 0, /* (PyNumberMethods *) tp_as_number */
0, /* (PySequenceMethods *) tp_as_sequence */ 0, /* (PySequenceMethods *) tp_as_sequence */
0, /* (PyMappingMethods *) tp_as_mapping */ 0, /* (PyMappingMethods *) tp_as_mapping */
/* More standard operations (here for binary compatibility) */ /* More standard operations (here for binary compatibility) */
0, /* (hashfunc) tp_hash */ 0, /* (hashfunc) tp_hash */
0, /* (ternaryfunc) tp_call */ 0, /* (ternaryfunc) tp_call */
0, /* (reprfunc) tp_str */ 0, /* (reprfunc) tp_str */
(getattrofunc)PyObject_GenericGetAttr, /* tp_getattro */ (getattrofunc)PyObject_GenericGetAttr, /* tp_getattro */
(setattrofunc)_mysql_ResultObject_setattro, /* tp_setattr */ (setattrofunc)_mysql_ResultObject_setattro, /* tp_setattr */
/* Functions to access object as input/output buffer */ /* Functions to access object as input/output buffer */
0, /* (PyBufferProcs *) tp_as_buffer */ 0, /* (PyBufferProcs *) tp_as_buffer */
/* Flags to define presence of optional/expanded features */ /* Flags to define presence of optional/expanded features */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
_mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */ _mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */
/* call function for all accessible objects */ /* call function for all accessible objects */
(traverseproc) _mysql_ResultObject_traverse, /* tp_traverse */ (traverseproc) _mysql_ResultObject_traverse, /* tp_traverse */
/* delete references to contained objects */ /* delete references to contained objects */
(inquiry) _mysql_ResultObject_clear, /* tp_clear */ (inquiry) _mysql_ResultObject_clear, /* tp_clear */
/* rich comparisons */ /* rich comparisons */
0, /* (richcmpfunc) tp_richcompare */ 0, /* (richcmpfunc) tp_richcompare */
/* weak reference enabler */ /* weak reference enabler */
0, /* (long) tp_weaklistoffset */ 0, /* (long) tp_weaklistoffset */
/* Iterators */ /* Iterators */
0, /* (getiterfunc) tp_iter */ 0, /* (getiterfunc) tp_iter */
0, /* (iternextfunc) tp_iternext */ 0, /* (iternextfunc) tp_iternext */
/* Attribute descriptor and subclassing stuff */ /* Attribute descriptor and subclassing stuff */
(struct PyMethodDef *) _mysql_ResultObject_methods, /* tp_methods */ (struct PyMethodDef *) _mysql_ResultObject_methods, /* tp_methods */
(struct PyMemberDef *) _mysql_ResultObject_memberlist, /*tp_members */ (struct PyMemberDef *) _mysql_ResultObject_memberlist, /*tp_members */

View File

@ -10,16 +10,15 @@ connect_kwargs = dict(
read_default_group = "MySQLdb-tests", read_default_group = "MySQLdb-tests",
) )
def connection_kwargs(kwargs): def connection_kwargs(kwargs):
db_kwargs = connect_kwargs.copy() db_kwargs = connect_kwargs.copy()
db_kwargs.update(kwargs) db_kwargs.update(kwargs)
return db_kwargs return db_kwargs
def connection_factory(**kwargs): def connection_factory(**kwargs):
import MySQLdb import MySQLdb
db_kwargs = connection_kwargs(kwargs) db_kwargs = connection_kwargs(kwargs)
db = MySQLdb.connect(**db_kwargs) db = MySQLdb.connect(**db_kwargs)
return db return db

View File

@ -1,204 +1,205 @@
#!/usr/bin/env python #!/usr/bin/env python
import dbapi20 import dbapi20
import unittest import unittest
import MySQLdb import MySQLdb
from configdb import connection_kwargs from configdb import connection_kwargs
import warnings import warnings
warnings.simplefilter("ignore") warnings.simplefilter("ignore")
class test_MySQLdb(dbapi20.DatabaseAPI20Test):
driver = MySQLdb class test_MySQLdb(dbapi20.DatabaseAPI20Test):
connect_args = () driver = MySQLdb
connect_kw_args = connection_kwargs(dict(sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL")) connect_args = ()
connect_kw_args = connection_kwargs(dict(sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL"))
def test_setoutputsize(self): pass
def test_setoutputsize_basic(self): pass def test_setoutputsize(self): pass
def test_nextset(self): pass def test_setoutputsize_basic(self): pass
def test_nextset(self): pass
"""The tests on fetchone and fetchall and rowcount bogusly
test for an exception if the statement cannot return a """The tests on fetchone and fetchall and rowcount bogusly
result set. MySQL always returns a result set; it's just that test for an exception if the statement cannot return a
some things return empty result sets.""" result set. MySQL always returns a result set; it's just that
some things return empty result sets."""
def test_fetchall(self):
con = self._connect() def test_fetchall(self):
try: con = self._connect()
cur = con.cursor() try:
# cursor.fetchall should raise an Error if called cur = con.cursor()
# without executing a query that may return rows (such # cursor.fetchall should raise an Error if called
# as a select) # without executing a query that may return rows (such
self.assertRaises(self.driver.Error, cur.fetchall) # as a select)
self.assertRaises(self.driver.Error, cur.fetchall)
self.executeDDL1(cur)
for sql in self._populate(): self.executeDDL1(cur)
cur.execute(sql) for sql in self._populate():
cur.execute(sql)
# cursor.fetchall should raise an Error if called
# after executing a a statement that cannot return rows # cursor.fetchall should raise an Error if called
## self.assertRaises(self.driver.Error,cur.fetchall) # after executing a a statement that cannot return rows
#self.assertRaises(self.driver.Error,cur.fetchall)
cur.execute('select name from %sbooze' % self.table_prefix)
rows = cur.fetchall() cur.execute('select name from %sbooze' % self.table_prefix)
self.assertTrue(cur.rowcount in (-1,len(self.samples))) rows = cur.fetchall()
self.assertEqual(len(rows),len(self.samples), self.assertTrue(cur.rowcount in (-1,len(self.samples)))
'cursor.fetchall did not retrieve all rows' self.assertEqual(len(rows),len(self.samples),
) 'cursor.fetchall did not retrieve all rows'
rows = [r[0] for r in rows] )
rows.sort() rows = [r[0] for r in rows]
for i in range(0,len(self.samples)): rows.sort()
self.assertEqual(rows[i],self.samples[i], for i in range(0,len(self.samples)):
'cursor.fetchall retrieved incorrect rows' self.assertEqual(rows[i],self.samples[i],
) 'cursor.fetchall retrieved incorrect rows'
rows = cur.fetchall() )
self.assertEqual( rows = cur.fetchall()
len(rows),0, self.assertEqual(
'cursor.fetchall should return an empty list if called ' len(rows),0,
'after the whole result set has been fetched' 'cursor.fetchall should return an empty list if called '
) 'after the whole result set has been fetched'
self.assertTrue(cur.rowcount in (-1,len(self.samples))) )
self.assertTrue(cur.rowcount in (-1,len(self.samples)))
self.executeDDL2(cur)
cur.execute('select name from %sbarflys' % self.table_prefix) self.executeDDL2(cur)
rows = cur.fetchall() cur.execute('select name from %sbarflys' % self.table_prefix)
self.assertTrue(cur.rowcount in (-1,0)) rows = cur.fetchall()
self.assertEqual(len(rows),0, self.assertTrue(cur.rowcount in (-1,0))
'cursor.fetchall should return an empty list if ' self.assertEqual(len(rows),0,
'a select query returns no rows' 'cursor.fetchall should return an empty list if '
) 'a select query returns no rows'
)
finally:
con.close() finally:
con.close()
def test_fetchone(self):
con = self._connect() def test_fetchone(self):
try: con = self._connect()
cur = con.cursor() try:
cur = con.cursor()
# cursor.fetchone should raise an Error if called before
# executing a select-type query # cursor.fetchone should raise an Error if called before
self.assertRaises(self.driver.Error,cur.fetchone) # executing a select-type query
self.assertRaises(self.driver.Error,cur.fetchone)
# cursor.fetchone should raise an Error if called after
# executing a query that cannnot return rows # cursor.fetchone should raise an Error if called after
self.executeDDL1(cur) # executing a query that cannnot return rows
## self.assertRaises(self.driver.Error,cur.fetchone) self.executeDDL1(cur)
## self.assertRaises(self.driver.Error,cur.fetchone)
cur.execute('select name from %sbooze' % self.table_prefix)
self.assertEqual(cur.fetchone(),None, cur.execute('select name from %sbooze' % self.table_prefix)
'cursor.fetchone should return None if a query retrieves ' self.assertEqual(cur.fetchone(),None,
'no rows' 'cursor.fetchone should return None if a query retrieves '
) 'no rows'
self.assertTrue(cur.rowcount in (-1,0)) )
self.assertTrue(cur.rowcount in (-1,0))
# cursor.fetchone should raise an Error if called after
# executing a query that cannnot return rows # cursor.fetchone should raise an Error if called after
cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( # executing a query that cannnot return rows
self.table_prefix cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
)) self.table_prefix
## self.assertRaises(self.driver.Error,cur.fetchone) ))
## self.assertRaises(self.driver.Error,cur.fetchone)
cur.execute('select name from %sbooze' % self.table_prefix)
r = cur.fetchone() cur.execute('select name from %sbooze' % self.table_prefix)
self.assertEqual(len(r),1, r = cur.fetchone()
'cursor.fetchone should have retrieved a single row' self.assertEqual(len(r),1,
) 'cursor.fetchone should have retrieved a single row'
self.assertEqual(r[0],'Victoria Bitter', )
'cursor.fetchone retrieved incorrect data' self.assertEqual(r[0],'Victoria Bitter',
) 'cursor.fetchone retrieved incorrect data'
## self.assertEqual(cur.fetchone(),None, )
## 'cursor.fetchone should return None if no more rows available' ## self.assertEqual(cur.fetchone(),None,
## ) ## 'cursor.fetchone should return None if no more rows available'
self.assertTrue(cur.rowcount in (-1,1)) ## )
finally: self.assertTrue(cur.rowcount in (-1,1))
con.close() finally:
con.close()
# Same complaint as for fetchall and fetchone
def test_rowcount(self): # Same complaint as for fetchall and fetchone
con = self._connect() def test_rowcount(self):
try: con = self._connect()
cur = con.cursor() try:
self.executeDDL1(cur) cur = con.cursor()
## self.assertEqual(cur.rowcount,-1, self.executeDDL1(cur)
## 'cursor.rowcount should be -1 after executing no-result ' ## self.assertEqual(cur.rowcount,-1,
## 'statements' ## 'cursor.rowcount should be -1 after executing no-result '
## ) ## 'statements'
cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( ## )
self.table_prefix cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
)) self.table_prefix
## self.assertTrue(cur.rowcount in (-1,1), ))
## 'cursor.rowcount should == number or rows inserted, or ' ## self.assertTrue(cur.rowcount in (-1,1),
## 'set to -1 after executing an insert statement' ## 'cursor.rowcount should == number or rows inserted, or '
## ) ## 'set to -1 after executing an insert statement'
cur.execute("select name from %sbooze" % self.table_prefix) ## )
self.assertTrue(cur.rowcount in (-1,1), cur.execute("select name from %sbooze" % self.table_prefix)
'cursor.rowcount should == number of rows returned, or ' self.assertTrue(cur.rowcount in (-1,1),
'set to -1 after executing a select statement' 'cursor.rowcount should == number of rows returned, or '
) 'set to -1 after executing a select statement'
self.executeDDL2(cur) )
## self.assertEqual(cur.rowcount,-1, self.executeDDL2(cur)
## 'cursor.rowcount not being reset to -1 after executing ' ## self.assertEqual(cur.rowcount,-1,
## 'no-result statements' ## 'cursor.rowcount not being reset to -1 after executing '
## ) ## 'no-result statements'
finally: ## )
con.close() finally:
con.close()
def test_callproc(self):
pass # performed in test_MySQL_capabilities def test_callproc(self):
pass # performed in test_MySQL_capabilities
def help_nextset_setUp(self,cur):
''' Should create a procedure called deleteme def help_nextset_setUp(self,cur):
that returns two result sets, first the ''' Should create a procedure called deleteme
number of rows in booze then "name from booze" that returns two result sets, first the
''' number of rows in booze then "name from booze"
sql=""" '''
create procedure deleteme() sql="""
begin create procedure deleteme()
select count(*) from %(tp)sbooze; begin
select name from %(tp)sbooze; select count(*) from %(tp)sbooze;
end select name from %(tp)sbooze;
""" % dict(tp=self.table_prefix) end
cur.execute(sql) """ % dict(tp=self.table_prefix)
cur.execute(sql)
def help_nextset_tearDown(self,cur):
'If cleaning up is needed after nextSetTest' def help_nextset_tearDown(self,cur):
cur.execute("drop procedure deleteme") 'If cleaning up is needed after nextSetTest'
cur.execute("drop procedure deleteme")
def test_nextset(self):
from warnings import warn def test_nextset(self):
con = self._connect() #from warnings import warn
try: con = self._connect()
cur = con.cursor() try:
if not hasattr(cur,'nextset'): cur = con.cursor()
return if not hasattr(cur, 'nextset'):
return
try:
self.executeDDL1(cur) try:
sql=self._populate() self.executeDDL1(cur)
for sql in self._populate(): sql=self._populate()
cur.execute(sql) for sql in self._populate():
cur.execute(sql)
self.help_nextset_setUp(cur)
self.help_nextset_setUp(cur)
cur.callproc('deleteme')
numberofrows=cur.fetchone() cur.callproc('deleteme')
assert numberofrows[0]== len(self.samples) numberofrows=cur.fetchone()
assert cur.nextset() assert numberofrows[0]== len(self.samples)
names=cur.fetchall() assert cur.nextset()
assert len(names) == len(self.samples) names=cur.fetchall()
s=cur.nextset() assert len(names) == len(self.samples)
if s: s=cur.nextset()
empty = cur.fetchall() if s:
self.assertEquals(len(empty), 0, empty = cur.fetchall()
"non-empty result set after other result sets") self.assertEquals(len(empty), 0,
#warn("Incompatibility: MySQL returns an empty result set for the CALL itself", "non-empty result set after other result sets")
# Warning) #warn("Incompatibility: MySQL returns an empty result set for the CALL itself",
#assert s == None,'No more return sets, should return None' # Warning)
finally: #assert s == None,'No more return sets, should return None'
self.help_nextset_tearDown(cur) finally:
self.help_nextset_tearDown(cur)
finally:
con.close() finally:
con.close()
if __name__ == '__main__':
unittest.main() if __name__ == '__main__':
unittest.main()

View File

@ -7,6 +7,7 @@ from configdb import connection_factory
import warnings import warnings
warnings.simplefilter("ignore") warnings.simplefilter("ignore")
class TestDBAPISet(unittest.TestCase): class TestDBAPISet(unittest.TestCase):
def test_set_equality(self): def test_set_equality(self):
self.assertTrue(MySQLdb.STRING == MySQLdb.STRING) self.assertTrue(MySQLdb.STRING == MySQLdb.STRING)
@ -21,7 +22,7 @@ class TestDBAPISet(unittest.TestCase):
self.assertTrue(FIELD_TYPE.DATE != MySQLdb.STRING) self.assertTrue(FIELD_TYPE.DATE != MySQLdb.STRING)
class CoreModule(unittest.TestCase): class TestCoreModule(unittest.TestCase):
"""Core _mysql module features.""" """Core _mysql module features."""
def test_NULL(self): def test_NULL(self):