[Python-3000-checkins] r56341 - in python/branches/py3k-struni: Lib/ctypes/test/test_bytes.py Modules/_ctypes/cfield.c

thomas.heller python-3000-checkins at python.org
Fri Jul 13 13:19:35 CEST 2007


Author: thomas.heller
Date: Fri Jul 13 13:19:35 2007
New Revision: 56341

Modified:
   python/branches/py3k-struni/Lib/ctypes/test/test_bytes.py
   python/branches/py3k-struni/Modules/_ctypes/cfield.c
Log:
Structure fields of type c_char array or c_wchar array accept bytes or
(unicode) string.


Modified: python/branches/py3k-struni/Lib/ctypes/test/test_bytes.py
==============================================================================
--- python/branches/py3k-struni/Lib/ctypes/test/test_bytes.py	(original)
+++ python/branches/py3k-struni/Lib/ctypes/test/test_bytes.py	Fri Jul 13 13:19:35 2007
@@ -1,3 +1,4 @@
+"""Test where byte objects are accepted"""
 import unittest
 from ctypes import *
 
@@ -22,5 +23,19 @@
         c_wchar_p("foo bar")
         c_wchar_p(b"foo bar")
 
+    def test_struct(self):
+        class X(Structure):
+            _fields_ = [("a", c_char * 3)]
+
+        X("abc")
+        X(b"abc")
+
+    def test_struct_W(self):
+        class X(Structure):
+            _fields_ = [("a", c_wchar * 3)]
+
+        X("abc")
+        X(b"abc")
+
 if __name__ == '__main__':
     unittest.main()

Modified: python/branches/py3k-struni/Modules/_ctypes/cfield.c
==============================================================================
--- python/branches/py3k-struni/Modules/_ctypes/cfield.c	(original)
+++ python/branches/py3k-struni/Modules/_ctypes/cfield.c	Fri Jul 13 13:19:35 2007
@@ -1260,7 +1260,7 @@
 	/* It's easier to calculate in characters than in bytes */
 	length /= sizeof(wchar_t);
 
-	if (PyString_Check(value)) {
+	if (PyBytes_Check(value)) {
 		value = PyUnicode_FromEncodedObject(value,
 						    conversion_mode_encoding,
 						    conversion_mode_errors);
@@ -1322,7 +1322,23 @@
 	char *data;
 	Py_ssize_t size;
 
-	data = PyString_AsString(value);
+	if (PyUnicode_Check(value)) {
+		value = PyUnicode_AsEncodedString(value,
+						  conversion_mode_encoding,
+						  conversion_mode_errors);
+		if (value == NULL)
+			return NULL;
+		assert(PyBytes_Check(value));
+	} else if(PyBytes_Check(value)) {
+		Py_INCREF(value);
+	} else {
+		PyErr_Format(PyExc_TypeError,
+			     "expected string, %s found",
+			     value->ob_type->tp_name);
+		return NULL;
+	}
+
+	data = PyBytes_AsString(value);
 	if (!data)
 		return NULL;
 	size = strlen(data);
@@ -1339,10 +1355,13 @@
 			     "string too long (%zd, maximum length %zd)",
 #endif
 			     size, length);
+		Py_DECREF(value);
 		return NULL;
 	}
 	/* Also copy the terminating NUL character if there is space */
 	memcpy((char *)ptr, data, size);
+
+	Py_DECREF(value);
 	_RET(value);
 }
 


More information about the Python-3000-checkins mailing list