From: Mike Bayer Date: Tue, 24 Jul 2007 15:43:32 +0000 (+0000) Subject: - ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary X-Git-Tag: rel_0_4_6~34 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a095e8d0ce3eadc11cbeffc97e297ff324677b5a;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary semantics for "__contains__" [ticket:606] --- diff --git a/CHANGES b/CHANGES index 668c94626c..f47e7be66f 100644 --- a/CHANGES +++ b/CHANGES @@ -194,6 +194,8 @@ - engines - Connections gain a .properties collection, with contents scoped to the lifetime of the underlying DBAPI connection + - ColumnCollection (i.e. the 'c' attribute on tables) follows dictionary + semantics for "__contains__" [ticket:606] - extensions - proxyengine is temporarily removed, pending an actually working replacement. diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index a335cdd69c..3985323604 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -523,7 +523,7 @@ class PropertyLoader(StrategizedProperty): # load "polymorphic" versions of the columns present in "remote_side" - this is # important for lazy-clause generation which goes off the polymorphic target selectable for c in list(self.remote_side): - if self.secondary and c in self.secondary.columns: + if self.secondary and self.secondary.columns.contains_column(c): continue for equiv in [c] + (c in target_equivalents and list(target_equivalents[c]) or []): corr = self.mapper.select_table.corresponding_column(equiv, raiseerr=False) diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 00b9cff68c..5b392bdb82 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -871,7 +871,7 @@ class Constraint(SchemaItem): self.columns = sql.ColumnCollection() def __contains__(self, x): - return x in self.columns + return self.columns.contains_column(x) def keys(self): return self.columns.keys() diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index 49fbb3aa03..c463e1e995 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -1593,8 +1593,10 @@ class ColumnCollection(util.OrderedProperties): l.append(c==local) return and_(*l) - def __contains__(self, col): - return self.contains_column(col) + def __contains__(self, other): + if not isinstance(other, basestring): + raise exceptions.ArgumentError("__contains__ requires a string argument") + return self.has_key(other) def contains_column(self, col): # have to use a Set here, because it will compare the identity @@ -1714,7 +1716,7 @@ class FromClause(Selectable): the exported columns of this ``FromClause``. """ - if column in self.c: + if self.c.contains_column(column): return column if require_embedded and column not in util.Set(self._get_all_embedded_columns()): diff --git a/test/base/utils.py b/test/base/utils.py index 96d3c96e43..97f3db06fc 100644 --- a/test/base/utils.py +++ b/test/base/utils.py @@ -1,5 +1,5 @@ import testbase -from sqlalchemy import util +from sqlalchemy import util, column, sql, exceptions from testlib import * @@ -34,5 +34,34 @@ class OrderedDictTest(PersistTest): self.assert_(o.keys() == ['a', 'b', 'c', 'd', 'e', 'f']) self.assert_(o.values() == [1, 2, 3, 4, 5, 6]) +class ColumnCollectionTest(PersistTest): + def test_in(self): + cc = sql.ColumnCollection() + cc.add(column('col1')) + cc.add(column('col2')) + cc.add(column('col3')) + assert 'col1' in cc + assert 'col2' in cc + + try: + cc['col1'] in cc + assert False + except exceptions.ArgumentError, e: + assert str(e) == "__contains__ requires a string argument" + + def test_compare(self): + cc1 = sql.ColumnCollection() + cc2 = sql.ColumnCollection() + cc3 = sql.ColumnCollection() + c1 = column('col1') + c2 = c1.label('col2') + c3 = column('col3') + cc1.add(c1) + cc2.add(c2) + cc3.add(c3) + assert (cc1==cc2).compare(c1 == c2) + assert not (cc1==cc3).compare(c2 == c3) + + if __name__ == "__main__": testbase.main()