Skip to content

Commit ad9e7dc

Browse files
committed
Port to Python 3.1
1 parent b372acc commit ad9e7dc

17 files changed

+461
-528
lines changed

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# git-ls-files --others --exclude-from=.git/info/exclude
2+
# Lines that start with '#' are comments.
3+
# For a project mostly in C, the following would be a good set of
4+
# exclude patterns (uncomment them if you want to use them):
5+
# *.[oa]
6+
# *~
7+
*.pyc
8+
*.pyo
9+
*~
10+
11+
.cvsignore
12+
.project
13+
.pydevproject
14+
15+
#profiling/outputs
16+
*.log
17+
dist
18+
build
19+
regress.py
20+
test.py
21+
PKG-INFO

MySQLdb/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"""
1515

1616
__revision__ = """$Revision: 603 $"""[11:-2]
17-
from release import __version__, version_info, __author__
17+
from .release import __version__, version_info, __author__
1818

1919
import _mysql
2020

@@ -77,7 +77,7 @@ def Binary(x):
7777

7878
def Connect(*args, **kwargs):
7979
"""Factory function for connections.Connection."""
80-
from connections import Connection
80+
from .connections import Connection
8181
return Connection(*args, **kwargs)
8282

8383
connect = Connection = Connect

MySQLdb/connections.py

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
override Connection.default_cursor with a non-standard Cursor class.
77
88
"""
9-
import cursors
9+
import MySQLdb.cursors
1010
from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
1111
DatabaseError, OperationalError, IntegrityError, InternalError, \
1212
NotSupportedError, ProgrammingError
@@ -33,7 +33,7 @@ def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
3333
connection.messages.append(error)
3434
del cursor
3535
del connection
36-
raise errorclass, errorvalue
36+
raise errorclass(errorvalue)
3737

3838
re_numeric_part = re.compile(r"^(\d+)")
3939

@@ -57,7 +57,7 @@ class Connection(_mysql.connection):
5757

5858
"""MySQL Database Connection Object"""
5959

60-
default_cursor = cursors.Cursor
60+
default_cursor = MySQLdb.cursors.Cursor
6161

6262
def __init__(self, *args, **kwargs):
6363
"""
@@ -109,17 +109,9 @@ def __init__(self, *args, **kwargs):
109109
cursorclass
110110
class object, used to create cursors (keyword only)
111111
112-
use_unicode
113-
If True, text-like columns are returned as unicode objects
114-
using the connection's character set. Otherwise, text-like
115-
columns are returned as strings. columns are returned as
116-
normal strings. Unicode objects will always be encoded to
117-
the connection's character set regardless of this setting.
118-
119112
charset
120113
If supplied, the connection character set will be changed
121-
to this character set (MySQL-4.1 and newer). This implies
122-
use_unicode=True.
114+
to this character set (MySQL-4.1 and newer).
123115
124116
sql_mode
125117
If supplied, the session SQL mode will be changed to this
@@ -143,15 +135,15 @@ class object, used to create cursors (keyword only)
143135
documentation for the MySQL C API for some hints on what they do.
144136
145137
"""
146-
from constants import CLIENT, FIELD_TYPE
147-
from converters import conversions
138+
from .constants import CLIENT, FIELD_TYPE
139+
from .converters import conversions
148140
from weakref import proxy, WeakValueDictionary
149141

150142
import types
151143

152144
kwargs2 = kwargs.copy()
153145

154-
if kwargs.has_key('conv'):
146+
if 'conv' in kwargs:
155147
conv = kwargs['conv']
156148
else:
157149
conv = conversions
@@ -165,14 +157,8 @@ class object, used to create cursors (keyword only)
165157
kwargs2['conv'] = conv2
166158

167159
self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
168-
charset = kwargs2.pop('charset', '')
160+
charset = kwargs2.pop('charset', 'utf8')
169161

170-
if charset:
171-
use_unicode = True
172-
else:
173-
use_unicode = False
174-
175-
use_unicode = kwargs2.pop('use_unicode', use_unicode)
176162
sql_mode = kwargs2.pop('sql_mode', '')
177163

178164
client_flag = kwargs.get('client_flag', 0)
@@ -197,34 +183,23 @@ def string_literal(obj, dummy=None):
197183
return db.string_literal(obj)
198184
return string_literal
199185

200-
def _get_unicode_literal():
201-
def unicode_literal(u, dummy=None):
202-
return db.literal(u.encode(unicode_literal.charset))
203-
return unicode_literal
204-
205-
def _get_string_decoder():
206-
def string_decoder(s):
207-
return s.decode(string_decoder.charset)
208-
return string_decoder
209-
186+
def _get_bytes_literal():
187+
def bytes_literal(u, dummy=None):
188+
return db.literal(u.decode(bytes_literal.charset))
189+
return bytes_literal
190+
210191
string_literal = _get_string_literal()
211-
self.unicode_literal = unicode_literal = _get_unicode_literal()
212-
self.string_decoder = string_decoder = _get_string_decoder()
192+
self.bytes_literal = bytes_literal = _get_bytes_literal()
213193
if not charset:
214194
charset = self.character_set_name()
215195
self.set_character_set(charset)
216196

