diff --git a/django/utils/functional.py b/django/utils/functional.py index f19a46aa3a..13aec9cb82 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -222,6 +222,10 @@ class LazyObject(object): By subclassing, you have the opportunity to intercept and alter the instantiation. If you don't need to do that, use SimpleLazyObject. """ + + # Avoid infinite recursion when tracing __init__ (#19456). + _wrapped = None + def __init__(self): self._wrapped = empty diff --git a/tests/utils_tests/simplelazyobject.py b/tests/utils_tests/simplelazyobject.py index 3bd6bf1e7f..883e60aa81 100644 --- a/tests/utils_tests/simplelazyobject.py +++ b/tests/utils_tests/simplelazyobject.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import copy import pickle +import sys from django.utils import six from django.utils.unittest import TestCase @@ -138,3 +139,16 @@ class TestUtilsSimpleLazyObject(TestCase): del lazydict['one'] with self.assertRaises(KeyError): lazydict['one'] + + def test_trace(self): + # See ticket #19456 + old_trace_func = sys.gettrace() + try: + def trace_func(frame, event, arg): + frame.f_locals['self'].__class__ + if old_trace_func is not None: + old_trace_func(frame, event, arg) + sys.settrace(trace_func) + SimpleLazyObject(None) + finally: + sys.settrace(old_trace_func)