mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Fix undefined memoryview format (#2223)
* Fix undefined memoryview format * Add missing <algorithm> header * Add workaround for py27 array compatibility * Workaround py27 memoryview behavior * Fix memoryview constructor from buffer_info * Workaround PyMemoryView_FromMemory availability in py27 * Fix up memoryview tests * Update memoryview test from buffer to check signedness * Use static factory method to create memoryview * Remove ndim arg from memoryview::frombuffer and add tests * Allow ndim=0 memoryview and documentation fixup * Use void* to align to frombuffer method signature * Add const variants of frombuffer and frommemory * Add memory view section in doc * Fix docs * Add test for null buffer * Workaround py27 nullptr behavior in test * Rename frombuffer to from_buffer
This commit is contained in:
@@ -278,3 +278,70 @@ def test_number_protocol():
|
||||
def test_list_slicing():
|
||||
li = list(range(100))
|
||||
assert li[::2] == m.test_list_slicing(li)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('method, args, fmt, expected_view', [
|
||||
(m.test_memoryview_object, (b'red',), 'B', b'red'),
|
||||
(m.test_memoryview_buffer_info, (b'green',), 'B', b'green'),
|
||||
(m.test_memoryview_from_buffer, (False,), 'h', [3, 1, 4, 1, 5]),
|
||||
(m.test_memoryview_from_buffer, (True,), 'H', [2, 7, 1, 8]),
|
||||
(m.test_memoryview_from_buffer_nativeformat, (), '@i', [4, 7, 5]),
|
||||
])
|
||||
def test_memoryview(method, args, fmt, expected_view):
|
||||
view = method(*args)
|
||||
assert isinstance(view, memoryview)
|
||||
assert view.format == fmt
|
||||
if isinstance(expected_view, bytes) or sys.version_info[0] >= 3:
|
||||
view_as_list = list(view)
|
||||
else:
|
||||
# Using max to pick non-zero byte (big-endian vs little-endian).
|
||||
view_as_list = [max([ord(c) for c in s]) for s in view]
|
||||
assert view_as_list == list(expected_view)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not hasattr(sys, 'getrefcount'),
|
||||
reason='getrefcount is not available')
|
||||
@pytest.mark.parametrize('method', [
|
||||
m.test_memoryview_object,
|
||||
m.test_memoryview_buffer_info,
|
||||
])
|
||||
def test_memoryview_refcount(method):
|
||||
buf = b'\x0a\x0b\x0c\x0d'
|
||||
ref_before = sys.getrefcount(buf)
|
||||
view = method(buf)
|
||||
ref_after = sys.getrefcount(buf)
|
||||
assert ref_before < ref_after
|
||||
assert list(view) == list(buf)
|
||||
|
||||
|
||||
def test_memoryview_from_buffer_empty_shape():
|
||||
view = m.test_memoryview_from_buffer_empty_shape()
|
||||
assert isinstance(view, memoryview)
|
||||
assert view.format == 'B'
|
||||
if sys.version_info.major < 3:
|
||||
# Python 2 behavior is weird, but Python 3 (the future) is fine.
|
||||
assert bytes(view).startswith(b'<memory at ')
|
||||
else:
|
||||
assert bytes(view) == b''
|
||||
|
||||
|
||||
def test_test_memoryview_from_buffer_invalid_strides():
|
||||
with pytest.raises(RuntimeError):
|
||||
m.test_memoryview_from_buffer_invalid_strides()
|
||||
|
||||
|
||||
def test_test_memoryview_from_buffer_nullptr():
|
||||
if sys.version_info.major < 3:
|
||||
m.test_memoryview_from_buffer_nullptr()
|
||||
else:
|
||||
with pytest.raises(ValueError):
|
||||
m.test_memoryview_from_buffer_nullptr()
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info.major < 3, reason='API not available')
|
||||
def test_memoryview_from_memory():
|
||||
view = m.test_memoryview_from_memory()
|
||||
assert isinstance(view, memoryview)
|
||||
assert view.format == 'B'
|
||||
assert bytes(view) == b'\xff\xe1\xab\x37'
|
||||
|
||||
Reference in New Issue
Block a user