Skip to content

Commit

Permalink
Fixed #19543 -- implemented SimpleLazyObject.__repr__
Browse files Browse the repository at this point in the history
Thanks to Florian Hahn for the patch
  • Loading branch information
ptone committed Mar 7, 2013
1 parent c8e3a23 commit 0ea5bf8
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
9 changes: 9 additions & 0 deletions django/utils/functional.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@ def __newobj__(cls, *args):
def __reduce__(self): def __reduce__(self):
return (self.__newobj__, (self.__class__,), self.__getstate__()) return (self.__newobj__, (self.__class__,), self.__getstate__())


# Return a meaningful representation of the lazy object for debugging
# without evaluating the wrapped object.
def __repr__(self):
if self._wrapped is empty:
repr_attr = self._setupfunc
else:
repr_attr = self._wrapped
return '<SimpleLazyObject: %r>' % repr_attr

# Need to pretend to be the wrapped class, for the sake of objects that care # Need to pretend to be the wrapped class, for the sake of objects that care
# about this (especially in equality tests) # about this (especially in equality tests)
__class__ = property(new_method_proxy(operator.attrgetter("__class__"))) __class__ = property(new_method_proxy(operator.attrgetter("__class__")))
Expand Down
3 changes: 3 additions & 0 deletions docs/releases/1.6.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ Minor features
:setting:`TEMPLATE_STRING_IF_INVALID` for variables not present in the :setting:`TEMPLATE_STRING_IF_INVALID` for variables not present in the
context, just like other template constructs. context, just like other template constructs.


* SimpleLazyObjects will now present more helpful representations in shell
debugging situations.

Backwards incompatible changes in 1.6 Backwards incompatible changes in 1.6
===================================== =====================================


Expand Down
16 changes: 12 additions & 4 deletions tests/utils_tests/simplelazyobject.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -59,10 +59,18 @@ def test_hash(self):
hash(SimpleLazyObject(complex_object))) hash(SimpleLazyObject(complex_object)))


def test_repr(self): def test_repr(self):
# For debugging, it will really confuse things if there is no clue that # First, for an unevaluated SimpleLazyObject
# SimpleLazyObject is actually a proxy object. So we don't x = SimpleLazyObject(complex_object)
# proxy __repr__ # __repr__ contains __repr__ of setup function and does not evaluate
self.assertTrue("SimpleLazyObject" in repr(SimpleLazyObject(complex_object))) # the SimpleLazyObject
self.assertEqual("<SimpleLazyObject: %r>" % complex_object, repr(x))
self.assertEqual(empty, x._wrapped)

# Second, for an evaluated SimpleLazyObject
name = x.name # evaluate
self.assertTrue(isinstance(x._wrapped, _ComplexObject))
# __repr__ contains __repr__ of wrapped object
self.assertEqual("<SimpleLazyObject: %r>" % x._wrapped, repr(x))


def test_bytes(self): def test_bytes(self):
self.assertEqual(b"I am _ComplexObject('joe')", self.assertEqual(b"I am _ComplexObject('joe')",
Expand Down

0 comments on commit 0ea5bf8

Please sign in to comment.