Commits

Dan Colish committed bacbc6d

add proxy support, and unicode buffer utf-8 encode to cpyext

Comments (0)

Files changed (5)

pypy/module/cpyext/stubs.py

     """Return true if ob is a reference object.
     """
     raise NotImplementedError
-
-@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyWeakref_CheckProxy(space, ob):
-    """Return true if ob is a proxy object.
-    """
-    raise NotImplementedError
-
-@cpython_api([PyObject, PyObject], PyObject)
-def PyWeakref_NewProxy(space, ob, callback):
-    """Return a weak reference proxy object for the object ob.  This will always
-    return a new reference, but is not guaranteed to create a new object; an
-    existing proxy object may be returned.  The second parameter, callback, can
-    be a callable object that receives notification when ob is garbage
-    collected; it should accept a single parameter, which will be the weak
-    reference object itself. callback may also be None or NULL.  If ob
-    is not a weakly-referencable object, or if callback is not callable,
-    None, or NULL, this will return NULL and raise TypeError.
-    """
-    raise NotImplementedError

pypy/module/cpyext/test/test_unicodeobject.py

         assert space.unwrap(w_u) == 'sp'
         rffi.free_charp(u)
 
+    def test_encode_utf8(self, space, api):
+        u = rffi.unicode2wcharp(u'sp�m')
+        w_res = api.PyUnicode_EncodeUTF8(u, 5, None)
+        assert space.type(w_res) is space.w_str
+        assert space.unwrap(w_res) == 'sp\xc3\xa4m\x00'
+
+        w_res = api.PyUnicode_EncodeUTF8(u, 2, None)
+        assert space.type(w_res) is space.w_str
+        assert space.unwrap(w_res) == 'sp'
+        rffi.free_wcharp(u)
+
     def test_IS(self, space, api):
         for char in [0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x1c, 0x1d, 0x1e, 0x1f,
                      0x20, 0x85, 0xa0, 0x1680, 0x2000, 0x2001, 0x2002,

pypy/module/cpyext/test/test_weakref.py

         assert api.PyErr_Occurred() is space.w_TypeError
         api.PyErr_Clear()
 
+    def test_weakref_proxy(self, space, api):
+        w_obj = space.w_Exception
+        w_proxy = api.PyWeakref_NewProxy(w_obj, space.w_None)
+        assert w_proxy is not None
+        assert space.is_w(w_proxy.dereference(), w_obj)
+        ret = api.PyWeakref_CheckProxy(w_proxy)
+        assert ret == 1
+
     def test_weakref_lockobject(self, space, api):
         # some new weakrefable object
         w_obj = space.call_function(space.w_type, space.wrap("newtype"),

pypy/module/cpyext/unicodeobject.py

         PyErr_BadArgument(space)
     return unicodetype.encode_object(space, w_unicode, "utf-8", "strict")
 
+@cpython_api([CONST_WSTRING, Py_ssize_t, CONST_STRING], PyObject)
+def PyUnicode_EncodeUTF8(space, s, size, errors):
+    """Encode the Py_UNICODE buffer of the given size using UTF-8 and return a
+    Python string object.  Return NULL if an exception was raised by the codec.
+
+    This function used an int type for size. This might require
+    changes in your code for properly supporting 64-bit systems."""
+    w_unicode = space.wrap(rffi.wcharpsize2unicode(s, size))
+    if errors:
+        w_errors = space.wrap(rffi.charp2str(errors))
+    else:
+        w_errors = space.w_None
+    return space.call_method(
+        w_unicode, 'encode', space.wrap("utf-8"), w_errors)
+
+
 @cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING], PyObject)
 def PyUnicode_DecodeUTF8(space, s, size, errors):
     """Create a Unicode object by decoding size bytes of the UTF-8 encoded string

pypy/module/cpyext/weakrefobject.py

-from pypy.module.cpyext.api import cpython_api
+from pypy.module.cpyext.api import cpython_api, build_type_checkers, CANNOT_FAIL
 from pypy.module.cpyext.pyobject import PyObject, borrow_from
-from pypy.module._weakref.interp__weakref import W_Weakref
+from pypy.module._weakref.interp__weakref import W_Weakref, W_CallableProxy, W_Proxy, proxy
+from pypy.rpython.lltypesystem import rffi
 
 @cpython_api([PyObject, PyObject], PyObject)
 def PyWeakref_NewRef(space, w_obj, w_callback):
     w_weakref = space.gettypeobject(W_Weakref.typedef)
     return space.call_function(w_weakref, w_obj, w_callback)
 
+@cpython_api([PyObject, PyObject], PyObject)
+def PyWeakref_NewProxy(space, w_obj, w_callback):
+    """Return a weak reference proxy object for the object *ob*.  This will always
+    return a new reference, but is not guaranteed to create a new object; an
+    existing proxy object may be returned.  The second parameter, *callback*, can
+    be a callable object that receives notification when *ob* is garbage
+    collected; it should accept a single parameter, which will be the weak
+    reference object itself. *callback* may also be ``None`` or *NULL*.  If *ob*
+    is not a weakly-referencable object, or if *callback* is not callable,
+    ``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`.
+    """
+    return proxy(space, w_obj, w_callback)
+
+@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyWeakref_CheckProxy(space, w_proxy):
+    """Return true if ob is a proxy object.
+    """
+    w_proxy_t = space.gettypeobject(W_Proxy.typedef)
+    w_callable_t = space.gettypeobject(W_CallableProxy.typedef)
+    if (space.is_true(space.isinstance(w_proxy, w_proxy_t)) or
+         space.is_true(space.isinstance(w_proxy, w_callable_t))):
+        return 1
+    else:
+        return -1
+
 @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 new reference.
     """
     return space.call_function(w_ref)
-