#pragma once #include "types.h" namespace pybind11 { inline void exec(const char* code, handle global = {}, handle local = {}) { vm->py_exec(code, global.ptr(), local.ptr()); } // wrapper for builtin functions in Python inline bool hasattr(const handle& obj, const handle& name) { auto& key = _builtin_cast(name); return vm->getattr(obj.ptr(), key, false) != nullptr; } inline bool hasattr(const handle& obj, const char* name) { return vm->getattr(obj.ptr(), name, false) != nullptr; } inline void delattr(const handle& obj, const handle& name) { auto& key = _builtin_cast(name); vm->delattr(obj.ptr(), key); } inline void delattr(const handle& obj, const char* name) { vm->delattr(obj.ptr(), name); } inline object getattr(const handle& obj, const handle& name) { auto& key = _builtin_cast(name); return reinterpret_borrow(vm->getattr(obj.ptr(), key)); } inline object getattr(const handle& obj, const char* name) { return reinterpret_borrow(vm->getattr(obj.ptr(), name)); } inline object getattr(const handle& obj, const handle& name, const handle& default_) { if(!hasattr(obj, name)) { return reinterpret_borrow(default_); } return getattr(obj, name); } inline object getattr(const handle& obj, const char* name, const handle& default_) { if(!hasattr(obj, name)) { return reinterpret_borrow(default_); } return getattr(obj, name); } inline void setattr(const handle& obj, const handle& name, const handle& value) { auto& key = _builtin_cast(name); vm->setattr(obj.ptr(), key, value.ptr()); } inline void setattr(const handle& obj, const char* name, const handle& value) { vm->setattr(obj.ptr(), name, value.ptr()); } template inline bool isinstance(const handle& obj) { pkpy::Type cls = _builtin_cast(type::handle_of().ptr()); return vm->isinstance(obj.ptr(), cls); } template <> inline bool isinstance(const handle&) = delete; template <> inline bool isinstance(const handle& obj) { return hasattr(obj, "__iter__"); } template <> inline bool isinstance(const handle& obj) { return hasattr(obj, "__iter__") && hasattr(obj, "__next__"); } inline bool isinstance(const handle& obj, const handle& type) { return vm->isinstance(obj.ptr(), _builtin_cast(type)); } inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); } template struct type_caster; template handle _cast(T&& value, return_value_policy policy = return_value_policy::automatic_reference, handle parent = handle()) { using U = std::remove_pointer_t>>; return type_caster::cast(std::forward(value), policy, parent); } template object cast(T&& value, return_value_policy policy = return_value_policy::automatic_reference, handle parent = handle()) { return reinterpret_borrow(_cast(std::forward(value), policy, parent)); } template T cast(handle obj, bool convert = false) { using Caster = type_caster>>>; Caster caster; if(caster.load(obj, convert)) { if constexpr(std::is_rvalue_reference_v) { return std::move(caster.value); } else { return caster.value; } } throw std::runtime_error("Unable to cast Python instance to C++ type"); } } // namespace pybind11