[pypy-commit] pypy pytest-update: merge default

RonnyPfannschmidt noreply at buildbot.pypy.org
Fri Feb 22 13:34:15 CET 2013


Author: Ronny Pfannschmidt <Ronny.Pfannschmidt at gmx.de>
Branch: pytest-update
Changeset: r61600:d79c78a22eec
Date: 2013-02-22 13:33 +0100
http://bitbucket.org/pypy/pypy/changeset/d79c78a22eec/

Log:	merge default

diff too long, truncating to 2000 out of 6880 lines

diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py
--- a/lib-python/2.7/test/test_generators.py
+++ b/lib-python/2.7/test/test_generators.py
@@ -1501,9 +1501,7 @@
 """
 
 coroutine_tests = """\
-A helper function to call gc.collect() without printing
->>> import gc
->>> def gc_collect(): gc.collect()
+>>> from test.test_support import gc_collect
 
 Sending a value into a started generator:
 
@@ -1823,8 +1821,7 @@
 references. We add it to the standard suite so the routine refleak-tests
 would trigger if it starts being uncleanable again.
 
->>> import gc
->>> def gc_collect(): gc.collect()
+>>> from test.test_support import gc_collect
 
 >>> import itertools
 >>> def leak():
diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py
--- a/lib-python/2.7/urllib.py
+++ b/lib-python/2.7/urllib.py
@@ -1205,15 +1205,17 @@
     # fastpath
     if len(res) == 1:
         return s
-    s = res[0]
-    for item in res[1:]:
+    res_list = [res[0]]
+    for j in xrange(1, len(res)):
+        item = res[j]
         try:
-            s += _hextochr[item[:2]] + item[2:]
+            x = _hextochr[item[:2]] + item[2:]
         except KeyError:
-            s += '%' + item
+            x = '%' + item
         except UnicodeDecodeError:
-            s += unichr(int(item[:2], 16)) + item[2:]
-    return s
+            x = unichr(int(item[:2], 16)) + item[2:]
+        res_list.append(x)
+    return ''.join(res_list)
 
 def unquote_plus(s):
     """unquote('%7e/abc+def') -> '~/abc def'"""
diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py
--- a/lib-python/2.7/urlparse.py
+++ b/lib-python/2.7/urlparse.py
@@ -321,15 +321,17 @@
     # fastpath
     if len(res) == 1:
         return s
-    s = res[0]
-    for item in res[1:]:
+    res_list = [res[0]]
+    for j in xrange(1, len(res)):
+        item = res[j]
         try:
-            s += _hextochr[item[:2]] + item[2:]
+            x = _hextochr[item[:2]] + item[2:]
         except KeyError:
-            s += '%' + item
+            x = '%' + item
         except UnicodeDecodeError:
-            s += unichr(int(item[:2], 16)) + item[2:]
-    return s
+            x = unichr(int(item[:2], 16)) + item[2:]
+        res_list.append(x)
+    return ''.join(res_list)
 
 def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
     """Parse a query given as a string argument.
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -272,7 +272,7 @@
     RegrTest('test_inspect.py'),
     RegrTest('test_int.py', core=True),
     RegrTest('test_int_literal.py', core=True),
-    RegrTest('test_io.py'),
+    RegrTest('test_io.py', usemodules='array binascii'),
     RegrTest('test_ioctl.py'),
     RegrTest('test_isinstance.py', core=True),
     RegrTest('test_iter.py', core=True),
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -271,6 +271,8 @@
     raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))
 
 def _check_int_field(value):
+    if isinstance(value, int):
+        return value
     if not isinstance(value, float):
         try:
             value = value.__int__()
@@ -279,7 +281,7 @@
         else:
             if isinstance(value, (int, long)):
                 return value
-    raise TypeError('integer argument expected')
+    raise TypeError('an integer is required')
 
 def _check_date_fields(year, month, day):
     year = _check_int_field(year)
@@ -457,6 +459,8 @@
     felt like it.
     """
 
+    __slots__ = '_days', '_seconds', '_microseconds'
+
     def __new__(cls, days=0, seconds=0, microseconds=0,
                 # XXX The following should only be used as keyword args:
                 milliseconds=0, minutes=0, hours=0, weeks=0):
@@ -770,6 +774,8 @@
     year, month, day
     """
 
+    __slots__ = '_year', '_month', '_day'
+
     def __new__(cls, year, month=None, day=None):
         """Constructor.
 
@@ -777,7 +783,7 @@
 
         year, month, day (required, base 1)
         """
-        if isinstance(year, str):
+        if isinstance(year, str) and len(year) == 4:
             # Pickle support
             self = object.__new__(cls)
             self.__setstate(year)
@@ -1063,6 +1069,8 @@
     Subclasses must override the name(), utcoffset() and dst() methods.
     """
 
+    __slots__ = ()
+
     def tzname(self, dt):
         "datetime -> string name of time zone."
         raise NotImplementedError("tzinfo subclass must override tzname()")
@@ -1155,6 +1163,8 @@
     hour, minute, second, microsecond, tzinfo
     """
 
+    __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo'
+
     def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None):
         """Constructor.
 
@@ -1457,9 +1467,11 @@
     instance of a tzinfo subclass. The remaining arguments may be ints or longs.
     """
 
+    __slots__ = date.__slots__ + time.__slots__
+
     def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
                 microsecond=0, tzinfo=None):
-        if isinstance(year, str):
+        if isinstance(year, str) and len(year) == 10:
             # Pickle support
             self = date.__new__(cls, year[:4])
             self.__setstate(year, month)
diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt
--- a/pypy/doc/_ref.txt
+++ b/pypy/doc/_ref.txt
@@ -1,24 +1,19 @@
 .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py
-.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/
+.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/
 .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/
 .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py
 .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/
 .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py
 .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/
 .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py
-.. _`pypy/annotation`:
-.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/
-.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py
-.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py
-.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py
 .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/
-.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py
+.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py
 .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/
 .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py
-.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py
 .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/
 .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/
 .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/
+.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/
 .. _`pypy/interpreter`:
 .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/
 .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py
@@ -54,11 +49,8 @@
 .. _`pypy/module`:
 .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/
 .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py
-.. _`pypy/objspace`:
 .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/
-.. _`pypy/objspace/flow`:
 .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/
-.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py
 .. _`pypy/objspace/std`:
 .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/
 .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py
@@ -70,49 +62,55 @@
 .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py
 .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py
 .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py
-.. _`pypy/rlib`:
-.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/
-.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py
-.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py
-.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py
-.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/
-.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py
-.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py
-.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py
-.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py
-.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py
-.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py
-.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/
-.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py
-.. _`pypy/rpython`:
-.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/
-.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/
-.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py
-.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/
-.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py
-.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py
-.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py
-.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py
-.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py
-.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py
-.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/
-.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py
-.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py
-.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py
-.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py
-.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py
-.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py
 .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/
 .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/
 .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/
-.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py
-.. _`pypy/translator`:
-.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/
-.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/
-.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/
-.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/
-.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h
-.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/
-.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/
-.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/
-.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/
+.. _`rpython/annotator`:
+.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/
+.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py
+.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py
+.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py
+.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py
+.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/
+.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py
+.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/
+.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py
+.. _`rpython/rlib`:
+.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/
+.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py
+.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py
+.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py
+.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/
+.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py
+.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py
+.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py
+.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py
+.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py
+.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py
+.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/
+.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py
+.. _`rpython/rtyper`:
+.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/
+.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/
+.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py
+.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/
+.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py
+.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py
+.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py
+.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py
+.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/
+.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py
+.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py
+.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py
+.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py
+.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py
+.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py
+.. _`rpython/translator`:
+.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/
+.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/
+.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/
+.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/
+.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h
+.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/
+.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/
+.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -303,7 +303,7 @@
 
   dicts with a unique key type only, provided it is hashable. Custom
   hash functions and custom equality will not be honored.
-  Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions.
+  Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions.
 
 
 **list comprehensions**
@@ -328,7 +328,7 @@
 **builtin functions**
 
   A number of builtin functions can be used.  The precise set can be
-  found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``).
+  found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``).
   Some builtin functions may be limited in what they support, though.
 
   ``int, float, str, ord, chr``... are available as simple conversion
@@ -365,7 +365,7 @@
 We use normal integers for signed arithmetic.  It means that before
 translation we get longs in case of overflow, and after translation we get a
 silent wrap-around.  Whenever we need more control, we use the following
-helpers (which live the `pypy/rlib/rarithmetic.py`_):
+helpers (which live in `rpython/rlib/rarithmetic.py`_):
 
 **ovfcheck()**
 
diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst
--- a/pypy/doc/configuration.rst
+++ b/pypy/doc/configuration.rst
@@ -188,7 +188,7 @@
 toolchain`_ 
 toolchain, have two separate sets of options. The translation toolchain options
 can be found on the ``config`` attribute of all ``TranslationContext``
-instances and are described in `pypy/config/translationoption.py`_. The interpreter options
+instances and are described in `rpython/config/translationoption.py`_. The interpreter options
 are attached to the object space, also under the name ``config`` and are
 described in `pypy/config/pypyoption.py`_.
 
diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst
--- a/pypy/doc/ctypes-implementation.rst
+++ b/pypy/doc/ctypes-implementation.rst
@@ -38,7 +38,7 @@
 in dynamic libraries through libffi. Freeing objects in most cases and making
 sure that objects referring to each other are kept alive is responsibility of the higher levels.
 
-This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``.
+This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``.
 
 We tried to keep this module as small as possible. It is conceivable
 that other implementations (e.g. Jython) could use our ctypes
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
@@ -39,7 +39,7 @@
 
 - Allocate variables on the stack, and pass their address ("by reference") to
   llexternal functions. For a typical usage, see
-  `pypy.rlib.rsocket.RSocket.getsockopt_int`.
+  `rpython.rlib.rsocket.RSocket.getsockopt_int`.
 
 Extensible type system for llexternal
 -------------------------------------
diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst
--- a/pypy/doc/garbage_collection.rst
+++ b/pypy/doc/garbage_collection.rst
@@ -42,7 +42,7 @@
 Two arenas of equal size, with only one arena in use and getting filled
 with new objects.  When the arena is full, the live objects are copied
 into the other arena using Cheney's algorithm.  The old arena is then
-cleared.  See `pypy/rpython/memory/gc/semispace.py`_.
+cleared.  See `rpython/rtyper/memory/gc/semispace.py`_.
 
 On Unix the clearing is done by reading ``/dev/zero`` into the arena,
 which is extremely memory efficient at least on Linux: it lets the
@@ -55,7 +55,7 @@
 Generational GC
 ---------------
 
-This is a two-generations GC.  See `pypy/rpython/memory/gc/generation.py`_.
+This is a two-generations GC.  See `rpython/rtyper/memory/gc/generation.py`_.
 
 It is implemented as a subclass of the Semispace copying collector.  It
 adds a nursery, which is a chunk of the current semispace.  Its size is
@@ -86,7 +86,7 @@
 Each generation is collected much less often than the previous one.  The
 division of the generations is slightly more complicated than just
 nursery / semispace / external; see the diagram at the start of the
-source code, in `pypy/rpython/memory/gc/hybrid.py`_.
+source code, in `rpython/rtyper/memory/gc/hybrid.py`_.
 
 Mark & Compact GC
 -----------------
@@ -161,7 +161,7 @@
   to the old stage. The dying case 2 objects are immediately freed.
 
 - The old stage is an area of memory containing old (small) objects.  It
-  is handled by `pypy/rpython/memory/gc/minimarkpage.py`_.  It is organized
+  is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_.  It is organized
   as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB.
   Each page can either be free, or contain small objects of all the same
   size.  Furthermore at any point in time each object location can be
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
@@ -58,8 +58,7 @@
 only use low level types that are available in C (e.g. int). The compiled
 version is now in a ``.so`` library. You can run it say using ctypes:
 
-   >>> from ctypes import CDLL
-   >>> f = CDLL(lib)
+   >>> f = get_c_function(lib, snippet.is_perfect_number)
    >>> f(5)
    0
    >>> f(6)
@@ -173,23 +172,23 @@
    ``xxxobject.py`` contain respectively the definition of the type and its
    (default) implementation.
 
-*  `pypy/translator`_ contains the code analysis and generation stuff.
+*  `rpython/translator`_ contains the code analysis and generation stuff.
    Start reading from translator.py, from which it should be easy to follow
    the pieces of code involved in the various translation phases.
 
-*  `pypy/annotation`_ contains the data model for the type annotation that
+*  `rpython/annotator`_ contains the data model for the type annotation that
    can be inferred about a graph.  The graph "walker" that uses this is in
-   `pypy/annotation/annrpython.py`_.
+   `rpython/annotator/annrpython.py`_.
 
-*  `pypy/rpython`_ contains the code of the RPython typer. The typer transforms
+*  `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms
    annotated flow graphs in a way that makes them very similar to C code so
    that they can be easy translated. The graph transformations are controlled
-   by the code in `pypy/rpython/rtyper.py`_. The object model that is used can
-   be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type
+   by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can
+   be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type
    there is a file rxxxx.py that contains the low level functions needed for
    this type.
 
-*  `pypy/rlib`_ contains the `RPython standard library`_, things that you can
+*  `rpython/rlib`_ contains the `RPython standard library`_, things that you can
    use from rpython.
 
 .. _`RPython standard library`: rlib.html
@@ -320,10 +319,10 @@
 Demos
 -------
 
-The `demo/`_ directory contains examples of various aspects of PyPy,
-ranging from running regular Python programs (that we used as compliance goals) 
-over experimental distribution mechanisms to examples translating 
-sufficiently static programs into low level code. 
+The `example-interpreter`_ repository contains an example interpreter
+written using the RPython translation toolchain.
+
+.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter
 
 Additional Tools for running (and hacking) PyPy 
 -----------------------------------------------
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -217,17 +217,20 @@
 Here is a fully referenced alphabetical two-level deep 
 directory overview of PyPy: 
 
-================================   =========================================== 
+=================================  ============================================
 Directory                          explanation/links
-================================   =========================================== 
+=================================  ============================================
+`pypy/bin/`_                       command-line scripts, mainly
+                                   `pypy/bin/pyinteractive.py`_
 
-`pypy/bin/`_                       command-line scripts, mainly `pyinteractive.py`_
+`pypy/config/`_                    handles the numerous options for building
+                                   and running PyPy
 
-`pypy/config/`_                    handles the numerous options for building and running PyPy
+`pypy/doc/`_                       text versions of PyPy developer
+                                   documentation
 
-`pypy/doc/`_                       text versions of PyPy developer documentation
-
-`pypy/doc/config/`_                documentation for the numerous translation options
+`pypy/doc/config/`_                documentation for the numerous translation
+                                   options
 
 `pypy/doc/discussion/`_            drafts of ideas and documentation
 
@@ -238,19 +241,24 @@
 
 `pypy/interpreter/pyparser/`_      interpreter-level Python source parser
 
-`pypy/interpreter/astcompiler/`_   interpreter-level bytecode compiler, via an AST
-                                   representation
+`pypy/interpreter/astcompiler/`_   interpreter-level bytecode compiler,
+                                   via an AST representation
 
-`pypy/module/`_                    contains `mixed modules`_ implementing core modules with 
+`pypy/module/`_                    contains `mixed modules`_
+                                   implementing core modules with 
                                    both application and interpreter level code.
-                                   Not all are finished and working.  Use the ``--withmod-xxx``
-                                   or ``--allworkingmodules`` translation options.
+                                   Not all are finished and working.  Use
+                                   the ``--withmod-xxx``
+                                   or ``--allworkingmodules`` translation
+                                   options.
 
 `pypy/objspace/`_                  `object space`_ implementations
 
-`pypy/objspace/std/`_              the StdObjSpace_ implementing CPython's objects and types
+`pypy/objspace/std/`_              the StdObjSpace_ implementing CPython's
+                                   objects and types
 
-`pypy/tool/`_                      various utilities and hacks used from various places 
+`pypy/tool/`_                      various utilities and hacks used
+                                   from various places 
 
 `pypy/tool/algo/`_                 general-purpose algorithmic and mathematic
                                    tools
@@ -258,49 +266,58 @@
 `pypy/tool/pytest/`_               support code for our `testing methods`_
 
 
-`rpython/annotator/`_              `type inferencing code`_ for `RPython`_ programs 
+`rpython/annotator/`_              `type inferencing code`_ for
+                                   `RPython`_ programs 
 
 `rpython/config/`_                 handles the numerous options for RPython
 
 
-`rpython/flowspace/`_              the FlowObjSpace_ implementing `abstract interpretation`_
+`rpython/flowspace/`_              the FlowObjSpace_ implementing
+                                   `abstract interpretation`_
 
-
-`rpython/rlib/`_                   a `"standard library"`_ for RPython_ programs
+`rpython/rlib/`_                   a `"standard library"`_ for RPython_
+                                   programs
 
 `rpython/rtyper/`_                 the `RPython Typer`_ 
 
-`rpython/rtyper/lltypesystem/`_    the `low-level type system`_ for C-like backends
+`rpython/rtyper/lltypesystem/`_    the `low-level type system`_ for
+                                   C-like backends
 
-`rpython/rtyper/ootypesystem/`_    the `object-oriented type system`_ for OO backends
+`rpython/rtyper/ootypesystem/`_    the `object-oriented type system`_
+                                   for OO backends
 
-`rpython/rtyper/memory/`_          the `garbage collector`_ construction framework
+`rpython/rtyper/memory/`_          the `garbage collector`_ construction
+                                   framework
 
 `rpython/translator/`_             translation_ backends and support code
 
-`rpython/translator/backendopt/`_  general optimizations that run before a backend generates code
+`rpython/translator/backendopt/`_  general optimizations that run before a 
+                                   backend generates code
 
-`rpython/translator/c/`_           the `GenC backend`_, producing C code from an
+`rpython/translator/c/`_           the `GenC backend`_, producing C code
+                                   from an
                                    RPython program (generally via the rtyper_)
 
-`rpython/translator/cli/`_         the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_)
+`rpython/translator/cli/`_         the `CLI backend`_ for `.NET`_
+                                   (Microsoft CLR or Mono_)
 
-`pypy/goal/`_                      our `main PyPy-translation scripts`_ live here
+`pypy/goal/`_                      our `main PyPy-translation scripts`_
+                                   live here
 
 `rpython/translator/jvm/`_         the Java backend
 
-`rpython/translator/tool/`_        helper tools for translation, including the Pygame
-                                   `graph viewer`_
+`rpython/translator/tool/`_        helper tools for translation
 
-``*/test/``                        many directories have a test subdirectory containing test 
+`dotviewer/`_                      `graph viewer`_
+
+``*/test/``                        many directories have a test subdirectory
+                                   containing test 
                                    modules (see `Testing in PyPy`_) 
 
-``_cache/``                        holds cache files from internally `translating application 
-                                   level to interpreterlevel`_ code.   
-================================   =========================================== 
+``_cache/``                        holds cache files from various purposes
+=================================  ============================================
 
 .. _`bytecode interpreter`: interpreter.html
-.. _`translating application level to interpreterlevel`: geninterp.html
 .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy 
 .. _`mixed modules`: coding-guide.html#mixed-modules 
 .. _`modules`: coding-guide.html#modules 
diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst
--- a/pypy/doc/rlib.rst
+++ b/pypy/doc/rlib.rst
@@ -7,18 +7,18 @@
 .. contents::
 
 
-This page lists some of the modules in `pypy/rlib`_ together with some hints
+This page lists some of the modules in `rpython/rlib`_ together with some hints
 for what they can be used for. The modules here will make up some general
 library useful for RPython programs (since most of the standard library modules
 are not RPython). Most of these modules are somewhat rough still and are likely
 to change at some point.  Usually it is useful to look at the tests in
-`pypy/rlib/test`_ to get an impression of how to use a module.
+`rpython/rlib/test`_ to get an impression of how to use a module.
 
 
 ``listsort``
 ============
 
-The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm
+The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm
 (the sort method of lists is not RPython). To use it, subclass from the
 ``listsort.TimSort`` class and override the ``lt`` method to change the
 comparison behaviour. The constructor of ``TimSort`` takes a list as an
@@ -30,7 +30,7 @@
 ``nonconst``
 ============
 
-The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and
+The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and
 the `annotator`_ do quite some constant folding, which is sometimes not desired
 in a test. To prevent constant folding on a certain value, use the ``NonConst``
 class. The constructor of ``NonConst`` takes an arbitrary value. The instance of
@@ -44,7 +44,7 @@
 ``objectmodel``
 ===============
 
-The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the
+The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the
 more useful ones are:
 
 ``ComputedIntSymbolic``:
@@ -94,7 +94,7 @@
 ``rarithmetic``
 ===============
 
-The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences
+The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences
 in the behaviour of arithmetic code in regular Python and RPython code. Most of
 them are already described in the `coding guide`_
 
@@ -104,7 +104,7 @@
 ``rbigint``
 ===========
 
-The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long``
+The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long``
 type (which itself is not supported in RPython). The ``rbigint`` class contains
 that implementation. To construct ``rbigint`` instances use the static methods
 ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back
@@ -118,7 +118,7 @@
 ``rrandom``
 ===========
 
-The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random
+The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random
 number generator. It contains one class ``Random`` which most importantly has a
 ``random`` method which returns a pseudo-random floating point number between
 0.0 and 1.0.
@@ -126,7 +126,7 @@
 ``rsocket``
 ===========
 
-The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of
+The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of
 the socket standard library with a slightly different interface.  The
 difficulty with the Python socket API is that addresses are not "well-typed"
 objects: depending on the address family they are tuples, or strings, and
@@ -137,7 +137,7 @@
 ``streamio``
 ============
 
-The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started
+The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started
 by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the
 upcoming new file implementation in Python 3000).
 
@@ -146,7 +146,7 @@
 ``unroll``
 ==========
 
-The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable``
+The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable``
 which wraps an iterator. Looping over the iterator in RPython code will not
 produce a loop in the resulting flow graph but will unroll the loop instead.
 
@@ -154,7 +154,7 @@
 ``parsing``
 ===========
 
-The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and
+The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and
 parsers in RPython. It is still highly experimental and only really used by the
 `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way
 to specify a tokenizer/grammar is to write it down using regular expressions and
@@ -204,7 +204,7 @@
     anything except a.
 
 To parse a regular expression and to get a matcher for it, you can use the
-function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module.  It
+function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module.  It
 returns a object with a ``recognize(input)`` method that returns True or False
 depending on whether ``input`` matches the string or not.
 
@@ -213,7 +213,7 @@
 EBNF
 ----
 
-To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse``
+To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse``
 defines a syntax for doing that.
 
 The syntax file contains a sequence or rules. Every rule either describes a
@@ -295,7 +295,7 @@
 
 The parsing process builds up a tree consisting of instances of ``Symbol`` and
 ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal
-symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use
+symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use
 the ``view()`` method ``Nonterminal`` instances to get a pygame view of the
 parse tree.
 
@@ -310,7 +310,7 @@
 ++++++++
 
 To write tree visitors for the parse trees that are RPython, there is a special
-baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your
+baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your
 class uses this, it will grow a ``dispatch(node)`` method, that calls an
 appropriate ``visit_<symbol>`` method, depending on the ``node`` argument. Here
 the <symbol> is replaced by the ``symbol`` attribute of the visited node.
diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst
--- a/pypy/doc/rtyper.rst
+++ b/pypy/doc/rtyper.rst
@@ -4,7 +4,7 @@
 .. contents::
 
 
-The RPython Typer lives in the directory `pypy/rpython/`_.
+The RPython Typer lives in the directory `rpython/rtyper/`_.
 
 
 Overview
@@ -52,7 +52,7 @@
 where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``.
 This is done by attaching an attribute ``concretetype`` to v1, v2 and v3
 (which might be instances of Variable or possibly Constant).  In our model,
-this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``.  Of
+this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``.  Of
 course, the purpose of replacing the operation called ``add`` with
 ``int_add`` is that code generators no longer have to worry about what kind
 of addition (or concatenation maybe?) it means.
@@ -66,7 +66,7 @@
 each operation.  In both cases the analysis of an operation depends on the
 annotations of its input arguments.  This is reflected in the usage of the same
 ``__extend__`` syntax in the source files (compare e.g.
-`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_).
+`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_).
 
 The analogy stops here, though: while it runs, the Annotator is in the middle
 of computing the annotations, so it might need to reflow and generalize until
@@ -104,7 +104,7 @@
 implementations for the same high-level operations.  This is the reason for
 turning representations into explicit objects.
 
-The base Repr class is defined in `pypy/rpython/rmodel.py`_.  Most of the
+The base Repr class is defined in `rpython/rtyper/rmodel.py`_.  Most of the
 ``rpython/r*.py`` files define one or a few subclasses of Repr.  The method
 getrepr() of the RTyper will build and cache a single Repr instance per
 SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the
@@ -131,9 +131,9 @@
 The RPython Typer uses a standard low-level model which we believe can
 correspond rather directly to various target languages such as C.
 This model is implemented in the first part of
-`pypy/rpython/lltypesystem/lltype.py`_.
+`rpython/rtyper/lltypesystem/lltype.py`_.
 
-The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable
+The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable
 implementation of these types, for testing purposes.  It allows us to write
 and test plain Python code using a malloc() function to obtain and manipulate
 structures and arrays.  This is useful for example to implement and test
@@ -147,7 +147,7 @@
 
 Here is a quick tour:
 
-    >>> from pypy.rpython.lltypesystem.lltype import *
+    >>> from rpython.rtyper.lltypesystem.lltype import *
 
 Here are a few primitive low-level types, and the typeOf() function to figure
 them out:
@@ -191,7 +191,7 @@
 types like list in this elementary world.  The ``malloc()`` function is a kind
 of placeholder, which must eventually be provided by the code generator for the
 target platform; but as we have just seen its Python implementation in
-`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for
+`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for
 testing, interactive exploring, etc.
 
 The argument to ``malloc()`` is the structure type directly, but it returns a
@@ -245,7 +245,7 @@
 +++++++++++++++
 
 Structure types are built as instances of 
-``pypy.rpython.lltypesystem.lltype.Struct``::
+``rpython.rtyper.lltypesystem.lltype.Struct``::
 
     MyStructType = Struct('somename',  ('field1', Type1), ('field2', Type2)...)
     MyStructType = GcStruct('somename',  ('field1', Type1), ('field2', Type2)...)
@@ -277,7 +277,7 @@
 +++++++++++
 
 An array type is built as an instance of 
-``pypy.rpython.lltypesystem.lltype.Array``::
+``rpython.rtyper.lltypesystem.lltype.Array``::
 
     MyIntArray = Array(Signed)
     MyOtherArray = Array(MyItemType)
@@ -316,7 +316,7 @@
 with care: the bigger structure of which they are part of could be freed while
 the Ptr to the substructure is still in use.  In general, it is a good idea to
 avoid passing around pointers to inlined substructures of malloc()ed structures.
-(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some
+(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some
 extent that you are not trying to use a pointer to a structure after its
 container has been freed, using weak references.  But pointers to non-GC
 structures are not officially meant to be weak references: using them after what
@@ -429,7 +429,7 @@
 change needed to the Annotator to allow it to perform type inference of our
 very-low-level snippets of code.
 
-See for example `pypy/rpython/rlist.py`_.
+See for example `rpython/rtyper/rlist.py`_.
 
 
 .. _`oo type`:
@@ -441,10 +441,10 @@
 targeting low level backends such as C, but it is not good
 enough for targeting higher level backends such as .NET CLI or Java
 JVM, so a new object oriented model has been introduced. This model is
-implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_.
+implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_.
 
 As for the low-level typesystem, the second part of
-`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of
+`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of
 these types, for testing purposes.
 
 
@@ -751,7 +751,7 @@
 The LLInterpreter is a simple piece of code that is able to interpret flow
 graphs. This is very useful for testing purposes, especially if you work on
 the RPython Typer. The most useful interface for it is the ``interpret``
-function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as
+function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as
 arguments a function and a list of arguments with which the function is
 supposed to be called. Then it generates the flow graph, annotates it
 according to the types of the arguments you passed to it and runs the
diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst
--- a/pypy/doc/stackless.rst
+++ b/pypy/doc/stackless.rst
@@ -29,7 +29,7 @@
 on 32-bit or a complete megabyte on 64-bit.  Moreover, the feature is
 only available (so far) on x86 and x86-64 CPUs; for other CPUs you need
 to add a short page of custom assembler to
-`pypy/translator/c/src/stacklet/`_.
+`rpython/translator/c/src/stacklet/`_.
 
 
 Theory
@@ -271,9 +271,9 @@
 Continulets are internally implemented using stacklets, which is the
 generic RPython-level building block for "one-shot continuations".  For
 more information about them please see the documentation in the C source
-at `pypy/translator/c/src/stacklet/stacklet.h`_.
+at `rpython/translator/c/src/stacklet/stacklet.h`_.
 
-The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above
+The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above
 functions.  The key point is that new() and switch() always return a
 fresh stacklet handle (or an empty one), and switch() additionally
 consumes one.  It makes no sense to have code in which the returned
diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py
--- a/pypy/doc/tool/makeref.py
+++ b/pypy/doc/tool/makeref.py
@@ -1,10 +1,9 @@
 
 import py
-py.path.local(__file__)
 import pypy
-pypydir = py.path.local(pypy.__file__).dirpath()
-distdir = pypydir.dirpath() 
-issue_url = 'http://codespeak.net/issue/pypy-dev/' 
+pypydir = py.path.local(pypy.__file__).join('..')
+distdir = pypydir.dirpath()
+issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' 
 bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/'
 
 import urllib2, posixpath
diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst
--- a/pypy/doc/translation.rst
+++ b/pypy/doc/translation.rst
@@ -90,7 +90,7 @@
 (although these steps are not quite as distinct as you might think from
 this presentation).
 
-There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the
+There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the
 translation process which allows you to interactively work through these
 stages.
 
@@ -116,7 +116,7 @@
 which are the basic data structures of the translation
 process.
 
-All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather
+All these types are defined in `rpython/flowspace/model.py`_ (which is a rather
 important module in the PyPy source base, to reinforce the point).
 
 The flow graph of a function is represented by the class ``FunctionGraph``.
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
@@ -19,7 +19,7 @@
 .. branch: numpypy-longdouble
 Long double support for numpypy
 .. branch: numpypy-real-as-view
-Convert real, imag from ufuncs to views. This involves the beginning of 
+Convert real, imag from ufuncs to views. This involves the beginning of
 view() functionality
 
 .. branch: signatures
@@ -57,4 +57,14 @@
 
 .. branch: cleanup-tests
 Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into
-+one directory for reduced confusion and so they all run nightly.
+one directory for reduced confusion and so they all run nightly.
+
+.. branch: unquote-faster
+.. branch: urlparse-unquote-faster
+
+.. branch: signal-and-thread
+Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a
+non-main thread to enable the processing of signal handlers in that thread.
+
+.. branch: coding-guide-update-rlib-refs
+.. branch: rlib-doc-rpython-refs
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1494,10 +1494,11 @@
             )
         return fd
 
-    def warn(self, msg, w_warningcls):
-        self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls):
+    def warn(self, w_msg, w_warningcls, stacklevel=2):
+        self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)],
+                     """(msg, warningcls, stacklevel):
             import _warnings
-            _warnings.warn(msg, warningcls, stacklevel=2)
+            _warnings.warn(msg, warningcls, stacklevel=stacklevel)
         """)
 
 
diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py
--- a/pypy/interpreter/miscutils.py
+++ b/pypy/interpreter/miscutils.py
@@ -17,8 +17,14 @@
     def setvalue(self, value):
         self._value = value
 
-    def ismainthread(self):
+    def signals_enabled(self):
         return True
 
+    def enable_signals(self, space):
+        pass
+
+    def disable_signals(self, space):
+        pass
+
     def getallvalues(self):
         return {0: self._value}
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -53,16 +53,17 @@
         kwargname = None
     return Signature(argnames, varargname, kwargname)
 
+
 class PyCode(eval.Code):
     "CPython-style code objects."
     _immutable_ = True
     _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]",
-                          "co_freevars[*]", "co_cellvars[*]"]
+                          "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"]
 
     def __init__(self, space,  argcount, nlocals, stacksize, flags,
                      code, consts, names, varnames, filename,
                      name, firstlineno, lnotab, freevars, cellvars,
-                     hidden_applevel=False, magic = default_magic):
+                     hidden_applevel=False, magic=default_magic):
         """Initialize a new code object from parameters given by
         the pypy compiler"""
         self.space = space
@@ -89,8 +90,6 @@
 
     def _initialize(self):
         self._init_flags()
-        # Precompute what arguments need to be copied into cellvars
-        self._args_as_cellvars = []
 
         if self.co_cellvars:
             argcount = self.co_argcount
@@ -108,16 +107,22 @@
             # produced by CPython are loaded by PyPy.  Note that CPython
             # contains the following bad-looking nested loops at *every*
             # function call!
-            argvars  = self.co_varnames
+
+            # Precompute what arguments need to be copied into cellvars
+            args_as_cellvars = []
+            argvars = self.co_varnames
             cellvars = self.co_cellvars
             for i in range(len(cellvars)):
                 cellname = cellvars[i]
                 for j in range(argcount):
                     if cellname == argvars[j]:
                         # argument j has the same name as the cell var i
-                        while len(self._args_as_cellvars) <= i:
-                            self._args_as_cellvars.append(-1)   # pad
-                        self._args_as_cellvars[i] = j
+                        while len(args_as_cellvars) <= i:
+                            args_as_cellvars.append(-1)   # pad
+                        args_as_cellvars[i] = j
+            self._args_as_cellvars = args_as_cellvars[:]
+        else:
+            self._args_as_cellvars = []
 
         self._compute_flatcall()
 
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -776,17 +776,16 @@
 
     @jit.unroll_safe
     def cmp_exc_match(self, w_1, w_2):
-        if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)):
-            for w_t in self.space.fixedview(w_2):
-                if self.space.is_true(self.space.isinstance(w_t,
-                                                            self.space.w_str)):
-                    self.space.warn("catching of string exceptions is "
-                                    "deprecated",
-                                    self.space.w_DeprecationWarning)
-        elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)):
-            self.space.warn("catching of string exceptions is deprecated",
-                            self.space.w_DeprecationWarning)
-        return self.space.newbool(self.space.exception_match(w_1, w_2))
+        space = self.space
+        if space.is_true(space.isinstance(w_2, space.w_tuple)):
+            for w_t in space.fixedview(w_2):
+                if space.is_true(space.isinstance(w_t, space.w_str)):
+                    msg = "catching of string exceptions is deprecated"
+                    space.warn(space.wrap(msg), space.w_DeprecationWarning)
+        elif space.is_true(space.isinstance(w_2, space.w_str)):
+            msg = "catching of string exceptions is deprecated"
+            space.warn(space.wrap(msg), space.w_DeprecationWarning)
+        return space.newbool(space.exception_match(w_1, w_2))
 
     def COMPARE_OP(self, testnum, next_instr):
         w_2 = self.popvalue()
diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py
--- a/pypy/interpreter/test2/test_app_main.py
+++ b/pypy/interpreter/test2/test_app_main.py
@@ -208,11 +208,6 @@
     These tests require pexpect (UNIX-only).
     http://pexpect.sourceforge.net/
     """
