[pypy-commit] pypy py3k: merge default

pjenvey noreply at buildbot.pypy.org
Sat Oct 13 02:09:56 CEST 2012


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r58091:4bf82358629c
Date: 2012-10-12 17:04 -0700
http://bitbucket.org/pypy/pypy/changeset/4bf82358629c/

Log:	merge default

diff too long, truncating to 2000 out of 29662 lines

diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py
--- a/pypy/annotation/annrpython.py
+++ b/pypy/annotation/annrpython.py
@@ -1,9 +1,8 @@
-import sys
 import types
-from pypy.tool.ansi_print import ansi_log, raise_nicer_exception
+from pypy.tool.ansi_print import ansi_log
 from pypy.tool.pairtype import pair
 from pypy.tool.error import (format_blocked_annotation_error,
-                             format_someobject_error, AnnotatorError)
+                             AnnotatorError, gather_error, ErrorWrapper)
 from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph,
                                       c_last_exception, checkgraph)
 from pypy.translator import simplify, transform
@@ -38,22 +37,9 @@
         self.links_followed = {} # set of links that have ever been followed
         self.notify = {}        # {block: {positions-to-reflow-from-when-done}}
         self.fixed_graphs = {}  # set of graphs not to annotate again
-        self.blocked_blocks = {} # set of {blocked_block: graph}
-        # --- the following information is recorded for debugging only ---
-        # --- and only if annotation.model.DEBUG is kept to True
-        self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)}
-                                    # records the location of BlockedInference
-                                    # exceptions that blocked some blocks.
+        self.blocked_blocks = {} # set of {blocked_block: (graph, index)}
+        # --- the following information is recorded for debugging ---
         self.blocked_graphs = {} # set of graphs that have blocked blocks
-        self.bindingshistory = {}# map Variables to lists of SomeValues
-        self.binding_caused_by = {}     # map Variables to position_keys
-               # records the caller position that caused bindings of inputargs
-               # to be updated
-        self.binding_cause_history = {} # map Variables to lists of positions
-                # history of binding_caused_by, kept in sync with
-                # bindingshistory
-        self.reflowcounter = {}
-        self.return_bindings = {} # map return Variables to their graphs
         # --- end of debugging information ---
         self.frozen = False
         if policy is None:
@@ -77,10 +63,6 @@
                 ret[key] = {}
         return ret
 
-    def _register_returnvar(self, flowgraph):
-        if annmodel.DEBUG:
-            self.return_bindings[flowgraph.getreturnvar()] = flowgraph
-
     #___ convenience high-level interface __________________
 
     def build_types(self, function, input_arg_types, complete_now=True,
@@ -182,10 +164,9 @@
     #___ medium-level interface ____________________________
 
     def addpendinggraph(self, flowgraph, inputcells):
-        self._register_returnvar(flowgraph)
         self.addpendingblock(flowgraph, flowgraph.startblock, inputcells)
 
-    def addpendingblock(self, graph, block, cells, called_from_graph=None):
+    def addpendingblock(self, graph, block, cells):
         """Register an entry point into block with the given input cells."""
         if graph in self.fixed_graphs:
             # special case for annotating/rtyping in several phases: calling
@@ -200,9 +181,9 @@
             for a in cells:
                 assert isinstance(a, annmodel.SomeObject)
             if block not in self.annotated:
-                self.bindinputargs(graph, block, cells, called_from_graph)
+                self.bindinputargs(graph, block, cells)
             else:
-                self.mergeinputargs(graph, block, cells, called_from_graph)
+                self.mergeinputargs(graph, block, cells)
             if not self.annotated[block]:
                 self.pendingblocks[block] = graph
 
@@ -211,8 +192,6 @@
         while True:
             while self.pendingblocks:
                 block, graph = self.pendingblocks.popitem()
-                if annmodel.DEBUG:
-                    self.flowin_block = block # we need to keep track of block
                 self.processblock(graph, block)
             self.policy.no_more_blocks_to_annotate(self)
             if not self.pendingblocks:
@@ -263,60 +242,14 @@
     def typeannotation(self, t):
         return signature.annotation(t, self.bookkeeper)
 
-    def ondegenerated(self, what, s_value, where=None, called_from_graph=None):
-        if self.policy.allow_someobjects:
-            return
-        # is the function itself tagged with allow_someobjects?
-        position_key = where or getattr(self.bookkeeper, 'position_key', None)
-        if position_key is not None:
-            graph, block, i = position_key
-            try:
-                if graph.func.allow_someobjects:
-                    return
-            except AttributeError:
-                pass
-
-        msgstr = format_someobject_error(self, position_key, what, s_value,
-                                         called_from_graph,
-                                         self.bindings.get(what, "(none)"))
-
-        raise AnnotatorError(msgstr)
-
-    def setbinding(self, arg, s_value, called_from_graph=None, where=None):
+    def setbinding(self, arg, s_value):
         if arg in self.bindings:
             assert s_value.contains(self.bindings[arg])
-            # for debugging purposes, record the history of bindings that
-            # have been given to this variable
-            if annmodel.DEBUG:
-                history = self.bindingshistory.setdefault(arg, [])
-                history.append(self.bindings[arg])
-                cause_history = self.binding_cause_history.setdefault(arg, [])
-                cause_history.append(self.binding_caused_by[arg])
-
-        degenerated = annmodel.isdegenerated(s_value)
-
-        if degenerated:
-            self.ondegenerated(arg, s_value, where=where,
-                               called_from_graph=called_from_graph)
-
         self.bindings[arg] = s_value
-        if annmodel.DEBUG:
-            if arg in self.return_bindings:
-                log.event("%s -> %s" % 
-                    (self.whereami((self.return_bindings[arg], None, None)), 
-                     s_value)) 
-
-            if arg in self.return_bindings and degenerated:
-                self.warning("result degenerated to SomeObject",
-                             (self.return_bindings[arg],None, None))
-                
-            self.binding_caused_by[arg] = called_from_graph
 
     def transfer_binding(self, v_target, v_source):
         assert v_source in self.bindings
         self.bindings[v_target] = self.bindings[v_source]
-        if annmodel.DEBUG:
-            self.binding_caused_by[v_target] = None
 
     def warning(self, msg, pos=None):
         if pos is None:
@@ -332,14 +265,11 @@
 
     #___ interface for annotator.bookkeeper _______
 
-    def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph 
+    def recursivecall(self, graph, whence, inputcells):
         if isinstance(whence, tuple):
-            parent_graph, parent_block, parent_index = position_key = whence
+            parent_graph, parent_block, parent_index = whence
             tag = parent_block, parent_index
             self.translator.update_call_graph(parent_graph, graph, tag)
-        else:
-            position_key = None
-        self._register_returnvar(graph)
         # self.notify[graph.returnblock] is a dictionary of call
         # points to this func which triggers a reflow whenever the
         # return block of this graph has been analysed.
@@ -353,8 +283,7 @@
             callpositions[callback] = True
 
         # generalize the function's input arguments
-        self.addpendingblock(graph, graph.startblock, inputcells,
-                             position_key)
+        self.addpendingblock(graph, graph.startblock, inputcells)
 
         # get the (current) return value
         v = graph.getreturnvar()
@@ -404,9 +333,6 @@
         #      input variables).
 
         #print '* processblock', block, cells
-        if annmodel.DEBUG:
-            self.reflowcounter.setdefault(block, 0)
-            self.reflowcounter[block] += 1
         self.annotated[block] = graph
         if block in self.blocked_blocks:
             del self.blocked_blocks[block]
@@ -414,7 +340,7 @@
             self.flowin(graph, block)
         except BlockedInference, e:
             self.annotated[block] = False   # failed, hopefully temporarily
-            self.blocked_blocks[block] = graph
+            self.blocked_blocks[block] = (graph, e.opindex)
         except Exception, e:
             # hack for debug tools only
             if not hasattr(e, '__annotator_block'):
@@ -433,25 +359,24 @@
         self.pendingblocks[block] = graph
         assert block in self.annotated
         self.annotated[block] = False  # must re-flow
-        self.blocked_blocks[block] = graph
+        self.blocked_blocks[block] = (graph, None)
 
-    def bindinputargs(self, graph, block, inputcells, called_from_graph=None):
+    def bindinputargs(self, graph, block, inputcells):
         # Create the initial bindings for the input args of a block.
         assert len(block.inputargs) == len(inputcells)
-        where = (graph, block, None)
         for a, cell in zip(block.inputargs, inputcells):
-            self.setbinding(a, cell, called_from_graph, where=where)
+            self.setbinding(a, cell)
         self.annotated[block] = False  # must flowin.
-        self.blocked_blocks[block] = graph
+        self.blocked_blocks[block] = (graph, None)
 
-    def mergeinputargs(self, graph, block, inputcells, called_from_graph=None):
+    def mergeinputargs(self, graph, block, inputcells):
         # Merge the new 'cells' with each of the block's existing input
         # variables.
         oldcells = [self.binding(a) for a in block.inputargs]
         unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)]
         # if the merged cells changed, we must redo the analysis
         if unions != oldcells:
