[pypy-commit] pypy default: Add docstring, and add a "special_methods" parameter, which seems safer

arigo noreply at buildbot.pypy.org
Tue Aug 20 14:12:23 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r66254:5b980423ca91
Date: 2013-08-20 14:11 +0200
http://bitbucket.org/pypy/pypy/changeset/5b980423ca91/

Log:	Add docstring, and add a "special_methods" parameter, which seems
	safer than filtering out a few random names.

diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -723,13 +723,24 @@
 
 # ____________________________________________________________
 
-def import_from_mixin(M):
+def import_from_mixin(M, special_methods=['__init__', '__del__']):
+    """Copy all methods and class attributes from the class M into
+    the current scope.  Should be called when defining a class body.
+    Function and staticmethod objects are duplicated, which means
+    that annotation will not consider them as identical to another
+    copy in another unrelated class.
+    
+    By default, "special" methods and class attributes, with a name
+    like "__xxx__", are not copied unless they are "__init__" or
+    "__del__".  The list can be changed with the optional second
+    argument.
+    """
     flatten = {}
     for base in inspect.getmro(M):
         for key, value in base.__dict__.items():
-            if key in ('__module__', '__name__', '__dict__',
-                       '__doc__', '__weakref__'):
-                continue
+            if key.startswith('__') and key.endswith('__'):
+                if key not in special_methods:
+                    continue
             if key in flatten:
                 continue
             if isinstance(value, types.FunctionType):
diff --git a/rpython/rlib/test/test_objectmodel.py b/rpython/rlib/test/test_objectmodel.py
--- a/rpython/rlib/test/test_objectmodel.py
+++ b/rpython/rlib/test/test_objectmodel.py
@@ -602,3 +602,13 @@
                 in str(e))
     else:
         raise AssertionError("failed to detect overwritten attribute")
+
+    class M(object):
+        def __str__(self):
+            return "m!"
+    class A(object):
+        import_from_mixin(M)
+    class B(object):
+        import_from_mixin(M, special_methods=['__str__'])
+    assert str(A()).startswith('<')
+    assert str(B()) == "m!"


More information about the pypy-commit mailing list