From e7545c7c40cf1830ceee77cdeb8b04a9d5b3c754 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Fri, 18 Apr 2014 23:25:01 +0900 Subject: [PATCH] refactoring. --- MySQLdb/compat.py | 4 ++++ MySQLdb/connections.py | 13 ++++++++++--- MySQLdb/converters.py | 38 +++++++++++--------------------------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/MySQLdb/compat.py b/MySQLdb/compat.py index 4d84afe..70580b6 100644 --- a/MySQLdb/compat.py +++ b/MySQLdb/compat.py @@ -1,8 +1,12 @@ import sys if sys.version_info[0] == 3: + PY2 = False unicode = str unichr = chr + long = int else: + PY2 = True unicode = unicode unichr = unichr + long = long diff --git a/MySQLdb/connections.py b/MySQLdb/connections.py index 3c7a977..1b18fa6 100644 --- a/MySQLdb/connections.py +++ b/MySQLdb/connections.py @@ -7,7 +7,7 @@ override Connection.default_cursor with a non-standard Cursor class. """ from MySQLdb import cursors -from MySQLdb.compat import unicode +from MySQLdb.compat import unicode, PY2 from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \ DatabaseError, OperationalError, IntegrityError, InternalError, \ NotSupportedError, ProgrammingError @@ -15,8 +15,6 @@ import _mysql import re import sys -PY2 = sys.version_info[0] == 2 - def defaulterrorhandler(connection, cursor, errorclass, errorvalue): """ @@ -123,6 +121,7 @@ class Connection(_mysql.connection): 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. + Default to False on Python 2 and True on Python 3. charset If supplied, the connection character set will be changed @@ -207,15 +206,18 @@ class Connection(_mysql.connection): db = proxy(self) def _get_string_literal(): + # Note: string_literal() is called for bytes object on Python 3. def string_literal(obj, dummy=None): return db.string_literal(obj) return string_literal def _get_unicode_literal(): if PY2: + # unicode_literal is called for only unicode object. def unicode_literal(u, dummy=None): return db.literal(u.encode(unicode_literal.charset)) else: + # unicode_literal() is called for arbitrary object. def unicode_literal(u, dummy=None): return db.literal(str(u).encode(unicode_literal.charset)) return unicode_literal @@ -288,6 +290,11 @@ class Connection(_mysql.connection): """ s = self.escape(o, self.encoders) + # Python 3 doesn't support % operation for bytes object. + # We should decode it before using %. + # Decoding with ascii and surrogateescape allows convert arbitrary + # bytes to unicode and back again. + # See http://python.org/dev/peps/pep-0383/ if not PY2 and isinstance(s, bytes): return s.decode('ascii', 'surrogateescape') return s diff --git a/MySQLdb/converters.py b/MySQLdb/converters.py index 7f6bfb7..9937e25 100644 --- a/MySQLdb/converters.py +++ b/MySQLdb/converters.py @@ -35,18 +35,9 @@ MySQL.connect(). from _mysql import string_literal, escape_sequence, escape_dict, escape, NULL from MySQLdb.constants import FIELD_TYPE, FLAG from MySQLdb.times import * +from MySQLdb.compat import PY2, long -try: - from types import IntType, LongType, FloatType, NoneType, TupleType, ListType, DictType, InstanceType, \ - 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 - ObjectType, BooleanType = object, bool - PY2 = False +NoneType = type(None) import array @@ -78,8 +69,6 @@ def Unicode2Str(s, d): is connection-dependent.""" return s.encode() -Long2Int = Thing2Str - def Float2Str(o, d): return '%.15g' % o @@ -88,12 +77,10 @@ def None2NULL(o, d): return NULL # duh def Thing2Literal(o, d): - """Convert something into a SQL string literal. If using MySQL-3.23 or newer, string_literal() is a method of the _mysql.MYSQL object, and this function will be overridden with that method when the connection is created.""" - return string_literal(o, d) @@ -107,19 +94,19 @@ def quote_tuple(t, d): return "(%s)" % (','.join(escape_sequence(t, d))) conversions = { - IntType: Thing2Str, - LongType: Long2Int, - FloatType: Float2Str, + int: Thing2Str, + long: Thing2Str, + float: Float2Str, NoneType: None2NULL, - TupleType: quote_tuple, - ListType: quote_tuple, - DictType: escape_dict, + tuple: quote_tuple, + list: quote_tuple, + dict: escape_dict, ArrayType: array2Str, - BooleanType: Bool2Str, + bool: Bool2Str, Date: Thing2Literal, DateTimeType: DateTime2literal, DateTimeDeltaType: DateTimeDelta2literal, - str: str, # default + str: Thing2Literal, # default set: Set2Str, FIELD_TYPE.TINY: int, FIELD_TYPE.SHORT: int, @@ -152,7 +139,7 @@ conversions = { if PY2: conversions[unicode] = Unicode2Str else: - conversions[bytes] = bytes + conversions[bytes] = Thing2Literal try: from decimal import Decimal @@ -160,6 +147,3 @@ try: conversions[FIELD_TYPE.NEWDECIMAL] = Decimal except ImportError: pass - - -