Issue 6239: ctypes.c_char_p return value must return bytes.
This commit is contained in:
parent
b6b13248e5
commit
8b93952621
|
@ -73,7 +73,7 @@ class Test(unittest.TestCase):
|
|||
# This didn't work: bad argument to internal function
|
||||
s = c_char_p("hiho")
|
||||
self.assertEqual(cast(cast(s, c_void_p), c_char_p).value,
|
||||
"hiho")
|
||||
b"hiho")
|
||||
|
||||
try:
|
||||
c_wchar_p
|
||||
|
|
|
@ -97,8 +97,8 @@ class CFuncPtrTestCase(unittest.TestCase):
|
|||
strchr = lib.my_strchr
|
||||
strchr.restype = c_char_p
|
||||
strchr.argtypes = (c_char_p, c_char)
|
||||
self.assertEqual(strchr("abcdefghi", "b"), "bcdefghi")
|
||||
self.assertEqual(strchr("abcdefghi", "x"), None)
|
||||
self.assertEqual(strchr(b"abcdefghi", b"b"), b"bcdefghi")
|
||||
self.assertEqual(strchr(b"abcdefghi", b"x"), None)
|
||||
|
||||
|
||||
strtok = lib.my_strtok
|
||||
|
@ -111,16 +111,16 @@ class CFuncPtrTestCase(unittest.TestCase):
|
|||
size = len(init) + 1
|
||||
return (c_char*size)(*init)
|
||||
|
||||
s = "a\nb\nc"
|
||||
s = b"a\nb\nc"
|
||||
b = c_string(s)
|
||||
|
||||
## b = (c_char * (len(s)+1))()
|
||||
## b.value = s
|
||||
|
||||
## b = c_string(s)
|
||||
self.assertEqual(strtok(b, b"\n"), "a")
|
||||
self.assertEqual(strtok(None, b"\n"), "b")
|
||||
self.assertEqual(strtok(None, b"\n"), "c")
|
||||
self.assertEqual(strtok(b, b"\n"), b"a")
|
||||
self.assertEqual(strtok(None, b"\n"), b"b")
|
||||
self.assertEqual(strtok(None, b"\n"), b"c")
|
||||
self.assertEqual(strtok(None, b"\n"), None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -177,7 +177,7 @@ class FunctionTestCase(unittest.TestCase):
|
|||
f.argtypes = None
|
||||
f.restype = c_char_p
|
||||
result = f(b"123")
|
||||
self.assertEqual(result, "123")
|
||||
self.assertEqual(result, b"123")
|
||||
|
||||
result = f(None)
|
||||
self.assertEqual(result, None)
|
||||
|
|
|
@ -17,9 +17,9 @@ class MyTestCase(unittest.TestCase):
|
|||
SetPointerType(lpcell, cell)
|
||||
|
||||
c1 = cell()
|
||||
c1.name = "foo"
|
||||
c1.name = b"foo"
|
||||
c2 = cell()
|
||||
c2.name = "bar"
|
||||
c2.name = b"bar"
|
||||
|
||||
c1.next = pointer(c2)
|
||||
c2.next = pointer(c1)
|
||||
|
@ -30,7 +30,7 @@ class MyTestCase(unittest.TestCase):
|
|||
for i in range(8):
|
||||
result.append(p.name)
|
||||
p = p.next[0]
|
||||
self.assertEqual(result, ["foo", "bar"] * 4)
|
||||
self.assertEqual(result, [b"foo", b"bar"] * 4)
|
||||
|
||||
# to not leak references, we must clean _pointer_type_cache
|
||||
from ctypes import _pointer_type_cache
|
||||
|
|
|
@ -37,7 +37,7 @@ class MemFunctionsTest(unittest.TestCase):
|
|||
|
||||
def test_cast(self):
|
||||
a = (c_ubyte * 32)(*map(ord, "abcdef"))
|
||||
self.assertEqual(cast(a, c_char_p).value, "abcdef")
|
||||
self.assertEqual(cast(a, c_char_p).value, b"abcdef")
|
||||
self.assertEqual(cast(a, POINTER(c_byte))[:7],
|
||||
[97, 98, 99, 100, 101, 102, 0])
|
||||
self.assertEqual(cast(a, POINTER(c_byte))[:7:],
|
||||
|
|
|
@ -24,7 +24,7 @@ assigned from Python must be kept.
|
|||
>>> array._objects
|
||||
{'4': b'foo bar'}
|
||||
>>> array[4]
|
||||
'foo bar'
|
||||
b'foo bar'
|
||||
>>>
|
||||
|
||||
It gets more complicated when the ctypes instance itself is contained
|
||||
|
|
|
@ -140,10 +140,10 @@ class PointersTestCase(unittest.TestCase):
|
|||
func.restype = c_char_p
|
||||
argv = (c_char_p * 2)()
|
||||
argc = c_int( 2 )
|
||||
argv[0] = 'hello'
|
||||
argv[1] = 'world'
|
||||
argv[0] = b'hello'
|
||||
argv[1] = b'world'
|
||||
result = func( byref(argc), argv )
|
||||
assert result == 'world', result
|
||||
self.assertEqual(result, b'world')
|
||||
|
||||
def test_bug_1467852(self):
|
||||
# http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702
|
||||
|
|
|
@ -92,14 +92,14 @@ class CharPointersTestCase(unittest.TestCase):
|
|||
func.argtypes = POINTER(c_char),
|
||||
|
||||
self.assertEqual(None, func(None))
|
||||
self.assertEqual("123", func("123"))
|
||||
self.assertEqual(b"123", func(b"123"))
|
||||
self.assertEqual(None, func(c_char_p(None)))
|
||||
self.assertEqual("123", func(c_char_p("123")))
|
||||
self.assertEqual(b"123", func(c_char_p(b"123")))
|
||||
|
||||
self.assertEqual("123", func(c_buffer("123")))
|
||||
ca = c_char("a")
|
||||
self.assertEqual("a", func(pointer(ca))[0])
|
||||
self.assertEqual("a", func(byref(ca))[0])
|
||||
self.assertEqual(b"123", func(c_buffer(b"123")))
|
||||
ca = c_char(b"a")
|
||||
self.assertEqual(ord(b"a"), func(pointer(ca))[0])
|
||||
self.assertEqual(ord(b"a"), func(byref(ca))[0])
|
||||
|
||||
def test_c_char_p_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
|
@ -107,14 +107,14 @@ class CharPointersTestCase(unittest.TestCase):
|
|||
func.argtypes = c_char_p,
|
||||
|
||||
self.assertEqual(None, func(None))
|
||||
self.assertEqual("123", func("123"))
|
||||
self.assertEqual(b"123", func(b"123"))
|
||||
self.assertEqual(None, func(c_char_p(None)))
|
||||
self.assertEqual("123", func(c_char_p("123")))
|
||||
self.assertEqual(b"123", func(c_char_p(b"123")))
|
||||
|
||||
self.assertEqual("123", func(c_buffer("123")))
|
||||
ca = c_char("a")
|
||||
self.assertEqual("a", func(pointer(ca))[0])
|
||||
self.assertEqual("a", func(byref(ca))[0])
|
||||
self.assertEqual(b"123", func(c_buffer(b"123")))
|
||||
ca = c_char(b"a")
|
||||
self.assertEqual(ord(b"a"), func(pointer(ca))[0])
|
||||
self.assertEqual(ord(b"a"), func(byref(ca))[0])
|
||||
|
||||
def test_c_void_p_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
|
@ -122,14 +122,14 @@ class CharPointersTestCase(unittest.TestCase):
|
|||
func.argtypes = c_void_p,
|
||||
|
||||
self.assertEqual(None, func(None))
|
||||
self.assertEqual("123", func(b"123"))
|
||||
self.assertEqual("123", func(c_char_p("123")))
|
||||
self.assertEqual(b"123", func(b"123"))
|
||||
self.assertEqual(b"123", func(c_char_p(b"123")))
|
||||
self.assertEqual(None, func(c_char_p(None)))
|
||||
|
||||
self.assertEqual("123", func(c_buffer("123")))
|
||||
self.assertEqual(b"123", func(c_buffer(b"123")))
|
||||
ca = c_char("a")
|
||||
self.assertEqual("a", func(pointer(ca))[0])
|
||||
self.assertEqual("a", func(byref(ca))[0])
|
||||
self.assertEqual(ord(b"a"), func(pointer(ca))[0])
|
||||
self.assertEqual(ord(b"a"), func(byref(ca))[0])
|
||||
|
||||
func(byref(c_int()))
|
||||
func(pointer(c_int()))
|
||||
|
|
|
@ -69,7 +69,7 @@ class CallbackTracbackTestCase(unittest.TestCase):
|
|||
out = self.capture_stderr(cb, "spam")
|
||||
self.assertEqual(out.splitlines()[-1],
|
||||
"TypeError: "
|
||||
"unsupported operand type(s) for /: 'int' and 'str'")
|
||||
"unsupported operand type(s) for /: 'int' and 'bytes'")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -12,12 +12,12 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
|
|||
get_strchr = dll.get_strchr
|
||||
get_strchr.restype = CFUNCTYPE(c_char_p, c_char_p, c_char)
|
||||
strchr = get_strchr()
|
||||
self.assertEqual(strchr("abcdef", "b"), "bcdef")
|
||||
self.assertEqual(strchr("abcdef", "x"), None)
|
||||
self.assertEqual(strchr("abcdef", 98), "bcdef")
|
||||
self.assertEqual(strchr("abcdef", 107), None)
|
||||
self.assertRaises(ArgumentError, strchr, "abcdef", 3.0)
|
||||
self.assertRaises(TypeError, strchr, "abcdef")
|
||||
self.assertEqual(strchr(b"abcdef", b"b"), b"bcdef")
|
||||
self.assertEqual(strchr(b"abcdef", b"x"), None)
|
||||
self.assertEqual(strchr(b"abcdef", 98), b"bcdef")
|
||||
self.assertEqual(strchr(b"abcdef", 107), None)
|
||||
self.assertRaises(ArgumentError, strchr, b"abcdef", 3.0)
|
||||
self.assertRaises(TypeError, strchr, b"abcdef")
|
||||
|
||||
def test_without_prototype(self):
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
|
|
|
@ -109,7 +109,7 @@ class SlicesTestCase(unittest.TestCase):
|
|||
dll.my_strdup.errcheck = errcheck
|
||||
try:
|
||||
res = dll.my_strdup(s)
|
||||
self.assertEqual(res, s.decode())
|
||||
self.assertEqual(res, s)
|
||||
finally:
|
||||
del dll.my_strdup.errcheck
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ class StringPtrTestCase(unittest.TestCase):
|
|||
# c_char_p and Python string is compatible
|
||||
# c_char_p and c_buffer is NOT compatible
|
||||
self.assertEqual(x.str, None)
|
||||
x.str = "Hello, World"
|
||||
self.assertEqual(x.str, "Hello, World")
|
||||
b = c_buffer("Hello, World")
|
||||
self.assertRaises(TypeError, setattr, x, "str", b)
|
||||
x.str = b"Hello, World"
|
||||
self.assertEqual(x.str, b"Hello, World")
|
||||
b = c_buffer(b"Hello, World")
|
||||
self.assertRaises(TypeError, setattr, x, b"str", b)
|
||||
|
||||
|
||||
def test_functions(self):
|
||||
|
@ -48,15 +48,15 @@ class StringPtrTestCase(unittest.TestCase):
|
|||
# c_char_p and Python string is compatible
|
||||
# c_char_p and c_buffer are now compatible
|
||||
strchr.argtypes = c_char_p, c_char
|
||||
self.assertEqual(strchr("abcdef", "c"), "cdef")
|
||||
self.assertEqual(strchr(c_buffer("abcdef"), "c"), "cdef")
|
||||
self.assertEqual(strchr(b"abcdef", b"c"), b"cdef")
|
||||
self.assertEqual(strchr(c_buffer(b"abcdef"), b"c"), b"cdef")
|
||||
|
||||
# POINTER(c_char) and Python string is NOT compatible
|
||||
# POINTER(c_char) and c_buffer() is compatible
|
||||
strchr.argtypes = POINTER(c_char), c_char
|
||||
buf = c_buffer("abcdef")
|
||||
self.assertEqual(strchr(buf, "c"), "cdef")
|
||||
self.assertEqual(strchr("abcdef", "c"), "cdef")
|
||||
buf = c_buffer(b"abcdef")
|
||||
self.assertEqual(strchr(buf, b"c"), b"cdef")
|
||||
self.assertEqual(strchr(b"abcdef", b"c"), b"cdef")
|
||||
|
||||
# XXX These calls are dangerous, because the first argument
|
||||
# to strchr is no longer valid after the function returns!
|
||||
|
|
|
@ -94,15 +94,15 @@ else:
|
|||
|
||||
def test_ascii_ignore(self):
|
||||
ctypes.set_conversion_mode("ascii", "ignore")
|
||||
self.assertEqual(func("abc"), "abc")
|
||||
self.assertEqual(func("abc"), "abc")
|
||||
self.assertEqual(func("\xe4\xf6\xfc\xdf"), "")
|
||||
self.assertEqual(func("abc"), b"abc")
|
||||
self.assertEqual(func("abc"), b"abc")
|
||||
self.assertEqual(func("\xe4\xf6\xfc\xdf"), b"")
|
||||
|
||||
def test_ascii_replace(self):
|
||||
ctypes.set_conversion_mode("ascii", "replace")
|
||||
self.assertEqual(func("abc"), "abc")
|
||||
self.assertEqual(func("abc"), "abc")
|
||||
self.assertEqual(func("\xe4\xf6\xfc\xdf"), "????")
|
||||
self.assertEqual(func("abc"), b"abc")
|
||||
self.assertEqual(func("abc"), b"abc")
|
||||
self.assertEqual(func("\xe4\xf6\xfc\xdf"), b"????")
|
||||
|
||||
def test_buffers(self):
|
||||
ctypes.set_conversion_mode("ascii", "strict")
|
||||
|
|
|
@ -68,6 +68,8 @@ C-API
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #6239: ctypes.c_char_p return value must return bytes.
|
||||
|
||||
- Issue #6838: Use a list to accumulate the value instead of
|
||||
repeatedly concatenating strings in http.client's
|
||||
HTTPResponse._read_chunked providing a significant speed increase
|
||||
|
|
|
@ -1428,7 +1428,8 @@ z_get(void *ptr, Py_ssize_t size)
|
|||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return PyUnicode_FromString(*(char **)ptr);
|
||||
return PyBytes_FromStringAndSize(*(char **)ptr,
|
||||
strlen(*(char **)ptr));
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
|
Loading…
Reference in New Issue