Merge branch 'master' into sh_merge_master

This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-07-21 06:53:22 -07:00
commit 4d774ec218
24 changed files with 452 additions and 154 deletions

View File

@ -1,68 +1,70 @@
FormatStyle: file
Checks: '
*bugprone*,
clang-analyzer-optin.performance.Padding,
clang-analyzer-optin.cplusplus.VirtualCall,
cppcoreguidelines-init-variables,
cppcoreguidelines-prefer-member-initializer,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-slicing,
google-explicit-constructor,
llvm-namespace-comment,
misc-definitions-in-headers,
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-loop-convert,
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,
modernize-use-default-member-init,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-emplace,
modernize-use-noexcept,
modernize-use-nullptr,
modernize-use-override,
modernize-use-using,
*performance*,
readability-avoid-const-params-in-decls,
readability-braces-around-statements,
readability-const-return-type,
readability-container-size-empty,
readability-delete-null-pointer,
readability-else-after-return,
readability-implicit-bool-conversion,
readability-inconsistent-declaration-parameter-name,
readability-make-member-function-const,
readability-misplaced-array-index,
readability-non-const-parameter,
readability-qualified-auto,
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-suspicious-call-argument,
readability-uniqueptr-delete-release,
-bugprone-exception-escape,
-bugprone-reserved-identifier,
-bugprone-unused-raii,
'
Checks: |
*bugprone*,
*performance*,
clang-analyzer-optin.cplusplus.VirtualCall,
clang-analyzer-optin.performance.Padding,
cppcoreguidelines-init-variables,
cppcoreguidelines-prefer-member-initializer,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-slicing,
google-explicit-constructor,
llvm-namespace-comment,
misc-definitions-in-headers,
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-loop-convert,
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,
modernize-use-default-member-init,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-noexcept,
modernize-use-nullptr,
modernize-use-override,
modernize-use-using,
readability-avoid-const-params-in-decls,
readability-braces-around-statements,
readability-const-return-type,
readability-container-size-empty,
readability-delete-null-pointer,
readability-else-after-return,
readability-implicit-bool-conversion,
readability-inconsistent-declaration-parameter-name,
readability-make-member-function-const,
readability-misplaced-array-index,
readability-non-const-parameter,
readability-qualified-auto,
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-suspicious-call-argument,
readability-uniqueptr-delete-release,
-bugprone-easily-swappable-parameters,
-bugprone-exception-escape,
-bugprone-reserved-identifier,
-bugprone-unused-raii,
CheckOptions:
- key: modernize-use-equals-default.IgnoreMacros
value: false
- key: performance-for-range-copy.WarnOnAllAutoCopies
value: true
- key: performance-inefficient-string-concatenation.StrictMode
@ -73,5 +75,3 @@ CheckOptions:
value: true
HeaderFilterRegex: 'pybind11/.*h'
WarningsAsErrors: '*'

View File

