diff --git a/Documentation/release/dev/python-wrap-char.md b/Documentation/release/dev/python-wrap-char.md new file mode 100644 index 0000000000000000000000000000000000000000..cedbd7cac3866c1367227fbd1b81d0de812ece89 --- /dev/null +++ b/Documentation/release/dev/python-wrap-char.md @@ -0,0 +1,9 @@ +## Change to the Python `char` wrapping + +If a VTK method parameter is type `char`, you can pass any python string `s` +where `ord(s) < 256`, instead of being restricted to ASCII characters. If a +VTK method returns `char`, then return value is always a python `str` with +a length of 1, with the null char being `'\x00'`. Previously, a `char` value +of zero would be returned as `''` (empty string), and calling `ord()` on an +empty string raises an exception. Now, calling `ord()` on the returned value +will never raise an exception. diff --git a/Wrapping/Python/Testing/Python/TestChar.py b/Wrapping/Python/Testing/Python/TestChar.py index c95d7026ead6cc1138e7d0ca395438436ad51134..88e54fcaa53570e33d6c84ec6ba81d9b3d052b97 100644 --- a/Wrapping/Python/Testing/Python/TestChar.py +++ b/Wrapping/Python/Testing/Python/TestChar.py @@ -21,12 +21,12 @@ class TestChar(Testing.vtkTest): """Pass a unicode string and get it back. """ a = vtkCharArray() - a.InsertNextValue('') + a.InsertNextValue('\0') a.InsertNextValue('%') a.InsertNextValue('\u00b5') # MICRON a.InsertNextValue('\u00d7') # MULTIPLICATION SIGN c = a.GetValue(0) - self.assertEqual(c, '') + self.assertEqual(c, '\0') c = a.GetValue(1) self.assertEqual(c, '%') c = a.GetValue(2) @@ -38,12 +38,12 @@ class TestChar(Testing.vtkTest): """Pass a bytes object, get back a unicode object """ a = vtkCharArray() - a.InsertNextValue(b'') + a.InsertNextValue(b'\0') a.InsertNextValue(b'%') a.InsertNextValue(b'\xb5') # MICRON a.InsertNextValue(b'\xd7') # MULTIPLICATION SIGN c = a.GetValue(0) - self.assertEqual(c, '') + self.assertEqual(c, '\0') c = a.GetValue(1) self.assertEqual(c, '%') c = a.GetValue(2) diff --git a/Wrapping/PythonCore/vtkPythonArgs.h b/Wrapping/PythonCore/vtkPythonArgs.h index 1aca5b9db3ea6ebc76fde6d288aa991ce4bfa3e0..c55f0e64a278447b9cfc18a9246d8bfce7e964be 100644 --- a/Wrapping/PythonCore/vtkPythonArgs.h +++ b/Wrapping/PythonCore/vtkPythonArgs.h @@ -891,20 +891,23 @@ inline PyObject* vtkPythonArgs::BuildValue(const std::string& a) inline PyObject* vtkPythonArgs::BuildValue(char a) { - char b[4] = { a, '\0', '\0', '\0' }; + char b[2] = { a, '\0' }; + Py_ssize_t n = 1; if ((static_cast<unsigned char>(a) & 0xc0) == 0x80) { // convert value [128,191] to equivalent utf-8 sequence b[0] = '\xc2'; b[1] = a; + n = 2; } else if ((static_cast<unsigned char>(a) & 0xc0) == 0xc0) { // convert value [192,255] to equivalent utf-8 sequence b[0] = '\xc3'; b[1] = a ^ '\x40'; + n = 2; } - return PyUnicode_FromString(b); + return PyUnicode_FromStringAndSize(b, n); } inline PyObject* vtkPythonArgs::BuildValue(double a)