* LazyInitializeAtLeastOnceDestroyNever v1
* Go back to using `union` as originally suggested by jbms@. The trick (also suggested by jbms@) is to add empty ctor + dtor.
* Revert "Go back to using `union` as originally suggested by jbms@. The trick (also suggested by jbms@) is to add empty ctor + dtor."
This reverts commit e7b8c4f0fc.
* Remove `#include <stdalign.h>`
* `include\pybind11/numpy.h(24,10): fatal error C1083: Cannot open include file: 'stdalign.h': No such file or directory`
* @tkoeppe wrote: this is a C interop header (and we're not writing C)
* Suppress gcc 4.8.5 (CentOS 7) warning.
```
include/pybind11/eigen/../numpy.h:63:53: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *reinterpret_cast<T *>(value_storage_);
^
```
* Replace comments:
Document PRECONDITION.
Adopt comment suggested by @tkoeppe: https://github.com/pybind/pybind11/pull/4877#discussion_r1350356093
* Adopt suggestion by @tkoeppe:
* https://github.com/pybind/pybind11/pull/4877#issuecomment-1752969127
* https://godbolt.org/z/Wa79nKz6e
* Add `PYBIND11_CONSTINIT`, but it does not work for the current use cases:
```
g++ -o pybind11/tests/test_numpy_array.os -c -std=c++20 -fPIC -fvisibility=hidden -O0 -g -Wall -Wextra -Wconversion -Wcast-qual -Wdeprecated -Wundef -Wnon-virtual-dtor -Wunused-result -Werror -isystem /usr/include/python3.11 -isystem /usr/include/eigen3 -DPYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX -DPYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD_IF_AVAILABLE -DPYBIND11_TEST_BOOST -Ipybind11/include -I/usr/local/google/home/rwgk/forked/pybind11/include -I/usr/local/google/home/rwgk/clone/pybind11/include /usr/local/google/home/rwgk/forked/pybind11/tests/test_numpy_array.cpp
```
```
In file included from /usr/local/google/home/rwgk/forked/pybind11/tests/test_numpy_array.cpp:10:
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/numpy.h: In static member function ‘static pybind11::detail::npy_api& pybind11::detail::npy_api::get()’:
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/numpy.h:258:82: error: ‘constinit’ variable ‘api_init’ does not have a constant initializer
258 | PYBIND11_CONSTINIT static LazyInitializeAtLeastOnceDestroyNever<npy_api> api_init;
| ^~~~~~~~
```
```
In file included from /usr/local/google/home/rwgk/forked/pybind11/tests/test_numpy_array.cpp:10:
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/numpy.h: In static member function ‘static pybind11::object& pybind11::dtype::_dtype_from_pep3118()’:
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/numpy.h:697:13: error: ‘constinit’ variable ‘imported_obj’ does not have a constant initializer
697 | imported_obj;
| ^~~~~~~~~~~~
```
* Revert "Add `PYBIND11_CONSTINIT`, but it does not work for the current use cases:"
This reverts commit f07b28bda9.
* Reapply "Add `PYBIND11_CONSTINIT`, but it does not work for the current use cases:"
This reverts commit 36be645758.
* Add Default Member Initializer on `value_storage_` as suggested by @tkoeppe:
https://github.com/pybind/pybind11/pull/4877#issuecomment-1753201342
This fixes the errors reported under commit f07b28bda9.
* Fix copy-paste-missed-a-change mishap in commit 88cec1152a.
* Semi-paranoid placement new (based on https://github.com/pybind/pybind11/pull/4877#discussion_r1350573114).
* Move PYBIND11_CONSTINIT to detail/common.h
* Move code to the right places, rename new class and some variables.
* Fix oversight: update tests/extra_python_package/test_files.py
* Get the name right first.
* Use `std::call_once`, `std::atomic`, following a pattern developed by @tkoeppe
* Make the API more self-documenting (and possibly more easily reusable).
* google-clang-tidy IWYU fixes
* Rewrite comment as suggested by @tkoeppe
* Update test_exceptions.cpp and exceptions.rst
* Fix oversight in previous commit: add `PYBIND11_CONSTINIT`
* Make `get_stored()` non-const for simplicity.
As suggested by @tkoeppe: not seeing any reasonable use in which `get_stored` has to be const.
* Add comment regarding `KeyboardInterrupt` behavior, based heavily on information provided by @jbms.
* Add `assert(PyGILState_Check())` in `gil_scoped_release` ctor (simple & non-simple implementation) as suggested by @EthanSteinberg.
* Fix oversight in previous commit (missing include cassert).
* Remove use of std::atomic, leaving comments with rationale, why it is not needed.
* Rewrite comment re `std:optional` based on deeper reflection (aka 2nd thoughts).
* Additional comment with the conclusion of a discussion under PR #4877.
* https://github.com/pybind/pybind11/pull/4877#issuecomment-1757363179
* Small comment changes suggested by @tkoeppe.
* fix: Add capitalize render name of `py::buffer` and `py::sequence`
* fix: Render `py::handle` same way as `py::object`
* tests: Fix tests `handle` -> `object`
* tests: Test capitaliation of `py::sequence` and `py::buffer`
* style: pre-commit fixes
* fix: Render `py::object` as `Any`
* Revert "fix: Render `py::object` as `Any`"
This reverts commit 7861dcfabb.
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
* Remove newlines from docstring signature
* Jean/dev (#1)
Replace newlines in arg values with spaces
* style: pre-commit fixes
* Don't use std::find_if for C++ 11 compatibility
* Avoid implicit char to bool conversion
* Test default arguments for line breaks
* style: pre-commit fixes
* Separate Eigen tests
* style: pre-commit fixes
* Fix merge
* Try importing numpy
* Avoid unreferenced variable in catch block
* style: pre-commit fixes
* Update squash function
* Reduce try block
* Additional test cases
* style: pre-commit fixes
* Put statement inside braces
* Move string into function body
* Rename repr for better readability. Make constr explicit.
* Add multiline string default argument test case
* style: pre-commit fixes
* Add std namespace, do not modify string repr
* Test for all space chars, test str repr not modified
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Copy clang 17 compatibility fixes from PR #4762 to a separate PR.
* static py::exception<> -> static py::handle
* Add `py::set_error()` but also try the suggestion of @malfet (https://github.com/pytorch/pytorch/pull/106401#pullrequestreview-1559961407).
* clang 17 compatibility fixes (#4767)
* Copy clang 17 compatibility fixes from PR #4762 to a separate PR.
* Add gcc:13 C++20
* Add silkeh/clang:16-bullseye C++20
* chore(deps): update pre-commit hooks (#4770)
updates:
- [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0)
- [github.com/astral-sh/ruff-pre-commit: v0.0.276 → v0.0.281](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.276...v0.0.281)
- [github.com/asottile/blacken-docs: 1.14.0 → 1.15.0](https://github.com/asottile/blacken-docs/compare/1.14.0...1.15.0)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* docs: Remove upper bound on pybind11 in example pyproject.toml for setuptools (#4774)
* docs: Remove upper bound on pybind11 in example pyproject.toml for setuptools
* Update docs/compiling.rst
---------
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
* Provide better type hints for a variety of generic types (#4259)
* Provide better type hints for a variety of generic types
* Makes better documentation
* tuple, dict, list, set, function
* Move to py::typing
* style: pre-commit fixes
* Update copyright line with correct year and actual author. The author information was copy-pasted from the git log output.
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Use `py::set_error()` everywhere possible (only one special case, in common.h).
Overload `py::set_error(py::handle, py::handle)`.
Change back to `static py::handle exc = ... .release();`
Deprecate `py::exception<>::operator()`
* Add `PYBIND11_WARNING_DISABLE` for INTEL and MSVC (and sort alphabetically).
* `PYBIND11_WARNING_DISABLE_INTEL(10441)` does not work.
For ICC only, falling back to the recommended `py::set_error()` to keep the testing simple.
It is troublesome to add `--diag-disable=10441` specifically for test_exceptions.cpp, even that is non-ideal because it covers the entire file, not just the one line we need it for, and the value of exercising the trivial deprecated `operator()` on this one extra platform is practically zero.
* Fix silly oversight.
* NVHPC 23.5.0 generates deprecation warnings. They are currently not treated as errors, but falling back to using `py::set_error()` to not have to deal with that distraction.
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Keto D. Zhang <keto.zhang@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
* Provide better type hints for a variety of generic types
* Makes better documentation
* tuple, dict, list, set, function
* Move to py::typing
* style: pre-commit fixes
* Update copyright line with correct year and actual author. The author information was copy-pasted from the git log output.
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add `npy_format_descriptor<PyObject *>` to enable `py::array_t<PyObject *>` to/from-python conversions.
* resolve clang-tidy warning
* Use existing constructor instead of adding a static method. Thanks @Skylion007 for pointing out.
* Add `format_descriptor<PyObject *>`
Trivial addition, but still in search for a meaningful test.
* Add test_format_descriptor_format
* Ensure the Eigen `type_caster`s do not segfault when loading arrays with dtype=object
* Use `static_assert()` `!std::is_pointer<>` to replace runtime guards.
* Add comments to explain how to check for ref-count bugs. (NO code changes.)
* Make the "Pointer types ... are not supported" message Eigen-specific, as suggested by @Lalaland. Move to new pybind11/eigen/common.h header.
* Change "format_descriptor_format" implementation as suggested by @Lalaland. Additional tests meant to ensure consistency between py::format_descriptor<>, np.array, np.format_parser turn out to be useful only to highlight long-standing inconsistencies.
* resolve clang-tidy warning
* Account for np.float128, np.complex256 not being available on Windows, in a future-proof way.
* Fully address i|q|l ambiguity (hopefully).
* Remove the new `np.format_parser()`-based test, it's much more distracting than useful.
* Use bi.itemsize to disambiguate "l" or "L"
* Use `py::detail::compare_buffer_info<T>::compare()` to validate the `format_descriptor<T>::format()` strings.
* Add `buffer_info::compare<T>` to make `detail::compare_buffer_info<T>::compare` more visible & accessible.
* silence clang-tidy warning
* pytest-compatible access to np.float128, np.complex256
* Revert "pytest-compatible access to np.float128, np.complex256"
This reverts commit e9a289c50f.
* Use `sizeof(long double) == sizeof(double)` instead of `std::is_same<>`
* Report skipped `long double` tests.
* Change the name of the new `buffer_info` member function to `item_type_is_equivalent_to`. Add comment defining "equivalent" by example.
* Change `item_type_is_equivalent_to<>()` from `static` function to member function, as suggested by @Lalaland
* First version adding `__notes__` to `error_already_set::what()` output.
* Fix trivial oversight (missing adjustment in existing test).
* Minor enhancements of new code.
* Re-enable `cmake --target cpptest -j 2`
* Revert "Re-enable `cmake --target cpptest -j 2`"
This reverts commit 60816285e9.
* Add general comment explaining why the `error_fetch_and_normalize` code is so unusual.
* Reproducer for property setter with return type that is not wrapped.
* Use `py::class_<OptionsBase>()` to work around the return value conversion issue.
* WIP drop_return_value
* Remove struct drop_return_value
* Introduce `return_value_policy::return_none` for use by setters.
* Add `is_setter` to attr.h and use from `.def_property()`
* Merge the new test into test_methods_and_attributes
* Remove return_none return_value_policy again.
* Fix oversight (NOLINTNEXTLINE placement).
* Simplification (for the better) found while searching for a way to resolve GCC build failures.
Example of failure resolved by this change:
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
```
cd /build/tests && /usr/bin/c++ -DPYBIND11_TEST_EIGEN -Dpybind11_tests_EXPORTS -I/mounted_pybind11/include -isystem /usr/include/python3.8 -isystem /build/_deps/eigen-src -g -std=c++17 -fPIC -fvisibility=hidden -Wall -Wextra -Wconversion -Wcast-qual -Wdeprecated -Wundef -Wnon-virtual-dtor -MD -MT tests/CMakeFiles/pybind11_tests.dir/test_buffers.cpp.o -MF CMakeFiles/pybind11_tests.dir/test_buffers.cpp.o.d -o CMakeFiles/pybind11_tests.dir/test_buffers.cpp.o -c /mounted_pybind11/tests/test_buffers.cpp
In file included from /mounted_pybind11/include/pybind11/stl.h:12,
from /mounted_pybind11/tests/test_buffers.cpp:10:
/mounted_pybind11/include/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property(const char*, const Getter&, const Setter&, const Extra& ...) [with Getter = pybind11::cpp_function; Setter = std::nullptr_t; Extra = {pybind11::return_value_policy}; type_ = pybind11::buffer_info; options = {}]’:
/mounted_pybind11/include/pybind11/pybind11.h:1716:58: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_readonly(const char*, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::return_value_policy}; type_ = pybind11::buffer_info; options = {}]’
/mounted_pybind11/include/pybind11/pybind11.h:1684:9: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_readonly(const char*, const D C::*, const Extra& ...) [with C = pybind11::buffer_info; D = long int; Extra = {}; type_ = pybind11::buffer_info; options = {}]’
/mounted_pybind11/tests/test_buffers.cpp:209:61: required from here
/mounted_pybind11/include/pybind11/pybind11.h:1740:25: error: call of overloaded ‘cpp_function(std::nullptr_t&, pybind11::is_setter)’ is ambiguous
1740 | name, fget, cpp_function(method_adaptor<type>(fset), is_setter()), extra...);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mounted_pybind11/include/pybind11/pybind11.h:101:5: note: candidate: ‘pybind11::cpp_function::cpp_function(Func&&, const Extra& ...) [with Func = std::nullptr_t&; Extra = {pybind11::is_setter}; <template-parameter-1-3> = void]’
101 | cpp_function(Func &&f, const Extra &...extra) {
| ^~~~~~~~~~~~
In file included from /mounted_pybind11/include/pybind11/stl.h:12,
from /mounted_pybind11/tests/test_buffers.cpp:10:
/mounted_pybind11/include/pybind11/pybind11.h:87:5: note: candidate: ‘pybind11::cpp_function::cpp_function(std::nullptr_t, const Extra& ...) [with Extra = {pybind11::is_setter}; std::nullptr_t = std::nullptr_t]’
87 | cpp_function(std::nullptr_t, const Extra &...) {}
| ^~~~~~~~~~~~
```
* Bug fix: obvious in hindsight. I thought the original version was incrementing the reference count for None, but no.
Discovered via many failing tests in the wild (10s of thousands).
It is very tricky to construct a meaningful unit test for this bug specifically. It's unlikely to come back, because 10s of thousands of tests will fail again.
* Add `type_caster<PyObject>` (tests are still incomplete).
* Fix oversight (`const PyObject *`).
* Ensure `type_caster<PyObject>` only works for `PyObject *`
* Move `is_same_ignoring_cvref` into `detail` namespace.
* Add test_cast_nullptr
* Change is_same_ignoring_cvref from variable template to using.
```
test_type_caster_pyobject_ptr.cpp:8:23: error: variable templates only available with ‘-std=c++14’ or ‘-std=gnu++14’ [-Werror]
8 | static constexpr bool is_same_ignoring_cvref = std::is_same<detail::remove_cvref_t<T>, U>::value;
| ^~~~~~~~~~~~~~~~~~~~~~
```
* Remove `return_value_policy::reference_internal` `keep_alive` feature (because of doubts about it actually being useful).
* Add missing test, fix bug (missing `throw error_already_set();`), various cosmetic changes.
* Move `type_caster<PyObject>` from test to new include (pybind11/type_caster_pyobject_ptr.h)
* Add new header file to CMakeLists.txt and tests/extra_python_package/test_files.py
* Backport changes from https://github.com/google/pywrapcc/pull/30021 to https://github.com/pybind/pybind11/pull/4601
* Fix oversight in test (to resolve a valgrind leak detection error) and add a related comment in cast.h.
No production code changes.
Make tests more sensitive by using `ValueHolder` instead of empty tuples and dicts.
Manual leak checks with `while True:` & top command repeated for all tests.
* Add tests for interop with stl.h `list_caster`
(No production code changes.)
* Bug fix in test. Minor comment enhancements.
* Change `type_caster<PyObject>::name` to `object`, as suggested by @Skylion007
* Expand comment for the new `T cast(const handle &handle)` [`T` = `PyObject *`]
* Add `T cast(object &&obj)` overload as suggested by @Skylion007
The original suggestion leads to `error: call to 'cast' is ambiguous` (full error message below), therefore SFINAE guarding is needed.
```
clang++ -o pybind11/tests/test_type_caster_pyobject_ptr.os -c -std=c++17 -fPIC -fvisibility=hidden -O0 -g -Wall -Wextra -Wconversion -Wcast-qual -Wdeprecated -Wundef -Wnon-virtual-dtor -Wunused-result -Werror -isystem /usr/include/python3.10 -isystem /usr/include/eigen3 -DPYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX -DPYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD_IF_AVAILABLE -DPYBIND11_TEST_BOOST -Ipybind11/include -I/usr/local/google/home/rwgk/forked/pybind11/include -I/usr/local/google/home/rwgk/clone/pybind11/include /usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_pyobject_ptr.cpp
In file included from /usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_pyobject_ptr.cpp:1:
In file included from /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/functional.h:12:
In file included from /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/pybind11.h:13:
In file included from /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/class.h:12:
In file included from /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/attr.h:14:
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/cast.h:1165:12: error: call to 'cast' is ambiguous
return pybind11::cast<T>(std::move(*this));
^~~~~~~~~~~~~~~~~
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/functional.h:109:70: note: in instantiation of function template specialization 'pybind11::object::cast<_object *>' requested here
return hfunc.f(std::forward<Args>(args)...).template cast<Return>();
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/functional.h:103:16: note: in instantiation of member function 'pybind11::detail::type_caster<std::function<_object *(int)>>::load(pybind11::handle, bool)::func_wrapper::operator()' requested here
struct func_wrapper {
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/cast.h:1456:47: note: in instantiation of member function 'pybind11::detail::type_caster<std::function<_object *(int)>>::load' requested here
if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is]))) {
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/cast.h:1434:50: note: in instantiation of function template specialization 'pybind11::detail::argument_loader<const std::function<_object *(int)> &, int>::load_impl_sequence<0UL, 1UL>' requested here
bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); }
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/pybind11.h:227:33: note: in instantiation of member function 'pybind11::detail::argument_loader<const std::function<_object *(int)> &, int>::load_args' requested here
if (!args_converter.load_args(call)) {
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/pybind11.h:101:9: note: in instantiation of function template specialization 'pybind11::cpp_function::initialize<(lambda at /usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_pyobject_ptr.cpp:50:9), _object *, const std::function<_object *(int)> &, int, pybind11::name, pybind11::scope, pybind11::sibling, pybind11::return_value_policy>' requested here
initialize(
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/pybind11.h:1163:22: note: in instantiation of function template specialization 'pybind11::cpp_function::cpp_function<(lambda at /usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_pyobject_ptr.cpp:50:9), pybind11::name, pybind11::scope, pybind11::sibling, pybind11::return_value_policy, void>' requested here
cpp_function func(std::forward<Func>(f),
^
/usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_pyobject_ptr.cpp:48:7: note: in instantiation of function template specialization 'pybind11::module_::def<(lambda at /usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_pyobject_ptr.cpp:50:9), pybind11::return_value_policy>' requested here
m.def(
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/cast.h:1077:3: note: candidate function [with T = _object *, $1 = 0]
T cast(object &&obj) {
^
/usr/local/google/home/rwgk/forked/pybind11/include/pybind11/cast.h:1149:1: note: candidate function [with T = _object *]
cast(object &&object) {
^
1 error generated.
```
* Testing
* Similar fix for std::vector
* Fix infinite recursion check:
1) Apply to is_copy_assignable additionally
2) Check infinite recursion for map-like types
* style: pre-commit fixes
* Optional commit that demonstrates the limitations of this PR
* Fix positioning of container bindings
The bindings were previously in a block that was only activated if numpy
was available.
* Suggestions from code review: API side
* Suggestions from code review: Test side
* Suggestions from code review
1) Renaming: is_recursive_container and
MutuallyRecursiveContainerPair(MV|VM)
2) Avoid ambiguous specializations of is_recursive_container
* Some little fixes
* Reordering of structs
* Add recursive checks for is_move_constructible
* Static testing for pybind11 type traits
* More precise checking of recursive types
Instead of a trait `is_recursive_container`, use a trait
`recursive_container_traits` with dependent type
`recursive_container_traits::type_to_check_recursively`.
So, instead of just checking if a type is recursive and then trying to
somehow deal with it, recursively-defined traits such as
is_move_constructible can now directly ask this trait where the
recursion should proceed.
* Review suggestions
1. Use std::conditional
2. Fix typo
* Remove leftover include from test
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>