[Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.86,1.87

Guido van Rossum gvanrossum@users.sourceforge.net
Thu, 11 Oct 2001 11:33:56 -0700


Update of /cvsroot/python/python/dist/src/Lib/test
In directory usw-pr-cvs1:/tmp/cvs-serv25854/Lib/test

Modified Files:
	test_descr.py 
Log Message:
Another step in the right direction: when a new class's attribute
corresponding to a dispatch slot (e.g. __getitem__ or __add__) is set,
calculate the proper dispatch slot and propagate the change to all
subclasses.  Because of multiple inheritance, there's no easy way to
avoid always recursing down the tree of subclasses.  Who cares?

(There's more to do, but this works.  There's also a test for this now.)



Index: test_descr.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v
retrieving revision 1.86
retrieving revision 1.87
diff -C2 -d -r1.86 -r1.87
*** test_descr.py	2001/10/09 20:36:44	1.86
--- test_descr.py	2001/10/11 18:33:53	1.87
***************
*** 8,11 ****
--- 8,15 ----
          raise TestFailed, "%r == %r" % (a, b)
  
+ def veris(a, b):
+     if a is not b:
+         raise TestFailed, "%r is %r" % (a, b)
+ 
  def testunop(a, res, expr="len(a)", meth="__len__"):
      if verbose: print "checking", expr
***************
*** 624,631 ****
          # 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)
--- 628,633 ----
          # Automatically add __super to the class
          # This trick only works for dynamic classes
          def __new__(metaclass, name, bases, dict):
!             assert dict.get("__dynamic__", 1)
              cls = super(autosuper, metaclass).__new__(metaclass,
                                                        name, bases, dict)
***************
*** 950,954 ****
      # Test handling of int*seq and seq*int
      class I(int):
!         __dynamic__ = 1
      vereq("a"*I(2), "aa")
      vereq(I(2)*"a", "aa")
--- 952,956 ----
      # Test handling of int*seq and seq*int
      class I(int):
!         __dynamic__ = 1 # XXX why?
      vereq("a"*I(2), "aa")
      vereq(I(2)*"a", "aa")
***************
*** 959,963 ****
      # Test handling of long*seq and seq*long
      class L(long):
!         __dynamic__ = 1
      vereq("a"*L(2L), "aa")
      vereq(L(2L)*"a", "aa")
--- 961,965 ----
      # Test handling of long*seq and seq*long
      class L(long):
!         __dynamic__ = 1 # XXX why?
      vereq("a"*L(2L), "aa")
      vereq(L(2L)*"a", "aa")
***************
*** 968,972 ****
      # Test comparison of classes with dynamic metaclasses
      class dynamicmetaclass(type):
!         __dynamic__ = 1
      class someclass:
          __metaclass__ = dynamicmetaclass
--- 970,974 ----
      # Test comparison of classes with dynamic metaclasses
      class dynamicmetaclass(type):
!         __dynamic__ = 1 # XXX ???
      class someclass:
          __metaclass__ = dynamicmetaclass
***************
*** 1254,1258 ****
      # Test the default behavior for dynamic classes
      class D(object):
!         __dynamic__ = 1
          def __getitem__(self, i):
              if 0 <= i < 10: return i
--- 1256,1260 ----
      # Test the default behavior for dynamic classes
      class D(object):
!         __dynamic__ = 1 # XXX why?
          def __getitem__(self, i):
              if 0 <= i < 10: return i
***************
*** 1564,1568 ****
  
      class madcomplex(complex):
!         __dynamic__ = 0
          def __repr__(self):
              return "%.17gj%+.17g" % (self.imag, self.real)
--- 1566,1570 ----
  
      class madcomplex(complex):
!         __dynamic__ = 0 # XXX Shouldn't be necessary
          def __repr__(self):
              return "%.17gj%+.17g" % (self.imag, self.real)
***************
*** 1570,1591 ****
      vereq(repr(a), "4j-3")
      base = complex(-3, 4)
!     verify(base.__class__ is complex)
      vereq(a, base)
      vereq(complex(a), base)
!     verify(complex(a).__class__ is complex)
      a = madcomplex(a)  # just trying another form of the constructor
      vereq(repr(a), "4j-3")
      vereq(a, base)
      vereq(complex(a), base)
!     verify(complex(a).__class__ is complex)
      vereq(hash(a), hash(base))
!     verify((+a).__class__ is complex)
!     verify((a + 0).__class__ is complex)
      vereq(a + 0, base)
!     verify((a - 0).__class__ is complex)
      vereq(a - 0, base)
!     verify((a * 1).__class__ is complex)
      vereq(a * 1, base)
!     verify((a / 1).__class__ is complex)
      vereq(a / 1, base)
  
--- 1572,1593 ----
      vereq(repr(a), "4j-3")
      base = complex(-3, 4)
!     veris(base.__class__, complex)
      vereq(a, base)
      vereq(complex(a), base)
!     veris(complex(a).__class__, complex)
      a = madcomplex(a)  # just trying another form of the constructor
      vereq(repr(a), "4j-3")
      vereq(a, base)
      vereq(complex(a), base)
!     veris(complex(a).__class__, complex)
      vereq(hash(a), hash(base))
!     veris((+a).__class__, complex)
!     veris((a + 0).__class__, complex)
      vereq(a + 0, base)
!     veris((a - 0).__class__, complex)
      vereq(a - 0, base)
!     veris((a * 1).__class__, complex)
      vereq(a * 1, base)
!     veris((a / 1).__class__, complex)
      vereq(a / 1, base)
  
***************
*** 2238,2241 ****
--- 2240,2303 ----
              return self.lower() == other.lower()
  
+ def subclasspropagation():
+     if verbose: print "Testing propagation of slot functions to subclasses..."
+     class A(object):
+         pass
+     class B(A):
+         pass
+     class C(A):
+         pass
+     class D(B, C):
+         pass
+     d = D()
+     vereq(hash(d), id(d))
+     A.__hash__ = lambda self: 42
+     vereq(hash(d), 42)
+     C.__hash__ = lambda self: 314
+     vereq(hash(d), 314)
+     B.__hash__ = lambda self: 144
+     vereq(hash(d), 144)
+     D.__hash__ = lambda self: 100
+     vereq(hash(d), 100)
+     del D.__hash__
+     vereq(hash(d), 144)
+     del B.__hash__
+     vereq(hash(d), 314)
+     del C.__hash__
+     vereq(hash(d), 42)
+     del A.__hash__
+     vereq(hash(d), id(d))
+     d.foo = 42
+     d.bar = 42
+     vereq(d.foo, 42)
+     vereq(d.bar, 42)
+     def __getattribute__(self, name):
+         if name == "foo":
+             return 24
+         return object.__getattribute__(self, name)
+     A.__getattribute__ = __getattribute__
+     vereq(d.foo, 24)
+     vereq(d.bar, 42)
+     def __getattr__(self, name):
+         if name in ("spam", "foo", "bar"):
+             return "hello"
+         raise AttributeError, name
+     B.__getattr__ = __getattr__
+     vereq(d.spam, "hello")
+     vereq(d.foo, 24)
+     vereq(d.bar, 42)
+     del A.__getattribute__
+     vereq(d.foo, 42)
+     del d.foo
+     vereq(d.foo, "hello")
+     vereq(d.bar, 42)
+     del B.__getattr__
+     try:
+         d.foo
+     except AttributeError:
+         pass
+     else:
+         raise TestFailed, "d.foo should be undefined now"
+     
  
  def test_main():
***************
*** 2285,2288 ****
--- 2347,2351 ----
      copies()
      binopoverride()
+     subclasspropagation()
      if verbose: print "All OK"