[pypy-svn] r73999 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test
afa at codespeak.net
afa at codespeak.net
Fri Apr 23 00:29:39 CEST 2010
Author: afa
Date: Fri Apr 23 00:29:37 2010
New Revision: 73999
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py
Log:
Add PyUnicode_GetSize, PyUnicode_EncodeMBCS and PyUnicode_DecodeMBCS on windows
the detection of leaks is not perfect, see test_unicodeobject.test_leak.
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py Fri Apr 23 00:29:37 2010
@@ -2,10 +2,12 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.unicodeobject import Py_UNICODE
from pypy.rpython.lltypesystem import rffi, lltype
+import sys, py
class TestUnicode(BaseApiTest):
def test_unicodeobject(self, space, api):
assert api.PyUnicode_GET_SIZE(space.wrap(u'späm')) == 4
+ assert api.PyUnicode_GetSize(space.wrap(u'späm')) == 4
unichar = rffi.sizeof(Py_UNICODE)
assert api.PyUnicode_GET_DATA_SIZE(space.wrap(u'späm')) == 4 * unichar
@@ -94,3 +96,27 @@
api.PyUnicode_Decode(b_text, 4, b_encoding, None)) == u'caf\xe9'
rffi.free_charp(b_text)
rffi.free_charp(b_encoding)
+
+ def test_leak(self):
+ py.test.skip("This test seems to leak memory")
+ size = 50
+ raw_buf, gc_buf = rffi.alloc_buffer(size)
+ for i in range(size): raw_buf[i] = 'a'
+ str = rffi.str_from_buffer(raw_buf, gc_buf, size, size)
+ rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
+
+ def test_mbcs(self, space, api):
+ if sys.platform != 'win32':
+ py.test.skip("mcbs encoding only exists on Windows")
+ # unfortunately, mbcs is locale-dependent.
+ # This tests works at least on a Western Windows.
+ unichars = u"abc" + unichr(12345)
+ wbuf = rffi.unicode2wcharp(unichars)
+ w_str = api.PyUnicode_EncodeMBCS(wbuf, 4, None)
+ rffi.free_wcharp(wbuf)
+ assert space.type(w_str) is space.w_str
+ assert space.str_w(w_str) == "abc?"
+
+ # XXX this test seems to leak references, see test_leak above
+ from pypy.module.cpyext.test.test_cpyext import freeze_refcnts
+ freeze_refcnts(self)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py Fri Apr 23 00:29:37 2010
@@ -10,6 +10,7 @@
from pypy.module.cpyext.stringobject import PyString_Check
from pypy.module.sys.interp_encoding import setdefaultencoding
from pypy.objspace.std import unicodeobject, unicodetype
+import sys
PyUnicodeObjectStruct = lltype.ForwardReference()
PyUnicodeObject = lltype.Ptr(PyUnicodeObjectStruct)
@@ -142,6 +143,15 @@
space.wrap("expected unicode object"))
return PyUnicode_AS_UNICODE(space, ref)
+ at cpython_api([PyObject], Py_ssize_t, error=-1)
+def PyUnicode_GetSize(space, ref):
+ if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_unicode:
+ ref = rffi.cast(PyUnicodeObject, ref)
+ return ref.c_size
+ else:
+ w_obj = from_ref(space, ref)
+ return space.int_w(space.len(w_obj))
+
@cpython_api([PyUnicodeObject, rffi.CWCHARP, Py_ssize_t], Py_ssize_t, error=-1)
def PyUnicode_AsWideChar(space, ref, buf, size):
"""Copy the Unicode object contents into the wchar_t buffer w. At most
@@ -245,3 +255,31 @@
else:
w_errors = space.w_None
return space.call_method(w_str, 'decode', w_encoding, w_errors)
+
+
+if sys.platform == 'win32':
+ @cpython_api([CONST_WSTRING, Py_ssize_t, CONST_STRING], PyObject)
+ def PyUnicode_EncodeMBCS(space, wchar_p, length, errors):
+ """Encode the Py_UNICODE buffer of the given size using MBCS and return a
+ Python string object. Return NULL if an exception was raised by the codec.
+ """
+ w_unicode = space.wrap(rffi.wcharpsize2unicode(wchar_p, length))
+ if errors:
+ w_errors = space.wrap(rffi.charp2str(errors))
+ else:
+ w_errors = space.w_None
+ return space.call_method(w_unicode, "encode",
+ space.wrap("mbcs"), w_errors)
+
+ @cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING], PyObject)
+ def PyUnicode_DecodeMBCS(space, s, size, errors):
+ """Create a Unicode object by decoding size bytes of the MBCS encoded string s.
+ Return NULL if an exception was raised by the codec.
+ """
+ w_str = space.wrap(rffi.charpsize2str(s, size))
+ w_encoding = space.wrap("mbcs")
+ if errors:
+ w_errors = space.wrap(rffi.charp2str(errors))
+ else:
+ w_errors = space.w_None
+ return space.call_method(w_str, 'decode', w_encoding, w_errors)
More information about the Pypy-commit
mailing list