fix memory leak in property and staticmethod.

This commit is contained in:
ykiko 2024-08-28 11:27:10 +08:00
parent ac8f4a1c2d
commit f09bd398cb
2 changed files with 59 additions and 26 deletions

View File

@ -585,24 +585,14 @@ class cpp_function : public function {
class property : public object {
PKBIND_TYPE_IMPL(object, property, tp_property);
property(handle getter, handle setter = none()) : object() {
auto start = py_peek(0);
py_push(getter.ptr());
py_push(setter.ptr());
raise_call<py_tpcall>(type::of<property>().index(), 2, start);
*this = object::from_ret();
}
property(handle getter, handle setter = none()) :
object(type::of<property>()(getter, setter)) {}
};
class staticmethod : public object {
PKBIND_TYPE_IMPL(object, staticmethod, tp_staticmethod);
staticmethod(handle method) : object() {
auto start = py_peek(0);
py_push(method.ptr());
raise_call<py_tpcall>(type::of<staticmethod>().index(), 1, start);
*this = object::from_ret();
}
staticmethod(handle method) : object(type::of<staticmethod>()(method)) {}
};
namespace impl {

View File

@ -1,5 +1,7 @@
#include "pybind11/internal/builtins.h"
#include "test.h"
#include <pybind11/operators.h>
#include <vector>
namespace {
@ -8,19 +10,19 @@ struct Int {
Int(int x) : x(x) {}
#define OPERATOR_IMPL(op) \
template <typename LHS, typename RHS> \
friend int operator op (const LHS& lhs, const RHS& rhs) { \
int l, r; \
if constexpr(std::is_same_v<LHS, Int>) \
l = lhs.x; \
else \
l = lhs; \
if constexpr(std::is_same_v<RHS, Int>) \
r = rhs.x; \
else \
r = rhs; \
return l op r; \
#define OPERATOR_IMPL(op) \
template <typename LHS, typename RHS> \
friend int operator op (const LHS& lhs, const RHS& rhs) { \
int l, r; \
if constexpr(std::is_same_v<LHS, Int>) \
l = lhs.x; \
else \
l = lhs; \
if constexpr(std::is_same_v<RHS, Int>) \
r = rhs.x; \
else \
r = rhs; \
return l op r; \
}
OPERATOR_IMPL(+)
@ -148,3 +150,44 @@ TEST_F(PYBIND11_TEST, logic_operators) {
EXPECT_FALSE(a >= b);
}
TEST_F(PYBIND11_TEST, item_operators) {
py::module_ m = py::module_::import("__main__");
py::class_<std::vector<int>>(m, "vector")
.def(py::init<>())
.def("__getitem__",
[](std::vector<int>& v, int i) {
return v[i];
})
.def("__setitem__",
[](std::vector<int>& v, int i, int x) {
v[i] = x;
})
.def("push_back",
[](std::vector<int>& v, int x) {
v.push_back(x);
})
.def("__str__", [](const std::vector<int>& v) {
std::ostringstream os;
os << "[";
for(size_t i = 0; i < v.size(); i++) {
if(i > 0) os << ", ";
os << v[i];
}
os << "]";
return os.str();
});
py::exec(R"(
v = vector()
v.push_back(1)
v.push_back(2)
v.push_back(3)
print(v)
assert v[0] == 1
assert v[1] == 2
assert v[2] == 3
v[1] = 4
assert v[1] == 4
)");
}