-    def setup_class(cls):
-        # some tests need to be able to import test2, change the cwd
-        goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..'))
-        os.chdir(goal_dir)
-
     def _spawn(self, *args, **kwds):
         try:
             import pexpect
@@ -456,13 +451,14 @@
         child.expect('789')    # expect to see it before the timeout hits
         child.sendline('X')
 
-    def test_options_i_m(self):
+    def test_options_i_m(self, monkeypatch):
         if sys.platform == "win32":
             skip("close_fds is not supported on Windows platforms")
         if not hasattr(runpy, '_run_module_as_main'):
             skip("requires CPython >= 2.6")
         p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py')
         p = os.path.abspath(p)
+        monkeypatch.chdir(os.path.dirname(app_main))
         child = self.spawn(['-i',
                             '-m', 'test2.mymodule',
                             'extra'])
@@ -562,12 +558,13 @@
         child.sendline('Not at all. They could be carried.')
         child.expect('A five ounce bird could not carry a one pound coconut.')
 
-    def test_no_space_before_argument(self):
+    def test_no_space_before_argument(self, monkeypatch):
         if not hasattr(runpy, '_run_module_as_main'):
             skip("requires CPython >= 2.6")
         child = self.spawn(['-cprint "hel" + "lo"'])
         child.expect('hello')
 
+        monkeypatch.chdir(os.path.dirname(app_main))
         child = self.spawn(['-mtest2.mymodule'])
         child.expect('mymodule running')
 
@@ -667,11 +664,12 @@
                         '-c "import sys; print sys.warnoptions"')
         assert "['ignore', 'default', 'once', 'error']" in data
 
-    def test_option_m(self):
+    def test_option_m(self, monkeypatch):
         if not hasattr(runpy, '_run_module_as_main'):
             skip("requires CPython >= 2.6")
         p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py')
         p = os.path.abspath(p)
+        monkeypatch.chdir(os.path.dirname(app_main))
         data = self.run('-m test2.mymodule extra')
         assert 'mymodule running' in data
         assert 'Name: __main__' in data
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -133,56 +133,77 @@
         v = v.add(step)
     return space.newlist(res_w)
 
+min_jitdriver = jit.JitDriver(name='min',
+        greens=['w_type'], reds='auto')
+max_jitdriver = jit.JitDriver(name='max',
+        greens=['w_type'], reds='auto')
+
+def make_min_max(unroll):
+    @specialize.arg(2)
+    def min_max_impl(space, args, implementation_of):
+        if implementation_of == "max":
+            compare = space.gt
+            jitdriver = max_jitdriver
+        else:
+            compare = space.lt
+            jitdriver = min_jitdriver
+        args_w = args.arguments_w
+        if len(args_w) > 1:
+            w_sequence = space.newtuple(args_w)
+        elif len(args_w):
+            w_sequence = args_w[0]
+        else:
+            msg = "%s() expects at least one argument" % (implementation_of,)
+            raise OperationError(space.w_TypeError, space.wrap(msg))
+        w_key = None
+        kwds = args.keywords
+        if kwds:
+            if kwds[0] == "key" and len(kwds) == 1:
+                w_key = args.keywords_w[0]
+            else:
+                msg = "%s() got unexpected keyword argument" % (implementation_of,)
+                raise OperationError(space.w_TypeError, space.wrap(msg))
+
+        w_iter = space.iter(w_sequence)
+        w_type = space.type(w_iter)
+        w_max_item = None
+        w_max_val = None
+        while True:
+            if not unroll:
+                jitdriver.jit_merge_point(w_type=w_type)
+            try:
+                w_item = space.next(w_iter)
+            except OperationError, e:
+                if not e.match(space, space.w_StopIteration):
+                    raise
+                break
+            if w_key is not None:
+                w_compare_with = space.call_function(w_key, w_item)
+            else:
+                w_compare_with = w_item
+            if w_max_item is None or \
+                    space.is_true(compare(w_compare_with, w_max_val)):
+                w_max_item = w_item
+                w_max_val = w_compare_with
+        if w_max_item is None:
+            msg = "arg is an empty sequence"
+            raise OperationError(space.w_ValueError, space.wrap(msg))
+        return w_max_item
+    if unroll:
+        min_max_impl = jit.unroll_safe(min_max_impl)
+    return min_max_impl
+
+min_max_unroll = make_min_max(True)
+min_max_normal = make_min_max(False)
 
 @specialize.arg(2)
- at jit.look_inside_iff(lambda space, args, implementation_of:
-    jit.isconstant(len(args.arguments_w)) and
-    len(args.arguments_w) == 2
-)
 def min_max(space, args, implementation_of):
-    if implementation_of == "max":
-        compare = space.gt
+    if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and
+            len(args.arguments_w) == 2):
+        return min_max_unroll(space, args, implementation_of)
     else:
-        compare = space.lt
-    args_w = args.arguments_w
-    if len(args_w) > 1:
-        w_sequence = space.newtuple(args_w)
-    elif len(args_w):
-        w_sequence = args_w[0]
-    else:
-        msg = "%s() expects at least one argument" % (implementation_of,)
-        raise OperationError(space.w_TypeError, space.wrap(msg))
-    w_key = None
-    kwds = args.keywords
-    if kwds:
-        if kwds[0] == "key" and len(kwds) == 1:
-            w_key = args.keywords_w[0]
-        else:
-            msg = "%s() got unexpected keyword argument" % (implementation_of,)
-            raise OperationError(space.w_TypeError, space.wrap(msg))
-
-    w_iter = space.iter(w_sequence)
-    w_max_item = None
-    w_max_val = None
-    while True:
-        try:
-            w_item = space.next(w_iter)
-        except OperationError, e:
-            if not e.match(space, space.w_StopIteration):
-                raise
-            break
-        if w_key is not None:
-            w_compare_with = space.call_function(w_key, w_item)
-        else:
-            w_compare_with = w_item
-        if w_max_item is None or \
-                space.is_true(compare(w_compare_with, w_max_val)):
-            w_max_item = w_item
-            w_max_val = w_compare_with
-    if w_max_item is None:
-        msg = "arg is an empty sequence"
-        raise OperationError(space.w_ValueError, space.wrap(msg))
-    return w_max_item
+        return min_max_normal(space, args, implementation_of)
+min_max._always_inline = True
 
 def max(space, __args__):
     """max(iterable[, key=func]) -> value
diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py
--- a/pypy/module/__builtin__/interp_classobj.py
+++ b/pypy/module/__builtin__/interp_classobj.py
@@ -154,9 +154,9 @@
                 return
             elif name == "__del__":
                 if self.lookup(space, name) is None:
-                    msg = ("a __del__ method added to an existing class "
-                           "will not be called")
-                    space.warn(msg, space.w_RuntimeWarning)
+                    msg = ("a __del__ method added to an existing class will "
+                           "not be called")
+                    space.warn(space.wrap(msg), space.w_RuntimeWarning)
         space.setitem(self.w_dict, w_attr, w_value)
 
     def descr_delattr(self, space, w_attr):
@@ -395,9 +395,9 @@
                 cache = space.fromcache(Cache)
                 if (not isinstance(self, cache.cls_with_del)
                     and self.getdictvalue(space, '__del__') is None):
-                    msg = ("a __del__ method added to an instance "
-                           "with no __del__ in the class will not be called")
-                    space.warn(msg, space.w_RuntimeWarning)
+                    msg = ("a __del__ method added to an instance with no "
+                           "__del__ in the class will not be called")
+                    space.warn(space.wrap(msg), space.w_RuntimeWarning)
         if w_meth is not None:
             space.call_function(w_meth, w_name, w_value)
         else:
@@ -454,11 +454,9 @@
             else:
                 w_as_str = self.descr_str(space)
             if space.len_w(w_format_spec) > 0:
-                space.warn(
-                    ("object.__format__ with a non-empty format string is "
-                        "deprecated"),
-                    space.w_PendingDeprecationWarning
-                )
+                msg = ("object.__format__ with a non-empty format string is "
+                       "deprecated")
+                space.warn(space.wrap(msg), space.w_PendingDeprecationWarning)
             return space.format(w_as_str, w_format_spec)
 
     def descr_len(self, space):
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -26,6 +26,16 @@
                 interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
 
 
+class ThreadModule(MixedModule):
+    appleveldefs = {
+        'signals_enabled': 'app_signal.signals_enabled',
+    }
+    interpleveldefs = {
+        '_signals_enter':  'interp_signal.signals_enter',
+        '_signals_exit':   'interp_signal.signals_exit',
+    }
+
+
 class Module(MixedModule):
     appleveldefs = {
     }
@@ -54,6 +64,7 @@
     submodules = {
         "builders": BuildersModule,
         "time": TimeModule,
+        "thread": ThreadModule,
     }
 
     def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/app_signal.py
@@ -0,0 +1,14 @@
+import __pypy__.thread
+
+class SignalsEnabled(object):
+    '''A context manager to use in non-main threads:
+enables receiving signals in a "with" statement.  More precisely, if a
+signal is received by the process, then the signal handler might be
+called either in the main thread (as usual) or within another thread
+that is within a "with signals_enabled:".  This other thread should be
+ready to handle unexpected exceptions that the signal handler might
+raise --- notably KeyboardInterrupt.'''
+    __enter__ = __pypy__.thread._signals_enter
+    __exit__  = __pypy__.thread._signals_exit
+
+signals_enabled = SignalsEnabled()
diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_signal.py
@@ -0,0 +1,6 @@
+
+def signals_enter(space):
+    space.threadlocals.enable_signals(space)
+
+def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None):
+    space.threadlocals.disable_signals(space)
diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_signal.py
@@ -0,0 +1,122 @@
+import sys
+
+from pypy.module.thread.test.support import GenericTestThread
+
+
+class AppTestMinimal:
+    spaceconfig = dict(usemodules=['__pypy__'])
+
+    def test_signal(self):
+        from __pypy__ import thread
+        with thread.signals_enabled:
+            pass
+        # assert did not crash
+
+
+class AppTestThreadSignal(GenericTestThread):
+    spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time'])
+
+    def test_exit_twice(self):
+        import __pypy__, thread
+        __pypy__.thread._signals_exit()
+        try:
+            raises(thread.error, __pypy__.thread._signals_exit)
+        finally:
+            __pypy__.thread._signals_enter()
+
+    def test_enable_signals(self):
+        import __pypy__, thread, signal, time
+
+        def subthread():
+            try:
+                with __pypy__.thread.signals_enabled:
+                    thread.interrupt_main()
+                    for i in range(10):
+                        print 'x'
+                        time.sleep(0.1)
+            except BaseException, e:
+                interrupted.append(e)
+            finally:
+                done.append(None)
+
+        # This is normally called by app_main.py
+        signal.signal(signal.SIGINT, signal.default_int_handler)
+
+        for i in range(10):
+            __pypy__.thread._signals_exit()
+            try:
+                done = []
+                interrupted = []
+                thread.start_new_thread(subthread, ())
+                for i in range(10):
+                    if len(done): break
+                    print '.'
+                    time.sleep(0.1)
+                assert len(done) == 1
+                assert len(interrupted) == 1
+                assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__
+            finally:
+                __pypy__.thread._signals_enter()
+
+    def test_thread_fork_signals(self):
+        import __pypy__
+        import os, thread, signal
+
+        if not hasattr(os, 'fork'):
+            skip("No fork on this platform")
+
+        def fork():
+            with __pypy__.thread.signals_enabled:
+                return os.fork()
+
+        def threadfunction():
+            pid = fork()
+            if pid == 0:
+                print 'in child'
+                # signal() only works from the 'main' thread
+                signal.signal(signal.SIGUSR1, signal.SIG_IGN)
+                os._exit(42)
+            else:
+                self.timeout_killer(pid, 5)
+                exitcode = os.waitpid(pid, 0)[1]
+                feedback.append(exitcode)
+
+        feedback = []
+        thread.start_new_thread(threadfunction, ())
+        self.waitfor(lambda: feedback)
+        # if 0, an (unraisable) exception was raised from the forked thread.
+        # if 9, process was killed by timer.
+        # if 42<<8, os._exit(42) was correctly reached.
+        assert feedback == [42<<8]
+
+
+class AppTestThreadSignalLock:
+    spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal'])
+
+    def setup_class(cls):
+        if (not cls.runappdirect or
+                '__pypy__' not in sys.builtin_module_names):
+            import py
+            py.test.skip("this is only a test for -A runs on top of pypy")
+
+    def test_enable_signals(self):
+        import __pypy__, thread, signal, time
+
+        interrupted = []
+        lock = thread.allocate_lock()
+        lock.acquire()
+
+        def subthread():
+            try:
+                time.sleep(0.25)
+                with __pypy__.thread.signals_enabled:
+                    thread.interrupt_main()
+            except BaseException, e:
+                interrupted.append(e)
+            finally:
+                lock.release()
+
+        thread.start_new_thread(subthread, ())
+        lock.acquire()
+        assert len(interrupted) == 1
+        assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -7,7 +7,7 @@
     appleveldefs = {
         }
     interpleveldefs = {
-        '__version__': 'space.wrap("0.4")',
+        '__version__': 'space.wrap("0.6")',
 
         'load_library': 'libraryobj.load_library',
 
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -119,9 +119,12 @@
 
     def getitem(self, w_index):
         space = self.space
-        i = space.getindex_w(w_index, space.w_IndexError)
-        ctype = self.ctype._check_subscript_index(self, i)
-        w_o = self._do_getitem(ctype, i)
+        if space.isinstance_w(w_index, space.w_slice):
+            w_o = self._do_getslice(w_index)
+        else:
+            i = space.getindex_w(w_index, space.w_IndexError)
+            ctype = self.ctype._check_subscript_index(self, i)
+            w_o = self._do_getitem(ctype, i)
         keepalive_until_here(self)
         return w_o
 
@@ -132,14 +135,100 @@
 
     def setitem(self, w_index, w_value):
         space = self.space
-        i = space.getindex_w(w_index, space.w_IndexError)
-        ctype = self.ctype._check_subscript_index(self, i)
-        ctitem = ctype.ctitem
-        ctitem.convert_from_object(
-            rffi.ptradd(self._cdata, i * ctitem.size),
-            w_value)
+        if space.isinstance_w(w_index, space.w_slice):
+            self._do_setslice(w_index, w_value)
+        else:
+            i = space.getindex_w(w_index, space.w_IndexError)
+            ctype = self.ctype._check_subscript_index(self, i)
+            ctitem = ctype.ctitem
+            ctitem.convert_from_object(
+                rffi.ptradd(self._cdata, i * ctitem.size),
+                w_value)
         keepalive_until_here(self)
 
+    def _do_getslicearg(self, w_slice):
+        from pypy.module._cffi_backend.ctypeptr import W_CTypePointer
+        from pypy.objspace.std.sliceobject import W_SliceObject
+        assert isinstance(w_slice, W_SliceObject)
+        space = self.space
+        #
+        if space.is_w(w_slice.w_start, space.w_None):
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("slice start must be specified"))
+        start = space.int_w(w_slice.w_start)
+        #
+        if space.is_w(w_slice.w_stop, space.w_None):
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("slice stop must be specified"))
+        stop = space.int_w(w_slice.w_stop)
+        #
+        if not space.is_w(w_slice.w_step, space.w_None):
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("slice with step not supported"))
+        #
+        if start > stop:
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("slice start > stop"))
+        #
+        ctype = self.ctype._check_slice_index(self, start, stop)
+        assert isinstance(ctype, W_CTypePointer)
+        #
+        return ctype, start, stop - start
+
+    def _do_getslice(self, w_slice):
+        ctptr, start, length = self._do_getslicearg(w_slice)
+        #
+        space = self.space
+        ctarray = ctptr.cache_array_type
+        if ctarray is None:
+            from pypy.module._cffi_backend import newtype
+            ctarray = newtype.new_array_type(space, ctptr, space.w_None)
+            ctptr.cache_array_type = ctarray
+        #
+        p = rffi.ptradd(self._cdata, start * ctarray.ctitem.size)
+        return W_CDataSliced(space, p, ctarray, length)
+
+    def _do_setslice(self, w_slice, w_value):
+        ctptr, start, length = self._do_getslicearg(w_slice)
+        ctitem = ctptr.ctitem
+        ctitemsize = ctitem.size
+        cdata = rffi.ptradd(self._cdata, start * ctitemsize)
+        #
+        if isinstance(w_value, W_CData):
+            from pypy.module._cffi_backend import ctypearray
+            ctv = w_value.ctype
+            if (isinstance(ctv, ctypearray.W_CTypeArray) and
+                ctv.ctitem is ctitem and
+                w_value.get_array_length() == length):
+                # fast path: copying from exactly the correct type
+                s = w_value._cdata
+                for i in range(ctitemsize * length):
+                    cdata[i] = s[i]
+                keepalive_until_here(w_value)
+                return
+        #
+        space = self.space
+        w_iter = space.iter(w_value)
+        for i in range(length):
+            try:
+                w_item = space.next(w_iter)
+            except OperationError, e:
+                if not e.match(space, space.w_StopIteration):
+                    raise
+                raise operationerrfmt(space.w_ValueError,
+                                      "need %d values to unpack, got %d",
+                                      length, i)
+            ctitem.convert_from_object(cdata, w_item)
+            cdata = rffi.ptradd(cdata, ctitemsize)
+        try:
+            space.next(w_iter)
+        except OperationError, e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+        else:
+            raise operationerrfmt(space.w_ValueError,
+                                  "got more than %d values to unpack", length)
+
     def _add_or_sub(self, w_other, sign):
         space = self.space
         i = sign * space.getindex_w(w_other, space.w_OverflowError)
@@ -281,6 +370,22 @@
         return self.structobj
 
 
+class W_CDataSliced(W_CData):
+    """Subclass with an explicit length, for slices."""
+    _attrs_ = ['length']
+    _immutable_fields_ = ['length']
+
+    def __init__(self, space, cdata, ctype, length):
+        W_CData.__init__(self, space, cdata, ctype)
+        self.length = length
+
+    def _repr_extra(self):
+        return "sliced length %d" % (self.length,)
+
+    def get_array_length(self):
+        return self.length
+
+
 W_CData.typedef = TypeDef(
     'CData',
     __module__ = '_cffi_backend',
diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py
--- a/pypy/module/_cffi_backend/ctypearray.py
+++ b/pypy/module/_cffi_backend/ctypearray.py
@@ -76,6 +76,17 @@
                 self.name, i, w_cdata.get_array_length())
         return self
 
+    def _check_slice_index(self, w_cdata, start, stop):
+        space = self.space
+        if start < 0:
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("negative index not supported"))
+        if stop > w_cdata.get_array_length():
+            raise operationerrfmt(space.w_IndexError,
+                "index too large (expected %d <= %d)",
+                stop, w_cdata.get_array_length())
+        return self.ctptr
+
     def convert_from_object(self, cdata, w_ob):
         self.convert_array_from_object(cdata, w_ob)
 
diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py
--- a/pypy/module/_cffi_backend/ctypeenum.py
+++ b/pypy/module/_cffi_backend/ctypeenum.py
@@ -6,23 +6,19 @@
 from rpython.rtyper.lltypesystem import rffi
 from rpython.rlib.rarithmetic import intmask, r_ulonglong
 from rpython.rlib.objectmodel import keepalive_until_here
+from rpython.rlib.objectmodel import specialize
 
 from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned
+from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned
 from pypy.module._cffi_backend import misc
 
 
-class W_CTypeEnum(W_CTypePrimitiveSigned):
-    _attrs_            = ['enumerators2values', 'enumvalues2erators']
-    _immutable_fields_ = ['enumerators2values', 'enumvalues2erators']
-    kind = "enum"
+class _Mixin_Enum(object):
+    _mixin_ = True
 
-    def __init__(self, space, name, enumerators, enumvalues):
-        from pypy.module._cffi_backend.newtype import alignment
+    def __init__(self, space, name, size, align, enumerators, enumvalues):
         name = "enum " + name
-        size = rffi.sizeof(rffi.INT)
-        align = alignment(rffi.INT)
-        W_CTypePrimitiveSigned.__init__(self, space, size,
-                                        name, len(name), align)
+        self._super.__init__(self, space, size, name, len(name), align)
         self.enumerators2values = {}   # str -> int
         self.enumvalues2erators = {}   # int -> str
         for i in range(len(enumerators)-1, -1, -1):
@@ -44,55 +40,46 @@
                 space.setitem(w_dct, space.wrap(enumerator),
                                      space.wrap(enumvalue))
             return w_dct
-        return W_CTypePrimitiveSigned._fget(self, attrchar)
+        return self._super._fget(self, attrchar)
+
+    def extra_repr(self, cdata):
+        value = self._get_value(cdata)
+        try:
+            s = self.enumvalues2erators[value]
+        except KeyError:
+            return str(value)
+        else:
+            return '%s: %s' % (value, s)
 
     def string(self, cdataobj, maxlen):
-        w_result = self.convert_to_object(cdataobj._cdata)
+        value = self._get_value(cdataobj._cdata)
         keepalive_until_here(cdataobj)
-        return w_result
+        try:
+            s = self.enumvalues2erators[value]
+        except KeyError:
+            s = str(value)
+        return self.space.wrap(s)
 
-    def convert_to_object(self, cdata):
-        value = misc.read_raw_long_data(cdata, self.size)
-        try:
-            enumerator = self.enumvalues2erators[value]
-        except KeyError:
-            enumerator = '#%d' % (value,)
-        return self.space.wrap(enumerator)
 
-    def convert_from_object(self, cdata, w_ob):
-        space = self.space
-        try:
-            return W_CTypePrimitiveSigned.convert_from_object(self, cdata,
-                                                              w_ob)
-        except OperationError, e:
-            if not e.match(space, space.w_TypeError):
-                raise
-        if space.isinstance_w(w_ob, space.w_basestring):
-            value = self.convert_enum_string_to_int(space.str_w(w_ob))
-            value = r_ulonglong(value)
-            misc.write_raw_integer_data(cdata, value, self.size)
-        else:
-            raise self._convert_error("str or int", w_ob)
+class W_CTypeEnumSigned(_Mixin_Enum, W_CTypePrimitiveSigned):
+    _attrs_            = ['enumerators2values', 'enumvalues2erators']
+    _immutable_fields_ = ['enumerators2values', 'enumvalues2erators']
+    kind = "enum"
+    _super = W_CTypePrimitiveSigned
 
-    def cast_str(self, w_ob):
-        space = self.space
-        return self.convert_enum_string_to_int(space.str_w(w_ob))
+    def _get_value(self, cdata):
+        # returns a signed long
+        assert self.value_fits_long
+        return misc.read_raw_long_data(cdata, self.size)
 
-    def cast_unicode(self, w_ob):
-        return self.cast_str(w_ob)
 
-    def convert_enum_string_to_int(self, s):
-        space = self.space
-        if s.startswith('#'):
-            try:
-                return int(s[1:])
-            except ValueError:
-                raise OperationError(space.w_ValueError,
-                                     space.wrap("invalid literal after '#'"))
-        else:
-            try:
-                return self.enumerators2values[s]
-            except KeyError:
-                raise operationerrfmt(space.w_ValueError,
-                                      "'%s' is not an enumerator for %s",
-                                      s, self.name)
+class W_CTypeEnumUnsigned(_Mixin_Enum, W_CTypePrimitiveUnsigned):
+    _attrs_            = ['enumerators2values', 'enumvalues2erators']
+    _immutable_fields_ = ['enumerators2values', 'enumvalues2erators']
+    kind = "enum"
+    _super = W_CTypePrimitiveUnsigned
+
+    def _get_value(self, cdata):
+        # returns an unsigned long
+        assert self.value_fits_ulong
+        return misc.read_raw_ulong_data(cdata, self.size)
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -93,12 +93,18 @@
                                    "not %s", self.name, expected,
                                    space.type(w_got).getname(space))
 
-    def _check_subscript_index(self, w_cdata, i):
+    def _cannot_index(self):
         space = self.space
         raise operationerrfmt(space.w_TypeError,
                               "cdata of type '%s' cannot be indexed",
                               self.name)
 
+    def _check_subscript_index(self, w_cdata, i):
+        raise self._cannot_index()
+
+    def _check_slice_index(self, w_cdata, start, stop):
+        raise self._cannot_index()
+
     def string(self, cdataobj, maxlen):
         space = self.space
         raise operationerrfmt(space.w_TypeError,
diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -171,9 +171,7 @@
             self.vrangemax = (r_uint(1) << sh) - 1
 
     def int(self, cdata):
-        # enums: really call convert_to_object() just below,
-        # and not the one overridden in W_CTypeEnum.
-        return W_CTypePrimitiveSigned.convert_to_object(self, cdata)
+        return self.convert_to_object(cdata)
 
     def convert_to_object(self, cdata):
         if self.value_fits_long:
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -174,9 +174,10 @@
 
 
 class W_CTypePointer(W_CTypePtrBase):
-    _attrs_ = ['is_file']
-    _immutable_fields_ = ['is_file']
+    _attrs_ = ['is_file', 'cache_array_type']
+    _immutable_fields_ = ['is_file', 'cache_array_type?']
     kind = "pointer"
+    cache_array_type = None
 
     def __init__(self, space, ctitem):
         from pypy.module._cffi_backend import ctypearray
@@ -185,7 +186,8 @@
             extra = "(*)"    # obscure case: see test_array_add
         else:
             extra = " *"
-        self.is_file = (ctitem.name == "struct _IO_FILE")
+        self.is_file = (ctitem.name == "struct _IO_FILE" or
+                        ctitem.name == "struct $FILE")
         W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem)
 
     def newp(self, w_init):
@@ -224,6 +226,9 @@
                                       self.name)
         return self
 
+    def _check_slice_index(self, w_cdata, start, stop):
+        return self
+
     def add(self, cdata, i):
         space = self.space
         ctitem = self.ctitem
diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -1,7 +1,8 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.gateway import unwrap_spec
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib.rarithmetic import ovfcheck
+from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask
+from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of
 from rpython.rlib.objectmodel import specialize
 
 from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray
@@ -263,26 +264,38 @@
 
 # ____________________________________________________________
 
- at unwrap_spec(name=str)
-def new_enum_type(space, name, w_enumerators, w_enumvalues):
+ at unwrap_spec(name=str, basectype=ctypeobj.W_CType)
+def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype):
     enumerators_w = space.fixedview(w_enumerators)
     enumvalues_w  = space.fixedview(w_enumvalues)
     if len(enumerators_w) != len(enumvalues_w):
         raise OperationError(space.w_ValueError,
                              space.wrap("tuple args must have the same size"))
     enumerators = [space.str_w(w) for w in enumerators_w]
-    enumvalues = []
+    #
+    if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and
+        not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)):
+        raise OperationError(space.w_TypeError,
+              space.wrap("expected a primitive signed or unsigned base type"))
+    #
+    lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw')
     try:
         for w in enumvalues_w:
-            enumvalues.append(space.c_int_w(w))
-    except OperationError, e:
-        if not e.match(space, space.w_OverflowError):
-            raise
-        i = len(enumvalues)
-        raise operationerrfmt(space.w_OverflowError,
-            "enum '%s' declaration for '%s' does not fit an int",
-                              name, enumerators[i])
-    ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues)
+            # detects out-of-range or badly typed values
+            basectype.convert_from_object(lvalue, w)
+    finally:
+        lltype.free(lvalue, flavor='raw')
+    #
+    size = basectype.size
+    align = basectype.align
+    if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned):
+        enumvalues = [space.int_w(w) for w in enumvalues_w]
+        ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align,
+                                            enumerators, enumvalues)
+    else:
+        enumvalues = [space.uint_w(w) for w in enumvalues_w]
+        ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align,
+                                              enumerators, enumvalues)
     return ctype
 
 # ____________________________________________________________
@@ -302,8 +315,13 @@
     #
     if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid))
             or isinstance(fresult, ctypearray.W_CTypeArray)):
-        raise operationerrfmt(space.w_TypeError,
-                              "invalid result type: '%s'", fresult.name)
+        if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion) and
+                fresult.size < 0):
+            raise operationerrfmt(space.w_TypeError,
+                                  "result type '%s' is opaque", fresult.name)
+        else:
+            raise operationerrfmt(space.w_TypeError,
+                                  "invalid result type: '%s'", fresult.name)
     #
     fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis)
     return fct
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1264,80 +1264,130 @@
     py.test.raises(TypeError, callback, BFunc, cb, -42)
 
 def test_enum_type():
-    BEnum = new_enum_type("foo", (), ())
+    BUInt = new_primitive_type("unsigned int")
+    BEnum = new_enum_type("foo", (), (), BUInt)
     assert repr(BEnum) == "<ctype 'enum foo'>"
     assert BEnum.kind == "enum"
     assert BEnum.cname == "enum foo"
     assert BEnum.elements == {}
     #
-    BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+    BInt = new_primitive_type("int")
+    BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt)
     assert BEnum.kind == "enum"
     assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
     # 'elements' is not the real dict, but merely a copy
     BEnum.elements[2] = '??'
     assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
     #


More information about the pypy-commit mailing list