-            self.bindinputargs(graph, block, unions, called_from_graph)
+            self.bindinputargs(graph, block, unions)
 
     def whereami(self, position_key):
         graph, block, i = position_key
@@ -471,14 +396,11 @@
             for i in range(len(block.operations)):
                 try:
                     self.bookkeeper.enter((graph, block, i))
-                    self.consider_op(block.operations[i])
+                    self.consider_op(block, i)
                 finally:
                     self.bookkeeper.leave()
 
         except BlockedInference, e:
-            if annmodel.DEBUG:
-                self.why_not_annotated[block] = sys.exc_info()
-
             if (e.op is block.operations[-1] and
                 block.exitswitch == c_last_exception):
                 # this is the case where the last operation of the block will
@@ -562,8 +484,7 @@
                    and issubclass(link.exitcase, py.builtin.BaseException):
                 assert last_exception_var and last_exc_value_var
                 last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase)
-                last_exception_object = annmodel.SomeObject()
-                last_exception_object.knowntype = type
+                last_exception_object = annmodel.SomeType()
                 if isinstance(last_exception_var, Constant):
                     last_exception_object.const = last_exception_var.value
                 last_exception_object.is_type_of = [last_exc_value_var]
@@ -573,8 +494,7 @@
                 if isinstance(last_exc_value_var, Variable):
                     self.setbinding(last_exc_value_var, last_exc_value_object)
 
-                last_exception_object = annmodel.SomeObject()
-                last_exception_object.knowntype = type
+                last_exception_object = annmodel.SomeType()
                 if isinstance(last_exception_var, Constant):
                     last_exception_object.const = last_exception_var.value
                 #if link.exitcase is Exception:
@@ -610,9 +530,8 @@
                         for v in cell.is_type_of:
                             new_vs = renaming.get(v,[])
                             renamed_is_type_of += new_vs
-                        newcell = annmodel.SomeObject()
-                        if cell.knowntype == type:
-                            newcell.knowntype = type
+                        assert cell.knowntype is type
+                        newcell = annmodel.SomeType()
                         if cell.is_constant():
                             newcell.const = cell.const
                         cell = newcell
@@ -653,7 +572,8 @@
 
     #___ creating the annotations based on operations ______
 
-    def consider_op(self, op):
+    def consider_op(self, block, opindex):
+        op = block.operations[opindex]
         argcells = [self.binding(a) for a in op.args]
         consider_meth = getattr(self,'consider_op_'+op.opname,
                                 None)
@@ -668,16 +588,18 @@
         # boom -- in the assert of setbinding()
         for arg in argcells:
             if isinstance(arg, annmodel.SomeImpossibleValue):
-                raise BlockedInference(self, op)
+                raise BlockedInference(self, op, opindex)
         try:
             resultcell = consider_meth(*argcells)
-        except Exception:
+        except Exception, e:
             graph = self.bookkeeper.position_key[0]
-            raise_nicer_exception(op, str(graph))
+            e.args = e.args + (
+                ErrorWrapper(gather_error(self, graph, block, opindex)),)
+            raise
         if resultcell is None:
             resultcell = self.noreturnvalue(op)
         elif resultcell == annmodel.s_ImpossibleValue:
-            raise BlockedInference(self, op) # the operation cannot succeed
+            raise BlockedInference(self, op, opindex) # the operation cannot succeed
         assert isinstance(resultcell, annmodel.SomeObject)
         assert isinstance(op.result, Variable)
         self.setbinding(op.result, resultcell)  # bind resultcell to op.result
@@ -728,13 +650,14 @@
     """This exception signals the type inference engine that the situation
     is currently blocked, and that it should try to progress elsewhere."""
 
-    def __init__(self, annotator, op):
+    def __init__(self, annotator, op, opindex):
         self.annotator = annotator
         try:
             self.break_at = annotator.bookkeeper.position_key
         except AttributeError:
             self.break_at = None
         self.op = op
+        self.opindex = opindex
 
     def __repr__(self):
         if not self.break_at:
diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -13,9 +13,9 @@
 from pypy.annotation.model import SomePBC, SomeFloat, s_None
 from pypy.annotation.model import SomeExternalObject, SomeWeakRef
 from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess
-from pypy.annotation.model import SomeSingleFloat, SomeLongFloat
+from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType
 from pypy.annotation.model import unionof, UnionError, missing_operation
-from pypy.annotation.model import isdegenerated, TLS
+from pypy.annotation.model import TLS
 from pypy.annotation.model import read_can_only_throw
 from pypy.annotation.model import add_knowntypedata, merge_knowntypedata
 from pypy.annotation.model import SomeGenericCallable
@@ -29,15 +29,6 @@
 def immutablevalue(x):
     return getbookkeeper().immutablevalue(x)
 
-def unioncheck(*somevalues):
-    s_value = unionof(*somevalues)
-    if isdegenerated(s_value):
-        if not getattr(TLS, 'no_side_effects_in_union', 0):
-            bookkeeper = getbookkeeper()
-            if bookkeeper is not None:
-                bookkeeper.ondegenerated('union', s_value)
-    return s_value
-
 # XXX unify this with ObjSpace.MethodTable
 BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod',
                          'truediv', 'floordiv', 'divmod', 'pow',
@@ -64,35 +55,7 @@
 class __extend__(pairtype(SomeObject, SomeObject)):
 
     def union((obj1, obj2)):
-        if obj1 == obj2:
-            return obj1
-        else:
-            result = SomeObject()
-            if obj1.knowntype == obj2.knowntype and obj1.knowntype != object:
-                result.knowntype = obj1.knowntype
-            is_type_of1 = getattr(obj1, 'is_type_of', None)
-            is_type_of2 = getattr(obj2, 'is_type_of', None)
-            if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const:
-                result.const = obj1.const
-                is_type_of = {}
-                if is_type_of1:
-                    for v in is_type_of1:
-                        is_type_of[v] = True
-                if is_type_of2:
-                    for v in is_type_of2:
-                        is_type_of[v] = True
-                if is_type_of:
-                    result.is_type_of = is_type_of.keys()
-            else:
-                if is_type_of1 and is_type_of1 == is_type_of2:
-                    result.is_type_of = is_type_of1
-            # try to preserve the origin of SomeObjects
-            if obj1 == result:
-                result = obj1
-            elif obj2 == result:
-                result = obj2
-            unioncheck(result)
-            return result
+        raise UnionError(obj1, obj2)
 
     # inplace_xxx ---> xxx by default
     def inplace_add((obj1, obj2)):      return pair(obj1, obj2).add()
@@ -238,7 +201,30 @@
 
     getitem_idx = getitem_idx_key
     getitem_key = getitem_idx_key
-        
+
+
+class __extend__(pairtype(SomeType, SomeType)):
+
+    def union((obj1, obj2)):
+        result = SomeType()
+        is_type_of1 = getattr(obj1, 'is_type_of', None)
+        is_type_of2 = getattr(obj2, 'is_type_of', None)
+        if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const:
+            result.const = obj1.const
+            is_type_of = {}
+            if is_type_of1:
+                for v in is_type_of1:
+                    is_type_of[v] = True
+            if is_type_of2:
+                for v in is_type_of2:
+                    is_type_of[v] = True
+            if is_type_of:
+                result.is_type_of = is_type_of.keys()
+        else:
+            if is_type_of1 and is_type_of1 == is_type_of2:
+                result.is_type_of = is_type_of1
+        return result
+
 
 # cloning a function with identical code, for the can_only_throw attribute
 def _clone(f, can_only_throw = None):
@@ -565,14 +551,30 @@
 
     def union((tup1, tup2)):
         if len(tup1.items) != len(tup2.items):
-            return SomeObject()
+            raise UnionError("cannot take the union of a tuple of length %d "
+                             "and a tuple of length %d" % (len(tup1.items),
+                                                           len(tup2.items)))
         else:
-            unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)]
+            unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)]
             return SomeTuple(items = unions)
 
     def add((tup1, tup2)):
         return SomeTuple(items = tup1.items + tup2.items)
 
+    def eq(tup1tup2):
+        tup1tup2.union()
+        return s_Bool
+    ne = eq
+
+    def lt((tup1, tup2)):
+        raise Exception("unsupported: (...) < (...)")
+    def le((tup1, tup2)):
+        raise Exception("unsupported: (...) <= (...)")
+    def gt((tup1, tup2)):
+        raise Exception("unsupported: (...) > (...)")
+    def ge((tup1, tup2)):
+        raise Exception("unsupported: (...) >= (...)")
+
 
 class __extend__(pairtype(SomeDict, SomeDict)):
 
@@ -724,8 +726,7 @@
         else:
             basedef = ins1.classdef.commonbase(ins2.classdef)
             if basedef is None:
-                # print warning?
-                return SomeObject()
+                raise UnionError(ins1, ins2)
         flags = ins1.flags
         if flags:
             flags = flags.copy()
@@ -765,7 +766,7 @@
 class __extend__(pairtype(SomeIterator, SomeIterator)):
 
     def union((iter1, iter2)):
-        s_cont = unioncheck(iter1.s_container, iter2.s_container)
+        s_cont = unionof(iter1.s_container, iter2.s_container)
         if iter1.variant != iter2.variant:
             raise UnionError("merging incompatible iterators variants")
         return SomeIterator(s_cont, *iter1.variant)
@@ -779,7 +780,7 @@
             bltn1.s_self is None or bltn2.s_self is None):
             raise UnionError("cannot merge two different builtin functions "
                              "or methods:\n  %r\n  %r" % (bltn1, bltn2))
-        s_self = unioncheck(bltn1.s_self, bltn2.s_self)
+        s_self = unionof(bltn1.s_self, bltn2.s_self)
         return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname)
 
 class __extend__(pairtype(SomePBC, SomePBC)):
@@ -807,7 +808,7 @@
             unique_key = desc
             bk = desc.bookkeeper
             s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s)
-            s_result = unioncheck(s_result, gencall.s_result)
+            s_result = unionof(s_result, gencall.s_result)
             assert gencall.s_result.contains(s_result)
         return gencall
 
diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py
--- a/pypy/annotation/bookkeeper.py
+++ b/pypy/annotation/bookkeeper.py
@@ -10,7 +10,7 @@
      SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \
      SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \
      SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \
-     SomeWeakRef, lltype_to_annotation
+     SomeWeakRef, lltype_to_annotation, SomeType
 from pypy.annotation.classdef import InstanceSource, ClassDef
 from pypy.annotation.listdef import ListDef, ListItem
 from pypy.annotation.dictdef import DictDef
@@ -148,7 +148,6 @@
         self.descs = {}          # map Python objects to their XxxDesc wrappers
         self.methoddescs = {}    # map (funcdesc, classdef) to the MethodDesc
         self.classdefs = []      # list of all ClassDefs
-        self.pbctypes = {}
         self.seen_mutable = {}
         self.listdefs = {}       # map position_keys to ListDefs
         self.dictdefs = {}       # map position_keys to DictDefs
@@ -167,9 +166,6 @@
 
         self.stats = Stats(self)
 
-        # used in SomeObject.__new__ for keeping debugging info
-        self._isomeobject_coming_from = identity_dict()
-
         delayed_imports()
 
     def count(self, category, *args):
@@ -275,8 +271,7 @@
         """Get the ClassDef associated with the given user cls.
         Avoid using this!  It breaks for classes that must be specialized.
         """
-        if cls is object:
-            return None
+        assert cls is not object
         desc = self.getdesc(cls)
         return desc.getuniqueclassdef()
 
@@ -325,8 +320,6 @@
         if hasattr(x, 'im_self') and x.im_self is None:
             x = x.im_func
             assert not hasattr(x, 'im_self')
-        if x is sys: # special case constant sys to someobject
-            return SomeObject()
         tp = type(x)
         if issubclass(tp, Symbolic): # symbolic constants support
             result = x.annotation()
@@ -445,6 +438,12 @@
             result = SomeOOInstance(ootype.typeOf(x))
         elif isinstance(x, (ootype._object)):
             result = SomeOOObject()
+        elif tp is type:
+            if (x is type(None) or      # add cases here if needed
+                x.__module__ == 'pypy.rpython.lltypesystem.lltype'):
+                result = SomeType()
+            else:
+                result = SomePBC([self.getdesc(x)])
         elif callable(x):
             if hasattr(x, 'im_self') and hasattr(x, 'im_func'):
                 # on top of PyPy, for cases like 'l.append' where 'l' is a
@@ -455,20 +454,13 @@
                 # for cases like 'l.append' where 'l' is a global constant list
                 s_self = self.immutablevalue(x.__self__, need_const)
                 result = s_self.find_method(x.__name__)
-                if result is None:
-                    result = SomeObject()
+                assert result is not None
             else:
                 result = None
             if result is None:
-                if (self.annotator.policy.allow_someobjects
-                    and getattr(x, '__module__', None) == '__builtin__'
-                    # XXX note that the print support functions are __builtin__
-                    and tp not in (types.FunctionType, types.MethodType)):
-                    result = SomeObject()
-                    result.knowntype = tp # at least for types this needs to be correct
-                else:
-                    result = SomePBC([self.getdesc(x)])
-        elif hasattr(x, '_freeze_') and x._freeze_():
+                result = SomePBC([self.getdesc(x)])
+        elif hasattr(x, '_freeze_'):
+            assert x._freeze_() is True
             # user-defined classes can define a method _freeze_(), which
             # is called when a prebuilt instance is found.  If the method
             # returns True, the instance is considered immutable and becomes
@@ -476,16 +468,18 @@
             result = SomePBC([self.getdesc(x)])
         elif hasattr(x, '__class__') \
                  and x.__class__.__module__ != '__builtin__':
+            if hasattr(x, '_cleanup_'):
+                x._cleanup_()
             self.see_mutable(x)
             result = SomeInstance(self.getuniqueclassdef(x.__class__))
         elif x is None:
             return s_None
         else:
-            result = SomeObject()
+            raise Exception("Don't know how to represent %r" % (x,))
         if need_const:
             result.const = x
         return result
-    
+
     def getdesc(self, pyobj):
         # get the XxxDesc wrapper for the given Python object, which must be
         # one of:
@@ -509,8 +503,10 @@
             elif isinstance(pyobj, types.MethodType):
                 if pyobj.im_self is None:   # unbound
                     return self.getdesc(pyobj.im_func)
-                elif (hasattr(pyobj.im_self, '_freeze_') and
-                      pyobj.im_self._freeze_()):  # method of frozen
+                if hasattr(pyobj.im_self, '_cleanup_'):
+                    pyobj.im_self._cleanup_()
+                if hasattr(pyobj.im_self, '_freeze_'):  # method of frozen
+                    assert pyobj.im_self._freeze_() is True
                     result = description.MethodOfFrozenDesc(self,
                         self.getdesc(pyobj.im_func),            # funcdesc
                         self.getdesc(pyobj.im_self))            # frozendesc
@@ -529,9 +525,9 @@
                         name)
             else:
                 # must be a frozen pre-built constant, but let's check
-                try:
-                    assert pyobj._freeze_()
-                except AttributeError:
+                if hasattr(pyobj, '_freeze_'):
+                    assert pyobj._freeze_() is True
+                else:
                     if hasattr(pyobj, '__call__'):
                         msg = "object with a __call__ is not RPython"
                     else:
@@ -551,11 +547,7 @@
             return False
         
     def getfrozen(self, pyobj):
-        result = description.FrozenDesc(self, pyobj)
-        cls = result.knowntype
-        if cls not in self.pbctypes:
-            self.pbctypes[cls] = True
-        return result
+        return description.FrozenDesc(self, pyobj)
 
     def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name,
                       flags={}):
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -150,7 +150,7 @@
 
 
 def builtin_isinstance(s_obj, s_type, variables=None):
-    r = SomeBool() 
+    r = SomeBool()
     if s_type.is_constant():
         typ = s_type.const
         if issubclass(typ, pypy.rlib.rarithmetic.base_int):
@@ -158,18 +158,12 @@
         else:
             if typ == long:
                 getbookkeeper().warning("isinstance(., long) is not RPython")
-                if s_obj.is_constant():
-                    r.const = isinstance(s_obj.const, long)
-                else:
-                    if type(s_obj) is not SomeObject: # only SomeObjects could be longs
-                        # type(s_obj) < SomeObject -> SomeBool(False)
-                        # type(s_obj) == SomeObject -> SomeBool()
-                        r.const = False
+                r.const = False
                 return r
-                
+
             assert not issubclass(typ, (int, long)) or typ in (bool, int, long), (
                 "for integers only isinstance(.,int|r_uint) are supported")
- 
+
             if s_obj.is_constant():
                 r.const = isinstance(s_obj.const, typ)
             elif our_issubclass(s_obj.knowntype, typ):
