[pypy-commit] pypy continulet-jit-3: hg merge default

arigo noreply at buildbot.pypy.org
Sat Oct 13 11:25:09 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: continulet-jit-3
Changeset: r58093:7465a76a9d28
Date: 2012-10-13 11:01 +0200
http://bitbucket.org/pypy/pypy/changeset/7465a76a9d28/

Log:	hg merge default

diff too long, truncating to 2000 out of 49446 lines

diff --git a/lib-python/2.7/test/test_csv.py b/lib-python/2.7/test/test_csv.py
--- a/lib-python/2.7/test/test_csv.py
+++ b/lib-python/2.7/test/test_csv.py
@@ -20,7 +20,8 @@
     """
     def _test_arg_valid(self, ctor, arg):
         self.assertRaises(TypeError, ctor)
-        self.assertRaises(TypeError, ctor, None)
+        # PyPy gets an AttributeError instead of a TypeError
+        self.assertRaises((TypeError, AttributeError), ctor, None)
         self.assertRaises(TypeError, ctor, arg, bad_attr = 0)
         self.assertRaises(TypeError, ctor, arg, delimiter = 0)
         self.assertRaises(TypeError, ctor, arg, delimiter = 'XX')
@@ -59,7 +60,8 @@
         self.assertRaises((TypeError, AttributeError), setattr, obj.dialect,
                           'delimiter', ':')
         self.assertRaises(AttributeError, delattr, obj.dialect, 'quoting')
-        self.assertRaises(AttributeError, setattr, obj.dialect,
+        # PyPy gets a TypeError instead of an AttributeError
+        self.assertRaises((AttributeError, TypeError), setattr, obj.dialect,
                           'quoting', None)
 
     def test_reader_attrs(self):
@@ -133,7 +135,8 @@
             os.unlink(name)
 
     def test_write_arg_valid(self):
-        self.assertRaises(csv.Error, self._write_test, None, '')
+        # PyPy gets a TypeError instead of a csv.Error for "not a sequence"
+        self.assertRaises((csv.Error, TypeError), self._write_test, None, '')
         self._write_test((), '')
         self._write_test([None], '""')
         self.assertRaises(csv.Error, self._write_test,
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -183,7 +183,7 @@
     RegrTest('test_cpickle.py', core=True),
     RegrTest('test_cprofile.py'), 
     RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32),
-    RegrTest('test_csv.py'),
+    RegrTest('test_csv.py', usemodules='_csv'),
 
     RegrTest('test_curses.py', skip="unsupported extension module"),
     RegrTest('test_datetime.py'),
diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py
--- a/lib_pypy/_csv.py
+++ b/lib_pypy/_csv.py
@@ -363,9 +363,7 @@
                             (self.dialect.delimiter, self.dialect.quotechar))
 
         elif self.state == self.EAT_CRNL:
-            if c in '\r\n':
-                pass
-            else:
+            if c not in '\r\n':
                 raise Error("new-line character seen in unquoted field - "
                             "do you need to open the file "
                             "in universal-newline mode?")
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -81,7 +81,9 @@
         addr = self._buffer[0]
         if addr == 0:
             raise ValueError("NULL pointer access")
-        return self._type_.from_address(addr)
+        instance = self._type_.from_address(addr)
+        instance.__dict__['_base'] = self
+        return instance
 
     def setcontents(self, value):
         if not isinstance(value, self._type_):
diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py
--- a/lib_pypy/dbm.py
+++ b/lib_pypy/dbm.py
@@ -126,8 +126,11 @@
     libpath = ctypes.util.find_library('db')
     if not libpath:
         # XXX this is hopeless...
-        libpath = ctypes.util.find_library('db-4.5')
-        if not libpath:
+        for c in '56789':
+            libpath = ctypes.util.find_library('db-4.%s' % c)
+            if libpath:
+                break
+        else:
             raise ImportError("Cannot find dbm library")
     lib = CDLL(libpath) # Linux
     _platform = 'bdb'
diff --git a/py/_io/capture.py b/py/_io/capture.py
--- a/py/_io/capture.py
+++ b/py/_io/capture.py
@@ -176,7 +176,7 @@
 
 
 class StdCaptureFD(Capture):
-    """ This class allows to capture writes to FD1 and FD2
+    """ This class allows capturing writes to FD1 and FD2
         and may connect a NULL file to FD0 (and prevent
         reads from sys.stdin).  If any of the 0,1,2 file descriptors
         is invalid it will not be captured.
@@ -267,8 +267,8 @@
         return l
 
 class StdCapture(Capture):
-    """ This class allows to capture writes to sys.stdout|stderr "in-memory"
-        and will raise errors on tries to read from sys.stdin. It only
+    """ This class allows capturing writes to sys.stdout|stderr "in-memory"
+        and will raise errors on read attempts from sys.stdin. It only
         modifies sys.stdout|stderr|stdin attributes and does not
         touch underlying File Descriptors (use StdCaptureFD for that).
     """
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):
@@ -564,14 +550,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)):
 
