Author: Antonio Cuni <anto.c...@gmail.com>
Branch: faster-rstruct-2
Changeset: r91382:4d0500d6eced
Date: 2017-05-23 00:30 +0200
http://bitbucket.org/pypy/pypy/changeset/4d0500d6eced/

Log:    hg merge default

diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -1,4 +1,3 @@
-
 from _ctypes.basics import _CData, _CDataMeta, cdata_from_address
 from _ctypes.primitive import SimpleType, _SimpleCData
 from _ctypes.basics import ArgumentError, keepalive_key
@@ -9,13 +8,16 @@
 import sys
 import traceback
 
-try: from __pypy__ import builtinify
-except ImportError: builtinify = lambda f: f
+
+try:
+    from __pypy__ import builtinify
+except ImportError:
+    builtinify = lambda f: f
 
 # XXX this file needs huge refactoring I fear
 
-PARAMFLAG_FIN   = 0x1
-PARAMFLAG_FOUT  = 0x2
+PARAMFLAG_FIN = 0x1
+PARAMFLAG_FOUT = 0x2
 PARAMFLAG_FLCID = 0x4
 PARAMFLAG_COMBINED = PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID
 
@@ -24,9 +26,9 @@
     PARAMFLAG_FIN,
     PARAMFLAG_FIN | PARAMFLAG_FOUT,
     PARAMFLAG_FIN | PARAMFLAG_FLCID
-    )
+)
 
-WIN64 = sys.platform == 'win32' and sys.maxint == 2**63 - 1
+WIN64 = sys.platform == 'win32' and sys.maxint == 2 ** 63 - 1
 
 
 def get_com_error(errcode, riid, pIunk):
@@ -35,6 +37,7 @@
     from _ctypes import COMError
     return COMError(errcode, None, None)
 
+
 @builtinify
 def call_function(func, args):
     "Only for debugging so far: So that we can call CFunction instances"
@@ -94,14 +97,9 @@
                         "item %d in _argtypes_ has no from_param method" % (
                             i + 1,))
             self._argtypes_ = list(argtypes)
-            self._check_argtypes_for_fastpath()
+
     argtypes = property(_getargtypes, _setargtypes)
 
-    def _check_argtypes_for_fastpath(self):
-        if all([hasattr(argtype, '_ffiargshape_') for argtype in 
self._argtypes_]):
-            fastpath_cls = make_fastpath_subclass(self.__class__)
-            fastpath_cls.enable_fastpath_maybe(self)
-
     def _getparamflags(self):
         return self._paramflags
 
@@ -126,27 +124,26 @@
                 raise TypeError(
                     "paramflags must be a sequence of (int [,string [,value]]) 
"
                     "tuples"
-                    )
+                )
             if not isinstance(flag, int):
                 raise TypeError(
                     "paramflags must be a sequence of (int [,string [,value]]) 
"
                     "tuples"
-                    )
+                )
             _flag = flag & PARAMFLAG_COMBINED
             if _flag == PARAMFLAG_FOUT:
                 typ = self._argtypes_[idx]
                 if getattr(typ, '_ffiargshape_', None) not in ('P', 'z', 'Z'):
                     raise TypeError(
                         "'out' parameter %d must be a pointer type, not %s"
-                        % (idx+1, type(typ).__name__)
-                        )
+                        % (idx + 1, type(typ).__name__)
+                    )
             elif _flag not in VALID_PARAMFLAGS:
                 raise TypeError("paramflag value %d not supported" % flag)
         self._paramflags = paramflags
 
     paramflags = property(_getparamflags, _setparamflags)
 
-
     def _getrestype(self):
         return self._restype_
 
@@ -156,7 +153,7 @@
             from ctypes import c_int
             restype = c_int
         if not (isinstance(restype, _CDataMeta) or restype is None or
-                callable(restype)):
+                    callable(restype)):
             raise TypeError("restype must be a type, a callable, or None")
         self._restype_ = restype
 
@@ -168,15 +165,18 @@
 
     def _geterrcheck(self):
         return getattr(self, '_errcheck_', None)
+
     def _seterrcheck(self, errcheck):
         if not callable(errcheck):
             raise TypeError("The errcheck attribute must be callable")
         self._errcheck_ = errcheck
+
     def _delerrcheck(self):
         try:
             del self._errcheck_
         except AttributeError:
             pass
+
     errcheck = property(_geterrcheck, _seterrcheck, _delerrcheck)
 
     def _ffishapes(self, args, restype):
@@ -188,7 +188,7 @@
                 raise TypeError("invalid result type for callback function")
             restype = restype._ffiargshape_
         else:
-            restype = 'O' # void
+            restype = 'O'  # void
         return argtypes, restype
 
     def _set_address(self, address):
@@ -201,7 +201,7 @@
 
     def __init__(self, *args):
         self.name = None
-        self._objects = {keepalive_key(0):self}
+        self._objects = {keepalive_key(0): self}
         self._needs_free = True
 
         # Empty function object -- this is needed for casts
@@ -222,10 +222,8 @@
             if self._argtypes_ is None:
                 self._argtypes_ = []
             self._ptr = self._getfuncptr_fromaddress(self._argtypes_, restype)
-            self._check_argtypes_for_fastpath()
             return
 
-
         # A callback into python
         if callable(argument) and not argsl:
             self.callable = argument
@@ -259,7 +257,7 @@
         if (sys.platform == 'win32' and isinstance(argument, (int, long))
             and argsl):
             ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
-            self._com_index =  argument + 0x1000
+            self._com_index = argument + 0x1000
             self.name = argsl.pop(0)
             if argsl:
                 self.paramflags = argsl.pop(0)
@@ -281,6 +279,7 @@
             except SystemExit as e:
                 handle_system_exit(e)
                 raise
+
         return f
 
     def __call__(self, *args, **kwargs):
@@ -317,7 +316,7 @@
             except:
                 exc_info = sys.exc_info()
                 traceback.print_tb(exc_info[2], file=sys.stderr)
-                print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, 
exc_info[1])
+                print >> sys.stderr, "%s: %s" % (exc_info[0].__name__, 
exc_info[1])
                 return 0
             if self._restype_ is not None:
                 return res
@@ -328,7 +327,7 @@
             # really slow".  Now we don't worry that much about slowness
             # of ctypes, and it's strange to get warnings for perfectly-
             # legal code.
-            #warnings.warn('C function without declared arguments called',
+            # warnings.warn('C function without declared arguments called',
             #              RuntimeWarning, stacklevel=2)
             argtypes = []
 
