[pypy-svn] r19992 - in pypy/branch/somepbc-refactoring/pypy: annotation annotation/test rpython translator/test

pedronis at codespeak.net pedronis at codespeak.net
Thu Nov 17 22:33:08 CET 2005


Author: pedronis
Date: Thu Nov 17 22:33:05 2005
New Revision: 19992

Modified:
   pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py
   pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py
   pypy/branch/somepbc-refactoring/pypy/annotation/builtin.py
   pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py
   pypy/branch/somepbc-refactoring/pypy/annotation/description.py
   pypy/branch/somepbc-refactoring/pypy/annotation/model.py
   pypy/branch/somepbc-refactoring/pypy/annotation/test/test_model.py
   pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py
   pypy/branch/somepbc-refactoring/pypy/rpython/normalizecalls.py
   pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py
Log:
(arigo, pedronis)

- moved ClassDef setup logic to ClassDesc

- now things are ready for synthetic ClassDescs

- !!! because of the latter SomeInstance cannot always have a knowntype being a python class. Now knowntype of SomeInstance
  is a special case being equal to the classdef




Modified: pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py	Thu Nov 17 22:33:05 2005
@@ -570,14 +570,15 @@
     def union((ins, pbc)):
         if pbc.isNone():
             return SomeInstance(classdef=ins.classdef, can_be_None = True)
+        raise UnionError("mixing pbc and instance not supported anymore:  %s %s" % (pbc, ins))
         # XXX is the following still useful?
-        classdef = ins.classdef.superdef_containing(pbc.knowntype)
-        if classdef is None:
-            # print warning?
-            return SomeObject()
-        if not getattr(TLS, 'no_side_effects_in_union', 0):
-            raise UnionError("mixing pbc and instance not supported anymore:  %s %s" % (pbc, ins))
-        return SomeInstance(classdef)
+        #classdef = ins.classdef.superdef_containing(pbc.knowntype)
+        #if classdef is None:
+        #    # print warning?
+        #    return SomeObject()
+        #if not getattr(TLS, 'no_side_effects_in_union', 0):
+        #    raise UnionError("mixing pbc and instance not supported anymore:  %s %s" % (pbc, ins))
+        #return SomeInstance(classdef)
 
 class __extend__(pairtype(SomePBC, SomeInstance)):
     def union((pbc, ins)):

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py	Thu Nov 17 22:33:05 2005
@@ -12,7 +12,7 @@
      SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, \
      SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \
      SomeList, SomeObject
-from pypy.annotation.classdef import ClassDef, ConstantSource
+from pypy.annotation.classdef import ClassDef, InstanceSource
 from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
 from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
 from pypy.annotation import description
@@ -89,7 +89,7 @@
 
     def typerepr(self, obj):
         if isinstance(obj, SomeInstance):
-            return obj.classdef.cls.__name__
+            return obj.classdef.name
         else:
             return obj.knowntype.__name__
 
@@ -269,7 +269,7 @@
     def immutablevalue(self, x):
         """The most precise SomeValue instance that contains the
         immutable value x."""
-        # convert unbound methods to the underlying function
+         # convert unbound methods to the underlying function
         if hasattr(x, 'im_self') and x.im_self is None:
             x = x.im_func
             assert not hasattr(x, 'im_self')
@@ -358,8 +358,9 @@
                                                # see for example test_circular_mutable_getattr
                     self.seen_mutable[x] = True
                     self.event('mutable', x)
+                    source = InstanceSource(self, x)
                     for attr in x.__dict__:
-                        clsdef.add_source_for_attribute(attr, ConstantSource(self, x, None)) # can trigger reflowing
+                        clsdef.add_source_for_attribute(attr, source) # can trigger reflowing
                 result = SomeInstance(clsdef)
         elif x is None:
             return s_None
@@ -382,6 +383,8 @@
             if isinstance(pyobj, types.FunctionType):
                 result = description.FunctionDesc(self, pyobj)
             elif isinstance(pyobj, (type, types.ClassType)):
