Merge branch 'master' into sh_merge_master

This commit is contained in:
Ralf W. Grosse-Kunstleve
2021-07-30 11:37:51 -07:00
18 changed files with 198 additions and 101 deletions

View File

@@ -406,7 +406,11 @@ template <typename StringType, bool IsView = false> struct string_caster {
const auto *buffer = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32
// Skip BOM for UTF-16/32
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {
buffer++;
length--;
}
value = StringType(buffer, length);
// If we're loading a string_view we need to keep the encoded Python object alive:
@@ -521,7 +525,7 @@ public:
// 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 (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
if (PYBIND11_SILENCE_MSVC_C4127(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
@@ -546,7 +550,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 (StringCaster::UTF_N == 16 && str_len == 2) {
else if (PYBIND11_SILENCE_MSVC_C4127(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)");
@@ -804,7 +808,7 @@ struct pyobject_caster {
// For Python 2, without this implicit conversion, Python code would
// need to be cluttered with six.ensure_text() or similar, only to be
// un-cluttered later after Python 2 support is dropped.
if (std::is_same<T, str>::value && isinstance<bytes>(src)) {
if (PYBIND11_SILENCE_MSVC_C4127(std::is_same<T, str>::value) && isinstance<bytes>(src)) {
PyObject *str_from_bytes = PyUnicode_FromEncodedObject(src.ptr(), "utf-8", nullptr);
if (!str_from_bytes) throw error_already_set();
value = reinterpret_steal<type>(str_from_bytes);

View File

@@ -89,13 +89,27 @@
# endif
#endif
#if !defined(PYBIND11_EXPORT_EXCEPTION)
# ifdef __MINGW32__
// workaround for:
// error: 'dllexport' implies default visibility, but xxx has already been declared with a different visibility
# define PYBIND11_EXPORT_EXCEPTION
# else
# define PYBIND11_EXPORT_EXCEPTION PYBIND11_EXPORT
# endif
#endif
#if defined(_MSC_VER)
# define PYBIND11_NOINLINE __declspec(noinline)
#else
# define PYBIND11_NOINLINE __attribute__ ((noinline))
#endif
#if defined(PYBIND11_CPP14)
#if defined(__MINGW32__)
// For unknown reasons all PYBIND11_DEPRECATED member trigger a warning when declared
// whether it is used or not
# define PYBIND11_DEPRECATED(reason)
#elif defined(PYBIND11_CPP14)
# define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]]
#else
# define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason)))
@@ -121,7 +135,8 @@
# define HAVE_ROUND 1
# endif
# pragma warning(push)
# pragma warning(disable: 4510 4610 4512 4005)
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
# pragma warning(disable: 4505)
# if defined(_DEBUG) && !defined(Py_DEBUG)
# define PYBIND11_DEBUG_MARKER
# undef _DEBUG
@@ -740,7 +755,7 @@ PYBIND11_NAMESPACE_END(detail)
# pragma warning(disable: 4275) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class.
#endif
/// C++ bindings of builtin Python exceptions
class PYBIND11_EXPORT builtin_exception : public std::runtime_error {
class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
/// Set the error using the Python C API
@@ -751,7 +766,7 @@ public:
#endif
#define PYBIND11_RUNTIME_EXCEPTION(name, type) \
class PYBIND11_EXPORT name : public builtin_exception { public: \
class PYBIND11_EXPORT_EXCEPTION name : public builtin_exception { public: \
using builtin_exception::builtin_exception; \
name() : name("") { } \
void set_error() const override { PyErr_SetString(type, what()); } \
@@ -926,5 +941,16 @@ inline constexpr void workaround_incorrect_msvc_c4100(Args &&...) {}
# define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)
#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(...) detail::silence_msvc_c4127(__VA_ARGS__)
#else
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
#endif
PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

View File

@@ -98,7 +98,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 (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
if (PYBIND11_SILENCE_MSVC_C4127(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
@@ -141,7 +141,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 (Class::has_alias && need_alias && !is_alias<Class>(ptr))
if (PYBIND11_SILENCE_MSVC_C4127(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");
@@ -158,7 +158,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 (Class::has_alias && need_alias)
if (PYBIND11_SILENCE_MSVC_C4127(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));
@@ -183,7 +183,7 @@ void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr,
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
auto *ptr = unq_ptr.get();
no_nullptr(ptr);
if (Class::has_alias && need_alias && !is_alias<Class>(ptr))
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr))
throw type_error("pybind11::init(): construction failed: returned std::unique_ptr pointee "
"is not an alias instance");
// Here and below: if the new object is a trampoline, the shared_from_this mechanism needs
@@ -219,7 +219,7 @@ void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, boo
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
auto *ptr = shd_ptr.get();
no_nullptr(ptr);
if (Class::has_alias && need_alias && !is_alias<Class>(ptr))
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr))
throw type_error("pybind11::init(): construction failed: returned std::shared_ptr pointee "
"is not an alias instance");
auto smhldr = type_caster<Cpp<Class>>::template smart_holder_from_shared_ptr(shd_ptr);

View File

@@ -1,14 +1,7 @@
#pragma once
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
# pragma warning(push)
# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
# pragma warning(disable: 4505) // warning C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
#elif defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#if defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
# pragma GCC diagnostic ignored "-Wattributes"
# if __GNUC__ >= 7
# pragma GCC diagnostic ignored "-Wnoexcept-type"
# endif
#endif

View File

@@ -41,6 +41,18 @@
# include <cxxabi.h>
#endif
/* 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
and only if the first template instantiation ... involves noexcept" [stackoverflow], therefore
it could get triggered from seemingly random places, depending on user code.
No other GCC version generates this warning.
*/
#if defined(__GNUC__) && __GNUC__ == 7
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnoexcept-type"
#endif
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)
@@ -151,7 +163,7 @@ protected:
auto rec = unique_rec.get();
/* Store the capture object directly in the function record if there is enough space */
if (sizeof(capture) <= sizeof(rec->data)) {
if (PYBIND11_SILENCE_MSVC_C4127(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. */
@@ -2481,8 +2493,10 @@ inline function get_overload(const T *this_ptr, const char *name) {
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
# pragma warning(pop)
#elif defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#if defined(__GNUC__) && __GNUC__ == 7
# pragma GCC diagnostic pop // -Wnoexcept-type
#endif
#if defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic pop
#endif

View File

@@ -327,7 +327,7 @@ PYBIND11_NAMESPACE_END(detail)
/// thrown to propagate python-side errors back through C++ which can either be caught manually or
/// else falls back to the function dispatcher (which then raises the captured error back to
/// python).
class PYBIND11_EXPORT error_already_set : public std::runtime_error {
class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
public:
/// Constructs a new exception from the current Python error indicator, if any. The current
/// Python error indicator will be cleared.
@@ -1191,9 +1191,9 @@ 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 (sizeof(Unsigned) <= sizeof(unsigned long)
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))
#if PY_VERSION_HEX < 0x03000000
|| PyInt_Check(o)
|| PyInt_Check(o)
#endif
) {
unsigned long v = PyLong_AsUnsignedLong(o);
@@ -1212,7 +1212,7 @@ public:
template <typename T,
detail::enable_if_t<std::is_integral<T>::value, int> = 0>
int_(T value) {
if (sizeof(T) <= sizeof(long)) {
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {
if (std::is_signed<T>::value)
m_ptr = PyLong_FromLong((long) value);
else