Author: Armin Rigo <armin.r...@gmail.com> Branch: Changeset: r91555:60d070027d70 Date: 2017-06-07 06:05 +0000 http://bitbucket.org/pypy/pypy/changeset/60d070027d70/
Log: Merged in palecsandru/pypy_ctypes_char_indexing/ctypes_char_indexing (pull request #552) Indexing into char* behaves differently than CPython diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -76,12 +76,16 @@ return self._type_._alignmentofinstances() def _CData_output(self, resarray, base=None, index=-1): - # this seems to be a string if we're array of char, surprise! - from ctypes import c_char, c_wchar - if self._type_ is c_char: - return _rawffi.charp2string(resarray.buffer, self._length_) - if self._type_ is c_wchar: - return _rawffi.wcharp2unicode(resarray.buffer, self._length_) + from _rawffi.alt import types + # If a char_p or unichar_p is received, skip the string interpretation + if base._ffiargtype != types.Pointer(types.char_p) and \ + base._ffiargtype != types.Pointer(types.unichar_p): + # this seems to be a string if we're array of char, surprise! + from ctypes import c_char, c_wchar + if self._type_ is c_char: + return _rawffi.charp2string(resarray.buffer, self._length_) + if self._type_ is c_wchar: + return _rawffi.wcharp2unicode(resarray.buffer, self._length_) res = self.__new__(self) ffiarray = self._ffiarray.fromaddress(resarray.buffer, self._length_) res._buffer = ffiarray diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_array.py b/pypy/module/test_lib_pypy/ctypes_tests/test_array.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_array.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_array.py @@ -138,4 +138,39 @@ x.y = 3 y[1] = x assert y[1].y == 3 + + def test_output_simple(self): + A = c_char * 10 + TP = POINTER(A) + x = TP(A()) + assert repr(x[0]) != "''" + assert isinstance(repr(x[0]), bytes) + + A = c_wchar * 10 + TP = POINTER(A) + x = TP(A()) + assert repr(x[0]) != "''" + assert isinstance(repr(x[0]), bytes) + + def test_output_complex_test(self): + class Car(Structure): + _fields_ = [("brand", c_char * 10), + ("speed", c_float), + ("owner", c_char * 10)] + + assert Car("abcdefghi", 42.0, "12345").brand == "abcdefghi" + assert Car("abcdefghio", 42.0, "12345").brand == "abcdefghio" + raises(ValueError, Car, "abcdefghiop", 42.0, "12345") + + A = Car._fields_[2][1] + TP = POINTER(A) + x = TP(A()) + assert repr(x[0]) != "''" + assert isinstance(repr(x[0]), bytes) + + c = Car() + c.brand = "abcdex" + c.speed = 42.0 + c.owner = "12345" + assert isinstance(repr(c.brand), bytes) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit