Author: phd
Date: Tue Aug 20 07:30:31 2013
New Revision: 4653
Log:
Merged revisions 4649:4652 from branch 1.5
Import validators from sqlobject.col, not from formencode.
Add dbEncoding parameter to SOCol. Move getDbEncoding to SOCol.
Encode unicode enum values to str.
Modified:
SQLObject/trunk/docs/News.txt
SQLObject/trunk/sqlobject/col.py
SQLObject/trunk/sqlobject/tests/test_enum.py
SQLObject/trunk/sqlobject/tests/test_validation.py
Modified: SQLObject/trunk/docs/News.txt
==============================================================================
--- SQLObject/trunk/docs/News.txt Tue Aug 20 07:28:06 2013 (r4652)
+++ SQLObject/trunk/docs/News.txt Tue Aug 20 07:30:31 2013 (r4653)
@@ -22,6 +22,8 @@
Minor features
--------------
+* Encode unicode enum values to str.
+
* A number of fixes for tests.
Bugfixes
Modified: SQLObject/trunk/sqlobject/col.py
==============================================================================
--- SQLObject/trunk/sqlobject/col.py Tue Aug 20 07:28:06 2013 (r4652)
+++ SQLObject/trunk/sqlobject/col.py Tue Aug 20 07:30:31 2013 (r4653)
@@ -25,10 +25,11 @@
import cPickle as pickle
except ImportError:
import pickle
-# Sadly the name "constraints" conflicts with many of the function
-# arguments in this module, so we rename it:
+import weakref
from formencode import compound, validators
from classregistry import findClass
+# Sadly the name "constraints" conflicts with many of the function
+# arguments in this module, so we rename it:
import constraints as constrs
import sqlbuilder
from styles import capword
@@ -106,6 +107,7 @@
title=None,
tags=[],
origName=None,
+ dbEncoding=None,
extra_vars=None):
super(SOCol, self).__init__()
@@ -197,6 +199,9 @@
if validator: _validators.append(validator)
if validator2: _validators.insert(0, validator2)
_vlen = len(_validators)
+ if _vlen:
+ for _validator in _validators:
+ _validator.soCol=weakref.proxy(self)
if _vlen == 0:
self.validator = None # Set sef.{from,to}_python
elif _vlen == 1:
@@ -210,6 +215,7 @@
self.origName = origName or name
self.title = title
self.tags = tags
+ self.dbEncoding = dbEncoding
if extra_vars:
for name, value in extra_vars.items():
@@ -368,6 +374,22 @@
def __delete__(self, obj):
raise AttributeError("I can't be deleted from %r" % obj)
+ def getDbEncoding(self, state, default='utf-8'):
+ if self.dbEncoding:
+ return self.dbEncoding
+ dbEncoding = state.soObject.sqlmeta.dbEncoding
+ if dbEncoding:
+ return dbEncoding
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ dbEncoding = None
+ else:
+ dbEncoding = getattr(connection, "dbEncoding", None)
+ if not dbEncoding:
+ dbEncoding = default
+ return dbEncoding
+
class Col(object):
@@ -410,6 +432,13 @@
self._name or '(unnamed)')
+class SOValidator(validators.Validator):
+ def getDbEncoding(self, state, default='utf-8'):
+ try:
+ return self.dbEncoding
+ except AttributeError:
+ return self.soCol.getDbEncoding(state, default=default)
+
class SOStringLikeCol(SOCol):
"""A common ancestor for SOStringCol and SOUnicodeCol"""
@@ -498,7 +527,7 @@
return self._sqlType()
-class StringValidator(validators.Validator):
+class StringValidator(SOValidator):
def to_python(self, value, state):
if value is None:
@@ -507,10 +536,8 @@
connection = state.connection or state.soObject._connection
binaryType = connection._binaryType
except AttributeError:
- dbEncoding = "ascii"
binaryType = type(None) # Just a simple workaround
- else:
- dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
+ dbEncoding = self.getDbEncoding(state, default='ascii')
if isinstance(value, unicode):
return value.encode(dbEncoding)
if self.dataType and isinstance(value, self.dataType):
@@ -544,13 +571,7 @@
assert db == 'mssql'
return "N" + sqlbuilder.sqlrepr(self.value, db)
-class UnicodeStringValidator(validators.Validator):
-
- def getDbEncoding(self, state):
- try:
- return self.dbEncoding
- except AttributeError:
- return self.soCol.getDbEncoding(state)
+class UnicodeStringValidator(SOValidator):
def to_python(self, value, state):
if value is None:
@@ -586,40 +607,20 @@
(self.name, type(value), value), value, state)
class SOUnicodeCol(SOStringLikeCol):
- def __init__(self, **kw):
- self.dbEncoding = kw.pop('dbEncoding', None)
- super(SOUnicodeCol, self).__init__(**kw)
-
def _mssqlType(self):
if self.customSQLType is not None:
return self.customSQLType
return 'N' + super(SOUnicodeCol, self)._mssqlType()
def createValidators(self):
- return [UnicodeStringValidator(name=self.name, soCol=self)] + \
+ return [UnicodeStringValidator(name=self.name)] + \
super(SOUnicodeCol, self).createValidators()
- def getDbEncoding(self, state):
- if self.dbEncoding:
- return self.dbEncoding
- dbEncoding = state.soObject.sqlmeta.dbEncoding
- if dbEncoding:
- return dbEncoding
- try:
- connection = state.connection or state.soObject._connection
- except AttributeError:
- dbEncoding = None
- else:
- dbEncoding = getattr(connection, "dbEncoding", None)
- if not dbEncoding:
- dbEncoding = "utf-8"
- return dbEncoding
-
class UnicodeCol(Col):
baseClass = SOUnicodeCol
-class IntValidator(validators.Validator):
+class IntValidator(SOValidator):
def to_python(self, value, state):
if value is None:
@@ -700,7 +701,7 @@
baseClass = SOBigIntCol
-class BoolValidator(validators.Validator):
+class BoolValidator(SOValidator):
def to_python(self, value, state):
if value is None:
@@ -747,7 +748,7 @@
baseClass = SOBoolCol
-class FloatValidator(validators.Validator):
+class FloatValidator(SOValidator):
def to_python(self, value, state):
if value is None:
@@ -959,10 +960,13 @@
super(ForeignKey, self).__init__(foreignKey=foreignKey, **kw)
-class EnumValidator(validators.Validator):
+class EnumValidator(SOValidator):
def to_python(self, value, state):
if value in self.enumValues:
+ if isinstance(value, unicode):
+ dbEncoding = self.getDbEncoding(state)
+ value = value.encode(dbEncoding)
return value
elif not self.notNone and value is None:
return None
@@ -1032,7 +1036,7 @@
baseClass = SOEnumCol
-class SetValidator(validators.Validator):
+class SetValidator(SOValidator):
"""
Translates Python tuples into SQL comma-delimited SET strings.
"""
@@ -1330,7 +1334,7 @@
baseClass = SOTimestampCol
-class TimedeltaValidator(validators.Validator):
+class TimedeltaValidator(SOValidator):
def to_python(self, value, state):
return value
@@ -1350,7 +1354,7 @@
from decimal import Decimal
-class DecimalValidator(validators.Validator):
+class DecimalValidator(SOValidator):
def to_python(self, value, state):
if value is None:
return None
@@ -1475,7 +1479,7 @@
baseClass = SODecimalStringCol
-class BinaryValidator(validators.Validator):
+class BinaryValidator(SOValidator):
"""
Validator for binary types.
@@ -1566,12 +1570,7 @@
if value is None:
return None
if isinstance(value, unicode):
- try:
- connection = state.connection or state.soObject._connection
- except AttributeError:
- dbEncoding = "ascii"
- else:
- dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
+ dbEncoding = self.getDbEncoding(state, default='ascii')
value = value.encode(dbEncoding)
if isinstance(value, str):
return pickle.loads(value)
Modified: SQLObject/trunk/sqlobject/tests/test_enum.py
==============================================================================
--- SQLObject/trunk/sqlobject/tests/test_enum.py Tue Aug 20 07:28:06 2013 (r4652)
+++ SQLObject/trunk/sqlobject/tests/test_enum.py Tue Aug 20 07:30:31 2013 (r4653)
@@ -1,6 +1,6 @@
from sqlobject import *
+from sqlobject.col import validators
from sqlobject.tests.dbtest import *
-from formencode import Invalid
########################################
## Enum test
@@ -17,9 +17,10 @@
raises(
(Enum1._connection.module.IntegrityError,
Enum1._connection.module.ProgrammingError,
- Invalid),
+ validators.Invalid),
Enum1, l='b')
+
class EnumWithNone(SQLObject):
l = EnumCol(enumValues=['a', 'bcd', 'e', None])
@@ -30,6 +31,7 @@
e = EnumWithNone(l=l)
assert e.l == l
+
class EnumWithDefaultNone(SQLObject):
l = EnumCol(enumValues=['a', 'bcd', 'e', None], default=None)
@@ -40,6 +42,7 @@
e = EnumWithDefaultNone()
assert e.l == None
+
class EnumWithDefaultOther(SQLObject):
l = EnumCol(enumValues=['a', 'bcd', 'e', None], default='a')
@@ -49,3 +52,17 @@
e = EnumWithDefaultOther()
assert e.l == 'a'
+
+
+class EnumUnicode(SQLObject):
+
+ n = UnicodeCol()
+ l = EnumCol(enumValues=['a', 'b'])
+
+def testUnicode():
+ setupClass(EnumUnicode)
+
+ EnumUnicode(n=u'a', l='a')
+ EnumUnicode(n=u'b', l=u'b')
+ EnumUnicode(n=u'\u201c', l='a')
+ EnumUnicode(n=u'\u201c', l=u'b')
Modified: SQLObject/trunk/sqlobject/tests/test_validation.py
==============================================================================
--- SQLObject/trunk/sqlobject/tests/test_validation.py Tue Aug 20 07:28:06 2013 (r4652)
+++ SQLObject/trunk/sqlobject/tests/test_validation.py Tue Aug 20 07:30:31 2013 (r4653)
@@ -1,6 +1,6 @@
from sqlobject import *
+from sqlobject.col import validators
from sqlobject.tests.dbtest import *
-from formencode import validators
########################################
## Validation/conversion
|