@@ -195,8 +189,8 @@
         for variable in variables:
             assert bk.annotator.binding(variable) == s_obj
         r.knowntypedata = {}
-        if (not isinstance(s_type, SomeBuiltin)
-            or typ.__module__ == '__builtin__'):
+        
+        if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC):
             add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ))
     return r
 
diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py
--- a/pypy/annotation/classdef.py
+++ b/pypy/annotation/classdef.py
@@ -2,8 +2,7 @@
 Type inference for user-defined classes.
 """
 from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof
-from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\
-     SomeString
+from pypy.annotation.model import SomeInteger, SomeTuple, SomeString
 from pypy.annotation import description
 
 
@@ -79,11 +78,7 @@
         if source.instance_level:
             # a prebuilt instance source forces readonly=False, see above
             self.modified(classdef)
-        s_new_value = unionof(self.s_value, s_value)       
-        if isdegenerated(s_new_value):            
-            self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name),
-                                          s_new_value)
-                
+        s_new_value = unionof(self.s_value, s_value)    # XXX "source %r attr %s" % (source, self.name),
         self.s_value = s_new_value
 
     def getvalue(self):
@@ -92,11 +87,7 @@
 
     def merge(self, other, classdef='?'):
         assert self.name == other.name
-        s_new_value = unionof(self.s_value, other.s_value)
-        if isdegenerated(s_new_value):
-            what = "%s attr %s" % (classdef, self.name)
-            self.bookkeeper.ondegenerated(what, s_new_value)
-
+        s_new_value = unionof(self.s_value, other.s_value)  # XXX "%s attr %s" % (classdef, self.name)
         self.s_value = s_new_value
         if not other.readonly:
             self.modified(classdef)
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -247,13 +247,16 @@
         defs_s = []
         if graph is None:
             signature = self.signature
-            defaults  = self.defaults
+            defaults = self.defaults
         else:
             signature = graph.signature
-            defaults  = graph.defaults
+            defaults = graph.defaults
         if defaults:
             for x in defaults:
-                defs_s.append(self.bookkeeper.immutablevalue(x))
+                if x is NODEFAULT:
+                    defs_s.append(None)
+                else:
+                    defs_s.append(self.bookkeeper.immutablevalue(x))
         try:
             inputcells = args.match_signature(signature, defs_s)
         except ArgErr, e:
diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py
--- a/pypy/annotation/dictdef.py
+++ b/pypy/annotation/dictdef.py
@@ -119,13 +119,9 @@
                 self.dictvalue is other.dictvalue)
 
     def union(self, other):
-        if (self.same_as(MOST_GENERAL_DICTDEF) or
-            other.same_as(MOST_GENERAL_DICTDEF)):
-            return MOST_GENERAL_DICTDEF   # without merging
-        else:
-            self.dictkey.merge(other.dictkey)
-            self.dictvalue.merge(other.dictvalue)
-            return self
+        self.dictkey.merge(other.dictkey)
+        self.dictvalue.merge(other.dictvalue)
+        return self
 
     def generalize_key(self, s_key):
         self.dictkey.generalize(s_key)
@@ -143,6 +139,3 @@
 
     def __repr__(self):
         return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value)
-
-
-MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject())
diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py
--- a/pypy/annotation/listdef.py
+++ b/pypy/annotation/listdef.py
@@ -1,6 +1,6 @@
 from pypy.annotation.model import SomeObject, s_ImpossibleValue
 from pypy.annotation.model import SomeList, SomeString
-from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated
+from pypy.annotation.model import unionof, TLS, UnionError
 
 
 class TooLateForChange(Exception):
@@ -92,11 +92,6 @@
             if s_new_value != s_value:
                 if self.dont_change_any_more:
                     raise TooLateForChange
-            if isdegenerated(s_new_value):
-                if self.bookkeeper:
-                    self.bookkeeper.ondegenerated(self, s_new_value)
-                elif other.bookkeeper:
-                    other.bookkeeper.ondegenerated(other, s_new_value)
             self.patch()    # which should patch all refs to 'other'
             if s_new_value != s_value:
                 self.s_value = s_new_value
@@ -114,8 +109,6 @@
 
     def generalize(self, s_other_value):
         s_new_value = unionof(self.s_value, s_other_value)
-        if isdegenerated(s_new_value) and self.bookkeeper:
-            self.bookkeeper.ondegenerated(self, s_new_value)        
         updated = s_new_value != self.s_value
         if updated:
             if self.dont_change_any_more:
@@ -157,12 +150,8 @@
         return self.listitem is other.listitem
 
     def union(self, other):
-        if (self.same_as(MOST_GENERAL_LISTDEF) or
-            other.same_as(MOST_GENERAL_LISTDEF)):
-            return MOST_GENERAL_LISTDEF   # without merging
-        else:
-            self.listitem.merge(other.listitem)
-            return self
+        self.listitem.merge(other.listitem)
+        return self
 
     def agree(self, other):
         s_self_value = self.read_item()
@@ -221,7 +210,5 @@
         #else: it's fine, don't set immutable=True at all (see
         #      test_can_merge_immutable_list_with_regular_list)
 
-MOST_GENERAL_LISTDEF = ListDef(None, SomeObject())
-
 s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True),
                                      resized = True))
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -36,8 +36,6 @@
 from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat
 import inspect, weakref
 
-DEBUG = False    # set to False to disable recording of debugging information
-
 class State(object):
     # A global attribute :-(  Patch it with 'True' to enable checking of
     # the no_nul attribute...
@@ -48,8 +46,11 @@
     """The set of all objects.  Each instance stands
     for an arbitrary object about which nothing is known."""
     __metaclass__ = extendabletype
+    immutable = False
     knowntype = object
-    immutable = False
+
+    def __init__(self):
+        assert type(self) is not SomeObject
 
     def __eq__(self, other):
         return (self.__class__ is other.__class__ and
@@ -105,60 +106,28 @@
         return self.immutable and 'const' in self.__dict__
 
     # delegate accesses to 'const' to accesses to 'const_box.value',
-    # where const_box is a Constant.  XXX the idea is to eventually
-    # use systematically 'const_box' instead of 'const' for
-    # non-immutable constant annotations
+    # where const_box is a Constant.  This is not a property, in order
+    # to allow 'self.const = xyz' to work as well.
     class ConstAccessDelegator(object):
         def __get__(self, obj, cls=None):
             return obj.const_box.value
     const = ConstAccessDelegator()
     del ConstAccessDelegator
 
-    # for debugging, record where each instance comes from
-    # this is disabled if DEBUG is set to False
-    def __new__(cls, *args, **kw):
-        new = super(SomeObject, cls).__new__
-        if new is object.__new__:
-            # Since python 2.6, object.__new__ warns
-            # when parameters are passed
-            self = new(cls)
-        else:
-            self = new(cls, *args, **kw)
-        if DEBUG:
-            try:
-                bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
-                position_key = bookkeeper.position_key
-            except AttributeError:
-                pass
-            else:
-                bookkeeper._isomeobject_coming_from[self] = position_key, None
+    def can_be_none(self):
+        return True
+
+    def nonnoneify(self):
         return self
 
-    def origin(self):
-        bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
-        if bookkeeper is None:
-            return None
-        return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0]
-    origin = property(origin)
 
-    def caused_by_merge(self):
-        bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
-        if bookkeeper is None:
-            return None
-        return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1]
-    def set_caused_by_merge(self, nvalue):
-        bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
-        if bookkeeper is None:
-            return
-        bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue
-    caused_by_merge = property(caused_by_merge, set_caused_by_merge)
-    del set_caused_by_merge
+class SomeType(SomeObject):
+    "Stands for a type.  We might not be sure which one it is."
+    knowntype = type
+    immutable = True
 
     def can_be_none(self):
-        return True
-        
-    def nonnoneify(self):
-        return self
+        return False
 
 class SomeFloat(SomeObject):
     "Stands for a float or an integer."
@@ -517,6 +486,7 @@
 
 s_None = SomePBC([], can_be_None=True)
 s_Bool = SomeBool()
+s_Int  = SomeInteger()
 s_ImpossibleValue = SomeImpossibleValue()
 s_Str0 = SomeString(no_nul=True)
 
@@ -710,14 +680,8 @@
         # this is just a performance shortcut
         if s1 != s2:
             s1 = pair(s1, s2).union()
-    if DEBUG:
-        if s1.caused_by_merge is None and len(somevalues) > 1:
-            s1.caused_by_merge = somevalues
     return s1
 
-def isdegenerated(s_value):
-    return s_value.__class__ is SomeObject and s_value.knowntype is not type
-
 # make knowntypedata dictionary
 
 def add_knowntypedata(ktd, truth, vars, s_obj):
diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py
--- a/pypy/annotation/policy.py
+++ b/pypy/annotation/policy.py
@@ -10,7 +10,6 @@
 
 
 class BasicAnnotatorPolicy(object):
-    allow_someobjects = True
 
     def event(pol, bookkeeper, what, *args):
         pass
@@ -80,6 +79,3 @@
     def specialize__ll_and_arg(pol, *args):
         from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
         return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args)
-
-class StrictAnnotatorPolicy(AnnotatorPolicy):
-    allow_someobjects = False
diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py
--- a/pypy/annotation/signature.py
+++ b/pypy/annotation/signature.py
@@ -3,9 +3,9 @@
 from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\
      SomeFloat, SomeList, SomeDict, s_None, \
      SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\
-     unionof, SomeUnicodeString
-from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
-from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
+     unionof, SomeUnicodeString, SomeType
+from pypy.annotation.listdef import ListDef
+from pypy.annotation.dictdef import DictDef
 
 _annotation_cache = {}
 
@@ -78,24 +78,18 @@
         return SomeString()
     elif t is unicode:
         return SomeUnicodeString()
-    elif t is list:
-        return SomeList(MOST_GENERAL_LISTDEF)
-    elif t is dict:
-        return SomeDict(MOST_GENERAL_DICTDEF)
-    # can't do tuple
     elif t is types.NoneType:
         return s_None
     elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy):
         entry = extregistry.lookup_type(t, bookkeeper.policy)
         return entry.compute_annotation_bk(bookkeeper)
-    elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes:
+    elif t is type:
+        return SomeType()
+    elif bookkeeper and not hasattr(t, '_freeze_'):
         classdef = bookkeeper.getuniqueclassdef(t)
         return SomeInstance(classdef)
     else:
-        o = SomeObject()
-        if t != object:
-            o.knowntype = t
-        return o
+        raise AssertionError("annotationoftype(%r)" % (t,))
 
 class Sig(object):
 
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -24,7 +24,7 @@
     assert isinstance(s_list, annmodel.SomeList)
     return s_list.listdef.listitem.s_value
 
-def somelist(s_type=annmodel.SomeObject()):
+def somelist(s_type):
     return annmodel.SomeList(ListDef(None, s_type))
 
 def dictkey(s_dict):
@@ -35,7 +35,7 @@
     assert isinstance(s_dict, annmodel.SomeDict)
     return s_dict.dictdef.dictvalue.s_value
 
-def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()):
+def somedict(s_key, s_value):
     return annmodel.SomeDict(DictDef(None, s_key, s_value))
 
 
@@ -205,15 +205,6 @@
                                 annmodel.SomeInteger()
                                 ])
 
-    def test_inheritance2(self):
-        a = self.RPythonAnnotator()
-        s = a.build_types(snippet._inheritance_nonrunnable, [])
-        # result should be exactly:
-        assert s == annmodel.SomeTuple([
-                                annmodel.SomeInteger(),
-                                annmodel.SomeObject()
-                                ])
-
     def test_poor_man_range(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.poor_man_range, [int])
@@ -336,9 +327,13 @@
 
     def test_flow_type_info(self):
         a = self.RPythonAnnotator()
-        s = a.build_types(snippet.flow_type_info, [object])
+        s = a.build_types(snippet.flow_type_info, [int])
         a.simplify()
-        #a.translator.view()
+        assert s.knowntype == int
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(snippet.flow_type_info, [str])
+        a.simplify()
         assert s.knowntype == int
 
     def test_flow_type_info_2(self):
@@ -351,7 +346,7 @@
 
     def test_flow_usertype_info(self):
         a = self.RPythonAnnotator()
-        s = a.build_types(snippet.flow_usertype_info, [object])
+        s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit])
         #a.translator.view()
         assert isinstance(s, annmodel.SomeInstance)
         assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit)
@@ -363,13 +358,6 @@
         assert isinstance(s, annmodel.SomeInstance)
         assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit)
 
-    def test_flow_identity_info(self):
-        a = self.RPythonAnnotator()
-        s = a.build_types(snippet.flow_identity_info, [object, object])
-        a.simplify()
-        #a.translator.view()
-        assert s == a.bookkeeper.immutablevalue((None, None))
-
     def test_mergefunctions(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.mergefunctions, [int])
@@ -431,11 +419,11 @@
         # the annotator (it doesn't check that they operate property, though)
         for example, methname, s_example in [
             ('', 'join',    annmodel.SomeString()),
-            ([], 'append',  somelist()),
-            ([], 'extend',  somelist()),
-            ([], 'reverse', somelist()),
-            ([], 'insert',  somelist()),
-            ([], 'pop',     somelist()),
+            ([], 'append',  somelist(annmodel.s_Int)),
+            ([], 'extend',  somelist(annmodel.s_Int)),
+            ([], 'reverse', somelist(annmodel.s_Int)),
+            ([], 'insert',  somelist(annmodel.s_Int)),
+            ([], 'pop',     somelist(annmodel.s_Int)),
             ]:
             constmeth = getattr(example, methname)
             s_constmeth = iv(constmeth)
@@ -497,12 +485,12 @@
 
     def test_simple_slicing(self):
         a = self.RPythonAnnotator()
-        s = a.build_types(snippet.simple_slice, [list])
+        s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)])
         assert isinstance(s, annmodel.SomeList)
 
     def test_simple_iter_list(self):
         a = self.RPythonAnnotator()
-        s = a.build_types(snippet.simple_iter, [list])
+        s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)])
         assert isinstance(s, annmodel.SomeIterator)
 
     def test_simple_iter_next(self):
@@ -542,11 +530,6 @@
         assert isinstance(dictkey(s), annmodel.SomeInteger)
         assert isinstance(dictvalue(s), annmodel.SomeInteger)
 
-        a = self.RPythonAnnotator()
-        s = a.build_types(snippet.dict_update, [str])
-        assert not isinstance(dictkey(s), annmodel.SomeString)
-        assert not isinstance(dictvalue(s), annmodel.SomeString)
-
     def test_dict_update_2(self):
         a = self.RPythonAnnotator()
         def g(n):
@@ -568,7 +551,7 @@
     def test_dict_keys2(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.dict_keys2, [])
-        assert not isinstance(listitem(s), annmodel.SomeString)
+        assert type(listitem(s)) is annmodel.SomeString
 
     def test_dict_values(self):
         a = self.RPythonAnnotator()
@@ -578,7 +561,7 @@
     def test_dict_values2(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.dict_values2, [])
-        assert not isinstance(listitem(s), annmodel.SomeString)
+        assert type(listitem(s)) is annmodel.SomeString
 
     def test_dict_items(self):
         a = self.RPythonAnnotator()
@@ -643,25 +626,6 @@
         s = a.build_types(operation_always_raising, [int])
         assert s == a.bookkeeper.immutablevalue(24)
 
-    def test_bltin_code_frame_confusion(self):
-        a = self.RPythonAnnotator()
-        a.build_types(snippet.bltin_code_frame_confusion,[])
-        f_flowgraph = graphof(a, snippet.bltin_code_frame_f)
-        g_flowgraph = graphof(a, snippet.bltin_code_frame_g)
-        # annotator confused by original bltin code/frame setup, we just get SomeObject here
-        assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject
-        assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject
-
-    def test_bltin_code_frame_reorg(self):
-        a = self.RPythonAnnotator()
-        a.build_types(snippet.bltin_code_frame_reorg,[])
-        f_flowgraph = graphof(a, snippet.bltin_code_frame_f)
-        g_flowgraph = graphof(a, snippet.bltin_code_frame_g)
-        assert isinstance(a.binding(f_flowgraph.getreturnvar()),
-                            annmodel.SomeInteger)
-        assert isinstance(a.binding(g_flowgraph.getreturnvar()),
-                          annmodel.SomeString)
-
     def test_propagation_of_fresh_instances_through_attrs(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int])
@@ -748,14 +712,15 @@
         assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
     def test_type_is(self):
-        class C(object):
+        class B(object):
+            pass
+        class C(B):
             pass
         def f(x):
-            if type(x) is C:
-                return x
-            raise Exception
-        a = self.RPythonAnnotator()
-        s = a.build_types(f, [object])
+            assert type(x) is C
+            return x
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [B])
         assert s.classdef is a.bookkeeper.getuniqueclassdef(C)
 
     def test_ann_assert(self):
@@ -793,24 +758,30 @@
             return None
 
         a = self.RPythonAnnotator()
-        s = a.build_types(f, [list])
+        s = a.build_types(f, [somelist(annmodel.s_Int)])
         assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError)  # KeyError ignored because l is a list
 
     def test_freeze_protocol(self):
         class Stuff:
-            def __init__(self, flag):
+            def __init__(self):
                 self.called = False
-                self.flag = flag
             def _freeze_(self):
                 self.called = True
-                return self.flag
-        myobj = Stuff(True)
+                return True
+        myobj = Stuff()
         a = self.RPythonAnnotator()
         s = a.build_types(lambda: myobj, [])
         assert myobj.called
         assert isinstance(s, annmodel.SomePBC)
         assert s.const == myobj
-        myobj = Stuff(False)
+
+    def test_cleanup_protocol(self): 
+        class Stuff:
+            def __init__(self):
+                self.called = False
+            def _cleanup_(self):
+                self.called = True
+        myobj = Stuff()
         a = self.RPythonAnnotator()
         s = a.build_types(lambda: myobj, [])
         assert myobj.called
@@ -854,7 +825,7 @@
         def f(a,b):
             return bool(a) or bool(b)
         a = self.RPythonAnnotator()
-        s = a.build_types(f, [int,list])
+        s = a.build_types(f, [int, somelist(annmodel.s_Int)])
         assert s.knowntype == bool
 
     def test_float(self):
@@ -1299,22 +1270,6 @@
         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):
-            pass
-        def g(l):
-            assert type(l) is list
-            return l
-        def f():
-            l = [T()]
-            return g(l)
-        a = self.RPythonAnnotator()
-        s = a.build_types(f, [])
-        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):
             return a*x+x*b
@@ -1395,11 +1350,10 @@
             except KeyError:
                 raise
         a = self.RPythonAnnotator()
-        a.build_types(f, [dict])
+        a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)])
         fg = graphof(a, f)
         et, ev = fg.exceptblock.inputargs
-        t = annmodel.SomeObject()
-        t.knowntype = type
+        t = annmodel.SomeType()
         t.const = KeyError
         t.is_type_of = [ev]
         assert a.binding(et) == t
@@ -1412,11 +1366,10 @@
             except:
                 raise
         a = self.RPythonAnnotator()
-        a.build_types(f, [dict])
+        a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)])
         fg = graphof(a, f)
         et, ev = fg.exceptblock.inputargs
-        t = annmodel.SomeObject()
-        t.knowntype = type
+        t = annmodel.SomeType()
         t.is_type_of = [ev]
         t.const = KeyError    # IndexError ignored because 'dic' is a dict
         assert a.binding(et) == t
@@ -1448,11 +1401,10 @@
                 finally:
                     h()
         a = self.RPythonAnnotator()
-        a.build_types(f, [int, list])
+        a.build_types(f, [int, somelist(annmodel.s_Int)])
         fg = graphof(a, f)
         et, ev = fg.exceptblock.inputargs
-        t = annmodel.SomeObject()
-        t.knowntype = type
+        t = annmodel.SomeType()
         t.is_type_of = [ev]
         assert a.binding(et) == t
         assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
@@ -1474,24 +1426,11 @@
         a.build_types(f, [])
         fg = graphof(a, f)
         et, ev = fg.exceptblock.inputargs
-        t = annmodel.SomeObject()
-        t.knowntype = type
+        t = annmodel.SomeType()
         t.is_type_of = [ev]
         assert a.binding(et) == t
         assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
 
-    def test_sys_attrs(self):
-        def f():
-            return sys.argv[0]
-        a = self.RPythonAnnotator()
-        try:
-            oldvalue = sys.argv
-            sys.argv = []
-            s = a.build_types(f, [])
-        finally:
-            sys.argv = oldvalue
-        assert s is not None
-
     def test_pow(self):
         def f(n):
             n **= 2
@@ -1523,7 +1462,6 @@
         a = self.RPythonAnnotator()
         s = a.build_types(f, [int, str, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')])
         assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)])
-        assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject]
 
     def test_is_true_coalesce2(self):
         def f(a,b,a1,b1,c,d,e):
@@ -1532,9 +1470,12 @@
                 return d,c
             return e,c
         a = self.RPythonAnnotator()
-        s = a.build_types(f, [int, str, float, list,  a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')])
-        assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)])
-        assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject]
+        s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int),
+                              a.bookkeeper.immutablevalue(1.0),
+                              a.bookkeeper.immutablevalue('d'),
+                              a.bookkeeper.immutablevalue('e')])
+        assert s == annmodel.SomeTuple([annmodel.SomeChar(),
+                                        a.bookkeeper.immutablevalue(1.0)])
 
     def test_is_true_coalesce_sanity(self):
         def f(a):
@@ -1954,16 +1895,7 @@
             t = type(x)
             return issubclass(t, A)
 
-        def f():
-            x = g(1)
-            y = g(0)
-            return x or y
-        a = self.RPythonAnnotator()
-        s = a.build_types(f, [])
-        assert s.knowntype == bool
-        assert not s.is_constant()
-        a = self.RPythonAnnotator()
-        # sanity check
+        a = self.RPythonAnnotator()
         x = annmodel.SomeInteger()
         x.const = 1
         s = a.build_types(g, [x])
@@ -2383,8 +2315,7 @@
 
         a = self.RPythonAnnotator()
         s = a.build_types(f, [int])
-        assert s.__class__ == annmodel.SomeObject
-        assert s.knowntype == type
+        assert isinstance(s, annmodel.SomeType)
 
     def test_annotate_iter_empty_container(self):
         def f():
@@ -3075,7 +3006,6 @@
                 v = -maxint
             return intmask(v * 10)
         P = policy.AnnotatorPolicy()
-        P.allow_someobjects = False
         a = self.RPythonAnnotator(policy=P)
         s = a.build_types(fun, [bool])
         assert isinstance(s, annmodel.SomeInteger)
@@ -3866,6 +3796,24 @@
         s = a.build_types(fn, [annmodel.SomeChar()])
         assert s == annmodel.SomeChar()
 
+    def test_isinstance_double_const(self):
+        class X(object):
+            def _freeze_(self):
+                return True
+
+        x = X()
+        
+        def f(i):
+            if i:
+                x1 = x
+            else:
+                x1 = None
+            print "hello" # this is to force the merge of blocks
+            return isinstance(x1, X)
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeInteger()])
+        assert isinstance(s, annmodel.SomeBool)
 
 def g(n):
     return [0,1,2,n]
diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py
--- a/pypy/annotation/test/test_model.py
+++ b/pypy/annotation/test/test_model.py
@@ -2,20 +2,20 @@
 import autopath
 import py
 from pypy.annotation.model import *
-from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
+from pypy.annotation.listdef import ListDef
 from pypy.rpython.ootypesystem.ootype import ROOT
 
 
 listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()]))
 listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()]))
 
-s1 = SomeObject()
+s1 = SomeType()
 s2 = SomeInteger(nonneg=True)
 s3 = SomeInteger(nonneg=False)
 s4 = SomeList(listdef1)
 s5 = SomeList(listdef2)
 s6 = SomeImpossibleValue()
-slist = [s1,s2,s3,s4,s6]  # not s5 -- unionof(s4,s5) modifies s4 and s5
+slist = [s1, s2, s3, s4, s6]  # not s5 -- unionof(s4,s5) modifies s4 and s5
 
 
 class C(object):
@@ -42,7 +42,7 @@
 
 def test_equality():
     assert s1 != s2 != s3 != s4 != s5 != s6
-    assert s1 == SomeObject()
+    assert s1 == SomeType()
     assert s2 == SomeInteger(nonneg=True)
     assert s3 == SomeInteger(nonneg=False)
     assert s4 == SomeList(listdef1)
@@ -51,19 +51,11 @@
 
 def test_contains():
     assert ([(s,t) for s in slist for t in slist if s.contains(t)] ==
-            [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6),
-                      (s2,s2),                   (s2,s6),
-                      (s3,s2), (s3,s3),          (s3,s6),
-                                        (s4,s4), (s4,s6),
-                                                 (s6,s6)])
-
-def test_union():
-    assert ([unionof(s,t) for s in slist for t in slist] ==
-            [s1, s1, s1, s1, s1,
-             s1, s2, s3, s1, s2,
-             s1, s3, s3, s1, s3,
-             s1, s1, s1, s4, s4,
-             s1, s2, s3, s4, s6])
+            [(s1, s1),                               (s1, s6),
+                       (s2, s2),                     (s2, s6),
+                       (s3, s2), (s3, s3),           (s3, s6),
+                                           (s4, s4), (s4, s6),
+                                                     (s6, s6)])
 
 def test_commonbase_simple():
     class A0: 
@@ -100,9 +92,10 @@
 def test_list_contains():
     listdef1 = ListDef(None, SomeInteger(nonneg=True))
     s1 = SomeList(listdef1)
-    s2 = SomeList(MOST_GENERAL_LISTDEF)
+    listdef2 = ListDef(None, SomeInteger(nonneg=False))
+    s2 = SomeList(listdef2)
     assert s1 != s2
-    assert s2.contains(s1)
+    assert not s2.contains(s1)
     assert s1 != s2
     assert not s1.contains(s2)
     assert s1 != s2
diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py
--- a/pypy/annotation/unaryop.py
+++ b/pypy/annotation/unaryop.py
@@ -7,7 +7,7 @@
      SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \
      SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \
      SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \
-     SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \
+     SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \
      s_ImpossibleValue, s_Bool, s_None, \
      unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \
      SomeGenericCallable, SomeWeakRef, SomeUnicodeString
@@ -39,14 +39,7 @@
     def type(obj, *moreargs):
         if moreargs:
             raise Exception, 'type() called with more than one argument'
-        if obj.is_constant():
-            if isinstance(obj, SomeInstance):
-                r = SomePBC([obj.classdef.classdesc])
-            else:
-                r = immutablevalue(obj.knowntype)
-        else:
-            r = SomeObject()
-            r.knowntype = type
+        r = SomeType()
         bk = getbookkeeper()
         fn, block, i = bk.position_key
         annotator = bk.annotator
@@ -133,9 +126,6 @@
     def float(obj):
         return SomeFloat()
 
-    def long(obj):
-        return SomeObject()   # XXX
-
     def delattr(obj, s_attr):
         if obj.__class__ != SomeObject or obj.knowntype != object:
             getbookkeeper().warning(
@@ -154,18 +144,17 @@
     def getattr(obj, s_attr):
         # get a SomeBuiltin if the SomeObject has
         # a corresponding method to handle it
-        if s_attr.is_constant() and isinstance(s_attr.const, str):
-            attr = s_attr.const
-            s_method = obj.find_method(attr)
-            if s_method is not None:
-                return s_method
-            # if the SomeObject is itself a constant, allow reading its attrs
-            if obj.is_immutable_constant() and hasattr(obj.const, attr):
-                return immutablevalue(getattr(obj.const, attr))
-        else:
-            getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' %
-                                    (obj, s_attr))
-        return SomeObject()
+        if not s_attr.is_constant() or not isinstance(s_attr.const, str):
+            raise AnnotatorError("getattr(%r, %r) has non-constant argument"
+                                 % (obj, s_attr))
+        attr = s_attr.const
+        s_method = obj.find_method(attr)
+        if s_method is not None:
+            return s_method
+        # if the SomeObject is itself a constant, allow reading its attrs
+        if obj.is_immutable_constant() and hasattr(obj.const, attr):
+            return immutablevalue(getattr(obj.const, attr))
+        raise AnnotatorError("Cannot find attribute %r on %r" % (attr, obj))
     getattr.can_only_throw = []
 
     def bind_callables_under(obj, classdef, name):
diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py
--- a/pypy/bin/translatorshell.py
+++ b/pypy/bin/translatorshell.py
@@ -8,10 +8,10 @@
 
 Example:
 
-    t = Translation(func)
+    t = Translation(func, [int])       # pass the list of args types
     t.view()                           # control flow graph
 
-    t.annotate([int])                  # pass the list of args types
+    t.annotate()
     t.view()                           # graph + annotations under the mouse
 
     t.rtype()                          # use low level operations 
diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py
--- a/pypy/config/test/test_config.py
+++ b/pypy/config/test/test_config.py
@@ -111,8 +111,8 @@
         else:
             return 'foo'
 
-    t = Translation(f)
-    t.rtype([int])
+    t = Translation(f, [int])
+    t.rtype()
     
     block = t.context.graphs[0].startblock
     assert len(block.exits[0].target.operations) == 0
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -129,8 +129,6 @@
 
     # misc
     BoolOption("verbose", "Print extra information", default=False),
-    BoolOption("debug", "Record extra annotation information",
-               cmdline="-d --debug", default=True),
     BoolOption("insist", "Try hard to go on RTyping", default=False,
                cmdline="--insist"),
     StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"),
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -111,15 +111,7 @@
 def maketestobjspace(config=None):
     if config is None:
         config = make_config(option)
-    try:
-        space = make_objspace(config)
-    except OperationError, e:
-        check_keyboard_interrupt(e)
-        if option.verbose:
-            import traceback
-            traceback.print_exc()
-        py.test.fail("fatal: cannot initialize objspace: %r" %
-                         (config.objspace.name,))
+    space = make_objspace(config)
     space.startup() # Initialize all builtin modules
     space.setitem(space.builtin.w_dict, space.wrap('AssertionError'),
                   appsupport.build_pytest_assertion(space))
diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst
--- a/pypy/doc/discussion/improve-rpython.rst
+++ b/pypy/doc/discussion/improve-rpython.rst
@@ -9,7 +9,7 @@
   `import` statements::
 
     from pypy.interpreter.baseobjspace import Wrappable
-    from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped
+    from pypy.interpreter.gateway import ObjSpace, W_Root
     from pypy.interpreter.argument import Arguments
     from pypy.interpreter.typedef import TypeDef, GetSetProperty
     from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w
diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst
--- a/pypy/doc/getting-started-dev.rst
+++ b/pypy/doc/getting-started-dev.rst
@@ -27,7 +27,7 @@
 ``pypy/translator/test/snippet.py``, which is imported under the name
 ``snippet``.  For example::
 
-    >>> t = Translation(snippet.is_perfect_number)
+    >>> t = Translation(snippet.is_perfect_number, [int])
     >>> t.view()
         
 After that, the graph viewer pops up, that lets you interactively inspect the
@@ -40,7 +40,7 @@
 We have a type annotator that can completely infer types for functions like
 ``is_perfect_number`` (as well as for much larger examples)::
 
-    >>> t.annotate([int])
+    >>> t.annotate()
     >>> t.view()
 
 Move the mouse over variable names (in red) to see their inferred types.
@@ -74,8 +74,8 @@
 
     >>> def myfunc(a, b): return a+b
     ... 
-    >>> t = Translation(myfunc)
-    >>> t.annotate([int, int])
+    >>> t = Translation(myfunc, [int, int])
+    >>> t.annotate()
     >>> f = t.compile_cli() # or compile_jvm()
     >>> f(4, 5)
     9
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -38,7 +38,8 @@
 
 .. branch: numpypy-complex2
 Complex dtype support for numpy
-
+.. branch: kill-someobject
+major cleanups including killing some object support
 
 
 .. "uninteresting" branches that we should just ignore for the whatsnew:
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -730,8 +730,15 @@
         # done by a method call on w_two (and not on w_one, because of the
         # expected programming style where we say "if x is None" or
         # "if x is object").
+        assert w_two is not None
         return w_two.is_w(self, w_one)
 
+    def is_none(self, w_obj):
+        """ mostly for checking inputargs that have unwrap_spec and
+        can accept both w_None and None
+        """
+        return w_obj is None or self.is_w(w_obj, self.w_None)
+
     def id(self, w_obj):
         w_result = w_obj.immutable_unique_id(self)
         if w_result is None:
@@ -815,7 +822,7 @@
         interpreter class (a subclass of Wrappable).
         """
         assert RequiredClass is not None
