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 ModSupportExtensionApiTest = ExtensionApi;
12
13TEST_F(ModSupportExtensionApiTest, AddObjectAddsToModule) {
14 static PyModuleDef def;
15 def = {
16 PyModuleDef_HEAD_INIT,
17 "mymodule",
18 };
19
20 testing::PyObjectPtr module(PyModule_Create(&def));
21 ASSERT_NE(module, nullptr);
22
23 PyObject* obj = PyList_New(1);
24 int myobj = PyModule_AddObject(module, "myobj", obj);
25 ASSERT_NE(myobj, -1);
26
27 ASSERT_EQ(testing::moduleSet("__main__", "mymodule", module), 0);
28 PyRun_SimpleString("x = mymodule.myobj");
29
30 testing::PyObjectPtr x(testing::mainModuleGet("x"));
31 ASSERT_TRUE(PyList_CheckExact(x));
32}
33
34TEST_F(ModSupportExtensionApiTest, RepeatedAddObjectOverwritesValue) {
35 static PyModuleDef def;
36 def = {
37 PyModuleDef_HEAD_INIT,
38 "mymodule",
39 };
40
41 testing::PyObjectPtr module(PyModule_Create(&def));
42 ASSERT_NE(module, nullptr);
43
44 PyObject* listobj = PyList_New(1);
45 int myobj = PyModule_AddObject(module, "myobj", listobj);
46 ASSERT_NE(myobj, -1);
47
48 PyObject* tupleobj = PyTuple_New(1);
49 myobj = PyModule_AddObject(module, "myobj", tupleobj);
50 ASSERT_NE(myobj, -1);
51
52 ASSERT_EQ(testing::moduleSet("__main__", "mymodule", module), 0);
53 PyRun_SimpleString("x = mymodule.myobj");
54
55 testing::PyObjectPtr x(testing::mainModuleGet("x"));
56 ASSERT_FALSE(PyList_CheckExact(x));
57 ASSERT_TRUE(PyTuple_CheckExact(x));
58}
59
60TEST_F(ModSupportExtensionApiTest, AddStringConstantAddsToModule) {
61 static PyModuleDef def;
62 def = {
63 PyModuleDef_HEAD_INIT,
64 "mymodule",
65 };
66
67 testing::PyObjectPtr module(PyModule_Create(&def));
68 ASSERT_NE(module, nullptr);
69
70 const char* c_str = "string";
71 ASSERT_EQ(PyModule_AddStringConstant(module, "mystr", c_str), 0);
72 EXPECT_EQ(PyErr_Occurred(), nullptr);
73
74 testing::PyObjectPtr str(PyObject_GetAttrString(module, "mystr"));
75 EXPECT_TRUE(isUnicodeEqualsCStr(str, c_str));
76}
77
78TEST_F(ModSupportExtensionApiTest, RepeatedAddStringConstantOverwritesValue) {
79 static PyModuleDef def;
80 def = {
81 PyModuleDef_HEAD_INIT,
82 "mymodule",
83 };
84
85 testing::PyObjectPtr module(PyModule_Create(&def));
86 ASSERT_NE(module, nullptr);
87
88 ASSERT_EQ(PyModule_AddStringConstant(module, "mystr", "hello"), 0);
89 EXPECT_EQ(PyErr_Occurred(), nullptr);
90
91 const char* c_str = "world";
92 ASSERT_EQ(PyModule_AddStringConstant(module, "mystr", c_str), 0);
93 EXPECT_EQ(PyErr_Occurred(), nullptr);
94
95 testing::PyObjectPtr str(PyObject_GetAttrString(module, "mystr"));
96 EXPECT_TRUE(isUnicodeEqualsCStr(str, c_str));
97}
98
99TEST_F(ModSupportExtensionApiTest, AddIntMacroAddsInt) {
100 static PyModuleDef def;
101 def = {
102 PyModuleDef_HEAD_INIT,
103 "mymodule",
104 };
105
106 testing::PyObjectPtr module(PyModule_Create(&def));
107 ASSERT_NE(module, nullptr);
108
109#pragma push_macro("MYINT")
110#undef MYINT
111#define MYINT 5
112 ASSERT_EQ(PyModule_AddIntMacro(module, MYINT), 0);
113 EXPECT_EQ(PyErr_Occurred(), nullptr);
114
115 testing::PyObjectPtr myint(PyObject_GetAttrString(module, "MYINT"));
116 EXPECT_EQ(PyLong_AsLong(myint), MYINT);
117#pragma pop_macro("MYINT")
118}
119
120TEST_F(ModSupportExtensionApiTest, BuildValue) {
121 testing::PyObjectPtr a_str(Py_BuildValue("s", "hello, world"));
122 EXPECT_TRUE(isUnicodeEqualsCStr(a_str, "hello, world"));
123}
124
125TEST_F(ModSupportExtensionApiTest, BuildValueStringLength) {
126 testing::PyObjectPtr a_str(Py_BuildValue("s#", "hello, world", 5));
127 EXPECT_TRUE(isUnicodeEqualsCStr(a_str, "hello"));
128}
129
130TEST_F(ModSupportExtensionApiTest, BuildValueInt) {
131 testing::PyObjectPtr an_int(Py_BuildValue("i", 42));
132 ASSERT_NE(an_int, nullptr);
133 ASSERT_TRUE(PyLong_Check(an_int));
134 ASSERT_EQ(PyLong_AsLong(an_int), 42);
135}
136
137TEST_F(ModSupportExtensionApiTest, BuildValueTupleOfInt) {
138 testing::PyObjectPtr a_tuple(Py_BuildValue("iiii", 111, 222, 333, 444));
139 ASSERT_NE(a_tuple, nullptr);
140 ASSERT_TRUE(PyTuple_Check(a_tuple));
141
142 PyObject* item0 = PyTuple_GetItem(a_tuple, 0);
143 ASSERT_NE(item0, nullptr);
144 ASSERT_EQ(PyLong_AsLong(item0), 111);
145
146 PyObject* item1 = PyTuple_GetItem(a_tuple, 1);
147 ASSERT_NE(item1, nullptr);
148 ASSERT_EQ(PyLong_AsLong(item1), 222);
149
150 PyObject* item2 = PyTuple_GetItem(a_tuple, 2);
151 ASSERT_NE(item2, nullptr);
152 ASSERT_EQ(PyLong_AsLong(item2), 333);
153
154 PyObject* item3 = PyTuple_GetItem(a_tuple, 3);
155 ASSERT_NE(item3, nullptr);
156 ASSERT_EQ(PyLong_AsLong(item3), 444);
157}
158
159} // namespace testing
160} // namespace py