(original) (raw)

changeset: 92049:06cf4044a11a parent: 92047:e205bce4cc0a parent: 92048:034a5f15561d user: Serhiy Storchaka storchaka@gmail.com date: Sat Aug 09 09:34:25 2014 +0300 files: Lib/ctypes/__init__.py description: Issue #22161: Conformed arguments type checks in ctype to actually supported types. Corrected error messages about bytes arguments. diff -r e205bce4cc0a -r 06cf4044a11a Lib/ctypes/__init__.py --- a/Lib/ctypes/__init__.py Sat Aug 09 16:19:41 2014 +1000 +++ b/Lib/ctypes/__init__.py Sat Aug 09 09:34:25 2014 +0300 @@ -49,7 +49,7 @@ create_string_buffer(anInteger) -> character array create_string_buffer(aString, anInteger) -> character array """ - if isinstance(init, (str, bytes)): + if isinstance(init, bytes): if size is None: size = len(init)+1 buftype = c_char * size @@ -284,7 +284,7 @@ create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ - if isinstance(init, (str, bytes)): + if isinstance(init, str): if size is None: size = len(init)+1 buftype = c_wchar * size diff -r e205bce4cc0a -r 06cf4044a11a Lib/ctypes/test/test_buffers.py --- a/Lib/ctypes/test/test_buffers.py Sat Aug 09 16:19:41 2014 +1000 +++ b/Lib/ctypes/test/test_buffers.py Sat Aug 09 09:34:25 2014 +0300 @@ -21,6 +21,8 @@ self.assertEqual(b[::2], b"ac") self.assertEqual(b[::5], b"a") + self.assertRaises(TypeError, create_string_buffer, "abc") + def test_buffer_interface(self): self.assertEqual(len(bytearray(create_string_buffer(0))), 0) self.assertEqual(len(bytearray(create_string_buffer(1))), 1) @@ -43,6 +45,8 @@ self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + self.assertRaises(TypeError, create_unicode_buffer, b"abc") + @need_symbol('c_wchar') def test_unicode_conversion(self): b = create_unicode_buffer("abc") diff -r e205bce4cc0a -r 06cf4044a11a Lib/ctypes/test/test_bytes.py --- a/Lib/ctypes/test/test_bytes.py Sat Aug 09 16:19:41 2014 +1000 +++ b/Lib/ctypes/test/test_bytes.py Sat Aug 09 09:34:25 2014 +0300 @@ -6,27 +6,40 @@ class BytesTest(unittest.TestCase): def test_c_char(self): x = c_char(b"x") + self.assertRaises(TypeError, c_char, "x") x.value = b"y" + with self.assertRaises(TypeError): + x.value = "y" c_char.from_param(b"x") + self.assertRaises(TypeError, c_char.from_param, "x") (c_char * 3)(b"a", b"b", b"c") + self.assertRaises(TypeError, c_char * 3, "a", "b", "c") def test_c_wchar(self): x = c_wchar("x") + self.assertRaises(TypeError, c_wchar, b"x") x.value = "y" + with self.assertRaises(TypeError): + x.value = b"y" c_wchar.from_param("x") + self.assertRaises(TypeError, c_wchar.from_param, b"x") (c_wchar * 3)("a", "b", "c") + self.assertRaises(TypeError, c_wchar * 3, b"a", b"b", b"c") def test_c_char_p(self): c_char_p(b"foo bar") + self.assertRaises(TypeError, c_char_p, "foo bar") def test_c_wchar_p(self): c_wchar_p("foo bar") + self.assertRaises(TypeError, c_wchar_p, b"foo bar") def test_struct(self): class X(Structure): _fields_ = [("a", c_char * 3)] x = X(b"abc") + self.assertRaises(TypeError, X, "abc") self.assertEqual(x.a, b"abc") self.assertEqual(type(x.a), bytes) @@ -35,6 +48,7 @@ _fields_ = [("a", c_wchar * 3)] x = X("abc") + self.assertRaises(TypeError, X, b"abc") self.assertEqual(x.a, "abc") self.assertEqual(type(x.a), str) @@ -46,5 +60,6 @@ BSTR("abc") + if __name__ == '__main__': unittest.main() diff -r e205bce4cc0a -r 06cf4044a11a Lib/ctypes/test/test_structures.py --- a/Lib/ctypes/test/test_structures.py Sat Aug 09 16:19:41 2014 +1000 +++ b/Lib/ctypes/test/test_structures.py Sat Aug 09 09:34:25 2014 +0300 @@ -322,7 +322,7 @@ self.assertEqual(cls, RuntimeError) self.assertEqual(msg, "(Phone) : " - "expected string, int found") + "expected bytes, int found") cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c")) self.assertEqual(cls, RuntimeError) diff -r e205bce4cc0a -r 06cf4044a11a Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Sat Aug 09 16:19:41 2014 +1000 +++ b/Modules/_ctypes/_ctypes.c Sat Aug 09 09:34:25 2014 +0300 @@ -1080,7 +1080,7 @@ ptr = view.buf; if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, - "string too long"); + "byte string too long"); goto fail; } @@ -1132,7 +1132,7 @@ size = PyBytes_GET_SIZE(value); if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, - "string too long"); + "byte string too long"); Py_DECREF(value); return -1; } @@ -1471,7 +1471,7 @@ Py_INCREF(Py_None); return Py_None; } - if (PyUnicode_Check(value) || PyBytes_Check(value)) { + if (PyUnicode_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = _ctypes_get_fielddesc("Z"); @@ -1623,7 +1623,7 @@ return (PyObject *)parg; } /* XXX struni: remove later */ -/* string */ +/* bytes */ if (PyBytes_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = _ctypes_get_fielddesc("z"); @@ -1640,23 +1640,6 @@ } return (PyObject *)parg; } -/* bytes */ - if (PyByteArray_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("z"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'z'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } /* unicode */ if (PyUnicode_Check(value)) { PyCArgObject *parg; @@ -3218,7 +3201,7 @@ return *pname ? 1 : 0; } PyErr_SetString(PyExc_TypeError, - "function name must be string or integer"); + "function name must be string, bytes object or integer"); return 0; } diff -r e205bce4cc0a -r 06cf4044a11a Modules/_ctypes/cfield.c --- a/Modules/_ctypes/cfield.c Sat Aug 09 16:19:41 2014 +1000 +++ b/Modules/_ctypes/cfield.c Sat Aug 09 09:34:25 2014 +0300 @@ -1160,7 +1160,7 @@ } error: PyErr_Format(PyExc_TypeError, - "one character string expected"); + "one character bytes, bytearray or integer expected"); return NULL; } @@ -1295,7 +1295,7 @@ Py_INCREF(value); } else { PyErr_Format(PyExc_TypeError, - "expected string, %s found", + "expected bytes, %s found", value->ob_type->tp_name); return NULL; } @@ -1311,7 +1311,7 @@ ++size; } else if (size > length) { PyErr_Format(PyExc_ValueError, - "string too long (%zd, maximum length %zd)", + "bytes too long (%zd, maximum length %zd)", size, length); Py_DECREF(value); return NULL;/storchaka@gmail.com