[pypy-svn] r74392 - in pypy/trunk/pypy/module/cpyext: . test

afa at codespeak.net afa at codespeak.net
Thu May 6 01:09:24 CEST 2010


Author: afa
Date: Thu May  6 01:09:22 2010
New Revision: 74392

Modified:
   pypy/trunk/pypy/module/cpyext/api.py
   pypy/trunk/pypy/module/cpyext/dictobject.py
   pypy/trunk/pypy/module/cpyext/funcobject.py
   pypy/trunk/pypy/module/cpyext/listobject.py
   pypy/trunk/pypy/module/cpyext/modsupport.py
   pypy/trunk/pypy/module/cpyext/object.py
   pypy/trunk/pypy/module/cpyext/pyerrors.py
   pypy/trunk/pypy/module/cpyext/pyobject.py
   pypy/trunk/pypy/module/cpyext/sequence.py
   pypy/trunk/pypy/module/cpyext/state.py
   pypy/trunk/pypy/module/cpyext/sysmodule.py
   pypy/trunk/pypy/module/cpyext/test/test_borrow.py
   pypy/trunk/pypy/module/cpyext/tupleobject.py
   pypy/trunk/pypy/module/cpyext/weakrefobject.py
Log:
Start to refactor the "borrowed references" system:
now functions may return a BorrowedPair that ties the container with the returned object
the idiom is now:
"return borrow_from(w_container, w_obj)"

'borrowed=True' disappears from the api signatures,
state.last_container is gone.

Let's see if this translates...


Modified: pypy/trunk/pypy/module/cpyext/api.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/api.py	(original)
+++ pypy/trunk/pypy/module/cpyext/api.py	Thu May  6 01:09:22 2010
@@ -104,13 +104,11 @@
 #
 
 class ApiFunction:
-    def __init__(self, argtypes, restype, callable,
-                 borrowed=False, error=_NOT_SPECIFIED):
+    def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED):
         self.argtypes = argtypes
         self.restype = restype
         self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
         self.callable = callable
-        self.borrowed = borrowed
         if error is not _NOT_SPECIFIED:
             self.error_value = error
 
@@ -141,7 +139,7 @@
             wrapper.relax_sig_check = True
         return wrapper
 
-def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED,
+def cpython_api(argtypes, restype, error=_NOT_SPECIFIED,
                 external=True, name=None):
     if error is _NOT_SPECIFIED:
         if restype is PyObject:
@@ -157,7 +155,7 @@
         else:
             func_name = name
             func = func_with_new_name(func, name)
-        api_function = ApiFunction(argtypes, restype, func, borrowed, error)
+        api_function = ApiFunction(argtypes, restype, func, error)
         func.api_func = api_function
 
         assert func_name not in FUNCTIONS
@@ -176,6 +174,7 @@
             def unwrapper(space, *args):
                 from pypy.module.cpyext.pyobject import Py_DecRef
                 from pypy.module.cpyext.pyobject import make_ref, from_ref
+                from pypy.module.cpyext.pyobject import BorrowedPair
                 newargs = ()
                 to_decref = []
                 assert len(args) == len(api_function.argtypes)
@@ -204,7 +203,7 @@
                     newargs += (arg, )
                 try:
                     try:
-                        return func(space, *newargs)
+                        res = func(space, *newargs)
                     except OperationError, e:
                         if not catch_exception:
                             raise
@@ -216,10 +215,11 @@
                             return None
                         else:
                             return api_function.error_value
+                    if isinstance(res, BorrowedPair):
+                        return res.w_borrowed
+                    else:
+                        return res
                 finally:
-                    if api_function.borrowed:
-                        state = space.fromcache(State)
-                        state.last_container = 0
                     for arg in to_decref:
                         Py_DecRef(space, arg)
             unwrapper.func = func
@@ -398,7 +398,7 @@
     @specialize.ll()
     def wrapper(*args):
         from pypy.module.cpyext.pyobject import make_ref, from_ref
-        from pypy.module.cpyext.pyobject import add_borrowed_object
+        from pypy.module.cpyext.pyobject import BorrowedPair
         from pypy.module.cpyext.pyobject import NullPointerException
         # we hope that malloc removal removes the newtuple() that is
         # inserted exactly here by the varargs specializer
@@ -446,13 +446,12 @@
                 retval = error_value
 
             elif callable.api_func.restype is PyObject:
-                borrowed = callable.api_func.borrowed
-                if not rffi._isllptr(result):
-                    retval = make_ref(space, result, borrowed=borrowed)
+                if isinstance(result, BorrowedPair):
+                    retval = result.get_ref(space)
+                elif not rffi._isllptr(result):
+                    retval = make_ref(space, result)
                 else:
                     retval = result
-                if borrowed:
-                    add_borrowed_object(space, retval)
             elif callable.api_func.restype is not lltype.Void:
                 retval = rffi.cast(callable.api_func.restype, result)
         except NullPointerException:

Modified: pypy/trunk/pypy/module/cpyext/dictobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/dictobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/dictobject.py	Thu May  6 01:09:22 2010
@@ -1,7 +1,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, build_type_checkers,\
         Py_ssize_t, PyObjectP, CONST_STRING
-from pypy.module.cpyext.pyobject import PyObject, register_container
+from pypy.module.cpyext.pyobject import PyObject, borrow_from
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.interpreter.error import OperationError
 
@@ -11,14 +11,13 @@
 
 PyDict_Check, PyDict_CheckExact = build_type_checkers("Dict")
 
- at cpython_api([PyObject, PyObject], PyObject, borrowed=True, error=CANNOT_FAIL)
+ at cpython_api([PyObject, PyObject], PyObject, error=CANNOT_FAIL)
 def PyDict_GetItem(space, w_dict, w_key):
     try:
         w_res = space.getitem(w_dict, w_key)
     except:
         return None
-    register_container(space, w_dict)
-    return w_res
+    return borrow_from(w_dict, w_res)
 
 @cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
 def PyDict_SetItem(space, w_dict, w_key, w_obj):
@@ -47,7 +46,7 @@
     else:
         PyErr_BadInternalCall(space)
 
- at cpython_api([PyObject, CONST_STRING], PyObject, borrowed=True, error=CANNOT_FAIL)
+ at cpython_api([PyObject, CONST_STRING], PyObject, error=CANNOT_FAIL)
 def PyDict_GetItemString(space, w_dict, key):
     """This is the same as PyDict_GetItem(), but key is specified as a
     char*, rather than a PyObject*."""
@@ -57,8 +56,7 @@
         w_res = None
     if w_res is None:
         return None
-    register_container(space, w_dict)
-    return w_res
+    return borrow_from(w_dict, w_res)
 
 @cpython_api([PyObject], Py_ssize_t, error=-1)
 def PyDict_Size(space, w_obj):

Modified: pypy/trunk/pypy/module/cpyext/funcobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/funcobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/funcobject.py	Thu May  6 01:09:22 2010
@@ -3,7 +3,7 @@
     PyObjectFields, generic_cpy_call,
     cpython_api, bootstrap_function, cpython_struct, build_type_checkers)
 from pypy.module.cpyext.pyobject import (
-    PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, register_container)
+    PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, borrow_from)
 from pypy.interpreter.function import Function, Method
 
 PyFunctionObjectStruct = lltype.ForwardReference()
@@ -43,18 +43,16 @@
     class which provides the unbound method."""
     return Method(space, w_func, w_self, w_cls)
 
- at cpython_api([PyObject], PyObject, borrowed=True)
+ at cpython_api([PyObject], PyObject)
 def PyMethod_Function(space, w_method):
     """Return the function object associated with the method meth."""
     assert isinstance(w_method, Method)
-    register_container(space, w_method)
-    return w_method.w_function
+    return borrow_from(w_method, w_method.w_function)
 
- at cpython_api([PyObject], PyObject, borrowed=True)
+ at cpython_api([PyObject], PyObject)
 def PyMethod_Class(space, w_method):
     """Return the class object from which the method meth was created; if this was
     created from an instance, it will be the class of the instance."""
     assert isinstance(w_method, Method)
-    register_container(space, w_method)
-    return w_method.w_class
+    return borrow_from(w_method, w_method.w_class)
 

Modified: pypy/trunk/pypy/module/cpyext/listobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/listobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/listobject.py	Thu May  6 01:09:22 2010
@@ -3,7 +3,7 @@
 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, register_container
+from pypy.module.cpyext.pyobject import Py_DecRef, PyObject, borrow_from
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.interpreter.error import OperationError
 
@@ -39,20 +39,19 @@
     wrappeditems[index] = w_item
     return 0
 
- at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True)
+ at cpython_api([PyObject, Py_ssize_t], PyObject)
 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."""