@@ -337,7 +336,7 @@
             if not args:
                 raise ValueError(
                     "native COM method call without 'this' parameter"
-                    )
+                )
             thisvalue = args[0]
             thisarg = cast(thisvalue, POINTER(POINTER(c_void_p)))
             keepalives, newargs, argtypes, outargs, errcheckargs = (
@@ -366,7 +365,6 @@
         return tuple(outargs)
 
     def _call_funcptr(self, funcptr, *newargs):
-
         if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
             tmp = _rawffi.get_errno()
             _rawffi.set_errno(get_errno())
@@ -431,7 +429,7 @@
             ffiargs = [argtype.get_ffi_argtype() for argtype in argtypes]
             ffires = restype.get_ffi_argtype()
             return _ffi.FuncPtr.fromaddr(ptr, '', ffiargs, ffires, 
self._flags_)
-        
+
         cdll = self.dll._handle
         try:
             ffi_argtypes = [argtype.get_ffi_argtype() for argtype in argtypes]
@@ -450,7 +448,7 @@
             # funcname -> _funcname@<n>
             # where n is 0, 4, 8, 12, ..., 128
             for i in range(33):
-                mangled_name = "_%s@%d" % (self.name, i*4)
+                mangled_name = "_%s@%d" % (self.name, i * 4)
                 try:
                     return cdll.getfunc(mangled_name,
                                         ffi_argtypes, ffi_restype,
@@ -492,7 +490,7 @@
         for argtype, arg in zip(argtypes, args):
             param = argtype.from_param(arg)
             _type_ = getattr(argtype, '_type_', None)
-            if _type_ == 'P': # special-case for c_void_p
+            if _type_ == 'P':  # special-case for c_void_p
                 param = param._get_buffer_value()
             elif self._is_primitive(argtype):
                 param = param.value
@@ -668,69 +666,11 @@
             self._needs_free = False
 
 
-def make_fastpath_subclass(CFuncPtr):
-    if CFuncPtr._is_fastpath:
-        return CFuncPtr
-    #
-    try:
-        return make_fastpath_subclass.memo[CFuncPtr]
-    except KeyError:
-        pass
-
-    class CFuncPtrFast(CFuncPtr):
-
-        _is_fastpath = True
-        _slowpath_allowed = True # set to False by tests
-
-        @classmethod
-        def enable_fastpath_maybe(cls, obj):
-            if (obj.callable is None and
-                obj._com_index is None):
-                obj.__class__ = cls
-
-        def __rollback(self):
-            assert self._slowpath_allowed
-            self.__class__ = CFuncPtr
-
-        # disable the fast path if we reset argtypes
-        def _setargtypes(self, argtypes):
-            self.__rollback()
-            self._setargtypes(argtypes)
-        argtypes = property(CFuncPtr._getargtypes, _setargtypes)
-
-        def _setcallable(self, func):
-            self.__rollback()
-            self.callable = func
-        callable = property(lambda x: None, _setcallable)
-
-        def _setcom_index(self, idx):
-            self.__rollback()
-            self._com_index = idx
-        _com_index = property(lambda x: None, _setcom_index)
-
-        def __call__(self, *args):
-            thisarg = None
-            argtypes = self._argtypes_
-            restype = self._restype_
-            funcptr = self._getfuncptr(argtypes, restype, thisarg)
-            try:
-                result = self._call_funcptr(funcptr, *args)
-                result, _ = self._do_errcheck(result, args)
-            except (TypeError, ArgumentError, UnicodeDecodeError):
-                assert self._slowpath_allowed
-                return CFuncPtr.__call__(self, *args)
-            return result
-
-    make_fastpath_subclass.memo[CFuncPtr] = CFuncPtrFast
-    return CFuncPtrFast
-make_fastpath_subclass.memo = {}
-
-
 def handle_system_exit(e):
     # issue #1194: if we get SystemExit here, then exit the interpreter.
     # Highly obscure imho but some people seem to depend on it.
     if sys.flags.inspect:
-        return   # Don't exit if -i flag was given.
+        return  # Don't exit if -i flag was given.
     else:
         code = e.code
         if isinstance(code, int):
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -220,9 +220,6 @@
         BoolOption("withsmalllong", "use a version of 'long' in a C long long",
                    default=False),
 
-        BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
-                   default=False),
-
         BoolOption("withspecialisedtuple",
                    "use specialised tuples",
                    default=False),
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
@@ -39,3 +39,20 @@
 
 Internal refactoring of buffers and memoryviews. Memoryviews will now be
 accepted in a few more places, e.g. in compile().
+
+.. branch: sthalik/fix-signed-integer-sizes-1494493539409
+
+.. branch: cpyext-obj-stealing
+
+Redo much of the refcount semantics in PyList_{SG}etItem to closer match
+CPython and ensure the same PyObject stored in the list can be later
+retrieved
+
+.. branch: cpyext-recursionlimit
+
+Implement Py_EnterRecursiveCall and associated functions
+
+.. branch: pypy_ctypes_nosegfault_nofastpath
+
+Remove faulty fastpath from ctypes
+
diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -297,20 +297,19 @@
         except SocketError as e:
             raise converted_error(space, e)
 
-    @unwrap_spec(level=int, optname=int)
-    def getsockopt_w(self, space, level, optname, w_buflen=None):
+    @unwrap_spec(level=int, optname=int, buflen=int)
+    def getsockopt_w(self, space, level, optname, buflen=0):
         """getsockopt(level, option[, buffersize]) -> value
 
         Get a socket option.  See the Unix manual for level and option.
         If a nonzero buffersize argument is given, the return value is a
         string of that length; otherwise it is an integer.
         """
-        if w_buflen is None:
+        if buflen == 0:
             try:
                 return space.newint(self.sock.getsockopt_int(level, optname))
             except SocketError as e:
                 raise converted_error(space, e)
-        buflen = space.int_w(w_buflen)
         return space.newbytes(self.sock.getsockopt(level, optname, buflen))
 
     def gettimeout_w(self, space):
diff --git a/pypy/module/_socket/test/test_sock_app.py 
b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -582,6 +582,19 @@
         (reuse,) = struct.unpack('i', reusestr)
         assert reuse != 0
 
+    def test_getsetsockopt_zero(self):
+        # related to issue #2561: when specifying the buffer size param:
+        # if 0 or None, should return the setted value,
+        # otherwise an empty buffer of the specified size
+        import _socket
+        s = _socket.socket()
+        assert s.getsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 0) == 0
+        assert s.getsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 2) == 
b'\x00\x00'
+        s.setsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, True)
+        assert s.getsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 0) == 1
+        s.setsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 1)
+        assert s.getsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 0) == 1
+
     def test_socket_ioctl(self):
         import _socket, sys
         if sys.platform != 'win32':
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -1557,7 +1557,6 @@
 
 @specialize.memo()
 def make_generic_cpy_call(FT, expect_null):
-    from pypy.module.cpyext.pyobject import make_ref, from_ref
     from pypy.module.cpyext.pyobject import is_pyobj, as_pyobj
     from pypy.module.cpyext.pyobject import get_w_obj_and_decref
     from pypy.module.cpyext.pyerrors import PyErr_Occurred
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -1,6 +1,8 @@
 from pypy.interpreter.error import oefmt
 from pypy.interpreter.astcompiler import consts
 from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.rarithmetic import widen
 from pypy.module.cpyext.api import (
     cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP,
     cpython_struct, is_valid_fp)
@@ -227,4 +229,51 @@
     cf.c_cf_flags = rffi.cast(rffi.INT, flags)
     return result
 
+@cpython_api([], rffi.INT_real, error=CANNOT_FAIL)
+def Py_GetRecursionLimit(space):
+    from pypy.module.sys.vm import getrecursionlimit
+    return space.int_w(getrecursionlimit(space))
 
+@cpython_api([rffi.INT_real], lltype.Void, error=CANNOT_FAIL)
+def Py_SetRecursionLimit(space, limit):
+    from pypy.module.sys.vm import setrecursionlimit
+    setrecursionlimit(space, widen(limit))
+
+limit = 0 # for testing
+
+@cpython_api([rffi.CCHARP], rffi.INT_real, error=1)
+def Py_EnterRecursiveCall(space, where):
+    """Marks a point where a recursive C-level call is about to be performed.
+
+    If USE_STACKCHECK is defined, this function checks if the the OS
+    stack overflowed using PyOS_CheckStack().  In this is the case, it
+    sets a MemoryError and returns a nonzero value.
+
+    The function then checks if the recursion limit is reached.  If this is the
+    case, a RuntimeError is set and a nonzero value is returned.
+    Otherwise, zero is returned.
+
+    where should be a string such as " in instance check" to be
+    concatenated to the RuntimeError message caused by the recursion depth
+    limit."""
+    if not we_are_translated():
+        # XXX hack since the stack checks only work translated
+        global limit
+        limit += 1
+        if limit > 10:
+            raise oefmt(space.w_RuntimeError, 
+                 "maximum recursion depth exceeded%s", rffi.charp2str(where))
+        return 0
+    from rpython.rlib.rstack import stack_almost_full
+    if stack_almost_full():
+        raise oefmt(space.w_RuntimeError,
+                 "maximum recursion depth exceeded%s", rffi.charp2str(where))
+    return 0
+
+@cpython_api([], lltype.Void)
+def Py_LeaveRecursiveCall(space):
+    """Ends a Py_EnterRecursiveCall().  Must be called once for each
+    successful invocation of Py_EnterRecursiveCall()."""
+    # A NOP in PyPy
+    if not we_are_translated():
+        limit = 0
diff --git a/pypy/module/cpyext/include/listobject.h 
b/pypy/module/cpyext/include/listobject.h
--- a/pypy/module/cpyext/include/listobject.h
+++ b/pypy/module/cpyext/include/listobject.h
@@ -1,1 +1,1 @@
-#define PyList_GET_ITEM(o, i) PyList_GetItem((PyObject*)(o), (i))
+/* empty */
diff --git a/pypy/module/cpyext/listobject.py b/pypy/module/cpyext/listobject.py
--- a/pypy/module/cpyext/listobject.py
+++ b/pypy/module/cpyext/listobject.py
@@ -1,9 +1,10 @@
 
