mirror of
https://github.com/django/django.git
synced 2026-02-09 02:49:25 +08:00
Fixed #36810 -- Avoided infinite recursion in SimpleLazyObject.__repr__().
Detect when `SimpleLazyObject._setupfunc` is a bound method of the same instance to use a safe representation and avoid infinite recursion.
This commit is contained in:
@@ -407,7 +407,11 @@ class SimpleLazyObject(LazyObject):
|
||||
# without evaluating the wrapped object.
|
||||
def __repr__(self):
|
||||
if self._wrapped is empty:
|
||||
repr_attr = self._setupfunc
|
||||
# Avoid recursion if setupfunc is a bound method of this instance.
|
||||
if getattr(self._setupfunc, "__self__", None) is self:
|
||||
repr_attr = f"<bound method {self._setupfunc.__name__}>"
|
||||
else:
|
||||
repr_attr = self._setupfunc
|
||||
else:
|
||||
repr_attr = self._wrapped
|
||||
return "<%s: %r>" % (type(self).__name__, repr_attr)
|
||||
|
||||
@@ -348,6 +348,22 @@ class SimpleLazyObjectTestCase(LazyObjectTestCase):
|
||||
self.assertIsInstance(obj._wrapped, int)
|
||||
self.assertEqual(repr(obj), "<SimpleLazyObject: 42>")
|
||||
|
||||
def test_repr_bound_method(self):
|
||||
|
||||
class MyLazyGenerator(SimpleLazyObject):
|
||||
def __init__(self):
|
||||
super().__init__(self._generate)
|
||||
|
||||
def _generate(self):
|
||||
return "test-generated-value"
|
||||
|
||||
obj = MyLazyGenerator()
|
||||
self.assertEqual(repr(obj), "<MyLazyGenerator: '<bound method _generate>'>")
|
||||
self.assertIs(obj._wrapped, empty) # The evaluation hasn't happened.
|
||||
|
||||
self.assertEqual(str(obj), "test-generated-value") # Evaluate.
|
||||
self.assertEqual(repr(obj), "<MyLazyGenerator: 'test-generated-value'>")
|
||||
|
||||
def test_add(self):
|
||||
obj1 = self.lazy_wrap(1)
|
||||
self.assertEqual(obj1 + 1, 2)
|
||||
|
||||
Reference in New Issue
Block a user