-    register_container(space, w_list)
     if not isinstance(w_list, W_ListObject):
         PyErr_BadInternalCall(space)
     wrappeditems = w_list.wrappeditems
     if index < 0 or index >= len(wrappeditems):
         raise OperationError(space.w_IndexError, space.wrap(
             "list index out of range"))
-    return wrappeditems[index]
+    return borrow_from(w_list, wrappeditems[index])
 
 
 @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1)

Modified: pypy/trunk/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/modsupport.py	(original)
+++ pypy/trunk/pypy/module/cpyext/modsupport.py	Thu May  6 01:09:22 2010
@@ -1,14 +1,14 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import cpython_api, cpython_struct, \
         METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, CONST_STRING
-from pypy.module.cpyext.pyobject import PyObject, register_container
+from pypy.module.cpyext.pyobject import PyObject, borrow_from
 from pypy.interpreter.module import Module
 from pypy.module.cpyext.methodobject import W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod, PyMethodDef, PyCFunction
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.module.cpyext.state import State
 from pypy.interpreter.error import OperationError
 
-#@cpython_api([rffi.CCHARP], PyObject, borrowed=True)
+#@cpython_api([rffi.CCHARP], PyObject)
 def PyImport_AddModule(space, name):
     """Return the module object corresponding to a module name.  The name argument
     may be of the form package.module. First check the modules dictionary if
@@ -30,7 +30,7 @@
     return w_mod
 
 @cpython_api([CONST_STRING, lltype.Ptr(PyMethodDef), CONST_STRING,
-              PyObject, rffi.INT_real], PyObject, borrowed=False) # we cannot borrow here
+              PyObject, rffi.INT_real], PyObject)
 def Py_InitModule4(space, name, methods, doc, w_self, apiver):
     """
     Create a new module object based on a name and table of functions, returning
@@ -58,6 +58,7 @@
     if doc:
         space.setattr(w_mod, space.wrap("__doc__"),
                       space.wrap(rffi.charp2str(doc)))
+    # we cannot borrow here
     return w_mod
 
 
@@ -108,13 +109,12 @@
     return int(space.is_w(w_type, w_obj_type) or
                space.is_true(space.issubtype(w_obj_type, w_type)))
 
- at cpython_api([PyObject], PyObject, borrowed=True)
+ at cpython_api([PyObject], PyObject)
 def PyModule_GetDict(space, w_mod):
     if PyModule_Check(space, w_mod):
         assert isinstance(w_mod, Module)
         w_dict = w_mod.getdict()
-        register_container(space, w_mod)
-        return w_dict
+        return borrow_from(w_mod, w_dict)
     else:
         PyErr_BadInternalCall(space)
 

Modified: pypy/trunk/pypy/module/cpyext/object.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/object.py	(original)
+++ pypy/trunk/pypy/module/cpyext/object.py	Thu May  6 01:09:22 2010
@@ -144,7 +144,7 @@
     This is the equivalent of the Python expression o[key]."""
     return space.getitem(w_obj, w_key)
 
- at cpython_api([PyObject, PyTypeObjectPtr], PyObject, borrowed=True)
+ at cpython_api([PyObject, PyTypeObjectPtr], PyObject)
 def PyObject_Init(space, op, type):
     """Initialize a newly-allocated object op with its type and initial
     reference.  Returns the initialized object.  If type indicates that the
@@ -157,7 +157,7 @@
     op.c_ob_refcnt = 1
     return from_ref(space, op) # XXX will give an exception
 
- at cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject, borrowed=True)
+ at cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject)
 def PyObject_InitVar(space, op, type, size):
     """This does everything PyObject_Init() does, and also initializes the
     length information for a variable-size object."""

Modified: pypy/trunk/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/pyerrors.py	(original)
+++ pypy/trunk/pypy/module/cpyext/pyerrors.py	Thu May  6 01:09:22 2010
@@ -5,7 +5,7 @@
 from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, CONST_STRING
 from pypy.module.exceptions.interp_exceptions import W_RuntimeWarning
 from pypy.module.cpyext.pyobject import (
-    PyObject, PyObjectP, make_ref, Py_DecRef, register_container)
+    PyObject, PyObjectP, make_ref, Py_DecRef, borrow_from)
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.import_ import PyImport_Import
 from pypy.rlib.rposix import get_errno