@ -235,12 +235,14 @@ directory inside your pybind11 git clone. Files will be modified in place,
so you can use git to monitor the changes.
```bash
docker run --rm -v $PWD:/mounted_pybind11 -it silkeh/clang:12
docker run --rm -v $PWD:/mounted_pybind11 -it silkeh/clang:13
apt-get update && apt-get install -y python3-dev python3-pytest
cmake -S /mounted_pybind11/ -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);-fix" -DDOWNLOAD_EIGEN=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_STANDARD=17
cmake --build build -j 2 -- --keep-going
cmake -S /mounted_pybind11/ -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--use-color" -DDOWNLOAD_EIGEN=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_STANDARD=17
cmake --build build -j 2
```
You can add `--fix` to the options list if you want.
### Include what you use
To run include what you use, install (`brew install include-what-you-use` on

View File

@ -282,6 +282,14 @@ jobs:
std: 20
- clang: 10
std: 17
- clang: 11
std: 20
- clang: 12
std: 20
- clang: 13
std: 20
- clang: 14
std: 20
name: "🐍 3 • Clang ${{ matrix.clang }} • C++${{ matrix.std }} • x64"
container: "silkeh/clang:${{ matrix.clang }}"
@ -436,14 +444,14 @@ jobs:
strategy:
fail-fast: false
matrix:
gcc:
- 7
- latest
std:
- 11
include:
- gcc: 10
std: 20
- { gcc: 7, std: 11 }
- { gcc: 7, std: 17 }
- { gcc: 8, std: 14 }
- { gcc: 8, std: 17 }
- { gcc: 10, std: 17 }
- { gcc: 11, std: 20 }
- { gcc: 12, std: 20 }
name: "🐍 3 • GCC ${{ matrix.gcc }} • C++${{ matrix.std }}• x64"
container: "gcc:${{ matrix.gcc }}"

View File

@ -37,7 +37,7 @@ jobs:
# in .github/CONTRIBUTING.md and update as needed.
name: Clang-Tidy
runs-on: ubuntu-latest
container: silkeh/clang:12
container: silkeh/clang:13
steps:
- uses: actions/checkout@v3
@ -47,7 +47,7 @@ jobs:
- name: Configure
run: >
cmake -S . -B build
-DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy)"
-DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--use-color;--warnings-as-errors=*"
-DDOWNLOAD_EIGEN=ON
-DDOWNLOAD_CATCH=ON
-DCMAKE_CXX_STANDARD=17

View File

@ -73,7 +73,7 @@ repos:
# Autoremoves unused imports
- repo: https://github.com/hadialqattan/pycln
rev: "v2.0.1"
rev: "v2.0.4"
hooks:
- id: pycln
stages: [manual]
@ -110,7 +110,7 @@ repos:
# PyLint has native support - not always usable, but works for us
- repo: https://github.com/PyCQA/pylint
rev: "v2.14.4"
rev: "v2.14.5"
hooks:
- id: pylint
files: ^pybind11

3
docs/_static/css/custom.css vendored Normal file
View File

@ -0,0 +1,3 @@
.highlight .go {
color: #707070;
}

View File

@ -1,11 +0,0 @@
.wy-table-responsive table td,
.wy-table-responsive table th {
white-space: initial !important;
}
.rst-content table.docutils td {
vertical-align: top !important;
}
div[class^='highlight'] pre {
white-space: pre;
white-space: pre-wrap;
}

View File

@ -9,14 +9,20 @@ Starting with version 1.8.0, pybind11 releases use a `semantic versioning
Changes will be added here periodically from the "Suggested changelog entry"
block in pull request descriptions.
IN DEVELOPMENT
--------------
Changes will be summarized here periodically.
Version 2.10.0 (Jul 15, 2022)
-----------------------------
Removed support for Python 2.7, Python 3.5, and MSVC 2015. Support for MSVC
2017 is limited due to availability of CI runners; we highly recommend MSVC
2019 or 2022 be used. Initial support added for Python 3.11.
New features:
* ``py::anyset`` & ``py::frozenset`` were added, with copying (cast) to
@ -70,6 +76,9 @@ Changes:
requiring ``NDEBUG``, allowing use with release builds if desired.
`#3913 <https://github.com/pybind/pybind11/pull/3913>`_
* Implicit conversion of the literal ``0`` to ``pybind11::handle`` is now disabled.
`#4008 <https://github.com/pybind/pybind11/pull/4008>`_
Bug fixes:
@ -98,6 +107,14 @@ Bug fixes:
* Fix cast from pytype rvalue to another pytype.
`#3949 <https://github.com/pybind/pybind11/pull/3949>`_
* Ensure proper behavior when garbage collecting classes with dynamic attributes in Python >=3.9.
`#4051 <https://github.com/pybind/pybind11/pull/4051>`_
* A couple long-standing ``PYBIND11_NAMESPACE``
``__attribute__((visibility("hidden")))`` inconsistencies are now fixed
(affects only unusual environments).
`#4043 <https://github.com/pybind/pybind11/pull/4043>`_
* ``pybind11::detail::get_internals()`` is now resilient to in-flight Python
exceptions.
`#3981 <https://github.com/pybind/pybind11/pull/3981>`_
@ -147,6 +164,9 @@ Performance and style:
* Optimize c++ to python function casting by using the rvalue caster.
`#3966 <https://github.com/pybind/pybind11/pull/3966>`_
* Optimize Eigen sparse matrix casting by removing unnecessary temporary.
`#4064 <https://github.com/pybind/pybind11/pull/4064>`_
* Avoid potential implicit copy/assignment constructors causing double free in
``strdup_gaurd``.
`#3905 <https://github.com/pybind/pybind11/pull/3905>`_
@ -182,6 +202,9 @@ Build system improvements:
Backend and tidying up:
* New theme for the documentation.
`#3109 <https://github.com/pybind/pybind11/pull/3109>`_
* Remove idioms in code comments. Use more inclusive language.
`#3809 <https://github.com/pybind/pybind11/pull/3809>`_

