[pypy-svn] r73379 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test
fijal at codespeak.net
fijal at codespeak.net
Sun Apr 4 20:18:43 CEST 2010
Author: fijal
Date: Sun Apr 4 20:18:41 2010
New Revision: 73379
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py
Log:
test and fix _PyString_Resize
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 Sun Apr 4 20:18:41 2010
@@ -8,6 +8,17 @@
PyString_Check, PyString_CheckExact = build_type_checkers("String", "w_str")
+def new_empty_str(space, length):
+ py_str = lltype.malloc(PyStringObject.TO, flavor='raw')
+ py_str.c_ob_refcnt = 1
+
+ buflen = length + 1
+ py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
+ py_str.c_buffer[buflen-1] = '\0'
+ py_str.c_size = length
+ py_str.c_ob_type = make_ref(space, space.w_str)
+ return py_str
+
@cpython_api_c()
def PyString_FromFormatV():
pass
@@ -19,16 +30,7 @@
ptr = make_ref(space, space.wrap(s))
return rffi.cast(PyStringObject, ptr)
else:
- py_str = lltype.malloc(PyStringObject.TO, flavor='raw')
- py_str.c_ob_refcnt = 1
-
- buflen = length + 1
- py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
- py_str.c_buffer[buflen-1] = '\0'
- py_str.c_size = length
- py_str.c_ob_type = make_ref(space, space.w_str)
-
- return py_str
+ return new_empty_str(space, length)
@cpython_api([rffi.CCHARP], PyObject)
def PyString_FromString(space, char_p):
@@ -69,13 +71,23 @@
This function used an int type for newsize. This might
require changes in your code for properly supporting 64-bit systems."""
# XXX always create a new string so far
- w_s = from_ref(space, ref[0])
+ py_str = rffi.cast(PyStringObject, ref[0])
+ if not py_str.c_buffer:
+ raise OperationError(space.w_SystemError, space.wrap(
+ "_PyString_Resize called on already created string"))
try:
- ptr = make_ref(space, space.wrap(space.str_w(w_s)[:newsize]))
- except:
+ py_newstr = new_empty_str(space, newsize)
+ except MemoryError:
Py_DecRef(space, ref[0])
- ref[0] = lltype.nullptr(PyStringObject)
+ ref[0] = lltype.nullptr(PyObject)
raise
+ to_cp = newsize
+ oldsize = py_str.c_size
+ if oldsize < newsize:
+ to_cp = oldsize
+ for i in range(to_cp):
+ py_newstr.c_buffer[i] = py_str.c_buffer[i]
+ py_newstr.c_buffer[newsize] = '\x00'
Py_DecRef(space, ref[0])
- ref[0] = ptr
+ ref[0] = rffi.cast(PyObject, py_newstr)
return 0
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 Sun Apr 4 20:18:41 2010
@@ -1,15 +1,12 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.test.test_api import BaseApiTest
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
import py
import sys
-#class TestObject(BaseApiTest):
-# def test_Size(self, space, api):
-# s = space.wrap("test")
-# assert api.PyString_Size(s) == 4
-
class AppTestStringObject(AppTestCpythonExtensionBase):
def test_stringobject(self):
module = self.import_extension('foo', [
@@ -128,3 +125,26 @@
''')
res = module.test_string_format_v(1, "xyz")
print res
+
+class TestString(BaseApiTest):
+ def test_string_resize(self, space, api):
+ py_str = new_empty_str(space, 10)
+ ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+ py_str.c_buffer[0] = 'a'
+ py_str.c_buffer[1] = 'b'
+ py_str.c_buffer[2] = 'c'
+ ar[0] = rffi.cast(PyObject, py_str)
+ api._PyString_Resize(ar, 3)
+ py_str = rffi.cast(PyStringObject, ar[0])
+ assert py_str.c_size == 3
+ assert py_str.c_buffer[1] == 'b'
+ assert py_str.c_buffer[3] == '\x00'
+ # the same for growing
+ ar[0] = rffi.cast(PyObject, py_str)
+ api._PyString_Resize(ar, 10)
+ py_str = rffi.cast(PyStringObject, ar[0])
+ assert py_str.c_size == 10
+ assert py_str.c_buffer[1] == 'b'
+ assert py_str.c_buffer[10] == '\x00'
+ lltype.free(ar, flavor='raw')
+
More information about the Pypy-commit
mailing list