[pypy-svn] r7606 - in pypy/trunk/src/pypy: annotation translator translator/test

mwh at codespeak.net mwh at codespeak.net
Tue Nov 23 13:11:50 CET 2004


Author: mwh
Date: Tue Nov 23 13:11:49 2004
New Revision: 7606

Modified:
   pypy/trunk/src/pypy/annotation/binaryop.py
   pypy/trunk/src/pypy/annotation/builtin.py
   pypy/trunk/src/pypy/annotation/factory.py
   pypy/trunk/src/pypy/annotation/model.py
   pypy/trunk/src/pypy/annotation/unaryop.py
   pypy/trunk/src/pypy/translator/annrpython.py
   pypy/trunk/src/pypy/translator/test/test_annrpython.py
Log:
Integrate the annotation of instances and pbcs, which ended up involving
refactoring quite a lot of the annotation of instances and classes.

In particular:

 - there is now an Attribute class containing potential 'sources' for
   an attribute.
 - immutablevalue and valueoftype are now methods of the Bookkeeper
   class.
 - .bookkeeper attributes are now more common and bookkeeper arguments
   somewhat less so.
 - I accidentally ran delete-trailing-whitespace on all of factory.py
   instead of the region I was aiming for which bulks out the diff a bit.
   Sorry about that.


Modified: pypy/trunk/src/pypy/annotation/binaryop.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/binaryop.py	(original)
+++ pypy/trunk/src/pypy/annotation/binaryop.py	Tue Nov 23 13:11:49 2004
@@ -8,11 +8,14 @@
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeCallable
 from pypy.annotation.model import SomeBuiltin, SomeIterator
-from pypy.annotation.model import SomePBC, immutablevalue
+from pypy.annotation.model import SomePBC
 from pypy.annotation.model import unionof, set, setunion, missing_operation
 from pypy.annotation.factory import generalize, isclassdef, getbookkeeper
 from pypy.objspace.flow.model import Constant
 
+# convenience only!
+def immutablevalue(x):
+    return getbookkeeper().immutablevalue(x)
 
 # XXX unify this with ObjSpace.MethodTable
 BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod',
@@ -307,3 +310,15 @@
     def union((pbc1, pbc2)):
         return SomePBC(setunion(pbc1.prebuiltinstances,
                                 pbc2.prebuiltinstances))
+
+class __extend__(pairtype(SomeInstance, SomePBC)):
+    def union((ins, pbc)):
+        classdef = ins.currentdef().superdef_containing(pbc.knowntype)
+        if classdef is None:
+            # print warning?
+            return SomeObject()
+        return SomeInstance(classdef)
+
+class __extend__(pairtype(SomePBC, SomeInstance)):
+    def union((pbc, ins)):
+        return pair(ins, pbc).union()

Modified: pypy/trunk/src/pypy/annotation/builtin.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/builtin.py	(original)
+++ pypy/trunk/src/pypy/annotation/builtin.py	Tue Nov 23 13:11:49 2004
@@ -4,11 +4,13 @@
 
 from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool
 from pypy.annotation.model import SomeList, SomeString, SomeTuple
-from pypy.annotation.model import immutablevalue, valueoftype
 from pypy.annotation.factory import ListFactory, getbookkeeper
 from pypy.objspace.flow.model import Constant
 import pypy.objspace.std.restricted_int
 
+# convenience only!
+def immutablevalue(x):
+    return getbookkeeper().immutablevalue(x)
 
 def builtin_len(s_obj):
     return s_obj.len()
@@ -64,7 +66,7 @@
             assert op.args[0] == Constant(isinstance)
             assert annotator.binding(op.args[1]) is s_obj
             r = SomeBool()
-            r.knowntypedata = (op.args[1], valueoftype(typ, bk))
+            r.knowntypedata = (op.args[1], bk.valueoftype(typ))
             return r
     return SomeBool()
 

Modified: pypy/trunk/src/pypy/annotation/factory.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/factory.py	(original)
+++ pypy/trunk/src/pypy/annotation/factory.py	Tue Nov 23 13:11:49 2004
@@ -9,13 +9,18 @@
 from __future__ import generators
 import new
 from types import FunctionType, ClassType, MethodType
-from pypy.annotation.model import SomeImpossibleValue, SomeList, SomeDict
-from pypy.annotation.model import SomeObject, SomeInstance
-from pypy.annotation.model import unionof, immutablevalue
+from pypy.annotation.model import *
 from pypy.interpreter.miscutils import getthreadlocals
 from pypy.interpreter.pycode import CO_VARARGS
 from pypy.tool.hack import func_with_new_name
 
+def ishashable(x):
+    try:
+        hash(x)
+    except TypeError:
+        return False
+    else:
+        return True
 
 class BlockedInference(Exception):
     """This exception signals the type inference engine that the situation
@@ -44,7 +49,6 @@
         self.creationpoints = {} # map position-in-a-block to its Factory
         self.userclasses = {}    # map classes to ClassDefs
         self.userclasseslist = []# userclasses.keys() in creation order
-        self.attrs_read_from_constants = {}
         self.cachespecializations = {}
 
     def enter(self, position_key):
@@ -87,6 +91,85 @@
             return self.userclasses[cls]
 
 
+    def immutablevalue(self, x):
+        """The most precise SomeValue instance that contains the
+        immutable value x."""
+        tp = type(x)
+        if tp is bool:
+            result = SomeBool()
+        elif tp is int:
+            result = SomeInteger(nonneg = x>=0)
+        elif tp is str:
+            result = SomeString()
+        elif tp is tuple:
+            result = SomeTuple(items = [self.immutablevalue(e) for e in x])
+        elif tp is list:
+            items_s = [self.immutablevalue(e) for e in x]
+            result = SomeList({}, unionof(*items_s))
+        elif tp is dict:   # exactly a dict
+            items = {}
+            for key, value in x.items():
+                items[key] = self.immutablevalue(value)
+            result = SomeDict({}, items)
+        elif ishashable(x) and x in BUILTIN_ANALYZERS:
+            result = SomeBuiltin(BUILTIN_ANALYZERS[x])
+        elif callable(x) or isinstance(x, staticmethod): # XXX
+            # maybe 'x' is a method bound to a not-yet-frozen cache?
+            # fun fun fun.
+            if (hasattr(x, 'im_self') and isinstance(x.im_self, Cache)
+                and not x.im_self.frozen):
+                x.im_self.freeze()
+            if hasattr(x, '__self__') and x.__self__ is not None:
+                s_self = self.immutablevalue(x.__self__)
+                # stop infinite recursion getattr<->immutablevalue
+                del s_self.const
+                s_name = self.immutablevalue(x.__name__)
+                result = s_self.getattr(s_name)
+            else:
+                result = SomeCallable({x : True})
+        elif hasattr(x, '__class__') \
+                 and x.__class__.__module__ != '__builtin__':
+            if isinstance(x, Cache) and not x.frozen:
+                x.freeze()
+            result = SomePBC({x: True}) # pre-built inst
+            clsdef = self.getclassdef(x.__class__)
+            for attr in x.__dict__:
+                clsdef.add_source_for_attribute(attr, x)
+        elif x is None:
+            result = SomeNone()
+        else:
+            result = SomeObject()
+        result.const = x
+        return result
+
+    def valueoftype(self, t):
+        """The most precise SomeValue instance that contains all
+        objects of type t."""
+        if t is bool:
+            return SomeBool()
+        elif t is int:
+            return SomeInteger()
+        elif t is str:
+            return SomeString()
+        elif t is list:
+            return SomeList(factories={})
+        # can't do dict, tuple
+        elif isinstance(t, (type, ClassType)) and \
+                 t.__module__ != '__builtin__':
+            classdef = self.getclassdef(t)
+            if self.is_in_an_operation():
+                # woha! instantiating a "mutable" SomeXxx like SomeInstance
+                # is always dangerous, because we need to record this fact
+                # in a factory, to allow reflowing from the current operation
+                # if/when the classdef later changes.
+                factory = self.getfactory(CallableFactory)
+                classdef.instancefactories[factory] = True
+            return SomeInstance(classdef)
+        else:
+            o = SomeObject()
+            o.knowntype = t
+            return o
+
 def getbookkeeper():
     """Get the current Bookkeeper.
     Only works during the analysis of an operation."""
@@ -105,14 +188,14 @@
         raise BlockedInference   # reflow now
 
 def isclassdef(x):
-    return isinstance(x, ClassDef) 
+    return isinstance(x, ClassDef)
 
 class ListFactory:
     s_item = SomeImpossibleValue()
 
     def __repr__(self):
         return '%s(s_item=%r)' % (self.__class__.__name__, self.s_item)
-    
+
     def create(self):
         return SomeList(factories = {self: True}, s_item = self.s_item)
 
@@ -145,11 +228,11 @@
             return False
 
 
-class CallableFactory: 
+class CallableFactory:
     def pycall(self, func, *args):
         if isinstance(func, (type, ClassType)) and \
             func.__module__ != '__builtin__':
-            cls = func 
+            cls = func
             x = getattr(cls, "_specialize_", False)
             if x:
                 if x == "location":
@@ -157,7 +240,7 @@
                 else:
                     raise Exception, \
                           "unsupported specialization type '%s'"%(x,)
-            
+
             classdef = self.bookkeeper.getclassdef(cls)
             classdef.instancefactories[self] = True
             s_instance = SomeInstance(classdef)
@@ -169,17 +252,17 @@
                 assert not args, "no __init__ found in %r" % (cls,)
             return s_instance
         if hasattr(func, '__call__') and \
-           isinstance(func.__call__, MethodType): 
+           isinstance(func.__call__, MethodType):
             func = func.__call__
         if hasattr(func, 'im_func'):
             if func.im_self is not None:
-                s_self = immutablevalue(func.im_self)
+                s_self = self.bookkeeper.immutablevalue(func.im_self)
                 args = [s_self] + list(args)
             try:
                 func.im_func.class_ = func.im_class
             except AttributeError:
                 # probably a builtin function, we don't care to preserve
-                # class information then 
+                # class information then
                 pass
             func = func.im_func
         assert isinstance(func, FunctionType), "expected function, got %r"%func
@@ -187,15 +270,15 @@
         x = getattr(func, '_specialize_', False)
         if x:
             if x == 'argtypes':
-                key = short_type_name(args) 
-                func = self.specialize_by_key(func, key, 
-                                              func.__name__+'__'+key) 
+                key = short_type_name(args)
+                func = self.specialize_by_key(func, key,
+                                              func.__name__+'__'+key)
             elif x == "location":
                 # fully specialize: create one version per call position
                 func = self.specialize_by_key(func, self.position_key)
             else:
                 raise Exception, "unsupported specialization type '%s'"%(x,)
-            
+
         elif func.func_code.co_flags & CO_VARARGS:
             # calls to *arg functions: create one version per number of args
             func = self.specialize_by_key(func, len(args),
@@ -222,20 +305,51 @@
 
 def short_type_name(args):
     l = []
-    for x in args: 
+    for x in args:
         if isinstance(x, SomeInstance) and hasattr(x, 'knowntype'):
-            name = "SI_" + x.knowntype.__name__ 
+            name = "SI_" + x.knowntype.__name__
         else:
             name = x.__class__.__name__
-        l.append(name) 
-    return "__".join(l) 
+        l.append(name)
+    return "__".join(l)
+
+
+class Attribute:
+    # readonly-ness
+    # SomeThing-ness
+    # more potential sources (pbcs or classes) of information
+
+    def __init__(self, name, bookkeeper):
+        self.name = name
+        self.bookkeeper = bookkeeper
+        self.sources = {} # source -> None or ClassDef
+        # XXX a SomeImpossibleValue() constant?  later!!
+        self.s_value = SomeImpossibleValue()
+        self.readonly = True
+
+    def getvalue(self):
+        while self.sources:
+            source, classdef = self.sources.popitem()
+            s_value = self.bookkeeper.immutablevalue(
+                source.__dict__[self.name])
+            if classdef:
+                s_value = s_value.bindcallables(classdef)
+            self.s_value = unionof(self.s_value, s_value)
+        return self.s_value
+
+    def merge(self, other):
+        assert self.name == other.name
+        self.sources.update(other.sources)
+        self.s_value = unionof(self.s_value, other.s_value)
+        self.readonly = self.readonly and other.readonly
+
 
 class ClassDef:
     "Wraps a user class."
 
     def __init__(self, cls, bookkeeper):
-        self.attrs = {}          # attrs is updated with new information
-        self.readonly = {}       # {attr: True-or-False}
+        self.bookkeeper = bookkeeper
+        self.attrs = {}          # {name: Attribute}
         self.revision = 0        # which increases the revision number
         self.instancefactories = {}
         self.cls = cls
@@ -250,6 +364,7 @@
         self.basedef = bookkeeper.getclassdef(base)
         if self.basedef:
             self.basedef.subdefs[cls] = self
+
         # collect the (supposed constant) class attributes
         for name, value in cls.__dict__.items():
             # ignore some special attributes
@@ -257,13 +372,21 @@
                 continue
             if isinstance(value, FunctionType):
                 value.class_ = cls # remember that this is really a method
-            # although self.getallfactories() is currently empty,
-            # the following might still invalidate some blocks if it
-            # generalizes existing values in parent classes
-            s_value = immutablevalue(value)
-            s_value = s_value.bindcallables(self)
-            self.generalize_attr(name, s_value, bookkeeper)
+            self.add_source_for_attribute(name, cls, self)
+
+    def add_source_for_attribute(self, attr, source, clsdef=None):
+        self.find_attribute(attr).sources[source] = clsdef
 
+    def locate_attribute(self, attr):
+        for cdef in self.getmro():
+            if attr in cdef.attrs:
+                return cdef
+        self.generalize_attr(attr)
+        return self
+
+    def find_attribute(self, attr):
+        return self.locate_attribute(attr).attrs[attr]
+    
     def __repr__(self):
         return "<ClassDef '%s.%s'>" % (self.cls.__module__, self.cls.__name__)
 
@@ -272,6 +395,12 @@
             other = other.basedef
         return other
 
+    def superdef_containing(self, cls):
+        clsdef = self
+        while clsdef is not None and not issubclass(cls, clsdef.cls):
+            clsdef = clsdef.basedef
+        return clsdef
+
     def getmro(self):
         while self is not None:
             yield self
@@ -293,41 +422,43 @@
             factories.update(clsdef.instancefactories)
         return factories
 
-    def _generalize_attr(self, attr, s_value, bookkeeper, readonly):
+    def _generalize_attr(self, attr, s_value):
         # first remove the attribute from subclasses -- including us!
-        subclass_values = []
+        subclass_attrs = []
         for subdef in self.getallsubdefs():
             if attr in subdef.attrs:
-                subclass_values.append(subdef.attrs[attr])
-                readonly = readonly and subdef.readonly[attr]
+                subclass_attrs.append(subdef.attrs[attr])
                 del subdef.attrs[attr]
-                del subdef.readonly[attr]
             # bump the revision number of this class and all subclasses
             subdef.revision += 1
 
         # do the generalization
-        self.attrs[attr] = unionof(s_value, *subclass_values)
-        self.readonly[attr] = readonly
-        
-        # reflow from all factories
-        if bookkeeper:
-            for factory in self.getallfactories():
-                bookkeeper.annotator.reflowfromposition(factory.position_key)
+        newattr = Attribute(attr, self.bookkeeper)
+        if s_value:
+            newattr.s_value = s_value
+            
+        for subattr in subclass_attrs:
+            newattr.merge(subattr)
+        self.attrs[attr] = newattr
 
+        # reflow from all factories
+        for factory in self.getallfactories():
+            self.bookkeeper.annotator.reflowfromposition(factory.position_key)
 
-    def generalize_attr(self, attr, s_value, bookkeeper=None, readonly=True):
+    def generalize_attr(self, attr, s_value=None):
         # if the attribute exists in a superclass, generalize there.
         for clsdef in self.getmro():
             if attr in clsdef.attrs:
-                clsdef._generalize_attr(attr, s_value, bookkeeper, readonly)
-                return
+                clsdef._generalize_attr(attr, s_value)
         else:
-            self._generalize_attr(attr, s_value, bookkeeper, readonly)
+            self._generalize_attr(attr, s_value)
 
     def about_attribute(self, name):
         for cdef in self.getmro():
             if name in cdef.attrs:
-                return cdef.attrs[name]
-        return SomeImpossibleValue()
+                return cdef.attrs[name].getvalue()
+        return None
+
+
 
-from pypy.annotation.builtin  import BUILTIN_ANALYZERS
+from pypy.annotation.builtin import BUILTIN_ANALYZERS

Modified: pypy/trunk/src/pypy/annotation/model.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/model.py	(original)
+++ pypy/trunk/src/pypy/annotation/model.py	Tue Nov 23 13:11:49 2004
@@ -204,99 +204,6 @@
         s1.caused_by_merge = somevalues
     return s1
 
-def ishashable(x):
-    try:
-        hash(x)
-    except TypeError:
-        return False
-    else:
-        return True
-
-def immutablevalue(x):
-    "The most precise SomeValue instance that contains the immutable value x."
-    tp = type(x)
-    if tp is bool:
-        result = SomeBool()
-    elif tp is int:
-        result = SomeInteger(nonneg = x>=0)
-    elif tp is str:
-        result = SomeString()
-    elif tp is tuple:
-        result = SomeTuple(items = [immutablevalue(e) for e in x])
-    elif tp is list:
-        items_s = [immutablevalue(e) for e in x]
-        result = SomeList({}, unionof(*items_s))
-    elif tp is dict:   # exactly a dict, not a subclass like Cache
-        items = {}
-        for key, value in x.items():
-            items[key] = immutablevalue(value)
-        result = SomeDict({}, items)
-    elif ishashable(x) and x in BUILTIN_ANALYZERS:
-        result = SomeBuiltin(BUILTIN_ANALYZERS[x])
-    elif callable(x) or isinstance(x, staticmethod): # XXX
-        # maybe 'x' is a method bound to a not-yet-frozen cache? fun fun fun.
-        if (hasattr(x, 'im_self') and isinstance(x.im_self, Cache)
-            and not x.im_self.frozen):
-            x.im_self.freeze()
-        if hasattr(x, '__self__') and x.__self__ is not None:
-            s_self = immutablevalue(x.__self__)
-            del s_self.const # stop infinite recursion getattr<->immutablevalue
-            s_name = immutablevalue(x.__name__)
-            result = s_self.getattr(s_name)
-        else:
-            result = SomeCallable({x : True})
-    elif hasattr(x, '__class__') and x.__class__.__module__ != '__builtin__':
-        if isinstance(x, Cache) and not x.frozen:
-            x.freeze()
-        result = SomePBC({x: True}) # pre-built inst:
-    elif x is None:
-        result = SomeNone()
-    else:
-        result = SomeObject()
-    result.const = x
-    return result
-
-def valueoftype(t, bookkeeper=None):
-    "The most precise SomeValue instance that contains all objects of type t."
-    if t is bool:
-        return SomeBool()
-    elif t is int:
-        return SomeInteger()
-    elif t is str:
-        return SomeString()
-    elif t is list:
-        return SomeList(factories={})
-    # can't do dict, tuple
-    elif isinstance(t, (type, ClassType)) and \
-             t.__module__ != '__builtin__' and bookkeeper is not None:
-        classdef = bookkeeper.getclassdef(t)
-        if bookkeeper.is_in_an_operation():
-            # woha! instantiating a "mutable" SomeXxx like SomeInstance
-            # is always dangerous, because we need to record this fact
-            # in a factory, to allow reflowing from the current operation
-            # if/when the classdef later changes.
-            from pypy.annotation.factory import CallableFactory
-            factory = bookkeeper.getfactory(CallableFactory)
-            classdef.instancefactories[factory] = True
-        return SomeInstance(classdef)
-    else:
-        o = SomeObject()
-        o.knowntype = t
-        return o
-
-##def decode_simple_call(s_args, s_kwds):
-##    s_nbargs = s_args.len()
-##    if not s_nbargs.is_constant():
-##        return None
-##    nbargs = s_nbargs.const
-##    arglist = [pair(s_args, immutablevalue(j)).getitem()
-##               for j in range(nbargs)]
-##    s_nbkwds = s_kwds.len()
-##    if not s_nbkwds.is_constant() or s_nbkwds.const != 0:
-##        return None    # XXX deal with dictionaries with keywords
-##    return arglist
-
-
 # ____________________________________________________________
 # internal
 

Modified: pypy/trunk/src/pypy/annotation/unaryop.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/unaryop.py	(original)
+++ pypy/trunk/src/pypy/annotation/unaryop.py	Tue Nov 23 13:11:49 2004
@@ -10,11 +10,13 @@
 from pypy.annotation.model import SomeInstance, SomeBuiltin 
 from pypy.annotation.model import SomeCallable, SomeIterator
 from pypy.annotation.model import SomePBC
-from pypy.annotation.model import immutablevalue
 from pypy.annotation.model import unionof, set, setunion, missing_operation
 from pypy.annotation.factory import BlockedInference, getbookkeeper
 from pypy.annotation.factory import CallableFactory, isclassdef 
 
+# convenience only!
+def immutablevalue(x):
+    return getbookkeeper().immutablevalue(x)
 
 UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'simple_call',
                         'iter', 'next'])
@@ -120,34 +122,27 @@
         if s_attr.is_constant() and isinstance(s_attr.const, str):
             attr = s_attr.const
             #print 'getattr:', ins, attr, ins.classdef.revision
-            # look for the attribute in the MRO order
-            for clsdef in ins.currentdef().getmro():
-                if attr in clsdef.attrs:
-                    return clsdef.attrs[attr]
-            # maybe the attribute exists in some subclass? if so, lift it
-            clsdef = ins.classdef
-            clsdef.generalize_attr(attr, SomeImpossibleValue(), getbookkeeper())
-            raise BlockedInference
+            s_result = ins.currentdef().find_attribute(attr).getvalue()
+            # we call this because it might raise BlockedInference if
+            # the above line caused generalization.
+            ins.currentdef()
+            return s_result
         return SomeObject()
 
     def setattr(ins, s_attr, s_value):
         if s_attr.is_constant() and isinstance(s_attr.const, str):
             attr = s_attr.const
-            for clsdef in ins.currentdef().getmro():
-                if attr in clsdef.attrs:
-                    # look for the attribute in ins.classdef or a parent class
-                    s_existing = clsdef.attrs[attr]
-                    if s_existing.contains(s_value):
-                        clsdef.readonly[attr] = False
-                        return   # already general enough, nothing to do
-                    break
-            else:
-                # if the attribute doesn't exist yet, create it here
-                clsdef = ins.classdef
+            clsdef = ins.currentdef().locate_attribute(attr)
+            attrdef = clsdef.attrs[attr]
+            attrdef.readonly = False
+
+            # if the attrdef is new, this must fail
+            if attrdef.getvalue().contains(s_value):
+                return
             # create or update the attribute in clsdef
-            clsdef.generalize_attr(attr, s_value, getbookkeeper(), readonly=False)
+            clsdef.generalize_attr(attr, s_value)
             raise BlockedInference
-        return SomeObject()
+        return
 
 class __extend__(SomeBuiltin):
     def simple_call(bltn, *args):
@@ -198,10 +193,9 @@
     def getattr(pbc, s_attr):
         assert s_attr.is_constant()
         attr = s_attr.const
-        bookkeeper = getbookkeeper()
         actuals = []
+        
         for c in pbc.prebuiltinstances:
-            bookkeeper.attrs_read_from_constants.setdefault(c, {})[attr] = True
             if hasattr(c, attr):
                 actuals.append(immutablevalue(getattr(c, attr)))
         return unionof(*actuals)

Modified: pypy/trunk/src/pypy/translator/annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/annrpython.py	Tue Nov 23 13:11:49 2004
@@ -60,7 +60,7 @@
         inputcells = []
         for t in input_arg_types:
             if not isinstance(t, annmodel.SomeObject):
-                t = annmodel.valueoftype(t, self.bookkeeper)
+                t = self.bookkeeper.valueoftype(t)
             inputcells.append(t)
         
         # register the entry point
@@ -101,9 +101,6 @@
             self.binding_caused_by[v] = None
             yield v
 
-    def getpbcattrs(self, pbc):
-        return self.bookkeeper.attrs_read_from_constants.get(pbc, {})
-
     #___ medium-level interface ____________________________
 
     def addpendingblock(self, fn, block, cells, called_from=None):
@@ -148,7 +145,7 @@
                 assert isinstance(in_link.exitcase, type(Exception))
                 assert issubclass(in_link.exitcase, Exception)
                 return annmodel.SomeObject()   # XXX
-            return annmodel.immutablevalue(arg.value)
+            return self.bookkeeper.immutablevalue(arg.value)
         else:
             raise TypeError, 'Variable or Constant expected, got %r' % (arg,)
 
@@ -210,7 +207,7 @@
                     "got %d inputcells in call to %r; expected %s" % (
                     len(inputcells), func, msg))
             for extra in func.func_defaults[-missingargs:]:
-                inputcells.append(annmodel.immutablevalue(extra))
+                inputcells.append(self.bookkeeper.immutablevalue(extra))
         inputcells.extend(extracells)
         self.addpendingblock(func, block, inputcells, factory)
 

Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_annrpython.py	Tue Nov 23 13:11:49 2004
@@ -7,7 +7,7 @@
 from pypy.translator.translator import Translator
 from pypy.objspace.flow.model import *
 
-from pypy.annotation.model import immutablevalue, SomeCallable
+from pypy.annotation.model import SomeCallable
 
 from pypy.translator.test import snippet
 
@@ -161,7 +161,7 @@
         s = a.build_types(snippet.inheritance1, [])
         # result should be exactly:
         self.assertEquals(s, annmodel.SomeTuple([
-                                annmodel.immutablevalue(()),
+                                a.bookkeeper.immutablevalue(()),
                                 annmodel.SomeInteger()
                                 ]))
 
@@ -198,8 +198,10 @@
         classes = a.bookkeeper.userclasses
         self.assertEquals(classes[snippet.F].attrs.keys(), ['m'])
         self.assertEquals(classes[snippet.G].attrs.keys(), ['m2'])
-        self.assertEquals(classes[snippet.H].attrs,
-                          {'attr': annmodel.immutablevalue(1)})
+        self.assertEquals(classes[snippet.H].attrs.keys(), ['attr']) 
+        self.assertEquals(classes[snippet.H].about_attribute('attr'),
+                          a.bookkeeper.immutablevalue(1))
+       
 
     def test_knownkeysdict(self):
         a = RPythonAnnotator()
@@ -227,9 +229,9 @@
         # XXX on which class should the attribute 'a' appear?  We only
         #     ever flow WithInit.__init__ with a self which is an instance
         #     of WithMoreInit, so currently it appears on WithMoreInit.
-        self.assertEquals(classes[snippet.WithMoreInit].attrs.get('a'),
+        self.assertEquals(classes[snippet.WithMoreInit].about_attribute('a'),
                           annmodel.SomeInteger())
-        self.assertEquals(classes[snippet.WithMoreInit].attrs.get('b'),
+        self.assertEquals(classes[snippet.WithMoreInit].about_attribute('b'),
                           annmodel.SomeBool())
 
     def test_global_instance(self):
@@ -237,14 +239,14 @@
         s = a.build_types(snippet.global_instance, [])
         # currently this returns the constant 42.
         # XXX not sure this is the best behavior...
-        self.assertEquals(s, annmodel.immutablevalue(42))
+        self.assertEquals(s, a.bookkeeper.immutablevalue(42))
 
     def test_call_five(self):
         a = RPythonAnnotator()
         s = a.build_types(snippet.call_five, [])
         # returns should be a list of constants (= 5)
         self.assert_(isinstance(s, annmodel.SomeList))
-        self.assertEquals(s.s_item, annmodel.immutablevalue(5))
+        self.assertEquals(s.s_item, a.bookkeeper.immutablevalue(5))
 
     def test_call_five_six(self):
         a = RPythonAnnotator()
@@ -258,7 +260,7 @@
         s = a.build_types(snippet.constant_result, [])
         #a.translator.simplify()
         # must return "yadda"
-        self.assertEquals(s, annmodel.immutablevalue("yadda"))
+        self.assertEquals(s, a.bookkeeper.immutablevalue("yadda"))
         keys = a.translator.flowgraphs.keys()
         keys.sort()
         expected = [snippet.constant_result,
@@ -273,7 +275,7 @@
     def test_call_pbc(self):
         a = RPythonAnnotator()
         s = a.build_types(snippet.call_cpbc, [])
-        self.assertEquals(s, annmodel.immutablevalue(42))
+        self.assertEquals(s, a.bookkeeper.immutablevalue(42))
 
     def test_flow_type_info(self):
         a = RPythonAnnotator()
@@ -309,7 +311,7 @@
         a.translator.simplify()
         a.simplify()
         #a.translator.view()
-        self.assertEquals(s, immutablevalue((None, None)))
+        self.assertEquals(s, a.bookkeeper.immutablevalue((None, None)))
 
     def test_mergefunctions(self):
         a = RPythonAnnotator()



More information about the Pypy-commit mailing list