summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2008-11-17 22:39:09 +0000
committerBenjamin Peterson <benjamin@python.org>2008-11-17 22:39:09 +0000
commit273c233c78d36f65059342981dcdc5b212a7e558 (patch)
treefad34c76f3329915666c8831dd70f2754a42b040 /Lib
parent233bb00c1c8fef8434710c7891e955323f48f256 (diff)
downloadcpython-git-273c233c78d36f65059342981dcdc5b212a7e558.tar.gz
when __getattr__ is a descriptor, call it correctly; fixes #4230
patch from Ziga Seilnacht
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_descr.py40
1 files changed, 40 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index f74073811f..b57e0fae05 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -4289,6 +4289,46 @@ order (MRO) for bases """
c[1:2] = 3
self.assertEqual(c.value, 3)
+ def test_getattr_hooks(self):
+ # issue 4230
+
+ class Descriptor(object):
+ counter = 0
+ def __get__(self, obj, objtype=None):
+ def getter(name):
+ self.counter += 1
+ raise AttributeError(name)
+ return getter
+
+ descr = Descriptor()
+ class A(object):
+ __getattribute__ = descr
+ class B(object):
+ __getattr__ = descr
+ class C(object):
+ __getattribute__ = descr
+ __getattr__ = descr
+
+ self.assertRaises(AttributeError, getattr, A(), "attr")
+ self.assertEquals(descr.counter, 1)
+ self.assertRaises(AttributeError, getattr, B(), "attr")
+ self.assertEquals(descr.counter, 2)
+ self.assertRaises(AttributeError, getattr, C(), "attr")
+ self.assertEquals(descr.counter, 4)
+
+ import gc
+ class EvilGetattribute(object):
+ # This used to segfault
+ def __getattr__(self, name):
+ raise AttributeError(name)
+ def __getattribute__(self, name):
+ del EvilGetattribute.__getattr__
+ for i in range(5):
+ gc.collect()
+ raise AttributeError(name)
+
+ self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr")
+
class DictProxyTests(unittest.TestCase):
def setUp(self):