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()); }
namespace impl {
template <typename T, typename SFINAE = void>
struct type_caster;
}
template <typename T>
handle cast(T&& value, return_value_policy policy, handle parent) {
// 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 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) {
assert(obj.ptr() != nullptr);
type_caster<T> caster = {};
impl::type_caster<T> caster = {};
if(caster.load(obj, convert)) {
return caster.value;

View File

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

View File

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

View File

@ -176,7 +176,7 @@ public:
template <typename Fn, std::size_t... Is, typename... Args>
handle invoke(Fn&& fn,
std::index_sequence<Is...>,
std::tuple<type_caster<Args>...>& casters,
std::tuple<impl::type_caster<Args>...>& casters,
return_value_policy policy,
handle parent) {
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
const auto n = vm->s_data._sp - view.end();
std::size_t index = 0;
int index = 0;
if constexpr(named_argc > 0) {
std::size_t arg_index = 0;
int arg_index = 0;
auto& arguments = *record.arguments;
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
std::tuple<type_caster<Args>...> casters;
std::tuple<impl::type_caster<Args>...> casters;
// check type compatibility
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>) {
// 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)) {
self.*setter = caster.value;
return vm->None;
}
} else {
// 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)) {
(self.*setter)(caster.value);
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>>>;
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)) {
setter(self, caster.value);
return vm->None;

View File

@ -37,7 +37,7 @@ class handle;
class object;
class iterator;
class str;
class arg;
struct arg;
struct args_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
using error_already_set = pkpy::TopLevelException;
#else
class error_already_set : std::exception {
public:
error_already_set() = default;
const char* what() const noexcept override { return "An error occurred while calling a Python function."; }
};
using error_already_set = pkpy::Exception;
#endif
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) {
auto package = this->package()._as<pkpy::Str>() + "." + this->name()._as<pkpy::Str>();
auto m = vm->new_module(name, package);
// TODO: resolve 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);
return m;
}

View File

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

View File

@ -25,9 +25,9 @@ struct function_traits {
static_assert(dependent_false<Fn>, "unsupported function type");
};
#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(qualifiers) \
#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(...) \
template <typename R, typename... Args> \
struct function_traits<R(Args...) qualifiers> { \
struct function_traits<R(Args...) __VA_ARGS__> { \
using return_type = R; \
using args_type = std::tuple<Args...>; \
constexpr static std::size_t args_count = sizeof...(Args); \
@ -167,4 +167,32 @@ constexpr auto type_name() {
#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

View File

@ -385,11 +385,11 @@ public:
};
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 {
PYBIND11_TYPE_IMPLEMENT(dict, struct empty, vm->tp_dict);
PYBIND11_TYPE_IMPLEMENT(dict, pybind11::empty, vm->tp_dict);
};
} // namespace pybind11

View File

@ -9,7 +9,7 @@
#include <map>
#include <unordered_map>
namespace pybind11 {
namespace pybind11::impl {
template <typename T, std::size_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