[pypy-svn] r9669 - in pypy/dist/pypy: annotation translator/test

pedronis at codespeak.net pedronis at codespeak.net
Sat Mar 5 20:14:54 CET 2005


Author: pedronis
Date: Sat Mar  5 20:14:53 2005
New Revision: 9669

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/classdef.py
   pypy/dist/pypy/translator/test/snippet.py
   pypy/dist/pypy/translator/test/test_annrpython.py
Log:
first cut at activating support for specialized classes.

Notice the code to make the original class appear totally abstract.

+ test



Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Sat Mar  5 20:14:53 2005
@@ -12,6 +12,8 @@
 from pypy.interpreter.pycode import cpython_code_signature
 from pypy.interpreter.argument import ArgErr
 
+import inspect, new
+
 class Bookkeeper:
     """The log of choices that have been made while analysing the operations.
     It ensures that the same 'choice objects' will be returned if we ask
@@ -259,8 +261,26 @@
                 #
                 thing = func_with_new_name(thing, name or thing.func_name)
             elif isinstance(thing, (type, ClassType)):
-                assert not "not working yet"
-                thing = type(thing)(name or thing.__name__, (thing,))
+                superclasses = iter(inspect.getmro(thing))
+                superclasses.next() # skip thing itself
+                for cls in superclasses:
+                    assert not hasattr(cls, "_specialize_"), "for now specialization only for leaf classes"
+                
+                newdict = {}
+                for attrname,val in thing.__dict__.iteritems():
+                    if attrname == '_specialize_': # don't copy the marker
+                        continue
+                    if isinstance(val, FunctionType):
+                        fname = val.func_name
+                        if name:
+                            fname = "%s_for_%s" % (fname, name)
+                        newval = func_with_new_name(val, fname)
+                    # xxx more special cases
+                    else: 
+                        newval  = val
+                    newdict[attrname] = newval
+
+                thing = type(thing)(name or thing.__name__, (thing,), newdict)
             else:
                 raise Exception, "specializing %r?? why??"%thing
             self.cachespecializations[key] = thing

Modified: pypy/dist/pypy/annotation/classdef.py
==============================================================================
--- pypy/dist/pypy/annotation/classdef.py	(original)
+++ pypy/dist/pypy/annotation/classdef.py	Sat Mar  5 20:14:53 2005
@@ -66,7 +66,10 @@
                 assert base is object, ("multiple inheritance only supported "
                                         "with _mixin_: %r" % (cls,))
                 base = b1
-        mixeddict.update(cls.__dict__)
+        if '_specialize_' not in cls.__dict__: # otherwise make the original specialized class appear empty
+            mixeddict.update(cls.__dict__)
+        else:
+            assert not mixeddict, " _specialize_ +  mixins not both supported right now"
         self.basedef = bookkeeper.getclassdef(base)
         if self.basedef:
             self.basedef.subdefs[cls] = self

Modified: pypy/dist/pypy/translator/test/snippet.py
==============================================================================
--- pypy/dist/pypy/translator/test/snippet.py	(original)
+++ pypy/dist/pypy/translator/test/snippet.py	Sat Mar  5 20:14:53 2005
@@ -1002,6 +1002,30 @@
   raise Exception
 
 
+# class specialization
 
+class PolyStk:
+    _specialize_ = 'location'
+
+    def __init__(self):
+        self.itms = []
+
+    def push(self, v):
+        self.itms.append(v)
+
+    def top(self):
+        return self.itms[-1]
+
+
+def class_spec():
+    istk = PolyStk()
+    istk.push(1)
+    sstk = PolyStk()
+    sstk.push("a")
+    istk.push(2)
+    sstk.push("b")
+    if not isinstance(istk, PolyStk):
+        return "confused"
+    return istk.top(), sstk.top()
 
 

Modified: pypy/dist/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/translator/test/test_annrpython.py	Sat Mar  5 20:14:53 2005
@@ -569,6 +569,11 @@
                 a.bookkeeper.immutablevalue('world'))
         assert s == a.bookkeeper.immutablevalue(42)
 
+    def test_class_spec(self):
+        a = RPythonAnnotator()
+        s = a.build_types(snippet.class_spec, [])
+        assert s.items[0].knowntype == int
+        assert s.items[1].knowntype == str
 
 def g(n):
     return [0,1,2,n]



More information about the Pypy-commit mailing list