[pypy-commit] pypy default: #2912

arigo pypy.commits at gmail.com
Mon Nov 12 11:56:08 EST 2018


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r95300:01d5d6b5425e
Date: 2018-11-12 17:55 +0100
http://bitbucket.org/pypy/pypy/changeset/01d5d6b5425e/

Log:	#2912

	Rewrite PyUnicode_FromEncodedObject() to use CPython's logic (still
	needs to be forward-ported to py3.5)

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
@@ -421,6 +421,8 @@
         with raises_w(space, TypeError):
             PyUnicode_FromEncodedObject(
                 space, space.wrap(u_text), null_charp, None)
+        assert space.unicode_w(PyUnicode_FromEncodedObject(
+            space, space.wrap(s_text), null_charp, None)) == u_text
         rffi.free_charp(b_text)
 
     def test_mbcs(self, space):
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
@@ -366,10 +366,14 @@
     in the unicode() built-in function.  The codec to be used is looked up
     using the Python codec registry.  Return NULL if an exception was raised by
     the codec."""
+    return _pyunicode_decode(space, rffi.charpsize2str(s, size),
+                             encoding, errors)
+
+def _pyunicode_decode(space, s, encoding, errors):
     if not encoding:
         # This tracks CPython 2.7, in CPython 3.4 'utf-8' is hardcoded instead
         encoding = PyUnicode_GetDefaultEncoding(space)
-    w_str = space.newbytes(rffi.charpsize2str(s, size))
+    w_str = space.newbytes(s)
     w_encoding = space.newtext(rffi.charp2str(encoding))
     if errors:
         w_errors = space.newbytes(rffi.charp2str(errors))
@@ -398,28 +402,12 @@
 
     All other objects, including Unicode objects, cause a TypeError to be
     set."""
-    if not encoding:
+    if space.isinstance_w(w_obj, space.w_unicode):
         raise oefmt(space.w_TypeError, "decoding Unicode is not supported")
-    w_encoding = space.newtext(rffi.charp2str(encoding))
-    if errors:
-        w_errors = space.newtext(rffi.charp2str(errors))
-    else:
-        w_errors = None
-
-    # - unicode is disallowed
-    # - raise TypeError for non-string types
-    if space.isinstance_w(w_obj, space.w_unicode):
-        w_meth = None
-    else:
-        try:
-            w_meth = space.getattr(w_obj, space.newtext('decode'))
-        except OperationError as e:
-            if not e.match(space, space.w_AttributeError):
-                raise
-            w_meth = None
-    if w_meth is None:
-        raise oefmt(space.w_TypeError, "decoding Unicode is not supported")
-    return space.call_function(w_meth, w_encoding, w_errors)
+    if space.isinstance_w(w_obj, space.w_bytearray):   # Python 2.x specific
+        raise oefmt(space.w_TypeError, "decoding bytearray is not supported")
+    s = space.bufferstr_w(w_obj)
+    return _pyunicode_decode(space, s, encoding, errors)
 
 @cpython_api([CONST_STRING], PyObject)
 def PyUnicode_FromString(space, s):


More information about the pypy-commit mailing list