this repo has no description
at trunk 111 lines 3.1 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "Python.h" 3#include "gtest/gtest.h" 4 5#include "capi-fixture.h" 6#include "capi-testing.h" 7 8namespace py { 9namespace testing { 10 11using GcModuleExtensionApiTest = ExtensionApi; 12 13TEST_F(GcModuleExtensionApiTest, GCMallocReturnsNotNullPtr) { 14 PyObject* py_obj = _PyObject_GC_Malloc(12); 15 EXPECT_NE(py_obj, nullptr); 16 PyObject_GC_Del(py_obj); 17} 18 19TEST_F(GcModuleExtensionApiTest, GCDelWithTrackedObjectSucceeds) { 20 PyObject* py_obj = _PyObject_GC_Malloc(12); 21 ASSERT_NE(py_obj, nullptr); 22 PyObject_GC_Track(py_obj); 23 PyObject_GC_Del(py_obj); 24} 25 26TEST_F(GcModuleExtensionApiTest, GCDelWithUnTrackedObjectSucceeds) { 27 PyObject* py_obj = _PyObject_GC_Malloc(12); 28 ASSERT_NE(py_obj, nullptr); 29 PyObject_GC_UnTrack(py_obj); 30 PyObject_GC_Del(py_obj); 31} 32 33TEST_F(GcModuleExtensionApiTest, GCTrackWithUnTrackedObjectSucceeds) { 34 PyObject* py_obj = _PyObject_GC_Malloc(12); 35 ASSERT_NE(py_obj, nullptr); 36 PyObject_GC_Track(py_obj); 37 PyObject_GC_UnTrack(py_obj); 38 PyObject_GC_Track(py_obj); 39 PyObject_GC_Del(py_obj); 40} 41 42TEST_F(GcModuleExtensionApiTest, NewReturnsAllocatedObject) { 43 struct BarObject { 44 PyObject_HEAD 45 int value; 46 }; 47 destructor dealloc = [](PyObject* self) { 48 PyTypeObject* type = Py_TYPE(self); 49 PyObject_GC_Del(self); 50 Py_DECREF(type); 51 }; 52 PyType_Slot slots[] = { 53 {Py_tp_dealloc, reinterpret_cast<void*>(dealloc)}, 54 {0, nullptr}, 55 }; 56 static PyType_Spec spec; 57 spec = { 58 "foo.Bar", sizeof(BarObject), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, 59 slots, 60 }; 61 PyObjectPtr type(PyType_FromSpec(&spec)); 62 Py_ssize_t refcnt = Py_REFCNT(type.get()); 63 PyObjectPtr instance(reinterpret_cast<PyObject*>( 64 PyObject_GC_New(BarObject, type.asTypeObject()))); 65 PyObject_GC_Track(instance); 66 ASSERT_NE(instance, nullptr); 67 EXPECT_EQ(PyErr_Occurred(), nullptr); 68 ASSERT_GE(Py_REFCNT(instance), 1); // CPython 69 ASSERT_LE(Py_REFCNT(instance), 2); // Pyro 70 EXPECT_EQ(Py_REFCNT(type), refcnt + 1); 71} 72 73TEST_F(GcModuleExtensionApiTest, NewVarReturnsAllocatedObject) { 74 struct BarObject { 75 PyObject_HEAD 76 int value; 77 }; 78 struct BarContainer { 79 PyObject_VAR_HEAD 80 BarObject* items[1]; 81 }; 82 destructor dealloc = [](PyObject* self) { 83 PyTypeObject* type = Py_TYPE(self); 84 PyObject_GC_Del(self); 85 Py_DECREF(type); 86 }; 87 PyType_Slot slots[] = { 88 {Py_tp_dealloc, reinterpret_cast<void*>(dealloc)}, 89 {0, nullptr}, 90 }; 91 static PyType_Spec spec; 92 spec = { 93 "foo.Bar", 94 sizeof(BarContainer), 95 sizeof(BarObject), 96 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, 97 slots, 98 }; 99 PyObjectPtr type(PyType_FromSpec(&spec)); 100 PyObjectPtr instance(reinterpret_cast<PyObject*>( 101 PyObject_GC_NewVar(BarContainer, type.asTypeObject(), 5))); 102 PyObject_GC_Track(instance); 103 ASSERT_NE(instance, nullptr); 104 EXPECT_EQ(PyErr_Occurred(), nullptr); 105 ASSERT_GE(Py_REFCNT(instance), 1); // CPython 106 ASSERT_LE(Py_REFCNT(instance), 2); // Pyro 107 EXPECT_EQ(Py_SIZE(instance.get()), 5); 108} 109 110} // namespace testing 111} // namespace py