From: Mike Bayer Date: Fri, 2 Aug 2013 00:25:56 +0000 (-0400) Subject: - assorted fixes raised by pypy 2.1beta2, but all of which are good X-Git-Tag: rel_0_9_0b1~154 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d2a6238372bf8050b847f5755817b5a1a16fcf10;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - assorted fixes raised by pypy 2.1beta2, but all of which are good ideas in general: - pypy2.1 w/ sqlite3 is the first DBAPI we're seeing returning unicode in cursor.description without being py3k. add a new on-connect check for this, if we get back a u"", just don't do description decoding, should be OK for now. - the set tests in test_collection were assuming the two sets would be ordered the same when it tested pop(), can't really assume that. - test_serializer gets worse and worse, pickle is just not really viable here, ding out pypy - pypy2.1b2 seems to allow cursor.lastrowid to work (or we changed something?) - pool._threadconns.current() is a weakref, it can be None - another one of those logging.handlers imports --- diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 3e8e96a42c..b8c3768a8c 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -191,6 +191,10 @@ class DefaultDialect(interfaces.Dialect): self.returns_unicode_strings = self._check_unicode_returns(connection) + if self.description_encoding is not None and \ + self._check_unicode_description(connection): + self._description_decoder = self.description_encoding = None + self.do_rollback(connection.connection) def on_connect(self): @@ -248,6 +252,26 @@ class DefaultDialect(interfaces.Dialect): else: return unicode_for_varchar + def _check_unicode_description(self, connection): + # all DBAPIs on Py2K return cursor.description as encoded, + # until pypy2.1beta2 with sqlite, so let's just check it - + # it's likely others will start doing this too in Py2k. + + if util.py2k and not self.supports_unicode_statements: + cast_to = util.binary_type + else: + cast_to = util.text_type + + cursor = connection.connection.cursor() + cursor.execute( + cast_to( + expression.select([ + expression.literal_column("'x'").label("some_label") + ]).compile(dialect=self) + ) + ) + return isinstance(cursor.description[0][0], util.text_type) + def type_descriptor(self, typeobj): """Provide a database-specific :class:`.TypeEngine` object, given the generic object which comes from the types module. diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 498b001c15..f2d6ca6ea4 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -277,7 +277,8 @@ class Pool(log.Identified): except AttributeError: pass else: - return rec.checkout_existing() + if rec is not None: + return rec.checkout_existing() return _ConnectionFairy.checkout(self, self._threadconns) diff --git a/lib/sqlalchemy/testing/suite/test_insert.py b/lib/sqlalchemy/testing/suite/test_insert.py index e671eeb7a2..21141f244d 100644 --- a/lib/sqlalchemy/testing/suite/test_insert.py +++ b/lib/sqlalchemy/testing/suite/test_insert.py @@ -56,8 +56,9 @@ class LastrowidTest(fixtures.TablesTest): [pk] ) - @exclusions.fails_if(lambda: util.pypy, "lastrowid not maintained after " - "connection close") + # failed on pypy1.9 but seems to be OK on pypy 2.1 + #@exclusions.fails_if(lambda: util.pypy, "lastrowid not maintained after " + # "connection close") @requirements.dbapi_lastrowid def test_native_lastrowid_autoinc(self): r = config.db.execute( diff --git a/test/orm/test_collection.py b/test/orm/test_collection.py index c9f9f6951d..fab2aac967 100644 --- a/test/orm/test_collection.py +++ b/test/orm/test_collection.py @@ -499,9 +499,9 @@ class CollectionsTest(fixtures.ORMTest): control = set() def assert_eq(): - self.assert_(set(direct) == canary.data) - self.assert_(set(adapter) == canary.data) - self.assert_(direct == control) + eq_(set(direct), canary.data) + eq_(set(adapter), canary.data) + eq_(direct, control) def addall(*values): for item in values: @@ -519,10 +519,6 @@ class CollectionsTest(fixtures.ORMTest): addall(e) addall(e) - if hasattr(direct, 'pop'): - direct.pop() - control.pop() - assert_eq() if hasattr(direct, 'remove'): e = creator() @@ -599,6 +595,12 @@ class CollectionsTest(fixtures.ORMTest): control.clear() assert_eq() + if hasattr(direct, 'pop'): + addall(creator()) + direct.pop() + control.pop() + assert_eq() + if hasattr(direct, 'difference_update'): zap() e = creator() @@ -739,6 +741,7 @@ class CollectionsTest(fixtures.ORMTest): except TypeError: assert True + def _test_set_bulk(self, typecallable, creator=None): if creator is None: creator = self.entity_maker diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py index 06ec4ce272..e742505b0e 100644 --- a/test/orm/test_mapper.py +++ b/test/orm/test_mapper.py @@ -17,6 +17,7 @@ from sqlalchemy.testing import fixtures from test.orm import _fixtures from sqlalchemy.testing.assertsql import CompiledSQL import logging +import logging.handlers class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): __dialect__ = 'default' diff --git a/test/requirements.py b/test/requirements.py index a56c037d19..2bd3954048 100644 --- a/test/requirements.py +++ b/test/requirements.py @@ -579,8 +579,9 @@ class DefaultRequirements(SuiteRequirements): def non_broken_pickle(self): from sqlalchemy.util import pickle return only_if( - lambda: pickle.__name__ == 'cPickle' or sys.version_info >= (3, 2), - "Needs cPickle or newer Python 3 pickle" + lambda: not util.pypy and pickle.__name__ == 'cPickle' + or sys.version_info >= (3, 2), + "Needs cPickle+cPython or newer Python 3 pickle" )