[pypy-commit] pypy default: PyWeakref_Check*() variants

arigo pypy.commits at gmail.com
Thu Dec 15 08:16:04 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r89065:04c5ad075bde
Date: 2016-12-15 14:15 +0100
http://bitbucket.org/pypy/pypy/changeset/04c5ad075bde/

Log:	PyWeakref_Check*() variants

diff --git a/pypy/module/cpyext/test/test_weakref.py b/pypy/module/cpyext/test/test_weakref.py
--- a/pypy/module/cpyext/test/test_weakref.py
+++ b/pypy/module/cpyext/test/test_weakref.py
@@ -56,3 +56,30 @@
             )
         ])
         module.test_macro_cast()
+
+    def test_weakref_check(self):
+        module = self.import_extension('foo', [
+            ("test_weakref_cast", "METH_O",
+             """
+             return Py_BuildValue("iiii",
+                                  (int)PyWeakref_Check(args),
+                                  (int)PyWeakref_CheckRef(args),
+                                  (int)PyWeakref_CheckRefExact(args),
+                                  (int)PyWeakref_CheckProxy(args));
+             """
+            )
+        ])
+        import weakref
+        def foo(): pass
+        class Bar(object):
+            pass
+        bar = Bar()
+        assert module.test_weakref_cast([]) == (0, 0, 0, 0)
+        assert module.test_weakref_cast(weakref.ref(foo)) == (1, 1, 1, 0)
+        assert module.test_weakref_cast(weakref.ref(bar)) == (1, 1, 1, 0)
+        assert module.test_weakref_cast(weakref.proxy(foo)) == (1, 0, 0, 1)
+        assert module.test_weakref_cast(weakref.proxy(bar)) == (1, 0, 0, 1)
+        class X(weakref.ref):
+            pass
+        assert module.test_weakref_cast(X(foo)) == (1, 1, 0, 0)
+        assert module.test_weakref_cast(X(bar)) == (1, 1, 0, 0)
diff --git a/pypy/module/cpyext/weakrefobject.py b/pypy/module/cpyext/weakrefobject.py
--- a/pypy/module/cpyext/weakrefobject.py
+++ b/pypy/module/cpyext/weakrefobject.py
@@ -1,6 +1,7 @@
 from pypy.module.cpyext.api import cpython_api
-from pypy.module.cpyext.pyobject import PyObject
+from pypy.module.cpyext.pyobject import PyObject, CANNOT_FAIL
 from pypy.module._weakref.interp__weakref import W_Weakref, proxy
+from pypy.module._weakref.interp__weakref import W_Proxy, W_CallableProxy
 from rpython.rtyper.lltypesystem import rffi
 
 @cpython_api([PyObject, PyObject], PyObject)
@@ -54,3 +55,34 @@
     PyWeakref_GetObject() and Py_INCREF().)
     """
     return space.call_function(w_ref)
+
+ at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyWeakref_CheckRef(space, w_obj):
+    """Return true if ob is a reference object.
+    """
+    w_obj_type = space.type(w_obj)
+    w_type = space.gettypeobject(W_Weakref.typedef)
+    return (space.is_w(w_obj_type, w_type) or
+            space.issubtype_w(w_obj_type, w_type))
+
+ at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyWeakref_CheckRefExact(space, w_obj):
+    w_obj_type = space.type(w_obj)
+    w_type = space.gettypeobject(W_Weakref.typedef)
+    return space.is_w(w_obj_type, w_type)
+
+ at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyWeakref_CheckProxy(space, w_obj):
+    """Return true if ob is a proxy object.
+    """
+    w_obj_type = space.type(w_obj)
+    w_type1 = space.gettypeobject(W_Proxy.typedef)
+    w_type2 = space.gettypeobject(W_CallableProxy.typedef)
+    return space.is_w(w_obj_type, w_type1) or space.is_w(w_obj_type, w_type2)
+
+ at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyWeakref_Check(space, w_obj):
+    """Return true if ob is either a reference or proxy object.
+    """
+    return (PyWeakref_CheckRef(space, w_obj) or
+            PyWeakref_CheckProxy(space, w_obj))


More information about the pypy-commit mailing list