mirror of https://github.com/python/cpython
Issue #22161: Conformed arguments type checks in ctype to actually supported
types. Corrected error messages about bytes arguments.
This commit is contained in:
commit
d5736faabe
|
@ -49,7 +49,7 @@ def create_string_buffer(init, size=None):
|
||||||
create_string_buffer(anInteger) -> character array
|
create_string_buffer(anInteger) -> character array
|
||||||
create_string_buffer(aString, anInteger) -> character array
|
create_string_buffer(aString, anInteger) -> character array
|
||||||
"""
|
"""
|
||||||
if isinstance(init, (str, bytes)):
|
if isinstance(init, bytes):
|
||||||
if size is None:
|
if size is None:
|
||||||
size = len(init)+1
|
size = len(init)+1
|
||||||
buftype = c_char * size
|
buftype = c_char * size
|
||||||
|
@ -284,7 +284,7 @@ def create_unicode_buffer(init, size=None):
|
||||||
create_unicode_buffer(anInteger) -> character array
|
create_unicode_buffer(anInteger) -> character array
|
||||||
create_unicode_buffer(aString, anInteger) -> character array
|
create_unicode_buffer(aString, anInteger) -> character array
|
||||||
"""
|
"""
|
||||||
if isinstance(init, (str, bytes)):
|
if isinstance(init, str):
|
||||||
if size is None:
|
if size is None:
|
||||||
size = len(init)+1
|
size = len(init)+1
|
||||||
buftype = c_wchar * size
|
buftype = c_wchar * size
|
||||||
|
|
|
@ -21,6 +21,8 @@ class StringBufferTestCase(unittest.TestCase):
|
||||||
self.assertEqual(b[::2], b"ac")
|
self.assertEqual(b[::2], b"ac")
|
||||||
self.assertEqual(b[::5], b"a")
|
self.assertEqual(b[::5], b"a")
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, create_string_buffer, "abc")
|
||||||
|
|
||||||
def test_buffer_interface(self):
|
def test_buffer_interface(self):
|
||||||
self.assertEqual(len(bytearray(create_string_buffer(0))), 0)
|
self.assertEqual(len(bytearray(create_string_buffer(0))), 0)
|
||||||
self.assertEqual(len(bytearray(create_string_buffer(1))), 1)
|
self.assertEqual(len(bytearray(create_string_buffer(1))), 1)
|
||||||
|
@ -43,6 +45,8 @@ class StringBufferTestCase(unittest.TestCase):
|
||||||
self.assertEqual(b[::2], "ac")
|
self.assertEqual(b[::2], "ac")
|
||||||
self.assertEqual(b[::5], "a")
|
self.assertEqual(b[::5], "a")
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, create_unicode_buffer, b"abc")
|
||||||
|
|
||||||
@need_symbol('c_wchar')
|
@need_symbol('c_wchar')
|
||||||
def test_unicode_conversion(self):
|
def test_unicode_conversion(self):
|
||||||
b = create_unicode_buffer("abc")
|
b = create_unicode_buffer("abc")
|
||||||
|
|
|
@ -6,27 +6,40 @@ from ctypes import *
|
||||||
class BytesTest(unittest.TestCase):
|
class BytesTest(unittest.TestCase):
|
||||||
def test_c_char(self):
|
def test_c_char(self):
|
||||||
x = c_char(b"x")
|
x = c_char(b"x")
|
||||||
|
self.assertRaises(TypeError, c_char, "x")
|
||||||
x.value = b"y"
|
x.value = b"y"
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
x.value = "y"
|
||||||
c_char.from_param(b"x")
|
c_char.from_param(b"x")
|
||||||
|
self.assertRaises(TypeError, c_char.from_param, "x")
|
||||||
(c_char * 3)(b"a", b"b", b"c")
|
(c_char * 3)(b"a", b"b", b"c")
|
||||||
|
self.assertRaises(TypeError, c_char * 3, "a", "b", "c")
|
||||||
|
|
||||||
def test_c_wchar(self):
|
def test_c_wchar(self):
|
||||||
x = c_wchar("x")
|
x = c_wchar("x")
|
||||||
|
self.assertRaises(TypeError, c_wchar, b"x")
|
||||||
x.value = "y"
|
x.value = "y"
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
x.value = b"y"
|
||||||
c_wchar.from_param("x")
|
c_wchar.from_param("x")
|
||||||
|
self.assertRaises(TypeError, c_wchar.from_param, b"x")
|
||||||
(c_wchar * 3)("a", "b", "c")
|
(c_wchar * 3)("a", "b", "c")
|
||||||
|
self.assertRaises(TypeError, c_wchar * 3, b"a", b"b", b"c")
|
||||||
|
|
||||||
def test_c_char_p(self):
|
def test_c_char_p(self):
|
||||||
c_char_p(b"foo bar")
|
c_char_p(b"foo bar")
|
||||||
|
self.assertRaises(TypeError, c_char_p, "foo bar")
|
||||||
|
|
||||||
def test_c_wchar_p(self):
|
def test_c_wchar_p(self):
|
||||||
c_wchar_p("foo bar")
|
c_wchar_p("foo bar")
|
||||||
|
self.assertRaises(TypeError, c_wchar_p, b"foo bar")
|
||||||
|
|
||||||
def test_struct(self):
|
def test_struct(self):
|
||||||
class X(Structure):
|
class X(Structure):
|
||||||
_fields_ = [("a", c_char * 3)]
|
_fields_ = [("a", c_char * 3)]
|
||||||
|
|
||||||
x = X(b"abc")
|
x = X(b"abc")
|
||||||
|
self.assertRaises(TypeError, X, "abc")
|
||||||
self.assertEqual(x.a, b"abc")
|
self.assertEqual(x.a, b"abc")
|
||||||
self.assertEqual(type(x.a), bytes)
|
self.assertEqual(type(x.a), bytes)
|
||||||
|
|
||||||
|
@ -35,6 +48,7 @@ class BytesTest(unittest.TestCase):
|
||||||
_fields_ = [("a", c_wchar * 3)]
|
_fields_ = [("a", c_wchar * 3)]
|
||||||
|
|
||||||
x = X("abc")
|
x = X("abc")
|
||||||
|
self.assertRaises(TypeError, X, b"abc")
|
||||||
self.assertEqual(x.a, "abc")
|
self.assertEqual(x.a, "abc")
|
||||||
self.assertEqual(type(x.a), str)
|
self.assertEqual(type(x.a), str)
|
||||||
|
|
||||||
|
@ -46,5 +60,6 @@ class BytesTest(unittest.TestCase):
|
||||||
|
|
||||||
BSTR("abc")
|
BSTR("abc")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -322,7 +322,7 @@ class StructureTestCase(unittest.TestCase):
|
||||||
self.assertEqual(cls, RuntimeError)
|
self.assertEqual(cls, RuntimeError)
|
||||||
self.assertEqual(msg,
|
self.assertEqual(msg,
|
||||||
"(Phone) <class 'TypeError'>: "
|
"(Phone) <class 'TypeError'>: "
|
||||||
"expected string, int found")
|
"expected bytes, int found")
|
||||||
|
|
||||||
cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c"))
|
cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c"))
|
||||||
self.assertEqual(cls, RuntimeError)
|
self.assertEqual(cls, RuntimeError)
|
||||||
|
|
|
@ -1080,7 +1080,7 @@ CharArray_set_raw(CDataObject *self, PyObject *value)
|
||||||
ptr = view.buf;
|
ptr = view.buf;
|
||||||
if (size > self->b_size) {
|
if (size > self->b_size) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"string too long");
|
"byte string too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,7 +1132,7 @@ CharArray_set_value(CDataObject *self, PyObject *value)
|
||||||
size = PyBytes_GET_SIZE(value);
|
size = PyBytes_GET_SIZE(value);
|
||||||
if (size > self->b_size) {
|
if (size > self->b_size) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"string too long");
|
"byte string too long");
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1471,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
if (PyUnicode_Check(value) || PyBytes_Check(value)) {
|
if (PyUnicode_Check(value)) {
|
||||||
PyCArgObject *parg;
|
PyCArgObject *parg;
|
||||||
struct fielddesc *fd = _ctypes_get_fielddesc("Z");
|
struct fielddesc *fd = _ctypes_get_fielddesc("Z");
|
||||||
|
|
||||||
|
@ -1623,25 +1623,8 @@ c_void_p_from_param(PyObject *type, PyObject *value)
|
||||||
return (PyObject *)parg;
|
return (PyObject *)parg;
|
||||||
}
|
}
|
||||||
/* XXX struni: remove later */
|
/* XXX struni: remove later */
|
||||||
/* string */
|
|
||||||
if (PyBytes_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;
|
|
||||||
}
|
|
||||||
/* bytes */
|
/* bytes */
|
||||||
if (PyByteArray_Check(value)) {
|
if (PyBytes_Check(value)) {
|
||||||
PyCArgObject *parg;
|
PyCArgObject *parg;
|
||||||
struct fielddesc *fd = _ctypes_get_fielddesc("z");
|
struct fielddesc *fd = _ctypes_get_fielddesc("z");
|
||||||
|
|
||||||
|
@ -3218,7 +3201,7 @@ _get_name(PyObject *obj, char **pname)
|
||||||
return *pname ? 1 : 0;
|
return *pname ? 1 : 0;
|
||||||
}
|
}
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"function name must be string or integer");
|
"function name must be string, bytes object or integer");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ c_set(void *ptr, PyObject *value, Py_ssize_t size)
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"one character string expected");
|
"one character bytes, bytearray or integer expected");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,7 +1295,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
Py_INCREF(value);
|
Py_INCREF(value);
|
||||||
} else {
|
} else {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"expected string, %s found",
|
"expected bytes, %s found",
|
||||||
value->ob_type->tp_name);
|
value->ob_type->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1311,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
++size;
|
++size;
|
||||||
} else if (size > length) {
|
} else if (size > length) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"string too long (%zd, maximum length %zd)",
|
"bytes too long (%zd, maximum length %zd)",
|
||||||
size, length);
|
size, length);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue