Merge pull request #282 from 16bit-ykiko/pybind11-fix

some fix.
This commit is contained in:
BLUELOVETH 2024-06-19 13:05:58 +08:00 committed by GitHub
commit 0c1bd532f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 67 additions and 34 deletions

View File

@ -81,9 +81,13 @@ inline bool isinstance(const handle& obj, const handle& type) {
inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); } inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); }
namespace impl {
template <typename T, typename SFINAE = void> template <typename T, typename SFINAE = void>
struct type_caster; struct type_caster;
}
template <typename T> template <typename T>
handle cast(T&& value, return_value_policy policy, handle parent) { handle cast(T&& value, return_value_policy policy, handle parent) {
// decay_t can resolve c-array type, but remove_cv_ref_t can't. // decay_t can resolve c-array type, but remove_cv_ref_t can't.
@ -107,7 +111,7 @@ handle cast(T&& value, return_value_policy policy, handle parent) {
: return_value_policy::move; : return_value_policy::move;
} }
return type_caster<underlying_type>::cast(std::forward<T>(value), policy, parent); return impl::type_caster<underlying_type>::cast(std::forward<T>(value), policy, parent);
} }
} }
@ -115,7 +119,7 @@ template <typename T>
T cast(const handle& obj, bool convert) { T cast(const handle& obj, bool convert) {
assert(obj.ptr() != nullptr); assert(obj.ptr() != nullptr);
type_caster<T> caster = {}; impl::type_caster<T> caster = {};
if(caster.load(obj, convert)) { if(caster.load(obj, convert)) {
return caster.value; return caster.value;

View File

@ -2,7 +2,7 @@
#include "instance.h" #include "instance.h"
#include "accessor.h" #include "accessor.h"
namespace pybind11 { namespace pybind11::impl {
using pkpy::is_floating_point_v; using pkpy::is_floating_point_v;
using pkpy::is_integral_v; using pkpy::is_integral_v;

View File

@ -169,15 +169,15 @@ public:
} }
enum_& value(const char* name, T value) { enum_& value(const char* name, T value) {
handle var = type_caster<T>::cast(value, return_value_policy::copy); handle var = pybind11::cast(value, return_value_policy::copy);
this->m_ptr->attr().set(name, var.ptr()); setattr(*this, name, var);
m_values.emplace_back(name, var); m_values.emplace_back(name, var);
return *this; return *this;
} }
enum_& export_values() { enum_& export_values() {
for(auto& [name, value]: m_values) { for(auto& [name, value]: m_values) {
Base::m_scope.ptr()->attr().set(name, value.ptr()); setattr(Base::m_scope, name, value);
} }
return *this; return *this;
} }

View File

@ -176,7 +176,7 @@ public:
template <typename Fn, std::size_t... Is, typename... Args> template <typename Fn, std::size_t... Is, typename... Args>
handle invoke(Fn&& fn, handle invoke(Fn&& fn,
std::index_sequence<Is...>, std::index_sequence<Is...>,
std::tuple<type_caster<Args>...>& casters, std::tuple<impl::type_caster<Args>...>& casters,
return_value_policy policy, return_value_policy policy,
handle parent) { handle parent) {
using underlying_type = std::decay_t<Fn>; using underlying_type = std::decay_t<Fn>;
@ -361,10 +361,10 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
// resolve keyword arguments // resolve keyword arguments
const auto n = vm->s_data._sp - view.end(); const auto n = vm->s_data._sp - view.end();
std::size_t index = 0; int index = 0;
if constexpr(named_argc > 0) { if constexpr(named_argc > 0) {
std::size_t arg_index = 0; int arg_index = 0;
auto& arguments = *record.arguments; auto& arguments = *record.arguments;
while(arg_index < named_argc && index < n) { while(arg_index < named_argc && index < n) {
@ -403,7 +403,7 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
} }
// ok, all the arguments are valid, call the function // ok, all the arguments are valid, call the function
std::tuple<type_caster<Args>...> casters; std::tuple<impl::type_caster<Args>...> casters;
// check type compatibility // check type compatibility
if(((std::get<Is>(casters).load(stack[Is], convert)) && ...)) { if(((std::get<Is>(casters).load(stack[Is], convert)) && ...)) {
@ -489,14 +489,14 @@ pkpy::PyVar setter_wrapper(pkpy::VM* vm, pkpy::ArgsView view) {
if constexpr(std::is_member_object_pointer_v<Setter>) { if constexpr(std::is_member_object_pointer_v<Setter>) {
// specialize for pointer to data member // specialize for pointer to data member
type_caster<member_type_t<Setter>> caster; impl::type_caster<member_type_t<Setter>> caster;
if(caster.load(view[1], true)) { if(caster.load(view[1], true)) {
self.*setter = caster.value; self.*setter = caster.value;
return vm->None; return vm->None;
} }
} else { } else {
// specialize for pointer to member function // specialize for pointer to member function
type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster; impl::type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster;
if(caster.load(view[1], true)) { if(caster.load(view[1], true)) {
(self.*setter)(caster.value); (self.*setter)(caster.value);
return vm->None; return vm->None;
@ -507,7 +507,7 @@ pkpy::PyVar setter_wrapper(pkpy::VM* vm, pkpy::ArgsView view) {
using Self = remove_cvref_t<std::tuple_element_t<0, callable_args_t<Setter>>>; using Self = remove_cvref_t<std::tuple_element_t<0, callable_args_t<Setter>>>;
auto& self = handle(view[0])._as<instance>()._as<Self>(); auto& self = handle(view[0])._as<instance>()._as<Self>();
type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster; impl::type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster;
if(caster.load(view[1], true)) { if(caster.load(view[1], true)) {
setter(self, caster.value); setter(self, caster.value);
return vm->None; return vm->None;

View File

@ -37,7 +37,7 @@ class handle;
class object; class object;
class iterator; class iterator;
class str; class str;
class arg; struct arg;
struct args_proxy; struct args_proxy;
struct kwargs_proxy; struct kwargs_proxy;
@ -210,12 +210,7 @@ constexpr inline bool is_pyobject_v = std::is_base_of_v<object, T>;
#if PK_VERSION_MAJOR == 2 #if PK_VERSION_MAJOR == 2
using error_already_set = pkpy::TopLevelException; using error_already_set = pkpy::TopLevelException;
#else #else
class error_already_set : std::exception { using error_already_set = pkpy::Exception;
public:
error_already_set() = default;
const char* what() const noexcept override { return "An error occurred while calling a Python function."; }
};
#endif #endif
inline void setattr(const handle& obj, const handle& name, const handle& value); inline void setattr(const handle& obj, const handle& name, const handle& value);

View File

@ -19,8 +19,10 @@ public:
} }
module_ def_submodule(const char* name, const char* doc = nullptr) { module_ def_submodule(const char* name, const char* doc = nullptr) {
auto package = this->package()._as<pkpy::Str>() + "." + this->name()._as<pkpy::Str>(); // TODO: resolve package
auto m = vm->new_module(name, package); //auto package = this->package()._as<pkpy::Str>() + "." + this->name()._as<pkpy::Str>();
auto fname = this->name()._as<pkpy::Str>() + "." + name;
auto m = vm->new_module(fname, "");
setattr(*this, name, m); setattr(*this, name, m);
return m; return m;
} }

View File

@ -69,15 +69,19 @@ public:
template <typename T> template <typename T>
decltype(auto) _as() const { decltype(auto) _as() const {
static_assert(!std::is_reference_v<T>, "T must not be a reference type."); static_assert(!std::is_reference_v<T>, "T must not be a reference type.");
#if PK_VERSION_MAJOR == 2 if constexpr(std::is_same_v<T, empty>) {
if constexpr(pkpy::is_sso_v<T>) { return empty();
return pkpy::_py_cast<T>(vm, ptr());
} else { } else {
return ptr().template obj_get<T>(); #if PK_VERSION_MAJOR == 2
} if constexpr(pkpy::is_sso_v<T>) {
return pkpy::_py_cast<T>(vm, ptr());
} else {
return ptr().template obj_get<T>();
}
#else #else
return (((pkpy::Py_<T>*)ptr())->_value); return (((pkpy::Py_<T>*)ptr())->_value);
#endif #endif
}
} }
}; };

View File

@ -25,9 +25,9 @@ struct function_traits {
static_assert(dependent_false<Fn>, "unsupported function type"); static_assert(dependent_false<Fn>, "unsupported function type");
}; };
#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(qualifiers) \ #define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(...) \
template <typename R, typename... Args> \ template <typename R, typename... Args> \
struct function_traits<R(Args...) qualifiers> { \ struct function_traits<R(Args...) __VA_ARGS__> { \
using return_type = R; \ using return_type = R; \
using args_type = std::tuple<Args...>; \ using args_type = std::tuple<Args...>; \
constexpr static std::size_t args_count = sizeof...(Args); \ constexpr static std::size_t args_count = sizeof...(Args); \
@ -167,4 +167,32 @@ constexpr auto type_name() {
#endif #endif
} }
template <typename... Args>
struct overload_cast_t {
template <typename Return>
constexpr auto operator() (Return (*pf)(Args...)) const noexcept -> decltype(pf) {
return pf;
}
template <typename Return, typename Class>
constexpr auto operator() (Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept -> decltype(pmf) {
return pmf;
}
template <typename Return, typename Class>
constexpr auto operator() (Return (Class::*pmf)(Args...) const, std::true_type) const noexcept -> decltype(pmf) {
return pmf;
}
};
/// Syntax sugar for resolving overloaded function pointers:
/// - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
/// - sweet: overload_cast<Arg0, Arg1, Arg2>(&Class::func)
template <typename... Args>
constexpr inline overload_cast_t<Args...> overload_cast;
/// Const member function selector for overload_cast
/// - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)
/// - sweet: overload_cast<Arg>(&Class::func, const_)
constexpr static auto const_ = std::true_type{};
} // namespace pybind11 } // namespace pybind11

View File

@ -385,11 +385,11 @@ public:
}; };
class args : public tuple { class args : public tuple {
PYBIND11_TYPE_IMPLEMENT(tuple, struct empty, vm->tp_tuple); PYBIND11_TYPE_IMPLEMENT(tuple, pybind11::empty, vm->tp_tuple);
}; };
class kwargs : public dict { class kwargs : public dict {
PYBIND11_TYPE_IMPLEMENT(dict, struct empty, vm->tp_dict); PYBIND11_TYPE_IMPLEMENT(dict, pybind11::empty, vm->tp_dict);
}; };
} // namespace pybind11 } // namespace pybind11

View File

@ -9,7 +9,7 @@
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
namespace pybind11 { namespace pybind11::impl {
template <typename T, std::size_t N> template <typename T, std::size_t N>
struct type_caster<std::array<T, N>> { struct type_caster<std::array<T, N>> {
@ -140,5 +140,5 @@ struct type_caster<T, std::enable_if_t<is_py_map_like_v<T>>> {
} }
}; };
} // namespace pybind11 } // namespace pybind11::impl