-        if can_be_None and self.is_w(w_obj, self.w_None):
+        if can_be_None and self.is_none(w_obj):
             return None
         obj = self.interpclass_w(w_obj)
         if not isinstance(obj, RequiredClass):   # or obj is None
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -207,11 +207,11 @@
         code = space.interp_w(Code, w_code)
         if not space.is_true(space.isinstance(w_globals, space.w_dict)):
             raise OperationError(space.w_TypeError, space.wrap("expected dict"))
-        if not space.is_w(w_name, space.w_None):
+        if not space.is_none(w_name):
             name = space.str_w(w_name)
         else:
             name = None
-        if not space.is_w(w_argdefs, space.w_None):
+        if not space.is_none(w_argdefs):
             defs_w = space.fixedview(w_argdefs)
         else:
             defs_w = []
@@ -219,7 +219,7 @@
         from pypy.interpreter.pycode import PyCode
         if isinstance(code, PyCode):
             nfreevars = len(code.co_freevars)
-        if space.is_w(w_closure, space.w_None) and nfreevars == 0:
+        if space.is_none(w_closure) and nfreevars == 0:
             closure = None
         elif not space.is_w(space.type(w_closure), space.w_tuple):
             raise OperationError(space.w_TypeError, space.wrap("invalid closure"))
