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 FuncExtensionApiTest = ExtensionApi;
12
13TEST_F(FuncExtensionApiTest,
14 StaticMethodCallOnInstanceReturnsPassedArgFirstArg) {
15 PyRun_SimpleString(R"(
16def foo(x):
17 return x
18)");
19 PyObjectPtr foo(mainModuleGet("foo"));
20 PyObjectPtr static_foo(PyStaticMethod_New(foo));
21 ASSERT_EQ(moduleSet("__main__", "static_foo", static_foo), 0);
22 PyRun_SimpleString(R"(
23class Bar:
24 pass
25setattr(Bar, "foo", static_foo)
26bar = Bar()
27result = bar.foo(123)
28)");
29 PyObjectPtr result(mainModuleGet("result"));
30 ASSERT_NE(result, nullptr);
31 ASSERT_EQ(PyLong_Check(result), 1);
32 EXPECT_EQ(PyLong_AsLong(result), 123);
33}
34
35TEST_F(FuncExtensionApiTest, StaticMethodCallOnTypeReturnsPassedAsFirstArg) {
36 PyRun_SimpleString(R"(
37def foo(x):
38 return x
39)");
40 PyObjectPtr foo(mainModuleGet("foo"));
41 PyObjectPtr static_foo(PyStaticMethod_New(foo));
42 ASSERT_EQ(moduleSet("__main__", "static_foo", static_foo), 0);
43 PyRun_SimpleString(R"(
44class Bar:
45 pass
46setattr(Bar, "foo", static_foo)
47result = Bar.foo(123)
48)");
49 PyObjectPtr result(mainModuleGet("result"));
50 ASSERT_NE(result, nullptr);
51 ASSERT_EQ(PyLong_Check(result), 1);
52 EXPECT_EQ(PyLong_AsLong(result), 123);
53}
54
55TEST_F(FuncExtensionApiTest, StaticMethodCallOnFreeFunctionRaisesTypeError) {
56 PyRun_SimpleString(R"(
57def foo(x):
58 return x
59)");
60 PyObjectPtr foo(mainModuleGet("foo"));
61 PyObjectPtr function(PyStaticMethod_New(foo));
62 PyObjectPtr args(PyTuple_New(1));
63 PyTuple_SetItem(args, 0, PyLong_FromLong(123));
64 PyObject* result = PyObject_CallObject(function, args);
65 ASSERT_EQ(result, nullptr);
66 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError));
67}
68
69TEST_F(FuncExtensionApiTest, ClassMethodCallOnInstanceReturnsTypeAsFirstArg) {
70 PyRun_SimpleString(R"(
71def foo(cls):
72 return cls
73)");
74 PyObjectPtr foo(mainModuleGet("foo"));
75 PyObjectPtr class_foo(PyClassMethod_New(foo));
76 ASSERT_EQ(moduleSet("__main__", "class_foo", class_foo), 0);
77 PyRun_SimpleString(R"(
78class Bar:
79 pass
80setattr(Bar, "foo", class_foo)
81result = Bar().foo()
82)");
83 PyObjectPtr bar_type(mainModuleGet("Bar"));
84 PyObjectPtr result(mainModuleGet("result"));
85 ASSERT_NE(result, nullptr);
86 ASSERT_EQ(PyType_Check(result), 1);
87 EXPECT_EQ(result, bar_type);
88}
89
90TEST_F(FuncExtensionApiTest, ClassMethodCallOnTypeReturnsTypeAsFirstArg) {
91 PyRun_SimpleString(R"(
92def foo(cls):
93 return cls
94)");
95 PyObjectPtr foo(mainModuleGet("foo"));
96 PyObjectPtr class_foo(PyClassMethod_New(foo));
97 ASSERT_EQ(moduleSet("__main__", "class_foo", class_foo), 0);
98 PyRun_SimpleString(R"(
99class Bar:
100 pass
101setattr(Bar, "foo", class_foo)
102result = Bar.foo()
103)");
104 PyObjectPtr bar_type(mainModuleGet("Bar"));
105 PyObjectPtr result(mainModuleGet("result"));
106 ASSERT_NE(result, nullptr);
107 ASSERT_EQ(PyType_Check(result), 1);
108 EXPECT_EQ(result, bar_type);
109}
110
111TEST_F(FuncExtensionApiTest, ClassMethodCallOnFreeFunctionCallRaisesTypeError) {
112 PyRun_SimpleString(R"(
113def foo(cls):
114 return cls
115)");
116 PyObjectPtr foo(mainModuleGet("foo"));
117 PyObjectPtr function(PyClassMethod_New(foo));
118 PyObjectPtr args(PyTuple_New(1));
119 PyTuple_SetItem(args, 0, PyLong_FromLong(123));
120 PyObject* result = PyObject_CallObject(function, args);
121 ASSERT_EQ(result, nullptr);
122 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError));
123}
124
125} // namespace testing
126} // namespace py