this repo has no description
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