]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
assert_unicode=True replaced with default of assert_unicode='warn'
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 5 Dec 2007 22:21:37 +0000 (22:21 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 5 Dec 2007 22:21:37 +0000 (22:21 +0000)
CHANGES
doc/build/content/types.txt
lib/sqlalchemy/types.py
test/sql/testtypes.py

diff --git a/CHANGES b/CHANGES
index f323bdab8d68ea5e3be843fde5839b6f081cc01d..791d4d6ef20c8c8d84fb38fc462eecf4e7eb50bb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -14,12 +14,13 @@ CHANGES
       represented so far but will continue to add to the system [ticket:615]
 
     - added new flag to String and create_engine(),
-      assert_unicode=(True|False|None). Defaults to `False` or `None` on
-      create_engine() and String, `True` on the Unicode type. When `True`,
+      assert_unicode=(True|False|'warn'|None). Defaults to `False` or `None` on
+      create_engine() and String, `'warn'` on the Unicode type. When `True`,
       results in all unicode conversion operations raising an exception when a
-      non-unicode bytestring is passed as a bind parameter. It is strongly
-      advised that all unicode-aware applications make proper use of Python
-      unicode objects (i.e. u'hello' and not 'hello').
+      non-unicode bytestring is passed as a bind parameter. 'warn' results
+      in a warning. It is strongly advised that all unicode-aware applications 
+      make proper use of Python unicode objects (i.e. u'hello' and not 'hello')
+      so that data round trips accurately.
 
     - tables with schemas can still be used in sqlite, firebird,
       schema name just gets dropped [ticket:890]
index 227f5b1870bf830798a0b7164e7871eb59cdd3cf..c1343f7b6cdfe0483df05f0694cfe18291fcab5d 100644 (file)
@@ -23,13 +23,13 @@ This type is the base type for all string and character types, such as `Unicode`
 
 `convert_unicode=True` indicates that incoming strings, if they are Python `unicode` strings, will be encoded into a raw bytestring using the `encoding` attribute of the dialect (defaults to `utf-8`).  Similarly, raw bytestrings coming back from the database will be decoded into `unicode` objects on the way back.
 
-`assert_unicode` is set to `None` by default. When `True`, it indicates that incoming bind parameters will be checked that they are in fact  `unicode` objects, else an error is raised.  Setting it to `None` indicates that the dialect-level `convert_unicode` setting should take place, whereas setting it to `False` disables it unconditionally  (this flag is new as of version 0.4.2).
+`assert_unicode` is set to `None` by default. When `True`, it indicates that incoming bind parameters will be checked that they are in fact  `unicode` objects, else an error is raised.  A value of `'warn'` instead raises a warning.  Setting it to `None` indicates that the dialect-level `convert_unicode` setting should take place, whereas setting it to `False` disables it unconditionally  (this flag is new as of version 0.4.2).
 
 Both `convert_unicode` and `assert_unicode` may be set at the engine level as flags to `create_engine()`.
 
 #### Unicode
 
-The `Unicode` type is shorthand for `String` with `convert_unicode=True` and `assert_unicode=True`.  When writing a unicode-aware appication, it is strongly recommended that this type is used, and that only unicode strings are used in the application.  By "unicode string" we mean a string with a u, i.e. `u'hello'`.  Otherwise, particularly when using the ORM, data will be converted to unicode when it returns from the database, but local data which was generated locally will not be in unicode format, which can create confusion.
+The `Unicode` type is shorthand for `String` with `convert_unicode=True` and `assert_unicode='warn'`.  When writing a unicode-aware appication, it is strongly recommended that this type is used, and that only unicode strings are used in the application.  By "unicode string" we mean a string with a u, i.e. `u'hello'`.  Otherwise, particularly when using the ORM, data will be converted to unicode when it returns from the database, but local data which was generated locally will not be in unicode format, which can create confusion.
 
 #### Numeric
 
index e23a695f3c72fa817e81ca484c03865ef66bd928..59b5282ec502d293b196a38daa03694d189a5636 100644 (file)
@@ -15,6 +15,7 @@ __all__ = [ 'TypeEngine', 'TypeDecorator',
 
 import inspect
 import datetime as dt
+import warnings
 
 from sqlalchemy import exceptions
 from sqlalchemy.util import pickle, Decimal as _python_Decimal
@@ -312,14 +313,17 @@ class String(Concatenable, TypeEngine):
     def bind_processor(self, dialect):
         if self.convert_unicode or dialect.convert_unicode:
             if self.assert_unicode is None:
-                assert_unicode = bool(dialect.assert_unicode)
+                assert_unicode = dialect.assert_unicode
             else:
                 assert_unicode = self.assert_unicode
             def process(value):
                 if isinstance(value, unicode):
                     return value.encode(dialect.encoding)
                 elif assert_unicode and not isinstance(value, (unicode, NoneType)):
-                    raise exceptions.InvalidRequestError("Received non-unicode bind param value %r" % value)
+                    if assert_unicode == 'warn':
+                        warnings.warn(RuntimeWarning("Unicode type received non-unicode bind param value %r" % value))                        
+                    else:
+                        raise exceptions.InvalidRequestError("Unicode type received non-unicode bind param value %r" % value)
                 else:
                     return value
             return process
@@ -352,7 +356,8 @@ class String(Concatenable, TypeEngine):
 
 class Unicode(String):
     def __init__(self, length=None, **kwargs):
-        kwargs['convert_unicode'] = kwargs['assert_unicode'] = True
+        kwargs['convert_unicode'] = True
+        kwargs['assert_unicode'] = 'warn'
         super(Unicode, self).__init__(length=length, **kwargs)
 
 class Integer(TypeEngine):
index 3d44a5294130ba7c9b0cbb21db5799e5d90a7282..b8154d32e661f5ef88c3155968a950eee7ea1f01 100644 (file)
@@ -288,11 +288,14 @@ class UnicodeTest(AssertMixin):
             self.assert_(not isinstance(x['plain_varchar'], unicode) and x['plain_varchar'] == rawdata)
     
     def testassert(self):
+        import warnings
+        warnings.filterwarnings("error", r".*non-unicode bind")
+        
         try:
             unicode_table.insert().execute(unicode_varchar='im not unicode')
             assert False
-        except exceptions.InvalidRequestError, e:
-            assert str(e) == "Received non-unicode bind param value 'im not unicode'"
+        except RuntimeWarning, e:
+            assert str(e) == "Unicode type received non-unicode bind param value 'im not unicode'", str(e)
         
         unicode_engine = engines.utf8_engine(options={'convert_unicode':True, 'assert_unicode':True})
         try:
@@ -300,7 +303,7 @@ class UnicodeTest(AssertMixin):
                 unicode_engine.execute(unicode_table.insert(), plain_varchar='im not unicode')
                 assert False
             except exceptions.InvalidRequestError, e:
-                assert str(e) == "Received non-unicode bind param value 'im not unicode'"
+                assert str(e) == "Unicode type received non-unicode bind param value 'im not unicode'"
         finally:
             unicode_engine.dispose()