[pypy-svn] r5618 - pypy/trunk/src/pypy/module

arigo at codespeak.net arigo at codespeak.net
Thu Jul 22 18:14:38 CEST 2004


Author: arigo
Date: Thu Jul 22 18:14:37 2004
New Revision: 5618

Modified:
   pypy/trunk/src/pypy/module/__builtin__module.py
Log:
"Clean down" class super to make it behave more precisely like CPython's.


Modified: pypy/trunk/src/pypy/module/__builtin__module.py
==============================================================================
--- pypy/trunk/src/pypy/module/__builtin__module.py	(original)
+++ pypy/trunk/src/pypy/module/__builtin__module.py	Thu Jul 22 18:14:37 2004
@@ -576,14 +576,21 @@
 #     http://www.python.org/2.2.3/descrintro.html
 # it exposes the same special attributes as CPython's.
 class super(object):
-    def __init__(self, type, obj=None):
-        # XXX check the arguments
-        self.__thisclass__ = type
-        self.__self__ = obj
-        if obj is not None and isinstance(obj, type):
-            self.__self_class__ = object.__getattribute__(obj, "__class__")
+    def __init__(self, typ, obj=None):
+        if obj is None:
+            objcls = None        # unbound super object
+        elif _issubtype(type(obj), type) and _issubtype(obj, type):
+            objcls = obj         # special case for class methods
+        elif _issubtype(type(obj), typ):
+            objcls = type(obj)   # normal case
         else:
-            self.__self_class__ = obj
+            objcls = getattr(obj, '__class__', type(obj))
+            if not _issubtype(objcls, typ):
+                raise TypeError, ("super(type, obj): "
+                                  "obj must be an instance or subtype of type")
+        self.__thisclass__ = typ
+        self.__self__ = obj
+        self.__self_class__ = objcls
     def __get__(self, obj, type=None):
         ga = object.__getattribute__
         if ga(self, '__self__') is None and obj is not None:
@@ -592,23 +599,24 @@
             return self
     def __getattribute__(self, attr):
         d = object.__getattribute__(self, '__dict__')
-        if attr in d:
-            return d[attr]   # for __self__, __thisclass__, __self_class__
-        mro = iter(d['__self_class__'].__mro__)
-        for cls in mro:
-            if cls is d['__thisclass__']:
-                break
-        # Note: mro is an iterator, so the second loop
-        # picks up where the first one left off!
-        for cls in mro:
-            try:                
-                x = cls.__dict__[attr]
-            except KeyError:
-                continue
-            if hasattr(x, '__get__'):
-                x = x.__get__(d['__self__'], type(d['__self__']))
-            return x
-        raise AttributeError, attr
+        if attr != '__class__' and d['__self_class__'] is not None:
+            # we want super().__class__ to be the real class
+            # and we don't do anything for unbound type objects
+            mro = iter(d['__self_class__'].__mro__)
+            for cls in mro:
+                if cls is d['__thisclass__']:
+                    break
+            # Note: mro is an iterator, so the second loop
+            # picks up where the first one left off!
+            for cls in mro:
+                try:                
+                    x = cls.__dict__[attr]
+                except KeyError:
+                    continue
+                if hasattr(x, '__get__'):
+                    x = x.__get__(d['__self__'], type(d['__self__']))
+                return x
+        return object.__getattribute__(self, attr)     # fall-back
 
 class complex(object):
     """complex(real[, imag]) -> complex number



More information about the Pypy-commit mailing list