summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_descr.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index ec966a1..f79af4d 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -392,6 +392,7 @@ def metaclass():
verify(C.__spam__ == 1)
c = C()
verify(c.__spam__ == 1)
+
class _instance(object):
pass
class M2(object):
@@ -420,6 +421,96 @@ def metaclass():
c = C()
verify(c.spam() == 42)
+ # More metaclass examples
+
+ class autosuper(type):
+ # Automatically add __super to the class
+ # This trick only works for dynamic classes
+ # so we force __dynamic__ = 1
+ def __new__(metaclass, name, bases, dict):
+ # XXX Should check that name isn't already a base class name
+ dict["__dynamic__"] = 1
+ cls = super(autosuper, metaclass).__new__(metaclass,
+ name, bases, dict)
+ while name[:1] == "_":
+ name = name[1:]
+ while name[-1:] == "_":
+ name = name[:-1]
+ if name:
+ name = "_%s__super" % name
+ else:
+ name = "__super"
+ setattr(cls, name, super(cls))
+ return cls
+ class A:
+ __metaclass__ = autosuper
+ def meth(self):
+ return "A"
+ class B(A):
+ def meth(self):
+ return "B" + self.__super.meth()
+ class C(A):
+ def meth(self):
+ return "C" + self.__super.meth()
+ class D(C, B):
+ def meth(self):
+ return "D" + self.__super.meth()
+ verify(D().meth() == "DCBA")
+ class E(B, C):
+ def meth(self):
+ return "E" + self.__super.meth()
+ verify(E().meth() == "EBCA")
+
+ class autogetset(type):
+ # Automatically create getset attributes when methods
+ # named _get_x and/or _set_x are found
+ def __new__(metaclass, name, bases, dict):
+ hits = {}
+ for key, val in dict.iteritems():
+ if key.startswith("_get_"):
+ key = key[5:]
+ get, set = hits.get(key, (None, None))
+ get = val
+ hits[key] = get, set
+ elif key.startswith("_set_"):
+ key = key[5:]
+ get, set = hits.get(key, (None, None))
+ set = val
+ hits[key] = get, set
+ for key, (get, set) in hits.iteritems():
+ dict[key] = getset(get, set)
+ return super(autogetset, metaclass).__new__(metaclass,
+ name, bases, dict)
+ class A:
+ __metaclass__ = autogetset
+ def _get_x(self):
+ return -self.__x
+ def _set_x(self, x):
+ self.__x = -x
+ a = A()
+ verify(not hasattr(a, "x"))
+ a.x = 12
+ verify(a.x == 12)
+ verify(a._A__x == -12)
+
+ class multimetaclass(autogetset, autosuper):
+ # Merge of multiple cooperating metaclasses
+ pass
+ class A:
+ __metaclass__ = multimetaclass
+ def _get_x(self):
+ return "A"
+ class B(A):
+ def _get_x(self):
+ return "B" + self.__super._get_x()
+ class C(A):
+ def _get_x(self):
+ return "C" + self.__super._get_x()
+ class D(C, B):
+ def _get_x(self):
+ return "D" + self.__super._get_x()
+ verify(D().x == "DCBA")
+
def pymods():
if verbose: print "Testing Python subclass of module..."
log = []
@@ -1193,6 +1284,19 @@ def inherits():
u = t.rev()
verify(u == s)
+ class madunicode(unicode):
+ _rev = None
+ def rev(self):
+ if self._rev is not None:
+ return self._rev
+ L = list(self)
+ L.reverse()
+ self._rev = self.__class__(u"".join(L))
+ return self._rev
+ u = madunicode("ABCDEF")
+ verify(u.rev() == madunicode(u"FEDCBA"))
+ verify(u.rev().rev() == madunicode(u"ABCDEF"))
+
def all():
lists()
dicts()