From ee3ecb8ae2f0d74fe50912364ec65bce1330af51 Mon Sep 17 00:00:00 2001 From: ka-bo <55587089+ka-bo@users.noreply.github.com> Date: Wed, 21 Jul 2021 18:00:57 +0200 Subject: [PATCH 01/22] Specified encoding in setup.py calls of open() (#3137) * Specified encoding in setup.py calls of open() * Fix for Python2 Co-authored-by: Karsten Bock --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ced3d6958..7aa151c01 100644 --- a/setup.py +++ b/setup.py @@ -11,6 +11,7 @@ import string import subprocess import sys import tempfile +import io import setuptools.command.sdist @@ -70,7 +71,7 @@ exec(code, loc) version = loc["__version__"] # Verify that the version matches the one in C++ -with open("include/pybind11/detail/common.h") as f: +with io.open("include/pybind11/detail/common.h", encoding="utf8") as f: matches = dict(VERSION_REGEX.findall(f.read())) cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches) if version != cpp_version: From b193d42c32763af3c7e3763657b7cba114010121 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 26 Jul 2021 11:28:36 -0700 Subject: [PATCH 02/22] Removing MSVC C4996 from pragma block at the top of pybind11.h (#3129) * Removing MSVC C4996 from pragma block at the top of pybind11.h * localtime_thread_safe, PYBIND11_COMPAT_STRDUP * Adding #include (attempt to fix MSVC 2015, 2017 errors). --- include/pybind11/chrono.h | 33 +++++++++++++++++++++++--------- include/pybind11/detail/common.h | 5 +++++ include/pybind11/pybind11.h | 18 ++++++++++++----- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/include/pybind11/chrono.h b/include/pybind11/chrono.h index d32b5b056..c4e81f572 100644 --- a/include/pybind11/chrono.h +++ b/include/pybind11/chrono.h @@ -11,9 +11,14 @@ #pragma once #include "pybind11.h" + +#include #include #include -#include +#include + +#include + #include // Backport the PyDateTime_DELTA functions from Python3.3 if required @@ -95,6 +100,22 @@ public: PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); }; +inline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) { +#if defined(__STDC_WANT_LIB_EXT1__) || defined(_MSC_VER) + if (localtime_s(buf, time)) + return nullptr; + return buf; +#else + static std::mutex mtx; + std::lock_guard lock(mtx); + std::tm *tm_ptr = localtime(time); + if (tm_ptr != nullptr) { + *buf = *tm_ptr; + } + return tm_ptr; +#endif +} + // This is for casting times on the system clock into datetime.datetime instances template class type_caster> { public: @@ -162,16 +183,10 @@ public: // (https://en.cppreference.com/w/cpp/chrono/system_clock/to_time_t) std::time_t tt = system_clock::to_time_t(time_point_cast(src - us)); - // std::localtime returns a pointer to a static internal std::tm object on success, - // or null pointer otherwise - std::tm *localtime_ptr = std::localtime(&tt); + std::tm localtime; + std::tm *localtime_ptr = localtime_thread_safe(&tt, &localtime); if (!localtime_ptr) throw cast_error("Unable to represent system_clock in local time"); - - // this function uses static memory so it's best to copy it out asap just in case - // otherwise other code that is using localtime may break this (not just python code) - std::tm localtime = *localtime_ptr; - return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday, diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 52b019335..3faf3ea32 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -125,6 +125,11 @@ # endif #endif +// https://en.cppreference.com/w/c/chrono/localtime +#if defined(__STDC_LIB_EXT1__) && !defined(__STDC_WANT_LIB_EXT1__) +# define __STDC_WANT_LIB_EXT1__ +#endif + #include #include #include diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index af8e730d3..cd6e41196 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -19,7 +19,6 @@ # pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant # pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) -# pragma warning(disable: 4996) // warning C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name # pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified # pragma warning(disable: 4505) // warning C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only) #elif defined(__GNUG__) && !defined(__clang__) @@ -43,6 +42,8 @@ #include #include +#include + #if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914)) # define PYBIND11_STD_LAUNDER std::launder # define PYBIND11_HAS_STD_LAUNDER 1 @@ -56,6 +57,12 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +#if defined(_MSC_VER) +# define PYBIND11_COMPAT_STRDUP _strdup +#else +# define PYBIND11_COMPAT_STRDUP strdup +#endif + /// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object class cpp_function : public function { public: @@ -253,7 +260,7 @@ protected: std::free(s); } char *operator()(const char *s) { - auto t = strdup(s); + auto t = PYBIND11_COMPAT_STRDUP(s); strings.push_back(t); return t; } @@ -497,7 +504,8 @@ protected: auto *func = (PyCFunctionObject *) m_ptr; std::free(const_cast(func->m_ml->ml_doc)); // Install docstring if it's non-empty (when at least one option is enabled) - func->m_ml->ml_doc = signatures.empty() ? nullptr : strdup(signatures.c_str()); + func->m_ml->ml_doc + = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str()); if (rec->is_method) { m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr()); @@ -1498,7 +1506,7 @@ public: detail::process_attributes::init(extra..., rec_fget); if (rec_fget->doc && rec_fget->doc != doc_prev) { free(doc_prev); - rec_fget->doc = strdup(rec_fget->doc); + rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc); } } if (rec_fset) { @@ -1506,7 +1514,7 @@ public: detail::process_attributes::init(extra..., rec_fset); if (rec_fset->doc && rec_fset->doc != doc_prev) { free(doc_prev); - rec_fset->doc = strdup(rec_fset->doc); + rec_fset->doc = PYBIND11_COMPAT_STRDUP(rec_fset->doc); } if (! rec_active) rec_active = rec_fset; } From 85b38c69dee5ae57fe23754becd437ebd4e30961 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 26 Jul 2021 12:02:50 -0700 Subject: [PATCH 03/22] Adding pragma warning(disable: 4522) for MSVC <= 2017. (#3142) --- include/pybind11/pybind11.h | 1 - include/pybind11/pytypes.h | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index cd6e41196..b5091ff25 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -19,7 +19,6 @@ # pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant # pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) -# pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified # pragma warning(disable: 4505) // warning C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only) #elif defined(__GNUG__) && !defined(__clang__) # pragma GCC diagnostic push diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index b483fb323..332998277 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -532,6 +532,10 @@ 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 template class accessor : public object_api> { using key_type = typename Policy::key_type; @@ -580,6 +584,9 @@ private: key_type key; mutable object cache; }; +#if defined(_MSC_VER) && _MSC_VER < 1920 +# pragma warning(pop) +#endif PYBIND11_NAMESPACE_BEGIN(accessor_policies) struct obj_attr { From c973660d6c5daa2a24bf5629306d640b6447e9ac Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Jul 2021 15:05:58 -0400 Subject: [PATCH 04/22] [pre-commit.ci] pre-commit autoupdate (#3143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.21.2 → v2.23.0](https://github.com/asottile/pyupgrade/compare/v2.21.2...v2.23.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa7b4774e..510b84126 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: exclude: ^noxfile.py$ - repo: https://github.com/asottile/pyupgrade - rev: v2.21.2 + rev: v2.23.0 hooks: - id: pyupgrade From e93d94594b063682a70ead0b7feb8c1329ae0717 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 26 Jul 2021 13:26:36 -0700 Subject: [PATCH 05/22] Removing MSVC C4800 from pragma block at the top of pybind11.h (#3141) * Adding PYBIND11_COMPAT_BOOL_CAST to appease MSVC 2015 warning C4800. * Replacing PYBIND11_COMPAT_BOOL_CAST with simpler != 0 * Extra parentheses (almost all compilers failed without these). --- include/pybind11/buffer_info.h | 2 +- include/pybind11/cast.h | 2 +- include/pybind11/detail/type_caster_base.h | 4 ++-- include/pybind11/pybind11.h | 1 - include/pybind11/pytypes.h | 6 ++++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/pybind11/buffer_info.h b/include/pybind11/buffer_info.h index 47dc39d4e..eba68d1aa 100644 --- a/include/pybind11/buffer_info.h +++ b/include/pybind11/buffer_info.h @@ -83,7 +83,7 @@ struct buffer_info { view->strides ? std::vector(view->strides, view->strides + view->ndim) : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), - view->readonly) { + (view->readonly != 0)) { this->m_view = view; this->ownview = ownview; } diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index a748c77c0..1da432358 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -322,7 +322,7 @@ public: } #endif if (res == 0 || res == 1) { - value = (bool) res; + value = (res != 0); return true; } PyErr_Clear(); diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 451690dc7..39d0740ff 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -231,7 +231,7 @@ struct value_and_holder { return reinterpret_cast(vh[0]); } // True if this `value_and_holder` has a non-null value pointer - explicit operator bool() const { return value_ptr(); } + explicit operator bool() const { return value_ptr() != nullptr; } template H &holder() const { return reinterpret_cast(vh[1]); @@ -252,7 +252,7 @@ struct value_and_holder { bool instance_registered() const { return inst->simple_layout ? inst->simple_instance_registered - : inst->nonsimple.status[index] & instance::status_instance_registered; + : ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0); } void set_instance_registered(bool v = true) const { if (inst->simple_layout) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index b5091ff25..6a2bd0f24 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -18,7 +18,6 @@ # pragma warning(push) # pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -# pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) # pragma warning(disable: 4505) // warning C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only) #elif defined(__GNUG__) && !defined(__clang__) # pragma GCC diagnostic push diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 332998277..cea4e7eb0 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -367,7 +367,9 @@ public: /// Check if the currently trapped error type matches the given Python exception class (or a /// subclass thereof). May also be passed a tuple to search for any exception class matches in /// the given tuple. - bool matches(handle exc) const { return PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()); } + bool matches(handle exc) const { + return (PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()) != 0); + } const object& type() const { return m_type; } const object& value() const { return m_value; } @@ -853,7 +855,7 @@ PYBIND11_NAMESPACE_END(detail) Name(handle h, borrowed_t) : Parent(h, borrowed_t{}) { } \ Name(handle h, stolen_t) : Parent(h, stolen_t{}) { } \ PYBIND11_DEPRECATED("Use py::isinstance(obj) instead") \ - bool check() const { return m_ptr != nullptr && (bool) CheckFun(m_ptr); } \ + bool check() const { return m_ptr != nullptr && (CheckFun(m_ptr) != 0); } \ static bool check_(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); } \ template \ Name(const ::pybind11::detail::accessor &a) : Name(object(a)) { } From fd71bd486d35f8e8a0d37e65e4654c9700990488 Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Tue, 27 Jul 2021 19:16:28 +0100 Subject: [PATCH 06/22] Allow python builtins to be used as callbacks (#1413) * Allow python builtins to be used as callbacks * Try to fix pypy segfault * Add expected fail for PyPy * Fix typo * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add more info to xfail * Add env * Try returning false * Try removing the move for pypy * Fix bugs * Try removing move * Just keep ignoring for PyPy * Add back xfail * Fix ctors * Revert change of std::move * Change to skip * Fix bug and edit comments * Remove clang-tidy bugprone fix skip bug Co-authored-by: Aaron Gokaslan Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- include/pybind11/functional.h | 34 ++++++++++++++++++++-------------- tests/test_callbacks.cpp | 6 ++++++ tests/test_callbacks.py | 11 +++++++++++ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index cc7099c6a..b9bf38919 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -43,27 +43,33 @@ public: captured variables), in which case the roundtrip can be avoided. */ if (auto cfunc = func.cpp_function()) { - auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); - auto rec = (function_record *) c; + auto cfunc_self = PyCFunction_GET_SELF(cfunc.ptr()); + if (isinstance(cfunc_self)) { + auto c = reinterpret_borrow(cfunc_self); + auto rec = (function_record *) c; - while (rec != nullptr) { - if (rec->is_stateless - && same_type(typeid(function_type), - *reinterpret_cast(rec->data[1]))) { - struct capture { - function_type f; - }; - value = ((capture *) &rec->data)->f; - return true; + while (rec != nullptr) { + if (rec->is_stateless + && same_type(typeid(function_type), + *reinterpret_cast(rec->data[1]))) { + struct capture { + function_type f; + }; + value = ((capture *) &rec->data)->f; + return true; + } + rec = rec->next; } - rec = rec->next; } + // PYPY segfaults here when passing builtin function like sum. + // Raising an fail exception here works to prevent the segfault, but only on gcc. + // See PR #1413 for full details } // ensure GIL is held during functor destruction struct func_handle { function f; - func_handle(function&& f_) : f(std::move(f_)) {} + func_handle(function &&f_) noexcept : f(std::move(f_)) {} func_handle(const func_handle& f_) { gil_scoped_acquire acq; f = f_.f; @@ -77,7 +83,7 @@ public: // to emulate 'move initialization capture' in C++11 struct func_wrapper { func_handle hfunc; - func_wrapper(func_handle&& hf): hfunc(std::move(hf)) {} + func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {} Return operator()(Args... args) const { gil_scoped_acquire acq; object retval(hfunc.f(std::forward(args)...)); diff --git a/tests/test_callbacks.cpp b/tests/test_callbacks.cpp index a208b44d0..a50771038 100644 --- a/tests/test_callbacks.cpp +++ b/tests/test_callbacks.cpp @@ -156,6 +156,12 @@ TEST_SUBMODULE(callbacks, m) { .def(py::init<>()) .def("triple", [](CppBoundMethodTest &, int val) { return 3 * val; }); + // This checks that builtin functions can be passed as callbacks + // rather than throwing RuntimeError due to trying to extract as capsule + m.def("test_sum_builtin", [](const std::function &sum_builtin, const py::iterable &i) { + return sum_builtin(i); + }); + // test async Python callbacks using callback_f = std::function; m.def("test_async_callback", [](const callback_f &f, const py::list &work) { diff --git a/tests/test_callbacks.py b/tests/test_callbacks.py index 397bf63d2..5bc4d1773 100644 --- a/tests/test_callbacks.py +++ b/tests/test_callbacks.py @@ -3,6 +3,7 @@ import pytest from pybind11_tests import callbacks as m from threading import Thread import time +import env # NOQA: F401 def test_callbacks(): @@ -124,6 +125,16 @@ def test_movable_object(): assert m.callback_with_movable(lambda _: None) is True +@pytest.mark.skipif( + "env.PYPY", + reason="PyPy segfaults on here. See discussion on #1413.", +) +def test_python_builtins(): + """Test if python builtins like sum() can be used as callbacks""" + assert m.test_sum_builtin(sum, [1, 2, 3]) == 6 + assert m.test_sum_builtin(sum, []) == 0 + + def test_async_callbacks(): # serves as state for async callback class Item: From 5c6bdb72156f5b290611b33bb2db258a1caa3488 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 27 Jul 2021 14:23:52 -0700 Subject: [PATCH 07/22] fix: the CMake config in Python package had a hard coded path (#3144) --- CMakeLists.txt | 6 ++++++ tests/extra_python_package/test_files.py | 14 ++++++++++++-- tools/pybind11Config.cmake.in | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c988ea0b5..b04311fd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,12 @@ if(PYBIND11_INSTALL) "${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for pybind11Config.cmake") + if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") + set(pybind11_INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}") + else() + set(pybind11_INCLUDEDIR "\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR}") + endif() + configure_package_config_file( tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) diff --git a/tests/extra_python_package/test_files.py b/tests/extra_python_package/test_files.py index 43e93c263..337a72dfe 100644 --- a/tests/extra_python_package/test_files.py +++ b/tests/extra_python_package/test_files.py @@ -138,6 +138,16 @@ def test_build_sdist(monkeypatch, tmpdir): ) as f: pyproject_toml = f.read() + with contextlib.closing( + tar.extractfile( + tar.getmember( + start + "pybind11/share/cmake/pybind11/pybind11Config.cmake" + ) + ) + ) as f: + contents = f.read().decode("utf8") + assert 'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")' in contents + files = {"pybind11/{}".format(n) for n in all_files} files |= sdist_files files |= {"pybind11{}".format(n) for n in local_sdist_files} @@ -151,11 +161,11 @@ def test_build_sdist(monkeypatch, tmpdir): .substitute(version=version, extra_cmd="") .encode() ) - assert setup_py == contents + assert setup_py == contents with open(os.path.join(MAIN_DIR, "tools", "pyproject.toml"), "rb") as f: contents = f.read() - assert pyproject_toml == contents + assert pyproject_toml == contents def test_build_global_dist(monkeypatch, tmpdir): diff --git a/tools/pybind11Config.cmake.in b/tools/pybind11Config.cmake.in index 6fa03a0f2..73ec104a0 100644 --- a/tools/pybind11Config.cmake.in +++ b/tools/pybind11Config.cmake.in @@ -201,7 +201,8 @@ Using ``find_package`` with version info is not recommended except for release v @PACKAGE_INIT@ # Location of pybind11/pybind11.h -set(pybind11_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@") +# This will be relative unless explicitly set as absolute +set(pybind11_INCLUDE_DIR "@pybind11_INCLUDEDIR@") set(pybind11_LIBRARY "") set(pybind11_DEFINITIONS USING_pybind11) From 0ac4c8afd6484bc95b84061fb7651ca59e4701e6 Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Tue, 27 Jul 2021 18:32:26 -0400 Subject: [PATCH 08/22] maint(clang-tidy): Improve code readability with explicit boolean casts (#3148) * maint(clang-tidy) Improve code readability * Fix minor typos * Revert optimization that removed test case * Fix comment formatting * Revert another optimization to repro an issue * Remove make_unique since it C++14 and newer only * eformat comments * Fix unsignedness of comparison * Update comment --- .clang-tidy | 13 +++++++++++++ include/pybind11/cast.h | 16 ++++++++++------ include/pybind11/detail/class.h | 7 ++++--- include/pybind11/detail/internals.h | 2 +- include/pybind11/detail/type_caster_base.h | 4 ++-- include/pybind11/embed.h | 4 ++-- include/pybind11/numpy.h | 19 +++++++++++-------- include/pybind11/pybind11.h | 15 +++++++++------ include/pybind11/pytypes.h | 12 ++++++++---- include/pybind11/stl/filesystem.h | 4 ++-- tests/test_embed/test_interpreter.cpp | 2 +- tests/test_methods_and_attributes.cpp | 1 + tests/test_numpy_dtypes.cpp | 6 ++++-- tests/test_numpy_vectorize.cpp | 2 +- tests/test_smart_ptr.cpp | 4 ++-- tests/test_stl.cpp | 6 ++---- 16 files changed, 73 insertions(+), 44 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 72304528a..db5077c22 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -5,13 +5,17 @@ cppcoreguidelines-init-variables, clang-analyzer-optin.cplusplus.VirtualCall, llvm-namespace-comment, misc-misplaced-const, +misc-non-copyable-objects, misc-static-assert, misc-throw-by-value-catch-by-reference, misc-uniqueptr-reset-release, +misc-unused-parameters, modernize-avoid-bind, +modernize-make-shared, modernize-redundant-void-arg, modernize-replace-auto-ptr, modernize-replace-disallow-copy-and-assign-macro, +modernize-replace-random-shuffle, modernize-shrink-to-fit, modernize-use-auto, modernize-use-bool-literals, @@ -23,13 +27,20 @@ modernize-use-emplace, modernize-use-override, modernize-use-using, *performance*, +readability-avoid-const-params-in-decls, readability-container-size-empty, readability-else-after-return, +readability-delete-null-pointer, +readability-implicit-bool-conversion, readability-make-member-function-const, +readability-misplaced-array-index, +readability-non-const-parameter, readability-redundant-function-ptr-dereference, readability-redundant-smartptr-get, readability-redundant-string-cstr, readability-simplify-subscript-expr, +readability-static-accessed-through-instance, +readability-static-definition-in-anonymous-namespace, readability-string-compare, readability-uniqueptr-delete-release, ' @@ -39,6 +50,8 @@ CheckOptions: value: true - key: performance-unnecessary-value-param.AllowedTypes value: 'exception_ptr$;' +- key: readability-implicit-bool-conversion.AllowPointerConditions + value: true HeaderFilterRegex: 'pybind11/.*h' diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 1da432358..898047b30 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -181,7 +181,7 @@ public: // Signed/unsigned checks happen elsewhere if (py_err || (std::is_integral::value && sizeof(py_type) != sizeof(T) && py_value != (py_type) (T) py_value)) { PyErr_Clear(); - if (py_err && convert && PyNumber_Check(src.ptr())) { + if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) { auto tmp = reinterpret_steal(std::is_floating_point::value ? PyNumber_Float(src.ptr()) : PyNumber_Long(src.ptr())); @@ -300,7 +300,7 @@ public: value = false; return true; } - if (convert || !std::strcmp("numpy.bool_", Py_TYPE(src.ptr())->tp_name)) { + if (convert || (std::strcmp("numpy.bool_", Py_TYPE(src.ptr())->tp_name) == 0)) { // (allow non-implicit conversion for numpy booleans) Py_ssize_t res = -1; @@ -501,10 +501,14 @@ public: // can fit into a single char value. if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) { auto v0 = static_cast(value[0]); - size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 - (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence - (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence - 4; // 0b11110xxx - start of 4-byte sequence + // low bits only: 0-127 + // 0b110xxxxx - start of 2-byte sequence + // 0b1110xxxx - start of 3-byte sequence + // 0b11110xxx - start of 4-byte sequence + size_t char0_bytes = (v0 & 0x80) == 0 ? 1 + : (v0 & 0xE0) == 0xC0 ? 2 + : (v0 & 0xF0) == 0xE0 ? 3 + : 4; if (char0_bytes == str_len) { // If we have a 128-255 value, we can decode it into a single char: diff --git a/include/pybind11/detail/class.h b/include/pybind11/detail/class.h index 5fee3318b..495183068 100644 --- a/include/pybind11/detail/class.h +++ b/include/pybind11/detail/class.h @@ -129,8 +129,9 @@ extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject* name, PyOb // 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop` // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment const auto static_prop = (PyObject *) get_internals().static_property_type; - const auto call_descr_set = descr && value && PyObject_IsInstance(descr, static_prop) - && !PyObject_IsInstance(value, static_prop); + const auto call_descr_set = (descr != nullptr) && (value != nullptr) + && (PyObject_IsInstance(descr, static_prop) != 0) + && (PyObject_IsInstance(value, static_prop) == 0); if (call_descr_set) { // Call `static_property.__set__()` instead of replacing the `static_property`. #if !defined(PYPY_VERSION) @@ -562,7 +563,7 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla view->len = view->itemsize; for (auto s : info->shape) view->len *= s; - view->readonly = info->readonly; + view->readonly = static_cast(info->readonly); if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) view->format = const_cast(info->format.c_str()); if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 5578c6516..273a0dbaf 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -293,7 +293,7 @@ PYBIND11_NOINLINE inline internals &get_internals() { PyThreadState *tstate = PyThreadState_Get(); #if PY_VERSION_HEX >= 0x03070000 internals_ptr->tstate = PyThread_tss_alloc(); - if (!internals_ptr->tstate || PyThread_tss_create(internals_ptr->tstate)) + if (!internals_ptr->tstate || (PyThread_tss_create(internals_ptr->tstate) != 0)) pybind11_fail("get_internals: could not successfully initialize the TSS key!"); PyThread_tss_set(internals_ptr->tstate, tstate); #else diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 39d0740ff..7a74133f6 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -238,8 +238,8 @@ struct value_and_holder { } bool holder_constructed() const { return inst->simple_layout - ? inst->simple_holder_constructed - : inst->nonsimple.status[index] & instance::status_holder_constructed; + ? inst->simple_holder_constructed + : (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u; } void set_holder_constructed(bool v = true) const { if (inst->simple_layout) diff --git a/include/pybind11/embed.h b/include/pybind11/embed.h index 204aaf989..abb1cd3cc 100644 --- a/include/pybind11/embed.h +++ b/include/pybind11/embed.h @@ -76,7 +76,7 @@ struct embedded_module { using init_t = void (*)(); #endif embedded_module(const char *name, init_t init) { - if (Py_IsInitialized()) + if (Py_IsInitialized() != 0) pybind11_fail("Can't add new modules after the interpreter has been initialized"); auto result = PyImport_AppendInittab(name, init); @@ -101,7 +101,7 @@ PYBIND11_NAMESPACE_END(detail) .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx \endrst */ inline void initialize_interpreter(bool init_signal_handlers = true) { - if (Py_IsInitialized()) + if (Py_IsInitialized() != 0) pybind11_fail("The interpreter is already running"); Py_InitializeEx(init_signal_handlers ? 1 : 0); diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index edba8bac9..7313897fe 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -465,7 +465,9 @@ public: explicit dtype(const buffer_info &info) { dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format))); // If info.itemsize == 0, use the value calculated from the format string - m_ptr = descr.strip_padding(info.itemsize ? info.itemsize : descr.itemsize()).release().ptr(); + m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize()) + .release() + .ptr(); } explicit dtype(const std::string &format) { @@ -486,7 +488,7 @@ public: /// This is essentially the same as calling numpy.dtype(args) in Python. static dtype from_args(object args) { PyObject *ptr = nullptr; - if (!detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) || !ptr) + if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) throw error_already_set(); return reinterpret_steal(ptr); } @@ -542,7 +544,7 @@ private: auto name = spec[0].cast(); auto format = spec[1].cast()[0].cast(); auto offset = spec[1].cast()[1].cast(); - if (!len(name) && format.kind() == 'V') + if ((len(name) == 0u) && format.kind() == 'V') continue; field_descriptors.push_back({(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset}); } @@ -872,11 +874,12 @@ public: : array(std::move(shape), std::move(strides), ptr, base) { } explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle()) - : array_t(private_ctor{}, std::move(shape), - ExtraFlags & f_style - ? detail::f_strides(*shape, itemsize()) - : detail::c_strides(*shape, itemsize()), - ptr, base) { } + : array_t(private_ctor{}, + std::move(shape), + (ExtraFlags & f_style) != 0 ? detail::f_strides(*shape, itemsize()) + : detail::c_strides(*shape, itemsize()), + ptr, + base) {} explicit array_t(ssize_t count, const T *ptr = nullptr, handle base = handle()) : array({count}, {}, ptr, base) { } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 6a2bd0f24..679c4beb5 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -296,7 +296,8 @@ protected: a.descr = guarded_strdup(repr(a.value).cast().c_str()); } - rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__"); + rec->is_constructor + = (strcmp(rec->name, "__init__") == 0) || (strcmp(rec->name, "__setstate__") == 0); #if !defined(NDEBUG) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING) if (rec->is_constructor && !rec->is_new_style_constructor) { @@ -1105,7 +1106,8 @@ protected: pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec.name) + "\": an object with that name is already defined"); - if (rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type)) + if ((rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type)) + != nullptr) pybind11_fail("generic_type: type \"" + std::string(rec.name) + "\" is already registered!"); @@ -1183,8 +1185,9 @@ protected: void def_property_static_impl(const char *name, handle fget, handle fset, detail::function_record *rec_func) { - const auto is_static = rec_func && !(rec_func->is_method && rec_func->scope); - const auto has_doc = rec_func && rec_func->doc && pybind11::options::show_user_defined_docstrings(); + const auto is_static = (rec_func != nullptr) && !(rec_func->is_method && rec_func->scope); + const auto has_doc = (rec_func != nullptr) && (rec_func->doc != nullptr) + && pybind11::options::show_user_defined_docstrings(); auto property = handle((PyObject *) (is_static ? get_internals().static_property_type : &PyProperty_Type)); attr(name) = property(fget.ptr() ? fget : none(), @@ -2154,8 +2157,8 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty Unfortunately this doesn't work on PyPy. */ #if !defined(PYPY_VERSION) PyFrameObject *frame = PyThreadState_Get()->frame; - if (frame && (std::string) str(frame->f_code->co_name) == name && - frame->f_code->co_argcount > 0) { + if (frame != nullptr && (std::string) str(frame->f_code->co_name) == name + && frame->f_code->co_argcount > 0) { PyFrame_FastToLocals(frame); PyObject *self_caller = dict_getitem( frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0)); diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index cea4e7eb0..161aed06f 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -773,7 +773,11 @@ protected: dict_readonly(handle obj, ssize_t pos) : obj(obj), pos(pos) { increment(); } reference dereference() const { return {key, value}; } - void increment() { if (!PyDict_Next(obj.ptr(), &pos, &key, &value)) { pos = -1; } } + void increment() { + if (PyDict_Next(obj.ptr(), &pos, &key, &value) == 0) { + pos = -1; + } + } bool equal(const dict_readonly &b) const { return pos == b.pos; } private: @@ -1169,14 +1173,14 @@ public: bool_() : object(Py_False, borrowed_t{}) { } // Allow implicit conversion from and to `bool`: bool_(bool value) : object(value ? Py_True : Py_False, borrowed_t{}) { } - operator bool() const { return m_ptr && PyLong_AsLong(m_ptr) != 0; } + operator bool() const { return (m_ptr != nullptr) && PyLong_AsLong(m_ptr) != 0; } private: /// Return the truth value of an object -- always returns a new reference static PyObject *raw_bool(PyObject *op) { const auto value = PyObject_IsTrue(op); if (value == -1) return nullptr; - return handle(value ? Py_True : Py_False).inc_ref().ptr(); + return handle(value != 0 ? Py_True : Py_False).inc_ref().ptr(); } }; @@ -1607,7 +1611,7 @@ inline memoryview memoryview::from_buffer( size_t ndim = shape->size(); if (ndim != strides->size()) pybind11_fail("memoryview: shape length doesn't match strides length"); - ssize_t size = ndim ? 1 : 0; + ssize_t size = ndim != 0u ? 1 : 0; for (size_t i = 0; i < ndim; ++i) size *= (*shape)[i]; Py_buffer view; diff --git a/include/pybind11/stl/filesystem.h b/include/pybind11/stl/filesystem.h index 7a8acdb60..431b94b4f 100644 --- a/include/pybind11/stl/filesystem.h +++ b/include/pybind11/stl/filesystem.h @@ -67,7 +67,7 @@ public: } PyObject* native = nullptr; if constexpr (std::is_same_v) { - if (PyUnicode_FSConverter(buf, &native)) { + if (PyUnicode_FSConverter(buf, &native) != 0) { if (auto c_str = PyBytes_AsString(native)) { // AsString returns a pointer to the internal buffer, which // must not be free'd. @@ -75,7 +75,7 @@ public: } } } else if constexpr (std::is_same_v) { - if (PyUnicode_FSDecoder(buf, &native)) { + if (PyUnicode_FSDecoder(buf, &native) != 0) { if (auto c_str = PyUnicode_AsWideCharString(native, nullptr)) { // AsWideCharString returns a new string that must be free'd. value = c_str; // Copies the string. diff --git a/tests/test_embed/test_interpreter.cpp b/tests/test_embed/test_interpreter.cpp index 6925ee978..cd50e952f 100644 --- a/tests/test_embed/test_interpreter.cpp +++ b/tests/test_embed/test_interpreter.cpp @@ -103,7 +103,7 @@ bool has_pybind11_internals_builtin() { bool has_pybind11_internals_static() { auto **&ipp = py::detail::get_internals_pp(); - return ipp && *ipp; + return (ipp != nullptr) && (*ipp != nullptr); } TEST_CASE("Restart the interpreter") { diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp index 9db31a0b8..4cf6f08b8 100644 --- a/tests/test_methods_and_attributes.cpp +++ b/tests/test_methods_and_attributes.cpp @@ -43,6 +43,7 @@ public: void add6(int other) { value += other; } // passing by value void add7(int &other) { value += other; } // passing by reference void add8(const int &other) { value += other; } // passing by const reference + // NOLINTNEXTLINE(readability-non-const-parameter) Deliberately non-const for testing void add9(int *other) { value += *other; } // passing by pointer void add10(const int *other) { value += *other; } // passing by const pointer diff --git a/tests/test_numpy_dtypes.cpp b/tests/test_numpy_dtypes.cpp index edf9cf200..340c972db 100644 --- a/tests/test_numpy_dtypes.cpp +++ b/tests/test_numpy_dtypes.cpp @@ -108,9 +108,11 @@ PYBIND11_PACKED(struct EnumStruct { std::ostream& operator<<(std::ostream& os, const StringStruct& v) { os << "a='"; - for (size_t i = 0; i < 3 && v.a[i]; i++) os << v.a[i]; + for (size_t i = 0; i < 3 && (v.a[i] != 0); i++) + os << v.a[i]; os << "',b='"; - for (size_t i = 0; i < 3 && v.b[i]; i++) os << v.b[i]; + for (size_t i = 0; i < 3 && (v.b[i] != 0); i++) + os << v.b[i]; return os << "'"; } diff --git a/tests/test_numpy_vectorize.cpp b/tests/test_numpy_vectorize.cpp index ed08a42be..b08a9f7ed 100644 --- a/tests/test_numpy_vectorize.cpp +++ b/tests/test_numpy_vectorize.cpp @@ -59,7 +59,7 @@ TEST_SUBMODULE(numpy_vectorize, m) { .def(py::init()) .def_readwrite("value", &NonPODClass::value); m.def("vec_passthrough", - py::vectorize([](double *a, + py::vectorize([](const double *a, double b, // Changing this broke things // NOLINTNEXTLINE(performance-unnecessary-value-param) diff --git a/tests/test_smart_ptr.cpp b/tests/test_smart_ptr.cpp index 7fd5a9b36..57b2d894e 100644 --- a/tests/test_smart_ptr.cpp +++ b/tests/test_smart_ptr.cpp @@ -101,7 +101,7 @@ private: // test_unique_nodelete // Object with a private destructor class MyObject4; -static std::unordered_set myobject4_instances; +std::unordered_set myobject4_instances; class MyObject4 { public: MyObject4(int value) : value{value} { @@ -127,7 +127,7 @@ private: // Object with std::unique_ptr where D is not matching the base class // Object with a protected destructor class MyObject4a; -static std::unordered_set myobject4a_instances; +std::unordered_set myobject4a_instances; class MyObject4a { public: MyObject4a(int i) { diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp index eb8cdab7b..23e2c07b3 100644 --- a/tests/test_stl.cpp +++ b/tests/test_stl.cpp @@ -102,7 +102,7 @@ TEST_SUBMODULE(stl, m) { // test_set m.def("cast_set", []() { return std::set{"key1", "key2"}; }); m.def("load_set", [](const std::set &set) { - return set.count("key1") && set.count("key2") && set.count("key3"); + return (set.count("key1") != 0u) && (set.count("key2") != 0u) && (set.count("key3") != 0u); }); // test_recursive_casting @@ -196,9 +196,7 @@ TEST_SUBMODULE(stl, m) { m.def("double_or_zero", [](const opt_int& x) -> int { return x.value_or(0) * 2; }); - m.def("half_or_none", [](int x) -> opt_int { - return x ? opt_int(x / 2) : opt_int(); - }); + m.def("half_or_none", [](int x) -> opt_int { return x != 0 ? opt_int(x / 2) : opt_int(); }); m.def("test_nullopt", [](opt_int x) { return x.value_or(42); }, py::arg_v("x", std::nullopt, "None")); From ed5fb66bd792fb709c0f4259b60b42b7d7101559 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 27 Jul 2021 15:33:31 -0700 Subject: [PATCH 09/22] Removing __INTEL_COMPILER section from pragma block at the top of pybind11.h (#3135) * Fixing `pragma warning pop` for `__INTEL_COMPILER`. * Adding push/pop to 3 tests. Removing #878 from top of pybind11.h (it was/is only needed for 1 test). * Trying again after CI failure, moving the push to the top of 2 tests. * Trying more after CI failure, adding push/pop to pybind11_tests.h, constructor_stats.h. * Moving ICC #2196 suppression to CMakeLists.txt * Fixing condition for `pragma GCC diagnostic push` in pybind11.h * Moving `pragma warning disable 2196` to common.h * Revising #ifdef to be more conservative. * Undoing insertion of notes that will hopefully soon be completely obsolete anyway. --- include/pybind11/detail/common.h | 3 +++ include/pybind11/pybind11.h | 8 ++------ tests/test_constants_and_functions.cpp | 7 +++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 3faf3ea32..0b4e30c18 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -56,6 +56,9 @@ # elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14) # error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14. # endif +/* The following pragma cannot be pop'ed: + https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */ +# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" #elif defined(__clang__) && !defined(__apple_build_version__) # if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) # error pybind11 requires clang 3.3 or newer diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 679c4beb5..f4aa9b881 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -10,16 +10,12 @@ #pragma once -#if defined(__INTEL_COMPILER) -# pragma warning push -# pragma warning disable 878 // incompatible exception specifications -# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" -#elif defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) # pragma warning(push) # pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter # 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__) +#elif defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-but-set-parameter" # pragma GCC diagnostic ignored "-Wattributes" diff --git a/tests/test_constants_and_functions.cpp b/tests/test_constants_and_functions.cpp index e7f018540..c0554503f 100644 --- a/tests/test_constants_and_functions.cpp +++ b/tests/test_constants_and_functions.cpp @@ -133,7 +133,14 @@ TEST_SUBMODULE(constants_and_functions, m) { ; m.def("f1", f1); m.def("f2", f2); +#if defined(__INTEL_COMPILER) +# pragma warning push +# pragma warning disable 878 // incompatible exception specifications +#endif m.def("f3", f3); +#if defined(__INTEL_COMPILER) +# pragma warning pop +#endif m.def("f4", f4); // test_function_record_leaks From 05852fb6bc2ba9bd89de671faf3cee072e1f7dbd Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 28 Jul 2021 08:58:36 -0700 Subject: [PATCH 10/22] Accommodating environments that define __STDC_WANT_LIB_EXT1__ even if __STDC_LIB_EXT1__ is not defined by the implementation. (#3151) Follow-on to PR #3129. --- include/pybind11/chrono.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/chrono.h b/include/pybind11/chrono.h index c4e81f572..61bbcbc54 100644 --- a/include/pybind11/chrono.h +++ b/include/pybind11/chrono.h @@ -101,7 +101,7 @@ public: }; inline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) { -#if defined(__STDC_WANT_LIB_EXT1__) || defined(_MSC_VER) +#if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || defined(_MSC_VER) if (localtime_s(buf, time)) return nullptr; return buf; From 46c51fc03bfc76bfd71e9ab5036bec7efefb4b5d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 30 Jul 2021 07:09:55 -0700 Subject: [PATCH 11/22] Limiting pragma for ignoring GCC 7 -Wnoexcept-type to the scope of pybind11.h. (#3161) * Moving pragma for ignoring -Wnoexcept-type to the one location where it is needed. * Trying a second location. * The previous commit worked (GitHub Actions green), but see the added comment about the dicy nature of -Wnoexcept-type ("if and only if"). * Applying reviewer suggestion. --- include/pybind11/pybind11.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index f4aa9b881..3eb71f386 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -19,9 +19,6 @@ # 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 #include "attr.h" @@ -49,6 +46,18 @@ # include #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) #if defined(_MSC_VER) @@ -2309,6 +2318,10 @@ inline function get_overload(const T *this_ptr, const char *name) { PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) +#if defined(__GNUC__) && __GNUC__ == 7 +# pragma GCC diagnostic pop // -Wnoexcept-type +#endif + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) # pragma warning(pop) #elif defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER) From c80e0593454411ad38205cc76134d6a0dd70032e Mon Sep 17 00:00:00 2001 From: Jerome Robert Date: Fri, 30 Jul 2021 19:48:41 +0200 Subject: [PATCH 12/22] fix: Mingw64 corrected and add a CI job to test it (#3132) * mingw64 platform string is like mingw_xxx not "mingw" See https://github.com/msys2/MINGW-packages/blob/master/mingw-w64-python/0099-Change-the-get_platform-method-in-sysconfig-and-dist.patch * Mingw: Do not dllexport exceptions This is a fix for errors like: D:/a/pybind11/pybind11/include/pybind11/detail/common.h:735:23: error: 'dllexport' implies default visibility, but 'class pybind11::builtin_exception' has already been declared with a different visibility 735 | class PYBIND11_EXPORT builtin_exception : public std::runtime_error { | ^~~~~~~~~~~~~~~~~ * GHA: Test Mingw64 build * fix: avoid thin binaries on mingw * fix: drop lto on MinGW * Mingw64: disable PYBIND11_DEPRECATED It trigger many warnings for unknown reasons Co-authored-by: Henry Schreiner --- .github/workflows/ci.yml | 31 +++++++++++++++++++++++++++++++ include/pybind11/detail/common.h | 20 +++++++++++++++++--- include/pybind11/pytypes.h | 2 +- pybind11/setup_helpers.py | 3 +-- tests/test_exceptions.h | 2 +- tools/pybind11Common.cmake | 7 ++++++- 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03c9225c1..73a6fd519 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -859,3 +859,34 @@ jobs: - name: Run all checks run: cmake --build build -t check + + mingw: + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + steps: + - uses: msys2/setup-msys2@v2 + with: + install: >- + mingw-w64-x86_64-gcc + mingw-w64-x86_64-python-pip + mingw-w64-x86_64-cmake + mingw-w64-x86_64-make + mingw-w64-x86_64-python-pytest + mingw-w64-x86_64-eigen3 + mingw-w64-x86_64-boost + mingw-w64-x86_64-catch + + - uses: actions/checkout@v1 + + - name: Configure + # LTO leads to many undefined reference like + # `pybind11::detail::function_call::function_call(pybind11::detail::function_call&&) + run: cmake -G "MinGW Makefiles" -S . -B build + + - name: Build + run: cmake --build build -j 2 + + - name: Python tests + run: cmake --build build --target pytest diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 0b4e30c18..09e8717ce 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -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))) @@ -740,7 +754,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 +765,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()); } \ diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 161aed06f..4cf606e8d 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -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. diff --git a/pybind11/setup_helpers.py b/pybind11/setup_helpers.py index 2b27f1f5a..0888ab487 100644 --- a/pybind11/setup_helpers.py +++ b/pybind11/setup_helpers.py @@ -59,8 +59,7 @@ except ImportError: import distutils.errors import distutils.ccompiler - -WIN = sys.platform.startswith("win32") and sysconfig.get_platform() != "mingw" +WIN = sys.platform.startswith("win32") and "mingw" not in sysconfig.get_platform() PY2 = sys.version_info[0] < 3 MACOS = sys.platform.startswith("darwin") STD_TMPL = "/std:c++{}" if WIN else "-std=c++{}" diff --git a/tests/test_exceptions.h b/tests/test_exceptions.h index 5d02d1b35..9d428312e 100644 --- a/tests/test_exceptions.h +++ b/tests/test_exceptions.h @@ -4,7 +4,7 @@ // shared exceptions for cross_module_tests -class PYBIND11_EXPORT shared_exception : public pybind11::builtin_exception { +class PYBIND11_EXPORT_EXCEPTION shared_exception : public pybind11::builtin_exception { public: using builtin_exception::builtin_exception; explicit shared_exception() : shared_exception("") {} diff --git a/tools/pybind11Common.cmake b/tools/pybind11Common.cmake index 57e42536e..7afb0d0b1 100644 --- a/tools/pybind11Common.cmake +++ b/tools/pybind11Common.cmake @@ -302,13 +302,18 @@ function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerfla endfunction() function(_pybind11_generate_lto target prefer_thin_lto) + if(MINGW) + message(STATUS "${target} disabled (problems with undefined symbols for MinGW for now)") + return() + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(cxx_append "") set(linker_append "") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE) # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it set(linker_append ";$<$:-O3>") - elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT MINGW) set(cxx_append ";-fno-fat-lto-objects") endif() From b961ac644ff0ec22e3a6edc5925bd9b0f2eff0df Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 30 Jul 2021 10:51:50 -0700 Subject: [PATCH 13/22] Moving pragma for MSVC warning C4505 from pybind11.h to existing list in detail/common.h (#3160) * Moving pragma for C4505 from pybind11.h to existing list in detail/common.h. * Removing 4 existing suppressions to 1. see what is still needed and 2. capture the MSVC messages. * It turns out none of the 4 pragmas are needed anymore. --- include/pybind11/detail/common.h | 3 ++- include/pybind11/pybind11.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 09e8717ce..9df670fa9 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -135,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 diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 3eb71f386..1cb232d3a 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -14,7 +14,6 @@ # pragma warning(push) # pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter # 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) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-but-set-parameter" From ada6b7910491f5b7fd910d8bf23c474b526f6591 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Aug 2021 10:56:57 -0400 Subject: [PATCH 14/22] [pre-commit.ci] pre-commit autoupdate (#3167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.23.0 → v2.23.1](https://github.com/asottile/pyupgrade/compare/v2.23.0...v2.23.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 510b84126..57beb7779 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: exclude: ^noxfile.py$ - repo: https://github.com/asottile/pyupgrade - rev: v2.23.0 + rev: v2.23.1 hooks: - id: pyupgrade From 9f204a18573d8a194549ad0fd51afdd3db5596e5 Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Tue, 3 Aug 2021 13:15:48 -0400 Subject: [PATCH 15/22] fix: func_handle for rule of two (#3169) * Fix func_handle for rule of two * Apply reviewer suggestion --- include/pybind11/functional.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index b9bf38919..bc8a8af82 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -70,9 +70,11 @@ public: struct func_handle { function f; func_handle(function &&f_) noexcept : f(std::move(f_)) {} - func_handle(const func_handle& f_) { + func_handle(const func_handle &f_) { operator=(f_); } + func_handle &operator=(const func_handle &f_) { gil_scoped_acquire acq; f = f_.f; + return *this; } ~func_handle() { gil_scoped_acquire acq; From 9095984850eb1d0240575a31281d8651ff5e7a2e Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 3 Aug 2021 10:16:14 -0700 Subject: [PATCH 16/22] chore: changelog update (#3163) * chore: changelog update * Update docs/changelog.rst --- docs/changelog.rst | 49 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 5e8a63258..2f76abe05 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,9 +6,54 @@ Changelog Starting with version 1.8.0, pybind11 releases use a `semantic versioning `_ policy. -Next version (WIP) ------------------- +v2.8.0 (WIP) +------------ +* Allow exception translators to be optionally registered local to a module + instead of applying globally across all pybind11 modules. Use + ``register_local_exception_translator(ExceptionTranslator&& translator)`` + instead of ``register_exception_translator(ExceptionTranslator&& + translator)`` to keep your exception remapping code local to the module. + `#2650 `_ + +v2.7.1 (Aug 3, 2021) +--------------------- + +Minor missing functionality added: + +* Allow Python builtins to be used as callbacks in CPython. + `#1413 `_ + +Bug fixes: + +* Fix regression in CMake Python package config: improper use of absolute path. + `#3144 `_ + +* Fix Mingw64 and add to the CI testing matrix. + `#3132 `_ + +* Specified UTF8-encoding in setup.py calls of open(). + `#3137 `_ + +* Add clang-tidy-readability rules to make boolean casts explicit improving + code readability. Also enabled other misc and readability clang-tidy checks. + `#3148 `_ + +* Move object in ``.pop()`` for list. + `#3116 `_ + +Backend and tidying up: + +* Removed and fixed warning suppressions. + `#3127 `_ + `#3129 `_ + `#3135 `_ + `#3141 `_ + `#3142 `_ + `#3150 `_ + `#3152 `_ + `#3160 `_ + `#3161 `_ v2.7.0 (Jul 16, 2021) From 078c1167497c81f866b94df5451939077aba0b6f Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 3 Aug 2021 15:05:54 -0400 Subject: [PATCH 17/22] chore: bump to version 2.7.1 --- include/pybind11/detail/common.h | 2 +- pybind11/_version.py | 2 +- setup.cfg | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 9df670fa9..8006a8df1 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -11,7 +11,7 @@ #define PYBIND11_VERSION_MAJOR 2 #define PYBIND11_VERSION_MINOR 7 -#define PYBIND11_VERSION_PATCH 1.dev1 +#define PYBIND11_VERSION_PATCH 1 // Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html // Additional convention: 0xD = dev diff --git a/pybind11/_version.py b/pybind11/_version.py index 2bb14b963..2bb4fe364 100644 --- a/pybind11/_version.py +++ b/pybind11/_version.py @@ -8,5 +8,5 @@ def _to_int(s): return s -__version__ = "2.7.1.dev1" +__version__ = "2.7.1" version_info = tuple(_to_int(s) for s in __version__.split(".")) diff --git a/setup.cfg b/setup.cfg index 31038eb02..95963d2f8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,6 +20,7 @@ classifiers = Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 License :: OSI Approved :: BSD License Programming Language :: Python :: Implementation :: PyPy Programming Language :: Python :: Implementation :: CPython From 787d2c88cafa4d07fb38c9519c485a86323cfcf4 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 3 Aug 2021 15:20:23 -0400 Subject: [PATCH 18/22] fix: include hex version in bump --- include/pybind11/detail/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 8006a8df1..dfd5b5699 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -15,7 +15,7 @@ // Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html // Additional convention: 0xD = dev -#define PYBIND11_VERSION_HEX 0x020701D1 +#define PYBIND11_VERSION_HEX 0x02070100 #define PYBIND11_NAMESPACE_BEGIN(name) namespace name { #define PYBIND11_NAMESPACE_END(name) } From 71fd524135cc73f8d6a6c3c0d7aea6cca1605e32 Mon Sep 17 00:00:00 2001 From: Philipp Bucher Date: Tue, 28 Sep 2021 16:09:38 +0200 Subject: [PATCH 19/22] docs: fix minor typo (#3311) --- docs/compiling.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/compiling.rst b/docs/compiling.rst index bf7acfc80..b4072d973 100644 --- a/docs/compiling.rst +++ b/docs/compiling.rst @@ -347,7 +347,7 @@ standard explicitly with set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ version selection") # or 11, 14, 17, 20 set(CMAKE_CXX_STANDARD_REQUIRED ON) # optional, ensure standard is supported - set(CMAKE_CXX_EXTENSIONS OFF) # optional, keep compiler extensionsn off + set(CMAKE_CXX_EXTENSIONS OFF) # optional, keep compiler extensions off The variables can also be set when calling CMake from the command line using the ``-D=`` flag. You can also manually set ``CXX_STANDARD`` From 89769e6e6da425546c00a45ba19f63e5437901c4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 18:28:30 -0500 Subject: [PATCH 20/22] [pre-commit.ci] pre-commit autoupdate (#3574) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.0.1 → v4.1.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.0.1...v4.1.0) - [github.com/pre-commit/mirrors-mypy: v0.920 → v0.930](https://github.com/pre-commit/mirrors-mypy/compare/v0.920...v0.930) - [github.com/shellcheck-py/shellcheck-py: v0.8.0.2 → v0.8.0.3](https://github.com/shellcheck-py/shellcheck-py/compare/v0.8.0.2...v0.8.0.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 972d2472b..3a6583ccf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.1.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -104,7 +104,7 @@ repos: # Check static types with mypy - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.920 + rev: v0.930 hooks: - id: mypy # Running per-file misbehaves a bit, so just run on all files, it's fast @@ -128,7 +128,7 @@ repos: args: ["-L", "nd,ot,thist"] - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.8.0.2 + rev: v0.8.0.3 hooks: - id: shellcheck From 45f792efdd92da094548e2095d6efdbfa7e536ee Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 28 Dec 2021 10:47:21 -0500 Subject: [PATCH 21/22] chore: prepare for 2.9 --- docs/changelog.rst | 4 ++-- include/pybind11/detail/common.h | 4 ++-- pybind11/_version.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 87fce2f2b..cc3f70efb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,8 +7,8 @@ Starting with version 1.8.0, pybind11 releases use a `semantic versioning `_ policy. -IN DEVELOPMENT --------------- +Version 2.9.0 (Dec 28, 2021) +---------------------------- This is the last version to support Python 2.7 and 3.5. diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 2d57367d0..b08bbc559 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -11,11 +11,11 @@ #define PYBIND11_VERSION_MAJOR 2 #define PYBIND11_VERSION_MINOR 9 -#define PYBIND11_VERSION_PATCH 0.dev1 +#define PYBIND11_VERSION_PATCH 0 // Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html // Additional convention: 0xD = dev -#define PYBIND11_VERSION_HEX 0x020900D1 +#define PYBIND11_VERSION_HEX 0x02090000 #define PYBIND11_NAMESPACE_BEGIN(name) namespace name { #define PYBIND11_NAMESPACE_END(name) } diff --git a/pybind11/_version.py b/pybind11/_version.py index ce894a774..6627d4c7e 100644 --- a/pybind11/_version.py +++ b/pybind11/_version.py @@ -8,5 +8,5 @@ def _to_int(s): return s -__version__ = "2.9.0.dev1" +__version__ = "2.9.0" version_info = tuple(_to_int(s) for s in __version__.split(".")) From 9b4f71d12de4f910a77aeb00d37ffb2220e645e7 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 28 Dec 2021 12:19:17 -0500 Subject: [PATCH 22/22] docs: remove duplication in changelog for 2.9.0 --- docs/changelog.rst | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index cc3f70efb..c05e7d3c5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -19,10 +19,6 @@ New Features: used. `#3402 `_ -* Add C++ Exception type to throw and catch ``AttributeError``. Useful for - defining custom ``__setattr__`` and ``__getattr__`` methods. - `#3387 `_ - Changes: * Make str/bytes/memoryview more interoperable with ``std::string_view``. @@ -35,11 +31,6 @@ Changes: Bug fixes: -* Fix a regression in 2.8.0 that caused undefined behavior (typically - segfaults) in ``make_key_iterator``/``make_value_iterator`` if dereferencing - the iterator returned a temporary value instead of a reference. - `#3348 `_ - * Fix a rare warning about extra copy in an Eigen constructor. `#3486 `_ @@ -53,25 +44,10 @@ Bug fixes: ``python dev`` label. `#3419 `_ -* Fix 2.8.0 regression with MSVC 2017 + C++17 mode + Python 3. - `#3407 `_ - -* Modernize usage of ``PyCodeObject`` on Python 3.9 (toward supporting Python - 3.11a1) - `#3368 `_ - -* A long-standing bug in eigen.h was fixed (originally PR #3343). The bug was - unmasked by newly added ``static_assert``'s in the Eigen 3.4.0 release. - `#3352 `_ - * Replace usage of deprecated ``Eigen::MappedSparseMatrix`` with ``Eigen::Map>`` for Eigen 3.3+. `#3499 `_ -* Fixed the potential for dangling references when using properties with - ``std::optional`` types. - `#3376 `_ - * Tweaks to support Microsoft Visual Studio 2022. `#3497 `_ @@ -84,13 +60,6 @@ Build system improvements: space in the package status message. `#3472 `_ -* Support multiple raw inclusion of CMake helper files (Conan.io does this for - multi-config generators). - `#3420 `_ - -* Fix harmless warning on CMake 3.22. - `#3368 `_ - * Flags starting with ``-g`` in ``$CFLAGS`` and ``$CPPFLAGS`` are no longer overridden by ``.Pybind11Extension``. `#3436 `_