@@ -247,7 +247,7 @@
     # delicate
     _all = {'': None}
 
-    def _freeze_(self):
+    def _cleanup_(self):
         from pypy.interpreter.gateway import BuiltinCode
         if isinstance(self.code, BuiltinCode):
             # we have been seen by other means so rtyping should not choke
@@ -346,7 +346,7 @@
     def fget_func_defaults(self, space):
         values_w = self.defs_w
         # the `None in values_w` check here is to ensure that interp-level
-        # functions with a default of NoneNotWrapped do not get their defaults
+        # functions with a default of None do not get their defaults
         # exposed at applevel
         if not values_w or None in values_w:
             return space.w_None
@@ -459,6 +459,7 @@
     def fdel_func_annotations(self, space):
         self.w_ann = None
 
+
 def descr_function_get(space, w_function, w_obj, w_cls=None):
     """functionobject.__get__(obj[, type]) -> method"""
     # this is not defined as a method on Function because it's generally
@@ -476,7 +477,7 @@
     def __init__(self, space, w_function, w_instance):
         self.space = space
         self.w_function = w_function
-        self.w_instance = w_instance
+        self.w_instance = w_instance   # or None
 
     def descr_method__new__(space, w_subtype, w_function, w_instance):
         if space.is_w(w_instance, space.w_None):