+                if pyobj is object:
+                    raise Exception, "ClassDesc for object not supported"
                 result = description.ClassDesc(self, pyobj)
             elif isinstance(pyobj, types.MethodType):
                 if pyobj.im_self is None:   # unbound

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/builtin.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/builtin.py	Thu Nov 17 22:33:05 2005
@@ -126,16 +126,24 @@
                 
             assert not issubclass(typ, (int,long)) or typ in (bool, int), (
                 "for integers only isinstance(.,int|r_uint) are supported")
+ 
             if s_obj.is_constant():
                 r.const = isinstance(s_obj.const, typ)
+            elif isinstance(s_obj, SomeInstance):
+                typdef = getbookkeeper().getuniqueclassdef(typ)
+                if s_obj.classdef.issubclass(typdef):
+                    if not s_obj.can_be_none():
+                        r.const = True 
+                elif not typdef.issubclass(s_obj.classdef):
+                    r.const = False
             elif our_issubclass(s_obj.knowntype, typ):
                 if not s_obj.can_be_none():
                     r.const = True 
             elif not our_issubclass(typ, s_obj.knowntype): 
                 r.const = False
             elif s_obj.knowntype == int and typ == bool: # xxx this will explode in case of generalisation
-                                                         # from bool to int, notice that isinstance( , bool|int)
-                                                         # is quite border case for RPython
+                                                   # from bool to int, notice that isinstance( , bool|int)
+                                                   # is quite border case for RPython
                 r.const = False
         # XXX HACK HACK HACK
         # XXX HACK HACK HACK

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py	Thu Nov 17 22:33:05 2005
@@ -3,7 +3,6 @@
 """
 
 from __future__ import generators
-from types import FunctionType
 from pypy.annotation.model import SomeImpossibleValue, SomePBC, unionof
 from pypy.annotation.model import SomeInteger, isdegenerated
 from pypy.annotation import description
@@ -65,24 +64,6 @@
 #        same name in all subclasses of A, if any.  (Parent class attributes can
 #        be visible in reads from instances of subclasses.)
 
-class ConstantSource:
-
-    def __init__(self, bookkeeper, obj, classdef=None):
-        self.bookkeeper = bookkeeper
-        self.obj = obj
-        self.classdef = classdef
-
-    def s_read_attribute(self, name):
-        s_value = self.bookkeeper.immutablevalue(
-            self.obj.__dict__[name])
-        if self.classdef:
-            s_value = s_value.bindcallables(self.classdef)
-        return s_value
-
-    def is_instance_level(self):
-        return self.classdef is None
-
-
 class Attribute:
     # readonly-ness
     # SomeThing-ness
@@ -137,7 +118,7 @@
                 if isinstance(desc, description.MethodDesc):
                     meth = True
                     break
-            if meth and getattr(homedef.cls, attr, None) is None:
+            if meth and homedef.classdesc.find_source_for(attr) is None:
                 self.bookkeeper.warning("demoting method %s to base class %s" % (self.name, homedef))
 
         for position in self.read_locations:
@@ -148,71 +129,24 @@
 class ClassDef:
     "Wraps a user class."
 
-    def __init__(self, cls, bookkeeper):
+    def __init__(self, bookkeeper, classdesc):
         self.bookkeeper = bookkeeper
         self.attrs = {}          # {name: Attribute}
-        #self.instantiation_locations = {}
-        self.cls = cls
-        self.subdefs = {}
+        self.classdesc = classdesc
+        self.name = self.classdesc.name
+        self.subdefs = []
         self.attr_sources = {}   # {name: {constant-source: True}}
-        base = object
 
+        if classdesc.basedesc:
+            self.basedef = classdesc.basedesc.getuniqueclassdef()
+            self.basedef.subdefs.append(self)
+        else:
+            self.basedef = None
 
-        classsources = {}
-
-        baselist = list(cls.__bases__)
-        baselist.reverse()
-        self.also_Exception_subclass = False
-        if Exception in baselist and len(baselist)>1: # special-case
-            baselist.remove(Exception)
-            classsources['__init__'] = ConstantSource(bookkeeper, Exception, self)
-            self.also_Exception_subclass = True
-        
-        def add_sources_for_class(cls):
-            source = ConstantSource(bookkeeper, cls, self)
-            for name, value in cls.__dict__.items():
-                # ignore some special attributes
-                if name.startswith('_') and not isinstance(value, FunctionType):
-                    continue
-                # for debugging
-                if isinstance(value, FunctionType):
-                    if not hasattr(value, 'class_'):
-                        value.class_ = self.cls # remember that this is really a method
-                classsources[name] = source
-
-        for b1 in baselist:
-            if b1 is object:
-                continue
-            if getattr(b1, '_mixin_', False):
-                assert b1.__bases__ == () or b1.__bases__ == (object,), (
-                    "mixin class %r should have no base" % (b1,))
-                add_sources_for_class(b1)
-            else:
-                assert base is object, ("multiple inheritance only supported "
-                                        "with _mixin_: %r" % (cls,))
-                base = b1
-
-        add_sources_for_class(cls)
-
-        self.basedef = bookkeeper.getuniqueclassdef(base)
-        if self.basedef:
-            self.basedef.subdefs[cls] = self
-
-        # pass some data to the setup() method, which must be called
-        # after the __init__()
-        self.sources_from_the_class = classsources
-
-        # forced attributes
-        if cls in FORCE_ATTRIBUTES_INTO_CLASSES:
-            for name, s_value in FORCE_ATTRIBUTES_INTO_CLASSES[cls].items():
-                self.generalize_attr(name, s_value)
-                self.find_attribute(name).readonly = False
+        self.parentdefs = dict.fromkeys(self.getmro())
 
-    def setup(self):
+    def setup(self, sources):
         # collect the (supposed constant) class attributes
-        cls = self.cls
-        sources = self.sources_from_the_class
-        del self.sources_from_the_class   # setup() shouldn't be called twice
         for name, source in sources.items():
             self.add_source_for_attribute(name, source)
         if self.bookkeeper:
@@ -264,23 +198,23 @@
         return self.locate_attribute(attr).attrs[attr]
     
     def __repr__(self):
-        return "<ClassDef '%s.%s'>" % (self.cls.__module__, self.cls.__name__)
+        return "<ClassDef '%s'>" % (self.name,)
 
     def commonbase(self, other):
         other1 = other
-        while other is not None and not issubclass(self.cls, other.cls):
+        while other is not None and not self.issubclass(other):
             other = other.basedef
         # special case for MI with Exception
-        if other is None and other1 is not None:
-            if issubclass(self.cls, Exception) and issubclass(other1.cls, Exception):
-                return self.bookkeeper.getclassdef(Exception)
+        #if other is None and other1 is not None:
+        #    if issubclass(self.cls, Exception) and issubclass(other1.cls, Exception):
+        #        return self.bookkeeper.getclassdef(Exception)
         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 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:
@@ -288,14 +222,14 @@
             self = self.basedef
 
     def issubclass(self, otherclsdef):
-        return issubclass(self.cls, otherclsdef.cls)
+        return otherclsdef in self.parentdefs
 
     def getallsubdefs(self):
         pending = [self]
         seen = {}
         for clsdef in pending:
             yield clsdef
-            for sub in clsdef.subdefs.values():
+            for sub in clsdef.subdefs:
                 if sub not in seen:
                     pending.append(sub)
                     seen[sub] = True
@@ -430,9 +364,10 @@
         return found
 
     def check_attr_here(self, name):
-        if name in self.cls.__dict__:
+        source = self.classdesc.find_source_for(name)
+        if source is not None:
             # oups! new attribute showed up
-            self.add_source_for_attribute(name, ConstantSource(self.bookkeeper, self.cls, self))
+            self.add_source_for_attribute(name, source)
             # maybe it also showed up in some subclass?
             for subdef in self.getallsubdefs():
                 if subdef is not self:
@@ -441,6 +376,25 @@
         else:
             return False
 
+    def _freeze_(self):
+        raise Exception, "ClassDefs are used as knowntype for instances but cannot be used as immutablevalue arguments directly"
+
+# ____________________________________________________________
+
+class InstanceSource:
+
+    def __init__(self, bookkeeper, obj):
+        self.bookkeeper = bookkeeper
+        self.obj = obj
+ 
+    def s_read_attribute(self, name):
+        s_value = self.bookkeeper.immutablevalue(
+            self.obj.__dict__[name])
+        return s_value
+
+    def is_instance_level(self):
+        return True
+
 # ____________________________________________________________
 
 FORCE_ATTRIBUTES_INTO_CLASSES = {

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/description.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/description.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/description.py	Thu Nov 17 22:33:05 2005
@@ -147,13 +147,75 @@
         # XXX static methods
         return self.bookkeeper.getmethoddesc(self, classdef)
 
+class ClassSource:
+
+    def __init__(self, bookkeeper, cls, classdesc):
+        self.bookkeeper = bookkeeper
+        self.cls = cls
+        self.classdesc = classdesc
+
+    def s_read_attribute(self, name):
+        s_value = self.bookkeeper.immutablevalue(
+            self.cls.__dict__[name])
+        s_value = s_value.bindcallables(self.classdesc.getuniqueclassdef())
+        return s_value
+
+    def is_instance_level(self):
+        return False
 
 class ClassDesc(Desc):
     knowntype = type
 
-    def __init__(self, bookkeeper, pyobj, specialize=None):
+    def __init__(self, bookkeeper, pyobj=None, name=None,
+                 basedesc=None, 
+                 classsources=None, specialize=None):
         super(ClassDesc, self).__init__(bookkeeper, pyobj)
-        self.name = pyobj.__module__ + '.' + pyobj.__name__
+
+        if pyobj is not None:
+            cls = pyobj
+            base = object
+
+            classsources = {}
+
+            baselist = list(cls.__bases__)
+            baselist.reverse()
+
+            def add_sources_for_class(cls):
+                source = ClassSource(bookkeeper, cls, self)
+                for name, value in cls.__dict__.items():
+                    # ignore some special attributes
+                    if name.startswith('_') and not isinstance(value, types.FunctionType):
+                        continue
+                    # for debugging
+                    if isinstance(value, types.FunctionType):
+                        if not hasattr(value, 'class_'):
+                            value.class_ = self.pyobj # remember that this is really a method
+                    classsources[name] = source
+
+            for b1 in baselist:
+                if b1 is object:
+                    continue
+                if getattr(b1, '_mixin_', False):
+                    assert b1.__bases__ == () or b1.__bases__ == (object,), (
+                        "mixin class %r should have no base" % (b1,))
+                    add_sources_for_class(b1)
+                else:
+                    assert base is object, ("multiple inheritance only supported "
+                                            "with _mixin_: %r" % (cls,))
+                    base = b1
+
+            add_sources_for_class(cls)
+
+            name = pyobj.__module__ + '.' + pyobj.__name__
+            if base is object:
+                basedesc = None
+            else:
+                basedesc = bookkeeper.getdesc(base)
+            
+        self.name = name
+        self.basedesc = basedesc
+        self.classsources = classsources
+
         if specialize is None:
             tag = pyobj.__dict__.get('_annspecialcase_', '')
             assert not tag  # XXX later
@@ -165,11 +227,20 @@
             raise Exception("not supported on class %r because it needs "
                             "specialization" % (self.name,))
         if self._classdef is None:
-            from pypy.annotation.classdef import ClassDef
-            classdef = ClassDef(self.pyobj, self.bookkeeper)
+            from pypy.annotation.classdef import ClassDef, FORCE_ATTRIBUTES_INTO_CLASSES
+            classdef = ClassDef(self.bookkeeper, self)
             self.bookkeeper.classdefs.append(classdef)
             self._classdef = classdef
-            classdef.setup()
+
+            # forced attributes
+            if self.pyobj is not None:
+                cls = self.pyobj
+                if cls in FORCE_ATTRIBUTES_INTO_CLASSES:
+                    for name, s_value in FORCE_ATTRIBUTES_INTO_CLASSES[cls].items():
+                        classdef.generalize_attr(name, s_value)
+                        classdef.find_attribute(name).readonly = False
+            
+            classdef.setup(self.classsources)
         return self._classdef
 
     def pycall(self, schedule, args):
@@ -190,6 +261,18 @@
                                 " (class %s)" % (self.name,))
         return s_instance
 
+    def find_source_for(self, name):
+        if name in self.classsources:
+            return self.classsources[name]
+        if self.pyobj is not None:
+            # check whether in the case the classdesc corresponds to a real class
+            # there is a new attribute
+            cls = self.pyobj
+            if name in cls.__dict__:
+                source = ClassSource(self.bookkeeper, cls, self)
+                self.classsources[name] = source
+                return source
+        return None
 
 class MethodDesc(Desc):
     knowntype = types.MethodType

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/model.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/model.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/model.py	Thu Nov 17 22:33:05 2005
@@ -274,18 +274,19 @@
 
 class SomeInstance(SomeObject):
     "Stands for an instance of a (user-defined) class."
+
     def __init__(self, classdef, can_be_None=False):
         self.classdef = classdef
-        if classdef is not None:   # XXX should never really be None
-            self.knowntype = classdef.cls
+        self.knowntype = classdef
         self.can_be_None = can_be_None
+
     def fmt_knowntype(self, kt):
         return None
-    def fmt_classdef(self, cd):
-        if cd is None:
+    def fmt_classdef(self, cdef):
+        if cdef is None:
             return 'object'
         else:
-            return cd.cls.__name__
+            return cdef.name
 
     def can_be_none(self):
         return self.can_be_None

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/test/test_model.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/test/test_model.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/test/test_model.py	Thu Nov 17 22:33:05 2005
@@ -23,6 +23,7 @@
 class DummyClassDef:
     def __init__(self, cls=C):
         self.cls = cls
+        self.name = cls.__name__
 
 si0 = SomeInstance(DummyClassDef(), True)
 si1 = SomeInstance(DummyClassDef())

Modified: pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py	Thu Nov 17 22:33:05 2005
@@ -35,7 +35,10 @@
         if moreargs:
             raise Exception, 'type() called with more than one argument'
         if obj.is_constant():
-            r = immutablevalue(obj.knowntype)
+            if isinstance(obj, SomeInstance):
+                r = SomePBC([obj.classdef.classdesc])
+            else:
+                r = immutablevalue(obj.knowntype)
         else:
             r = SomeObject()
             r.knowntype = type

Modified: pypy/branch/somepbc-refactoring/pypy/rpython/normalizecalls.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/rpython/normalizecalls.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/rpython/normalizecalls.py	Thu Nov 17 22:33:05 2005
@@ -349,7 +349,7 @@
     def assign_id(classdef, nextid):
         classdef.minid = nextid
         nextid += 1
-        for subclass in classdef.subdefs.values():
+        for subclass in classdef.subdefs:
             nextid = assign_id(subclass, nextid)
         classdef.maxid = nextid
         return classdef.maxid

Modified: pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py	Thu Nov 17 22:33:05 2005
@@ -179,7 +179,8 @@
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.build_instance, [])
         # result should be a snippet.C instance
-        assert s.knowntype == snippet.C
+        assert isinstance(s, annmodel.SomeInstance)
+        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.C)
 
     def test_set_attr(self):
         a = self.RPythonAnnotator()
@@ -223,7 +224,9 @@
         # result should be a tuple of (C, positive_int)
         assert s.knowntype == tuple
         assert len(s.items) == 2
-        assert s.items[0].knowntype == snippet.C
+        s0 = s.items[0]
+        assert isinstance(s0, annmodel.SomeInstance)
+        assert s0.classdef == a.bookkeeper.getuniqueclassdef(snippet.C)
         assert s.items[1].knowntype == int
         assert s.items[1].nonneg == True
 
@@ -327,13 +330,15 @@
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.flow_usertype_info, [object])
         #a.translator.view()
-        assert s.knowntype == snippet.WithInit
+        assert isinstance(s, annmodel.SomeInstance)
+        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit)
 
     def test_flow_usertype_info2(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.flow_usertype_info, [snippet.WithMoreInit])
         #a.translator.view()
-        assert s.knowntype == snippet.WithMoreInit
+        assert isinstance(s, annmodel.SomeInstance)
+        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit)
 
     def test_flow_identity_info(self):
         a = self.RPythonAnnotator()
@@ -495,13 +500,13 @@
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction, [])
         assert isinstance(s, annmodel.SomeInstance)
-        assert s.knowntype is snippet.Exc
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
         
     def test_exception_deduction_we_are_dumb(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction_we_are_dumb, [])
         assert isinstance(s, annmodel.SomeInstance)
-        assert s.knowntype is snippet.Exc
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
         
     def test_nested_exception_deduction(self):
         a = self.RPythonAnnotator()
@@ -509,8 +514,8 @@
         assert isinstance(s, annmodel.SomeTuple)
         assert isinstance(s.items[0], annmodel.SomeInstance)
         assert isinstance(s.items[1], annmodel.SomeInstance)
-        assert s.items[0].knowntype is snippet.Exc
-        assert s.items[1].knowntype is snippet.Exc2
+        assert s.items[0].classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
+        assert s.items[1].classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc2)
 
     def test_exc_deduction_our_exc_plus_others(self):
         a = self.RPythonAnnotator()
@@ -565,9 +570,9 @@
     def test_propagation_of_fresh_instances_through_attrs_rec_0(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.make_r, [int])
-        assert s.knowntype == snippet.R
         Rdef = a.bookkeeper.getuniqueclassdef(snippet.R)
-        assert Rdef.attrs['r'].s_value.knowntype == snippet.R
+        assert s.classdef == Rdef
+        assert Rdef.attrs['r'].s_value.classdef == Rdef
         assert Rdef.attrs['n'].s_value.knowntype == int
         assert Rdef.attrs['m'].s_value.knowntype == int
     
@@ -575,13 +580,13 @@
     def test_propagation_of_fresh_instances_through_attrs_rec_eo(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.make_eo, [int])
-        assert s.knowntype == snippet.B
+        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.B)
         Even_def = a.bookkeeper.getuniqueclassdef(snippet.Even)
         Odd_def = a.bookkeeper.getuniqueclassdef(snippet.Odd)
-        assert listitem(Even_def.attrs['x'].s_value).knowntype == snippet.Odd
-        assert listitem(Even_def.attrs['y'].s_value).knowntype == snippet.Even
-        assert listitem(Odd_def.attrs['x'].s_value).knowntype == snippet.Even
-        assert listitem(Odd_def.attrs['y'].s_value).knowntype == snippet.Odd        
+        assert listitem(Even_def.attrs['x'].s_value).classdef == Odd_def
+        assert listitem(Even_def.attrs['y'].s_value).classdef == Even_def
+        assert listitem(Odd_def.attrs['x'].s_value).classdef == Even_def
+        assert listitem(Odd_def.attrs['y'].s_value).classdef == Odd_def
 
     def test_flow_rev_numbers(self):
         a = self.RPythonAnnotator()
@@ -627,20 +632,20 @@
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction_with_raise1, [bool])
         assert isinstance(s, annmodel.SomeInstance)
-        assert s.knowntype is snippet.Exc
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
 
     def test_exception_deduction_with_raise2(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction_with_raise2, [bool])
         assert isinstance(s, annmodel.SomeInstance)
-        assert s.knowntype is snippet.Exc
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
     def test_exception_deduction_with_raise3(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction_with_raise3, [bool])
         assert isinstance(s, annmodel.SomeInstance)
-        assert s.knowntype is snippet.Exc
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
     def test_type_is(self):
         class C(object):
@@ -651,7 +656,7 @@
             raise Exception
         a = self.RPythonAnnotator()
         s = a.build_types(f, [object])
-        assert s.knowntype is C
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(C)
 
     def test_ann_assert(self):
         def assert_(x):
@@ -689,7 +694,7 @@
 
         a = self.RPythonAnnotator()
         s = a.build_types(f, [list])
-        assert s.knowntype is IndexError  # KeyError ignored because l is a list
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError)  # KeyError ignored because l is a list
 
     def test_overrides(self):
         import sys
@@ -744,7 +749,8 @@
             return c.x
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
-        assert s.knowntype == C
+        assert isinstance(s, annmodel.SomeInstance)
+        assert s.classdef == a.bookkeeper.getuniqueclassdef(C)
 
     def test_circular_list_type(self):
         def f(n):
@@ -947,16 +953,19 @@
 
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
-        assert s.items[0].knowntype == C1
-        assert s.items[1].knowntype == C2
+        C1df = a.bookkeeper.getuniqueclassdef(C1)
+        C2df = a.bookkeeper.getuniqueclassdef(C2)
+        
+        assert s.items[0].classdef == C1df
+        assert s.items[1].classdef == C2df
 
         allocdesc = a.bookkeeper.getdesc(alloc)
         s_C1 = a.bookkeeper.immutablevalue(C1)
         s_C2 = a.bookkeeper.immutablevalue(C2)
         graph1 = allocdesc.specialize([s_C1])
         graph2 = allocdesc.specialize([s_C2])
-        assert a.binding(graph1.getreturnvar()).knowntype == C1
-        assert a.binding(graph2.getreturnvar()).knowntype == C2
+        assert a.binding(graph1.getreturnvar()).classdef == C1df
+        assert a.binding(graph2.getreturnvar()).classdef == C2df
         assert graph1 in a.translator.graphs
         assert graph2 in a.translator.graphs
 
@@ -971,7 +980,9 @@
             return g(l)
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
-        assert listitem(s).knowntype == T
+        s_item = listitem(s)
+        assert isinstance(s_item, annmodel.SomeInstance)
+        assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
           
     def test_assert_type_is_list_doesnt_lose_info(self):
         class T(object):
@@ -984,7 +995,10 @@
             return g(l)
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
-        assert listitem(s).knowntype == T
+        s_item = listitem(s)
+        assert isinstance(s_item, annmodel.SomeInstance)
+        assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
+
 
     def test_int_str_mul(self):
         def f(x,a,b):
@@ -1074,7 +1088,7 @@
         t.const = KeyError
         t.is_type_of = [ev]
         assert a.binding(et) == t
-        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef.cls == KeyError
+        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(KeyError)
 
     def test_reraiseAnything(self):
         def f(dic):
@@ -1091,7 +1105,7 @@
         t.is_type_of = [ev]
         t.const = KeyError    # IndexError ignored because 'dic' is a dict
         assert a.binding(et) == t
-        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef.cls == KeyError
+        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(KeyError)
 
     def test_exception_mixing(self):
         def h():
@@ -1126,7 +1140,7 @@
         t.knowntype = type
         t.is_type_of = [ev]
         assert a.binding(et) == t
-        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef.cls == Exception
+        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
 
     def test_try_except_raise_finally1(self):
         def h(): pass
@@ -1149,7 +1163,7 @@
         t.knowntype = type
         t.is_type_of = [ev]
         assert a.binding(et) == t
-        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef.cls == Exception
+        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
 
     def test_sys_attrs(self):
         import sys
@@ -1295,7 +1309,7 @@
         s = a.build_types(f, [])
         assert isinstance(s, annmodel.SomeInstance)
         assert not s.can_be_None
-        assert s.classdef.cls is A
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(A)
 
     def test_class_attribute(self):
         class A:
@@ -1321,7 +1335,7 @@
         s = a.build_types(f, [])
         assert isinstance(s, annmodel.SomeInstance)
         assert s.can_be_None
-        assert s.classdef.cls is A
+        assert s.classdef is a.bookkeeper.getuniqueclassdef(A)
 
     def test_long_list_recursive_getvalue(self):
         class A: pass
@@ -1502,7 +1516,7 @@
         s = a.build_types(f, [])
         assert isinstance(s, annmodel.SomeTuple)
         assert isinstance(s.items[0], annmodel.SomeInstance)
-        assert s.items[0].classdef.cls is A
+        assert s.items[0].classdef is a.bookkeeper.getuniqueclassdef(A)
         assert s.items[0].can_be_None
         assert s.items[1] == a.bookkeeper.immutablevalue(A.hello)
 
@@ -1711,7 +1725,8 @@
             return g(None)
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
-        assert s.knowntype == B
+        assert isinstance(s, annmodel.SomeInstance)
+        assert s.classdef == a.bookkeeper.getuniqueclassdef(B)
 
     def test_type_is_no_improvement(self):
         class B(object):



More information about the Pypy-commit mailing list