Skip to content

Commit 8ac8b6c

Browse files
committed
Add some checks for "own" attributes in __getattr__. Fixes infinite recursion issues when factory does something crazy like raising AttributeError. Fixes ionelmc#3.
1 parent cd6ba17 commit 8ac8b6c

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

src/lazy_object_proxy/simple.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ def __new__(cls, name, bases, dictionary):
7272

7373

7474
class Proxy(with_metaclass(_ProxyMetaType)):
75+
__factory__ = None
76+
7577
def __init__(self, factory):
7678
self.__dict__['__factory__'] = factory
7779

@@ -122,7 +124,10 @@ def __setattr__(self, name, value):
122124
setattr(self.__wrapped__, name, value)
123125

124126
def __getattr__(self, name):
125-
return getattr(self.__wrapped__, name)
127+
if name in ('__wrapped__', '__factory__'):
128+
raise AttributeError(name)
129+
else:
130+
return getattr(self.__wrapped__, name)
126131

127132
def __delattr__(self, name):
128133
if hasattr(type(self), name):

src/lazy_object_proxy/slots.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,10 @@ def __setattr__(self, name, value, __setattr__=object.__setattr__):
182182
setattr(self.__wrapped__, name, value)
183183

184184
def __getattr__(self, name):
185-
return getattr(self.__wrapped__, name)
185+
if name in ('__wrapped__', '__factory__'):
186+
raise AttributeError(name)
187+
else:
188+
return getattr(self.__wrapped__, name)
186189

187190
def __delattr__(self, name, __delattr__=object.__delattr__):
188191
if hasattr(type(self), name):

tests/test_lazy_object_proxy.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,15 @@ class Foo(object):
15981598
del proxy.__wrapped__
15991599

16001600

1601+
def test_raise_attribute_error(lazy_object_proxy):
1602+
def foo():
1603+
raise AttributeError("boom!")
1604+
proxy = lazy_object_proxy.Proxy(foo)
1605+
pytest.raises(AttributeError, str, proxy)
1606+
pytest.raises(AttributeError, lambda: proxy.__wrapped__)
1607+
assert proxy.__factory__ is foo
1608+
1609+
16011610
def test_new(lazy_object_proxy):
16021611
a = lazy_object_proxy.Proxy.__new__(lazy_object_proxy.Proxy)
16031612
b = lazy_object_proxy.Proxy.__new__(lazy_object_proxy.Proxy)

0 commit comments

Comments
 (0)