From: Mike Bayer Date: Sun, 14 Aug 2011 16:20:54 +0000 (-0400) Subject: - Added a slightly nicer __repr__() to SchemaItem X-Git-Tag: rel_0_7_3~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76a9219a1ebe9d6abdc510fec87968df905be4fe;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Added a slightly nicer __repr__() to SchemaItem classes. Note the repr here can't fully support the "repr is the constructor" idea since schema items can be very deeply nested/cyclical, have late initialization of some things, etc. [ticket:2223] --- diff --git a/CHANGES b/CHANGES index 4f244b4458..5c1b2425cb 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,14 @@ CHANGES on a new mapper would establish a backref on the first mapper. +- schema + - Added a slightly nicer __repr__() to SchemaItem + classes. Note the repr here can't fully support + the "repr is the constructor" idea since schema + items can be very deeply nested/cyclical, have + late initialization of some things, etc. + [ticket:2223] + - engine - The recreate() method in all pool classes uses self.__class__ to get at the type of pool diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 7b5b3ab70c..8fd4e75781 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -68,7 +68,7 @@ class SchemaItem(events.SchemaEventTarget, visitors.Visitable): return [] def __repr__(self): - return "%s()" % self.__class__.__name__ + return util.generic_repr(self) @util.memoized_property def info(self): @@ -918,7 +918,7 @@ class Column(SchemaItem, expression.ColumnClause): [repr(x) for x in self.foreign_keys if x is not None] + [repr(x) for x in self.constraints] + [(self.table is not None and "table=<%s>" % - self.table.description or "")] + + self.table.description or "table=None")] + ["%s=%s" % (k, repr(getattr(self, k))) for k in kwarg]) def _set_parent(self, table): @@ -1401,9 +1401,6 @@ class DefaultGenerator(_NotAColumnExpr, SchemaItem): else: return None - def __repr__(self): - return "DefaultGenerator()" - class ColumnDefault(DefaultGenerator): """A plain default value on a column. @@ -1600,12 +1597,6 @@ class Sequence(DefaultGenerator): """ return expression.func.next_value(self, bind=self.bind) - def __repr__(self): - return "Sequence(%s)" % ', '.join( - [repr(self.name)] + - ["%s=%s" % (k, repr(getattr(self, k))) - for k in ['start', 'increment', 'optional']]) - def _set_parent(self, column): super(Sequence, self)._set_parent(column) column._on_table_attach(self._set_table) @@ -1681,8 +1672,7 @@ class FetchedValue(_NotAColumnExpr, events.SchemaEventTarget): self.column.server_default = self def __repr__(self): - return 'FetchedValue(for_update=%r)' % self.for_update - + return util.generic_repr(self) class DefaultClause(FetchedValue): """A DDL-specified DEFAULT column value. @@ -2178,10 +2168,12 @@ class Index(ColumnCollectionMixin, SchemaItem): bind._run_visitor(ddl.SchemaDropper, self) def __repr__(self): - return 'Index("%s", %s%s)' % ( - self.name, - ', '.join(repr(c) for c in self.columns), - (self.unique and ', unique=True') or '') + return 'Index(%s)' % ( + ", ".join( + [repr(self.name)] + + [repr(c) for c in self.columns] + + (self.unique and ["unique=True"] or []) + )) class MetaData(SchemaItem): """A collection of :class:`.Table` objects and their associated schema constructs. @@ -2248,7 +2240,7 @@ class MetaData(SchemaItem): self.reflect() def __repr__(self): - return 'MetaData(%r)' % self.bind + return 'MetaData(bind=%r)' % self.bind def __contains__(self, table_or_key): if not isinstance(table_or_key, basestring): diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 11d4cdaf60..453cafd830 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -237,9 +237,12 @@ def generic_repr(obj): for arg in args[1:-default_len]: yield repr(getattr(obj, arg, None)) for (arg, defval) in zip(args[-default_len:], defaults): - val = getattr(obj, arg, None) - if val != defval: - yield '%s=%r' % (arg, val) + try: + val = getattr(obj, arg, None) + if val != defval: + yield '%s=%r' % (arg, val) + except: + pass return "%s(%s)" % (obj.__class__.__name__, ", ".join(genargs())) class portable_instancemethod(object): diff --git a/test/aaa_profiling/test_orm.py b/test/aaa_profiling/test_orm.py index 9e30c0b4ae..4da0979948 100644 --- a/test/aaa_profiling/test_orm.py +++ b/test/aaa_profiling/test_orm.py @@ -196,6 +196,8 @@ class LoadManyToOneFromIdentityTest(fixtures.MappedTest): go() class MergeBackrefsTest(fixtures.MappedTest): + __only_on__ = 'sqlite' # keep things simple + @classmethod def define_tables(cls, metadata): Table('a', metadata, diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py index 406db27a7a..2107a3a77d 100644 --- a/test/sql/test_metadata.py +++ b/test/sql/test_metadata.py @@ -549,6 +549,35 @@ class MetaDataTest(fixtures.TestBase, ComparesTables): 'fake_table', MetaData(testing.db), autoload=True) + def test_assorted_repr(self): + t1 = Table("foo", MetaData(), Column("x", Integer)) + i1 = Index("bar", t1.c.x) + ck = schema.CheckConstraint("x > y", name="someconstraint") + + for const, exp in ( + (Sequence("my_seq"), + "Sequence('my_seq')"), + (Sequence("my_seq", start=5), + "Sequence('my_seq', start=5)"), + (Column("foo", Integer), + "Column('foo', Integer(), table=None)"), + (Table("bar", MetaData(), Column("x", String)), + "Table('bar', MetaData(bind=None), " + "Column('x', String(), table=), schema=None)"), + (schema.DefaultGenerator(for_update=True), + "DefaultGenerator(for_update=True)"), + (schema.Index("bar"), "Index('bar')"), + (i1, "Index('bar', Column('x', Integer(), table=))"), + (schema.FetchedValue(), "FetchedValue()"), + (ck, + "CheckConstraint(" + "%s" + ", name='someconstraint')" % repr(ck.sqltext)), + ): + eq_( + repr(const), + exp + ) class TableTest(fixtures.TestBase, AssertsCompiledSQL): def test_prefixes(self): @@ -1138,7 +1167,7 @@ class CatchAllEventsTest(fixtures.TestBase): canary.append("%s->%s" % (obj.__class__.__name__, parent.__class__.__name__)) def after_attach(obj, parent): - canary.append("%s->%s" % (obj, parent)) + canary.append("%s->%s" % (obj.__class__.__name__, parent)) event.listen(schema.SchemaItem, "before_parent_attach", before_attach) event.listen(schema.SchemaItem, "after_parent_attach", after_attach) @@ -1154,22 +1183,15 @@ class CatchAllEventsTest(fixtures.TestBase): eq_( canary, - [ - 'Sequence->Column', - "Sequence('foo_id', start=None, increment=None, optional=False)->id", - 'ForeignKey->Column', - "ForeignKey('t2.id')->bar", - 'Table->MetaData', - 'PrimaryKeyConstraint->Table', 'PrimaryKeyConstraint()->t1', - 'Column->Table', 't1.id->t1', - 'Column->Table', 't1.bar->t1', - 'ForeignKeyConstraint->Table', - 'ForeignKeyConstraint()->t1', - 't1->MetaData(None)', - 'Table->MetaData', - 'PrimaryKeyConstraint->Table', 'PrimaryKeyConstraint()->t2', - 'Column->Table', - 't2.id->t2', 't2->MetaData(None)'] + ['Sequence->Column', 'Sequence->id', 'ForeignKey->Column', + 'ForeignKey->bar', 'Table->MetaData', + 'PrimaryKeyConstraint->Table', 'PrimaryKeyConstraint->t1', + 'Column->Table', 'Column->t1', 'Column->Table', + 'Column->t1', 'ForeignKeyConstraint->Table', + 'ForeignKeyConstraint->t1', 'Table->MetaData(bind=None)', + 'Table->MetaData', 'PrimaryKeyConstraint->Table', + 'PrimaryKeyConstraint->t2', 'Column->Table', 'Column->t2', + 'Table->MetaData(bind=None)'] ) def test_events_per_constraint(self):