[pypy-commit] pypy py3k: cpyext: implement PyUnicode_TransformDecimalToASCII

amauryfa noreply at buildbot.pypy.org
Sat Dec 1 23:23:22 CET 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r59191:80c0c0164810
Date: 2012-12-01 16:47 +0100
http://bitbucket.org/pypy/pypy/changeset/80c0c0164810/

Log:	cpyext: implement PyUnicode_TransformDecimalToASCII

diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -2037,15 +2037,6 @@
     raise NotImplementedError
     
 
- at cpython_api([rffi.CArrayPtr(Py_UNICODE), Py_ssize_t], PyObject)
-def PyUnicode_TransformDecimalToASCII(space, s, size):
-    """Create a Unicode object by replacing all decimal digits in
-    Py_UNICODE buffer of the given size by ASCII digits 0--9
-    according to their decimal value.  Return NULL if an exception
-    occurs."""
-    raise NotImplementedError
-    
-
 @cpython_api([PyObject], rffi.CArrayPtr(Py_UNICODE))
 def PyUnicode_AsUnicodeCopy(space, unicode):
     """Create a copy of a Unicode string ending with a nul character. Return NULL
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -395,6 +395,18 @@
         assert api.Py_UNICODE_TONUMERIC(u'A') == -1.0
         assert api.Py_UNICODE_TONUMERIC(u'\N{VULGAR FRACTION ONE HALF}') == .5
 
+    def test_transform_decimal(self, space, api):
+        def transform_decimal(s):
+            with rffi.scoped_unicode2wcharp(s) as u:
+                return space.unwrap(
+                    api.PyUnicode_TransformDecimalToASCII(u, len(s)))
+        assert isinstance(transform_decimal(u'123'), unicode)
+        assert transform_decimal(u'123') == u'123'
+        assert transform_decimal(u'\u0663.\u0661\u0664') == u'3.14'
+        assert transform_decimal(u"\N{EM SPACE}3.14\N{EN SPACE}") == (
+            u"\N{EM SPACE}3.14\N{EN SPACE}")
+        assert transform_decimal(u'123\u20ac') == u'123\u20ac'
+
     def test_fromobject(self, space, api):
         w_u = space.wrap(u'a')
         assert api.PyUnicode_FromObject(w_u) is w_u
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -14,7 +14,7 @@
 from pypy.module._codecs.interp_codecs import CodecState
 from pypy.module.posix.interp_posix import fsencode, fsdecode
 from pypy.objspace.std import unicodeobject, unicodetype, stringtype
-from pypy.rlib import runicode
+from pypy.rlib import runicode, rstring
 from pypy.tool.sourcetools import func_renamer
 import sys
 
@@ -738,6 +738,23 @@
         i -= 1
     return 0
 
+ at cpython_api([rffi.CArrayPtr(Py_UNICODE), Py_ssize_t], PyObject)
+def PyUnicode_TransformDecimalToASCII(space, s, size):
+    """Create a Unicode object by replacing all decimal digits in
+    Py_UNICODE buffer of the given size by ASCII digits 0--9
+    according to their decimal value.  Return NULL if an exception
+    occurs."""
+    result = rstring.UnicodeBuilder(size)
+    for i in range(size):
+        ch = s[i]
+        if ord(ch) > 127:
+            decimal = Py_UNICODE_TODECIMAL(space, ch)
+            decimal = rffi.cast(lltype.Signed, decimal)
+            if decimal >= 0:
+                ch = unichr(ord('0') + decimal)
+        result.append(ch)
+    return space.wrap(result.build())
+    
 @cpython_api([PyObject, PyObject], rffi.INT_real, error=-2)
 def PyUnicode_Compare(space, w_left, w_right):
     """Compare two strings and return -1, 0, 1 for less than, equal, and greater


More information about the pypy-commit mailing list