From: Mike Bayer Date: Wed, 16 Mar 2011 17:04:07 +0000 (-0400) Subject: - alex gaynor's latest batch of pypy test fixes X-Git-Tag: rel_0_7b3~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b1b8e7defd7ee0d3d6d32d16a412a75b1c93ed0d;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - alex gaynor's latest batch of pypy test fixes --- diff --git a/CHANGES b/CHANGES index 7bd83e1628..e60ddd8fb6 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ CHANGES ======= 0.7.0b3 ======= +- general + - Lots of fixes to unit tests when run under Pypy. + - orm - Changed the underlying approach to query.count(). query.count() is now in all cases exactly: diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 5dd95190f7..64997706c4 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -4,7 +4,7 @@ # This module is part of SQLAlchemy and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -"""Routines to help with the creation, loading and introspection of +"""Routines to help with the creation, loading and introspection of modules, classes, hierarchies, attributes, functions, and methods. """ @@ -61,7 +61,7 @@ def get_cls_kwargs(cls): pass along unrecognized keywords to it's base classes, and the collection process is repeated recursively on each of the bases. - Uses a subset of inspect.getargspec() to cut down on method overhead. + Uses a subset of inspect.getargspec() to cut down on method overhead. No anonymous tuple arguments please ! """ @@ -77,7 +77,9 @@ def get_cls_kwargs(cls): while stack: class_ = stack.pop() ctr = class_.__dict__.get('__init__', False) - if not ctr or not isinstance(ctr, types.FunctionType): + if (not ctr or + not isinstance(ctr, types.FunctionType) or + not isinstance(ctr.func_code, types.CodeType)): stack.update(class_.__bases__) continue @@ -270,10 +272,10 @@ def class_hierarchy(cls): return list(hier) def iterate_attributes(cls): - """iterate all the keys and attributes associated + """iterate all the keys and attributes associated with a class, without using getattr(). - Does not use getattr() so that class-sensitive + Does not use getattr() so that class-sensitive descriptors (i.e. property.__get__()) are not called. """ @@ -498,13 +500,13 @@ class importlater(object): @memoized_property def module(self): if self._il_addtl: - m = __import__(self._il_path, globals(), locals(), + m = __import__(self._il_path, globals(), locals(), [self._il_addtl]) try: return getattr(m, self._il_addtl) except AttributeError: raise ImportError( - "Module %s has no attribute '%s'" % + "Module %s has no attribute '%s'" % (self._il_path, self._il_addtl) ) else: @@ -518,7 +520,7 @@ class importlater(object): attr = getattr(self.module, key) except AttributeError: raise AttributeError( - "Module %s has no attribute '%s'" % + "Module %s has no attribute '%s'" % (self._il_path, key) ) self.__dict__[key] = attr @@ -537,7 +539,7 @@ def asbool(obj): return bool(obj) def bool_or_str(*text): - """Return a callable that will evaulate a string as + """Return a callable that will evaulate a string as boolean, or one of a set of "alternate" string values. """ @@ -610,11 +612,11 @@ def assert_arg_type(arg, argtype, name): else: if isinstance(argtype, tuple): raise exc.ArgumentError( - "Argument '%s' is expected to be one of type %s, got '%s'" % + "Argument '%s' is expected to be one of type %s, got '%s'" % (name, ' or '.join("'%s'" % a for a in argtype), type(arg))) else: raise exc.ArgumentError( - "Argument '%s' is expected to be of type '%s', got '%s'" % + "Argument '%s' is expected to be of type '%s', got '%s'" % (name, argtype, type(arg))) @@ -653,7 +655,7 @@ class classproperty(property): on classes rather than instances. The decorator is currently special when using the declarative - module, but note that the + module, but note that the :class:`~.sqlalchemy.ext.declarative.declared_attr` decorator should be used for this purpose with declarative. @@ -699,9 +701,9 @@ class symbol(object): is strictly so that Sphinx autoattr picks up the docstring we want (it doesn't appear to pick up the in-module docstring if the datamember is in a different module - autoattribute also blows up completely). - If Sphinx fixes/improves this then we would no longer need + If Sphinx fixes/improves this then we would no longer need ``doc`` here. - + """ symbols = {} _lock = threading.Lock() @@ -741,11 +743,11 @@ def warn_exception(func, *args, **kwargs): def warn(msg, stacklevel=3): """Issue a warning. - If msg is a string, :class:`.exc.SAWarning` is used as + If msg is a string, :class:`.exc.SAWarning` is used as the category. .. note:: This function is swapped out when the test suite - runs, with a compatible version that uses + runs, with a compatible version that uses warnings.warn_explicit, so that the warnings registry can be controlled. diff --git a/test/base/test_utils.py b/test/base/test_utils.py index e44a1862f0..48fc075eef 100644 --- a/test/base/test_utils.py +++ b/test/base/test_utils.py @@ -2,7 +2,7 @@ from test.lib.testing import assert_raises, assert_raises_message import copy, threading from sqlalchemy import util, sql, exc from test.lib import TestBase -from test.lib.testing import eq_, is_, ne_ +from test.lib.testing import eq_, is_, ne_, fails_if from test.lib.util import gc_collect, picklers from sqlalchemy.util import classproperty @@ -860,6 +860,7 @@ class TestFormatArgspec(TestBase): 'apply_kw': 'a=a, b=b', 'apply_pos': 'a, b' }, grouped=False) + @fails_if(lambda: util.pypy, "object.__init__ is introspectable") def test_init_grouped(self): object_spec = { 'args': '(self)', 'self_arg': 'self', @@ -875,6 +876,7 @@ class TestFormatArgspec(TestBase): self._test_init(None, object_spec, wrapper_spec, custom_spec) self._test_init(True, object_spec, wrapper_spec, custom_spec) + @fails_if(lambda: util.pypy, "object.__init__ can be introspected") def test_init_bare(self): object_spec = { 'args': 'self', 'self_arg': 'self', diff --git a/test/orm/test_session.py b/test/orm/test_session.py index db49315900..d00854528f 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -70,13 +70,13 @@ class SessionTest(_fixtures.FixtureTest): def test_object_session_raises(self): assert_raises( orm_exc.UnmappedInstanceError, - object_session, + object_session, object() ) assert_raises( orm_exc.UnmappedInstanceError, - object_session, + object_session, User() ) @@ -270,7 +270,7 @@ class SessionTest(_fixtures.FixtureTest): sess.add(u1) assert u1 in sess.new - # test expired attributes + # test expired attributes # get unexpired u1 = sess.query(User).first() sess.expire(u1) @@ -327,7 +327,7 @@ class SessionTest(_fixtures.FixtureTest): @testing.resolve_artifact_names def test_autoflush_expressions(self): - """test that an expression which is dependent on object state is + """test that an expression which is dependent on object state is evaluated after the session autoflushes. This is the lambda inside of strategies.py lazy_clause. @@ -828,10 +828,10 @@ class SessionTest(_fixtures.FixtureTest): assert sess.connection(mapper=Address, bind=e1).engine is e1 assert sess.connection(mapper=Address).engine is e2 assert sess.connection(clause=addresses.select()).engine is e2 - assert sess.connection(mapper=User, + assert sess.connection(mapper=User, clause=addresses.select()).engine is e1 - assert sess.connection(mapper=User, - clause=addresses.select(), + assert sess.connection(mapper=User, + clause=addresses.select(), bind=e2).engine is e2 sess.close() diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py index b306dcbba2..b7ff8095e9 100644 --- a/test/orm/test_subquery_relations.py +++ b/test/orm/test_subquery_relations.py @@ -19,7 +19,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): def test_basic(self): mapper(User, users, properties={ 'addresses':relationship( - mapper(Address, addresses), + mapper(Address, addresses), order_by=Address.id) }) sess = create_session() @@ -35,9 +35,9 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): self.assert_sql_count(testing.db, go, 2) - def go(): + def go(): eq_( - self.static.user_address_result, + self.static.user_address_result, q.order_by(User.id).all() ) self.assert_sql_count(testing.db, go, 2) @@ -68,9 +68,9 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): self.assert_sql_count(testing.db, go, 2) - def go(): + def go(): eq_( - self.static.user_address_result, + self.static.user_address_result, q.order_by(u.id).all() ) self.assert_sql_count(testing.db, go, 2) @@ -99,7 +99,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): def test_from_get(self): mapper(User, users, properties={ 'addresses':relationship( - mapper(Address, addresses), + mapper(Address, addresses), order_by=Address.id) }) sess = create_session() @@ -118,7 +118,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): def test_from_params(self): mapper(User, users, properties={ 'addresses':relationship( - mapper(Address, addresses), + mapper(Address, addresses), order_by=Address.id) }) sess = create_session() @@ -152,7 +152,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): ) @testing.resolve_artifact_names - def test_many_to_many(self): + def test_many_to_many_plain(self): mapper(Keyword, keywords) mapper(Item, items, properties = dict( keywords = relationship(Keyword, secondary=item_keywords, @@ -163,11 +163,27 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): eq_(self.static.item_keyword_result, q.all()) self.assert_sql_count(testing.db, go, 2) + @testing.resolve_artifact_names + def test_many_to_many_with_join(self): + mapper(Keyword, keywords) + mapper(Item, items, properties = dict( + keywords = relationship(Keyword, secondary=item_keywords, + lazy='subquery', order_by=keywords.c.id))) + + q = create_session().query(Item).order_by(Item.id) def go(): eq_(self.static.item_keyword_result[0:2], q.join('keywords').filter(Keyword.name == 'red').all()) self.assert_sql_count(testing.db, go, 2) + @testing.resolve_artifact_names + def test_many_to_many_with_join_alias(self): + mapper(Keyword, keywords) + mapper(Item, items, properties = dict( + keywords = relationship(Keyword, secondary=item_keywords, + lazy='subquery', order_by=keywords.c.id))) + + q = create_session().query(Item).order_by(Item.id) def go(): eq_(self.static.item_keyword_result[0:2], (q.join('keywords', aliased=True). @@ -177,7 +193,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): @testing.resolve_artifact_names def test_orderby(self): mapper(User, users, properties = { - 'addresses':relationship(mapper(Address, addresses), + 'addresses':relationship(mapper(Address, addresses), lazy='subquery', order_by=addresses.c.email_address), }) q = create_session().query(User) @@ -199,8 +215,8 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): @testing.resolve_artifact_names def test_orderby_multi(self): mapper(User, users, properties = { - 'addresses':relationship(mapper(Address, addresses), - lazy='subquery', + 'addresses':relationship(mapper(Address, addresses), + lazy='subquery', order_by=[ addresses.c.email_address, addresses.c.id]), @@ -223,12 +239,12 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): @testing.resolve_artifact_names def test_orderby_related(self): - """A regular mapper select on a single table can + """A regular mapper select on a single table can order by a relationship to a second table""" mapper(Address, addresses) mapper(User, users, properties = dict( - addresses = relationship(Address, + addresses = relationship(Address, lazy='subquery', order_by=addresses.c.id), )) @@ -300,18 +316,18 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): 'orders':relationship(Order, order_by=orders.c.id), # o2m, m2o }) mapper(Order, orders, properties={ - 'items':relationship(Item, + 'items':relationship(Item, secondary=order_items, order_by=items.c.id), #m2m }) mapper(Item, items, properties={ - 'keywords':relationship(Keyword, + 'keywords':relationship(Keyword, secondary=item_keywords, order_by=keywords.c.id) #m2m }) mapper(Keyword, keywords) callables = { - 'joinedload':joinedload, + 'joinedload':joinedload, 'subqueryload':subqueryload } @@ -336,14 +352,14 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): for o, i, k, count in configs: mapper(User, users, properties={ - 'orders':relationship(Order, lazy=opts[o], order_by=orders.c.id), + 'orders':relationship(Order, lazy=opts[o], order_by=orders.c.id), }) mapper(Order, orders, properties={ - 'items':relationship(Item, - secondary=order_items, lazy=opts[i], order_by=items.c.id), + 'items':relationship(Item, + secondary=order_items, lazy=opts[i], order_by=items.c.id), }) mapper(Item, items, properties={ - 'keywords':relationship(Keyword, + 'keywords':relationship(Keyword, lazy=opts[k], secondary=item_keywords, order_by=keywords.c.id) @@ -398,7 +414,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): @testing.resolve_artifact_names def test_double(self): - """Eager loading with two relationships simultaneously, + """Eager loading with two relationships simultaneously, from the same table, using aliases.""" openorders = sa.alias(orders, 'openorders') @@ -453,7 +469,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): @testing.resolve_artifact_names def test_double_same_mappers(self): - """Eager loading with two relationships simulatneously, + """Eager loading with two relationships simulatneously, from the same table, using aliases.""" mapper(Address, addresses) @@ -529,8 +545,8 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): order_by=items.c.id) }) mapper(User, users, properties={ - 'addresses':relationship(mapper(Address, addresses), - lazy='subquery', + 'addresses':relationship(mapper(Address, addresses), + lazy='subquery', order_by=addresses.c.id), 'orders':relationship(Order, lazy='select', order_by=orders.c.id) }) @@ -548,7 +564,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): @testing.resolve_artifact_names def test_one_to_many_scalar(self): mapper(User, users, properties = dict( - address = relationship(mapper(Address, addresses), + address = relationship(mapper(Address, addresses), lazy='subquery', uselist=False) )) q = create_session().query(User) @@ -588,7 +604,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): 'orders':relationship(Order, backref='user', lazy='subquery', order_by=orders.c.id), 'max_order':relationship( - mapper(Order, max_orders, non_primary=True), + mapper(Order, max_orders, non_primary=True), lazy='subquery', uselist=False) }) @@ -611,9 +627,9 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): ], q.order_by(User.id).all()) self.assert_sql_count(testing.db, go, 3) - @testing.resolve_artifact_names + @testing.resolve_artifact_names def test_uselist_false_warning(self): - """test that multiple rows received by a + """test that multiple rows received by a uselist=False raises a warning.""" mapper(User, users, properties={ @@ -694,8 +710,8 @@ class SelfReferentialTest(_base.MappedTest): self.children.append(node) mapper(Node, nodes, properties={ - 'children':relationship(Node, - lazy='subquery', + 'children':relationship(Node, + lazy='subquery', join_depth=3, order_by=nodes.c.id) }) sess = create_session() @@ -791,7 +807,7 @@ class SelfReferentialTest(_base.MappedTest): sess.expunge_all() def go(): - eq_( + eq_( Node(data='n1', children=[Node(data='n11'), Node(data='n12')]), sess.query(Node).order_by(Node.id).first(), )