@@ -27,13 +27,12 @@
     """This is a shorthand for PyErr_SetObject(type, Py_None)."""
     PyErr_SetObject(space, w_type, space.w_None)
 
- at cpython_api([], PyObject, borrowed=True)
+ at cpython_api([], PyObject)
 def PyErr_Occurred(space):
     state = space.fromcache(State)
     if state.operror is None:
         return None
-    register_container(space, lltype.nullptr(PyObject.TO))
-    return state.operror.w_type
+    return borrow_from(None, state.operror.w_type)
 
 @cpython_api([], lltype.Void)
 def PyErr_Clear(space):

Modified: pypy/trunk/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/pyobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/pyobject.py	Thu May  6 01:09:22 2010
@@ -319,29 +319,28 @@
 #___________________________________________________________
 # Support for borrowed references
 
- at cpython_api([PyObject], lltype.Void, external=False)
-def register_container(space, container):
-    state = space.fromcache(State)
-    if not container: # self-managed
-        container_ptr = -1
-    else:
+class BorrowedPair:
+    def __init__(self, w_container, w_borrowed):
+        self.w_borrowed = w_borrowed
+        self.w_container = w_container
+
+    def get_ref(self, space):
+        if self.w_borrowed is None:
+            return lltype.nullptr(PyObject.TO)
+        state = space.fromcache(State)
+        container = make_ref(space, self.w_container)
+        Py_DecRef(space, container)
         container_ptr = rffi.cast(ADDR, container)
-    assert not state.last_container, "Last container was not fetched"
-    state.last_container = container_ptr
+        ref = make_ref(space, self.w_borrowed, borrowed=True)
+        if self.w_container is None: # self-managed
+            return ref
+        obj_ptr = rffi.cast(ADDR, ref)
+        borrowees = state.borrow_mapping.setdefault(container_ptr, {})
+        borrowees[obj_ptr] = None
+        return ref
 
-def add_borrowed_object(space, obj):
-    state = space.fromcache(State)
-    container_ptr = state.last_container
-    state.last_container = 0
-    if not obj:
-        return
-    if not container_ptr:
-        raise NullPointerException
-    if container_ptr == -1:
-        return
-    obj_ptr = rffi.cast(ADDR, obj)
-    borrowees = state.borrow_mapping.setdefault(container_ptr, {})
-    borrowees[obj_ptr] = None
+def borrow_from(container, borrowed):
+    return BorrowedPair(container, borrowed)
 
 #___________________________________________________________
 

Modified: pypy/trunk/pypy/module/cpyext/sequence.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/sequence.py	(original)
+++ pypy/trunk/pypy/module/cpyext/sequence.py	Thu May  6 01:09:22 2010
@@ -2,7 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.api import (
     cpython_api, CANNOT_FAIL, CONST_STRING, Py_ssize_t)
-from pypy.module.cpyext.pyobject import PyObject, register_container
+from pypy.module.cpyext.pyobject import PyObject, borrow_from
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.objspace.std import listobject, tupleobject
 
@@ -40,7 +40,7 @@
     except OperationError:
         raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m)))
 
