[pypy-svn] r73614 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test

jandem at codespeak.net jandem at codespeak.net
Sat Apr 10 14:50:24 CEST 2010


Author: jandem
Date: Sat Apr 10 14:50:23 2010
New Revision: 73614

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py
Log:
Add PyString_Concat{AndDel}


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py	Sat Apr 10 14:50:23 2010
@@ -88,3 +88,31 @@
     Py_DecRef(space, ref[0])
     ref[0] = rffi.cast(PyObject, py_newstr)
     return 0
+
+ at cpython_api([PyObjectP, PyObject], lltype.Void)
+def PyString_Concat(space, ref, w_newpart):
+    """Create a new string object in *string containing the contents of newpart
+    appended to string; the caller will own the new reference.  The reference to
+    the old value of string will be stolen.  If the new string cannot be created,
+    the old reference to string will still be discarded and the value of
+    *string will be set to NULL; the appropriate exception will be set."""
+    
+    if not ref[0]: 
+        return
+    
+    if w_newpart is None or not PyString_Check(space, ref[0]) or \
+            not PyString_Check(space, w_newpart):
+         Py_DecRef(space, ref[0])
+         ref[0] = lltype.nullptr(PyObject.TO)
+         return
+    w_str = from_ref(space, ref[0])
+    w_newstr = space.add(w_str, w_newpart)
+    Py_DecRef(space, ref[0])
+    ref[0] = make_ref(space, w_newstr)
+
+ at cpython_api([PyObjectP, PyObject], lltype.Void)
+def PyString_ConcatAndDel(space, ref, newpart):
+    """Create a new string object in *string containing the contents of newpart
+    appended to string.  This version decrements the reference count of newpart."""
+    PyString_Concat(space, ref, newpart)
+    Py_DecRef(space, newpart)

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py	Sat Apr 10 14:50:23 2010
@@ -3,7 +3,7 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.stringobject import new_empty_str
 from pypy.module.cpyext.api import PyStringObject, PyObjectP, PyObject
-from pypy.module.cpyext.pyobject import Py_DecRef
+from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
 
 import py
 import sys
@@ -177,3 +177,30 @@
         assert c_buf.c_bf_getreadbuffer(py_obj, 0, ref) == 10
         lltype.free(ref, flavor='raw')
         Py_DecRef(space, py_obj)
+        
+    def test_Concat(self, space, api):
+        ref = make_ref(space, space.wrap('abc'))
+        ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        ptr[0] = ref
+        api.PyString_Concat(ptr, space.wrap('def'))
+        assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
+        api.PyString_Concat(ptr, space.w_None)
+        assert not ptr[0]
+        ptr[0] = lltype.nullptr(PyObject.TO)
+        api.PyString_Concat(ptr, space.wrap('def')) # should not crash
+        lltype.free(ptr, flavor='raw')
+    
+    def test_ConcatAndDel(self, space, api):
+        ref1 = make_ref(space, space.wrap('abc'))
+        ref2 = make_ref(space, space.wrap('def'))
+        ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        ptr[0] = ref1
+        api.PyString_ConcatAndDel(ptr, ref2)
+        assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
+        assert ref2.c_ob_refcnt == 0
+        Py_DecRef(space, ptr[0])
+        ptr[0] = lltype.nullptr(PyObject.TO)
+        ref2 = make_ref(space, space.wrap('foo'))
+        api.PyString_ConcatAndDel(ptr, ref2) # should not crash
+        assert ref2.c_ob_refcnt == 0
+        lltype.free(ptr, flavor='raw')



More information about the Pypy-commit mailing list