View File

@ -35,6 +35,7 @@ DIR = Path(__file__).parent.resolve()
# ones.
extensions = [
"breathe",
"sphinx_copybutton",
"sphinxcontrib.rsvgconverter",
"sphinxcontrib.moderncmakedomain",
]
@ -125,23 +126,7 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_context = {"css_files": ["_static/theme_overrides.css"]}
else:
html_context = {
"css_files": [
"//media.readthedocs.org/css/sphinx_rtd_theme.css",
"//media.readthedocs.org/css/readthedocs-doc-embed.css",
"_static/theme_overrides.css",
]
}
html_theme = "furo"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@ -172,6 +157,10 @@ else:
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_css_files = [
"css/custom.css",
]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,5 +1,6 @@
breathe==4.32.0
sphinx==4.4.0
sphinx_rtd_theme==1.0.0
breathe==4.34.0
furo==2022.6.21
sphinx==5.0.2
sphinx-copybutton==0.5.0
sphinxcontrib-moderncmakedomain==3.21.4
sphinxcontrib-svg2pdfconverter==1.2.0

View File

@ -10,12 +10,12 @@
#pragma once
#define PYBIND11_VERSION_MAJOR 2
#define PYBIND11_VERSION_MINOR 10
#define PYBIND11_VERSION_MINOR 11
#define PYBIND11_VERSION_PATCH 0.dev1
// Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html
// Additional convention: 0xD = dev
#define PYBIND11_VERSION_HEX 0x020A00D1
#define PYBIND11_VERSION_HEX 0x020B00D1
#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
#define PYBIND11_NAMESPACE_END(name) }
@ -1170,6 +1170,24 @@ constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }
# 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. */ \
|| (__clang_major__ >= 7 \
&& __clang_major__ <= 12) /* Clang 3, 5, 13, 14, 15 do not generate the warning. */ \
)
# define PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
// Example:
// tests/test_kwargs_and_defaults.cpp:46:68: error: local variable 'args' will be copied despite
// being returned by name [-Werror,-Wreturn-std-move]
// m.def("args_function", [](py::args args) -> py::tuple { return args; });
// ^~~~
// test_kwargs_and_defaults.cpp:46:68: note: call 'std::move' explicitly to avoid copying
// m.def("args_function", [](py::args args) -> py::tuple { return args; });
// ^~~~
// std::move(args)
#endif
// Pybind offers detailed error messages by default for all builts that are debug (through the
// negation of ndebug). This can also be manually enabled by users, for any builds, through
// defining PYBIND11_DETAILED_ERROR_MESSAGES.

View File

@ -695,9 +695,9 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
array innerIndices(src.nonZeros(), src.innerIndexPtr());
return matrix_type(std::make_tuple(
return matrix_type(pybind11::make_tuple(
std::move(data), std::move(innerIndices), std::move(outerIndices)),
std::make_pair(src.rows(), src.cols()))
pybind11::make_tuple(src.rows(), src.cols()))
.release();
}

