mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
Merge branch 'master' into sh_merge_master_3
This commit is contained in:
commit
10d4aa7476
5
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
5
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -21,10 +21,11 @@ body:
|
|||||||
- label: Consider asking first in the [Gitter chat room](https://gitter.im/pybind/Lobby) or in a [Discussion](https:/pybind/pybind11/discussions/new).
|
- label: Consider asking first in the [Gitter chat room](https://gitter.im/pybind/Lobby) or in a [Discussion](https:/pybind/pybind11/discussions/new).
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
- type: Input
|
- type: input
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
label: What version (or hash if on master) of pybind11 are you using?
|
label: What version (or hash if on master) of pybind11 are you using?
|
||||||
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
@ -52,7 +53,7 @@ body:
|
|||||||
starting point for working out fixes.
|
starting point for working out fixes.
|
||||||
render: text
|
render: text
|
||||||
|
|
||||||
- type: Input
|
- type: input
|
||||||
id: regression
|
id: regression
|
||||||
attributes:
|
attributes:
|
||||||
label: Is this a regression? Put the last known working version here if it is.
|
label: Is this a regression? Put the last known working version here if it is.
|
||||||
|
4
.github/workflows/pip.yml
vendored
4
.github/workflows/pip.yml
vendored
@ -99,13 +99,13 @@ jobs:
|
|||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
|
|
||||||
- name: Publish standard package
|
- name: Publish standard package
|
||||||
uses: pypa/gh-action-pypi-publish@v1.5.1
|
uses: pypa/gh-action-pypi-publish@v1.5.2
|
||||||
with:
|
with:
|
||||||
password: ${{ secrets.pypi_password }}
|
password: ${{ secrets.pypi_password }}
|
||||||
packages_dir: standard/
|
packages_dir: standard/
|
||||||
|
|
||||||
- name: Publish global package
|
- name: Publish global package
|
||||||
uses: pypa/gh-action-pypi-publish@v1.5.1
|
uses: pypa/gh-action-pypi-publish@v1.5.2
|
||||||
with:
|
with:
|
||||||
password: ${{ secrets.pypi_password_global }}
|
password: ${{ secrets.pypi_password_global }}
|
||||||
packages_dir: global/
|
packages_dir: global/
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
|
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
|
||||||
@ -419,7 +422,7 @@ struct string_caster {
|
|||||||
|
|
||||||
// For UTF-8 we avoid the need for a temporary `bytes` object by using
|
// For UTF-8 we avoid the need for a temporary `bytes` object by using
|
||||||
// `PyUnicode_AsUTF8AndSize`.
|
// `PyUnicode_AsUTF8AndSize`.
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {
|
if (UTF_N == 8) {
|
||||||
Py_ssize_t size = -1;
|
Py_ssize_t size = -1;
|
||||||
const auto *buffer
|
const auto *buffer
|
||||||
= reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
|
= reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
|
||||||
@ -446,7 +449,7 @@ struct string_caster {
|
|||||||
= reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
|
= reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
|
||||||
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
|
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
|
||||||
// Skip BOM for UTF-16/32
|
// Skip BOM for UTF-16/32
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {
|
if (UTF_N > 8) {
|
||||||
buffer++;
|
buffer++;
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
@ -606,7 +609,7 @@ public:
|
|||||||
// figure out how long the first encoded character is in bytes to distinguish between these
|
// figure out how long the first encoded character is in bytes to distinguish between these
|
||||||
// two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as
|
// two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as
|
||||||
// those can fit into a single char value.
|
// those can fit into a single char value.
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {
|
if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
|
||||||
auto v0 = static_cast<unsigned char>(value[0]);
|
auto v0 = static_cast<unsigned char>(value[0]);
|
||||||
// low bits only: 0-127
|
// low bits only: 0-127
|
||||||
// 0b110xxxxx - start of 2-byte sequence
|
// 0b110xxxxx - start of 2-byte sequence
|
||||||
@ -632,7 +635,7 @@ public:
|
|||||||
// UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
|
// UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
|
||||||
// surrogate pair with total length 2 instantly indicates a range error (but not a "your
|
// surrogate pair with total length 2 instantly indicates a range error (but not a "your
|
||||||
// string was too long" error).
|
// string was too long" error).
|
||||||
else if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 16) && str_len == 2) {
|
else if (StringCaster::UTF_N == 16 && str_len == 2) {
|
||||||
one_char = static_cast<CharT>(value[0]);
|
one_char = static_cast<CharT>(value[0]);
|
||||||
if (one_char >= 0xD800 && one_char < 0xE000) {
|
if (one_char >= 0xD800 && one_char < 0xE000) {
|
||||||
throw value_error("Character code point not in range(0x10000)");
|
throw value_error("Character code point not in range(0x10000)");
|
||||||
|
@ -17,8 +17,69 @@
|
|||||||
// Additional convention: 0xD = dev
|
// Additional convention: 0xD = dev
|
||||||
#define PYBIND11_VERSION_HEX 0x020B00D1
|
#define PYBIND11_VERSION_HEX 0x020B00D1
|
||||||
|
|
||||||
#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
|
// Define some generic pybind11 helper macros for warning management.
|
||||||
#define PYBIND11_NAMESPACE_END(name) }
|
//
|
||||||
|
// Note that compiler-specific push/pop pairs are baked into the
|
||||||
|
// PYBIND11_NAMESPACE_BEGIN/PYBIND11_NAMESPACE_END pair of macros. Therefore manual
|
||||||
|
// PYBIND11_WARNING_PUSH/PYBIND11_WARNING_POP are usually only needed in `#include` sections.
|
||||||
|
//
|
||||||
|
// If you find you need to suppress a warning, please try to make the suppression as local as
|
||||||
|
// possible using these macros. Please also be sure to push/pop with the pybind11 macros. Please
|
||||||
|
// only use compiler specifics if you need to check specific versions, e.g. Apple Clang vs. vanilla
|
||||||
|
// Clang.
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define PYBIND11_COMPILER_MSVC
|
||||||
|
# define PYBIND11_PRAGMA(...) __pragma(__VA_ARGS__)
|
||||||
|
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning(push))
|
||||||
|
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning(pop))
|
||||||
|
#elif defined(__INTEL_COMPILER)
|
||||||
|
# define PYBIND11_COMPILER_INTEL
|
||||||
|
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
|
||||||
|
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning push)
|
||||||
|
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning pop)
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define PYBIND11_COMPILER_CLANG
|
||||||
|
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
|
||||||
|
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(clang diagnostic push)
|
||||||
|
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(clang diagnostic push)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define PYBIND11_COMPILER_GCC
|
||||||
|
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
|
||||||
|
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(GCC diagnostic push)
|
||||||
|
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(GCC diagnostic pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PYBIND11_COMPILER_MSVC
|
||||||
|
# define PYBIND11_WARNING_DISABLE_MSVC(name) PYBIND11_PRAGMA(warning(disable : name))
|
||||||
|
#else
|
||||||
|
# define PYBIND11_WARNING_DISABLE_MSVC(name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PYBIND11_COMPILER_CLANG
|
||||||
|
# define PYBIND11_WARNING_DISABLE_CLANG(name) PYBIND11_PRAGMA(clang diagnostic ignored name)
|
||||||
|
#else
|
||||||
|
# define PYBIND11_WARNING_DISABLE_CLANG(name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PYBIND11_COMPILER_GCC
|
||||||
|
# define PYBIND11_WARNING_DISABLE_GCC(name) PYBIND11_PRAGMA(GCC diagnostic ignored name)
|
||||||
|
#else
|
||||||
|
# define PYBIND11_WARNING_DISABLE_GCC(name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PYBIND11_COMPILER_INTEL
|
||||||
|
# define PYBIND11_WARNING_DISABLE_INTEL(name) PYBIND11_PRAGMA(warning disable name)
|
||||||
|
#else
|
||||||
|
# define PYBIND11_WARNING_DISABLE_INTEL(name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PYBIND11_NAMESPACE_BEGIN(name) \
|
||||||
|
namespace name { \
|
||||||
|
PYBIND11_WARNING_PUSH
|
||||||
|
|
||||||
|
#define PYBIND11_NAMESPACE_END(name) \
|
||||||
|
PYBIND11_WARNING_POP \
|
||||||
|
}
|
||||||
|
|
||||||
// Robust support for some features and loading modules compiled against different pybind versions
|
// Robust support for some features and loading modules compiled against different pybind versions
|
||||||
// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute
|
// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute
|
||||||
@ -151,9 +212,9 @@
|
|||||||
|
|
||||||
/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
|
/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(push)
|
PYBIND11_WARNING_PUSH
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4505)
|
||||||
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
|
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
|
||||||
# pragma warning(disable : 4505)
|
|
||||||
# if defined(_DEBUG) && !defined(Py_DEBUG)
|
# if defined(_DEBUG) && !defined(Py_DEBUG)
|
||||||
// Workaround for a VS 2022 issue.
|
// Workaround for a VS 2022 issue.
|
||||||
// NOTE: This workaround knowingly violates the Python.h include order requirement:
|
// NOTE: This workaround knowingly violates the Python.h include order requirement:
|
||||||
@ -236,7 +297,7 @@
|
|||||||
# define _DEBUG
|
# define _DEBUG
|
||||||
# undef PYBIND11_DEBUG_MARKER
|
# undef PYBIND11_DEBUG_MARKER
|
||||||
# endif
|
# endif
|
||||||
# pragma warning(pop)
|
PYBIND11_WARNING_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -1160,17 +1221,6 @@ constexpr
|
|||||||
# define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
|
# define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) // All versions (as of July 2021).
|
|
||||||
|
|
||||||
// warning C4127: Conditional expression is constant
|
|
||||||
constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }
|
|
||||||
|
|
||||||
# define PYBIND11_SILENCE_MSVC_C4127(...) ::pybind11::detail::silence_msvc_c4127(__VA_ARGS__)
|
|
||||||
|
|
||||||
#else
|
|
||||||
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__) \
|
#if defined(__clang__) \
|
||||||
&& (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \
|
&& (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \
|
||||||
available. */ \
|
available. */ \
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include "smart_holder_sfinae_hooks_only.h"
|
#include "smart_holder_sfinae_hooks_only.h"
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -116,7 +119,7 @@ template <typename Class>
|
|||||||
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
||||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||||
no_nullptr(ptr);
|
no_nullptr(ptr);
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
|
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||||
// We're going to try to construct an alias by moving the cpp type. Whether or not
|
// We're going to try to construct an alias by moving the cpp type. Whether or not
|
||||||
// that succeeds, we still need to destroy the original cpp pointer (either the
|
// that succeeds, we still need to destroy the original cpp pointer (either the
|
||||||
// moved away leftover, if the alias construction works, or the value itself if we
|
// moved away leftover, if the alias construction works, or the value itself if we
|
||||||
@ -162,7 +165,7 @@ void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
|||||||
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
||||||
no_nullptr(ptr);
|
no_nullptr(ptr);
|
||||||
// If we need an alias, check that the held pointer is actually an alias instance
|
// If we need an alias, check that the held pointer is actually an alias instance
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
|
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||||
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
|
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
|
||||||
"is not an alias instance");
|
"is not an alias instance");
|
||||||
}
|
}
|
||||||
@ -180,7 +183,7 @@ void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
|
|||||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||||
static_assert(std::is_move_constructible<Cpp<Class>>::value,
|
static_assert(std::is_move_constructible<Cpp<Class>>::value,
|
||||||
"pybind11::init() return-by-value factory function requires a movable class");
|
"pybind11::init() return-by-value factory function requires a movable class");
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias) {
|
if (Class::has_alias && need_alias) {
|
||||||
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
|
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
|
||||||
} else {
|
} else {
|
||||||
v_h.value_ptr() = new Cpp<Class>(std::move(result));
|
v_h.value_ptr() = new Cpp<Class>(std::move(result));
|
||||||
|
@ -479,9 +479,6 @@ PYBIND11_NOINLINE internals &get_internals() {
|
|||||||
internals_ptr = new internals();
|
internals_ptr = new internals();
|
||||||
#if defined(WITH_THREAD)
|
#if defined(WITH_THREAD)
|
||||||
|
|
||||||
# if PY_VERSION_HEX < 0x03090000
|
|
||||||
PyEval_InitThreads();
|
|
||||||
# endif
|
|
||||||
PyThreadState *tstate = PyThreadState_Get();
|
PyThreadState *tstate = PyThreadState_Get();
|
||||||
if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
|
if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
|
||||||
pybind11_fail("get_internals: could not successfully initialize the tstate TSS key!");
|
pybind11_fail("get_internals: could not successfully initialize the tstate TSS key!");
|
||||||
|
@ -16,29 +16,15 @@
|
|||||||
https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
|
https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
|
||||||
https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler
|
https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler
|
||||||
*/
|
*/
|
||||||
// The C4127 suppression was introduced for Eigen 3.4.0. In theory we could
|
PYBIND11_WARNING_PUSH
|
||||||
// make it version specific, or even remove it later, but considering that
|
PYBIND11_WARNING_DISABLE_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
|
||||||
// 1. C4127 is generally far more distracting than useful for modern template code, and
|
|
||||||
// 2. we definitely want to ignore any MSVC warnings originating from Eigen code,
|
|
||||||
// it is probably best to keep this around indefinitely.
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable : 4127) // C4127: conditional expression is constant
|
|
||||||
# pragma warning(disable : 5054) // https://github.com/pybind/pybind11/pull/3741
|
|
||||||
// C5054: operator '&': deprecated between enumerations of different types
|
// C5054: operator '&': deprecated between enumerations of different types
|
||||||
#elif defined(__MINGW32__)
|
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
|
||||||
# pragma GCC diagnostic push
|
|
||||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
#include <Eigen/SparseCore>
|
#include <Eigen/SparseCore>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
PYBIND11_WARNING_POP
|
||||||
# pragma warning(pop)
|
|
||||||
#elif defined(__MINGW32__)
|
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit
|
// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit
|
||||||
// move constructors that break things. We could detect this an explicitly copy, but an extra copy
|
// move constructors that break things. We could detect this an explicitly copy, but an extra copy
|
||||||
@ -48,6 +34,8 @@ static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
|
|||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
|
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
|
||||||
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
template <typename MatrixType>
|
template <typename MatrixType>
|
||||||
@ -189,8 +177,7 @@ struct EigenProps {
|
|||||||
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
|
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
|
||||||
np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
|
np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
|
||||||
np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));
|
np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));
|
||||||
if ((PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && np_rows != rows)
|
if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
|
||||||
|| (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +190,7 @@ struct EigenProps {
|
|||||||
stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
|
stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
|
||||||
|
|
||||||
if (vector) { // Eigen type is a compile-time vector
|
if (vector) { // Eigen type is a compile-time vector
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(fixed) && size != n) {
|
if (fixed && size != n) {
|
||||||
return false; // Vector size mismatch
|
return false; // Vector size mismatch
|
||||||
}
|
}
|
||||||
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
|
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
|
||||||
@ -220,7 +207,7 @@ struct EigenProps {
|
|||||||
}
|
}
|
||||||
return {1, n, stride};
|
return {1, n, stride};
|
||||||
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
|
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && rows != n) {
|
if (fixed_rows && rows != n) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return {n, 1, stride};
|
return {n, 1, stride};
|
||||||
|
@ -13,28 +13,23 @@
|
|||||||
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
|
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
// Disable warnings for Eigen
|
||||||
# pragma warning(push)
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma warning(disable : 4554) // Tensor.h warning
|
PYBIND11_WARNING_DISABLE_MSVC(4554)
|
||||||
# pragma warning(disable : 4127) // Tensor.h warning
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
#elif defined(__MINGW32__)
|
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
|
||||||
# pragma GCC diagnostic push
|
|
||||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <unsupported/Eigen/CXX11/Tensor>
|
#include <unsupported/Eigen/CXX11/Tensor>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
PYBIND11_WARNING_POP
|
||||||
# pragma warning(pop)
|
|
||||||
#elif defined(__MINGW32__)
|
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
|
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
|
||||||
"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
|
"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
inline bool is_tensor_aligned(const void *data) {
|
inline bool is_tensor_aligned(const void *data) {
|
||||||
@ -138,10 +133,8 @@ struct get_tensor_descriptor {
|
|||||||
//
|
//
|
||||||
// We need to disable the type-limits warning for the inner loop when size = 0.
|
// We need to disable the type-limits warning for the inner loop when size = 0.
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma GCC diagnostic push
|
PYBIND11_WARNING_DISABLE_GCC("-Wtype-limits")
|
||||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T, int size>
|
template <typename T, int size>
|
||||||
std::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) {
|
std::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) {
|
||||||
@ -165,9 +158,7 @@ Eigen::DSizes<T, size> get_shape_for_array(const array &arr) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
PYBIND11_WARNING_POP
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
|
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
|
||||||
@ -393,7 +384,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
|
|||||||
|
|
||||||
constexpr bool is_aligned = (Options & Eigen::Aligned) != 0;
|
constexpr bool is_aligned = (Options & Eigen::Aligned) != 0;
|
||||||
|
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(is_aligned) && !is_tensor_aligned(arr.data())) {
|
if (is_aligned && !is_tensor_aligned(arr.data())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +394,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(needs_writeable) && !arr.writeable()) {
|
if (needs_writeable && !arr.writeable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,38 +86,26 @@ inline wchar_t *widen_chars(const char *safe_arg) {
|
|||||||
return widened_arg;
|
return widened_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
inline void precheck_interpreter() {
|
||||||
|
|
||||||
/** \rst
|
|
||||||
Initialize the Python interpreter. No other pybind11 or CPython API functions can be
|
|
||||||
called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The
|
|
||||||
optional `init_signal_handlers` parameter can be used to skip the registration of
|
|
||||||
signal handlers (see the `Python documentation`_ for details). Calling this function
|
|
||||||
again after the interpreter has already been initialized is a fatal error.
|
|
||||||
|
|
||||||
If initializing the Python interpreter fails, then the program is terminated. (This
|
|
||||||
is controlled by the CPython runtime and is an exception to pybind11's normal behavior
|
|
||||||
of throwing exceptions on errors.)
|
|
||||||
|
|
||||||
The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are
|
|
||||||
used to populate ``sys.argv`` and ``sys.path``.
|
|
||||||
See the |PySys_SetArgvEx documentation|_ for details.
|
|
||||||
|
|
||||||
.. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx
|
|
||||||
.. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation
|
|
||||||
.. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx
|
|
||||||
\endrst */
|
|
||||||
inline void initialize_interpreter(bool init_signal_handlers = true,
|
|
||||||
int argc = 0,
|
|
||||||
const char *const *argv = nullptr,
|
|
||||||
bool add_program_dir_to_path = true) {
|
|
||||||
if (Py_IsInitialized() != 0) {
|
if (Py_IsInitialized() != 0) {
|
||||||
pybind11_fail("The interpreter is already running");
|
pybind11_fail("The interpreter is already running");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if PY_VERSION_HEX < 0x030B0000
|
#if !defined(PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX)
|
||||||
|
# define PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX (0x03080000)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||||
|
inline void initialize_interpreter_pre_pyconfig(bool init_signal_handlers,
|
||||||
|
int argc,
|
||||||
|
const char *const *argv,
|
||||||
|
bool add_program_dir_to_path) {
|
||||||
|
detail::precheck_interpreter();
|
||||||
Py_InitializeEx(init_signal_handlers ? 1 : 0);
|
Py_InitializeEx(init_signal_handlers ? 1 : 0);
|
||||||
|
# if defined(WITH_THREAD) && PY_VERSION_HEX < 0x03070000
|
||||||
|
PyEval_InitThreads();
|
||||||
|
# endif
|
||||||
|
|
||||||
// Before it was special-cased in python 3.8, passing an empty or null argv
|
// Before it was special-cased in python 3.8, passing an empty or null argv
|
||||||
// caused a segfault, so we have to reimplement the special case ourselves.
|
// caused a segfault, so we have to reimplement the special case ourselves.
|
||||||
@ -147,25 +135,29 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
|
|||||||
auto *pysys_argv = widened_argv.get();
|
auto *pysys_argv = widened_argv.get();
|
||||||
|
|
||||||
PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
|
PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
|
||||||
#else
|
}
|
||||||
PyConfig config;
|
#endif
|
||||||
PyConfig_InitIsolatedConfig(&config);
|
|
||||||
config.isolated = 0;
|
|
||||||
config.use_environment = 1;
|
|
||||||
config.install_signal_handlers = init_signal_handlers ? 1 : 0;
|
|
||||||
|
|
||||||
PyStatus status = PyConfig_SetBytesArgv(&config, argc, const_cast<char *const *>(argv));
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
if (PyStatus_Exception(status)) {
|
|
||||||
|
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||||
|
inline void initialize_interpreter(PyConfig *config,
|
||||||
|
int argc = 0,
|
||||||
|
const char *const *argv = nullptr,
|
||||||
|
bool add_program_dir_to_path = true) {
|
||||||
|
detail::precheck_interpreter();
|
||||||
|
PyStatus status = PyConfig_SetBytesArgv(config, argc, const_cast<char *const *>(argv));
|
||||||
|
if (PyStatus_Exception(status) != 0) {
|
||||||
// A failure here indicates a character-encoding failure or the python
|
// A failure here indicates a character-encoding failure or the python
|
||||||
// interpreter out of memory. Give up.
|
// interpreter out of memory. Give up.
|
||||||
PyConfig_Clear(&config);
|
PyConfig_Clear(config);
|
||||||
throw std::runtime_error(PyStatus_IsError(status) ? status.err_msg
|
throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
|
||||||
: "Failed to prepare CPython");
|
: "Failed to prepare CPython");
|
||||||
}
|
}
|
||||||
status = Py_InitializeFromConfig(&config);
|
status = Py_InitializeFromConfig(config);
|
||||||
PyConfig_Clear(&config);
|
if (PyStatus_Exception(status) != 0) {
|
||||||
if (PyStatus_Exception(status)) {
|
PyConfig_Clear(config);
|
||||||
throw std::runtime_error(PyStatus_IsError(status) ? status.err_msg
|
throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
|
||||||
: "Failed to init CPython");
|
: "Failed to init CPython");
|
||||||
}
|
}
|
||||||
if (add_program_dir_to_path) {
|
if (add_program_dir_to_path) {
|
||||||
@ -174,6 +166,43 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
|
|||||||
"os.path.abspath(os.path.dirname(sys.argv[0])) "
|
"os.path.abspath(os.path.dirname(sys.argv[0])) "
|
||||||
"if sys.argv and os.path.exists(sys.argv[0]) else '')");
|
"if sys.argv and os.path.exists(sys.argv[0]) else '')");
|
||||||
}
|
}
|
||||||
|
PyConfig_Clear(config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Initialize the Python interpreter. No other pybind11 or CPython API functions can be
|
||||||
|
called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The
|
||||||
|
optional `init_signal_handlers` parameter can be used to skip the registration of
|
||||||
|
signal handlers (see the `Python documentation`_ for details). Calling this function
|
||||||
|
again after the interpreter has already been initialized is a fatal error.
|
||||||
|
|
||||||
|
If initializing the Python interpreter fails, then the program is terminated. (This
|
||||||
|
is controlled by the CPython runtime and is an exception to pybind11's normal behavior
|
||||||
|
of throwing exceptions on errors.)
|
||||||
|
|
||||||
|
The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are
|
||||||
|
used to populate ``sys.argv`` and ``sys.path``.
|
||||||
|
See the |PySys_SetArgvEx documentation|_ for details.
|
||||||
|
|
||||||
|
.. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx
|
||||||
|
.. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation
|
||||||
|
.. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx
|
||||||
|
\endrst */
|
||||||
|
inline void initialize_interpreter(bool init_signal_handlers = true,
|
||||||
|
int argc = 0,
|
||||||
|
const char *const *argv = nullptr,
|
||||||
|
bool add_program_dir_to_path = true) {
|
||||||
|
#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||||
|
detail::initialize_interpreter_pre_pyconfig(
|
||||||
|
init_signal_handlers, argc, argv, add_program_dir_to_path);
|
||||||
|
#else
|
||||||
|
PyConfig config;
|
||||||
|
PyConfig_InitIsolatedConfig(&config);
|
||||||
|
config.isolated = 0;
|
||||||
|
config.use_environment = 1;
|
||||||
|
config.install_signal_handlers = init_signal_handlers ? 1 : 0;
|
||||||
|
initialize_interpreter(&config, argc, argv, add_program_dir_to_path);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +290,15 @@ public:
|
|||||||
initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
|
initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||||
|
explicit scoped_interpreter(PyConfig *config,
|
||||||
|
int argc = 0,
|
||||||
|
const char *const *argv = nullptr,
|
||||||
|
bool add_program_dir_to_path = true) {
|
||||||
|
initialize_interpreter(config, argc, argv, add_program_dir_to_path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
scoped_interpreter(const scoped_interpreter &) = delete;
|
scoped_interpreter(const scoped_interpreter &) = delete;
|
||||||
scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
|
scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
|
||||||
scoped_interpreter &operator=(const scoped_interpreter &) = delete;
|
scoped_interpreter &operator=(const scoped_interpreter &) = delete;
|
||||||
|
@ -36,6 +36,8 @@ static_assert(std::is_signed<Py_intptr_t>::value, "Py_intptr_t must be signed");
|
|||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
class array; // Forward declaration
|
class array; // Forward declaration
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
@ -875,7 +877,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <typename T, ssize_t Dims = -1>
|
template <typename T, ssize_t Dims = -1>
|
||||||
detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
|
detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
|
if (Dims >= 0 && ndim() != Dims) {
|
||||||
throw std::domain_error("array has incorrect number of dimensions: "
|
throw std::domain_error("array has incorrect number of dimensions: "
|
||||||
+ std::to_string(ndim()) + "; expected "
|
+ std::to_string(ndim()) + "; expected "
|
||||||
+ std::to_string(Dims));
|
+ std::to_string(Dims));
|
||||||
@ -893,7 +895,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <typename T, ssize_t Dims = -1>
|
template <typename T, ssize_t Dims = -1>
|
||||||
detail::unchecked_reference<T, Dims> unchecked() const & {
|
detail::unchecked_reference<T, Dims> unchecked() const & {
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
|
if (Dims >= 0 && ndim() != Dims) {
|
||||||
throw std::domain_error("array has incorrect number of dimensions: "
|
throw std::domain_error("array has incorrect number of dimensions: "
|
||||||
+ std::to_string(ndim()) + "; expected "
|
+ std::to_string(ndim()) + "; expected "
|
||||||
+ std::to_string(Dims));
|
+ std::to_string(Dims));
|
||||||
@ -1865,9 +1867,10 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto result = returned_array::create(trivial, shape);
|
auto result = returned_array::create(trivial, shape);
|
||||||
|
|
||||||
|
PYBIND11_WARNING_PUSH
|
||||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
||||||
# pragma clang diagnostic push
|
PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
|
||||||
# pragma clang diagnostic ignored "-Wreturn-std-move"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
@ -1883,9 +1886,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
PYBIND11_WARNING_POP
|
||||||
# pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t... Index, size_t... VIndex, size_t... BIndex>
|
template <size_t... Index, size_t... VIndex, size_t... BIndex>
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
# include <cxxabi.h>
|
# include <cxxabi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning
|
/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning
|
||||||
This warning is about ABI compatibility, not code health.
|
This warning is about ABI compatibility, not code health.
|
||||||
It is only actually needed in a couple places, but apparently GCC 7 "generates this warning if
|
It is only actually needed in a couple places, but apparently GCC 7 "generates this warning if
|
||||||
@ -44,11 +46,10 @@
|
|||||||
No other GCC version generates this warning.
|
No other GCC version generates this warning.
|
||||||
*/
|
*/
|
||||||
#if defined(__GNUC__) && __GNUC__ == 7
|
#if defined(__GNUC__) && __GNUC__ == 7
|
||||||
# pragma GCC diagnostic push
|
PYBIND11_WARNING_DISABLE_GCC("-Wnoexcept-type")
|
||||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
@ -178,22 +179,22 @@ protected:
|
|||||||
auto *rec = unique_rec.get();
|
auto *rec = unique_rec.get();
|
||||||
|
|
||||||
/* Store the capture object directly in the function record if there is enough space */
|
/* Store the capture object directly in the function record if there is enough space */
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(capture) <= sizeof(rec->data))) {
|
if (sizeof(capture) <= sizeof(rec->data)) {
|
||||||
/* Without these pragmas, GCC warns that there might not be
|
/* Without these pragmas, GCC warns that there might not be
|
||||||
enough space to use the placement new operator. However, the
|
enough space to use the placement new operator. However, the
|
||||||
'if' statement above ensures that this is the case. */
|
'if' statement above ensures that this is the case. */
|
||||||
#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma GCC diagnostic push
|
|
||||||
# pragma GCC diagnostic ignored "-Wplacement-new"
|
#if defined(__GNUG__) && __GNUC__ >= 6
|
||||||
|
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
new ((capture *) &rec->data) capture{std::forward<Func>(f)};
|
new ((capture *) &rec->data) capture{std::forward<Func>(f)};
|
||||||
#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
|
||||||
# pragma GCC diagnostic pop
|
#if !PYBIND11_HAS_STD_LAUNDER
|
||||||
#endif
|
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
||||||
#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)
|
|
||||||
# pragma GCC diagnostic push
|
|
||||||
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// UB without std::launder, but without breaking ABI and/or
|
// UB without std::launder, but without breaking ABI and/or
|
||||||
// a significant refactoring it's "impossible" to solve.
|
// a significant refactoring it's "impossible" to solve.
|
||||||
if (!std::is_trivially_destructible<capture>::value) {
|
if (!std::is_trivially_destructible<capture>::value) {
|
||||||
@ -203,9 +204,7 @@ protected:
|
|||||||
data->~capture();
|
data->~capture();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_POP
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
rec->data[0] = new capture{std::forward<Func>(f)};
|
rec->data[0] = new capture{std::forward<Func>(f)};
|
||||||
rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
|
rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
|
||||||
@ -2087,8 +2086,7 @@ private:
|
|||||||
if (holder_ptr) {
|
if (holder_ptr) {
|
||||||
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
} else if (PYBIND11_SILENCE_MSVC_C4127(detail::always_construct_holder<holder_type>::value)
|
} else if (detail::always_construct_holder<holder_type>::value || inst->owned) {
|
||||||
|| inst->owned) {
|
|
||||||
new (std::addressof(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();
|
v_h.set_holder_constructed();
|
||||||
}
|
}
|
||||||
@ -3131,7 +3129,3 @@ inline function get_overload(const T *this_ptr, const char *name) {
|
|||||||
PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);
|
PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 7
|
|
||||||
# pragma GCC diagnostic pop // -Wnoexcept-type
|
|
||||||
#endif
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
/* A few forward declarations */
|
/* A few forward declarations */
|
||||||
class handle;
|
class handle;
|
||||||
class object;
|
class object;
|
||||||
@ -884,10 +886,8 @@ object object_or_cast(T &&o);
|
|||||||
// Match a PyObject*, which we want to convert directly to handle via its converting constructor
|
// Match a PyObject*, which we want to convert directly to handle via its converting constructor
|
||||||
inline handle object_or_cast(PyObject *ptr) { return ptr; }
|
inline handle object_or_cast(PyObject *ptr) { return ptr; }
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1920
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma warning(push)
|
PYBIND11_WARNING_DISABLE_MSVC(4522) // warning C4522: multiple assignment operators specified
|
||||||
# pragma warning(disable : 4522) // warning C4522: multiple assignment operators specified
|
|
||||||
#endif
|
|
||||||
template <typename Policy>
|
template <typename Policy>
|
||||||
class accessor : public object_api<accessor<Policy>> {
|
class accessor : public object_api<accessor<Policy>> {
|
||||||
using key_type = typename Policy::key_type;
|
using key_type = typename Policy::key_type;
|
||||||
@ -951,9 +951,7 @@ private:
|
|||||||
key_type key;
|
key_type key;
|
||||||
mutable object cache;
|
mutable object cache;
|
||||||
};
|
};
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1920
|
PYBIND11_WARNING_POP
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(accessor_policies)
|
PYBIND11_NAMESPACE_BEGIN(accessor_policies)
|
||||||
struct obj_attr {
|
struct obj_attr {
|
||||||
@ -1693,7 +1691,7 @@ PYBIND11_NAMESPACE_BEGIN(detail)
|
|||||||
// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).
|
// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).
|
||||||
template <typename Unsigned>
|
template <typename Unsigned>
|
||||||
Unsigned as_unsigned(PyObject *o) {
|
Unsigned as_unsigned(PyObject *o) {
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))) {
|
if (sizeof(Unsigned) <= sizeof(unsigned long)) {
|
||||||
unsigned long v = PyLong_AsUnsignedLong(o);
|
unsigned long v = PyLong_AsUnsignedLong(o);
|
||||||
return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
|
return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
|
||||||
}
|
}
|
||||||
@ -1710,7 +1708,7 @@ public:
|
|||||||
template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
int_(T value) {
|
int_(T value) {
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {
|
if (sizeof(T) <= sizeof(long)) {
|
||||||
if (std::is_signed<T>::value) {
|
if (std::is_signed<T>::value) {
|
||||||
m_ptr = PyLong_FromLong((long) value);
|
m_ptr = PyLong_FromLong((long) value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,6 +7,8 @@ Adds docstring and exceptions message sanitizers.
|
|||||||
import contextlib
|
import contextlib
|
||||||
import difflib
|
import difflib
|
||||||
import gc
|
import gc
|
||||||
|
import multiprocessing
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
@ -15,6 +17,22 @@ import pytest
|
|||||||
# Early diagnostic for failed imports
|
# Early diagnostic for failed imports
|
||||||
import pybind11_tests
|
import pybind11_tests
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
|
def always_forkserver_on_unix():
|
||||||
|
if os.name == "nt":
|
||||||
|
return
|
||||||
|
|
||||||
|
# Full background: https://github.com/pybind/pybind11/issues/4105#issuecomment-1301004592
|
||||||
|
# In a nutshell: fork() after starting threads == flakiness in the form of deadlocks.
|
||||||
|
# It is actually a well-known pitfall, unfortunately without guard rails.
|
||||||
|
# "forkserver" is more performant than "spawn" (~9s vs ~13s for tests/test_gil_scoped.py,
|
||||||
|
# visit the issuecomment link above for details).
|
||||||
|
# Windows does not have fork() and the associated pitfall, therefore it is best left
|
||||||
|
# running with defaults.
|
||||||
|
multiprocessing.set_start_method("forkserver")
|
||||||
|
|
||||||
|
|
||||||
_long_marker = re.compile(r"([0-9])L")
|
_long_marker = re.compile(r"([0-9])L")
|
||||||
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")
|
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")
|
||||||
|
|
||||||
|
@ -80,6 +80,9 @@ PYBIND11_NAMESPACE_END(detail)
|
|||||||
PYBIND11_NAMESPACE_END(pybind11)
|
PYBIND11_NAMESPACE_END(pybind11)
|
||||||
|
|
||||||
TEST_SUBMODULE(builtin_casters, m) {
|
TEST_SUBMODULE(builtin_casters, m) {
|
||||||
|
PYBIND11_WARNING_PUSH
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
// test_simple_string
|
// test_simple_string
|
||||||
m.def("string_roundtrip", [](const char *s) { return s; });
|
m.def("string_roundtrip", [](const char *s) { return s; });
|
||||||
|
|
||||||
@ -93,7 +96,7 @@ TEST_SUBMODULE(builtin_casters, m) {
|
|||||||
std::wstring wstr;
|
std::wstring wstr;
|
||||||
wstr.push_back(0x61); // a
|
wstr.push_back(0x61); // a
|
||||||
wstr.push_back(0x2e18); // ⸘
|
wstr.push_back(0x2e18); // ⸘
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {
|
if (sizeof(wchar_t) == 2) {
|
||||||
wstr.push_back(mathbfA16_1);
|
wstr.push_back(mathbfA16_1);
|
||||||
wstr.push_back(mathbfA16_2);
|
wstr.push_back(mathbfA16_2);
|
||||||
} // 𝐀, utf16
|
} // 𝐀, utf16
|
||||||
@ -120,7 +123,7 @@ TEST_SUBMODULE(builtin_casters, m) {
|
|||||||
// Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger
|
// Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger
|
||||||
// UnicodeDecodeError
|
// UnicodeDecodeError
|
||||||
m.def("bad_utf32_string", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); });
|
m.def("bad_utf32_string", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); });
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {
|
if (sizeof(wchar_t) == 2) {
|
||||||
m.def("bad_wchar_string", [=]() {
|
m.def("bad_wchar_string", [=]() {
|
||||||
return std::wstring({wchar_t(0x61), wchar_t(0xd800)});
|
return std::wstring({wchar_t(0x61), wchar_t(0xd800)});
|
||||||
});
|
});
|
||||||
@ -415,4 +418,6 @@ TEST_SUBMODULE(builtin_casters, m) {
|
|||||||
[]() { return std::string_view("\xba\xd0\xba\xd0"); },
|
[]() { return std::string_view("\xba\xd0\xba\xd0"); },
|
||||||
py::return_value_policy::_return_as_bytes);
|
py::return_value_policy::_return_as_bytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PYBIND11_WARNING_POP
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,8 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
PYBIND11_WARNING_DISABLE_MSVC(4324)
|
||||||
# pragma warning(disable : 4324)
|
|
||||||
// warning C4324: structure was padded due to alignment specifier
|
// warning C4324: structure was padded due to alignment specifier
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -52,15 +52,12 @@ int f1(int x) noexcept { return x + 1; }
|
|||||||
#endif
|
#endif
|
||||||
int f2(int x) noexcept(true) { return x + 2; }
|
int f2(int x) noexcept(true) { return x + 2; }
|
||||||
int f3(int x) noexcept(false) { return x + 3; }
|
int f3(int x) noexcept(false) { return x + 3; }
|
||||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma GCC diagnostic push
|
PYBIND11_WARNING_DISABLE_GCC("-Wdeprecated")
|
||||||
# pragma GCC diagnostic ignored "-Wdeprecated"
|
PYBIND11_WARNING_DISABLE_CLANG("-Wdeprecated")
|
||||||
#endif
|
|
||||||
// NOLINTNEXTLINE(modernize-use-noexcept)
|
// NOLINTNEXTLINE(modernize-use-noexcept)
|
||||||
int f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true)
|
int f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true)
|
||||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_POP
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
struct C {
|
struct C {
|
||||||
int m1(int x) noexcept { return x - 1; }
|
int m1(int x) noexcept { return x - 1; }
|
||||||
int m2(int x) const noexcept { return x - 2; }
|
int m2(int x) const noexcept { return x - 2; }
|
||||||
@ -68,17 +65,14 @@ struct C {
|
|||||||
int m4(int x) const noexcept(true) { return x - 4; }
|
int m4(int x) const noexcept(true) { return x - 4; }
|
||||||
int m5(int x) noexcept(false) { return x - 5; }
|
int m5(int x) noexcept(false) { return x - 5; }
|
||||||
int m6(int x) const noexcept(false) { return x - 6; }
|
int m6(int x) const noexcept(false) { return x - 6; }
|
||||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma GCC diagnostic push
|
PYBIND11_WARNING_DISABLE_GCC("-Wdeprecated")
|
||||||
# pragma GCC diagnostic ignored "-Wdeprecated"
|
PYBIND11_WARNING_DISABLE_CLANG("-Wdeprecated")
|
||||||
#endif
|
|
||||||
// NOLINTNEXTLINE(modernize-use-noexcept)
|
// NOLINTNEXTLINE(modernize-use-noexcept)
|
||||||
int m7(int x) throw() { return x - 7; }
|
int m7(int x) throw() { return x - 7; }
|
||||||
// NOLINTNEXTLINE(modernize-use-noexcept)
|
// NOLINTNEXTLINE(modernize-use-noexcept)
|
||||||
int m8(int x) const throw() { return x - 8; }
|
int m8(int x) const throw() { return x - 8; }
|
||||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_POP
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
} // namespace test_exc_sp
|
} // namespace test_exc_sp
|
||||||
|
|
||||||
@ -126,14 +120,12 @@ TEST_SUBMODULE(constants_and_functions, m) {
|
|||||||
.def("m8", &C::m8);
|
.def("m8", &C::m8);
|
||||||
m.def("f1", f1);
|
m.def("f1", f1);
|
||||||
m.def("f2", f2);
|
m.def("f2", f2);
|
||||||
#if defined(__INTEL_COMPILER)
|
|
||||||
# pragma warning push
|
PYBIND11_WARNING_PUSH
|
||||||
# pragma warning disable 878 // incompatible exception specifications
|
PYBIND11_WARNING_DISABLE_INTEL(878) // incompatible exception specifications
|
||||||
#endif
|
|
||||||
m.def("f3", f3);
|
m.def("f3", f3);
|
||||||
#if defined(__INTEL_COMPILER)
|
PYBIND11_WARNING_POP
|
||||||
# pragma warning pop
|
|
||||||
#endif
|
|
||||||
m.def("f4", f4);
|
m.def("f4", f4);
|
||||||
|
|
||||||
// test_function_record_leaks
|
// test_function_record_leaks
|
||||||
|
@ -13,9 +13,7 @@
|
|||||||
#include "constructor_stats.h"
|
#include "constructor_stats.h"
|
||||||
#include "pybind11_tests.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
PYBIND11_WARNING_DISABLE_MSVC(4996)
|
||||||
# pragma warning(disable : 4996) // C4996: std::unary_negation is deprecated
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <Eigen/Cholesky>
|
#include <Eigen/Cholesky>
|
||||||
|
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
#include "pybind11_tests.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
namespace PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE {
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE)
|
||||||
|
|
||||||
|
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||||
|
|
||||||
template <typename M>
|
template <typename M>
|
||||||
void reset_tensor(M &x) {
|
void reset_tensor(M &x) {
|
||||||
@ -90,7 +92,7 @@ struct CustomExample {
|
|||||||
template <int Options>
|
template <int Options>
|
||||||
void init_tensor_module(pybind11::module &m) {
|
void init_tensor_module(pybind11::module &m) {
|
||||||
const char *needed_options = "";
|
const char *needed_options = "";
|
||||||
if (PYBIND11_SILENCE_MSVC_C4127(Options == Eigen::ColMajor)) {
|
if (Options == Eigen::ColMajor) {
|
||||||
needed_options = "F";
|
needed_options = "F";
|
||||||
} else {
|
} else {
|
||||||
needed_options = "C";
|
needed_options = "C";
|
||||||
@ -330,4 +332,4 @@ void test_module(py::module_ &m) {
|
|||||||
init_tensor_module<Eigen::RowMajor>(c_style);
|
init_tensor_module<Eigen::RowMajor>(c_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE
|
PYBIND11_NAMESPACE_END(PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE)
|
||||||
|
@ -3,11 +3,9 @@
|
|||||||
|
|
||||||
#include <pybind11/embed.h>
|
#include <pybind11/embed.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
|
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
|
||||||
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).
|
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).
|
||||||
# pragma warning(disable : 4996)
|
PYBIND11_WARNING_DISABLE_MSVC(4996)
|
||||||
#endif
|
|
||||||
|
|
||||||
// Catch uses _ internally, which breaks gettext style defines
|
// Catch uses _ internally, which breaks gettext style defines
|
||||||
#ifdef _
|
#ifdef _
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
#include <pybind11/embed.h>
|
#include <pybind11/embed.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
|
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
|
||||||
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).
|
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).
|
||||||
# pragma warning(disable : 4996)
|
PYBIND11_WARNING_DISABLE_MSVC(4996)
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -16,6 +14,11 @@
|
|||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
using namespace py::literals;
|
using namespace py::literals;
|
||||||
|
|
||||||
|
size_t get_sys_path_size() {
|
||||||
|
auto sys_path = py::module::import("sys").attr("path");
|
||||||
|
return py::len(sys_path);
|
||||||
|
}
|
||||||
|
|
||||||
class Widget {
|
class Widget {
|
||||||
public:
|
public:
|
||||||
explicit Widget(std::string message) : message(std::move(message)) {}
|
explicit Widget(std::string message) : message(std::move(message)) {}
|
||||||
@ -168,6 +171,70 @@ TEST_CASE("There can be only one interpreter") {
|
|||||||
py::initialize_interpreter();
|
py::initialize_interpreter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||||
|
TEST_CASE("Custom PyConfig") {
|
||||||
|
py::finalize_interpreter();
|
||||||
|
PyConfig config;
|
||||||
|
PyConfig_InitPythonConfig(&config);
|
||||||
|
REQUIRE_NOTHROW(py::scoped_interpreter{&config});
|
||||||
|
{
|
||||||
|
py::scoped_interpreter p{&config};
|
||||||
|
REQUIRE(py::module_::import("widget_module").attr("add")(1, 41).cast<int>() == 42);
|
||||||
|
}
|
||||||
|
py::initialize_interpreter();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Custom PyConfig with argv") {
|
||||||
|
py::finalize_interpreter();
|
||||||
|
{
|
||||||
|
PyConfig config;
|
||||||
|
PyConfig_InitIsolatedConfig(&config);
|
||||||
|
char *argv[] = {strdup("a.out")};
|
||||||
|
py::scoped_interpreter argv_scope{&config, 1, argv};
|
||||||
|
std::free(argv[0]);
|
||||||
|
auto module = py::module::import("test_interpreter");
|
||||||
|
auto py_widget = module.attr("DerivedWidget")("The question");
|
||||||
|
const auto &cpp_widget = py_widget.cast<const Widget &>();
|
||||||
|
REQUIRE(cpp_widget.argv0() == "a.out");
|
||||||
|
}
|
||||||
|
py::initialize_interpreter();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("Add program dir to path pre-PyConfig") {
|
||||||
|
py::finalize_interpreter();
|
||||||
|
size_t path_size_add_program_dir_to_path_false = 0;
|
||||||
|
{
|
||||||
|
py::scoped_interpreter scoped_interp{true, 0, nullptr, false};
|
||||||
|
path_size_add_program_dir_to_path_false = get_sys_path_size();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
py::scoped_interpreter scoped_interp{};
|
||||||
|
REQUIRE(get_sys_path_size() == path_size_add_program_dir_to_path_false + 1);
|
||||||
|
}
|
||||||
|
py::initialize_interpreter();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
|
||||||
|
TEST_CASE("Add program dir to path using PyConfig") {
|
||||||
|
py::finalize_interpreter();
|
||||||
|
size_t path_size_add_program_dir_to_path_false = 0;
|
||||||
|
{
|
||||||
|
PyConfig config;
|
||||||
|
PyConfig_InitPythonConfig(&config);
|
||||||
|
py::scoped_interpreter scoped_interp{&config, 0, nullptr, false};
|
||||||
|
path_size_add_program_dir_to_path_false = get_sys_path_size();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
PyConfig config;
|
||||||
|
PyConfig_InitPythonConfig(&config);
|
||||||
|
py::scoped_interpreter scoped_interp{&config};
|
||||||
|
REQUIRE(get_sys_path_size() == path_size_add_program_dir_to_path_false + 1);
|
||||||
|
}
|
||||||
|
py::initialize_interpreter();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool has_pybind11_internals_builtin() {
|
bool has_pybind11_internals_builtin() {
|
||||||
auto builtins = py::handle(PyEval_GetBuiltins());
|
auto builtins = py::handle(PyEval_GetBuiltins());
|
||||||
return builtins.contains(PYBIND11_INTERNALS_ID);
|
return builtins.contains(PYBIND11_INTERNALS_ID);
|
||||||
|
@ -5,6 +5,7 @@ import time
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
import env
|
||||||
from pybind11_tests import gil_scoped as m
|
from pybind11_tests import gil_scoped as m
|
||||||
|
|
||||||
|
|
||||||
@ -144,7 +145,6 @@ def _intentional_deadlock():
|
|||||||
|
|
||||||
|
|
||||||
ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK = ALL_BASIC_TESTS + (_intentional_deadlock,)
|
ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK = ALL_BASIC_TESTS + (_intentional_deadlock,)
|
||||||
SKIP_IF_DEADLOCK = True # See PR #4216
|
|
||||||
|
|
||||||
|
|
||||||
def _run_in_process(target, *args, **kwargs):
|
def _run_in_process(target, *args, **kwargs):
|
||||||
@ -181,7 +181,7 @@ def _run_in_process(target, *args, **kwargs):
|
|||||||
elif process.exitcode is None:
|
elif process.exitcode is None:
|
||||||
assert t_delta > 0.9 * timeout
|
assert t_delta > 0.9 * timeout
|
||||||
msg = "DEADLOCK, most likely, exactly what this test is meant to detect."
|
msg = "DEADLOCK, most likely, exactly what this test is meant to detect."
|
||||||
if SKIP_IF_DEADLOCK:
|
if env.PYPY and env.WIN:
|
||||||
pytest.skip(msg)
|
pytest.skip(msg)
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
return process.exitcode
|
return process.exitcode
|
||||||
|
@ -44,14 +44,13 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
|
|||||||
|
|
||||||
// test_args_and_kwargs
|
// test_args_and_kwargs
|
||||||
m.def("args_function", [](py::args args) -> py::tuple {
|
m.def("args_function", [](py::args args) -> py::tuple {
|
||||||
|
PYBIND11_WARNING_PUSH
|
||||||
|
|
||||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
||||||
# pragma clang diagnostic push
|
PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
|
||||||
# pragma clang diagnostic ignored "-Wreturn-std-move"
|
|
||||||
#endif
|
#endif
|
||||||
return args;
|
return args;
|
||||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
PYBIND11_WARNING_POP
|
||||||
# pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
});
|
});
|
||||||
m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) {
|
m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) {
|
||||||
return py::make_tuple(args, kwargs);
|
return py::make_tuple(args, kwargs);
|
||||||
|
@ -132,22 +132,18 @@ struct hash<HashMe> {
|
|||||||
// Not a good abs function, but easy to test.
|
// Not a good abs function, but easy to test.
|
||||||
std::string abs(const Vector2 &) { return "abs(Vector2)"; }
|
std::string abs(const Vector2 &) { return "abs(Vector2)"; }
|
||||||
|
|
||||||
// MSVC & Intel warns about unknown pragmas, and warnings are errors.
|
|
||||||
#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
|
|
||||||
# pragma GCC diagnostic push
|
|
||||||
// clang 7.0.0 and Apple LLVM 10.0.1 introduce `-Wself-assign-overloaded` to
|
// clang 7.0.0 and Apple LLVM 10.0.1 introduce `-Wself-assign-overloaded` to
|
||||||
// `-Wall`, which is used here for overloading (e.g. `py::self += py::self `).
|
// `-Wall`, which is used here for overloading (e.g. `py::self += py::self `).
|
||||||
// Here, we suppress the warning using `#pragma diagnostic`.
|
// Here, we suppress the warning
|
||||||
// Taken from: https://github.com/RobotLocomotion/drake/commit/aaf84b46
|
// Taken from: https://github.com/RobotLocomotion/drake/commit/aaf84b46
|
||||||
// TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`).
|
// TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`).
|
||||||
# if defined(__APPLE__) && defined(__clang__)
|
#if defined(__APPLE__) && defined(__clang__)
|
||||||
# if (__clang_major__ >= 10)
|
# if (__clang_major__ >= 10)
|
||||||
# pragma GCC diagnostic ignored "-Wself-assign-overloaded"
|
PYBIND11_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
|
||||||
# endif
|
# endif
|
||||||
# elif defined(__clang__)
|
#elif defined(__clang__)
|
||||||
# if (__clang_major__ >= 7)
|
# if (__clang_major__ >= 7)
|
||||||
# pragma GCC diagnostic ignored "-Wself-assign-overloaded"
|
PYBIND11_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -283,6 +279,3 @@ TEST_SUBMODULE(operators, m) {
|
|||||||
|
|
||||||
m.def("get_unhashable_HashMe_set", []() { return std::unordered_set<HashMe>{{"one"}}; });
|
m.def("get_unhashable_HashMe_set", []() { return std::unordered_set<HashMe>{{"one"}}; });
|
||||||
}
|
}
|
||||||
#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
|
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user