217197
if sql_mode:
218198
self.set_sql_mode(sql_mode)
219199

220-
if use_unicode:
221-
self.converter[FIELD_TYPE.STRING].append((None, string_decoder))
222-
self.converter[FIELD_TYPE.VAR_STRING].append((None, string_decoder))
223-
self.converter[FIELD_TYPE.VARCHAR].append((None, string_decoder))
224-
self.converter[FIELD_TYPE.BLOB].append((None, string_decoder))
225-
226-
self.encoders[types.StringType] = string_literal
227-
self.encoders[types.UnicodeType] = unicode_literal
200+
self.encoders[str] = string_literal
201+
self.encoders[bytes] = bytes_literal
202+
228203
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
229204
if self._transactional:
230205
# PEP-249 requires autocommit to be initially off
@@ -295,17 +270,16 @@ def set_character_set(self, charset):
295270
except AttributeError:
296271
if self._server_version < (4, 1):
297272
raise NotSupportedError("server is too old to set charset")
298-
self.query('SET NAMES %s' % charset)
273+
self.query('SET NAMES {!s}'.format(charset))
299274
self.store_result()
300-
self.string_decoder.charset = charset
301-
self.unicode_literal.charset = charset
275+
self.bytes_literal.charset = charset
302276

303277
def set_sql_mode(self, sql_mode):
304278
"""Set the connection sql_mode. See MySQL documentation for
305279
legal values."""
306280
if self._server_version < (4, 1):
307281
raise NotSupportedError("server is too old to set sql_mode")
308-
self.query("SET SESSION sql_mode='%s'" % sql_mode)
282+
self.query("SET SESSION sql_mode='{!s}'".format(sql_mode))
309283
self.store_result()
310284

311285
def show_warnings(self):

MySQLdb/converters.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
"""
3434

3535
from _mysql import string_literal, escape_sequence, escape_dict, escape, NULL
36-
from constants import FIELD_TYPE, FLAG
37-
from times import *
38-
import types
36+
from .constants import FIELD_TYPE, FLAG
37+
from .times import *
38+
import datetime
3939
import array
4040

4141
try:
@@ -55,16 +55,16 @@ def Thing2Str(s, d):
5555
"""Convert something into a string via str()."""
5656
return str(s)
5757

58-
def Unicode2Str(s, d):
59-
"""Convert a unicode object to a string using the default encoding.
58+
def Bytes2Str(s, d):
59+
"""Convert a bytes object to a string using the default encoding.
6060
This is only used as a placeholder for the real function, which
6161
is connection-dependent."""
62-
return s.encode()
62+
return s.decode()
6363

6464
Long2Int = Thing2Str
6565

6666
def Float2Str(o, d):
67-
return '%.15g' % o
67+
return '%.15g'.format(o)
6868

6969
def None2NULL(o, d):
7070
"""Convert None to NULL."""
@@ -115,30 +115,30 @@ def array2Str(o, d):
115115
return Thing2Literal(o.tostring(), d)
116116