@@ -723,8 +725,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()
@@ -764,7 +765,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)
@@ -778,7 +779,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)):
@@ -806,7 +807,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)
@@ -3859,6 +3789,32 @@
             a = self.RPythonAnnotator()
             py.test.raises(Exception, a.build_types, fn, [])
 
+    def test_lower_char(self):
+        def fn(c):
+            return c.lower()
+        a = self.RPythonAnnotator()
+        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):
@@ -586,6 +575,12 @@
     def method_isupper(chr):
         return s_Bool
 
+    def method_lower(chr):
+        return chr
+
+    def method_upper(chr):
+        return chr
+
 class __extend__(SomeIterator):
 
     def iter(itr):
diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py
--- a/pypy/bin/reportstaticdata.py
+++ b/pypy/bin/reportstaticdata.py
@@ -2,9 +2,9 @@
 
 """
 Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME
-Print a report for the static data informations contained in FILENAME
+Print a report for the static data information contained in FILENAME
 
-The static data informations are saved in the file staticdata.info when
+The static data information is saved in the file staticdata.info when
 passing --dump_static_data_info to translate.py.
 
 Options:
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/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -34,7 +34,7 @@
      "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
      "_bisect", "binascii", "_multiprocessing", '_warnings',
      "_collections", "_multibytecodec", "micronumpy", "_ffi",
-     "_continuation", "_cffi_backend"]
+     "_continuation", "_cffi_backend", "_csv"]
 ))
 
 translation_modules = default_modules.copy()
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
@@ -101,15 +101,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/architecture.rst b/pypy/doc/architecture.rst
--- a/pypy/doc/architecture.rst
+++ b/pypy/doc/architecture.rst
@@ -238,7 +238,7 @@
    interpreter`_.
 
 .. _`documentation index`: index.html#project-documentation
-.. _`getting-started`: getting-started.html
+.. _`getting-started`: getting-started-dev.html
 .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf
 .. _`the translation document`: translation.html
 .. _`RPython toolchain`: translation.html
diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst
--- a/pypy/doc/arm.rst
+++ b/pypy/doc/arm.rst
@@ -23,7 +23,7 @@
 
 The tools required to cross translate from a Linux based host to an ARM based Linux target are:
 
-- A checkout of PyPy's arm-backend-2 branch.
+- A checkout of PyPy (default branch).
 - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work.
 - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package).
 - A 32-bit PyPy or Python.
@@ -147,4 +147,4 @@
       return 0
 
   def target(*args):
-      return main, None
\ No newline at end of file
+      return main, None
diff --git a/pypy/doc/config/objspace.usemodules._csv.txt b/pypy/doc/config/objspace.usemodules._csv.txt
new file mode 100644
--- /dev/null
+++ b/pypy/doc/config/objspace.usemodules._csv.txt
@@ -0,0 +1,2 @@
+Implementation in RPython for the core of the 'csv' module
+
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
@@ -41,9 +41,6 @@
   llexternal functions. For a typical usage, see
   `pypy.rlib.rsocket.RSocket.getsockopt_int`.
 
-- Support context managers and the `with` statement. This could be a workaround
-  before the previous point is available.
-
 Extensible type system for llexternal
 -------------------------------------
 
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/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst
--- a/pypy/doc/jit/pyjitpl5.rst
+++ b/pypy/doc/jit/pyjitpl5.rst
@@ -149,7 +149,7 @@
 
 A *virtual* value is an array, struct, or RPython level instance that is created
 during the loop and does not escape from it via calls or longevity past the
-loop.  Since it is only used by the JIT, it be "optimized out"; the value
+loop.  Since it is only used by the JIT, it can be "optimized out"; the value
 doesn't have to be allocated at all and its fields can be stored as first class
 values instead of deferencing them in memory.  Virtuals allow temporary objects
 in the interpreter to be unwrapped.  For example, a W_IntObject in the PyPy can
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -21,7 +21,7 @@
 -------------------------
 
 PyPy's implementation of the Python ``long`` type is slower than CPython's.
-Find out why and optimize them.
+Find out why and optimize them.  **UPDATE:** this was done (thanks stian).
 
 Make bytearray type fast
 ------------------------
@@ -103,13 +103,35 @@
 
 * A concurrent garbage collector (a lot of work)
 
-STM, a.k.a. "remove the GIL"
-----------------------------
+STM (Software Transactional Memory)
+-----------------------------------
 
-Removing the GIL --- or more precisely, a GIL-less thread-less solution ---
-is `now work in progress.`__  Contributions welcome.
+This is work in progress.  Besides the main development path, whose goal is
+to make a (relatively fast) version of pypy which includes STM, there are
+independent topics that can already be experimented with on the existing,
+JIT-less pypy-stm version:
+  
+* What kind of conflicts do we get in real use cases?  And, sometimes,
+  which data structures would be more appropriate?  For example, a dict
+  implemented as a hash table will suffer "stm collisions" in all threads
+  whenever one thread writes anything to it; but there could be other
+  implementations.  Maybe alternate strategies can be implemented at the
+  level of the Python interpreter (see list/dict strategies,
+  ``pypy/objspace/std/{list,dict}object.py``).
 
-.. __: http://pypy.org/tmdonate.html
+* More generally, there is the idea that we would need some kind of
+  "debugger"-like tool to "debug" things that are not bugs, but stm
+  conflicts.  How would this tool look like to the end Python
+  programmers?  Like a profiler?  Or like a debugger with breakpoints
+  on aborted transactions?  It would probably be all app-level, with
+  a few hooks e.g. for transaction conflicts.
+
+* Find good ways to have libraries using internally threads and atomics,
+  but not exposing threads to the user.  Right now there is a rough draft
+  in ``lib_pypy/transaction.py``, but much better is possible.  For example
+  we could probably have an iterator-like concept that allows each loop
+  iteration to run in parallel.
+
 
 Introduce new benchmarks
 ------------------------
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
@@ -18,6 +18,9 @@
 .. branch: numpypy_count_nonzero
 .. branch: numpy-refactor
 Remove numpy lazy evaluation and simplify everything
+.. branch: numpy-reintroduce-jit-drivers
+.. branch: numpy-fancy-indexing
+Support for array[array-of-ints] in numpy
 .. branch: even-more-jit-hooks
 Implement better JIT hooks
 .. branch: virtual-arguments
@@ -33,6 +36,11 @@
 .. branch: stdlib-2.7.3
 The stdlib was updated to version 2.7.3
 
+.. 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:
 .. branch: slightly-shorter-c
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -65,24 +65,44 @@
         self.marked = False
         self.have_return = False
 
-    def _post_order(self, blocks):
-        if self.marked:
-            return
-        self.marked = True
-        if self.next_block is not None:
-            self.next_block._post_order(blocks)
-        for instr in self.instructions:
-            if instr.has_jump:
-                instr.jump[0]._post_order(blocks)
-        blocks.append(self)
-        self.marked = True
+    def _post_order_see(self, stack, nextblock):
+        if nextblock.marked == 0:
+            nextblock.marked = 1
+            stack.append(nextblock)
 
     def post_order(self):
-        """Return this block and its children in post order."""
-        blocks = []
-        self._post_order(blocks)
-        blocks.reverse()
-        return blocks
+        """Return this block and its children in post order.
+        This means that the graph of blocks is first cleaned up to
+        ignore back-edges, thus turning it into a DAG.  Then the DAG
+        is linearized.  For example:
+
+                   A --> B -\           =>     [A, D, B, C]


More information about the pypy-commit mailing list