Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e5095e1

Browse files
author
Thomas Heller
committed
Structure fields of type c_char array or c_wchar array accept bytes or
(unicode) string.
1 parent 745f5e2 commit e5095e1

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

Lib/ctypes/test/test_bytes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Test where byte objects are accepted"""
12
import unittest
23
from ctypes import *
34

@@ -22,5 +23,19 @@ def test_c_wchar_p(self):
2223
c_wchar_p("foo bar")
2324
c_wchar_p(b"foo bar")
2425

26+
def test_struct(self):
27+
class X(Structure):
28+
_fields_ = [("a", c_char * 3)]
29+
30+
X("abc")
31+
X(b"abc")
32+
33+
def test_struct_W(self):
34+
class X(Structure):
35+
_fields_ = [("a", c_wchar * 3)]
36+
37+
X("abc")
38+
X(b"abc")
39+
2540
if __name__ == '__main__':
2641
unittest.main()

Modules/_ctypes/cfield.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
12601260
/* It's easier to calculate in characters than in bytes */
12611261
length /= sizeof(wchar_t);
12621262

1263-
if (PyString_Check(value)) {
1263+
if (PyBytes_Check(value)) {
12641264
value = PyUnicode_FromEncodedObject(value,
12651265
conversion_mode_encoding,
12661266
conversion_mode_errors);
@@ -1322,7 +1322,23 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
13221322
char *data;
13231323
Py_ssize_t size;
13241324

1325-
data = PyString_AsString(value);
1325+
if (PyUnicode_Check(value)) {
1326+
value = PyUnicode_AsEncodedString(value,
1327+
conversion_mode_encoding,
1328+
conversion_mode_errors);
1329+
if (value == NULL)
1330+
return NULL;
1331+
assert(PyBytes_Check(value));
1332+
} else if(PyBytes_Check(value)) {
1333+
Py_INCREF(value);
1334+
} else {
1335+
PyErr_Format(PyExc_TypeError,
1336+
"expected string, %s found",
1337+
value->ob_type->tp_name);
1338+
return NULL;
1339+
}
1340+
1341+
data = PyBytes_AsString(value);
13261342
if (!data)
13271343
return NULL;
13281344
size = strlen(data);
@@ -1339,10 +1355,13 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
13391355
"string too long (%zd, maximum length %zd)",
13401356
#endif
13411357
size, length);
1358+
Py_DECREF(value);
13421359
return NULL;
13431360
}
13441361
/* Also copy the terminating NUL character if there is space */
13451362
memcpy((char *)ptr, data, size);
1363+
1364+
Py_DECREF(value);
13461365
_RET(value);
13471366
}
13481367

0 commit comments

Comments
 (0)