+from rpython.rlib.objectmodel import always_inline
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, Py_ssize_t,
                                     build_type_checkers)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
-from pypy.module.cpyext.pyobject import Py_DecRef, PyObject, make_ref
+from pypy.module.cpyext.pyobject import decref, incref, PyObject, make_ref
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.interpreter.error import oefmt
 
@@ -19,59 +20,69 @@
     PySequence_SetItem()  or expose the object to Python code before
     setting all items to a real object with PyList_SetItem().
     """
-    return space.newlist([None] * len)
+    w_list = space.newlist([None] * len)
+    #w_list.convert_to_cpy_strategy(space)
+    return w_list
 
-@cpython_api([rffi.VOIDP, Py_ssize_t, PyObject], PyObject, error=CANNOT_FAIL,
-             result_borrowed=True)
-def PyList_SET_ITEM(space, w_list, index, w_item):
-    """Macro form of PyList_SetItem() without error checking. This is normally
+@always_inline
+def get_list_storage(space, w_list):
+    from pypy.module.cpyext.sequence import CPyListStrategy
+    w_list.convert_to_cpy_strategy(space)
+    return CPyListStrategy.unerase(w_list.lstorage)
+
+@cpython_api([rffi.VOIDP, Py_ssize_t, PyObject], lltype.Void, 
error=CANNOT_FAIL)
+def PyList_SET_ITEM(space, w_list, index, py_item):
+    """Form of PyList_SetItem() without error checking. This is normally
     only used to fill in new lists where there is no previous content.
 
-    This function "steals" a reference to item, and, unlike PyList_SetItem(),
-    does not discard a reference to any item that it being replaced; any
-    reference in list at position i will be leaked.
+    "steals" a reference to item, and, unlike PyList_SetItem(), does not
+    discard a reference to any item that it being replaced; any reference in
+    list at position i will be leaked.
     """
     assert isinstance(w_list, W_ListObject)
+    storage = get_list_storage(space, w_list)
     assert 0 <= index < w_list.length()
-    # Deliberately leak, so that it can be safely decref'd.
-    make_ref(space, w_list.getitem(index))
-    Py_DecRef(space, w_item)
-    w_list.setitem(index, w_item)
-    return w_item
-
+    storage._elems[index] = py_item
 
 @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
-def PyList_SetItem(space, w_list, index, w_item):
+def PyList_SetItem(space, w_list, index, py_item):
     """Set the item at index index in list to item.  Return 0 on success
     or -1 on failure.
-    
+
     This function "steals" a reference to item and discards a reference to
     an item already in the list at the affected position.
     """
-    Py_DecRef(space, w_item)
     if not isinstance(w_list, W_ListObject):
+        decref(space, py_item)
         PyErr_BadInternalCall(space)
     if index < 0 or index >= w_list.length():
+        decref(space, py_item)
         raise oefmt(space.w_IndexError, "list assignment index out of range")
-    w_list.setitem(index, w_item)
+    storage = get_list_storage(space, w_list)
+    py_old = storage._elems[index]
+    storage._elems[index] = py_item
+    decref(w_list.space, py_old)
     return 0
 
-@cpython_api([PyObject, Py_ssize_t], PyObject, result_borrowed=True)
+@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject, result_is_ll=True)
+def PyList_GET_ITEM(space, w_list, index):
+    assert isinstance(w_list, W_ListObject)
+    storage = get_list_storage(space, w_list)
+    assert 0 <= index < w_list.length()
+    return storage._elems[index]     # borrowed ref
+
+@cpython_api([PyObject, Py_ssize_t], PyObject, result_is_ll=True)
 def PyList_GetItem(space, w_list, index):
     """Return the object at position pos in the list pointed to by p.  The
     position must be positive, indexing from the end of the list is not
     supported.  If pos is out of bounds, return NULL and set an
     IndexError exception."""
-    from pypy.module.cpyext.sequence import CPyListStrategy
     if not isinstance(w_list, W_ListObject):
         PyErr_BadInternalCall(space)
     if index < 0 or index >= w_list.length():
         raise oefmt(space.w_IndexError, "list index out of range")
-    cpy_strategy = space.fromcache(CPyListStrategy)
-    if w_list.strategy is not cpy_strategy:
-        w_list.ensure_object_strategy() # make sure we can return a borrowed 
obj
-    w_res = w_list.getitem(index)
-    return w_res     # borrowed ref
+    storage = get_list_storage(space, w_list)
+    return storage._elems[index]     # borrowed ref
 
 
 @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1)
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -30,8 +30,7 @@
         return subtype_dealloc.api_func
 
     def allocate(self, space, w_type, itemcount=0):
-        # similar to PyType_GenericAlloc?
-        # except that it's not related to any pypy object.
+        # typically called from PyType_GenericAlloc via typedescr.allocate
         # this returns a PyObject with ob_refcnt == 1.
 
         pytype = as_pyobj(space, w_type)
@@ -250,6 +249,8 @@
     w_obj = rawrefcount.to_obj(W_Root, pyobj)
     return w_obj is not None and w_obj is not w_marker_deallocating
 
+def w_obj_has_pyobj(w_obj):
+    return bool(rawrefcount.from_obj(PyObject, w_obj))
 
 def is_pyobj(x):
     if x is None or isinstance(x, W_Root):
@@ -275,13 +276,14 @@
     """
     if is_pyobj(obj):
         pyobj = rffi.cast(PyObject, obj)
+        at_least = 1
     else:
         pyobj = as_pyobj(space, obj, w_userdata)
+        at_least = rawrefcount.REFCNT_FROM_PYPY
     if pyobj:
-        assert pyobj.c_ob_refcnt > 0
+        assert pyobj.c_ob_refcnt >= at_least
         pyobj.c_ob_refcnt += 1
-        if not is_pyobj(obj):
-            keepalive_until_here(obj)
+        keepalive_until_here(obj)
     return pyobj
 
 
@@ -315,9 +317,14 @@
         obj = rffi.cast(PyObject, obj)
         if obj:
             assert obj.c_ob_refcnt > 0
+            assert obj.c_ob_pypy_link == 0 or obj.c_ob_refcnt > 
rawrefcount.REFCNT_FROM_PYPY
             obj.c_ob_refcnt -= 1
             if obj.c_ob_refcnt == 0:
                 _Py_Dealloc(space, obj)
+            #else:
+            #    w_obj = rawrefcount.to_obj(W_Root, ref)
+            #    if w_obj is not None:
+            #        assert obj.c_ob_refcnt >= rawrefcount.REFCNT_FROM_PYPY
     else:
         get_w_obj_and_decref(space, obj)
 
diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py
--- a/pypy/module/cpyext/sequence.py
+++ b/pypy/module/cpyext/sequence.py
@@ -256,8 +256,9 @@
     def setitem(self, w_list, index, w_obj):
         storage = self.unerase(w_list.lstorage)
         index = self._check_index(index, storage._length)
-        decref(w_list.space, storage._elems[index])
+        py_old = storage._elems[index]
         storage._elems[index] = make_ref(w_list.space, w_obj)
+        decref(w_list.space, py_old)
 
     def length(self, w_list):
         storage = self.unerase(w_list.lstorage)
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -490,29 +490,6 @@
     0 on success, -1 on failure."""
     raise NotImplementedError
 
-@cpython_api([rffi.CCHARP], rffi.INT_real, error=1)
-def Py_EnterRecursiveCall(space, where):
-    """Marks a point where a recursive C-level call is about to be performed.
-
-    If USE_STACKCHECK is defined, this function checks if the the OS
-    stack overflowed using PyOS_CheckStack().  In this is the case, it
-    sets a MemoryError and returns a nonzero value.
-
-    The function then checks if the recursion limit is reached.  If this is the
-    case, a RuntimeError is set and a nonzero value is returned.
-    Otherwise, zero is returned.
-
-    where should be a string such as " in instance check" to be
-    concatenated to the RuntimeError message caused by the recursion depth
-    limit."""
-    raise NotImplementedError
-
-@cpython_api([], lltype.Void)
-def Py_LeaveRecursiveCall(space):
-    """Ends a Py_EnterRecursiveCall().  Must be called once for each
-    successful invocation of Py_EnterRecursiveCall()."""
-    raise NotImplementedError
-
 @cpython_api([PyFileObject], lltype.Void)
 def PyFile_IncUseCount(space, p):
     """Increments the PyFileObject's internal use count to indicate
diff --git a/pypy/module/cpyext/test/array.c b/pypy/module/cpyext/test/array.c
--- a/pypy/module/cpyext/test/array.c
+++ b/pypy/module/cpyext/test/array.c
@@ -1872,6 +1872,7 @@
             for (nn = 0; nn < n; nn++)
             {
                 v = PyList_GetItem(obj1, nn);
+                Py_INCREF(v);
                 PyList_SetItem(ret, nn+ii*n, v);
             }
         return ret;
@@ -1887,6 +1888,7 @@
             for (nn = 0; nn < n; nn++)
             {
                 v = PyList_GetItem(obj2, nn);
+                Py_INCREF(v);
                 PyList_SetItem(ret, nn+ii*n, v);
             }
         return ret;
diff --git a/pypy/module/cpyext/test/test_eval.py 
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -331,3 +331,30 @@
                 def nested_flags():
                     return module.get_flags()""" in ns
         assert ns['nested_flags']() == (1, 0x2000)  # CO_FUTURE_DIVISION
+
+    def test_recursive_function(self):
+        module = self.import_extension('foo', [
+            ("call_recursive", "METH_NOARGS",
+             """
+                int res = 0;
+                int recurse(void) {
+                    if (Py_EnterRecursiveCall(" while calling recurse"))
+                        return -1;
+                    res ++;
+                    return recurse();
+                }
+                int oldlimit = Py_GetRecursionLimit();
+                Py_SetRecursionLimit(200);
+                res = recurse();
+                Py_SetRecursionLimit(oldlimit);
+                if (PyErr_Occurred())
+                    return NULL;
+                return PyLong_FromLong(res);
+             """),], prologue= ''' int recurse(void); '''
+            )
+        try:
+            res = module.call_recursive()
+        except RuntimeError as e:
+            assert 'while calling recurse' in str(e)
+        else:
+            assert False, "expected RuntimeError"  
diff --git a/pypy/module/cpyext/test/test_listobject.py 
b/pypy/module/cpyext/test/test_listobject.py
--- a/pypy/module/cpyext/test/test_listobject.py
+++ b/pypy/module/cpyext/test/test_listobject.py
@@ -38,11 +38,13 @@
         assert api.PyList_Insert(w_l, 0, space.wrap(1)) == 0
         assert api.PyList_Size(w_l) == 3
         assert api.PyList_Insert(w_l, 99, space.wrap(2)) == 0
-        assert space.unwrap(api.PyList_GetItem(w_l, 3)) == 2
+        assert api.PyObject_Compare(api.PyList_GetItem(w_l, 3),
+                                    space.wrap(2)) == 0
         # insert at index -1: next-to-last
         assert api.PyList_Insert(w_l, -1, space.wrap(3)) == 0
-        assert space.unwrap(api.PyList_GetItem(w_l, 3)) == 3
-    
+        assert api.PyObject_Compare(api.PyList_GET_ITEM(w_l, 3),
+                                    space.wrap(3)) == 0
+
     def test_sort(self, space, api):
         l = space.newlist([space.wrap(1), space.wrap(0), space.wrap(7000)])
         assert api.PyList_Sort(l) == 0
@@ -152,29 +154,35 @@
     def test_list_macros(self):
         """The PyList_* macros cast, and calls expecting that build."""
         module = self.import_extension('foo', [
-            ("test_macro_invocations", "METH_NOARGS",
+            ("test_macro_invocations", "METH_O",
              """
              PyObject* o = PyList_New(2);
              PyListObject* l = (PyListObject*)o;
 
+             Py_INCREF(args);
+             Py_INCREF(args);
+             PyList_SET_ITEM(o, 0, args);
+             PyList_SET_ITEM(l, 1, args);
 
-             Py_INCREF(o);
-             PyList_SET_ITEM(o, 0, o);
-             Py_INCREF(o);
-             PyList_SET_ITEM(l, 1, o);
+             if(PyList_GET_ITEM(o, 0) != PyList_GET_ITEM(l, 1))
+             {
+                PyErr_SetString(PyExc_AssertionError, "PyList_GET_ITEM error");
+                return NULL;
+             }
 
-             PyList_GET_ITEM(o, 0);
-             PyList_GET_ITEM(l, 1);
-
-             PyList_GET_SIZE(o);
-             PyList_GET_SIZE(l);
+             if(PyList_GET_SIZE(o) != PyList_GET_SIZE(l))
+             {
+                PyErr_SetString(PyExc_AssertionError, "PyList_GET_SIZE error");
+                return NULL;
+             }
 
              return o;
              """
             )
         ])
-        x = module.test_macro_invocations()
-        assert x[0] is x[1] is x
+        s = 'abcdef'
+        x = module.test_macro_invocations(s)
+        assert x[0] is x[1] is s
 
     def test_get_item_macro(self):
         module = self.import_extension('foo', [
@@ -183,39 +191,96 @@
                 PyObject* o, *o2, *o3;
                 o = PyList_New(1);
 
-                o2 = PyInt_FromLong(0);
+                o2 = PyBytes_FromString("test_get_item0");
+                Py_INCREF(o2);
                 PyList_SET_ITEM(o, 0, o2);
-                o2 = NULL;
 
                 o3 = PyList_GET_ITEM(o, 0);
                 Py_INCREF(o3);
-                Py_CLEAR(o);
+                Py_DECREF(o);
+                Py_DECREF(o2);
                 return o3;
              """)])
-        assert module.test_get_item() == 0
+        assert module.test_get_item() == b'test_get_item0'
 
-    def test_set_item_macro(self):
+    def test_item_refcounts(self):
         """PyList_SET_ITEM leaks a reference to the target."""
         module = self.import_extension('foo', [
-             ("test_refcount_diff_after_setitem", "METH_NOARGS",
+             ("test_refcount_diff", "METH_VARARGS",
              """
-                PyObject* o = PyList_New(0);
-                PyObject* o2 = PyList_New(0);
-                Py_ssize_t refcount, new_refcount;
+                /* test that the refcount differences for functions
+                 * are correct. diff1 - expected refcount diff for i1,
+                 *              diff2 - expected refcount diff for i2
+                 */
+                #define CHECKCOUNT(diff1, diff2, action) \
+                    new_count1 = Py_REFCNT(i1); \
+                    new_count2 = Py_REFCNT(i2); \
+                    diff = new_count1 - old_count1; \
+                    if (diff != diff1) {\
+                        sprintf(errbuffer, action \
+                            " i1 expected diff of %ld got %ld", (long)diff1, 
(long)diff); \
+                    PyErr_SetString(PyExc_AssertionError, errbuffer); \
+                    return NULL; } \
+                    diff = new_count2 - old_count2; \
+                    if (diff != diff2) {\
+                        sprintf(errbuffer, action \
+                            " i2 expected diff of %ld got %ld", (long)diff2, 
(long)diff); \
+                    PyErr_SetString(PyExc_AssertionError, errbuffer); \
+                    return NULL; } \
+                    old_count1 = new_count1; \
+                    old_count2 = new_count2;
 
-                PyList_Append(o, o2);  // does not steal o2
+                PyObject* tmp, *o = PyList_New(0);
+                char errbuffer[1024];
+                PyObject* i1 = PyTuple_GetItem(args, 0);
+                PyObject* i2 = PyTuple_GetItem(args, 1);
+                Py_ssize_t old_count1, new_count1;
+                Py_ssize_t old_count2, new_count2;
+                Py_ssize_t diff;
+                int ret;
 
-                refcount = Py_REFCNT(o2);
+                old_count1 = Py_REFCNT(i1);
+                old_count2 = Py_REFCNT(i2);
 
-                // Steal a reference to o2, but leak the old reference to o2.
-                // The net result should be no change in refcount.
-                PyList_SET_ITEM(o, 0, o2);
+                ret = PyList_Append(o, i1);
+                if (ret != 0) 
+                    return NULL;
+                /* check the result of Append(), and also force the list
+                   to use the CPyListStrategy now */
+                if (PyList_GET_ITEM(o, 0) != i1)
+                {
+                    PyErr_SetString(PyExc_AssertionError, "Append() error?");
+                    return NULL;
+                }
+                CHECKCOUNT(1, 0, "PyList_Append");
 
-                new_refcount = Py_REFCNT(o2);
+                Py_INCREF(i2);   /* for PyList_SET_ITEM */
+                CHECKCOUNT(0, 1, "Py_INCREF");
 
-                Py_CLEAR(o);
-                Py_DECREF(o2); // append incref'd.
-                // Py_CLEAR(o2);  // naive implementation would fail here.
-                return PyLong_FromSsize_t(new_refcount - refcount);
+                PyList_SET_ITEM(o, 0, i2);
+                CHECKCOUNT(0, 0, "PyList_SET_ITEM");
+
+                tmp = PyList_GET_ITEM(o, 0);
+                if (tmp != i2)
+                {
+                    PyErr_SetString(PyExc_AssertionError, "SetItem() error?");
+                    return NULL;
+                }
+                CHECKCOUNT(0, 0, "PyList_GET_ITEM");
+
+                PyList_SetItem(o, 0, i1);
+                CHECKCOUNT(0, -1, "PyList_Set_Item");
+
+                PyList_GetItem(o, 0);
+                CHECKCOUNT(0, 0, "PyList_Get_Item");
+
+                Py_DECREF(o); 
+                #ifndef PYPY_VERSION
+                {
+                    // PyPy deletes only at teardown
+                    CHECKCOUNT(-1, 0, "Py_DECREF(o)");
+                }
+                #endif
+                return PyLong_FromSsize_t(0);
              """)])
-        assert module.test_refcount_diff_after_setitem() == 0
+        assert module.test_refcount_diff(["first"], ["second"]) == 0
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -24,7 +24,7 @@
     W_PyCMethodObject, W_PyCFunctionObject)
 from pypy.module.cpyext.modsupport import convert_method_defs
 from pypy.module.cpyext.pyobject import (
-    PyObject, make_ref, create_ref, from_ref, get_typedescr, make_typedescr,
+    PyObject, make_ref, from_ref, get_typedescr, make_typedescr,
     track_reference, Py_DecRef, as_pyobj)
 from pypy.module.cpyext.slotdefs import (
     slotdefs_for_tp_slots, slotdefs_for_wrappers, get_slot_tp_function,
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/README 
b/pypy/module/test_lib_pypy/ctypes_tests/README
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/ctypes_tests/README
@@ -0,0 +1,8 @@
+-------Ctypes tests------
+
+Unlike the other tests in the PyPy sources, these tests are assumed to run 
after the translation is complete.
+Therefore, using the resulting binary, you can then call, for example:
+
+/path/to/your_modified_pypy_binary pytest.py 
pypy/module/test_lib_pypy/ctypes_tests/test_libc.py
+
+This also applies to any other test in ctypes_tests.
\ No newline at end of file
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
deleted file mode 100644
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
+++ /dev/null
@@ -1,128 +0,0 @@
-from ctypes import CDLL, POINTER, pointer, c_byte, c_int, c_char_p, CFUNCTYPE, 
c_void_p, c_size_t
-import sys
-import py
-from support import BaseCTypesTestChecker
-
-class MyCDLL(CDLL):
-    def __getattr__(self, attr):
-        fn = self[attr] # this way it's not cached as an attribute
-        fn._slowpath_allowed = False
-        return fn
-
-def setup_module(mod):
-    import conftest
-    _ctypes_test = str(conftest.sofile)
-    mod.dll = MyCDLL(_ctypes_test)  # slowpath not allowed
-    mod.dll2 = CDLL(_ctypes_test)   # slowpath allowed
-
-
-class TestFastpath(BaseCTypesTestChecker):
-
-    def test_fastpath_forbidden(self):
-        def myfunc():
-            pass
-        #
-        tf_b = dll.tf_b
-        tf_b.restype = c_byte
-        #
-        # so far, it's still using the slowpath
-        assert not tf_b._is_fastpath
-        tf_b.callable = myfunc
-        tf_b.argtypes = (c_byte,)
-        # errcheck prevented the fastpath to kick in
-        assert not tf_b._is_fastpath
-        #
-        del tf_b.callable
-        tf_b.argtypes = (c_byte,) # try to re-enable the fastpath
-        assert tf_b._is_fastpath
-        #
-        assert not tf_b._slowpath_allowed
-        py.test.raises(AssertionError, "tf_b.callable = myfunc")
-        py.test.raises(AssertionError, "tf_b('aaa')") # force a TypeError
-
-    def test_simple_args(self):
-        tf_b = dll.tf_b
-        tf_b.restype = c_byte
-        tf_b.argtypes = (c_byte,)
-        assert tf_b(-126) == -42
-
-    def test_from_cfunctype(self):
-        from _ctypes import _memmove_addr
-        functype = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)
-        my_memmove = functype(_memmove_addr)
-        assert my_memmove._is_fastpath
-
-    def test_undeclared_restype(self):
-        # make sure we get a fresh function
-        try:
-            del dll.tf_i
-        except AttributeError:
-            pass
-        tf_i = dll.tf_i
-        assert not tf_i._is_fastpath
-        tf_i.argtypes = (c_int,)
-        assert tf_i._is_fastpath
-        assert tf_i(12) == 4
-
-    def test_pointer_args(self):
-        f = dll._testfunc_p_p
-        f.restype = POINTER(c_int)
-        f.argtypes = [POINTER(c_int)]
-        v = c_int(42)
-        result = f(pointer(v))
-        assert type(result) == POINTER(c_int)
-        assert result.contents.value == 42
-
-    def test_simple_pointer_args(self):
-        f = dll.my_strchr
-        f.argtypes = [c_char_p, c_int]
-        f.restype = c_char_p
-        mystr = c_char_p("abcd")
-        result = f(mystr, ord("b"))
-        assert result == "bcd"
-
-    def test_strings(self):
-        f = dll.my_strchr
-        f.argtypes = [c_char_p, c_int]
-        f.restype = c_char_p
-        result = f("abcd", ord("b"))
-        assert result == "bcd"
-
-    def test_errcheck(self):
-        def errcheck(result, func, args):
-            return 'hello'
-        tf_b = dll.tf_b
-        tf_b.restype = c_byte
-        tf_b.argtypes = (c_byte,)
-        tf_b.errcheck = errcheck
-        assert tf_b(-126) == 'hello'
-
-    def test_array_to_ptr(self):
-        ARRAY = c_int * 8
-        func = dll._testfunc_ai8
-        func.restype = POINTER(c_int)
-        func.argtypes = [ARRAY]
-        array = ARRAY(1, 2, 3, 4, 5, 6, 7, 8)
-        ptr = func(array)
-        assert ptr[0] == 1
-        assert ptr[7] == 8
-
-
-class TestFallbackToSlowpath(BaseCTypesTestChecker):
-
-    def test_argtypes_is_None(self):
-        tf_b = dll2.tf_b
-        tf_b.restype = c_byte
-        tf_b.argtypes = (c_char_p,)  # this is intentionally wrong
-        tf_b.argtypes = None # kill the fast path
-        assert not tf_b._is_fastpath
-        assert tf_b(-126) == -42
-
-    def test_callable_is_None(self):
-        tf_b = dll2.tf_b
-        tf_b.restype = c_byte
-        tf_b.argtypes = (c_byte,)
-        tf_b.callable = lambda x: x+1
-        assert not tf_b._is_fastpath
-        assert tf_b(-126) == -125
-        tf_b.callable = None
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py
@@ -478,7 +478,7 @@
         raises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT()))
 
     def test_argument_conversion_and_checks(self):
-        py.test.skip("XXX currently broken on PyPy, sorry")
+        #This test is designed to check for segfaults if the wrong type of 
argument is passed as parameter
         strlen = dll.my_strchr
         strlen.argtypes = [c_char_p, c_int]
         strlen.restype = c_char_p
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -611,55 +611,31 @@
         return mod_format(space, w_values, self, do_unicode=False)
 
     def descr_eq(self, space, w_other):
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            if isinstance(w_other, W_StringBufferObject):
-                return space.newbool(self._value == w_other.force())
         if not isinstance(w_other, W_BytesObject):
             return space.w_NotImplemented
         return space.newbool(self._value == w_other._value)
 
     def descr_ne(self, space, w_other):
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            if isinstance(w_other, W_StringBufferObject):
-                return space.newbool(self._value != w_other.force())
         if not isinstance(w_other, W_BytesObject):
             return space.w_NotImplemented
         return space.newbool(self._value != w_other._value)
 
     def descr_lt(self, space, w_other):
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            if isinstance(w_other, W_StringBufferObject):
-                return space.newbool(self._value < w_other.force())
         if not isinstance(w_other, W_BytesObject):
             return space.w_NotImplemented
         return space.newbool(self._value < w_other._value)
 
     def descr_le(self, space, w_other):
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            if isinstance(w_other, W_StringBufferObject):
-                return space.newbool(self._value <= w_other.force())
         if not isinstance(w_other, W_BytesObject):
             return space.w_NotImplemented
         return space.newbool(self._value <= w_other._value)
 
     def descr_gt(self, space, w_other):
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            if isinstance(w_other, W_StringBufferObject):
-                return space.newbool(self._value > w_other.force())
         if not isinstance(w_other, W_BytesObject):
             return space.w_NotImplemented
         return space.newbool(self._value > w_other._value)
 
     def descr_ge(self, space, w_other):
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            if isinstance(w_other, W_StringBufferObject):
-                return space.newbool(self._value >= w_other.force())
         if not isinstance(w_other, W_BytesObject):
             return space.w_NotImplemented
         return space.newbool(self._value >= w_other._value)
@@ -677,18 +653,6 @@
             from .bytearrayobject import W_BytearrayObject, _make_data
             self_as_bytearray = W_BytearrayObject(_make_data(self._value))
             return space.add(self_as_bytearray, w_other)
-        if space.config.objspace.std.withstrbuf:
-            from pypy.objspace.std.strbufobject import W_StringBufferObject
-            try:
-                other = self._op_val(space, w_other)
-            except OperationError as e:
-                if e.match(space, space.w_TypeError):
-                    return space.w_NotImplemented
-                raise
-            builder = StringBuilder()
-            builder.append(self._value)
-            builder.append(other)
-            return W_StringBufferObject(builder)
         return self._StringMethods_descr_add(space, w_other)
 
     _StringMethods__startswith = _startswith
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -230,15 +230,13 @@
         return list(items)
 
     def switch_to_object_strategy(self):
+        object_strategy = self.space.fromcache(ObjectListStrategy)
+        if self.strategy is object_strategy:
+            return
         list_w = self.getitems()
-        object_strategy = self.space.fromcache(ObjectListStrategy)
         self.strategy = object_strategy
         object_strategy.init_from_list_w(self, list_w)
 
-    def ensure_object_strategy(self):     # for cpyext
-        if self.strategy is not self.space.fromcache(ObjectListStrategy):
-            self.switch_to_object_strategy()
-
     def _temporarily_as_objects(self):
         if self.strategy is self.space.fromcache(ObjectListStrategy):
             return self
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -16,7 +16,7 @@
 from pypy.objspace.std.boolobject import W_BoolObject
 from pypy.objspace.std.bufferobject import W_Buffer
 from pypy.objspace.std.bytearrayobject import W_BytearrayObject
-from pypy.objspace.std.bytesobject import W_AbstractBytesObject, W_BytesObject
+from pypy.objspace.std.bytesobject import W_BytesObject
 from pypy.objspace.std.complexobject import W_ComplexObject
 from pypy.objspace.std.dictmultiobject import W_DictMultiObject, W_DictObject
 from pypy.objspace.std.floatobject import W_FloatObject
@@ -81,9 +81,6 @@
             W_TypeObject.typedef: W_TypeObject,
             W_UnicodeObject.typedef: W_UnicodeObject,
         }
-        if self.config.objspace.std.withstrbuf:
-            builtin_type_classes[W_BytesObject.typedef] = W_AbstractBytesObject
-
         self.builtin_types = {}
         self._interplevel_classes = {}
         for typedef, cls in builtin_type_classes.items():
@@ -285,7 +282,7 @@
         return W_LongObject.fromint(self, val)
 
     @specialize.argtype(1)
-    def newlong_from_rarith_int(self, val): # val is an rarithmetic type 
+    def newlong_from_rarith_int(self, val): # val is an rarithmetic type
         return W_LongObject.fromrarith_int(val)
 
     def newlong_from_rbigint(self, val):
diff --git a/pypy/objspace/std/strbufobject.py 
b/pypy/objspace/std/strbufobject.py
deleted file mode 100644
--- a/pypy/objspace/std/strbufobject.py
+++ /dev/null
@@ -1,96 +0,0 @@
-import inspect
-
-import py
-
-from pypy.objspace.std.bytesobject import W_AbstractBytesObject, W_BytesObject
-from pypy.interpreter.gateway import interp2app, unwrap_spec
-from pypy.interpreter.buffer import SimpleView, StringBuffer
-from pypy.interpreter.error import OperationError
-from rpython.rlib.rstring import StringBuilder
-
-
-class W_StringBufferObject(W_AbstractBytesObject):
-    w_str = None
-
-    def __init__(self, builder):
-        self.builder = builder             # StringBuilder
-        self.length = builder.getlength()
-
-    def force(self):
-        if self.w_str is None:
-            s = self.builder.build()
-            if self.length < len(s):
-                s = s[:self.length]
-            self.w_str = W_BytesObject(s)
-            return s
-        else:
-            return self.w_str._value
-
-    def __repr__(self):
-        """ representation for debugging purposes """
-        return "%s(%r[:%d])" % (
-            self.__class__.__name__, self.builder, self.length)
-
-    def unwrap(self, space):
-        return self.force()
-
-    def str_w(self, space):
-        return self.force()
-
-    def buffer_w(self, space, flags):
-        return SimpleView(StringBuffer(self.force()))
-
-    def descr_len(self, space):
-        return space.newint(self.length)
-
-    def descr_add(self, space, w_other):
-        try:
-            other = W_BytesObject._op_val(space, w_other)
-        except OperationError as e:
-            if e.match(space, space.w_TypeError):
-                return space.w_NotImplemented
-            raise
-        if self.builder.getlength() != self.length:
-            builder = StringBuilder()
-            builder.append(self.force())
-        else:
-            builder = self.builder
-        builder.append(other)
-        return W_StringBufferObject(builder)
-
-    def descr_str(self, space):
-        # you cannot get subclasses of W_StringBufferObject here
-        assert type(self) is W_StringBufferObject
-        return self
-
-
-delegation_dict = {}
-for key, value in W_BytesObject.typedef.rawdict.iteritems():
-    if not isinstance(value, interp2app):
-        continue
-    if key in ('__len__', '__add__', '__str__'):
-        continue
-
-    func = value._code._bltin
-    args = inspect.getargs(func.func_code)
-    if args.varargs or args.keywords:
-        raise TypeError("Varargs and keywords not supported in unwrap_spec")
-    argspec = ', '.join([arg for arg in args.args[1:]])
-    func_code = py.code.Source("""
-    def f(self, %(args)s):
-        self.force()
-        return self.w_str.%(func_name)s(%(args)s)
-    """ % {'args': argspec, 'func_name': func.func_name})
-    d = {}
-    exec func_code.compile() in d
-    f = d['f']
-    f.func_defaults = func.func_defaults
-    f.__module__ = func.__module__
-    # necessary for unique identifiers for pickling
-    f.func_name = func.func_name
-    unwrap_spec_ = getattr(func, 'unwrap_spec', None)
-    if unwrap_spec_ is not None:
-        f = unwrap_spec(**unwrap_spec_)(f)
-    setattr(W_StringBufferObject, func.func_name, f)
-
-W_StringBufferObject.typedef = W_BytesObject.typedef
diff --git a/pypy/objspace/std/test/test_stdobjspace.py 
b/pypy/objspace/std/test/test_stdobjspace.py
--- a/pypy/objspace/std/test/test_stdobjspace.py
+++ b/pypy/objspace/std/test/test_stdobjspace.py
@@ -57,13 +57,6 @@
         cls = space._get_interplevel_cls(w_sequenceiterator)
         assert cls is W_AbstractSeqIterObject
 
-    def test_withstrbuf_fastpath_isinstance(self):
-        from pypy.objspace.std.bytesobject import W_AbstractBytesObject
-
-        space = gettestobjspace(withstrbuf=True)
-        cls = space._get_interplevel_cls(space.w_bytes)
-        assert cls is W_AbstractBytesObject
-
     def test_wrap_various_unsigned_types(self):
         import sys
         from rpython.rlib.rarithmetic import r_uint
diff --git a/pypy/objspace/std/test/test_strbufobject.py 
b/pypy/objspace/std/test/test_strbufobject.py
deleted file mode 100644
--- a/pypy/objspace/std/test/test_strbufobject.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import py
-
-from pypy.objspace.std.test import test_bytesobject
-
-class AppTestStringObject(test_bytesobject.AppTestBytesObject):
-    spaceconfig = {"objspace.std.withstrbuf": True}
-
-    def test_basic(self):
-        import __pypy__
-        # cannot do "Hello, " + "World!" because cpy2.5 optimises this
-        # away on AST level
-        s = "Hello, ".__add__("World!")
-        assert type(s) is str
-        assert 'W_StringBufferObject' in __pypy__.internal_repr(s)
-
-    def test_add_twice(self):
-        x = "a".__add__("b")
-        y = x + "c"
-        c = x + "d"
-        assert y == "abc"
-        assert c == "abd"
-
-    def test_add(self):
-        import __pypy__
-        all = ""
-        for i in range(20):
-            all += str(i)
-        assert 'W_StringBufferObject' in __pypy__.internal_repr(all)
-        assert all == "012345678910111213141516171819"
-
-    def test_hash(self):
-        import __pypy__
-        def join(s): return s[:len(s) // 2] + s[len(s) // 2:]
-        t = 'a' * 101
-        s = join(t)
-        assert 'W_StringBufferObject' in __pypy__.internal_repr(s)
-        assert hash(s) == hash(t)
-
-    def test_len(self):
-        s = "a".__add__("b")
-        r = "c".__add__("d")
-        t = s + r
-        assert len(s) == 2
-        assert len(r) == 2
-        assert len(t) == 4
-
-    def test_buffer(self):
-        s = b'a'.__add__(b'b')
-        assert buffer(s) == buffer(b'ab')
-        assert memoryview(s) == b'ab'
-
-    def test_add_strbuf(self):
-        # make three strbuf objects
-        s = 'a'.__add__('b')
-        t = 'x'.__add__('c')
-        u = 'y'.__add__('d')
-
-        # add two different strbufs to the same string
-        v = s + t
-        w = s + u
-
-        # check that insanity hasn't resulted.
-        assert v == "abxc"
-        assert w == "abyd"
-
-    def test_more_adding_fun(self):
-        s = 'a'.__add__('b') # s is a strbuf now
-        t = s + 'c'
-        u = s + 'd'
-        v = s + 'e'
-        assert v == 'abe'
-        assert u == 'abd'
-        assert t == 'abc'
-
-    def test_buh_even_more(self):
-        a = 'a'.__add__('b')
-        b = a + 'c'
-        c = '0'.__add__('1')
-        x = c + a
-        assert x == '01ab'
-
-    def test_add_non_string(self):
-        a = 'a'
-        a += 'b'
-        raises(TypeError, "a += 5")
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -514,13 +514,13 @@
     ne = eq
 
     def lt((tup1, tup2)):
-        raise Exception("unsupported: (...) < (...)")
+        raise AnnotatorError("unsupported: (...) < (...)")
     def le((tup1, tup2)):
-        raise Exception("unsupported: (...) <= (...)")
+        raise AnnotatorError("unsupported: (...) <= (...)")
     def gt((tup1, tup2)):
-        raise Exception("unsupported: (...) > (...)")
+        raise AnnotatorError("unsupported: (...) > (...)")
     def ge((tup1, tup2)):
-        raise Exception("unsupported: (...) >= (...)")
+        raise AnnotatorError("unsupported: (...) >= (...)")
 
 
 class __extend__(pairtype(SomeDict, SomeDict)):
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -15,7 +15,8 @@
     SomeDict, SomeBuiltin, SomePBC, SomeInteger, TLS, SomeUnicodeCodePoint,
     s_None, s_ImpossibleValue, SomeBool, SomeTuple, SomeException,
     SomeImpossibleValue, SomeUnicodeString, SomeList, HarmlesslyBlocked,
-    SomeWeakRef, SomeByteArray, SomeConstantType, SomeProperty)
+    SomeWeakRef, SomeByteArray, SomeConstantType, SomeProperty,
+    AnnotatorError)
 from rpython.annotator.classdesc import ClassDef, ClassDesc
 from rpython.annotator.listdef import ListDef, ListItem
 from rpython.annotator.dictdef import DictDef
@@ -343,7 +344,7 @@
         elif x is None:
             return s_None
         else:
-            raise Exception("Don't know how to represent %r" % (x,))
+            raise AnnotatorError("Don't know how to represent %r" % (x,))
         result.const = x
         return result
 
@@ -363,7 +364,7 @@
                 result = self.newfuncdesc(pyobj)
             elif isinstance(pyobj, (type, types.ClassType)):
                 if pyobj is object:
-                    raise Exception("ClassDesc for object not supported")
+                    raise AnnotatorError("ClassDesc for object not supported")
                 if pyobj.__module__ == '__builtin__': # avoid making classdefs 
for builtin types
                     result = self.getfrozen(pyobj)
                 else:
@@ -400,7 +401,7 @@
                         msg = "object with a __call__ is not RPython"
                     else:
                         msg = "unexpected prebuilt constant"
-                    raise Exception("%s: %r" % (msg, pyobj))
+                    raise AnnotatorError("%s: %r" % (msg, pyobj))
                 result = self.getfrozen(pyobj)
             self.descs[obj_key] = result
             return result
@@ -589,7 +590,7 @@
         for name, value in dict.iteritems():
             if value is func:
                 return cls, name
-    raise Exception("could not match bound-method to attribute name: %r" % 
(boundmeth,))
+    raise AnnotatorError("could not match bound-method to attribute name: %r" 
% (boundmeth,))
 
 def ishashable(x):
     try:
diff --git a/rpython/annotator/classdesc.py b/rpython/annotator/classdesc.py
--- a/rpython/annotator/classdesc.py
+++ b/rpython/annotator/classdesc.py
@@ -550,8 +550,8 @@
                                         "with _mixin_: %r" % (cls,))
                 base = b1
         if mixins_before and mixins_after:
-            raise Exception("unsupported: class %r has mixin bases both"
-                            " before and after the regular base" % (self,))
+            raise AnnotatorError("unsupported: class %r has mixin bases both"
+                                 " before and after the regular base" % 
(self,))
         self.add_mixins(mixins_after, check_not_in=base)
         self.add_mixins(mixins_before)
         self.add_sources_for_class(cls)
@@ -569,8 +569,8 @@
                 attrs.update(decl)
             if self.basedesc is not None:
                 if self.basedesc.all_enforced_attrs is None:
-                    raise Exception("%r has slots or _attrs_, "
-                                    "but not its base class" % (cls,))
+                    raise AnnotatorError("%r has slots or _attrs_, "
+                                         "but not its base class" % (cls,))
                 attrs.update(self.basedesc.all_enforced_attrs)
             self.all_enforced_attrs = attrs
 
@@ -714,8 +714,8 @@
                 try:
                     args.fixedunpack(0)
                 except ValueError:
-                    raise Exception("default __init__ takes no argument"
-                                    " (class %s)" % (self.name,))
+                    raise AnnotatorError("default __init__ takes no argument"
+                                         " (class %s)" % (self.name,))
             elif self.pyobj is Exception:
                 # check explicitly against "raise Exception, x" where x
                 # is a low-level exception pointer
@@ -824,8 +824,8 @@
         # actual copy in the rtyper). Tested in rpython.rtyper.test.test_rlist,
         # test_immutable_list_out_of_instance.
         if self._detect_invalid_attrs and attr in self._detect_invalid_attrs:
-            raise Exception("field %r was migrated to %r from a subclass in "
-                            "which it was declared as _immutable_fields_" %
+            raise AnnotatorError("field %r was migrated to %r from a subclass 
in "
+                                 "which it was declared as _immutable_fields_" 
%
                             (attr, self.pyobj))
         search1 = '%s[*]' % (attr,)
         search2 = '%s?[*]' % (attr,)
@@ -858,7 +858,7 @@
             # call to a single class, look at the result annotation
             # in case it was specialized
             if not isinstance(s_result, SomeInstance):
-                raise Exception("calling a class didn't return an instance??")
+                raise AnnotatorError("calling a class didn't return an 
instance??")
             classdefs = [s_result.classdef]
         else:
             # call to multiple classes: specialization not supported
diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py
--- a/rpython/annotator/description.py
+++ b/rpython/annotator/description.py
@@ -314,8 +314,8 @@
         enforceargs = getattr(self.pyobj, '_annenforceargs_', None)
         signature = getattr(self.pyobj, '_signature_', None)
         if enforceargs and signature:
-            raise Exception("%r: signature and enforceargs cannot both be "
-                            "used" % (self,))
+            raise AnnotatorError("%r: signature and enforceargs cannot both be 
"
+                                 "used" % (self,))
         if enforceargs:
             if not callable(enforceargs):
                 from rpython.annotator.signature import Sig
@@ -432,7 +432,7 @@
     def func_args(self, args):
         from rpython.annotator.model import SomeInstance
         if self.selfclassdef is None:
-            raise Exception("calling %r" % (self,))
+            raise AnnotatorError("calling %r" % (self,))
         s_instance = SomeInstance(self.selfclassdef, flags=self.flags)
         return args.prepend(s_instance)
 
diff --git a/rpython/annotator/test/test_annrpython.py 
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -4584,7 +4584,7 @@
             return Ellipsis
         a = self.RPythonAnnotator()
         e = py.test.raises(Exception, a.build_types, f, [])
-        assert str(e.value) == "Don't know how to represent Ellipsis"
+        assert "Don't know how to represent Ellipsis" in str(e.value)
 
     def test_must_be_light_finalizer(self):
         from rpython.rlib import rgc
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -185,8 +185,8 @@
         return SomeString()
 
     def id(self):
-        raise Exception("cannot use id() in RPython; "
-                        "see objectmodel.compute_xxx()")
+        raise AnnotatorError("cannot use id() in RPython; "
+                             "see objectmodel.compute_xxx()")
 
     def int(self):
         return SomeInteger()
@@ -421,7 +421,7 @@
     def setslice(self, s_start, s_stop, s_iterable):
         check_negative_slice(s_start, s_stop)
         if not isinstance(s_iterable, SomeList):
-            raise Exception("list[start:stop] = x: x must be a list")
+            raise AnnotatorError("list[start:stop] = x: x must be a list")
         self.listdef.mutate()
         self.listdef.agree(getbookkeeper(), s_iterable.listdef)
         self.listdef.resize()
diff --git a/rpython/translator/platform/openbsd.py 
b/rpython/translator/platform/openbsd.py
--- a/rpython/translator/platform/openbsd.py
+++ b/rpython/translator/platform/openbsd.py
@@ -16,5 +16,14 @@
         libraries=set(libraries + ("intl", "iconv"))
         return ['-l%s' % lib for lib in libraries if lib not in ["crypt", 
"dl", "rt"]]
 
+    def makefile_link_flags(self):
+        # On OpenBSD, we need to build the final binary with the link flags
+        # below. However, if we modify self.link_flags to include these, the
+        # various platform check binaries that RPython builds end up with these
+        # flags: since these binaries are generally located on /tmp -- which
+        # isn't a wxallowed file system -- that gives rise to "permission
+        # denied" errors, which kill the build.
+        return list(self.link_flags) + ["-Wl,-z,wxneeded"]
+
 class OpenBSD_64(OpenBSD):
     shared_only = ('-fPIC',)
diff --git a/rpython/translator/platform/posix.py 
b/rpython/translator/platform/posix.py
--- a/rpython/translator/platform/posix.py
+++ b/rpython/translator/platform/posix.py
@@ -98,6 +98,9 @@
     def get_shared_only_compile_flags(self):
         return tuple(self.shared_only) + ('-fvisibility=hidden',)
 
+    def makefile_link_flags(self):
+        return list(self.link_flags)
+
     def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                      shared=False, headers_to_precompile=[],
                      no_precompile_cfiles = [], config=None):
@@ -113,7 +116,7 @@
         else:
             exe_name = exe_name.new(ext=self.exe_ext)
 
-        linkflags = list(self.link_flags)
+        linkflags = self.makefile_link_flags()
         if shared:
             linkflags = self._args_for_shared(linkflags)
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to