Author: Ronan Lamy <ronan.l...@gmail.com> Branch: py3.5 Changeset: r93019:a3c86e99e3e4 Date: 2017-11-14 19:51 +0000 http://bitbucket.org/pypy/pypy/changeset/a3c86e99e3e4/
Log: PyUnicode_FromObject only works on instances of str 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 @@ -319,6 +319,20 @@ assert module.unsafe_len(u'aАbБcСdД') == 8 assert module.unsafe_len(u"café\U0001F4A9") == 5 + def test_FromObject(self): + module = self.import_extension('foo', [ + ("from_object", "METH_O", + """ + return PyUnicode_FromObject(args); + """)]) + class my_str(str): pass + assert module.from_object('abc') == 'abc' + res = module.from_object(my_str('abc')) + assert type(res) is str + assert res == 'abc' + raises(TypeError, module.from_object, b'abc') + raises(TypeError, module.from_object, 42) + class TestUnicode(BaseApiTest): def test_unicodeobject(self, space): @@ -500,6 +514,12 @@ assert ret == Py_CLEANUP_SUPPORTED assert space.isinstance_w(from_ref(space, result[0]), space.w_bytes) assert PyUnicode_FSDecoder(space, None, result) == 1 + # Input is invalid + w_input = space.newint(42) + with lltype.scoped_alloc(PyObjectP.TO, 1) as result: + with pytest.raises(OperationError): + PyUnicode_FSConverter(space, w_input, result) + def test_IS(self, space): for char in [0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x1c, 0x1d, 0x1e, 0x1f, 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 @@ -505,12 +505,19 @@ @cpython_api([PyObject], PyObject) def PyUnicode_FromObject(space, w_obj): - """Shortcut for PyUnicode_FromEncodedObject(obj, NULL, "strict") which is used - throughout the interpreter whenever coercion to Unicode is needed.""" + """Copy an instance of a Unicode subtype to a new true Unicode object if + necessary. If obj is already a true Unicode object (not a subtype), return + the reference with incremented refcount. + + Objects other than Unicode or its subtypes will cause a TypeError. + """ if space.is_w(space.type(w_obj), space.w_unicode): return w_obj + elif space.isinstance_w(w_obj, space.w_unicode): + return space.call_function(space.w_unicode, w_obj) else: - return space.call_function(space.w_unicode, w_obj) + raise oefmt(space.w_TypeError, + "Can't convert '%T' object to str implicitly", w_obj) @cpython_api([PyObject, CONST_STRING, CONST_STRING], PyObject) def PyUnicode_FromEncodedObject(space, w_obj, encoding, errors): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit