summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-08-14 12:20:54 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2011-08-14 12:20:54 -0400
commit76a9219a1ebe9d6abdc510fec87968df905be4fe (patch)
tree8c7f0304d7806b7ebe30597059785e6eaa474ddc
parent9a2edbf3ebf04bfff3ad2a7214605503d5cdcaa2 (diff)
downloadsqlalchemy-76a9219a1ebe9d6abdc510fec87968df905be4fe.tar.gz
- 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]
-rw-r--r--CHANGES8
-rw-r--r--lib/sqlalchemy/schema.py28
-rw-r--r--lib/sqlalchemy/util/langhelpers.py9
-rw-r--r--test/aaa_profiling/test_orm.py2
-rw-r--r--test/sql/test_metadata.py56
5 files changed, 65 insertions, 38 deletions
diff --git a/CHANGES b/CHANGES
index 4f244b445..5c1b2425c 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 7b5b3ab70..8fd4e7578 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 11d4cdaf6..453cafd83 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 9e30c0b4a..4da097994 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 406db27a7..2107a3a77 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=<bar>), schema=None)"),
+ (schema.DefaultGenerator(for_update=True),
+ "DefaultGenerator(for_update=True)"),
+ (schema.Index("bar"), "Index('bar')"),
+ (i1, "Index('bar', Column('x', Integer(), table=<foo>))"),
+ (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):