Commit d561cb01 authored by Wenzel Jakob's avatar Wenzel Jakob
Browse files

fully moved __pybind11__ Python attributes to the C++ side, cleanup &...

fully moved __pybind11__ Python attributes to the C++ side, cleanup & documentation pass over the main header file
parent e45b2904
......@@ -22,17 +22,19 @@ NAMESPACE_BEGIN(detail)
class type_caster_generic {
public:
PYBIND11_NOINLINE type_caster_generic(const std::type_info *type_info) {
auto & registered_types = get_internals().registered_types;
auto it = registered_types.find(type_info);
if (it != registered_types.end()) {
typeinfo = &it->second;
auto &types = get_internals().registered_types_cpp;
auto it = types.find(type_info);
if (it != types.end()) {
typeinfo = (detail::type_info *) it->second;
} else {
/* Unknown type?! Since std::type_info* often varies across
module boundaries, the following does an explicit check */
for (auto const &type : registered_types) {
if (strcmp(type.first->name(), type_info->name()) == 0) {
registered_types[type_info] = type.second;
typeinfo = &type.second;
for (auto const &type : types) {
auto *first = (const std::type_info *) type.first;
if (strcmp(first->name(), type_info->name()) == 0) {
types[type_info] = type.second;
typeinfo = (detail::type_info *) type.second;
break;
}
}
......@@ -71,20 +73,20 @@ public:
auto& internals = get_internals();
auto it_instance = internals.registered_instances.find(src);
if (it_instance != internals.registered_instances.end() && !dont_cache) {
PyObject *inst = it_instance->second;
PyObject *inst = (PyObject *) it_instance->second;
Py_INCREF(inst);
return inst;
}
auto it = internals.registered_types.find(type_info);
if (it == internals.registered_types.end()) {
auto it = internals.registered_types_cpp.find(type_info);
if (it == internals.registered_types_cpp.end()) {
std::string tname = type_info->name();
detail::clean_type_id(tname);
std::string msg = "Unregistered type : " + tname;
PyErr_SetString(PyExc_TypeError, msg.c_str());
return nullptr;
}
auto &reg_type = it->second;
instance<void> *inst = (instance<void> *) PyType_GenericAlloc(reg_type.type, 0);
auto tinfo = (const detail::type_info *) it->second;
instance<void> *inst = (instance<void> *) PyType_GenericAlloc(tinfo->type, 0);
inst->value = src;
inst->owned = true;
inst->parent = nullptr;
......@@ -102,7 +104,7 @@ public:
Py_XINCREF(parent);
}
PyObject *inst_pyobj = (PyObject *) inst;
reg_type.init_holder(inst_pyobj, existing_holder);
tinfo->init_holder(inst_pyobj, existing_holder);
if (!dont_cache)
internals.registered_instances[inst->value] = inst_pyobj;
return inst_pyobj;
......
......@@ -66,25 +66,6 @@
#pragma warning(pop)
#endif
#if PY_MAJOR_VERSION >= 3
#define PYBIND11_PLUGIN_IMPL(name) \
extern "C" PYBIND11_EXPORT PyObject *PyInit_##name()
#else
#define PYBIND11_PLUGIN_IMPL(name) \
extern "C" PYBIND11_EXPORT PyObject *init##name()
#endif
#define PYBIND11_PLUGIN(name) \
static PyObject *pybind11_init(); \
PYBIND11_PLUGIN_IMPL(name) { \
try { \
return pybind11_init(); \
} catch (const std::exception &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} \
} \
PyObject *pybind11_init()
#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
#define PYBIND11_BYTES_CHECK PyBytes_Check
#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString
......@@ -97,6 +78,10 @@
#define PYBIND11_BYTES_NAME "bytes"
#define PYBIND11_STRING_NAME "str"
#define PYBIND11_SLICE_OBJECT PyObject
#define PYBIND11_FROM_STRING PyUnicode_FromString
#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_base.ob_base.ob_type
#define PYBIND11_PLUGIN_IMPL(name) \
extern "C" PYBIND11_EXPORT PyObject *PyInit_##name()
#else
#define PYBIND11_BYTES_CHECK PyString_Check
#define PYBIND11_BYTES_FROM_STRING PyString_FromString
......@@ -109,8 +94,27 @@
#define PYBIND11_BYTES_NAME "str"
#define PYBIND11_STRING_NAME "unicode"
#define PYBIND11_SLICE_OBJECT PySliceObject
#define PYBIND11_FROM_STRING PyString_FromString
#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_type
#define PYBIND11_PLUGIN_IMPL(name) \
extern "C" PYBIND11_EXPORT PyObject *init##name()
#endif
#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code
#define PYBIND11_PLUGIN(name) \
static PyObject *pybind11_init(); \
PYBIND11_PLUGIN_IMPL(name) { \
try { \
return pybind11_init(); \
} catch (const std::exception &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} \
} \
PyObject *pybind11_init()
NAMESPACE_BEGIN(pybind11)
typedef Py_ssize_t ssize_t;
......@@ -220,8 +224,9 @@ struct argument_entry {
/// Internal data struture used to track registered instances and types
struct internals {
std::unordered_map<const std::type_info *, type_info> registered_types;
std::unordered_map<const void *, PyObject *> registered_instances;
std::unordered_map<const void *, void*> registered_types_cpp; // std::type_info* -> type_info
std::unordered_map<const void *, void*> registered_types_py; // PyTypeObject* -> type_info
std::unordered_map<const void *, void*> registered_instances; // void * -> PyObject*
std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache;
};
......
This diff is collapsed.
......@@ -404,7 +404,6 @@ public:
class function : public object {
public:
PYBIND11_OBJECT_DEFAULT(function, object, PyFunction_Check)
bool is_cpp_function() const {
PyObject *ptr = detail::get_function(m_ptr);
return ptr != nullptr && PyCFunction_Check(ptr);
......@@ -426,7 +425,7 @@ public:
};
NAMESPACE_BEGIN(detail)
inline internals &get_internals() {
PYBIND11_NOINLINE inline internals &get_internals() {
static internals *internals_ptr = nullptr;
if (internals_ptr)
return *internals_ptr;
......@@ -441,7 +440,19 @@ inline internals &get_internals() {
return *internals_ptr;
}
inline std::string error_string() {
PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
auto const &type_dict = get_internals().registered_types_py;
do {
auto it = type_dict.find(type);
if (it != type_dict.end())
return (detail::type_info *) it->second;
type = type->tp_base;
if (type == nullptr)
throw std::runtime_error("pybind11::detail::get_type_info: unable to find type object!");
} while (true);
}
PYBIND11_NOINLINE inline std::string error_string() {
std::string errorString;
PyThreadState *tstate = PyThreadState_GET();
if (tstate == nullptr)
......@@ -457,20 +468,12 @@ inline std::string error_string() {
return errorString;
}
inline handle get_object_handle(const void *ptr) {
PYBIND11_NOINLINE inline handle get_object_handle(const void *ptr) {
auto instances = get_internals().registered_instances;
auto it = instances.find(ptr);
if (it == instances.end())
return handle();
return it->second;
}
inline handle get_type_handle(const std::type_info &tp) {
auto instances = get_internals().registered_types;
auto it = instances.find(&tp);
if (it == instances.end())
return handle();
return handle((PyObject *) it->second.type);
return handle((PyObject *) it->second);
}
NAMESPACE_END(detail)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment