this repo has no description
at trunk 113 lines 4.0 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include <cstring> 3 4#include "Python.h" 5#include "gtest/gtest.h" 6 7#include "capi-fixture.h" 8#include "capi-testing.h" 9 10namespace py { 11namespace testing { 12 13using MemoryViewExtensionApiTest = ExtensionApi; 14 15TEST_F(MemoryViewExtensionApiTest, FromObjectWithNoneRaisesTypeError) { 16 PyObjectPtr result(PyMemoryView_FromObject(Py_None)); 17 ASSERT_EQ(result, nullptr); 18 ASSERT_NE(PyErr_Occurred(), nullptr); 19 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 20} 21 22TEST_F(MemoryViewExtensionApiTest, FromObjectWithBytesReturnsMemoryView) { 23 PyObjectPtr bytes(PyBytes_FromString("")); 24 PyObjectPtr result(PyMemoryView_FromObject(bytes)); 25 EXPECT_EQ(PyErr_Occurred(), nullptr); 26 EXPECT_TRUE(PyMemoryView_Check(result)); 27} 28 29TEST_F(MemoryViewExtensionApiTest, FromObjectWithMemoryViewReturnsMemoryView) { 30 PyObjectPtr bytes(PyBytes_FromString("")); 31 PyObjectPtr view(PyMemoryView_FromObject(bytes)); 32 ASSERT_TRUE(PyMemoryView_Check(view)); 33 PyObjectPtr result(PyMemoryView_FromObject(view)); 34 EXPECT_EQ(PyErr_Occurred(), nullptr); 35 EXPECT_TRUE(PyMemoryView_Check(result)); 36 EXPECT_NE(result.get(), view.get()); 37} 38 39TEST_F(MemoryViewExtensionApiTest, 40 FromObjectWithBufferProtocolReturnsMemoryView) { 41 static char contents[] = "hello world"; 42 static Py_ssize_t contents_len = std::strlen(contents); 43 getbufferproc getbuffer_func = [](PyObject* obj, Py_buffer* view, int flags) { 44 return PyBuffer_FillInfo(view, obj, ::strdup(contents), contents_len, 45 /*readonly=*/1, flags); 46 }; 47 releasebufferproc releasebuffer_func = [](PyObject*, Py_buffer* view) { 48 std::free(view->buf); 49 view->obj = nullptr; 50 }; 51 PyType_Slot slots[] = { 52 {Py_bf_getbuffer, reinterpret_cast<void*>(getbuffer_func)}, 53 {Py_bf_releasebuffer, reinterpret_cast<void*>(releasebuffer_func)}, 54 {0, nullptr}, 55 }; 56 static PyType_Spec spec; 57 spec = { 58 "foo.Bar", 0, 0, Py_TPFLAGS_DEFAULT, slots, 59 }; 60 PyObjectPtr type(PyType_FromSpec(&spec)); 61 ASSERT_NE(type, nullptr); 62 PyObjectPtr instance(PyObject_CallFunction(type, nullptr)); 63 ASSERT_NE(instance, nullptr); 64 PyObjectPtr view(PyMemoryView_FromObject(instance)); 65 ASSERT_NE(view, nullptr); 66 EXPECT_EQ(PyErr_Occurred(), nullptr); 67 EXPECT_TRUE(PyMemoryView_Check(view)); 68} 69 70TEST_F(MemoryViewExtensionApiTest, 71 DunderNewWithBufferProtocolReturnsMemoryView) { 72 static char contents[] = "hello world"; 73 static Py_ssize_t contents_len = std::strlen(contents); 74 getbufferproc getbuffer_func = [](PyObject* obj, Py_buffer* view, int flags) { 75 return PyBuffer_FillInfo(view, obj, ::strdup(contents), contents_len, 76 /*readonly=*/1, flags); 77 }; 78 releasebufferproc releasebuffer_func = [](PyObject*, Py_buffer* view) { 79 std::free(view->buf); 80 view->obj = nullptr; 81 }; 82 PyType_Slot slots[] = { 83 {Py_bf_getbuffer, reinterpret_cast<void*>(getbuffer_func)}, 84 {Py_bf_releasebuffer, reinterpret_cast<void*>(releasebuffer_func)}, 85 {0, nullptr}, 86 }; 87 static PyType_Spec spec; 88 spec = { 89 "foo.Bar", 0, 0, Py_TPFLAGS_DEFAULT, slots, 90 }; 91 PyObjectPtr type(PyType_FromSpec(&spec)); 92 ASSERT_NE(type, nullptr); 93 PyObjectPtr instance(PyObject_CallFunction(type, nullptr)); 94 ASSERT_NE(instance, nullptr); 95 PyObjectPtr view(PyObject_CallFunction( 96 reinterpret_cast<PyObject*>(&PyMemoryView_Type), "O", instance.get())); 97 ASSERT_NE(view, nullptr); 98 EXPECT_EQ(PyErr_Occurred(), nullptr); 99 EXPECT_TRUE(PyMemoryView_Check(view)); 100} 101 102TEST_F(MemoryViewExtensionApiTest, FromMemoryReturnsMemoryView) { 103 const int size = 5; 104 int memory[size] = {0}; 105 PyObjectPtr result(PyMemoryView_FromMemory(reinterpret_cast<char*>(memory), 106 size, PyBUF_READ)); 107 EXPECT_NE(result, nullptr); 108 EXPECT_EQ(PyErr_Occurred(), nullptr); 109 EXPECT_TRUE(PyMemoryView_Check(result)); 110} 111 112} // namespace testing 113} // namespace py