MySQLdb1
MySQLdb1 copied to clipboard
Installable under Python 3.3
This are some fixes that should make it possible to at least install this projekt under Python 3.3. Running the tests under Python 3.3 fails with an segmentation fault.
:+1:
This passes for me on py26 and py27 and crashes with a segfault on py33, as you said.
$ tox -e py26,py27,py33
...
py26: commands succeeded
py27: commands succeeded
ERROR: py33: commands failed
$ .tox/py33/bin/nosetests -w tests -v
test_BLOB (test_MySQLdb_capabilities.test_MySQLdb) ... [4] 309 segmentation fault .tox/py33/bin/nosetests -w tests -v
I have some minor suggestions, but otherwise this is good to merge I think.
Trying to figure out what's wrong by looking at core dump. In case this is useful for someone with more knowledge of CPython and more recent experience with C:
$ ulimit -c unlimited
$ .tox/py33/bin/nosetests -w tests -v
test_BLOB (test_MySQLdb_capabilities.test_MySQLdb) ... [4] 1578 segmentation fault (core dumped) .tox/py33/bin/nosetests -w tests -v
$ lldb -c /cores/core.939
error: core.939 is a corrupt mach-o file: load command 185 LC_SEGMENT_64 has a fileoff + filesize (0x17e56000) that extends beyond the end of the file (0x17e55000), the segment will be truncated
error: core.939 is a corrupt mach-o file: load command 186 LC_SEGMENT_64 has a fileoff (0x17e56000) that extends beyond the end of the file (0x17e55000)
Core file '/cores/core.939' (x86_64) was loaded.
Process 0 stopped
* thread #1: tid = 0x0000, 0x00000001000639ec Python`PyObject_Malloc + 92, stop reason = signal SIGSTOP
frame #0: 0x00000001000639ec Python`PyObject_Malloc + 92
Python`PyObject_Malloc + 92:
-> 0x1000639ec: movq (%rsi), %rax
0x1000639ef: movq %rax, 8(%rcx)
0x1000639f3: movq %rsi, %rdx
0x1000639f6: testq %rax, %rax
(lldb) bt 10
* thread #1: tid = 0x0000, 0x00000001000639ec Python`PyObject_Malloc + 92, stop reason = signal SIGSTOP
frame #0: 0x00000001000639ec Python`PyObject_Malloc + 92
frame #1: 0x000000010008396f Python`PyUnicode_New + 175
frame #2: 0x000000010009af5d Python`_PyUnicode_FromASCII + 109
frame #3: 0x000000010015b22e Python`_textiowrapper_readline + 1678
frame #4: 0x000000010015b3ac Python`textiowrapper_iternext + 236
frame #5: 0x0000000100042997 Python`listextend + 199
frame #6: 0x000000010000d5a8 Python`PyObject_Call + 104
frame #7: 0x000000010000dca6 Python`callmethod + 134
frame #8: 0x000000010000f217 Python`_PyObject_CallMethodId_SizeT + 183
frame #9: 0x000000010014e2f9 Python`iobase_readlines + 233
diff --git a/MySQLdb/connections.py b/MySQLdb/connections.py
index 13e55c4..6c7c03a 100644
--- a/MySQLdb/connections.py
+++ b/MySQLdb/connections.py
@@ -10,8 +10,12 @@
from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
DatabaseError, OperationalError, IntegrityError, InternalError, \
NotSupportedError, ProgrammingError
-import types, _mysql
+import _mysql
import re
+import sys
+
+if sys.version_info[0] == 3:
+ unicode = str
def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
@@ -233,8 +237,8 @@ def string_decoder(s):
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[bytes] = string_literal
+ self.encoders[unicode] = unicode_literal
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
if self._transactional:
if autocommit is not None:
diff --git a/MySQLdb/cursors.py b/MySQLdb/cursors.py
index b45ddaf..4c884a3 100644
--- a/MySQLdb/cursors.py
+++ b/MySQLdb/cursors.py
@@ -7,15 +7,11 @@
import re
import sys
-try:
- from types import ListType, TupleType, UnicodeType
-except ImportError:
- # Python 3
- ListType = list
- TupleType = tuple
- UnicodeType = str
-
-restr = r"""
+
+if sys.version_info[0] == 3:
+ unicode = str
+
+restr = rb"""
\s
values
\s*
@@ -305,7 +301,7 @@ def callproc(self, procname, args=()):
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 unicode:
q = q.encode(db.unicode_literal.charset)
self._query(q)
self._executed = q
diff --git a/tests/capabilities.py b/tests/capabilities.py
index 076361c..e1760a7 100644
--- a/tests/capabilities.py
+++ b/tests/capabilities.py
@@ -9,7 +9,10 @@
import array
import unittest
from configdb import connection_factory
+import sys
+if sys.version_info[0] == 3:
+ unichr = chr
class DatabaseTest(unittest.TestCase):
@msabramo I've fixed one memory corruption on #61. Could you try it?
@methane: #61 seemed to stop the segfault on Python 3.3 but it segfaults on Python 2.6 and 2.7 -- both locally and on Travis CI: https://travis-ci.org/farcepest/MySQLdb1/builds/23126432
I made the changes suggested by @msabramo regarding the use of SafeConfigParser from setup_common.py
.