- at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True)
+ at cpython_api([PyObject, Py_ssize_t], PyObject)
 def PySequence_Fast_GET_ITEM(space, w_obj, index):
     """Return the ith element of o, assuming that o was returned by
     PySequence_Fast(), o is not NULL, and that i is within bounds.
@@ -50,8 +50,7 @@
     else:
         assert isinstance(w_obj, tupleobject.W_TupleObject)
         w_res = w_obj.wrappeditems[index]
-    register_container(space, w_obj)
-    return w_res
+    return borrow_from(w_obj, w_res)
 
 @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
 def PySequence_Fast_GET_SIZE(space, w_obj):

Modified: pypy/trunk/pypy/module/cpyext/state.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/state.py	(original)
+++ pypy/trunk/pypy/module/cpyext/state.py	Thu May  6 01:09:22 2010
@@ -17,7 +17,6 @@
         self.borrow_mapping = {} # { addr of container -> { addr of containee -> None } }
         self.borrowed_objects = {} # { addr of containee -> None }
         self.non_heaptypes = [] # list of wrapped objects
-        self.last_container = 0 # addr of last container
         self.operror = None
         self.new_method_def = lltype.nullptr(PyMethodDef)
 

Modified: pypy/trunk/pypy/module/cpyext/sysmodule.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/sysmodule.py	(original)
+++ pypy/trunk/pypy/module/cpyext/sysmodule.py	Thu May  6 01:09:22 2010
@@ -1,17 +1,16 @@
 from pypy.interpreter.error import OperationError
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import CANNOT_FAIL, cpython_api, CONST_STRING
-from pypy.module.cpyext.pyobject import PyObject, register_container
+from pypy.module.cpyext.pyobject import PyObject, borrow_from
 
- at cpython_api([CONST_STRING], PyObject, borrowed=True, error=CANNOT_FAIL)
+ at cpython_api([CONST_STRING], PyObject, error=CANNOT_FAIL)
 def PySys_GetObject(space, name):
     """Return the object name from the sys module or NULL if it does
     not exist, without setting an exception."""
     name = rffi.charp2str(name)
     w_dict = space.sys.getdict()
     w_obj = space.finditem_str(w_dict, name)
-    register_container(space, w_dict)
-    return w_obj
+    return borrow_from(w_dict, w_obj)
 
 @cpython_api([CONST_STRING, PyObject], rffi.INT_real, error=-1)
 def PySys_SetObject(space, name, w_obj):

Modified: pypy/trunk/pypy/module/cpyext/test/test_borrow.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_borrow.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_borrow.py	Thu May  6 01:09:22 2010
@@ -2,7 +2,7 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.state import State
-from pypy.module.cpyext.pyobject import make_ref, add_borrowed_object
+from pypy.module.cpyext.pyobject import make_ref, borrow_from
 
 
 class TestBorrowing(BaseApiTest):
@@ -11,9 +11,7 @@
         w_int = space.wrap(1)
         w_tuple = space.newtuple([w_int])
         api.Py_IncRef(w_tuple)
-        api.register_container(w_tuple)
-        one_pyo = make_ref(space, w_int, borrowed=True)
-        add_borrowed_object(space, one_pyo)
+        one_pyo = borrow_from(w_tuple, w_int).get_ref(space)
         print state.borrowed_objects
         api.Py_DecRef(w_tuple)
         state.print_refcounts()

Modified: pypy/trunk/pypy/module/cpyext/tupleobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/tupleobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/tupleobject.py	Thu May  6 01:09:22 2010
@@ -2,7 +2,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL,
                                     build_type_checkers)
-from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, register_container
+from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, borrow_from
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.objspace.std.tupleobject import W_TupleObject
 
@@ -23,14 +23,13 @@
     Py_DecRef(space, w_obj) # SetItem steals a reference!
     return 0
 
- at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True)
+ at cpython_api([PyObject, Py_ssize_t], PyObject)
 def PyTuple_GetItem(space, w_t, pos):
     if not PyTuple_Check(space, w_t):
         PyErr_BadInternalCall(space)
     assert isinstance(w_t, W_TupleObject)
     w_obj = w_t.wrappeditems[pos]
-    register_container(space, w_t)
-    return w_obj
+    return borrow_from(w_t, w_obj)
 
 @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
 def PyTuple_GET_SIZE(space, w_t):

Modified: pypy/trunk/pypy/module/cpyext/weakrefobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/weakrefobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/weakrefobject.py	Thu May  6 01:09:22 2010
@@ -1,5 +1,5 @@
 from pypy.module.cpyext.api import cpython_api
-from pypy.module.cpyext.pyobject import PyObject, register_container
+from pypy.module.cpyext.pyobject import PyObject, borrow_from
 from pypy.module._weakref.interp__weakref import W_Weakref
 
 @cpython_api([PyObject, PyObject], PyObject)
@@ -16,13 +16,12 @@
     w_weakref = space.gettypeobject(W_Weakref.typedef)
     return space.call_function(w_weakref, w_obj, w_callback)
 
- at cpython_api([PyObject], PyObject, borrowed=True)
+ at cpython_api([PyObject], PyObject)
 def PyWeakref_GetObject(space, w_ref):
     """Return the referenced object from a weak reference.  If the referent is
     no longer live, returns None. This function returns a borrowed reference.
     """
-    register_container(space, w_ref)
-    return space.call_function(w_ref)
+    return borrow_from(w_ref, space.call_function(w_ref))
 
 @cpython_api([PyObject], PyObject)
 def PyWeakref_LockObject(space, w_ref):



More information about the Pypy-commit mailing list