@@ -577,7 +578,7 @@
         self.w_function = w_function
 
     def descr_classmethod_get(self, space, w_obj, w_klass=None):
-        if space.is_w(w_klass, space.w_None):
+        if space.is_none(w_klass):
             w_klass = space.type(w_obj)
         return space.wrap(Method(space, self.w_function, w_klass))
 
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -7,31 +7,29 @@
 
 """
 
-import types, sys, os
-from pypy.tool.compat import md5
+import sys
+import os
+import types
 
-NoneNotWrapped = object()
+import py
 
-from pypy.tool.sourcetools import func_with_new_name
+from pypy.interpreter.eval import Code
+from pypy.interpreter.argument import Arguments, Signature
+from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable,
+    SpaceCache, DescrMismatch)
 from pypy.interpreter.error import OperationError
-from pypy.interpreter import eval
-from pypy.interpreter.function import Function, Method, ClassMethod
-from pypy.interpreter.function import FunctionWithFixedCode
-from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable
-from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch
-from pypy.interpreter.argument import Arguments, Signature
-from pypy.tool.sourcetools import NiceCompile, compile2
-from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint
+from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode
 from pypy.rlib import rstackovf
 from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint
+from pypy.tool.sourcetools import func_with_new_name, compile2
+
 
 # internal non-translatable parts:
-import py
-
 class SignatureBuilder(object):
     "NOT_RPYTHON"
     def __init__(self, func=None, argnames=None, varargname=None,
-                 kwargname=None, name = None):
+                 kwargname=None, name=None):
         self.func = func
         if func is not None:
             self.name = func.__name__
@@ -60,10 +58,12 @@
         if isinstance(el, str):
             getattr(self, "visit_%s" % (el,))(el, *args)
         elif isinstance(el, tuple):
-            if el[0] == 'self':
+            if el[0] == 'INTERNAL:self':
                 self.visit_self(el[1], *args)
             else:
-                self.visit_function(el, *args)
+                assert False, "not supported any more, use WrappedDefault"
+        elif isinstance(el, WrappedDefault):
+            self.visit__W_Root(W_Root, *args)
         elif isinstance(el, type):
             for typ in self.bases_order:
                 if issubclass(el, typ):
@@ -81,8 +81,8 @@
         for el in unwrap_spec:
             dispatch(el, *extra)
 
+
 class UnwrapSpecEmit(UnwrapSpecRecipe):
-
     def __init__(self):
         self.n = 0
         self.miniglobals = {}
@@ -97,10 +97,11 @@
         self.miniglobals[name] = obj
         return name
 
+
 #________________________________________________________________
 
+
 class UnwrapSpec_Check(UnwrapSpecRecipe):
-
     # checks for checking interp2app func argument names wrt unwrap_spec
     # and synthetizing an app-level signature
 
@@ -108,9 +109,6 @@
         self.func = original_sig.func
         self.orig_arg = iter(original_sig.argnames).next
 
-    def visit_function(self, (func, cls), app_sig):
-        self.dispatch(cls, app_sig)
-
     def visit_self(self, cls, app_sig):
         self.visit__Wrappable(cls, app_sig)
 
@@ -168,8 +166,8 @@
         app_sig.append(argname[2:])
 
     def visit__Arguments(self, el, app_sig):
-        argname = self.orig_arg()
-        assert app_sig.varargname is None,(
+        self.orig_arg()
+        assert app_sig.varargname is None, (
             "built-in function %r has conflicting rest args specs" % self.func)
         app_sig.varargname = 'args'
         app_sig.kwargname = 'keywords'
@@ -179,7 +177,7 @@
         assert argname.endswith('_w'), (
             "rest arguments arg %s of built-in function %r should end in '_w'" %
             (argname, self.func))
-        assert app_sig.varargname is None,(
+        assert app_sig.varargname is None, (
             "built-in function %r has conflicting rest args specs" % self.func)
         app_sig.varargname = argname[:-2]
 
@@ -188,7 +186,7 @@
         assert argname.startswith('w_'), (
             "rest arguments arg %s of built-in function %r should start 'w_'" %
             (argname, self.func))
-        assert app_sig.varargname is None,(
+        assert app_sig.varargname is None, (
             "built-in function %r has conflicting rest args specs" % self.func)
         app_sig.varargname = argname[2:]
 
@@ -208,10 +206,6 @@
     def scopenext(self):
         return "scope_w[%d]" % self.succ()
 
-    def visit_function(self, (func, cls)):
-        self.run_args.append("%s(%s)" % (self.use(func),
-                                         self.scopenext()))
-
     def visit_self(self, typ):
         self.run_args.append("space.descr_self_interp_w(%s, %s)" %
                              (self.use(typ), self.scopenext()))
@@ -284,6 +278,8 @@
                 if isinstance(el, tuple):
                     parts.append(''.join([getattr(subel, '__name__', subel)
                                           for subel in el]))
+                elif isinstance(el, WrappedDefault):
+                    parts.append('W_Root')
                 else:
                     parts.append(getattr(el, '__name__', el))
             label = '_'.join(parts)
@@ -320,15 +316,16 @@
 
     def _run(self, space, scope_w):
         """Subclasses with behavior specific for an unwrap spec are generated"""
-        raise TypeError, "abstract"
+        raise TypeError("abstract")
 
 #________________________________________________________________
 
+
 class FastFuncNotSupported(Exception):
     pass
 
+
 class UnwrapSpec_FastFunc_Unwrap(UnwrapSpecEmit):
-
     def __init__(self):
         UnwrapSpecEmit.__init__(self)
         self.args = []
@@ -346,9 +343,6 @@
         self.args.append(arg)
         return arg
 
-    def visit_function(self, (func, cls)):
-        raise FastFuncNotSupported
-
     def visit_self(self, typ):
         self.unwrap.append("space.descr_self_interp_w(%s, %s)" %
                            (self.use(typ), self.nextarg()))
@@ -439,6 +433,7 @@
         return narg, fastfunc
     make_fastfunc = staticmethod(make_fastfunc)
 
+
 def int_unwrapping_space_method(typ):
     assert typ in (int, str, float, unicode, r_longlong, r_uint, r_ulonglong, bool)
     if typ is r_int is r_longlong:
@@ -455,6 +450,7 @@
     - positional arguments must be as many as the function parameters
     - keywords arguments allow to change only some parameter specs
     """
+    assert spec or kwargs
     def decorator(func):
         if kwargs:
             if spec:
@@ -466,6 +462,14 @@
         return func
     return decorator
 
+class WrappedDefault(object):
+    """ Can be used inside unwrap_spec as WrappedDefault(3) which means
+    it'll be treated as W_Root, but fed with default which will be a wrapped
+    argument to constructor.
+    """
+    def __init__(self, default_value):
+        self.default_value = default_value
+
 def build_unwrap_spec(func, argnames, self_type=None):
     """build the list of parameter unwrap spec for the function.
     """
@@ -505,7 +509,8 @@
 
     return unwrap_spec
 
-class BuiltinCode(eval.Code):
+
+class BuiltinCode(Code):
     "The code object implementing a built-in (interpreter-level) hook."
     _immutable_ = True
     hidden_applevel = True
@@ -515,14 +520,11 @@
     # When a BuiltinCode is stored in a Function object,
     # you get the functionality of CPython's built-in function type.
 
-    NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec']
-
-    def __init__(self, func, unwrap_spec = None, self_type = None,
-                 descrmismatch=None):


More information about the pypy-commit mailing list