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).
|
||||
required: false
|
||||
|
||||
- type: Input
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: What version (or hash if on master) of pybind11 are you using?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
@ -52,7 +53,7 @@ body:
|
||||
starting point for working out fixes.
|
||||
render: text
|
||||
|
||||
- type: Input
|
||||
- type: input
|
||||
id: regression
|
||||
attributes:
|
||||
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
|
||||
|
||||
- name: Publish standard package
|
||||
uses: pypa/gh-action-pypi-publish@v1.5.1
|
||||
uses: pypa/gh-action-pypi-publish@v1.5.2
|
||||
with:
|
||||
password: ${{ secrets.pypi_password }}
|
||||
packages_dir: standard/
|
||||
|
||||
- name: Publish global package
|
||||
uses: pypa/gh-action-pypi-publish@v1.5.1
|
||||
uses: pypa/gh-action-pypi-publish@v1.5.2
|
||||
with:
|
||||
password: ${{ secrets.pypi_password_global }}
|
||||
packages_dir: global/
|
||||
|
@ -35,6 +35,9 @@
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#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
|
||||
// `PyUnicode_AsUTF8AndSize`.
|
||||
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {
|
||||
if (UTF_N == 8) {
|
||||
Py_ssize_t size = -1;
|
||||
const auto *buffer
|
||||
= 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()));
|
||||
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
|
||||
// Skip BOM for UTF-16/32
|
||||
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {
|
||||
if (UTF_N > 8) {
|
||||
buffer++;
|
||||
length--;
|
||||
}
|
||||
@ -606,7 +609,7 @@ public:
|
||||
// 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
|
||||
// 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]);
|
||||
// low bits only: 0-127
|
||||
// 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
|
||||
// surrogate pair with total length 2 instantly indicates a range error (but not a "your
|
||||
// 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]);
|
||||
if (one_char >= 0xD800 && one_char < 0xE000) {
|
||||
throw value_error("Character code point not in range(0x10000)");
|
||||
|
@ -17,8 +17,69 @@
|
||||
// Additional convention: 0xD = dev
|
||||
#define PYBIND11_VERSION_HEX 0x020B00D1
|
||||
|
||||
#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
|
||||
#define PYBIND11_NAMESPACE_END(name) }
|
||||
// Define some generic pybind11 helper macros for warning management.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
#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)
|
||||
# pragma warning(disable : 4505)
|
||||
# if defined(_DEBUG) && !defined(Py_DEBUG)
|
||||
// Workaround for a VS 2022 issue.
|
||||
// NOTE: This workaround knowingly violates the Python.h include order requirement:
|
||||
@ -236,7 +297,7 @@
|
||||
# define _DEBUG
|
||||
# undef PYBIND11_DEBUG_MARKER
|
||||
# endif
|
||||
# pragma warning(pop)
|
||||
PYBIND11_WARNING_POP
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
@ -1160,17 +1221,6 @@ constexpr
|
||||
# define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
|
||||
#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__) \
|
||||
&& (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \
|
||||
available. */ \
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "smart_holder_sfinae_hooks_only.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <>
|
||||
@ -116,7 +119,7 @@ template <typename Class>
|
||||
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
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
|
||||
// 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
|
||||
@ -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);
|
||||
no_nullptr(ptr);
|
||||
// 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 "
|
||||
"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);
|
||||
static_assert(std::is_move_constructible<Cpp<Class>>::value,
|
||||
"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));
|
||||
} else {
|
||||
v_h.value_ptr() = new Cpp<Class>(std::move(result));
|
||||
|
@ -479,9 +479,6 @@ PYBIND11_NOINLINE internals &get_internals() {
|
||||
internals_ptr = new internals();
|
||||
#if defined(WITH_THREAD)
|
||||
|
||||
# if PY_VERSION_HEX < 0x03090000
|
||||
PyEval_InitThreads();
|
||||
# endif
|
||||
PyThreadState *tstate = PyThreadState_Get();
|
||||
if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
|
||||
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/1741816/isystem-for-ms-visual-studio-c-compiler
|
||||
*/
|
||||
// The C4127 suppression was introduced for Eigen 3.4.0. In theory we could
|
||||
// make it version specific, or even remove it later, but considering that
|
||||
// 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
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
|
||||
// C5054: operator '&': deprecated between enumerations of different types
|
||||
#elif defined(__MINGW32__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/SparseCore>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#elif defined(__MINGW32__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
// 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
|
||||
@ -48,6 +34,8 @@ static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
|
||||
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
template <typename MatrixType>
|
||||
@ -189,8 +177,7 @@ struct EigenProps {
|
||||
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
|
||||
np_rstride = a.strides(0) / 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)
|
||||
|| (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {
|
||||
if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,7 +190,7 @@ struct EigenProps {
|
||||
stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
|
||||
|
||||
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 {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
|
||||
@ -220,7 +207,7 @@ struct EigenProps {
|
||||
}
|
||||
return {1, n, stride};
|
||||
} // 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 {n, 1, stride};
|
||||
|
@ -13,28 +13,23 @@
|
||||
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4554) // Tensor.h warning
|
||||
# pragma warning(disable : 4127) // Tensor.h warning
|
||||
#elif defined(__MINGW32__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
// Disable warnings for Eigen
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4554)
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
|
||||
|
||||
#include <unsupported/Eigen/CXX11/Tensor>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#elif defined(__MINGW32__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
|
||||
"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
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.
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wtype-limits")
|
||||
|
||||
template <typename T, int size>
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
template <typename Type>
|
||||
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;
|
||||
|
||||
if (PYBIND11_SILENCE_MSVC_C4127(is_aligned) && !is_tensor_aligned(arr.data())) {
|
||||
if (is_aligned && !is_tensor_aligned(arr.data())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -403,7 +394,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PYBIND11_SILENCE_MSVC_C4127(needs_writeable) && !arr.writeable()) {
|
||||
if (needs_writeable && !arr.writeable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -86,38 +86,26 @@ inline wchar_t *widen_chars(const char *safe_arg) {
|
||||
return widened_arg;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/** \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) {
|
||||
inline void precheck_interpreter() {
|
||||
if (Py_IsInitialized() != 0) {
|
||||
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);
|
||||
# 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
|
||||
// caused a segfault, so we have to reimplement the special case ourselves.
|
||||
@ -147,26 +135,30 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
|
||||
auto *pysys_argv = widened_argv.get();
|
||||
|
||||
PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(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;
|
||||
}
|
||||
#endif
|
||||
|
||||
PyStatus status = PyConfig_SetBytesArgv(&config, argc, const_cast<char *const *>(argv));
|
||||
if (PyStatus_Exception(status)) {
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
#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
|
||||
// interpreter out of memory. Give up.
|
||||
PyConfig_Clear(&config);
|
||||
throw std::runtime_error(PyStatus_IsError(status) ? status.err_msg
|
||||
: "Failed to prepare CPython");
|
||||
PyConfig_Clear(config);
|
||||
throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
|
||||
: "Failed to prepare CPython");
|
||||
}
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
PyConfig_Clear(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
throw std::runtime_error(PyStatus_IsError(status) ? status.err_msg
|
||||
: "Failed to init CPython");
|
||||
status = Py_InitializeFromConfig(config);
|
||||
if (PyStatus_Exception(status) != 0) {
|
||||
PyConfig_Clear(config);
|
||||
throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
|
||||
: "Failed to init CPython");
|
||||
}
|
||||
if (add_program_dir_to_path) {
|
||||
PyRun_SimpleString("import sys, os.path; "
|
||||
@ -174,6 +166,43 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
|
||||
"os.path.abspath(os.path.dirname(sys.argv[0])) "
|
||||
"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
|
||||
}
|
||||
|
||||
@ -261,6 +290,15 @@ public:
|
||||
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(scoped_interpreter &&other) noexcept { other.is_valid = false; }
|
||||
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_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
class array; // Forward declaration
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
@ -875,7 +877,7 @@ public:
|
||||
*/
|
||||
template <typename T, ssize_t Dims = -1>
|
||||
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: "
|
||||
+ std::to_string(ndim()) + "; expected "
|
||||
+ std::to_string(Dims));
|
||||
@ -893,7 +895,7 @@ public:
|
||||
*/
|
||||
template <typename T, ssize_t Dims = -1>
|
||||
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: "
|
||||
+ std::to_string(ndim()) + "; expected "
|
||||
+ std::to_string(Dims));
|
||||
@ -1865,9 +1867,10 @@ private:
|
||||
}
|
||||
|
||||
auto result = returned_array::create(trivial, shape);
|
||||
|
||||
PYBIND11_WARNING_PUSH
|
||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wreturn-std-move"
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
|
||||
#endif
|
||||
|
||||
if (size == 0) {
|
||||
@ -1883,9 +1886,7 @@ private:
|
||||
}
|
||||
|
||||
return result;
|
||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
}
|
||||
|
||||
template <size_t... Index, size_t... VIndex, size_t... BIndex>
|
||||
|
@ -36,6 +36,8 @@
|
||||
# include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning
|
||||
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
|
||||
@ -44,11 +46,10 @@
|
||||
No other GCC version generates this warning.
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wnoexcept-type")
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
@ -178,22 +179,22 @@ protected:
|
||||
auto *rec = unique_rec.get();
|
||||
|
||||
/* 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
|
||||
enough space to use the placement new operator. However, the
|
||||
'if' statement above ensures that this is the case. */
|
||||
#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wplacement-new"
|
||||
PYBIND11_WARNING_PUSH
|
||||
|
||||
#if defined(__GNUG__) && __GNUC__ >= 6
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
|
||||
#endif
|
||||
|
||||
new ((capture *) &rec->data) capture{std::forward<Func>(f)};
|
||||
#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
|
||||
#if !PYBIND11_HAS_STD_LAUNDER
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
||||
#endif
|
||||
|
||||
// UB without std::launder, but without breaking ABI and/or
|
||||
// a significant refactoring it's "impossible" to solve.
|
||||
if (!std::is_trivially_destructible<capture>::value) {
|
||||
@ -203,9 +204,7 @@ protected:
|
||||
data->~capture();
|
||||
};
|
||||
}
|
||||
#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
} else {
|
||||
rec->data[0] = new capture{std::forward<Func>(f)};
|
||||
rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
|
||||
@ -2087,8 +2086,7 @@ private:
|
||||
if (holder_ptr) {
|
||||
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
||||
v_h.set_holder_constructed();
|
||||
} else if (PYBIND11_SILENCE_MSVC_C4127(detail::always_construct_holder<holder_type>::value)
|
||||
|| inst->owned) {
|
||||
} else if (detail::always_construct_holder<holder_type>::value || inst->owned) {
|
||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
||||
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_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_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
/* A few forward declarations */
|
||||
class handle;
|
||||
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
|
||||
inline handle object_or_cast(PyObject *ptr) { return ptr; }
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1920
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4522) // warning C4522: multiple assignment operators specified
|
||||
#endif
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4522) // warning C4522: multiple assignment operators specified
|
||||
template <typename Policy>
|
||||
class accessor : public object_api<accessor<Policy>> {
|
||||
using key_type = typename Policy::key_type;
|
||||
@ -951,9 +951,7 @@ private:
|
||||
key_type key;
|
||||
mutable object cache;
|
||||
};
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1920
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(accessor_policies)
|
||||
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).
|
||||
template <typename Unsigned>
|
||||
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);
|
||||
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>
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
int_(T value) {
|
||||
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {
|
||||
if (sizeof(T) <= sizeof(long)) {
|
||||
if (std::is_signed<T>::value) {
|
||||
m_ptr = PyLong_FromLong((long) value);
|
||||
} else {
|
||||
|
@ -7,6 +7,8 @@ Adds docstring and exceptions message sanitizers.
|
||||
import contextlib
|
||||
import difflib
|
||||
import gc
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
@ -15,6 +17,22 @@ import pytest
|
||||
# Early diagnostic for failed imports
|
||||
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")
|
||||
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")
|
||||
|
||||
|
@ -80,6 +80,9 @@ PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(pybind11)
|
||||
|
||||
TEST_SUBMODULE(builtin_casters, m) {
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
// test_simple_string
|
||||
m.def("string_roundtrip", [](const char *s) { return s; });
|
||||
|
||||
@ -93,7 +96,7 @@ TEST_SUBMODULE(builtin_casters, m) {
|
||||
std::wstring wstr;
|
||||
wstr.push_back(0x61); // a
|
||||
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_2);
|
||||
} // 𝐀, utf16
|
||||
@ -120,7 +123,7 @@ TEST_SUBMODULE(builtin_casters, m) {
|
||||
// Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger
|
||||
// UnicodeDecodeError
|
||||
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", [=]() {
|
||||
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"); },
|
||||
py::return_value_policy::_return_as_bytes);
|
||||
#endif
|
||||
|
||||
PYBIND11_WARNING_POP
|
||||
}
|
||||
|
@ -22,10 +22,8 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable : 4324)
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4324)
|
||||
// warning C4324: structure was padded due to alignment specifier
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -52,15 +52,12 @@ int f1(int x) noexcept { return x + 1; }
|
||||
#endif
|
||||
int f2(int x) noexcept(true) { return x + 2; }
|
||||
int f3(int x) noexcept(false) { return x + 3; }
|
||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wdeprecated")
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wdeprecated")
|
||||
// NOLINTNEXTLINE(modernize-use-noexcept)
|
||||
int f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true)
|
||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
struct C {
|
||||
int m1(int x) noexcept { return x - 1; }
|
||||
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 m5(int x) noexcept(false) { return x - 5; }
|
||||
int m6(int x) const noexcept(false) { return x - 6; }
|
||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wdeprecated")
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wdeprecated")
|
||||
// NOLINTNEXTLINE(modernize-use-noexcept)
|
||||
int m7(int x) throw() { return x - 7; }
|
||||
// NOLINTNEXTLINE(modernize-use-noexcept)
|
||||
int m8(int x) const throw() { return x - 8; }
|
||||
#if defined(__GNUG__) && !defined(__INTEL_COMPILER)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
};
|
||||
} // namespace test_exc_sp
|
||||
|
||||
@ -126,14 +120,12 @@ TEST_SUBMODULE(constants_and_functions, m) {
|
||||
.def("m8", &C::m8);
|
||||
m.def("f1", f1);
|
||||
m.def("f2", f2);
|
||||
#if defined(__INTEL_COMPILER)
|
||||
# pragma warning push
|
||||
# pragma warning disable 878 // incompatible exception specifications
|
||||
#endif
|
||||
|
||||
PYBIND11_WARNING_PUSH
|
||||
PYBIND11_WARNING_DISABLE_INTEL(878) // incompatible exception specifications
|
||||
m.def("f3", f3);
|
||||
#if defined(__INTEL_COMPILER)
|
||||
# pragma warning pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
|
||||
m.def("f4", f4);
|
||||
|
||||
// test_function_record_leaks
|
||||
|
@ -13,9 +13,7 @@
|
||||
#include "constructor_stats.h"
|
||||
#include "pybind11_tests.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable : 4996) // C4996: std::unary_negation is deprecated
|
||||
#endif
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4996)
|
||||
|
||||
#include <Eigen/Cholesky>
|
||||
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#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>
|
||||
void reset_tensor(M &x) {
|
||||
@ -90,7 +92,7 @@ struct CustomExample {
|
||||
template <int Options>
|
||||
void init_tensor_module(pybind11::module &m) {
|
||||
const char *needed_options = "";
|
||||
if (PYBIND11_SILENCE_MSVC_C4127(Options == Eigen::ColMajor)) {
|
||||
if (Options == Eigen::ColMajor) {
|
||||
needed_options = "F";
|
||||
} else {
|
||||
needed_options = "C";
|
||||
@ -330,4 +332,4 @@ void test_module(py::module_ &m) {
|
||||
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>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// 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).
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4996)
|
||||
|
||||
// Catch uses _ internally, which breaks gettext style defines
|
||||
#ifdef _
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include <pybind11/embed.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// 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).
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4996)
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <cstdlib>
|
||||
@ -16,6 +14,11 @@
|
||||
namespace py = pybind11;
|
||||
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 {
|
||||
public:
|
||||
explicit Widget(std::string message) : message(std::move(message)) {}
|
||||
@ -168,6 +171,70 @@ TEST_CASE("There can be only one 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() {
|
||||
auto builtins = py::handle(PyEval_GetBuiltins());
|
||||
return builtins.contains(PYBIND11_INTERNALS_ID);
|
||||
|
@ -5,6 +5,7 @@ import time
|
||||
|
||||
import pytest
|
||||
|
||||
import env
|
||||
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,)
|
||||
SKIP_IF_DEADLOCK = True # See PR #4216
|
||||
|
||||
|
||||
def _run_in_process(target, *args, **kwargs):
|
||||
@ -181,7 +181,7 @@ def _run_in_process(target, *args, **kwargs):
|
||||
elif process.exitcode is None:
|
||||
assert t_delta > 0.9 * timeout
|
||||
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)
|
||||
raise RuntimeError(msg)
|
||||
return process.exitcode
|
||||
|
@ -44,14 +44,13 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
|
||||
|
||||
// test_args_and_kwargs
|
||||
m.def("args_function", [](py::args args) -> py::tuple {
|
||||
PYBIND11_WARNING_PUSH
|
||||
|
||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wreturn-std-move"
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
|
||||
#endif
|
||||
return args;
|
||||
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
PYBIND11_WARNING_POP
|
||||
});
|
||||
m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) {
|
||||
return py::make_tuple(args, kwargs);
|
||||
|
@ -132,22 +132,18 @@ struct hash<HashMe> {
|
||||
// Not a good abs function, but easy to test.
|
||||
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
|
||||
// `-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
|
||||
// TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`).
|
||||
# if defined(__APPLE__) && defined(__clang__)
|
||||
# if (__clang_major__ >= 10)
|
||||
# pragma GCC diagnostic ignored "-Wself-assign-overloaded"
|
||||
# endif
|
||||
# elif defined(__clang__)
|
||||
# if (__clang_major__ >= 7)
|
||||
# pragma GCC diagnostic ignored "-Wself-assign-overloaded"
|
||||
# endif
|
||||
#if defined(__APPLE__) && defined(__clang__)
|
||||
# if (__clang_major__ >= 10)
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
|
||||
# endif
|
||||
#elif defined(__clang__)
|
||||
# if (__clang_major__ >= 7)
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -283,6 +279,3 @@ TEST_SUBMODULE(operators, m) {
|
||||
|
||||
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