117117
conversions = {
118-
types.IntType: Thing2Str,
119-
types.LongType: Long2Int,
120-
types.FloatType: Float2Str,
121-
types.NoneType: None2NULL,
122-
types.TupleType: escape_sequence,
123-
types.ListType: escape_sequence,
124-
types.DictType: escape_dict,
125-
types.InstanceType: Instance2Str,
118+
int: Long2Int,
119+
float: Float2Str,
120+
type(None): None2NULL,
121+
tuple: escape_sequence,
122+
list: escape_sequence,
123+
dict: escape_dict,
124+
object: Instance2Str,
126125
array.ArrayType: array2Str,
127-
types.StringType: Thing2Literal, # default
128-
types.UnicodeType: Unicode2Str,
129-
types.ObjectType: Instance2Str,
130-
types.BooleanType: Bool2Str,
131-
DateTimeType: DateTime2literal,
132-
DateTimeDeltaType: DateTimeDelta2literal,
126+
str: Thing2Literal, # default
127+
bytes: Bytes2Str,
128+
bool: Bool2Str,
129+
datetime.date: DateTime2literal,
130+
datetime.time: DateTime2literal,
131+
datetime.datetime: DateTime2literal,
132+
datetime.timedelta: DateTimeDelta2literal,
133133
set: Set2Str,
134134
FIELD_TYPE.TINY: int,
135135
FIELD_TYPE.SHORT: int,
136-
FIELD_TYPE.LONG: long,
136+
FIELD_TYPE.LONG: int,
137137
FIELD_TYPE.FLOAT: float,
138138
FIELD_TYPE.DOUBLE: float,
139139
FIELD_TYPE.DECIMAL: float,
140140
FIELD_TYPE.NEWDECIMAL: float,
141-
FIELD_TYPE.LONGLONG: long,
141+
FIELD_TYPE.LONGLONG: int,
142142
FIELD_TYPE.INT24: int,
143143
FIELD_TYPE.YEAR: int,
144144
FIELD_TYPE.SET: Str2Set,

MySQLdb/cursors.py

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import re
99
import sys
10-
from types import ListType, TupleType, UnicodeType
1110

1211

1312
restr = (r"\svalues\s*"
@@ -153,13 +152,24 @@ def execute(self, query, args=None):
153152
del self.messages[:]
154153
db = self._get_db()
155154
charset = db.character_set_name()
156-
if isinstance(query, unicode):
157-
query = query.encode(charset)
155+
158156
if args is not None:
159-
query = query % db.literal(args)
157+
if isinstance(query, bytes):
158+
query = query.decode();
159+
160+
if isinstance(args, dict):
161+
query = query.format( **db.literal(args) )
162+
elif isinstance(args, tuple) or isinstance(args, list):
163+
query = query.format( *db.literal(args) )
164+
else:
165+
query = query.format( db.literal(args) )
166+
167+
if isinstance(query, str):
168+
query = query.encode(charset);
169+
160170
try:
161171
r = self._query(query)
162-
except TypeError, m:
172+
except TypeError as m:
163173
if m.args[0] in ("not enough arguments for format string",
164174
"not all arguments converted"):
165175
self.messages.append((ProgrammingError, m.args[0]))
@@ -197,8 +207,6 @@ def executemany(self, query, args):
197207
del self.messages[:]
198208
db = self._get_db()
199209
if not args: return
200-
charset = db.character_set_name()
201-
if isinstance(query, unicode): query = query.encode(charset)
202210
m = insert_values.search(query)
203211
if not m:
204212
r = 0
@@ -209,8 +217,16 @@ def executemany(self, query, args):
209217
e = m.end(1)
210218
qv = m.group(1)
211219
try:
212-
q = [ qv % db.literal(a) for a in args ]
213-
except TypeError, msg:
220+
q = []
221+
for a in args:
222+
if isinstance(a, dict):
223+
data = qv.format(**db.literal(a))
224+
elif isinstance(a, tuple) or isinstance(a, list):
225+
data = qv.format( *db.literal(a) )
226+
else:
227+
data = qv.format( db.literal(a) )
228+
q.append( data )
229+
except TypeError as msg:
214230
if msg.args[0] in ("not enough arguments for format string",
215231
"not all arguments converted"):
216232
self.errorhandler(self, ProgrammingError, msg.args[0])
@@ -220,7 +236,7 @@ def executemany(self, query, args):
220236
exc, value, tb = sys.exc_info()
221237
del tb
222238
self.errorhandler(self, exc, value)
223-
r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]]))
239+
r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]]));
224240
if not self._defer_warnings: self._warning_check()
225241
return r
226242

@@ -257,17 +273,15 @@ def callproc(self, procname, args=()):
257273
db = self._get_db()
258274
charset = db.character_set_name()
259275
for index, arg in enumerate(args):
260-
q = "SET @_%s_%d=%s" % (procname, index,
261-
db.literal(arg))
262-
if isinstance(q, unicode):
276+
q = "SET @_{!s}_{:d}={!s}".format(procname, index, db.literal(arg))
277+
if isinstance(q, str):
263278
q = q.encode(charset)
264279
self._query(q)
265280
self.nextset()
266281

267-
q = "CALL %s(%s)" % (procname,
268-
','.join(['@_%s_%d' % (procname, i)
282+
q = "CALL {!s}({!s})".format(procname, ','.join(['@_{!s}_{:d}'.format(procname, i)
269283
for i in range(len(args))]))
270-
if type(q) is UnicodeType:
284+
if type(q) is str:
271285
q = q.encode(charset)
272286
self._query(q)
273287
self._executed = q
@@ -276,7 +290,7 @@ def callproc(self, procname, args=()):
276290

277291
def _do_query(self, q):
278292
db = self._get_db()
279-
self._last_executed = q
293+
self._last_executed = q;
280294
db.query(q)
281295
self._do_get_result()
282296
return self.rowcount
@@ -363,7 +377,7 @@ def scroll(self, value, mode='relative'):
363377
r = value
364378
else:
365379
self.errorhandler(self, ProgrammingError,
366-
"unknown scroll mode %s" % `mode`)
380+
"unknown scroll mode %s" % mode)
367381
if r < 0 or r >= len(self._rows):
368382
self.errorhandler(self, IndexError, "out of range")
369383
self.rownumber = r

0 commit comments

Comments
 (0)