From 382fb9f9b3453f579f7bb59af46f127405635945 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Thu, 17 Apr 2014 22:24:46 +0900 Subject: [PATCH] Random fixes. --- MySQLdb/__init__.py | 2 +- MySQLdb/converters.py | 52 ++++++++++++------------------------------- MySQLdb/cursors.py | 43 ++++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/MySQLdb/__init__.py b/MySQLdb/__init__.py index 8761671..fc41481 100644 --- a/MySQLdb/__init__.py +++ b/MySQLdb/__init__.py @@ -73,7 +73,7 @@ def test_DBAPISet_set_inequality_membership(): assert FIELD_TYPE.DATE != STRING def Binary(x): - return str(x) + return bytes(x) def Connect(*args, **kwargs): """Factory function for connections.Connection.""" diff --git a/MySQLdb/converters.py b/MySQLdb/converters.py index 26c1f90..7f6bfb7 100644 --- a/MySQLdb/converters.py +++ b/MySQLdb/converters.py @@ -38,13 +38,15 @@ from MySQLdb.times import * try: from types import IntType, LongType, FloatType, NoneType, TupleType, ListType, DictType, InstanceType, \ - StringType, UnicodeType, ObjectType, BooleanType, ClassType, TypeType + ObjectType, BooleanType + PY2 = True except ImportError: # Python 3 long = int IntType, LongType, FloatType, NoneType = int, long, float, type(None) TupleType, ListType, DictType, InstanceType = tuple, list, dict, None - StringType, UnicodeType, ObjectType, BooleanType = bytes, str, object, bool + ObjectType, BooleanType = object, bool + PY2 = False import array @@ -95,34 +97,6 @@ def Thing2Literal(o, d): return string_literal(o, d) -def Instance2Str(o, d): - - """ - - Convert an Instance to a string representation. If the __str__() - method produces acceptable output, then you don't need to add the - class to conversions; it will be handled by the default - converter. If the exact class is not found in d, it will use the - first class it can find for which o is an instance. - - """ - - if o.__class__ in d: - return d[o.__class__](o, d) - cl = filter(lambda x,o=o: - type(x) is ClassType - and isinstance(o, x), d.keys()) - if not cl: - cl = filter(lambda x,o=o: - type(x) is TypeType - and isinstance(o, x) - and d[x] is not Instance2Str, - d.keys()) - if not cl: - return d[StringType](o,d) - d[o.__class__] = d[cl[0]] - return d[cl[0]](o, d) - def char_array(s): return array.array('c', s) @@ -140,14 +114,12 @@ conversions = { TupleType: quote_tuple, ListType: quote_tuple, DictType: escape_dict, - InstanceType: Instance2Str, ArrayType: array2Str, - StringType: Thing2Literal, # default - UnicodeType: Unicode2Str, - ObjectType: Instance2Str, BooleanType: Bool2Str, + Date: Thing2Literal, DateTimeType: DateTime2literal, DateTimeDeltaType: DateTimeDelta2literal, + str: str, # default set: Set2Str, FIELD_TYPE.TINY: int, FIELD_TYPE.SHORT: int, @@ -165,18 +137,22 @@ conversions = { FIELD_TYPE.TIME: TimeDelta_or_None, FIELD_TYPE.DATE: Date_or_None, FIELD_TYPE.BLOB: [ - (FLAG.BINARY, str), + (FLAG.BINARY, bytes), ], FIELD_TYPE.STRING: [ - (FLAG.BINARY, str), + (FLAG.BINARY, bytes), ], FIELD_TYPE.VAR_STRING: [ - (FLAG.BINARY, str), + (FLAG.BINARY, bytes), ], FIELD_TYPE.VARCHAR: [ - (FLAG.BINARY, str), + (FLAG.BINARY, bytes), ], } +if PY2: + conversions[unicode] = Unicode2Str +else: + conversions[bytes] = bytes try: from decimal import Decimal diff --git a/MySQLdb/cursors.py b/MySQLdb/cursors.py index c19f256..f63cbee 100644 --- a/MySQLdb/cursors.py +++ b/MySQLdb/cursors.py @@ -7,10 +7,11 @@ default, MySQLdb uses the Cursor class. import re import sys +PY2 = sys.version_info[0] == 2 from MySQLdb.compat import unicode -restr = r""" +restr = br""" \s values \s* @@ -68,9 +69,9 @@ class BaseCursor(object): _defer_warnings = False def __init__(self, connection): - from weakref import proxy + from weakref import ref - self.connection = proxy(connection) + self.connection = ref(connection) self.description = None self.description_flags = None self.rowcount = -1 @@ -91,7 +92,8 @@ class BaseCursor(object): def close(self): """Close the cursor. No further queries will be possible.""" - if not self.connection: return + if self.connection is None or self.connection() is None: + return while self.nextset(): pass self.connection = None @@ -152,9 +154,12 @@ class BaseCursor(object): """Does nothing, required by DB API.""" def _get_db(self): - if not self.connection: + con = self.connection + if con is not None: + con = con() + if con is None: self.errorhandler(self, ProgrammingError, "cursor closed") - return self.connection + return con def execute(self, query, args=None): @@ -172,14 +177,32 @@ class BaseCursor(object): """ del self.messages[:] db = self._get_db() - if isinstance(query, unicode): + if PY2 and isinstance(query, unicode): query = query.encode(db.unicode_literal.charset) + else: + def decode(x): + if isinstance(x, bytes): + x = x.decode('ascii', 'surrogateescape') + return x + if args is not None: if isinstance(args, dict): - query = query % dict((key, db.literal(item)) - for key, item in args.iteritems()) + if PY2: + args = dict((key, db.literal(item)) for key, item in args.iteritems()) + else: + args = dict((key, decode(db.literal(item))) for key, item in args.items()) else: - query = query % tuple([db.literal(item) for item in args]) + if PY2: + args = tuple(map(db.literal, args)) + else: + args = tuple([decode(db.literal(x)) for x in args]) + if not PY2 and isinstance(query, bytes): + query = query.decode(db.unicode_literal.charset) + query = query % args + + if isinstance(query, unicode): + query = query.encode(db.unicode_literal.charset, 'surrogateescape') + try: r = None r = self._query(query)