summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2009-05-08 03:25:19 (GMT)
committerBenjamin Peterson <benjamin@python.org>2009-05-08 03:25:19 (GMT)
commit224205fde2af8fdbbd11de0b219880df9a0edabd (patch)
tree85c6a9b1b07d31f712654d82b2e25cf5abeac92a /Lib
parentc04dad772c4c01a60b3c0e70e3ae3e53bf7f9b66 (diff)
downloadcpython-224205fde2af8fdbbd11de0b219880df9a0edabd.zip
cpython-224205fde2af8fdbbd11de0b219880df9a0edabd.tar.gz
cpython-224205fde2af8fdbbd11de0b219880df9a0edabd.tar.bz2
Merged revisions 72461 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r72461 | benjamin.peterson | 2009-05-07 22:06:00 -0500 (Thu, 07 May 2009) | 1 line add _PyObject_LookupSpecial to handle fetching special method lookup ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_descr.py52
1 files changed, 52 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 4558b98..7137095 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1538,6 +1538,58 @@ order (MRO) for bases """
self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound
self.assert_(repr(C.foo.__get__(C(1))).startswith("<bound method "))
+ def test_special_method_lookup(self):
+ # The lookup of special methods bypasses __getattr__ and
+ # __getattribute__, but they still can be descriptors.
+
+ def run_context(manager):
+ with manager:
+ pass
+ def iden(self):
+ return self
+ def hello(self):
+ return b"hello"
+
+ # It would be nice to have every special method tested here, but I'm
+ # only listing the ones I can remember outside of typeobject.c, since it
+ # does it right.
+ specials = [
+ ("__bytes__", bytes, hello),
+ # These two fail because the compiler generates LOAD_ATTR to look
+ # them up. We'd have to add a new opcode to fix this, and it's
+ # probably not worth it.
+ # ("__enter__", run_context, iden),
+ # ("__exit__", run_context, iden),
+ ]
+
+ class Checker(object):
+ def __getattr__(self, attr, test=self):
+ test.fail("__getattr__ called with {0}".format(attr))
+ def __getattribute__(self, attr, test=self):
+ test.fail("__getattribute__ called with {0}".format(attr))
+ class SpecialDescr(object):
+ def __init__(self, impl):
+ self.impl = impl
+ def __get__(self, obj, owner):
+ record.append(1)
+ return self
+ def __call__(self, *args):
+ return self.impl(*args)
+
+
+ for name, runner, meth_impl in specials:
+ class X(Checker):
+ pass
+ setattr(X, name, staticmethod(meth_impl))
+ runner(X())
+
+ record = []
+ class X(Checker):
+ pass
+ setattr(X, name, SpecialDescr(meth_impl))
+ runner(X())
+ self.assertEqual(record, [1], name)
+
def test_specials(self):
# Testing special operators...
# Test operators like __hash__ for which a built-in default exists