"tests/vscode:/vscode.git/clone" did not exist on "a3f10c2138c51035c19b0135876431bea28f4d79"
Unverified Commit 2ef8e3ac authored by Adrià Arrufat's avatar Adrià Arrufat Committed by GitHub
Browse files

Update to pybind11 v2.2.4 (closes #1806) (#2229)

* Update to  PyBind11 v2.2.4

* re-add custom changes

* fix indentation

* remove blank line
parent 93b992d7
......@@ -38,6 +38,8 @@ set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE INTERNAL "")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} CACHE INTERNAL "")
set(PYTHON_MODULE_PREFIX ${PYTHON_MODULE_PREFIX} CACHE INTERNAL "")
set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "")
set(PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR} CACHE INTERNAL "")
set(PYTHON_VERSION_MINOR ${PYTHON_VERSION_MINOR} CACHE INTERNAL "")
# NB: when adding a header don't forget to also add it to setup.py
set(PYBIND11_HEADERS
......
......@@ -99,7 +99,7 @@ In addition to the core functionality, pybind11 provides some extra goodies:
1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or newer)
2. GCC 4.8 or newer
3. Microsoft Visual Studio 2015 Update 3 or newer
4. Intel C++ compiler 16 or newer (15 with a [workaround](https://github.com/pybind/pybind11/issues/276))
4. Intel C++ compiler 17 or newer (16 with pybind11 v2.0 and 15 with pybind11 v2.0 and a [workaround](https://github.com/pybind/pybind11/issues/276))
5. Cygwin/GCC (tested on 2.5.1)
## About
......
......@@ -1171,7 +1171,7 @@ private:
#else
// PyPy seems to have multiple problems related to PyUnicode_UTF*: the UTF8 version
// sometimes segfaults for unknown reasons, while the UTF16 and 32 versions require a
// non-const char * arguments, which is also a nuissance, so bypass the whole thing by just
// non-const char * arguments, which is also a nuisance, so bypass the whole thing by just
// passing the encoding as a string value, which works properly:
return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr);
#endif
......@@ -1392,7 +1392,7 @@ public:
explicit operator type*() { return this->value; }
explicit operator type&() { return *(this->value); }
explicit operator holder_type*() { return &holder; }
explicit operator holder_type*() { return std::addressof(holder); }
// Workaround for Intel compiler bug
// see pybind11 issue 94
......@@ -1462,7 +1462,7 @@ struct move_only_holder_caster {
static handle cast(holder_type &&src, return_value_policy, handle) {
auto *ptr = holder_helper<holder_type>::get(src);
return type_caster_base<type>::cast_holder(ptr, &src);
return type_caster_base<type>::cast_holder(ptr, std::addressof(src));
}
static PYBIND11_DESCR name() { return type_caster_base<type>::name(); }
};
......@@ -1561,9 +1561,13 @@ template <typename type> using cast_is_temporary_value_reference = bool_constant
// When a value returned from a C++ function is being cast back to Python, we almost always want to
// force `policy = move`, regardless of the return value policy the function/method was declared
// with. Some classes (most notably Eigen::Ref and related) need to avoid this, and so can do so by
// specializing this struct.
// with.
template <typename Return, typename SFINAE = void> struct return_value_policy_override {
static return_value_policy policy(return_value_policy p) { return p; }
};
template <typename Return> struct return_value_policy_override<Return,
detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {
static return_value_policy policy(return_value_policy p) {
return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value
? return_value_policy::move : p;
......
......@@ -27,15 +27,16 @@
# endif
#endif
#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER)
# if __cplusplus >= 201402L
# define PYBIND11_CPP14
# if __cplusplus > 201402L /* Temporary: should be updated to >= the final C++17 value once known */
# if __cplusplus >= 201703L
# define PYBIND11_CPP17
# endif
# endif
#elif defined(_MSC_VER)
#elif defined(_MSC_VER) && __cplusplus == 199711L
// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented)
// Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer
# if _MSVC_LANG >= 201402L
# define PYBIND11_CPP14
# if _MSVC_LANG > 201402L && _MSC_VER >= 1910
......@@ -46,8 +47,8 @@
// Compiler version assertions
#if defined(__INTEL_COMPILER)
# if __INTEL_COMPILER < 1500
# error pybind11 requires Intel C++ compiler v15 or newer
# if __INTEL_COMPILER < 1700
# error pybind11 requires Intel C++ compiler v17 or newer
# endif
#elif defined(__clang__) && !defined(__apple_build_version__)
# if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3)
......@@ -93,7 +94,7 @@
#define PYBIND11_VERSION_MAJOR 2
#define PYBIND11_VERSION_MINOR 2
#define PYBIND11_VERSION_PATCH 2
#define PYBIND11_VERSION_PATCH 4
/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
#if defined(_MSC_VER)
......@@ -481,7 +482,7 @@ template <typename...> struct void_t_impl { using type = void; };
template <typename... Ts> using void_t = typename void_t_impl<Ts...>::type;
/// Compile-time all/any/none of that check the boolean value of all template types
#ifdef __cpp_fold_expressions
#if defined(__cpp_fold_expressions) && !(defined(_MSC_VER) && (_MSC_VER < 1916))
template <class... Ts> using all_of = bool_constant<(Ts::value && ...)>;
template <class... Ts> using any_of = bool_constant<(Ts::value || ...)>;
#elif !defined(_MSC_VER)
......
......@@ -18,6 +18,33 @@ inline PyTypeObject *make_static_property_type();
inline PyTypeObject *make_default_metaclass();
inline PyObject *make_object_base_type(PyTypeObject *metaclass);
// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
// Thread Specific Storage (TSS) API.
#if PY_VERSION_HEX >= 0x03070000
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr
# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (tstate))
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
#else
// Usually an int but a long on Cygwin64 with Python 3.x
# define PYBIND11_TLS_KEY_INIT(var) decltype(PyThread_create_key()) var = 0
# define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))
# if PY_MAJOR_VERSION < 3
# define PYBIND11_TLS_DELETE_VALUE(key) \
PyThread_delete_key_value(key)
# define PYBIND11_TLS_REPLACE_VALUE(key, value) \
do { \
PyThread_delete_key_value((key)); \
PyThread_set_key_value((key), (value)); \
} while (false)
# else
# define PYBIND11_TLS_DELETE_VALUE(key) \
PyThread_set_key_value((key), nullptr)
# define PYBIND11_TLS_REPLACE_VALUE(key, value) \
PyThread_set_key_value((key), (value))
# endif
#endif
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under
......@@ -79,7 +106,7 @@ struct internals {
PyTypeObject *default_metaclass;
PyObject *instance_base;
#if defined(WITH_THREAD)
decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x
PYBIND11_TLS_KEY_INIT(tstate);
PyInterpreterState *istate = nullptr;
#endif
};
......@@ -111,7 +138,7 @@ struct type_info {
};
/// Tracks the `internals` and `type_info` ABI version independent of the main library version
#define PYBIND11_INTERNALS_VERSION 1
#define PYBIND11_INTERNALS_VERSION 2
#if defined(WITH_THREAD)
# define PYBIND11_INTERNALS_KIND ""
......@@ -166,8 +193,17 @@ PYBIND11_NOINLINE inline internals &get_internals() {
#if defined(WITH_THREAD)
PyEval_InitThreads();
PyThreadState *tstate = PyThreadState_Get();
#if PY_VERSION_HEX >= 0x03070000
internals_ptr->tstate = PyThread_tss_alloc();
if (!internals_ptr->tstate || PyThread_tss_create(internals_ptr->tstate))
pybind11_fail("get_internals: could not successfully initialize the TSS key!");
PyThread_tss_set(internals_ptr->tstate, tstate);
#else
internals_ptr->tstate = PyThread_create_key();
if (internals_ptr->tstate == -1)
pybind11_fail("get_internals: could not successfully initialize the TLS key!");
PyThread_set_key_value(internals_ptr->tstate, tstate);
#endif
internals_ptr->istate = tstate->interp;
#endif
builtins[id] = capsule(internals_pp);
......
......@@ -350,14 +350,6 @@ private:
Type value;
};
// Eigen Ref/Map classes have slightly different policy requirements, meaning we don't want to force
// `move` when a Ref/Map rvalue is returned; we treat Ref<> sort of like a pointer (we care about
// the underlying data, not the outer shell).
template <typename Return>
struct return_value_policy_override<Return, enable_if_t<is_eigen_dense_map<Return>::value>> {
static return_value_policy policy(return_value_policy p) { return p; }
};
// Base class for casting reference/map/block/etc. objects back to python.
template <typename MapType> struct eigen_map_caster {
private:
......
......@@ -34,7 +34,7 @@ private:
*pptr() = traits_type::to_char_type(c);
pbump(1);
}
return sync() ? traits_type::not_eof(c) : traits_type::eof();
return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();
}
int sync() {
......
......@@ -764,6 +764,7 @@ protected:
static std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
auto ndim = shape.size();
std::vector<ssize_t> strides(ndim, itemsize);
if (ndim > 0)
for (size_t i = ndim - 1; i > 0; --i)
strides[i - 1] = strides[i] * shape[i];
return strides;
......@@ -1586,7 +1587,7 @@ Helper vectorize(Return (Class::*f)(Args...)) {
return Helper(std::mem_fn(f));
}
// Vectorize a class method (non-const):
// Vectorize a class method (const):
template <typename Return, typename Class, typename... Args,
typename Helper = detail::vectorize_helper<decltype(std::mem_fn(std::declval<Return (Class::*)(Args...) const>())), Return, const Class *, Args...>>
Helper vectorize(Return (Class::*f)(Args...) const) {
......
......@@ -145,7 +145,7 @@ protected:
capture *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));
/* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */
const auto policy = return_value_policy_override<Return>::policy(call.func.policy);
return_value_policy policy = return_value_policy_override<Return>::policy(call.func.policy);
/* Function scope guard -- defaults to the compile-to-nothing `void_type` */
using Guard = extract_guard_t<Extra...>;
......@@ -314,7 +314,7 @@ protected:
rec->def = new PyMethodDef();
std::memset(rec->def, 0, sizeof(PyMethodDef));
rec->def->ml_name = rec->name;
rec->def->ml_meth = reinterpret_cast<PyCFunction>(*dispatcher);
rec->def->ml_meth = reinterpret_cast<PyCFunction>(reinterpret_cast<void (*) (void)>(*dispatcher));
rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;
capsule rec_capsule(rec, [](void *ptr) {
......@@ -1267,25 +1267,25 @@ private:
auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(
v_h.value_ptr<type>()->shared_from_this());
if (sh) {
new (&v_h.holder<holder_type>()) holder_type(std::move(sh));
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));
v_h.set_holder_constructed();
}
} catch (const std::bad_weak_ptr &) {}
if (!v_h.holder_constructed() && inst->owned) {
new (&v_h.holder<holder_type>()) holder_type(v_h.value_ptr<type>());
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
v_h.set_holder_constructed();
}
}
static void init_holder_from_existing(const detail::value_and_holder &v_h,
const holder_type *holder_ptr, std::true_type /*is_copy_constructible*/) {
new (&v_h.holder<holder_type>()) holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));
new (std::addressof(v_h.holder<holder_type>())) holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));
}
static void init_holder_from_existing(const detail::value_and_holder &v_h,
const holder_type *holder_ptr, std::false_type /*is_copy_constructible*/) {
new (&v_h.holder<holder_type>()) holder_type(std::move(*const_cast<holder_type *>(holder_ptr)));
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(*const_cast<holder_type *>(holder_ptr)));
}
/// Initialize holder object, variant 2: try to construct from existing holder object, if possible
......@@ -1295,7 +1295,7 @@ private:
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
v_h.set_holder_constructed();
} else if (inst->owned || detail::always_construct_holder<holder_type>::value) {
new (&v_h.holder<holder_type>()) holder_type(v_h.value_ptr<type>());
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
v_h.set_holder_constructed();
}
}
......@@ -1631,6 +1631,7 @@ void register_exception_translator(ExceptionTranslator&& translator) {
template <typename type>
class exception : public object {
public:
exception() = default;
exception(handle scope, const char *name, PyObject *base = PyExc_Exception) {
std::string full_name = scope.attr("__name__").cast<std::string>() +
std::string(".") + name;
......@@ -1647,6 +1648,14 @@ public:
}
};
NAMESPACE_BEGIN(detail)
// Returns a reference to a function-local static exception object used in the simple
// register_exception approach below. (It would be simpler to have the static local variable
// directly in register_exception, but that makes clang <3.5 segfault - issue #1349).
template <typename CppException>
exception<CppException> &get_exception_object() { static exception<CppException> ex; return ex; }
NAMESPACE_END(detail)
/**
* Registers a Python exception in `m` of the given `name` and installs an exception translator to
* translate the C++ exception to the created Python exception using the exceptions what() method.
......@@ -1657,13 +1666,15 @@ template <typename CppException>
exception<CppException> &register_exception(handle scope,
const char *name,
PyObject *base = PyExc_Exception) {
static exception<CppException> ex(scope, name, base);
auto &ex = detail::get_exception_object<CppException>();
if (!ex) ex = exception<CppException>(scope, name, base);
register_exception_translator([](std::exception_ptr p) {
if (!p) return;
try {
std::rethrow_exception(p);
} catch (const CppException &e) {
ex(e.what());
detail::get_exception_object<CppException>()(e.what());
}
});
return ex;
......@@ -1736,7 +1747,7 @@ class gil_scoped_acquire {
public:
PYBIND11_NOINLINE gil_scoped_acquire() {
auto const &internals = detail::get_internals();
tstate = (PyThreadState *) PyThread_get_key_value(internals.tstate);
tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate);
if (!tstate) {
tstate = PyThreadState_New(internals.istate);
......@@ -1745,10 +1756,7 @@ public:
pybind11_fail("scoped_acquire: could not create thread state!");
#endif
tstate->gilstate_counter = 0;
#if PY_MAJOR_VERSION < 3
PyThread_delete_key_value(internals.tstate);
#endif
PyThread_set_key_value(internals.tstate, tstate);
PYBIND11_TLS_REPLACE_VALUE(internals.tstate, tstate);
} else {
release = detail::get_thread_state_unchecked() != tstate;
}
......@@ -1787,7 +1795,7 @@ public:
#endif
PyThreadState_Clear(tstate);
PyThreadState_DeleteCurrent();
PyThread_delete_key_value(detail::get_internals().tstate);
PYBIND11_TLS_DELETE_VALUE(detail::get_internals().tstate);
release = false;
}
}
......@@ -1812,11 +1820,7 @@ public:
tstate = PyEval_SaveThread();
if (disassoc) {
auto key = internals.tstate;
#if PY_MAJOR_VERSION < 3
PyThread_delete_key_value(key);
#else
PyThread_set_key_value(key, nullptr);
#endif
PYBIND11_TLS_DELETE_VALUE(key);
}
}
~gil_scoped_release() {
......@@ -1825,10 +1829,7 @@ public:
PyEval_RestoreThread(tstate);
if (disassoc) {
auto key = detail::get_internals().tstate;
#if PY_MAJOR_VERSION < 3
PyThread_delete_key_value(key);
#endif
PyThread_set_key_value(key, tstate);
PYBIND11_TLS_REPLACE_VALUE(key, tstate);
}
}
private:
......@@ -1856,6 +1857,7 @@ class gil_scoped_release { };
error_already_set::~error_already_set() {
if (type) {
error_scope scope;
gil_scoped_acquire gil;
type.release().dec_ref();
value.release().dec_ref();
......
......@@ -83,6 +83,7 @@ template <typename Type, typename Key> struct set_caster {
template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
policy = return_value_policy_override<Key>::policy(policy);
pybind11::set s;
for (auto &&value : src) {
auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent));
......@@ -118,9 +119,11 @@ template <typename Type, typename Key, typename Value> struct map_caster {
template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
dict d;
return_value_policy policy_key = return_value_policy_override<Key>::policy(policy);
return_value_policy policy_value = return_value_policy_override<Value>::policy(policy);
for (auto &&kv : src) {
auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy, parent));
auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy, parent));
auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy_key, parent));
auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy_value, parent));
if (!key || !value)
return handle();
d[key] = value;
......@@ -158,6 +161,7 @@ private:
public:
template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
policy = return_value_policy_override<Value>::policy(policy);
list l(src.size());
size_t index = 0;
for (auto &&value : src) {
......@@ -252,6 +256,7 @@ template<typename T> struct optional_caster {
static handle cast(T_ &&src, return_value_policy policy, handle parent) {
if (!src)
return none().inc_ref();
policy = return_value_policy_override<typename T::value_type>::policy(policy);
return value_conv::cast(*std::forward<T_>(src), policy, parent);
}
......@@ -356,6 +361,7 @@ struct variant_caster<V<Ts...>> {
template <typename... Ts>
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> { };
#endif
NAMESPACE_END(detail)
inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
......
......@@ -135,6 +135,13 @@ function(pybind11_add_module target_name)
PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config
PRIVATE ${PYTHON_INCLUDE_DIRS})
# Python debug libraries expose slightly different objects
# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
if(PYTHON_IS_DEBUG)
target_compile_definitions(${target_name} PRIVATE Py_DEBUG)
endif()
# The prefix and extension are provided by FindPythonLibsNew.cmake
set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
......
Markdown is supported
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