View File

@ -537,7 +537,7 @@ PYBIND11_NAMESPACE_END(detail)
class dtype : public object {
public:
PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);
PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_)
explicit dtype(const buffer_info &info) {
dtype descr(_dtype_from_pep3118()(pybind11::str(info.format)));
@ -1865,9 +1865,13 @@ private:
}
auto result = returned_array::create(trivial, shape);
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wreturn-std-move"
#endif
if (size == 0) {
return std::move(result);
return result;
}
/* Call the function */
@ -1878,7 +1882,10 @@ private:
apply_trivial(buffers, params, mutable_data, size, i_seq, vi_seq, bi_seq);
}
return std::move(result);
return result;
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic pop
#endif
}
template <size_t... Index, size_t... VIndex, size_t... BIndex>

View File

@ -155,23 +155,23 @@ public:
object operator-() const;
object operator~() const;
object operator+(object_api const &other) const;
object operator+=(object_api const &other) const;
object operator+=(object_api const &other);
object operator-(object_api const &other) const;
object operator-=(object_api const &other) const;
object operator-=(object_api const &other);
object operator*(object_api const &other) const;
object operator*=(object_api const &other) const;
object operator*=(object_api const &other);
object operator/(object_api const &other) const;
object operator/=(object_api const &other) const;
object operator/=(object_api const &other);
object operator|(object_api const &other) const;
object operator|=(object_api const &other) const;
object operator|=(object_api const &other);
object operator&(object_api const &other) const;
object operator&=(object_api const &other) const;
object operator&=(object_api const &other);
object operator^(object_api const &other) const;
object operator^=(object_api const &other) const;
object operator^=(object_api const &other);
object operator<<(object_api const &other) const;
object operator<<=(object_api const &other) const;
object operator<<=(object_api const &other);
object operator>>(object_api const &other) const;
object operator>>=(object_api const &other) const;
object operator>>=(object_api const &other);
PYBIND11_DEPRECATED("Use py::str(obj) instead")
pybind11::str str() const;
@ -190,6 +190,11 @@ private:
bool rich_compare(object_api const &other, int value) const;
};
template <typename T>
using is_pyobj_ptr_or_nullptr_t = detail::any_of<std::is_same<T, PyObject *>,
std::is_same<T, PyObject *const>,
std::is_same<T, std::nullptr_t>>;
PYBIND11_NAMESPACE_END(detail)
#if !defined(PYBIND11_HANDLE_REF_DEBUG) && !defined(NDEBUG)
@ -211,9 +216,23 @@ class handle : public detail::object_api<handle> {
public:
/// The default constructor creates a handle with a ``nullptr``-valued pointer
handle() = default;
/// Creates a ``handle`` from the given raw Python object pointer
/// Enable implicit conversion from ``PyObject *`` and ``nullptr``.
/// Not using ``handle(PyObject *ptr)`` to avoid implicit conversion from ``0``.
template <typename T,
detail::enable_if_t<detail::is_pyobj_ptr_or_nullptr_t<T>::value, int> = 0>
// NOLINTNEXTLINE(google-explicit-constructor)
handle(PyObject *ptr) : m_ptr(ptr) {} // Allow implicit conversion from PyObject*
handle(T ptr) : m_ptr(ptr) {}
/// Enable implicit conversion through ``T::operator PyObject *()``.
template <
typename T,
detail::enable_if_t<detail::all_of<detail::none_of<std::is_base_of<handle, T>,
detail::is_pyobj_ptr_or_nullptr_t<T>>,
std::is_convertible<T, PyObject *>>::value,
int> = 0>
// NOLINTNEXTLINE(google-explicit-constructor)
handle(T &obj) : m_ptr(obj) {}
/// Return the underlying ``PyObject *`` pointer
PyObject *ptr() const { return m_ptr; }
@ -315,12 +334,15 @@ public:
}
object &operator=(const object &other) {
other.inc_ref();
// Use temporary variable to ensure `*this` remains valid while
// `Py_XDECREF` executes, in case `*this` is accessible from Python.
handle temp(m_ptr);
m_ptr = other.m_ptr;
temp.dec_ref();
// Skip inc_ref and dec_ref if both objects are the same
if (!this->is(other)) {
other.inc_ref();
// Use temporary variable to ensure `*this` remains valid while
// `Py_XDECREF` executes, in case `*this` is accessible from Python.
handle temp(m_ptr);
m_ptr = other.m_ptr;
temp.dec_ref();
}
return *this;
}
@ -334,6 +356,20 @@ public:
return *this;
}
#define PYBIND11_INPLACE_OP(iop) \
object iop(object_api const &other) { return operator=(handle::iop(other)); }
PYBIND11_INPLACE_OP(operator+=)
PYBIND11_INPLACE_OP(operator-=)
PYBIND11_INPLACE_OP(operator*=)
PYBIND11_INPLACE_OP(operator/=)
PYBIND11_INPLACE_OP(operator|=)
PYBIND11_INPLACE_OP(operator&=)
PYBIND11_INPLACE_OP(operator^=)
PYBIND11_INPLACE_OP(operator<<=)
PYBIND11_INPLACE_OP(operator>>=)
#undef PYBIND11_INPLACE_OP
// Calling cast() on an object lvalue just copies (via handle::cast)
template <typename T>
T cast() const &;
@ -437,6 +473,12 @@ struct error_fetch_and_normalize {
+ " failed to obtain the name "
"of the normalized active exception type.");
}
#if defined(PYPY_VERSION)
// This behavior runs the risk of masking errors in the error handling, but avoids a
// conflict with PyPy, which relies on the normalization here to change OSError to
// FileNotFoundError (https://github.com/pybind/pybind11/issues/4075).
m_lazy_error_string = exc_type_name_norm;
#else
if (exc_type_name_norm != m_lazy_error_string) {
std::string msg = std::string(called)
+ ": MISMATCH of original and normalized "
@ -448,6 +490,7 @@ struct error_fetch_and_normalize {
msg += ": " + format_value_and_trace();
pybind11_fail(msg);
}
#endif
}
error_fetch_and_normalize(const error_fetch_and_normalize &) = delete;
@ -1247,7 +1290,7 @@ public:
#define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun) \
PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \
Name() : Parent() {}
Name() = default;
#define PYBIND11_OBJECT_CHECK_FAILED(Name, o_ptr) \
::pybind11::type_error("Object of type '" \
@ -1270,7 +1313,7 @@ public:
#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun) \
PYBIND11_OBJECT(Name, Parent, CheckFun) \
Name() : Parent() {}
Name() = default;
/// \addtogroup pytypes
/// @{
@ -2345,26 +2388,35 @@ bool object_api<D>::rich_compare(object_api const &other, int value) const {
return result; \
}
#define PYBIND11_MATH_OPERATOR_BINARY_INPLACE(iop, fn) \
template <typename D> \
object object_api<D>::iop(object_api const &other) { \
object result = reinterpret_steal<object>(fn(derived().ptr(), other.derived().ptr())); \
if (!result.ptr()) \
throw error_already_set(); \
return result; \
}
PYBIND11_MATH_OPERATOR_UNARY(operator~, PyNumber_Invert)
PYBIND11_MATH_OPERATOR_UNARY(operator-, PyNumber_Negative)
PYBIND11_MATH_OPERATOR_BINARY(operator+, PyNumber_Add)
PYBIND11_MATH_OPERATOR_BINARY(operator+=, PyNumber_InPlaceAdd)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator+=, PyNumber_InPlaceAdd)
PYBIND11_MATH_OPERATOR_BINARY(operator-, PyNumber_Subtract)
PYBIND11_MATH_OPERATOR_BINARY(operator-=, PyNumber_InPlaceSubtract)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator-=, PyNumber_InPlaceSubtract)
PYBIND11_MATH_OPERATOR_BINARY(operator*, PyNumber_Multiply)
PYBIND11_MATH_OPERATOR_BINARY(operator*=, PyNumber_InPlaceMultiply)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator*=, PyNumber_InPlaceMultiply)
PYBIND11_MATH_OPERATOR_BINARY(operator/, PyNumber_TrueDivide)
PYBIND11_MATH_OPERATOR_BINARY(operator/=, PyNumber_InPlaceTrueDivide)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator/=, PyNumber_InPlaceTrueDivide)
PYBIND11_MATH_OPERATOR_BINARY(operator|, PyNumber_Or)
PYBIND11_MATH_OPERATOR_BINARY(operator|=, PyNumber_InPlaceOr)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator|=, PyNumber_InPlaceOr)
PYBIND11_MATH_OPERATOR_BINARY(operator&, PyNumber_And)
PYBIND11_MATH_OPERATOR_BINARY(operator&=, PyNumber_InPlaceAnd)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator&=, PyNumber_InPlaceAnd)
PYBIND11_MATH_OPERATOR_BINARY(operator^, PyNumber_Xor)
PYBIND11_MATH_OPERATOR_BINARY(operator^=, PyNumber_InPlaceXor)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator^=, PyNumber_InPlaceXor)
PYBIND11_MATH_OPERATOR_BINARY(operator<<, PyNumber_Lshift)
PYBIND11_MATH_OPERATOR_BINARY(operator<<=, PyNumber_InPlaceLshift)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator<<=, PyNumber_InPlaceLshift)
PYBIND11_MATH_OPERATOR_BINARY(operator>>, PyNumber_Rshift)
PYBIND11_MATH_OPERATOR_BINARY(operator>>=, PyNumber_InPlaceRshift)
PYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator>>=, PyNumber_InPlaceRshift)
#undef PYBIND11_MATH_OPERATOR_UNARY
#undef PYBIND11_MATH_OPERATOR_BINARY

View File

@ -5,7 +5,17 @@ import nox
nox.needs_version = ">=2022.1.7"
nox.options.sessions = ["lint", "tests", "tests_packaging"]
PYTHON_VERISONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.7", "pypy3.8"]
PYTHON_VERSIONS = [
"3.6",
"3.7",
"3.8",
"3.9",
"3.10",
"3.11",
"pypy3.7",
"pypy3.8",
"pypy3.9",
]
if os.environ.get("CI", None):
nox.options.error_on_missing_interpreters = True
@ -20,7 +30,7 @@ def lint(session: nox.Session) -> None:
session.run("pre-commit", "run", "-a")
@nox.session(python=PYTHON_VERISONS)
@nox.session(python=PYTHON_VERSIONS)
def tests(session: nox.Session) -> None:
"""
Run the tests (requires a compiler).
@ -61,10 +71,10 @@ def docs(session: nox.Session) -> None:
session.chdir("docs")
if "pdf" in session.posargs:
session.run("sphinx-build", "-b", "latexpdf", ".", "_build")
session.run("sphinx-build", "-M", "latexpdf", ".", "_build")
return
session.run("sphinx-build", "-b", "html", ".", "_build")
session.run("sphinx-build", "-M", "html", ".", "_build")
if "serve" in session.posargs:
session.log("Launching docs at http://localhost:8000/ - use Ctrl-C to quit")

View File

@ -8,5 +8,5 @@ def _to_int(s: str) -> Union[int, str]:
return s
__version__ = "2.10.0.dev1"
__version__ = "2.11.0.dev1"
version_info = tuple(_to_int(s) for s in __version__.split("."))

View File

@ -7,7 +7,7 @@ if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STR
return()
endif()
find_package(Catch 2.13.5)
find_package(Catch 2.13.9)
if(CATCH_FOUND)
message(STATUS "Building interpreter tests using Catch v${CATCH_VERSION}")

View File

@ -334,4 +334,14 @@ TEST_SUBMODULE(exceptions, m) {
e.restore();
}
});
// https://github.com/pybind/pybind11/issues/4075
m.def("test_pypy_oserror_normalization", []() {
try {
py::module_::import("io").attr("open")("this_filename_must_not_exist", "r");
} catch (const py::error_already_set &e) {
return py::str(e.what()); // str must be built before e goes out of scope.
}
return py::str("UNEXPECTED");
});
}

View File

@ -360,3 +360,9 @@ def test_error_already_set_double_restore():
"Internal error: pybind11::detail::error_fetch_and_normalize::restore()"
" called a second time. ORIGINAL ERROR: ValueError: Random error."
)
def test_pypy_oserror_normalization():
# https://github.com/pybind/pybind11/issues/4075
what = m.test_pypy_oserror_normalization()
assert "this_filename_must_not_exist" in what

View File

@ -43,7 +43,16 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
m.def("kw_func_udl_z", kw_func, "x"_a, "y"_a = 0);
// test_args_and_kwargs
m.def("args_function", [](py::args args) -> py::tuple { return std::move(args); });
m.def("args_function", [](py::args args) -> py::tuple {
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wreturn-std-move"
#endif
return args;
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic pop
#endif
});
m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) {
return py::make_tuple(args, kwargs);
});

View File

@ -39,7 +39,68 @@ class float_ : public py::object {
};
} // namespace external
namespace implicit_conversion_from_0_to_handle {
// Uncomment to trigger compiler error. Note: Before PR #4008 this used to compile successfully.
// void expected_to_trigger_compiler_error() { py::handle(0); }
} // namespace implicit_conversion_from_0_to_handle
// Used to validate systematically that PR #4008 does/did NOT change the behavior.
void pure_compile_tests_for_handle_from_PyObject_pointers() {
{
PyObject *ptr = Py_None;
py::handle{ptr};
}
{
PyObject *const ptr = Py_None;
py::handle{ptr};
}
// Uncomment to trigger compiler errors.
// PyObject const * ptr = Py_None; py::handle{ptr};
// PyObject const *const ptr = Py_None; py::handle{ptr};
// PyObject volatile * ptr = Py_None; py::handle{ptr};
// PyObject volatile *const ptr = Py_None; py::handle{ptr};
// PyObject const volatile * ptr = Py_None; py::handle{ptr};
// PyObject const volatile *const ptr = Py_None; py::handle{ptr};
}
namespace handle_from_move_only_type_with_operator_PyObject {
// Reduced from
// https://github.com/pytorch/pytorch/blob/279634f384662b7c3a9f8bf7ccc3a6afd2f05657/torch/csrc/utils/object_ptr.h
struct operator_ncnst {
operator_ncnst() = default;
operator_ncnst(operator_ncnst &&) = default;
operator PyObject *() /* */ { return Py_None; } // NOLINT(google-explicit-constructor)
};
struct operator_const {
operator_const() = default;
operator_const(operator_const &&) = default;
operator PyObject *() const { return Py_None; } // NOLINT(google-explicit-constructor)
};
bool from_ncnst() {
operator_ncnst obj;
auto h = py::handle(obj); // Critical part of test: does this compile?
return h.ptr() == Py_None; // Just something.
}
bool from_const() {
operator_const obj;
auto h = py::handle(obj); // Critical part of test: does this compile?
return h.ptr() == Py_None; // Just something.
}
void m_defs(py::module_ &m) {
m.def("handle_from_move_only_type_with_operator_PyObject_ncnst", from_ncnst);
m.def("handle_from_move_only_type_with_operator_PyObject_const", from_const);
}
} // namespace handle_from_move_only_type_with_operator_PyObject
TEST_SUBMODULE(pytypes, m) {
handle_from_move_only_type_with_operator_PyObject::m_defs(m);
// test_bool
m.def("get_bool", [] { return py::bool_(false); });
// test_int
@ -695,4 +756,38 @@ TEST_SUBMODULE(pytypes, m) {
}
return o;
});
// testing immutable object augmented assignment: #issue 3812
m.def("inplace_append", [](py::object &a, const py::object &b) {
a += b;
return a;
});
m.def("inplace_subtract", [](py::object &a, const py::object &b) {
a -= b;
return a;
});
m.def("inplace_multiply", [](py::object &a, const py::object &b) {
a *= b;
return a;
});
m.def("inplace_divide", [](py::object &a, const py::object &b) {
a /= b;
return a;
});
m.def("inplace_or", [](py::object &a, const py::object &b) {
a |= b;
return a;
});
m.def("inplace_and", [](py::object &a, const py::object &b) {
a &= b;
return a;
});
m.def("inplace_lshift", [](py::object &a, const py::object &b) {
a <<= b;
return a;
});
m.def("inplace_rshift", [](py::object &a, const py::object &b) {
a >>= b;
return a;
});
}

View File

@ -9,6 +9,11 @@ from pybind11_tests import detailed_error_messages_enabled
from pybind11_tests import pytypes as m
def test_handle_from_move_only_type_with_operator_PyObject(): # noqa: N802
assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
assert m.handle_from_move_only_type_with_operator_PyObject_const()
def test_bool(doc):
assert doc(m.get_bool) == "get_bool() -> bool"
@ -734,3 +739,75 @@ def test_populate_obj_str_attrs():
new_attrs = {k: v for k, v in new_o.__dict__.items() if not k.startswith("_")}
assert all(isinstance(v, str) for v in new_attrs.values())
assert len(new_attrs) == pop
@pytest.mark.parametrize(
"a,b", [("foo", "bar"), (1, 2), (1.0, 2.0), (list(range(3)), list(range(3, 6)))]
)
def test_inplace_append(a, b):
expected = a + b
assert m.inplace_append(a, b) == expected
@pytest.mark.parametrize("a,b", [(3, 2), (3.0, 2.0), (set(range(3)), set(range(2)))])
def test_inplace_subtract(a, b):
expected = a - b
assert m.inplace_subtract(a, b) == expected
@pytest.mark.parametrize("a,b", [(3, 2), (3.0, 2.0), ([1], 3)])
def test_inplace_multiply(a, b):
expected = a * b
assert m.inplace_multiply(a, b) == expected
@pytest.mark.parametrize("a,b", [(6, 3), (6.0, 3.0)])
def test_inplace_divide(a, b):
expected = a / b
assert m.inplace_divide(a, b) == expected
@pytest.mark.parametrize(
"a,b",
[
(False, True),
(
set(),
{
1,
},
),
],
)
def test_inplace_or(a, b):
expected = a | b
assert m.inplace_or(a, b) == expected
@pytest.mark.parametrize(
"a,b",
[
(True, False),
(
{1, 2, 3},
{
1,
},
),
],
)
def test_inplace_and(a, b):
expected = a & b
assert m.inplace_and(a, b) == expected
@pytest.mark.parametrize("a,b", [(8, 1), (-3, 2)])
def test_inplace_lshift(a, b):
expected = a << b
assert m.inplace_lshift(a, b) == expected
@pytest.mark.parametrize("a,b", [(8, 1), (-2, 2)])
def test_inplace_rshift(a, b):
expected = a >> b
assert m.inplace_rshift(a, b) == expected

View File

@ -342,9 +342,8 @@ TEST_SUBMODULE(virtual_functions, m) {
const AdderBase &adder,
const AdderBase::DataVisitor &visitor) {
adder(first, second, [&](const AdderBase::Data &first_plus_second) {
adder(first_plus_second,
third,
visitor); // NOLINT(readability-suspicious-call-argument)
// NOLINTNEXTLINE(readability-suspicious-call-argument)
adder(first_plus_second, third, visitor);
});
});