the UUID example on the site that uses TypeEngine
as the "impl".
+ - Added an improved repr() to TypeEngine objects
+ that will only display constructor args which
+ are positional or kwargs that deviate
+ from the default. [ticket:2209]
+
- engine
- Use urllib.parse_qsl() in Python 2.6 and above,
no deprecation warning about cgi.parse_qsl()
"constructor %s is deprecated" % self.__class__)
def __repr__(self):
- return "%s(%s)" % (
- self.__class__.__name__,
- ", ".join("%s=%r" % (k, getattr(self, k, None))
- for k in inspect.getargspec(self.__init__)[0][1:]))
-
+ return util.generic_repr(self)
class UserDefinedType(TypeEngine):
"""Base for user defined types.
monkeypatch_proxied_specials, asbool, bool_or_str, coerce_kw_type,\
duck_type_collection, assert_arg_type, symbol, dictlike_iteritems,\
classproperty, set_creation_order, warn_exception, warn, NoneType,\
- constructor_copy, methods_equivalent, chop_traceback, asint
+ constructor_copy, methods_equivalent, chop_traceback, asint,\
+ generic_repr
from deprecations import warn_deprecated, warn_pending_deprecation, \
deprecated, pending_deprecation
else:
return func_or_cls
+def generic_repr(obj):
+ """Produce a __repr__() based on direct association of the __init__()
+ specification vs. same-named attributes present.
+
+ """
+ def genargs():
+ try:
+ (args, vargs, vkw, defaults) = inspect.getargspec(obj.__init__)
+ except TypeError:
+ return
+
+ default_len = defaults and len(defaults) or 0
+
+ if not default_len:
+ for arg in args[1:]:
+ yield repr(getattr(obj, arg, None))
+ if vargs is not None and hasattr(obj, vargs):
+ yield ', '.join(repr(val) for val in getattr(obj, vargs))
+ else:
+ 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)
+ return "%s(%s)" % (obj.__class__.__name__, ", ".join(genargs()))
+
class portable_instancemethod(object):
"""Turn an instancemethod into a (parent, name) pair
to produce a serializable callable.
test(O.__init__, custom_spec)
+
+class GenericReprTest(fixtures.TestBase):
+ def test_all_positional(self):
+ class Foo(object):
+ def __init__(self, a, b, c):
+ self.a = a
+ self.b = b
+ self.c = c
+ eq_(
+ util.generic_repr(Foo(1, 2, 3)),
+ "Foo(1, 2, 3)"
+ )
+
+ def test_positional_plus_kw(self):
+ class Foo(object):
+ def __init__(self, a, b, c=5, d=4):
+ self.a = a
+ self.b = b
+ self.c = c
+ self.d = d
+ eq_(
+ util.generic_repr(Foo(1, 2, 3, 6)),
+ "Foo(1, 2, c=3, d=6)"
+ )
+
+ def test_kw_defaults(self):
+ class Foo(object):
+ def __init__(self, a=1, b=2, c=3, d=4):
+ self.a = a
+ self.b = b
+ self.c = c
+ self.d = d
+ eq_(
+ util.generic_repr(Foo(1, 5, 3, 7)),
+ "Foo(b=5, d=7)"
+ )
+
+ def test_discard_vargs(self):
+ class Foo(object):
+ def __init__(self, a, b, *args):
+ self.a = a
+ self.b = b
+ self.c, self.d = args[0:2]
+ eq_(
+ util.generic_repr(Foo(1, 2, 3, 4)),
+ "Foo(1, 2)"
+ )
+
+ def test_discard_vargs_kwargs(self):
+ class Foo(object):
+ def __init__(self, a, b, *args, **kw):
+ self.a = a
+ self.b = b
+ self.c, self.d = args[0:2]
+ eq_(
+ util.generic_repr(Foo(1, 2, 3, 4, x=7, y=4)),
+ "Foo(1, 2)"
+ )
+
+ def test_significant_vargs(self):
+ class Foo(object):
+ def __init__(self, a, b, *args):
+ self.a = a
+ self.b = b
+ self.args = args
+ eq_(
+ util.generic_repr(Foo(1, 2, 3, 4)),
+ "Foo(1, 2, 3, 4)"
+ )
+
+ def test_no_args(self):
+ class Foo(object):
+ def __init__(self):
+ pass
+ eq_(
+ util.generic_repr(Foo()),
+ "Foo()"
+ )
+
+ def test_no_init(self):
+ class Foo(object):
+ pass
+ eq_(
+ util.generic_repr(Foo()),
+ "Foo()"
+ )
+
class AsInterfaceTest(fixtures.TestBase):
class Something(object):
getattr(t2, k) == t1.__dict__[k] or \
t1.__dict__[k] is None
+ @testing.uses_deprecated()
+ def test_repr(self):
+ for typ in self._all_types():
+ if typ in (types.TypeDecorator, types.TypeEngine):
+ continue
+ elif typ is dialects.postgresql.ARRAY:
+ t1 = typ(String)
+ else:
+ t1 = typ()
+ repr(t1)
+
def test_plain_init_deprecation_warning(self):
for typ in (Integer, Date, SmallInteger):
assert_raises_message(