[Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.26,1.27
Guido van Rossum
gvanrossum@users.sourceforge.net
Thu, 30 Aug 2001 13:52:42 -0700
Update of /cvsroot/python/python/dist/src/Lib/test
In directory usw-pr-cvs1:/tmp/cvs-serv10900
Modified Files:
test_descr.py
Log Message:
metaclass(): add some more examples of metaclasses, including one
using cooperative multiple inheritance.
inherits(): add a test for subclassing the unicode type.
Index: test_descr.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -d -r1.26 -r1.27
*** test_descr.py 2001/08/30 20:06:08 1.26
--- test_descr.py 2001/08/30 20:52:40 1.27
***************
*** 393,396 ****
--- 393,397 ----
c = C()
verify(c.__spam__ == 1)
+
class _instance(object):
pass
***************
*** 421,424 ****
--- 422,515 ----
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..."
***************
*** 1193,1196 ****
--- 1284,1300 ----
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():