[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