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
8// We need to use this functions from the internal `node.h` CPython header
9// in order to avoid a test leaking memory.
10extern "C" void PyNode_Free(_node*);
11
12namespace py {
13namespace testing {
14
15using CompileExtensionApiTest = ExtensionApi;
16
17TEST_F(CompileExtensionApiTest, PyMangleReturnsIdent) {
18 PyObjectPtr s0(PyUnicode_FromString("Foo"));
19 PyObjectPtr s1(PyUnicode_FromString("bar"));
20 PyObjectPtr result(_Py_Mangle(s0, s1));
21 EXPECT_TRUE(isUnicodeEqualsCStr(result, "bar"));
22}
23
24TEST_F(CompileExtensionApiTest, PyMangleWithDunderIdentReturnsIdent) {
25 PyObjectPtr s0(PyUnicode_FromString("Foo"));
26 PyObjectPtr s1(PyUnicode_FromString("__bar__"));
27 PyObjectPtr result(_Py_Mangle(s0, s1));
28 EXPECT_TRUE(isUnicodeEqualsCStr(result, "__bar__"));
29}
30
31TEST_F(CompileExtensionApiTest, PyMangleWithDotIdentReturnsIdent) {
32 PyObjectPtr s0(PyUnicode_FromString("Foo"));
33 PyObjectPtr s1(PyUnicode_FromString("__ba.r"));
34 PyObjectPtr result(_Py_Mangle(s0, s1));
35 EXPECT_TRUE(isUnicodeEqualsCStr(result, "__ba.r"));
36}
37
38TEST_F(CompileExtensionApiTest, PyMangleWithNullPrivateObjReturnsIdent) {
39 PyObjectPtr s1(PyUnicode_FromString("baz"));
40 PyObjectPtr result(_Py_Mangle(nullptr, s1));
41 EXPECT_TRUE(isUnicodeEqualsCStr(result, "baz"));
42}
43
44TEST_F(CompileExtensionApiTest, PyMangleWithOnlyUnderscoreClassReturnsIdent) {
45 PyObjectPtr s0(PyUnicode_FromString("___"));
46 PyObjectPtr s1(PyUnicode_FromString("__baz"));
47 PyObjectPtr result(_Py_Mangle(s0, s1));
48 EXPECT_TRUE(isUnicodeEqualsCStr(result, "__baz"));
49}
50
51TEST_F(CompileExtensionApiTest, PyMangleReturnsIdentWithClassnamePrefix) {
52 PyObjectPtr s0(PyUnicode_FromString("Foo"));
53 PyObjectPtr s1(PyUnicode_FromString("__bar"));
54 PyObjectPtr result(_Py_Mangle(s0, s1));
55 EXPECT_TRUE(isUnicodeEqualsCStr(result, "_Foo__bar"));
56}
57
58TEST_F(CompileExtensionApiTest, PyMangleReturnsClassnameWithoutUnderscores) {
59 PyObjectPtr s0(PyUnicode_FromString("___Foo"));
60 PyObjectPtr s1(PyUnicode_FromString("__bar"));
61 PyObjectPtr result(_Py_Mangle(s0, s1));
62 EXPECT_TRUE(isUnicodeEqualsCStr(result, "_Foo__bar"));
63}
64
65TEST_F(CompileExtensionApiTest, PyNodeCompileReturnsCodeObject) {
66 _node* astnode = PyParser_SimpleParseStringFlagsFilename(
67 "4+5", "<test string>", Py_eval_input, 0);
68 ASSERT_NE(astnode, nullptr);
69
70 PyObjectPtr code(
71 reinterpret_cast<PyObject*>(PyNode_Compile(astnode, "<test string>")));
72 EXPECT_TRUE(PyCode_Check(code));
73 PyNode_Free(astnode);
74}
75
76TEST_F(CompileExtensionApiTest, PyAstCompileExReturnsCodeObject) {
77 PyArena* arena = PyArena_New();
78 PyCompilerFlags flags = _PyCompilerFlags_INIT;
79 _mod* mod = PyParser_ASTFromString("4+5", "<test string>", Py_eval_input,
80 &flags, arena);
81 ASSERT_NE(mod, nullptr);
82 PyObjectPtr code(reinterpret_cast<PyObject*>(
83 PyAST_CompileEx(mod, "<test string>", &flags, -1, arena)));
84 EXPECT_TRUE(PyCode_Check(code));
85 PyArena_Free(arena);
86}
87
88TEST_F(CompileExtensionApiTest, PyAstCompileReturnsCodeObject) {
89 PyArena* arena = PyArena_New();
90 PyCompilerFlags flags = _PyCompilerFlags_INIT;
91 _mod* mod = PyParser_ASTFromString("4+5", "<test string>", Py_single_input,
92 &flags, arena);
93 ASSERT_NE(mod, nullptr);
94 PyCodeObject* code = PyAST_Compile(mod, "<test string>", &flags, arena);
95 EXPECT_TRUE(PyCode_Check(code));
96 Py_XDECREF(code);
97 PyArena_Free(arena);
98}
99
100TEST_F(CompileExtensionApiTest, PyAstCompileObjectReturnsCodeObject) {
101 PyArena* arena = PyArena_New();
102 PyCompilerFlags flags = _PyCompilerFlags_INIT;
103 _mod* mod = PyParser_ASTFromString("def foo(): pass", "<test string>",
104 Py_file_input, &flags, arena);
105 ASSERT_NE(mod, nullptr);
106 PyObjectPtr filename(PyUnicode_FromString("<test string>"));
107 PyCodeObject* code =
108 PyAST_CompileObject(mod, filename, &flags, /*optimize=*/-1, arena);
109 ASSERT_NE(code, nullptr);
110 EXPECT_FALSE(PyErr_Occurred());
111 EXPECT_TRUE(PyCode_Check(code));
112 Py_XDECREF(code);
113 PyArena_Free(arena);
114}
115
116TEST_F(CompileExtensionApiTest,
117 PyAstCompileObjectAcceptsOptimizationLevelGreaterThanTwo) {
118 PyArena* arena = PyArena_New();
119 PyCompilerFlags flags = _PyCompilerFlags_INIT;
120 _mod* mod = PyParser_ASTFromString("def foo(): pass", "<test string>",
121 Py_file_input, &flags, arena);
122 ASSERT_NE(mod, nullptr);
123 PyObjectPtr filename(PyUnicode_FromString("<test string>"));
124 PyCodeObject* code =
125 PyAST_CompileObject(mod, filename, &flags, /*optimize=*/123, arena);
126 ASSERT_NE(code, nullptr);
127 EXPECT_FALSE(PyErr_Occurred());
128 EXPECT_TRUE(PyCode_Check(code));
129 Py_XDECREF(code);
130 PyArena_Free(arena);
131}
132
133} // namespace testing
134} // namespace py