2016-01-17 21:36:44 +00:00
|
|
|
/*
|
2017-05-09 17:50:34 +00:00
|
|
|
pybind11/attr.h: Infrastructure for processing custom
|
2016-01-17 21:36:44 +00:00
|
|
|
type and function attributes
|
|
|
|
|
2016-04-17 18:21:41 +00:00
|
|
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
All rights reserved. Use of this source code is governed by a
|
|
|
|
BSD-style license that can be found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-05-02 19:30:19 +00:00
|
|
|
#include "detail/common.h"
|
2016-01-17 21:36:44 +00:00
|
|
|
#include "cast.h"
|
|
|
|
|
2021-09-24 19:08:22 +00:00
|
|
|
#include <functional>
|
|
|
|
|
2020-07-08 22:14:41 +00:00
|
|
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2017-01-31 15:54:08 +00:00
|
|
|
/// \addtogroup annotations
|
|
|
|
/// @{
|
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Annotation for methods
|
2022-02-10 20:17:07 +00:00
|
|
|
struct is_method {
|
|
|
|
handle class_;
|
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
* Adding google-explicit-constructor to .clang-tidy
* clang-tidy explicit attr.h (all automatic)
* clang-tidy explicit cast.h (all automatic)
* clang-tidy detail/init.h (1 NOLINT)
* clang-tidy detail/type_caster_base.h (2 NOLINT)
* clang-tidy pybind11.h (7 NOLINT)
* clang-tidy detail/common.h (3 NOLINT)
* clang-tidy detail/descr.h (2 NOLINT)
* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)
* clang-tidy eigen.h (7 NOLINT, 0 explicit)
* Adding 2 explicit in functional.h
* Adding 4 explicit in iostream.h
* clang-tidy numpy.h (1 NOLINT, 1 explicit)
* clang-tidy embed.h (0 NOLINT, 1 explicit)
* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)
* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)
* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)
* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)
* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)
* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)
* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/object.h (0 NOLINT, 2 explicit)
* clang-tidy batch of fully automatic fixes.
* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
2021-09-09 01:53:38 +00:00
|
|
|
explicit is_method(const handle &c) : class_(c) {}
|
|
|
|
};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
Elide to-python conversion of setter return values (#4621)
* 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.
2023-05-08 17:13:54 +00:00
|
|
|
/// Annotation for setters
|
|
|
|
struct is_setter {};
|
|
|
|
|
2016-09-10 06:28:37 +00:00
|
|
|
/// Annotation for operators
|
2022-02-10 20:17:07 +00:00
|
|
|
struct is_operator {};
|
2016-09-10 06:28:37 +00:00
|
|
|
|
2020-04-05 06:34:00 +00:00
|
|
|
/// Annotation for classes that cannot be subclassed
|
2022-02-10 20:17:07 +00:00
|
|
|
struct is_final {};
|
2020-04-05 06:34:00 +00:00
|
|
|
|
2016-02-04 22:02:07 +00:00
|
|
|
/// Annotation for parent scope
|
2022-02-10 20:17:07 +00:00
|
|
|
struct scope {
|
|
|
|
handle value;
|
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
* Adding google-explicit-constructor to .clang-tidy
* clang-tidy explicit attr.h (all automatic)
* clang-tidy explicit cast.h (all automatic)
* clang-tidy detail/init.h (1 NOLINT)
* clang-tidy detail/type_caster_base.h (2 NOLINT)
* clang-tidy pybind11.h (7 NOLINT)
* clang-tidy detail/common.h (3 NOLINT)
* clang-tidy detail/descr.h (2 NOLINT)
* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)
* clang-tidy eigen.h (7 NOLINT, 0 explicit)
* Adding 2 explicit in functional.h
* Adding 4 explicit in iostream.h
* clang-tidy numpy.h (1 NOLINT, 1 explicit)
* clang-tidy embed.h (0 NOLINT, 1 explicit)
* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)
* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)
* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)
* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)
* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)
* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)
* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/object.h (0 NOLINT, 2 explicit)
* clang-tidy batch of fully automatic fixes.
* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
2021-09-09 01:53:38 +00:00
|
|
|
explicit scope(const handle &s) : value(s) {}
|
|
|
|
};
|
2016-02-04 22:02:07 +00:00
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Annotation for documentation
|
2022-02-10 20:17:07 +00:00
|
|
|
struct doc {
|
|
|
|
const char *value;
|
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
* Adding google-explicit-constructor to .clang-tidy
* clang-tidy explicit attr.h (all automatic)
* clang-tidy explicit cast.h (all automatic)
* clang-tidy detail/init.h (1 NOLINT)
* clang-tidy detail/type_caster_base.h (2 NOLINT)
* clang-tidy pybind11.h (7 NOLINT)
* clang-tidy detail/common.h (3 NOLINT)
* clang-tidy detail/descr.h (2 NOLINT)
* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)
* clang-tidy eigen.h (7 NOLINT, 0 explicit)
* Adding 2 explicit in functional.h
* Adding 4 explicit in iostream.h
* clang-tidy numpy.h (1 NOLINT, 1 explicit)
* clang-tidy embed.h (0 NOLINT, 1 explicit)
* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)
* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)
* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)
* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)
* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)
* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)
* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/object.h (0 NOLINT, 2 explicit)
* clang-tidy batch of fully automatic fixes.
* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
2021-09-09 01:53:38 +00:00
|
|
|
explicit doc(const char *value) : value(value) {}
|
|
|
|
};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Annotation for function names
|
2022-02-10 20:17:07 +00:00
|
|
|
struct name {
|
|
|
|
const char *value;
|
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
* Adding google-explicit-constructor to .clang-tidy
* clang-tidy explicit attr.h (all automatic)
* clang-tidy explicit cast.h (all automatic)
* clang-tidy detail/init.h (1 NOLINT)
* clang-tidy detail/type_caster_base.h (2 NOLINT)
* clang-tidy pybind11.h (7 NOLINT)
* clang-tidy detail/common.h (3 NOLINT)
* clang-tidy detail/descr.h (2 NOLINT)
* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)
* clang-tidy eigen.h (7 NOLINT, 0 explicit)
* Adding 2 explicit in functional.h
* Adding 4 explicit in iostream.h
* clang-tidy numpy.h (1 NOLINT, 1 explicit)
* clang-tidy embed.h (0 NOLINT, 1 explicit)
* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)
* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)
* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)
* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)
* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)
* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)
* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/object.h (0 NOLINT, 2 explicit)
* clang-tidy batch of fully automatic fixes.
* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
2021-09-09 01:53:38 +00:00
|
|
|
explicit name(const char *value) : value(value) {}
|
|
|
|
};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Annotation indicating that a function is an overload associated with a given "sibling"
|
2022-02-10 20:17:07 +00:00
|
|
|
struct sibling {
|
|
|
|
handle value;
|
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
* Adding google-explicit-constructor to .clang-tidy
* clang-tidy explicit attr.h (all automatic)
* clang-tidy explicit cast.h (all automatic)
* clang-tidy detail/init.h (1 NOLINT)
* clang-tidy detail/type_caster_base.h (2 NOLINT)
* clang-tidy pybind11.h (7 NOLINT)
* clang-tidy detail/common.h (3 NOLINT)
* clang-tidy detail/descr.h (2 NOLINT)
* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)
* clang-tidy eigen.h (7 NOLINT, 0 explicit)
* Adding 2 explicit in functional.h
* Adding 4 explicit in iostream.h
* clang-tidy numpy.h (1 NOLINT, 1 explicit)
* clang-tidy embed.h (0 NOLINT, 1 explicit)
* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)
* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)
* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)
* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)
* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)
* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)
* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/object.h (0 NOLINT, 2 explicit)
* clang-tidy batch of fully automatic fixes.
* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
2021-09-09 01:53:38 +00:00
|
|
|
explicit sibling(const handle &value) : value(value.ptr()) {}
|
|
|
|
};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Annotation indicating that a class derives from another given type
|
2022-02-10 20:17:07 +00:00
|
|
|
template <typename T>
|
|
|
|
struct base {
|
2020-09-11 03:15:22 +00:00
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
PYBIND11_DEPRECATED(
|
|
|
|
"base<T>() was deprecated in favor of specifying 'T' as a template argument to class_")
|
Dropping MSVC 2015 (#3722)
* Changing `_MSC_VER` guard to `< 1910` (dropping MSVC 2015).
* Removing MSVC 2015 from ci.yml, and .appveyor.yml entirely.
* Bringing back .appveyor.yml from master.
* appveyor Visual Studio 2017
* 1st manual pass, builds & tests with unix_clang, before pre-commit.
* After clang-format (via pre-commit).
* Manual pass looking for "2015", builds & tests with unix_clang, before pre-commit.
* Backtracking for include/pybind11 changes in previous commit.
git checkout d07865846c7d31dd61111e6df801864327b65070 include/pybind11/attr.h include/pybind11/detail/common.h include/pybind11/functional.h
--------------------
CI #4160 errors observed:
https://github.com/pybind/pybind11/pull/3722/commits/2a26873727214c5f1e159cba98f5c625b908381a
https://github.com/pybind/pybind11/runs/5168332130?check_suite_focus=true
$ grep ' error C' *.txt | sed 's/2022-02-12[^ ]*//' | sed 's/^[0-9][0-9]*//' | sed 's/^.*\.txt: //' | sort | uniqD:\a\pybind11\pybind11\include\pybind11\cast.h(1364,1): error C2752: 'pybind11::detail::type_caster<Eigen::Ref<Eigen::Vector3f,0,pybind11::EigenDStride>,void>': more than one partial specialization matches the template argument list [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\cross_module_gil_utils.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\pybind11_cross_module_tests.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\test_embed\external_module.vcxproj]
D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
$ grep ': error C2737' *.txt | sed 's/^.*MSVC//' | sed 's/___.*//' | sort | uniq
_2017
$ grep ': error C2752' *.txt
3______3.8_____MSVC_2019_____x86_-DCMAKE_CXX_STANDARD=17.txt:2022-02-12T16:12:45.9921122Z D:\a\pybind11\pybind11\include\pybind11\cast.h(1364,1): error C2752: 'pybind11::detail::type_caster<Eigen::Ref<Eigen::Vector3f,0,pybind11::EigenDStride>,void>': more than one partial specialization matches the template argument list [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
$ grep ': fatal error C1001:' *.txt
10______pypy-3.8-v7.3.7_____windows-2022_____x64.txt:2022-02-12T16:12:56.3163683Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
1______3.6_____MSVC_2019_____x86.txt:2022-02-12T16:12:47.6774625Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
16______3.6_____windows-latest_____x64_-DPYBIND11_FINDPYTHON=ON.txt:2022-02-12T16:12:27.0556151Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
17______3.9_____windows-2019_____x64.txt:2022-02-12T16:12:30.3822566Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
2______3.7_____MSVC_2019_____x86.txt:2022-02-12T16:12:38.7018911Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
6______3.6_____windows-2022_____x64.txt:2022-02-12T16:12:00.4513642Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
7______3.9_____windows-2022_____x64.txt:2022-02-12T16:11:43.6306160Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
8______3.10_____windows-2022_____x64.txt:2022-02-12T16:11:49.9589644Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
9______pypy-3.7-v7.3.7_____windows-2022_____x64.txt:2022-02-12T16:11:53.7912112Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
* common.h: is_template_base_of
* Re-applying 4 changes from 2a26873727214c5f1e159cba98f5c625b908381a that work universally.
* `overload_cast = {};` only for MSVC 2017 and Clang 5
* Refining condition for using is_template_base_of workaround.
* Undoing MSVC 2015 workaround in test_constants_and_functions.cpp
* CentOS7: silence_unused_warnings
* Tweaks in response to reviews.
* Adding windows-2022 C++20
* Trying another way of adding windows-2022 C++20
2022-02-14 19:36:22 +00:00
|
|
|
base() = default;
|
2016-09-12 03:03:20 +00:00
|
|
|
};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Keep patient alive while nurse lives
|
2022-02-10 20:17:07 +00:00
|
|
|
template <size_t Nurse, size_t Patient>
|
|
|
|
struct keep_alive {};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2016-09-11 11:00:40 +00:00
|
|
|
/// Annotation indicating that a class is involved in a multiple inheritance relationship
|
2022-02-10 20:17:07 +00:00
|
|
|
struct multiple_inheritance {};
|
2016-09-11 11:00:40 +00:00
|
|
|
|
2016-10-10 23:12:48 +00:00
|
|
|
/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class
|
2022-02-10 20:17:07 +00:00
|
|
|
struct dynamic_attr {};
|
2016-10-10 23:12:48 +00:00
|
|
|
|
2016-12-16 14:00:46 +00:00
|
|
|
/// Annotation which enables the buffer protocol for a type
|
2022-02-10 20:17:07 +00:00
|
|
|
struct buffer_protocol {};
|
2016-12-16 14:00:46 +00:00
|
|
|
|
|
|
|
/// Annotation which requests that a special metaclass is created for a type
|
2017-02-16 22:02:56 +00:00
|
|
|
struct metaclass {
|
|
|
|
handle value;
|
|
|
|
|
|
|
|
PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
|
Dropping MSVC 2015 (#3722)
* Changing `_MSC_VER` guard to `< 1910` (dropping MSVC 2015).
* Removing MSVC 2015 from ci.yml, and .appveyor.yml entirely.
* Bringing back .appveyor.yml from master.
* appveyor Visual Studio 2017
* 1st manual pass, builds & tests with unix_clang, before pre-commit.
* After clang-format (via pre-commit).
* Manual pass looking for "2015", builds & tests with unix_clang, before pre-commit.
* Backtracking for include/pybind11 changes in previous commit.
git checkout d07865846c7d31dd61111e6df801864327b65070 include/pybind11/attr.h include/pybind11/detail/common.h include/pybind11/functional.h
--------------------
CI #4160 errors observed:
https://github.com/pybind/pybind11/pull/3722/commits/2a26873727214c5f1e159cba98f5c625b908381a
https://github.com/pybind/pybind11/runs/5168332130?check_suite_focus=true
$ grep ' error C' *.txt | sed 's/2022-02-12[^ ]*//' | sed 's/^[0-9][0-9]*//' | sed 's/^.*\.txt: //' | sort | uniqD:\a\pybind11\pybind11\include\pybind11\cast.h(1364,1): error C2752: 'pybind11::detail::type_caster<Eigen::Ref<Eigen::Vector3f,0,pybind11::EigenDStride>,void>': more than one partial specialization matches the template argument list [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\cross_module_gil_utils.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\pybind11_cross_module_tests.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
d:\a\pybind11\pybind11\include\pybind11\detail/common.h(1023): error C2737: 'pybind11::overload_cast': 'constexpr' object must be initialized [D:\a\pybind11\pybind11\build\tests\test_embed\external_module.vcxproj]
D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
$ grep ': error C2737' *.txt | sed 's/^.*MSVC//' | sed 's/___.*//' | sort | uniq
_2017
$ grep ': error C2752' *.txt
3______3.8_____MSVC_2019_____x86_-DCMAKE_CXX_STANDARD=17.txt:2022-02-12T16:12:45.9921122Z D:\a\pybind11\pybind11\include\pybind11\cast.h(1364,1): error C2752: 'pybind11::detail::type_caster<Eigen::Ref<Eigen::Vector3f,0,pybind11::EigenDStride>,void>': more than one partial specialization matches the template argument list [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
$ grep ': fatal error C1001:' *.txt
10______pypy-3.8-v7.3.7_____windows-2022_____x64.txt:2022-02-12T16:12:56.3163683Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
1______3.6_____MSVC_2019_____x86.txt:2022-02-12T16:12:47.6774625Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
16______3.6_____windows-latest_____x64_-DPYBIND11_FINDPYTHON=ON.txt:2022-02-12T16:12:27.0556151Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
17______3.9_____windows-2019_____x64.txt:2022-02-12T16:12:30.3822566Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
2______3.7_____MSVC_2019_____x86.txt:2022-02-12T16:12:38.7018911Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
6______3.6_____windows-2022_____x64.txt:2022-02-12T16:12:00.4513642Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
7______3.9_____windows-2022_____x64.txt:2022-02-12T16:11:43.6306160Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
8______3.10_____windows-2022_____x64.txt:2022-02-12T16:11:49.9589644Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
9______pypy-3.7-v7.3.7_____windows-2022_____x64.txt:2022-02-12T16:11:53.7912112Z D:\a\pybind11\pybind11\include\pybind11\detail/common.h(624): fatal error C1001: Internal compiler error. [D:\a\pybind11\pybind11\tests\pybind11_tests.vcxproj]
* common.h: is_template_base_of
* Re-applying 4 changes from 2a26873727214c5f1e159cba98f5c625b908381a that work universally.
* `overload_cast = {};` only for MSVC 2017 and Clang 5
* Refining condition for using is_template_base_of workaround.
* Undoing MSVC 2015 workaround in test_constants_and_functions.cpp
* CentOS7: silence_unused_warnings
* Tweaks in response to reviews.
* Adding windows-2022 C++20
* Trying another way of adding windows-2022 C++20
2022-02-14 19:36:22 +00:00
|
|
|
metaclass() = default;
|
2017-02-16 22:02:56 +00:00
|
|
|
|
|
|
|
/// Override pybind11's default metaclass
|
2022-02-10 20:17:07 +00:00
|
|
|
explicit metaclass(handle value) : value(value) {}
|
2017-02-16 22:02:56 +00:00
|
|
|
};
|
2016-12-16 14:00:46 +00:00
|
|
|
|
2021-09-24 19:08:22 +00:00
|
|
|
/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that
|
|
|
|
/// may be used to customize the Python type.
|
|
|
|
///
|
|
|
|
/// The callback is invoked immediately before `PyType_Ready`.
|
|
|
|
///
|
|
|
|
/// Note: This is an advanced interface, and uses of it may require changes to
|
|
|
|
/// work with later versions of pybind11. You may wish to consult the
|
|
|
|
/// implementation of `make_new_python_type` in `detail/classes.h` to understand
|
|
|
|
/// the context in which the callback will be run.
|
|
|
|
struct custom_type_setup {
|
|
|
|
using callback = std::function<void(PyHeapTypeObject *heap_type)>;
|
|
|
|
|
|
|
|
explicit custom_type_setup(callback value) : value(std::move(value)) {}
|
|
|
|
|
|
|
|
callback value;
|
|
|
|
};
|
|
|
|
|
2017-07-29 02:03:44 +00:00
|
|
|
/// Annotation that marks a class as local to the module:
|
2022-02-10 20:17:07 +00:00
|
|
|
struct module_local {
|
|
|
|
const bool value;
|
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
* Adding google-explicit-constructor to .clang-tidy
* clang-tidy explicit attr.h (all automatic)
* clang-tidy explicit cast.h (all automatic)
* clang-tidy detail/init.h (1 NOLINT)
* clang-tidy detail/type_caster_base.h (2 NOLINT)
* clang-tidy pybind11.h (7 NOLINT)
* clang-tidy detail/common.h (3 NOLINT)
* clang-tidy detail/descr.h (2 NOLINT)
* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)
* clang-tidy eigen.h (7 NOLINT, 0 explicit)
* Adding 2 explicit in functional.h
* Adding 4 explicit in iostream.h
* clang-tidy numpy.h (1 NOLINT, 1 explicit)
* clang-tidy embed.h (0 NOLINT, 1 explicit)
* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)
* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)
* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)
* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)
* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)
* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)
* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)
* clang-tidy tests/object.h (0 NOLINT, 2 explicit)
* clang-tidy batch of fully automatic fixes.
* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
2021-09-09 01:53:38 +00:00
|
|
|
constexpr explicit module_local(bool v = true) : value(v) {}
|
|
|
|
};
|
2017-07-29 02:03:44 +00:00
|
|
|
|
2016-11-17 22:24:47 +00:00
|
|
|
/// Annotation to mark enums as an arithmetic type
|
2022-02-10 20:17:07 +00:00
|
|
|
struct arithmetic {};
|
2016-11-17 22:24:47 +00:00
|
|
|
|
2020-10-06 02:36:33 +00:00
|
|
|
/// Mark a function for addition at the beginning of the existing overload chain instead of the end
|
2022-02-10 20:17:07 +00:00
|
|
|
struct prepend {};
|
2020-10-06 02:36:33 +00:00
|
|
|
|
2017-03-16 10:22:26 +00:00
|
|
|
/** \rst
|
|
|
|
A call policy which places one or more guard variables (``Ts...``) around the function call.
|
|
|
|
|
|
|
|
For example, this definition:
|
|
|
|
|
|
|
|
.. code-block:: cpp
|
|
|
|
|
|
|
|
m.def("foo", foo, py::call_guard<T>());
|
|
|
|
|
|
|
|
is equivalent to the following pseudocode:
|
|
|
|
|
|
|
|
.. code-block:: cpp
|
|
|
|
|
|
|
|
m.def("foo", [](args...) {
|
|
|
|
T scope_guard;
|
|
|
|
return foo(args...); // forwarded arguments
|
|
|
|
});
|
|
|
|
\endrst */
|
2022-02-10 20:17:07 +00:00
|
|
|
template <typename... Ts>
|
|
|
|
struct call_guard;
|
2017-03-16 10:22:26 +00:00
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct call_guard<> {
|
|
|
|
using type = detail::void_type;
|
|
|
|
};
|
2017-03-16 10:22:26 +00:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct call_guard<T> {
|
|
|
|
static_assert(std::is_default_constructible<T>::value,
|
|
|
|
"The guard type must be default constructible");
|
|
|
|
|
|
|
|
using type = T;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename... Ts>
|
|
|
|
struct call_guard<T, Ts...> {
|
|
|
|
struct type {
|
|
|
|
T guard{}; // Compose multiple guard types with left-to-right default-constructor order
|
|
|
|
typename call_guard<Ts...>::type next{};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2017-01-31 15:54:08 +00:00
|
|
|
/// @} annotations
|
|
|
|
|
2020-07-08 22:14:41 +00:00
|
|
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
2016-01-17 21:36:44 +00:00
|
|
|
/* Forward declarations */
|
|
|
|
enum op_id : int;
|
|
|
|
enum op_type : int;
|
|
|
|
struct undefined_t;
|
2022-02-10 20:17:07 +00:00
|
|
|
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>
|
|
|
|
struct op_;
|
PYBIND11_NOINLINE-related cleanup. (#3179)
* Removing pragma for GCC -Wattributes, fixing forward declarations.
* Introducing PYBIND11_NOINLINE_FWD to deal with CUDA, GCC7, GCC8.
* Updating PYBIND11_NOINLINE_DCL in Doxyfile.
* Trying noinline, noinline for {CUDA, GCC7, GCC8}
* Trying noinline, inline for {CUDA, GCC7, GCC8}
* Adding GCC -Wattributes `pragma` in 3 header files.
* Introducing PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED, used in 9 header files.
* Removing ICC pragma 2196, to see if it is still needed.
* Trying noinline, noinline for ICC
* Trying noinline, inline for ICC
* Restoring ICC pragma 2196, introducing PYBIND11_NOINLINE_FORCED, defined for testing.
* Removing code accidentally left in (was for experimentation only).
* Removing one-time-test define.
* Removing PYBIND11_NOINLINE_FWD macro (after learning that it makes no sense).
* Testing with PYBIND11_NOINLINE_DISABLED. Minor non-functional enhancements.
* Removing #define PYBIND11_NOINLINE_DISABLED (test was successful).
* Removing PYBIND11_NOINLINE_FORCED and enhancing comments for PYBIND11_NOINLINE.
* WIP stripping back
* Making -Wattributes pragma in pybind11 specific to GCC7, GCC8, CUDA.
2021-08-09 17:10:38 +00:00
|
|
|
void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Internal data structure which holds metadata about a keyword argument
|
|
|
|
struct argument_record {
|
|
|
|
const char *name; ///< Argument name
|
|
|
|
const char *descr; ///< Human-readable version of the argument value
|
|
|
|
handle value; ///< Associated Python object
|
Add support for non-converting arguments
This adds support for controlling the `convert` flag of arguments
through the py::arg annotation. This then allows arguments to be
flagged as non-converting, which the type_caster is able to use to
request different behaviour.
Currently, AFAICS `convert` is only used for type converters of regular
pybind11-registered types; all of the other core type_casters ignore it.
We can, however, repurpose it to control internal conversion of
converters like Eigen and `array`: most usefully to give callers a way
to disable the conversion that would otherwise occur when a
`Eigen::Ref<const Eigen::Matrix>` argument is passed a numpy array that
requires conversion (either because it has an incompatible stride or the
wrong dtype).
Specifying a noconvert looks like one of these:
m.def("f1", &f, "a"_a.noconvert() = "default"); // Named, default, noconvert
m.def("f2", &f, "a"_a.noconvert()); // Named, no default, no converting
m.def("f3", &f, py::arg().noconvert()); // Unnamed, no default, no converting
(The last part--being able to declare a py::arg without a name--is new:
previous py::arg() only accepted named keyword arguments).
Such an non-convert argument is then passed `convert = false` by the
type caster when loading the argument. Whether this has an effect is up
to the type caster itself, but as mentioned above, this would be
extremely helpful for the Eigen support to give a nicer way to specify
a "no-copy" mode than the custom wrapper in the current PR, and
moreover isn't an Eigen-specific hack.
2017-01-23 08:50:00 +00:00
|
|
|
bool convert : 1; ///< True if the argument is allowed to convert when loading
|
2017-05-17 15:55:43 +00:00
|
|
|
bool none : 1; ///< True if None is allowed when loading
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2017-05-17 15:55:43 +00:00
|
|
|
argument_record(const char *name, const char *descr, handle value, bool convert, bool none)
|
2022-02-10 20:17:07 +00:00
|
|
|
: name(name), descr(descr), value(value), convert(convert), none(none) {}
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
/// Internal data structure which holds metadata about a bound function (signature, overloads,
|
|
|
|
/// etc.)
|
2016-01-17 21:36:44 +00:00
|
|
|
struct function_record {
|
2016-09-10 06:28:37 +00:00
|
|
|
function_record()
|
2017-08-17 00:01:32 +00:00
|
|
|
: is_constructor(false), is_new_style_constructor(false), is_stateless(false),
|
Elide to-python conversion of setter return values (#4621)
* 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.
2023-05-08 17:13:54 +00:00
|
|
|
is_operator(false), is_method(false), is_setter(false), has_args(false),
|
|
|
|
has_kwargs(false), prepend(false) {}
|
2016-09-10 06:28:37 +00:00
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Function name
|
|
|
|
char *name = nullptr; /* why no C++ strings? They generate heavier code.. */
|
|
|
|
|
|
|
|
// User-specified documentation string
|
|
|
|
char *doc = nullptr;
|
|
|
|
|
|
|
|
/// Human-readable version of the function signature
|
|
|
|
char *signature = nullptr;
|
|
|
|
|
|
|
|
/// List of registered keyword arguments
|
|
|
|
std::vector<argument_record> args;
|
|
|
|
|
|
|
|
/// Pointer to lambda function which converts arguments and performs the actual call
|
2022-02-10 20:17:07 +00:00
|
|
|
handle (*impl)(function_call &) = nullptr;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Storage for the wrapped function pointer and captured data, if any
|
2022-02-10 20:17:07 +00:00
|
|
|
void *data[3] = {};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Pointer to custom destructor for 'data' (if needed)
|
2022-02-10 20:17:07 +00:00
|
|
|
void (*free_data)(function_record *ptr) = nullptr;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Return value policy associated with this function
|
|
|
|
return_value_policy policy = return_value_policy::automatic;
|
|
|
|
|
|
|
|
/// True if name == '__init__'
|
2016-05-10 14:59:01 +00:00
|
|
|
bool is_constructor : 1;
|
|
|
|
|
2017-08-17 00:01:32 +00:00
|
|
|
/// True if this is a new-style `__init__` defined in `detail/init.h`
|
|
|
|
bool is_new_style_constructor : 1;
|
|
|
|
|
2016-07-10 08:13:18 +00:00
|
|
|
/// True if this is a stateless function pointer
|
|
|
|
bool is_stateless : 1;
|
|
|
|
|
2016-09-10 06:28:37 +00:00
|
|
|
/// True if this is an operator (__add__), etc.
|
|
|
|
bool is_operator : 1;
|
|
|
|
|
2017-12-23 22:56:07 +00:00
|
|
|
/// True if this is a method
|
|
|
|
bool is_method : 1;
|
|
|
|
|
Elide to-python conversion of setter return values (#4621)
* 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.
2023-05-08 17:13:54 +00:00
|
|
|
/// True if this is a setter
|
|
|
|
bool is_setter : 1;
|
|
|
|
|
2016-05-10 14:59:01 +00:00
|
|
|
/// True if the function has a '*args' argument
|
|
|
|
bool has_args : 1;
|
|
|
|
|
|
|
|
/// True if the function has a '**kwargs' argument
|
|
|
|
bool has_kwargs : 1;
|
|
|
|
|
2020-10-06 02:36:33 +00:00
|
|
|
/// True if this function is to be inserted at the beginning of the overload resolution chain
|
|
|
|
bool prepend : 1;
|
|
|
|
|
2017-01-22 04:42:14 +00:00
|
|
|
/// Number of arguments (including py::args and/or py::kwargs, if present)
|
Add support for non-converting arguments
This adds support for controlling the `convert` flag of arguments
through the py::arg annotation. This then allows arguments to be
flagged as non-converting, which the type_caster is able to use to
request different behaviour.
Currently, AFAICS `convert` is only used for type converters of regular
pybind11-registered types; all of the other core type_casters ignore it.
We can, however, repurpose it to control internal conversion of
converters like Eigen and `array`: most usefully to give callers a way
to disable the conversion that would otherwise occur when a
`Eigen::Ref<const Eigen::Matrix>` argument is passed a numpy array that
requires conversion (either because it has an incompatible stride or the
wrong dtype).
Specifying a noconvert looks like one of these:
m.def("f1", &f, "a"_a.noconvert() = "default"); // Named, default, noconvert
m.def("f2", &f, "a"_a.noconvert()); // Named, no default, no converting
m.def("f3", &f, py::arg().noconvert()); // Unnamed, no default, no converting
(The last part--being able to declare a py::arg without a name--is new:
previous py::arg() only accepted named keyword arguments).
Such an non-convert argument is then passed `convert = false` by the
type caster when loading the argument. Whether this has an effect is up
to the type caster itself, but as mentioned above, this would be
extremely helpful for the Eigen support to give a nicer way to specify
a "no-copy" mode than the custom wrapper in the current PR, and
moreover isn't an Eigen-specific hack.
2017-01-23 08:50:00 +00:00
|
|
|
std::uint16_t nargs;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
feat: allow kw-only args after a py::args (#3402)
* Simply has_kw_only_args handling
This simplifies tracking the number of kw-only args by instead tracking
the number of positional arguments (which is really what we care about
everywhere this is used).
* Allow keyword-only arguments to follow py::args
This removes the constraint that py::args has to be last (or
second-last, with py::kwargs) and instead makes py::args imply
py::kw_only for any remaining arguments, allowing you to bind a function
that works the same way as a Python function such as:
def f(a, *args, b):
return a * b + sum(args)
f(10, 1, 2, 3, b=20) # == 206
With this change, you can bind such a function using:
m.def("f", [](int a, py::args args, int b) { /* ... */ },
"a"_a, "b"_a);
Or, to be more explicit about the keyword-only arguments:
m.def("g", [](int a, py::args args, int b) { /* ... */ },
"a"_a, py::kw_only{}, "b"_a);
(The only difference between the two is that the latter will fail at
binding time if the `kw_only{}` doesn't match the `py::args` position).
This doesn't affect backwards compatibility at all because, currently,
you can't have a py::args anywhere except the end/2nd-last.
* Take args/kwargs by const lvalue ref
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-29 03:16:55 +00:00
|
|
|
/// Number of leading positional arguments, which are terminated by a py::args or py::kwargs
|
|
|
|
/// argument or by a py::kw_only annotation.
|
|
|
|
std::uint16_t nargs_pos = 0;
|
2020-09-05 00:02:05 +00:00
|
|
|
|
|
|
|
/// Number of leading arguments (counted in `nargs`) that are positional-only
|
|
|
|
std::uint16_t nargs_pos_only = 0;
|
2017-12-23 22:56:07 +00:00
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Python method object
|
|
|
|
PyMethodDef *def = nullptr;
|
|
|
|
|
2016-02-04 22:02:07 +00:00
|
|
|
/// Python handle to the parent scope (a class or a module)
|
|
|
|
handle scope;
|
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Python handle to the sibling function representing an overload chain
|
|
|
|
handle sibling;
|
|
|
|
|
|
|
|
/// Pointer to next overload
|
|
|
|
function_record *next = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Special data structure which (temporarily) holds metadata about a bound class
|
|
|
|
struct type_record {
|
2016-12-16 14:00:46 +00:00
|
|
|
PYBIND11_NOINLINE type_record()
|
2019-06-10 20:02:40 +00:00
|
|
|
: multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),
|
2022-02-10 20:17:07 +00:00
|
|
|
default_holder(true), module_local(false), is_final(false) {}
|
2016-09-11 11:00:40 +00:00
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Handle to the parent scope
|
|
|
|
handle scope;
|
|
|
|
|
|
|
|
/// Name of the class
|
|
|
|
const char *name = nullptr;
|
|
|
|
|
|
|
|
// Pointer to RTTI type_info data structure
|
|
|
|
const std::type_info *type = nullptr;
|
|
|
|
|
|
|
|
/// How large is the underlying C++ type?
|
|
|
|
size_t type_size = 0;
|
|
|
|
|
2018-11-09 19:14:53 +00:00
|
|
|
/// What is the alignment of the underlying C++ type?
|
|
|
|
size_t type_align = 0;
|
|
|
|
|
2017-02-23 02:36:09 +00:00
|
|
|
/// How large is the type's holder?
|
|
|
|
size_t holder_size = 0;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2017-03-21 00:15:20 +00:00
|
|
|
/// The global operator new can be overridden with a class-specific variant
|
2018-11-09 19:14:53 +00:00
|
|
|
void *(*operator_new)(size_t) = nullptr;
|
2017-03-21 00:15:20 +00:00
|
|
|
|
2017-07-25 04:53:23 +00:00
|
|
|
/// Function pointer to class_<..>::init_instance
|
|
|
|
void (*init_instance)(instance *, const void *) = nullptr;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Function pointer to class_<..>::dealloc
|
Allow binding factory functions as constructors
This allows you to use:
cls.def(py::init(&factory_function));
where `factory_function` returns a pointer, holder, or value of the
class type (or a derived type). Various compile-time checks
(static_asserts) are performed to ensure the function is valid, and
various run-time type checks where necessary.
Some other details of this feature:
- The `py::init` name doesn't conflict with the templated no-argument
`py::init<...>()`, but keeps the naming consistent: the existing
templated, no-argument one wraps constructors, the no-template,
function-argument one wraps factory functions.
- If returning a CppClass (whether by value or pointer) when an CppAlias
is required (i.e. python-side inheritance and a declared alias), a
dynamic_cast to the alias is attempted (for the pointer version); if
it fails, or if returned by value, an Alias(Class &&) constructor
is invoked. If this constructor doesn't exist, a runtime error occurs.
- for holder returns when an alias is required, we try a dynamic_cast of
the wrapped pointer to the alias to see if it is already an alias
instance; if it isn't, we raise an error.
- `py::init(class_factory, alias_factory)` is also available that takes
two factories: the first is called when an alias is not needed, the
second when it is.
- Reimplement factory instance clearing. The previous implementation
failed under python-side multiple inheritance: *each* inherited
type's factory init would clear the instance instead of only setting
its own type value. The new implementation here clears just the
relevant value pointer.
- dealloc is updated to explicitly set the leftover value pointer to
nullptr and the `holder_constructed` flag to false so that it can be
used to clear preallocated value without needing to rebuild the
instance internals data.
- Added various tests to test out new allocation/deallocation code.
- With preallocation now done lazily, init factory holders can
completely avoid the extra overhead of needing an extra
allocation/deallocation.
- Updated documentation to make factory constructors the default
advanced constructor style.
- If an `__init__` is called a second time, we have two choices: we can
throw away the first instance, replacing it with the second; or we can
ignore the second call. The latter is slightly easier, so do that.
2017-06-13 01:52:48 +00:00
|
|
|
void (*dealloc)(detail::value_and_holder &) = nullptr;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2016-09-11 11:00:40 +00:00
|
|
|
/// List of base classes of the newly created type
|
|
|
|
list bases;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Optional docstring
|
|
|
|
const char *doc = nullptr;
|
2016-09-11 11:00:40 +00:00
|
|
|
|
2017-02-16 22:02:56 +00:00
|
|
|
/// Custom metaclass (optional)
|
|
|
|
handle metaclass;
|
|
|
|
|
2021-09-24 19:08:22 +00:00
|
|
|
/// Custom type setup.
|
|
|
|
custom_type_setup::callback custom_type_setup_callback;
|
|
|
|
|
2016-09-11 11:00:40 +00:00
|
|
|
/// Multiple inheritance marker
|
2016-12-16 14:00:46 +00:00
|
|
|
bool multiple_inheritance : 1;
|
2016-09-11 11:00:40 +00:00
|
|
|
|
2016-10-10 23:12:48 +00:00
|
|
|
/// Does the class manage a __dict__?
|
2016-12-16 14:00:46 +00:00
|
|
|
bool dynamic_attr : 1;
|
|
|
|
|
|
|
|
/// Does the class implement the buffer protocol?
|
|
|
|
bool buffer_protocol : 1;
|
|
|
|
|
2017-01-31 15:52:11 +00:00
|
|
|
/// Is the default (unique_ptr) holder type used?
|
|
|
|
bool default_holder : 1;
|
|
|
|
|
2017-07-29 02:03:44 +00:00
|
|
|
/// Is the class definition local to the module shared object?
|
|
|
|
bool module_local : 1;
|
|
|
|
|
2020-04-05 06:34:00 +00:00
|
|
|
/// Is the class inheritable from python classes?
|
|
|
|
bool is_final : 1;
|
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {
|
2022-02-09 14:24:57 +00:00
|
|
|
auto *base_info = detail::get_type_info(base, false);
|
2016-09-11 11:00:40 +00:00
|
|
|
if (!base_info) {
|
2017-06-21 17:38:10 +00:00
|
|
|
std::string tname(base.name());
|
2016-09-11 11:00:40 +00:00
|
|
|
detail::clean_type_id(tname);
|
2022-02-10 20:17:07 +00:00
|
|
|
pybind11_fail("generic_type: type \"" + std::string(name)
|
|
|
|
+ "\" referenced unknown base type \"" + tname + "\"");
|
2016-09-11 11:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-01-31 15:52:11 +00:00
|
|
|
if (default_holder != base_info->default_holder) {
|
2017-06-21 17:38:10 +00:00
|
|
|
std::string tname(base.name());
|
2017-01-31 15:52:11 +00:00
|
|
|
detail::clean_type_id(tname);
|
2022-02-10 20:17:07 +00:00
|
|
|
pybind11_fail("generic_type: type \"" + std::string(name) + "\" "
|
|
|
|
+ (default_holder ? "does not have" : "has")
|
|
|
|
+ " a non-default holder type while its base \"" + tname + "\" "
|
|
|
|
+ (base_info->default_holder ? "does not" : "does"));
|
2017-01-31 15:52:11 +00:00
|
|
|
}
|
|
|
|
|
2016-09-11 11:00:40 +00:00
|
|
|
bases.append((PyObject *) base_info->type);
|
|
|
|
|
2022-07-06 20:35:12 +00:00
|
|
|
#if PY_VERSION_HEX < 0x030B0000
|
|
|
|
dynamic_attr |= base_info->type->tp_dictoffset != 0;
|
|
|
|
#else
|
|
|
|
dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;
|
|
|
|
#endif
|
2016-10-14 16:01:17 +00:00
|
|
|
|
2022-02-08 00:23:20 +00:00
|
|
|
if (caster) {
|
2017-04-21 21:14:22 +00:00
|
|
|
base_info->implicit_casts.emplace_back(type, caster);
|
2022-02-08 00:23:20 +00:00
|
|
|
}
|
2016-09-11 11:00:40 +00:00
|
|
|
}
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {
|
Add support for non-converting arguments
This adds support for controlling the `convert` flag of arguments
through the py::arg annotation. This then allows arguments to be
flagged as non-converting, which the type_caster is able to use to
request different behaviour.
Currently, AFAICS `convert` is only used for type converters of regular
pybind11-registered types; all of the other core type_casters ignore it.
We can, however, repurpose it to control internal conversion of
converters like Eigen and `array`: most usefully to give callers a way
to disable the conversion that would otherwise occur when a
`Eigen::Ref<const Eigen::Matrix>` argument is passed a numpy array that
requires conversion (either because it has an incompatible stride or the
wrong dtype).
Specifying a noconvert looks like one of these:
m.def("f1", &f, "a"_a.noconvert() = "default"); // Named, default, noconvert
m.def("f2", &f, "a"_a.noconvert()); // Named, no default, no converting
m.def("f3", &f, py::arg().noconvert()); // Unnamed, no default, no converting
(The last part--being able to declare a py::arg without a name--is new:
previous py::arg() only accepted named keyword arguments).
Such an non-convert argument is then passed `convert = false` by the
type caster when loading the argument. Whether this has an effect is up
to the type caster itself, but as mentioned above, this would be
extremely helpful for the Eigen support to give a nicer way to specify
a "no-copy" mode than the custom wrapper in the current PR, and
moreover isn't an Eigen-specific hack.
2017-01-23 08:50:00 +00:00
|
|
|
args.reserve(f.nargs);
|
|
|
|
args_convert.reserve(f.nargs);
|
|
|
|
}
|
2017-01-30 18:34:38 +00:00
|
|
|
|
2017-08-17 00:01:32 +00:00
|
|
|
/// Tag for a new-style `__init__` defined in `detail/init.h`
|
2022-02-10 20:17:07 +00:00
|
|
|
struct is_new_style_constructor {};
|
2017-08-17 00:01:32 +00:00
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/**
|
|
|
|
* Partial template specializations to process custom attributes provided to
|
|
|
|
* cpp_function_ and class_. These are either used to initialize the respective
|
2016-09-11 11:00:40 +00:00
|
|
|
* fields in the type_record and function_record data structures or executed at
|
|
|
|
* runtime to deal with custom call policies (e.g. keep_alive).
|
2016-01-17 21:36:44 +00:00
|
|
|
*/
|
2022-02-10 20:17:07 +00:00
|
|
|
template <typename T, typename SFINAE = void>
|
|
|
|
struct process_attribute;
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
template <typename T>
|
|
|
|
struct process_attribute_default {
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Default implementation: do nothing
|
2022-02-10 20:17:07 +00:00
|
|
|
static void init(const T &, function_record *) {}
|
|
|
|
static void init(const T &, type_record *) {}
|
|
|
|
static void precall(function_call &) {}
|
|
|
|
static void postcall(function_call &, handle) {}
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Process an attribute specifying the function's name
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<name> : process_attribute_default<name> {
|
2016-01-17 21:36:44 +00:00
|
|
|
static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Process an attribute specifying the function's docstring
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<doc> : process_attribute_default<doc> {
|
2016-01-17 21:36:44 +00:00
|
|
|
static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Process an attribute specifying the function's docstring (provided as a C-style string)
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<const char *> : process_attribute_default<const char *> {
|
2016-01-17 21:36:44 +00:00
|
|
|
static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }
|
2023-01-03 15:20:39 +00:00
|
|
|
static void init(const char *d, type_record *r) { r->doc = d; }
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<char *> : process_attribute<const char *> {};
|
2016-01-17 21:36:44 +00:00
|
|
|
|
|
|
|
/// Process an attribute indicating the function's return value policy
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {
|
2016-01-17 21:36:44 +00:00
|
|
|
static void init(const return_value_policy &p, function_record *r) { r->policy = p; }
|
|
|
|
};
|
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
/// Process an attribute which indicates that this is an overloaded function associated with a
|
|
|
|
/// given sibling
|
|
|
|
template <>
|
|
|
|
struct process_attribute<sibling> : process_attribute_default<sibling> {
|
2016-01-17 21:36:44 +00:00
|
|
|
static void init(const sibling &s, function_record *r) { r->sibling = s.value; }
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Process an attribute which indicates that this function is a method
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<is_method> : process_attribute_default<is_method> {
|
|
|
|
static void init(const is_method &s, function_record *r) {
|
|
|
|
r->is_method = true;
|
|
|
|
r->scope = s.class_;
|
|
|
|
}
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
Elide to-python conversion of setter return values (#4621)
* 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.
2023-05-08 17:13:54 +00:00
|
|
|
/// Process an attribute which indicates that this function is a setter
|
|
|
|
template <>
|
|
|
|
struct process_attribute<is_setter> : process_attribute_default<is_setter> {
|
|
|
|
static void init(const is_setter &, function_record *r) { r->is_setter = true; }
|
|
|
|
};
|
|
|
|
|
2016-02-04 22:02:07 +00:00
|
|
|
/// Process an attribute which indicates the parent scope of a method
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<scope> : process_attribute_default<scope> {
|
2016-02-04 22:02:07 +00:00
|
|
|
static void init(const scope &s, function_record *r) { r->scope = s.value; }
|
|
|
|
};
|
|
|
|
|
2016-09-10 06:28:37 +00:00
|
|
|
/// Process an attribute which indicates that this function is an operator
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<is_operator> : process_attribute_default<is_operator> {
|
2016-09-10 06:28:37 +00:00
|
|
|
static void init(const is_operator &, function_record *r) { r->is_operator = true; }
|
|
|
|
};
|
2016-02-04 22:02:07 +00:00
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<is_new_style_constructor>
|
|
|
|
: process_attribute_default<is_new_style_constructor> {
|
|
|
|
static void init(const is_new_style_constructor &, function_record *r) {
|
|
|
|
r->is_new_style_constructor = true;
|
|
|
|
}
|
2017-08-17 00:01:32 +00:00
|
|
|
};
|
|
|
|
|
feat: allow kw-only args after a py::args (#3402)
* Simply has_kw_only_args handling
This simplifies tracking the number of kw-only args by instead tracking
the number of positional arguments (which is really what we care about
everywhere this is used).
* Allow keyword-only arguments to follow py::args
This removes the constraint that py::args has to be last (or
second-last, with py::kwargs) and instead makes py::args imply
py::kw_only for any remaining arguments, allowing you to bind a function
that works the same way as a Python function such as:
def f(a, *args, b):
return a * b + sum(args)
f(10, 1, 2, 3, b=20) # == 206
With this change, you can bind such a function using:
m.def("f", [](int a, py::args args, int b) { /* ... */ },
"a"_a, "b"_a);
Or, to be more explicit about the keyword-only arguments:
m.def("g", [](int a, py::args args, int b) { /* ... */ },
"a"_a, py::kw_only{}, "b"_a);
(The only difference between the two is that the latter will fail at
binding time if the `kw_only{}` doesn't match the `py::args` position).
This doesn't affect backwards compatibility at all because, currently,
you can't have a py::args anywhere except the end/2nd-last.
* Take args/kwargs by const lvalue ref
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-29 03:16:55 +00:00
|
|
|
inline void check_kw_only_arg(const arg &a, function_record *r) {
|
2022-02-08 00:23:20 +00:00
|
|
|
if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) {
|
|
|
|
pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or "
|
|
|
|
"args() argument");
|
|
|
|
}
|
2017-12-23 22:56:07 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 00:01:57 +00:00
|
|
|
inline void append_self_arg_if_needed(function_record *r) {
|
2022-02-08 00:23:20 +00:00
|
|
|
if (r->is_method && r->args.empty()) {
|
|
|
|
r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false);
|
|
|
|
}
|
2021-11-21 00:01:57 +00:00
|
|
|
}
|
|
|
|
|
2016-01-17 21:36:44 +00:00
|
|
|
/// Process a keyword argument attribute (*without* a default value)
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<arg> : process_attribute_default<arg> {
|
2016-01-17 21:36:44 +00:00
|
|
|
static void init(const arg &a, function_record *r) {
|
2021-11-21 00:01:57 +00:00
|
|
|
append_self_arg_if_needed(r);
|
2017-05-17 15:55:43 +00:00
|
|
|
r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);
|
2017-12-23 22:56:07 +00:00
|
|
|
|
feat: allow kw-only args after a py::args (#3402)
* Simply has_kw_only_args handling
This simplifies tracking the number of kw-only args by instead tracking
the number of positional arguments (which is really what we care about
everywhere this is used).
* Allow keyword-only arguments to follow py::args
This removes the constraint that py::args has to be last (or
second-last, with py::kwargs) and instead makes py::args imply
py::kw_only for any remaining arguments, allowing you to bind a function
that works the same way as a Python function such as:
def f(a, *args, b):
return a * b + sum(args)
f(10, 1, 2, 3, b=20) # == 206
With this change, you can bind such a function using:
m.def("f", [](int a, py::args args, int b) { /* ... */ },
"a"_a, "b"_a);
Or, to be more explicit about the keyword-only arguments:
m.def("g", [](int a, py::args args, int b) { /* ... */ },
"a"_a, py::kw_only{}, "b"_a);
(The only difference between the two is that the latter will fail at
binding time if the `kw_only{}` doesn't match the `py::args` position).
This doesn't affect backwards compatibility at all because, currently,
you can't have a py::args anywhere except the end/2nd-last.
* Take args/kwargs by const lvalue ref
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-29 03:16:55 +00:00
|
|
|
check_kw_only_arg(a, r);
|
2016-01-17 21:36:44 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Process a keyword argument attribute (*with* a default value)
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
2016-09-05 22:49:21 +00:00
|
|
|
static void init(const arg_v &a, function_record *r) {
|
2022-02-08 00:23:20 +00:00
|
|
|
if (r->is_method && r->args.empty()) {
|
|
|
|
r->args.emplace_back(
|
|
|
|
"self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);
|
|
|
|
}
|
2016-01-17 21:36:44 +00:00
|
|
|
|
2016-09-05 22:49:21 +00:00
|
|
|
if (!a.value) {
|
2022-05-02 19:30:19 +00:00
|
|
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
2017-02-08 07:45:51 +00:00
|
|
|
std::string descr("'");
|
2022-02-10 17:23:15 +00:00
|
|
|
if (a.name) {
|
|
|
|
descr += std::string(a.name) + ": ";
|
|
|
|
}
|
2017-02-08 07:45:51 +00:00
|
|
|
descr += a.type + "'";
|
2016-11-20 04:27:05 +00:00
|
|
|
if (r->is_method) {
|
2022-02-10 17:23:15 +00:00
|
|
|
if (r->name) {
|
2022-02-10 20:17:07 +00:00
|
|
|
descr += " in method '" + (std::string) str(r->scope) + "."
|
|
|
|
+ (std::string) r->name + "'";
|
2022-02-10 17:23:15 +00:00
|
|
|
} else {
|
2016-11-20 04:27:05 +00:00
|
|
|
descr += " in method of '" + (std::string) str(r->scope) + "'";
|
2022-02-10 17:23:15 +00:00
|
|
|
}
|
2016-04-01 10:17:03 +00:00
|
|
|
} else if (r->name) {
|
2017-02-08 07:45:51 +00:00
|
|
|
descr += " in function '" + (std::string) r->name + "'";
|
2016-04-01 10:17:03 +00:00
|
|
|
}
|
2022-02-10 20:17:07 +00:00
|
|
|
pybind11_fail("arg(): could not convert default argument " + descr
|
|
|
|
+ " into a Python object (type not registered yet?)");
|
2016-02-09 08:46:11 +00:00
|
|
|
#else
|
2017-02-08 07:45:51 +00:00
|
|
|
pybind11_fail("arg(): could not convert default argument "
|
2016-02-09 08:46:11 +00:00
|
|
|
"into a Python object (type not registered yet?). "
|
2022-05-02 19:30:19 +00:00
|
|
|
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
|
|
|
"more information.");
|
2016-02-09 08:46:11 +00:00
|
|
|
#endif
|
|
|
|
}
|
2017-05-17 15:55:43 +00:00
|
|
|
r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
|
2017-12-23 22:56:07 +00:00
|
|
|
|
feat: allow kw-only args after a py::args (#3402)
* Simply has_kw_only_args handling
This simplifies tracking the number of kw-only args by instead tracking
the number of positional arguments (which is really what we care about
everywhere this is used).
* Allow keyword-only arguments to follow py::args
This removes the constraint that py::args has to be last (or
second-last, with py::kwargs) and instead makes py::args imply
py::kw_only for any remaining arguments, allowing you to bind a function
that works the same way as a Python function such as:
def f(a, *args, b):
return a * b + sum(args)
f(10, 1, 2, 3, b=20) # == 206
With this change, you can bind such a function using:
m.def("f", [](int a, py::args args, int b) { /* ... */ },
"a"_a, "b"_a);
Or, to be more explicit about the keyword-only arguments:
m.def("g", [](int a, py::args args, int b) { /* ... */ },
"a"_a, py::kw_only{}, "b"_a);
(The only difference between the two is that the latter will fail at
binding time if the `kw_only{}` doesn't match the `py::args` position).
This doesn't affect backwards compatibility at all because, currently,
you can't have a py::args anywhere except the end/2nd-last.
* Take args/kwargs by const lvalue ref
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-29 03:16:55 +00:00
|
|
|
check_kw_only_arg(a, r);
|
2017-12-23 22:56:07 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Process a keyword-only-arguments-follow pseudo argument
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<kw_only> : process_attribute_default<kw_only> {
|
2020-09-05 00:02:05 +00:00
|
|
|
static void init(const kw_only &, function_record *r) {
|
2021-11-21 00:01:57 +00:00
|
|
|
append_self_arg_if_needed(r);
|
2022-02-08 00:23:20 +00:00
|
|
|
if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {
|
|
|
|
pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative "
|
|
|
|
"argument location (or omit kw_only() entirely)");
|
|
|
|
}
|
feat: allow kw-only args after a py::args (#3402)
* Simply has_kw_only_args handling
This simplifies tracking the number of kw-only args by instead tracking
the number of positional arguments (which is really what we care about
everywhere this is used).
* Allow keyword-only arguments to follow py::args
This removes the constraint that py::args has to be last (or
second-last, with py::kwargs) and instead makes py::args imply
py::kw_only for any remaining arguments, allowing you to bind a function
that works the same way as a Python function such as:
def f(a, *args, b):
return a * b + sum(args)
f(10, 1, 2, 3, b=20) # == 206
With this change, you can bind such a function using:
m.def("f", [](int a, py::args args, int b) { /* ... */ },
"a"_a, "b"_a);
Or, to be more explicit about the keyword-only arguments:
m.def("g", [](int a, py::args args, int b) { /* ... */ },
"a"_a, py::kw_only{}, "b"_a);
(The only difference between the two is that the latter will fail at
binding time if the `kw_only{}` doesn't match the `py::args` position).
This doesn't affect backwards compatibility at all because, currently,
you can't have a py::args anywhere except the end/2nd-last.
* Take args/kwargs by const lvalue ref
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-29 03:16:55 +00:00
|
|
|
r->nargs_pos = static_cast<std::uint16_t>(r->args.size());
|
2020-09-05 00:02:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Process a positional-only-argument maker
|
2022-02-10 20:17:07 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<pos_only> : process_attribute_default<pos_only> {
|
2020-09-05 00:02:05 +00:00
|
|
|
static void init(const pos_only &, function_record *r) {
|
2021-11-21 00:01:57 +00:00
|
|
|
append_self_arg_if_needed(r);
|
2020-09-05 00:02:05 +00:00
|
|
|
r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());
|
2022-02-08 00:23:20 +00:00
|
|
|
if (r->nargs_pos_only > r->nargs_pos) {
|
feat: allow kw-only args after a py::args (#3402)
* Simply has_kw_only_args handling
This simplifies tracking the number of kw-only args by instead tracking
the number of positional arguments (which is really what we care about
everywhere this is used).
* Allow keyword-only arguments to follow py::args
This removes the constraint that py::args has to be last (or
second-last, with py::kwargs) and instead makes py::args imply
py::kw_only for any remaining arguments, allowing you to bind a function
that works the same way as a Python function such as:
def f(a, *args, b):
return a * b + sum(args)
f(10, 1, 2, 3, b=20) # == 206
With this change, you can bind such a function using:
m.def("f", [](int a, py::args args, int b) { /* ... */ },
"a"_a, "b"_a);
Or, to be more explicit about the keyword-only arguments:
m.def("g", [](int a, py::args args, int b) { /* ... */ },
"a"_a, py::kw_only{}, "b"_a);
(The only difference between the two is that the latter will fail at
binding time if the `kw_only{}` doesn't match the `py::args` position).
This doesn't affect backwards compatibility at all because, currently,
you can't have a py::args anywhere except the end/2nd-last.
* Take args/kwargs by const lvalue ref
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-29 03:16:55 +00:00
|
|
|
pybind11_fail("pos_only(): cannot follow a py::args() argument");
|
2022-02-08 00:23:20 +00:00
|
|
|
}
|
2022-02-10 20:17:07 +00:00
|
|
|
// It also can't follow a kw_only, but a static_assert in pybind11.h checks that
|
2016-01-17 21:36:44 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-02-10 20:17:07 +00:00
|
|
|
/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees
|
|
|
|
/// that)
|
2016-01-17 21:36:44 +00:00
|
|
|
template <typename T>
|
2022-02-10 20:17:07 +00:00
|
|
|
struct process_attribute<T, enable_if_t<is_pyobject<T>::value>>
|
|
|
|
: process_attribute_default<handle> {
|
2016-09-11 11:00:40 +00:00
|
|
|
static void init(const handle &h, type_record *r) { r->bases.append(h); }
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
2016-09-11 11:00:40 +00:00
|
|
|
/// Process a parent class attribute (deprecated, does not support multiple inheritance)
|
2016-01-17 21:36:44 +00:00
|
|
|
template <typename T>
|
|
|
|
struct process_attribute<base<T>> : process_attribute_default<base<T>> {
|
2017-06-21 17:38:10 +00:00
|
|
|
static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }
|
2016-09-11 11:00:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Process a multiple inheritance attribute
|
|
|
|
template <>
|
|
|
|
struct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {
|
2022-02-10 20:17:07 +00:00
|
|
|
static void init(const multiple_inheritance &, type_record *r) {
|
|
|
|
r->multiple_inheritance = true;
|
|
|
|
}
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
2016-10-10 23:12:48 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {
|
|
|
|
static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }
|
|
|
|
};
|
|
|
|
|
2021-09-24 19:08:22 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<custom_type_setup> {
|
|
|
|
static void init(const custom_type_setup &value, type_record *r) {
|
|
|
|
r->custom_type_setup_callback = value.value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-04-05 06:34:00 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<is_final> : process_attribute_default<is_final> {
|
|
|
|
static void init(const is_final &, type_record *r) { r->is_final = true; }
|
|
|
|
};
|
|
|
|
|
2016-12-16 14:00:46 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {
|
|
|
|
static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct process_attribute<metaclass> : process_attribute_default<metaclass> {
|
2017-02-16 22:02:56 +00:00
|
|
|
static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }
|
2016-12-16 14:00:46 +00:00
|
|
|
};
|
|
|
|
|
2017-07-29 02:03:44 +00:00
|
|
|
template <>
|
|
|
|
struct process_attribute<module_local> : process_attribute_default<module_local> {
|
|
|
|
static void init(const module_local &l, type_record *r) { r->module_local = l.value; }
|
|
|
|
};
|
2016-11-17 22:24:47 +00:00
|
|
|
|
2020-10-06 02:36:33 +00:00
|
|
|
/// Process a 'prepend' attribute, putting this at the beginning of the overload chain
|
|
|
|
template <>
|
|
|
|
struct process_attribute<prepend> : process_attribute_default<prepend> {
|
|
|
|
static void init(const prepend &, function_record *r) { r->prepend = true; }
|
|
|
|
};
|
|
|
|
|
2016-11-17 22:24:47 +00:00
|
|
|
/// Process an 'arithmetic' attribute for enums (does nothing here)
|
|
|
|
template <>
|
|
|
|
struct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};
|
|
|
|
|
2017-03-16 10:22:26 +00:00
|
|
|
template <typename... Ts>
|
2022-02-10 20:17:07 +00:00
|
|
|
struct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};
|
2017-03-16 10:22:26 +00:00
|
|
|
|
2017-05-22 16:06:16 +00:00
|
|
|
/**
|
2016-01-17 21:36:44 +00:00
|
|
|
* Process a keep_alive call policy -- invokes keep_alive_impl during the
|
|
|
|
* pre-call handler if both Nurse, Patient != 0 and use the post-call handler
|
|
|
|
* otherwise
|
|
|
|
*/
|
2022-02-10 20:17:07 +00:00
|
|
|
template <size_t Nurse, size_t Patient>
|
|
|
|
struct process_attribute<keep_alive<Nurse, Patient>>
|
|
|
|
: public process_attribute_default<keep_alive<Nurse, Patient>> {
|
2017-01-22 14:23:53 +00:00
|
|
|
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
|
2022-02-10 20:17:07 +00:00
|
|
|
static void precall(function_call &call) {
|
|
|
|
keep_alive_impl(Nurse, Patient, call, handle());
|
|
|
|
}
|
2017-01-22 14:23:53 +00:00
|
|
|
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
|
2022-02-10 20:17:07 +00:00
|
|
|
static void postcall(function_call &, handle) {}
|
2017-01-22 14:23:53 +00:00
|
|
|
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
|
2022-02-10 20:17:07 +00:00
|
|
|
static void precall(function_call &) {}
|
2017-01-22 14:23:53 +00:00
|
|
|
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
|
2022-02-10 20:17:07 +00:00
|
|
|
static void postcall(function_call &call, handle ret) {
|
|
|
|
keep_alive_impl(Nurse, Patient, call, ret);
|
|
|
|
}
|
2016-01-17 21:36:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Recursively iterate over variadic template arguments
|
2022-02-10 20:17:07 +00:00
|
|
|
template <typename... Args>
|
|
|
|
struct process_attributes {
|
|
|
|
static void init(const Args &...args, function_record *r) {
|
2021-07-29 00:01:21 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
|
2021-08-06 19:27:11 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
|
|
|
|
using expander = int[];
|
|
|
|
(void) expander{
|
|
|
|
0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
|
2016-01-17 21:36:44 +00:00
|
|
|
}
|
2022-02-10 20:17:07 +00:00
|
|
|
static void init(const Args &...args, type_record *r) {
|
2021-07-29 00:01:21 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
|
2021-08-06 19:27:11 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
|
|
|
|
using expander = int[];
|
|
|
|
(void) expander{0,
|
|
|
|
(process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
|
2016-01-17 21:36:44 +00:00
|
|
|
}
|
2017-01-30 18:34:38 +00:00
|
|
|
static void precall(function_call &call) {
|
2021-07-29 00:01:21 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);
|
2021-08-06 19:27:11 +00:00
|
|
|
using expander = int[];
|
|
|
|
(void) expander{0,
|
|
|
|
(process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};
|
2016-01-17 21:36:44 +00:00
|
|
|
}
|
2017-01-30 18:34:38 +00:00
|
|
|
static void postcall(function_call &call, handle fn_ret) {
|
2021-07-29 00:01:21 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);
|
2021-08-06 19:27:11 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);
|
|
|
|
using expander = int[];
|
|
|
|
(void) expander{
|
|
|
|
0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};
|
2016-01-17 21:36:44 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-03-16 10:22:26 +00:00
|
|
|
template <typename T>
|
|
|
|
using is_call_guard = is_instantiation<call_guard, T>;
|
|
|
|
|
|
|
|
/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
|
|
|
|
template <typename... Extra>
|
2017-03-29 09:55:18 +00:00
|
|
|
using extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;
|
2017-03-16 10:22:26 +00:00
|
|
|
|
2016-06-03 22:27:32 +00:00
|
|
|
/// Check the number of named arguments at compile time
|
|
|
|
template <typename... Extra,
|
|
|
|
size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),
|
2022-02-10 20:17:07 +00:00
|
|
|
size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>
|
2017-01-22 04:42:14 +00:00
|
|
|
constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
|
2021-07-29 00:01:21 +00:00
|
|
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);
|
2021-01-14 04:14:06 +00:00
|
|
|
return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs;
|
2016-06-03 22:27:32 +00:00
|
|
|
}
|
|
|
|
|
2020-07-08 22:14:41 +00:00
|
|
|
PYBIND11_NAMESPACE_END(detail)
|
|
|
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|