forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pythongh-111495: Add tests for PyBytes and PyByteArray C API (pythonG…
- Loading branch information
1 parent
d7402d4
commit b107dc5
Showing
5 changed files
with
725 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
import unittest | ||
import sys | ||
from test.support import import_helper | ||
|
||
_testcapi = import_helper.import_module('_testcapi') | ||
|
||
NULL = None | ||
|
||
class ByteArraySubclass(bytearray): | ||
pass | ||
|
||
class BytesLike: | ||
def __init__(self, value): | ||
self.value = value | ||
def __bytes__(self): | ||
return self.value | ||
|
||
|
||
class CAPITest(unittest.TestCase): | ||
def test_check(self): | ||
# Test PyByteArray_Check() | ||
check = _testcapi.bytearray_check | ||
self.assertTrue(check(bytearray(b'abc'))) | ||
self.assertFalse(check(b'abc')) | ||
self.assertTrue(check(ByteArraySubclass(b'abc'))) | ||
self.assertFalse(check(BytesLike(b'abc'))) | ||
self.assertFalse(check(3)) | ||
self.assertFalse(check([])) | ||
self.assertFalse(check(object())) | ||
|
||
# CRASHES check(NULL) | ||
|
||
def test_checkexact(self): | ||
# Test PyByteArray_CheckExact() | ||
check = _testcapi.bytearray_checkexact | ||
self.assertTrue(check(bytearray(b'abc'))) | ||
self.assertFalse(check(b'abc')) | ||
self.assertFalse(check(ByteArraySubclass(b'abc'))) | ||
self.assertFalse(check(BytesLike(b'abc'))) | ||
self.assertFalse(check(3)) | ||
self.assertFalse(check([])) | ||
self.assertFalse(check(object())) | ||
|
||
# CRASHES check(NULL) | ||
|
||
def test_fromstringandsize(self): | ||
# Test PyByteArray_FromStringAndSize() | ||
fromstringandsize = _testcapi.bytearray_fromstringandsize | ||
|
||
self.assertEqual(fromstringandsize(b'abc'), bytearray(b'abc')) | ||
self.assertEqual(fromstringandsize(b'abc', 2), bytearray(b'ab')) | ||
self.assertEqual(fromstringandsize(b'abc\0def'), bytearray(b'abc\0def')) | ||
self.assertEqual(fromstringandsize(b'', 0), bytearray()) | ||
self.assertEqual(fromstringandsize(NULL, 0), bytearray()) | ||
self.assertEqual(len(fromstringandsize(NULL, 3)), 3) | ||
self.assertRaises(MemoryError, fromstringandsize, NULL, sys.maxsize) | ||
|
||
self.assertRaises(SystemError, fromstringandsize, b'abc', -1) | ||
self.assertRaises(SystemError, fromstringandsize, NULL, -1) | ||
|
||
def test_fromobject(self): | ||
# Test PyByteArray_FromObject() | ||
fromobject = _testcapi.bytearray_fromobject | ||
|
||
self.assertEqual(fromobject(b'abc'), bytearray(b'abc')) | ||
self.assertEqual(fromobject(bytearray(b'abc')), bytearray(b'abc')) | ||
self.assertEqual(fromobject(ByteArraySubclass(b'abc')), bytearray(b'abc')) | ||
self.assertEqual(fromobject([97, 98, 99]), bytearray(b'abc')) | ||
self.assertEqual(fromobject(3), bytearray(b'\0\0\0')) | ||
self.assertRaises(TypeError, fromobject, BytesLike(b'abc')) | ||
self.assertRaises(TypeError, fromobject, 'abc') | ||
self.assertRaises(TypeError, fromobject, object()) | ||
|
||
# CRASHES fromobject(NULL) | ||
|
||
def test_size(self): | ||
# Test PyByteArray_Size() | ||
size = _testcapi.bytearray_size | ||
|
||
self.assertEqual(size(bytearray(b'abc')), 3) | ||
self.assertEqual(size(ByteArraySubclass(b'abc')), 3) | ||
|
||
# CRASHES size(b'abc') | ||
# CRASHES size(object()) | ||
# CRASHES size(NULL) | ||
|
||
def test_asstring(self): | ||
"""Test PyByteArray_AsString()""" | ||
asstring = _testcapi.bytearray_asstring | ||
|
||
self.assertEqual(asstring(bytearray(b'abc'), 4), b'abc\0') | ||
self.assertEqual(asstring(ByteArraySubclass(b'abc'), 4), b'abc\0') | ||
self.assertEqual(asstring(bytearray(b'abc\0def'), 8), b'abc\0def\0') | ||
|
||
# CRASHES asstring(b'abc', 0) | ||
# CRASHES asstring(object()', 0) | ||
# CRASHES asstring(NULL, 0) | ||
|
||
def test_concat(self): | ||
"""Test PyByteArray_Concat()""" | ||
concat = _testcapi.bytearray_concat | ||
|
||
ba = bytearray(b'abc') | ||
self.assertEqual(concat(ba, b'def'), bytearray(b'abcdef')) | ||
self.assertEqual(ba, b'abc') | ||
|
||
self.assertEqual(concat(b'abc', b'def'), bytearray(b'abcdef')) | ||
self.assertEqual(concat(b'a\0b', b'c\0d'), bytearray(b'a\0bc\0d')) | ||
self.assertEqual(concat(bytearray(b'abc'), b'def'), bytearray(b'abcdef')) | ||
self.assertEqual(concat(b'abc', bytearray(b'def')), bytearray(b'abcdef')) | ||
self.assertEqual(concat(bytearray(b'abc'), b''), bytearray(b'abc')) | ||
self.assertEqual(concat(b'', bytearray(b'def')), bytearray(b'def')) | ||
self.assertEqual(concat(memoryview(b'xabcy')[1:4], b'def'), | ||
bytearray(b'abcdef')) | ||
self.assertEqual(concat(b'abc', memoryview(b'xdefy')[1:4]), | ||
bytearray(b'abcdef')) | ||
|
||
self.assertRaises(TypeError, concat, memoryview(b'axbycz')[::2], b'def') | ||
self.assertRaises(TypeError, concat, b'abc', memoryview(b'dxeyfz')[::2]) | ||
self.assertRaises(TypeError, concat, b'abc', 'def') | ||
self.assertRaises(TypeError, concat, 'abc', b'def') | ||
self.assertRaises(TypeError, concat, 'abc', 'def') | ||
self.assertRaises(TypeError, concat, [], b'def') | ||
self.assertRaises(TypeError, concat, b'abc', []) | ||
self.assertRaises(TypeError, concat, [], []) | ||
|
||
# CRASHES concat(NULL, bytearray(b'def')) | ||
# CRASHES concat(bytearray(b'abc'), NULL) | ||
# CRASHES concat(NULL, object()) | ||
# CRASHES concat(object(), NULL) | ||
|
||
def test_resize(self): | ||
"""Test PyByteArray_Resize()""" | ||
resize = _testcapi.bytearray_resize | ||
|
||
ba = bytearray(b'abcdef') | ||
self.assertEqual(resize(ba, 3), 0) | ||
self.assertEqual(ba, bytearray(b'abc')) | ||
self.assertEqual(resize(ba, 10), 0) | ||
self.assertEqual(len(ba), 10) | ||
self.assertEqual(ba[:3], bytearray(b'abc')) | ||
self.assertEqual(resize(ba, 2**20), 0) | ||
self.assertEqual(len(ba), 2**20) | ||
self.assertEqual(ba[:3], bytearray(b'abc')) | ||
self.assertEqual(resize(ba, 0), 0) | ||
self.assertEqual(ba, bytearray()) | ||
|
||
ba = ByteArraySubclass(b'abcdef') | ||
self.assertEqual(resize(ba, 3), 0) | ||
self.assertEqual(ba, bytearray(b'abc')) | ||
|
||
self.assertRaises(MemoryError, resize, bytearray(), sys.maxsize) | ||
self.assertRaises(MemoryError, resize, bytearray(1000), sys.maxsize) | ||
|
||
# CRASHES resize(bytearray(b'abc'), -1) | ||
# CRASHES resize(b'abc', 0) | ||
# CRASHES resize(object(), 0) | ||
# CRASHES resize(NULL, 0) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
import unittest | ||
import sys | ||
from test.support import import_helper | ||
|
||
_testcapi = import_helper.import_module('_testcapi') | ||
|
||
NULL = None | ||
|
||
class BytesSubclass(bytes): | ||
pass | ||
|
||
class BytesLike: | ||
def __init__(self, value): | ||
self.value = value | ||
def __bytes__(self): | ||
return self.value | ||
|
||
|
||
class CAPITest(unittest.TestCase): | ||
def test_check(self): | ||
# Test PyBytes_Check() | ||
check = _testcapi.bytes_check | ||
self.assertTrue(check(b'abc')) | ||
self.assertFalse(check('abc')) | ||
self.assertFalse(check(bytearray(b'abc'))) | ||
self.assertTrue(check(BytesSubclass(b'abc'))) | ||
self.assertFalse(check(BytesLike(b'abc'))) | ||
self.assertFalse(check(3)) | ||
self.assertFalse(check([])) | ||
self.assertFalse(check(object())) | ||
|
||
# CRASHES check(NULL) | ||
|
||
def test_checkexact(self): | ||
# Test PyBytes_CheckExact() | ||
check = _testcapi.bytes_checkexact | ||
self.assertTrue(check(b'abc')) | ||
self.assertFalse(check('abc')) | ||
self.assertFalse(check(bytearray(b'abc'))) | ||
self.assertFalse(check(BytesSubclass(b'abc'))) | ||
self.assertFalse(check(BytesLike(b'abc'))) | ||
self.assertFalse(check(3)) | ||
self.assertFalse(check([])) | ||
self.assertFalse(check(object())) | ||
|
||
# CRASHES check(NULL) | ||
|
||
def test_fromstringandsize(self): | ||
# Test PyBytes_FromStringAndSize() | ||
fromstringandsize = _testcapi.bytes_fromstringandsize | ||
|
||
self.assertEqual(fromstringandsize(b'abc'), b'abc') | ||
self.assertEqual(fromstringandsize(b'abc', 2), b'ab') | ||
self.assertEqual(fromstringandsize(b'abc\0def'), b'abc\0def') | ||
self.assertEqual(fromstringandsize(b'', 0), b'') | ||
self.assertEqual(fromstringandsize(NULL, 0), b'') | ||
self.assertEqual(len(fromstringandsize(NULL, 3)), 3) | ||
self.assertRaises((MemoryError, OverflowError), fromstringandsize, NULL, sys.maxsize) | ||
|
||
self.assertRaises(SystemError, fromstringandsize, b'abc', -1) | ||
self.assertRaises(SystemError, fromstringandsize, NULL, -1) | ||
|
||
def test_fromstring(self): | ||
# Test PyBytes_FromString() | ||
fromstring = _testcapi.bytes_fromstring | ||
|
||
self.assertEqual(fromstring(b'abc\0def'), b'abc') | ||
self.assertEqual(fromstring(b''), b'') | ||
|
||
# CRASHES fromstring(NULL) | ||
|
||
def test_fromobject(self): | ||
# Test PyBytes_FromObject() | ||
fromobject = _testcapi.bytes_fromobject | ||
|
||
self.assertEqual(fromobject(b'abc'), b'abc') | ||
self.assertEqual(fromobject(bytearray(b'abc')), b'abc') | ||
self.assertEqual(fromobject(BytesSubclass(b'abc')), b'abc') | ||
self.assertEqual(fromobject([97, 98, 99]), b'abc') | ||
self.assertRaises(TypeError, fromobject, 3) | ||
self.assertRaises(TypeError, fromobject, BytesLike(b'abc')) | ||
self.assertRaises(TypeError, fromobject, 'abc') | ||
self.assertRaises(TypeError, fromobject, object()) | ||
self.assertRaises(SystemError, fromobject, NULL) | ||
|
||
def test_size(self): | ||
# Test PyBytes_Size() | ||
size = _testcapi.bytes_size | ||
|
||
self.assertEqual(size(b'abc'), 3) | ||
self.assertEqual(size(BytesSubclass(b'abc')), 3) | ||
self.assertRaises(TypeError, size, bytearray(b'abc')) | ||
self.assertRaises(TypeError, size, 'abc') | ||
self.assertRaises(TypeError, size, object()) | ||
|
||
# CRASHES size(NULL) | ||
|
||
def test_asstring(self): | ||
"""Test PyBytes_AsString()""" | ||
asstring = _testcapi.bytes_asstring | ||
|
||
self.assertEqual(asstring(b'abc', 4), b'abc\0') | ||
self.assertEqual(asstring(b'abc\0def', 8), b'abc\0def\0') | ||
self.assertRaises(TypeError, asstring, 'abc', 0) | ||
self.assertRaises(TypeError, asstring, object(), 0) | ||
|
||
# CRASHES asstring(NULL, 0) | ||
|
||
def test_asstringandsize(self): | ||
"""Test PyBytes_AsStringAndSize()""" | ||
asstringandsize = _testcapi.bytes_asstringandsize | ||
asstringandsize_null = _testcapi.bytes_asstringandsize_null | ||
|
||
self.assertEqual(asstringandsize(b'abc', 4), (b'abc\0', 3)) | ||
self.assertEqual(asstringandsize(b'abc\0def', 8), (b'abc\0def\0', 7)) | ||
self.assertEqual(asstringandsize_null(b'abc', 4), b'abc\0') | ||
self.assertRaises(ValueError, asstringandsize_null, b'abc\0def', 8) | ||
self.assertRaises(TypeError, asstringandsize, 'abc', 0) | ||
self.assertRaises(TypeError, asstringandsize_null, 'abc', 0) | ||
self.assertRaises(TypeError, asstringandsize, object(), 0) | ||
self.assertRaises(TypeError, asstringandsize_null, object(), 0) | ||
|
||
# CRASHES asstringandsize(NULL, 0) | ||
# CRASHES asstringandsize_null(NULL, 0) | ||
|
||
def test_repr(self): | ||
# Test PyBytes_Repr() | ||
bytes_repr = _testcapi.bytes_repr | ||
|
||
self.assertEqual(bytes_repr(b'''abc''', 0), r"""b'abc'""") | ||
self.assertEqual(bytes_repr(b'''abc''', 1), r"""b'abc'""") | ||
self.assertEqual(bytes_repr(b'''a'b"c"d''', 0), r"""b'a\'b"c"d'""") | ||
self.assertEqual(bytes_repr(b'''a'b"c"d''', 1), r"""b'a\'b"c"d'""") | ||
self.assertEqual(bytes_repr(b'''a'b"c''', 0), r"""b'a\'b"c'""") | ||
self.assertEqual(bytes_repr(b'''a'b"c''', 1), r"""b'a\'b"c'""") | ||
self.assertEqual(bytes_repr(b'''a'b'c"d''', 0), r"""b'a\'b\'c"d'""") | ||
self.assertEqual(bytes_repr(b'''a'b'c"d''', 1), r"""b'a\'b\'c"d'""") | ||
self.assertEqual(bytes_repr(b'''a'b'c'd''', 0), r"""b'a\'b\'c\'d'""") | ||
self.assertEqual(bytes_repr(b'''a'b'c'd''', 1), r'''b"a'b'c'd"''') | ||
|
||
self.assertEqual(bytes_repr(BytesSubclass(b'abc'), 0), r"""b'abc'""") | ||
|
||
# UDEFINED bytes_repr(object(), 0) | ||
# CRASHES bytes_repr(NULL, 0) | ||
|
||
def test_concat(self, concat=None): | ||
"""Test PyBytes_Concat()""" | ||
if concat is None: | ||
concat = _testcapi.bytes_concat | ||
|
||
self.assertEqual(concat(b'abc', b'def'), b'abcdef') | ||
self.assertEqual(concat(b'a\0b', b'c\0d'), b'a\0bc\0d') | ||
self.assertEqual(concat(bytearray(b'abc'), b'def'), b'abcdef') | ||
self.assertEqual(concat(b'abc', bytearray(b'def')), b'abcdef') | ||
self.assertEqual(concat(bytearray(b'abc'), b''), b'abc') | ||
self.assertEqual(concat(b'', bytearray(b'def')), b'def') | ||
self.assertEqual(concat(memoryview(b'xabcy')[1:4], b'def'), b'abcdef') | ||
self.assertEqual(concat(b'abc', memoryview(b'xdefy')[1:4]), b'abcdef') | ||
|
||
self.assertEqual(concat(b'abc', b'def', True), b'abcdef') | ||
self.assertEqual(concat(b'abc', bytearray(b'def'), True), b'abcdef') | ||
# Check that it does not change the singleton | ||
self.assertEqual(concat(bytes(), b'def', True), b'def') | ||
self.assertEqual(len(bytes()), 0) | ||
|
||
self.assertRaises(TypeError, concat, memoryview(b'axbycz')[::2], b'def') | ||
self.assertRaises(TypeError, concat, b'abc', memoryview(b'dxeyfz')[::2]) | ||
self.assertRaises(TypeError, concat, b'abc', 'def') | ||
self.assertRaises(TypeError, concat, 'abc', b'def') | ||
self.assertRaises(TypeError, concat, 'abc', 'def') | ||
self.assertRaises(TypeError, concat, [], b'def') | ||
self.assertRaises(TypeError, concat, b'abc', []) | ||
self.assertRaises(TypeError, concat, [], []) | ||
|
||
self.assertEqual(concat(NULL, b'def'), NULL) | ||
self.assertEqual(concat(b'abc', NULL), NULL) | ||
self.assertEqual(concat(NULL, object()), NULL) | ||
self.assertEqual(concat(object(), NULL), NULL) | ||
|
||
def test_concatanddel(self): | ||
"""Test PyBytes_ConcatAndDel()""" | ||
self.test_concat(_testcapi.bytes_concatanddel) | ||
|
||
def test_decodeescape(self): | ||
"""Test PyBytes_DecodeEscape()""" | ||
decodeescape = _testcapi.bytes_decodeescape | ||
|
||
self.assertEqual(decodeescape(b'abc'), b'abc') | ||
self.assertEqual(decodeescape(br'\t\n\r\x0b\x0c\x00\\\'\"'), | ||
b'''\t\n\r\v\f\0\\'"''') | ||
self.assertEqual(decodeescape(b'\t\n\r\x0b\x0c\x00'), b'\t\n\r\v\f\0') | ||
self.assertEqual(decodeescape(br'\xa1\xa2'), b'\xa1\xa2') | ||
self.assertEqual(decodeescape(br'\2\24\241'), b'\x02\x14\xa1') | ||
self.assertEqual(decodeescape(b'\xa1\xa2'), b'\xa1\xa2') | ||
with self.assertWarns(DeprecationWarning): | ||
self.assertEqual(decodeescape(br'\u4f60'), br'\u4f60') | ||
with self.assertWarns(DeprecationWarning): | ||
self.assertEqual(decodeescape(br'\z'), br'\z') | ||
with self.assertWarns(DeprecationWarning): | ||
self.assertEqual(decodeescape(br'\541'), b'a') | ||
|
||
for b in b'\\', br'\x', br'\xa', br'\xz', br'\xaz': | ||
self.assertRaises(ValueError, decodeescape, b) | ||
self.assertRaises(ValueError, decodeescape, b, 'strict') | ||
self.assertEqual(decodeescape(br'x\xa', 'replace'), b'x?') | ||
self.assertEqual(decodeescape(br'x\xay', 'replace'), b'x?y') | ||
self.assertEqual(decodeescape(br'x\xa\xy', 'replace'), b'x??y') | ||
self.assertEqual(decodeescape(br'x\xa\xy', 'ignore'), b'xy') | ||
self.assertRaises(ValueError, decodeescape, b'\\', 'spam') | ||
self.assertEqual(decodeescape(NULL), b'') | ||
|
||
# CRASHES decodeescape(NULL, NULL, 1) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.