From: Mike Bayer Date: Wed, 5 Dec 2007 22:21:37 +0000 (+0000) Subject: assert_unicode=True replaced with default of assert_unicode='warn' X-Git-Tag: rel_0_4_2~103 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=594784a20639198690f59ded0bebb3529dbadb2e;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git assert_unicode=True replaced with default of assert_unicode='warn' --- diff --git a/CHANGES b/CHANGES index f323bdab8d..791d4d6ef2 100644 --- 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] diff --git a/doc/build/content/types.txt b/doc/build/content/types.txt index 227f5b1870..c1343f7b6c 100644 --- a/doc/build/content/types.txt +++ b/doc/build/content/types.txt @@ -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 diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index e23a695f3c..59b5282ec5 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -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): diff --git a/test/sql/testtypes.py b/test/sql/testtypes.py index 3d44a52941..b8154d32e6 100644 --- a/test/sql/testtypes.py +++ b/test/sql/testtypes.py @@ -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()