Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
/*
|
2017-06-08 22:44:49 +00:00
|
|
|
tests/test_class.cpp -- test py::class_ definitions and basic functionality
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
|
|
|
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
|
|
|
|
|
|
|
All rights reserved. Use of this source code is governed by a
|
|
|
|
BSD-style license that can be found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
fix: Intel ICC C++17 compatibility (#2729)
* CI: Intel icc/icpc via oneAPI
Add testing for Intel icc/icpc via the oneAPI images.
Intel oneAPI is in a late beta stage, currently shipping
oneAPI beta09 with ICC 20.2.
CI: Skip Interpreter Tests for Intel
Cannot find how to add this, neiter the package `libc6-dev` nor
`intel-oneapi-mkl-devel` help when installed to solve this:
```
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - not found
CMake Error at /__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:165 (message):
Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
/__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:458 (_FPHSA_FAILURE_MESSAGE)
/__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindThreads.cmake:234 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
tests/test_embed/CMakeLists.txt:17 (find_package)
```
CI: libc6-dev from GCC for ICC
CI: Run bare metal for oneAPI
CI: Ubuntu 18.04 for oneAPI
CI: Intel +Catch -Eigen
CI: CMake from Apt (ICC tests)
CI: Replace Intel Py with GCC Py
CI: Intel w/o GCC's Eigen
CI: ICC with verbose make
[Debug] Find core dump
tests: use arg{} instead of arg() for Intel
tests: adding a few more missing {}
fix: sync with @tobiasleibner's branch
fix: try ubuntu 20-04
fix: drop exit 1
docs: Apply suggestions from code review
Co-authored-by: Tobias Leibner <tobias.leibner@googlemail.com>
Workaround for ICC enable_if issues
Another workaround for ICC's enable_if issues
fix error in previous commit
Disable one test for the Intel compiler in C++17 mode
Add back one instance of py::arg().noconvert()
Add NOLINT to fix clang-tidy check
Work around for ICC internal error in PYBIND11_EXPAND_SIDE_EFFECTS in C++17 mode
CI: Intel ICC with C++17
docs: pybind11/numpy.h does not require numpy at build time. (#2720)
This is nice enough to be mentioned explicitly in the docs.
docs: Update warning about Python 3.9.0 UB, now that 3.9.1 has been released (#2719)
Adjusting `type_caster<std::reference_wrapper<T>>` to support const/non-const propagation in `cast_op`. (#2705)
* Allow type_caster of std::reference_wrapper<T> to be the same as a native reference.
Before, both std::reference_wrapper<T> and std::reference_wrapper<const T> would
invoke cast_op<type>. This doesn't allow the type_caster<> specialization for T
to distinguish reference_wrapper types from value types.
After, the type_caster<> specialization invokes cast_op<type&>, which allows
reference_wrapper to behave in the same way as a native reference type.
* Add tests/examples for std::reference_wrapper<const T>
* Add tests which use mutable/immutable variants
This test is a chimera; it blends the pybind11 casters with a custom
pytype implementation that supports immutable and mutable calls.
In order to detect the immutable/mutable state, the cast_op needs
to propagate it, even through e.g. std::reference<const T>
Note: This is still a work in progress; some things are crashing,
which likely means that I have a refcounting bug or something else
missing.
* Add/finish tests that distinguish const& from &
Fixes the bugs in my custom python type implementation,
demonstrate test that requires const& and reference_wrapper<const T>
being treated differently from Non-const.
* Add passing a const to non-const method.
* Demonstrate non-const conversion of reference_wrapper in tests.
Apply formatting presubmit check.
* Fix build errors from presubmit checks.
* Try and fix a few more CI errors
* More CI fixes.
* More CI fixups.
* Try and get PyPy to work.
* Additional minor fixups. Getting close to CI green.
* More ci fixes?
* fix clang-tidy warnings from presubmit
* fix more clang-tidy warnings
* minor comment and consistency cleanups
* PyDECREF -> Py_DECREF
* copy/move constructors
* Resolve codereview comments
* more review comment fixes
* review comments: remove spurious &
* Make the test fail even when the static_assert is commented out.
This expands the test_freezable_type_caster a bit by:
1/ adding accessors .is_immutable and .addr to compare identity
from python.
2/ Changing the default cast_op of the type_caster<> specialization
to return a non-const value. In normal codepaths this is a reasonable
default.
3/ adding roundtrip variants to exercise the by reference, by pointer
and by reference_wrapper in all call paths. In conjunction with 2/, this
demonstrates the failure case of the existing std::reference_wrpper conversion,
which now loses const in a similar way that happens when using the default cast_op_type<>.
* apply presubmit formatting
* Revert inclusion of test_freezable_type_caster
There's some concern that this test is a bit unwieldly because of the use
of the raw <Python.h> functions. Removing for now.
* Add a test that validates const references propagation.
This test verifies that cast_op may be used to correctly detect
const reference types when used with std::reference_wrapper.
* mend
* Review comments based changes.
1. std::add_lvalue_reference<type> -> type&
2. Simplify the test a little more; we're never returning the ConstRefCaster
type so the class_ definition can be removed.
* formatted files again.
* Move const_ref_caster test to builtin_casters
* Review comments: use cast_op and adjust some comments.
* Simplify ConstRefCasted test
I like this version better as it moves the assertion that matters
back into python.
ci: drop pypy2 linux, PGI 20.7, add Python 10 dev (#2724)
* ci: drop pypy2 linux, add Python 10 dev
* ci: fix mistake
* ci: commented-out PGI 20.11, drop 20.7
fix: regression with installed pybind11 overriding local one (#2716)
* fix: regression with installed pybind11 overriding discovered one
Closes #2709
* docs: wording incorrect
style: remove redundant instance->owned = true (#2723)
which was just before set to True in instance->allocate_layout()
fix: also throw in the move-constructor added by the PYBIND11_OBJECT macro, after the argument has been moved-out (if necessary) (#2701)
Make args_are_all_* ICC workarounds unconditional
Disable test_aligned on Intel ICC
Fix test_aligned on Intel ICC
Skip test_python_alreadyset_in_destructor on Intel ICC
Fix test_aligned again
ICC CI: Downgrade pytest
pytest 6 does not capture the `discard_as_unraisable` stderr and
just writes a warning with its content instead.
* refactor: simpler Intel workaround, suggested by @laramiel
* fix: try version with impl to see if it is easier to compile
* docs: update README for ICC
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2021-01-18 00:53:07 +00:00
|
|
|
#if defined(__INTEL_COMPILER) && __cplusplus >= 201703L
|
|
|
|
// Intel compiler requires a separate header file to support aligned new operators
|
|
|
|
// and does not set the __cpp_aligned_new feature macro.
|
|
|
|
// This header needs to be included before pybind11.
|
|
|
|
#include <aligned_new>
|
|
|
|
#endif
|
|
|
|
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
#include "pybind11_tests.h"
|
2017-06-08 22:44:49 +00:00
|
|
|
#include "constructor_stats.h"
|
2017-07-29 02:03:44 +00:00
|
|
|
#include "local_bindings.h"
|
2018-01-11 17:22:13 +00:00
|
|
|
#include <pybind11/stl.h>
|
|
|
|
|
2018-11-09 19:14:53 +00:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
# pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier
|
|
|
|
#endif
|
|
|
|
|
Adding py::smart_holder (for smart-pointer interoperability). (#2672)
* Adding test_unique_ptr_member (for desired PyCLIF behavior).
See also: https://github.com/pybind/pybind11/issues/2583
Does not build with upstream master or
https://github.com/pybind/pybind11/pull/2047, but builds with
https://github.com/RobotLocomotion/pybind11 and almost runs:
```
Running tests in directory "/usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests":
================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.5, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests, inifile: pytest.ini
collected 2 items
test_unique_ptr_member.py .F [100%]
====================================================================================== FAILURES =======================================================================================
_____________________________________________________________________________ test_pointee_and_ptr_owner ______________________________________________________________________________
def test_pointee_and_ptr_owner():
obj = m.pointee()
assert obj.get_int() == 213
m.ptr_owner(obj)
with pytest.raises(ValueError) as exc_info:
> obj.get_int()
E Failed: DID NOT RAISE <class 'ValueError'>
test_unique_ptr_member.py:17: Failed
============================================================================= 1 failed, 1 passed in 0.06s =============================================================================
```
* unique_ptr or shared_ptr return
* new test_variant_unique_shared with vptr_holder prototype
* moving prototype code to pybind11/vptr_holder.h, adding type_caster specialization to make the bindings involving unique_ptr passing compile, but load and cast implementations are missing
* disabling GitHub Actions on pull_request (for this PR)
* disabling AppVeyor (for this PR)
* TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_STACK (pointee)
* adding test_promotion_of_disowned_to_shared
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising returning and passing unique_ptr<T>, shared_ptr<T>
with unique_ptr, shared_ptr holder.
Observations:
test_holder_unique_ptr:
make_unique_pointee OK
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee Abort free(): double free detected
pass_shared_pointee RuntimeError: Unable to load a custom holder type from a default-holder instance
test_holder_shared_ptr:
make_unique_pointee Segmentation fault (#1138)
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee OK
pass_shared_pointee OK
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising casting between shared_ptr<base>, shared_ptr<derived>.
* Demonstration of Undefined Behavior in handling of shared_ptr holder.
Based on https://godbolt.org/z/4fdjaW by jorgbrown@ (thanks Jorg!).
* Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
* fixing up-down mixup in comment
* Demonstration of Undefined Behavior in handling of polymorphic pointers.
(This demo does NOT involve smart pointers at all, unlike the otherwise similar test_smart_ptr_private_first_base.)
* minor test_private_first_base.cpp simplification (after discovering that this can be wrapped with Boost.Python, using boost::noncopyable)
* pybind11 equivalent of Boost.Python test similar to reproducer under #1333
* Snapshot of WIP, TODO: shared_ptr deleter with on/off switch
* Adding vptr_deleter.
* Adding from/as unique_ptr<T> and unique_ptr<T, D>.
* Adding from_shared_ptr. Some polishing.
* New tests/core/smart_holder_poc_test.cpp, using Catch2.
* Adding in vptr_deleter_guard_flag.
* Improved labeling of TEST_CASEs.
* Shuffling existing TEST_CASEs into systematic matrix.
* Implementing all [S]uccess tests.
* Implementing all [E]xception tests.
* Testing of exceptions not covered by the from-as matrix.
* Adding top-level comment.
* Converting from methods to factory functions (no functional change).
* Removing obsolete and very incomplete test (replaced by Catch2-based test).
* Removing stray file.
* Adding type_caster_bare_interface_demo.
* Adding shared_ptr<mpty>, shared_ptr<mpty const> casters.
* Adding unique_ptr<mpty>, unique_ptr<mpty const> casters.
* Pure copy of `class class_` implementation in pybind11.h (master commit 98f1bbb8004f654ba9e26717bdf5912fb899b05a).
* classh.h: renaming of class_ to classh + namespace; forking test_classh_wip from test_type_caster_bare_interface_demo.
* Hard-coding smart_holder into classh.
* Adding mpty::mtxt string member.
* Adding isinstance<mpty> in type_caster::load functions.
* Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing const.
* Retrieving smart_holder pointer in type_caster<mpty>::load, and using it cast_op operators.
* Factoring out smart_holder_type_caster_load.
* Retrieving smart_holder pointer in type_caster<std::shared_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Improved error messaging: Cannot disown nullptr (as_unique_ptr).
* Retrieving smart_holder pointer in type_caster<std::unique_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Pure `clang-format --style=file -i` change.
* Pure `clang-format --style=file -i` change, with two `clang-format off` directives.
* Fixing oversight (discovered by flake8).
* flake8 cleanup
* Systematically setting mtxt for all rtrn_mpty_* functions (preparation, the values are not actually used yet).
* static cast handle for rtrn_cptr works by simply dropping in code from type_caster_base (marked with comments).
* static cast handle for rtrn_cref works by simply dropping in code from type_caster_base (marked with comments). rtrn_mref and rtrn_mptr work via const_cast (to add const).
* static cast handle for rtrn_valu works by simply dropping in code from type_caster_base (marked with comments). rtrn_rref raises a RuntimeError, to be investigated.
* Copying type_caster_generic::cast into type_caster<mpty> as-is (preparation for handling smart pointers).
* Pure clang-format change (applied to original type_caster_generic::cast).
* Adding comment re potential use_count data race.
* static handle cast implementations for rtrn_shmp, rtrn_shcp.
* Adding MISSING comments in operator std::unique_ptr<mpty[ const]>.
* static handle cast implementations for rtrn_uqmp, rtrn_uqcp.
* Bug fix: vptr_deleter_armed_flag_ptr has to live on the heap.
See new bullet point in comment section near the top.
The variable was also renamed to reflect its function more accurately.
* Fixing bugs discovered by ASAN. The code is now ASAN, MSAN, UBSAN clean.
* Making test_type_caster_bare_interface_demo.cpp slightly more realistic, ASAN, MSAN, UBSAN clean.
* Calling deregister_instance after disowning via unique_ptr.
* Removing enable_shared_from_this stub, simplifying existing code, clang-format.
Open question, with respect to the original code:
https://github.com/pybind/pybind11/blob/76a160070b369f8d82b945c97924227e8b835c94/include/pybind11/pybind11.h#L1510
To me it looks like the exact situation marked as `std::shared_ptr<Good> gp1 = not_so_good.getptr();` here: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
The comment there is: `// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)`
Does the existing code have UB pre C++17?
I'll leave handling of enable_shared_from_this for later, as the need arises.
* Cosmetical change around helper functions.
* Using type_caster_base<mpty>::src_and_type directly, removing copy. Also renaming one cast to cast_const_raw_ptr, for clarity.
* Fixing clang-format oversight.
* Using factored-out make_constructor (PR #2798), removing duplicate code.
* Inserting additional assert to ensure a returned unique_ptr is always a new Python instance.
* Adding minor comment (change to internals needed to distinguish uninitialized/disowned in error message).
* Factoring out find_existing_python_instance().
* Moving factored-out make_constructor to test_classh_wip.cpp, restoring previous version of cast.h. This is currently the most practical approach. See PR #2798 for background.
* Copying classh type_casters from test_classh_wip.cpp UNMODIFIED, as a baseline for generalizing the code.
* Using pybind11/detail/classh_type_casters.h from test_classh_wip.cpp.
* Adding & using PYBIND11_CLASSH_TYPE_CASTERS define.
* Adding test_classh_inheritance, currently failing (passes with class_).
* Removing .clang-format before git rebase master (where the file was added).
* Bringing back .clang-format, the previous rm was a bad idea.
* Folding in modified_type_caster_generic_load_impl, just enough to pass test_class_wip. test_classh_inheritance is still failing, but with a different error: [RuntimeError: Incompatible type (as_raw_ptr_unowned).]
* Minimal changes needed to pass test_classh_inheritance.
* First pass adjusting try_implicit_casts and try_load_foreign_module_local to capture loaded_v_h, but untested and guarded with pybind11_failure("Untested"). This was done mainly to determine general feasibility. Note the TODO in pybind11.h, where type_caster_generic::local_load is currently hard-coded. test_classh_wip and test_classh_inheritance still pass, as before.
* Decoupling generic_type from type_caster_generic.
* Changes and tests covering classh_type_casters try_implicit_casts.
* Minimal test covering classh_type_casters load_impl Case 2b.
* Removing stray isinstance<T>(src): it interferes with the py::module_local feature. Adding missing #includes.
* Tests for classh py::module_local() feature.
* Pure renaming of function names in test_classh_inheritance, similar to the systematic approach used in test_class_wip. NO functional changes.
* Pure renaming of function and variable names, for better generalization when convoluting with inheritance. NO functional changes.
* Adopting systematic naming scheme from test_classh_wip. NO functional changes.
* Moving const after type name, for functions that cover a systematic scheme. NO functional changes.
* Adding smart_holder_type_caster_load::loaded_as_shared_ptr, currently bypassing smart_holder shared_ptr tracking completely, but the tests pass and are sanitizer clean.
* Removing rtti_held from smart_holder. See updated comment.
* Cleaning up loaded_as_raw_ptr_unowned, loaded_as_shared_ptr.
* Factoring out convert_type and folding into loaded_as_unique_ptr.
* Folding convert_type into lvalue_ref and rvalue_ref paths. Some smart_holder_type_caster_load cleanup.
* Using unique_ptr in local_load to replace static variable. Also adding local_load_safety_guard.
* Converting test_unique_ptr_member to using classh: fully working, ASAN, MSAN, UBSAN clean.
* Removing debugging comments (GET_STACK, GET_INT_STACK). cast.h is identical to current master again, pybind11.h only has the generic_type::initialize(..., &type_caster_generic::local_load) change.
* Purging obsolete pybind11/vptr_holder.h and associated test.
* Moving several tests to github.com/rwgk/rwgk_tbx/tree/main/pybind11_tests
https://github.com/rwgk/rwgk_tbx/commit/a2c2f88174a30f5de80d7d26e0f77c7b60f5fb85
These tests are from experimenting, and for demonstrating UB in pybind11 multiple inheritance handling ("first_base"), to be fixed later.
* Adding py::smart_holder support to py::class_, purging py::classh completely.
* Renaming files in include directory, creating pybind11/smart_holder.h.
* Renaming all "classh" to "smart_holder" in pybind11/detail/smart_holder_type_casters.h.
The user-facing macro is now PYBIND11_SMART_HOLDER_TYPE_CASTERS.
* Systematically renaming tests to use "class_sh" in the name.
* Renaming test_type_caster_bare_interface_demo to test_type_caster_bare_interface.
* Renaming new tests/core subdirectory to tests/pure_cpp.
* Adding new tests to CMake config, resetting CI config.
* Changing CMake file so that test_class_sh_module_local.py actually runs.
* clang-tidy fixes.
* 32-bit compatibility.
* Reusing type_caster_base make_copy_constructor, make_move_constructor with a trick.
* CMake COMPARE NATURAL is not available with older versions.
* Adding copyright notices to new header files.
* Explicitly define copy/move constructors/assignments.
* Adding new header files to tests/extra_python_package/test_files.py.
* Adding tests/pure_cpp/CMakeLists.txt.
* Making use of the new find_existing_python_instance() function factored out with PR #2822.
* Moving define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T) down in the file. NO functional changes. Preparation for follow-up work (to keep that diff smaller).
* Reintroducing py::classh, this time as a simple alias for py::class_<U, py::smart_holder>.
* Replacing detail::is_smart_holder<H> in cast.h with detail::is_smart_holder_type_caster<T>.
Moving get_local_load_function_ptr, init_instance_for_type to smart_holder_type_caster_class_hooks.
Expanding static_assert in py::type::handle_of<> to accommodate smart_holder_type_casters.
* Fixing oversight.
* Adding classu alias for class_<U, std::unique_ptr<U>>.
* Giving up on idea to use legacy init_instance only if is_base_of<type_caster_generic, type_caster<T>. There are use cases in the wild that define both a custom type_caster and class_.
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Moving up is_smart_holder_type_caster, to also use in cast_is_temporary_value_reference.
* Adding smart_holder_type_casters for unique_ptr with custom deleter. SEVERE CODE DUPLICATION. This commit is to establish a baseline for consolidating the unique_ptr code.
* Unification of unique_ptr, unique_ptr_with_deleter code in smart_holder_poc.h. Leads to more fitting error messages. Enables use of unique_ptr<T, D> smart_holder_type_casters also for unique_ptr<T>.
* Copying files as-is from branch test_unique_ptr_member (PR #2672).
* Adding comment, simplifying naming, cmake addition.
* Introducing PYBIND11_USE_SMART_HOLDER_AS_DEFAULT macro (tested only undefined; there are many errors with the macro defined).
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Fixing oversight introduced with commit 95425f13d6c14fcb6ee479b62b602dc8a605ec49.
* Setting record.default_holder correctly for PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
With this test_class.cpp builds and even mostly runs, except
`test_multiple_instances_with_same_pointer`, which segfaults because it is
using a `unique_ptr` holder but `smart_holder` `type_caster`.
Also adding `static_assert`s to generate build errors for such situations,
but guarding with `#if 0` to first pivot to test_factory_constructors.cpp.
* Fixing up cast.h and smart_holder.h after rebase.
* Removing detail/smart_holder_type_casters.h in separate commit.
* Commenting out const in def_buffer(... const). With this, test_buffers builds and runs with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT. Explanation why the const needs to be removed, or fix elsewhere, is still needed, but left for later.
* Adding test_class_sh_factory_constructors, reproducing test_factory_constructors failure. Using py::class_ in this commit, to be changed to py::classh for debugging.
* Removing include/pybind11/detail/smart_holder_type_casters.h from CMakeLists.txt, test_files.py (since it does not exist in this branch).
* Adding // DANGER ZONE reminders.
* Converting as many py::class_ to py::classh as possible, not breaking tests.
* Adding initimpl::construct() overloads, resulting in test_class_sh_factory_constructors feature parity for py::class_ and py::classh.
* Adding enable_if !is_smart_holder_type_caster to existing initimpl::construct(). With this test_factory_constructors.cpp builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Disabling shared_ptr&, shared_ptr* tests when building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT for now, pending work on smart_holder_type_caster<shared_ptr>.
* Factoring out struct and class definitions into anonymous namespace. Preparation for building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Simplifying from_unique_ptr(): typename D = std::default_delete<T> is not needed. Factoring out is_std_default_delete<T>() for consistentcy between ensure_compatible_rtti_uqp_del() and from_unique_ptr().
* Introducing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. Using it in test_smart_ptr.cpp. With this test_smart_ptr builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT and all but one test run successfully.
* Introducing 1. type_caster_for_class_, used in PYBIND11_MAKE_OPAQUE, and 2. default_holder_type, used in stl_bind.h.
* Using __VA_ARGS__ in PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS.
* Replacing condense_for_macro with much simpler approach.
* Softening static_assert, to only check specifically that smart_holder is not mixed with type_caster_base, and unique_ptr/shared_ptr holders are not mixed with smart_holder_type_casters.
* Adding PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS in test_class.cpp (with this all but one test succeed with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT).
* Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for "necessary conditions" for both types of default holder, static_assert for "strict conditions" guarded by new PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX. All tests build & run as before with unique_ptr as the default holder, all tests build for smart_holder as the default holder, even with the strict static_assert.
* Introducing check_is_smart_holder_type_caster() function for runtime check, and reinterpreting record.default_holder as "uses_unique_ptr_holder". With this test_smart_ptr succeeds. (All 42 tests build, 35 tests succeed, 5 run but have some failures, 2 segfault.)
* Bug fix: Adding have_value() to smart_holder_type_caster_load. With this test_builtin_casters succeeds. (All 42 tests build, 36 tests succeed, 5 run but have some failures, 1 segfault.)
* Adding unowned_void_ptr_from_direct_conversion to modified_type_caster_generic_load_impl. This fixes the last remaining segfault (test_numpy_dtypes). New stats for all tests combined: 12 failed, 458 passed.
* Adding "Lazy allocation for unallocated values" (for old-style __init__) into load_value_and_holder. Deferring destruction of disowned holder until clear_instance, to remain inspectable for "uninitialized" or "disowned" detection. New stats for all tests combined: 5 failed, 465 passed.
* Changing std::shared_ptr pointer/reference to const pointer/reference. New stats for all tests combined: 4 failed, 466 passed.
* Adding return_value_policy::move to permissible policies for unique_ptr returns. New stats for all tests combined: 3 failed, 467 passed.
* Overlooked flake8 fixes.
* Manipulating failing ConstructorStats test to pass, to be able to run all tests with ASAN.
This version of the code is ASAN clean with unique_ptr or smart_holder as the default.
This change needs to be reverted after adopting the existing move-only-if-refcount-is-1
logic used by type_caster_base.
* Adding copy constructor and move constructor tracking to atyp. Preparation for a follow-up change in smart_holder_type_caster, to make this test sensitive to the changing behavior.
[skip ci]
* Removing `operator T&&() &&` from smart_holder_type_caster, for compatibility with the behavior of type_caster_base. Enables reverting 2 of 3 test manipulations applied under commit 249df7cbdb09817fed0ddf80f01ba5af12466820. The manipulation in test_factory_constructors.py is NOT reverted in this commit.
[skip ci]
* Fixing unfortunate editing mishap. This reverts the last remaining test manipulation in commit 249df7cbdb09817fed0ddf80f01ba5af12466820 and makes all existing unit tests pass with smart_holder as default holder.
* GitHub CI clang-tidy fixes.
* Adding messages to terse `static_assert`s, for pre-C++17 compatibility.
* Using @pytest.mark.parametrize to run each assert separately (to see all errors, not just the first).
* Systematically removing _atyp from function names, to make the test code simpler.
* Using re.match to accommodate variable number of intermediate MvCtor.
* Also removing `operator T()` from smart_holder_type_caster, to fix gcc compilation errors. The only loss is pass_rref in test_class_sh_basic.
* Systematically replacing `detail::enable_if_t<...smart_holder...>` with `typename std::enable_if<...smart_holder...>::type`. Attempt to work around MSVC 2015 issues, to be tested via GitHub CI. The idea for this change originates from this comment: https://github.com/pybind/pybind11/issues/1616#issuecomment-444536813
* Importing re before pytest after observing a PyPy CI flake when importing pytest first.
* Copying MSVC 2015 compatibility change from branch pr2672_use_smart_holder_as_default.
* Introducing is_smart_holder_type_caster_base_tag, to keep smart_holder code more disconnected.
* Working around MSVC 2015 bug.
* Expanding comment for MSVC 2015 workaround.
* Systematically changing std::enable_if back to detail::enable_if_t, effectively reverting commit 5d4b6890a337ae1bbaec4091f4195606f89a3b06.
* Removing unused smart_holder_type_caster_load::loaded_as_rvalue_ref (it was an oversight that it was not removed with commit 23036a45eb4731a06b488ec1fdf83bca677b7f67).
* Removing py::classu, because it does not seem useful enough.
* Reverting commit 63495313066119dcf7510c2ae8b468b46c12ef8f by un-commenting `const` in `def_buffer(...)`. To make this possible, `operator T const&` and `operator T const*` in `smart_holder_type_caster` need to be marked as `const` member functions.
* Adding construct() overloads for constructing smart_holder from alias unique_ptr, shared_ptr returns.
* Adding test_class_sh_factory_constructors.cpp to tests/CMakeLists.txt (fixes oversight, this should have been added long before).
* Compatibility with old clang versions (clang 3.6, 3.7 C++11).
* Cleaning up changes to existing unit tests.
* Systematically adding SMART_HOLDER_WIP tag. Removing minor UNTESTED tags (only the throw are not actually exercised, investing time there has a high cost but very little benefit).
* Splitting out smart_holder_type_casters again, into new detail/smart_holder_type_casters_inline_include.h.
* Splitting out smart_holder_init_inline_include.h.
* Adding additional new include files to CMakeLists.txt, tests/extra_python_package/test_files.py.
* clang-format cleanup of most smart_holder code.
* Adding source code comments in response to review.
* Simple micro-benchmark ("ubench") comparing runtime performance for several holders.
Tested using github.com/rwgk/pybind11_scons and Google-internal build system.
Sorry, no cmake support at the moment.
First results: https://docs.google.com/spreadsheets/d/1InapCYws2Gt-stmFf_Bwl33eOMo3aLE_gc9adveY7RU/edit#gid=0
* Breaking out number_bucket.h, adding hook for also collecting performance data for PyCLIF.
* Accounting for ubench in MANIFEST.in (simply prune, for now).
* Smarter determination of call_repetitions.
[skip ci]
* Also scaling performance data to PyCLIF.
[skip ci]
* Adding ubench/python/number_bucket.clif here for general visibility.
* Fix after rebase
* Merging detail/smart_holder_init_inline_include.h into detail/init.h.
* Renaming detail/is_smart_holder_type_caster.h -> detail/smart_holder_sfinae_hooks_only.h.
* Renaming is_smart_holder_type_caster -> type_uses_smart_holder_type_caster for clarity.
* Renaming type_caster_type_is_smart_holder_type_caster -> wrapped_type_uses_smart_holder_type_caster for clarity.
* Renaming is_smart_holder_type_caster_base_tag -> smart_holder_type_caster_base_tag for simplicity.
* Adding copyright notices and minor colateral cleanup.
* iwyu cleanup (comprehensive only for cast.h and smart_holder*.h files).
* Fixing `git rebase master` accident.
* Moving large `pragma warning` block from pybind11.h to detail/common.h.
* Fixing another `git rebase master` accident.
2021-02-24 05:50:42 +00:00
|
|
|
namespace {
|
|
|
|
|
2018-01-11 17:22:13 +00:00
|
|
|
// test_brace_initialization
|
|
|
|
struct NoBraceInitialization {
|
|
|
|
NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}
|
|
|
|
template <typename T>
|
|
|
|
NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}
|
|
|
|
|
|
|
|
std::vector<int> vec;
|
|
|
|
};
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
|
Adding py::smart_holder (for smart-pointer interoperability). (#2672)
* Adding test_unique_ptr_member (for desired PyCLIF behavior).
See also: https://github.com/pybind/pybind11/issues/2583
Does not build with upstream master or
https://github.com/pybind/pybind11/pull/2047, but builds with
https://github.com/RobotLocomotion/pybind11 and almost runs:
```
Running tests in directory "/usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests":
================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.5, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests, inifile: pytest.ini
collected 2 items
test_unique_ptr_member.py .F [100%]
====================================================================================== FAILURES =======================================================================================
_____________________________________________________________________________ test_pointee_and_ptr_owner ______________________________________________________________________________
def test_pointee_and_ptr_owner():
obj = m.pointee()
assert obj.get_int() == 213
m.ptr_owner(obj)
with pytest.raises(ValueError) as exc_info:
> obj.get_int()
E Failed: DID NOT RAISE <class 'ValueError'>
test_unique_ptr_member.py:17: Failed
============================================================================= 1 failed, 1 passed in 0.06s =============================================================================
```
* unique_ptr or shared_ptr return
* new test_variant_unique_shared with vptr_holder prototype
* moving prototype code to pybind11/vptr_holder.h, adding type_caster specialization to make the bindings involving unique_ptr passing compile, but load and cast implementations are missing
* disabling GitHub Actions on pull_request (for this PR)
* disabling AppVeyor (for this PR)
* TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_STACK (pointee)
* adding test_promotion_of_disowned_to_shared
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising returning and passing unique_ptr<T>, shared_ptr<T>
with unique_ptr, shared_ptr holder.
Observations:
test_holder_unique_ptr:
make_unique_pointee OK
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee Abort free(): double free detected
pass_shared_pointee RuntimeError: Unable to load a custom holder type from a default-holder instance
test_holder_shared_ptr:
make_unique_pointee Segmentation fault (#1138)
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee OK
pass_shared_pointee OK
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising casting between shared_ptr<base>, shared_ptr<derived>.
* Demonstration of Undefined Behavior in handling of shared_ptr holder.
Based on https://godbolt.org/z/4fdjaW by jorgbrown@ (thanks Jorg!).
* Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
* fixing up-down mixup in comment
* Demonstration of Undefined Behavior in handling of polymorphic pointers.
(This demo does NOT involve smart pointers at all, unlike the otherwise similar test_smart_ptr_private_first_base.)
* minor test_private_first_base.cpp simplification (after discovering that this can be wrapped with Boost.Python, using boost::noncopyable)
* pybind11 equivalent of Boost.Python test similar to reproducer under #1333
* Snapshot of WIP, TODO: shared_ptr deleter with on/off switch
* Adding vptr_deleter.
* Adding from/as unique_ptr<T> and unique_ptr<T, D>.
* Adding from_shared_ptr. Some polishing.
* New tests/core/smart_holder_poc_test.cpp, using Catch2.
* Adding in vptr_deleter_guard_flag.
* Improved labeling of TEST_CASEs.
* Shuffling existing TEST_CASEs into systematic matrix.
* Implementing all [S]uccess tests.
* Implementing all [E]xception tests.
* Testing of exceptions not covered by the from-as matrix.
* Adding top-level comment.
* Converting from methods to factory functions (no functional change).
* Removing obsolete and very incomplete test (replaced by Catch2-based test).
* Removing stray file.
* Adding type_caster_bare_interface_demo.
* Adding shared_ptr<mpty>, shared_ptr<mpty const> casters.
* Adding unique_ptr<mpty>, unique_ptr<mpty const> casters.
* Pure copy of `class class_` implementation in pybind11.h (master commit 98f1bbb8004f654ba9e26717bdf5912fb899b05a).
* classh.h: renaming of class_ to classh + namespace; forking test_classh_wip from test_type_caster_bare_interface_demo.
* Hard-coding smart_holder into classh.
* Adding mpty::mtxt string member.
* Adding isinstance<mpty> in type_caster::load functions.
* Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing const.
* Retrieving smart_holder pointer in type_caster<mpty>::load, and using it cast_op operators.
* Factoring out smart_holder_type_caster_load.
* Retrieving smart_holder pointer in type_caster<std::shared_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Improved error messaging: Cannot disown nullptr (as_unique_ptr).
* Retrieving smart_holder pointer in type_caster<std::unique_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Pure `clang-format --style=file -i` change.
* Pure `clang-format --style=file -i` change, with two `clang-format off` directives.
* Fixing oversight (discovered by flake8).
* flake8 cleanup
* Systematically setting mtxt for all rtrn_mpty_* functions (preparation, the values are not actually used yet).
* static cast handle for rtrn_cptr works by simply dropping in code from type_caster_base (marked with comments).
* static cast handle for rtrn_cref works by simply dropping in code from type_caster_base (marked with comments). rtrn_mref and rtrn_mptr work via const_cast (to add const).
* static cast handle for rtrn_valu works by simply dropping in code from type_caster_base (marked with comments). rtrn_rref raises a RuntimeError, to be investigated.
* Copying type_caster_generic::cast into type_caster<mpty> as-is (preparation for handling smart pointers).
* Pure clang-format change (applied to original type_caster_generic::cast).
* Adding comment re potential use_count data race.
* static handle cast implementations for rtrn_shmp, rtrn_shcp.
* Adding MISSING comments in operator std::unique_ptr<mpty[ const]>.
* static handle cast implementations for rtrn_uqmp, rtrn_uqcp.
* Bug fix: vptr_deleter_armed_flag_ptr has to live on the heap.
See new bullet point in comment section near the top.
The variable was also renamed to reflect its function more accurately.
* Fixing bugs discovered by ASAN. The code is now ASAN, MSAN, UBSAN clean.
* Making test_type_caster_bare_interface_demo.cpp slightly more realistic, ASAN, MSAN, UBSAN clean.
* Calling deregister_instance after disowning via unique_ptr.
* Removing enable_shared_from_this stub, simplifying existing code, clang-format.
Open question, with respect to the original code:
https://github.com/pybind/pybind11/blob/76a160070b369f8d82b945c97924227e8b835c94/include/pybind11/pybind11.h#L1510
To me it looks like the exact situation marked as `std::shared_ptr<Good> gp1 = not_so_good.getptr();` here: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
The comment there is: `// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)`
Does the existing code have UB pre C++17?
I'll leave handling of enable_shared_from_this for later, as the need arises.
* Cosmetical change around helper functions.
* Using type_caster_base<mpty>::src_and_type directly, removing copy. Also renaming one cast to cast_const_raw_ptr, for clarity.
* Fixing clang-format oversight.
* Using factored-out make_constructor (PR #2798), removing duplicate code.
* Inserting additional assert to ensure a returned unique_ptr is always a new Python instance.
* Adding minor comment (change to internals needed to distinguish uninitialized/disowned in error message).
* Factoring out find_existing_python_instance().
* Moving factored-out make_constructor to test_classh_wip.cpp, restoring previous version of cast.h. This is currently the most practical approach. See PR #2798 for background.
* Copying classh type_casters from test_classh_wip.cpp UNMODIFIED, as a baseline for generalizing the code.
* Using pybind11/detail/classh_type_casters.h from test_classh_wip.cpp.
* Adding & using PYBIND11_CLASSH_TYPE_CASTERS define.
* Adding test_classh_inheritance, currently failing (passes with class_).
* Removing .clang-format before git rebase master (where the file was added).
* Bringing back .clang-format, the previous rm was a bad idea.
* Folding in modified_type_caster_generic_load_impl, just enough to pass test_class_wip. test_classh_inheritance is still failing, but with a different error: [RuntimeError: Incompatible type (as_raw_ptr_unowned).]
* Minimal changes needed to pass test_classh_inheritance.
* First pass adjusting try_implicit_casts and try_load_foreign_module_local to capture loaded_v_h, but untested and guarded with pybind11_failure("Untested"). This was done mainly to determine general feasibility. Note the TODO in pybind11.h, where type_caster_generic::local_load is currently hard-coded. test_classh_wip and test_classh_inheritance still pass, as before.
* Decoupling generic_type from type_caster_generic.
* Changes and tests covering classh_type_casters try_implicit_casts.
* Minimal test covering classh_type_casters load_impl Case 2b.
* Removing stray isinstance<T>(src): it interferes with the py::module_local feature. Adding missing #includes.
* Tests for classh py::module_local() feature.
* Pure renaming of function names in test_classh_inheritance, similar to the systematic approach used in test_class_wip. NO functional changes.
* Pure renaming of function and variable names, for better generalization when convoluting with inheritance. NO functional changes.
* Adopting systematic naming scheme from test_classh_wip. NO functional changes.
* Moving const after type name, for functions that cover a systematic scheme. NO functional changes.
* Adding smart_holder_type_caster_load::loaded_as_shared_ptr, currently bypassing smart_holder shared_ptr tracking completely, but the tests pass and are sanitizer clean.
* Removing rtti_held from smart_holder. See updated comment.
* Cleaning up loaded_as_raw_ptr_unowned, loaded_as_shared_ptr.
* Factoring out convert_type and folding into loaded_as_unique_ptr.
* Folding convert_type into lvalue_ref and rvalue_ref paths. Some smart_holder_type_caster_load cleanup.
* Using unique_ptr in local_load to replace static variable. Also adding local_load_safety_guard.
* Converting test_unique_ptr_member to using classh: fully working, ASAN, MSAN, UBSAN clean.
* Removing debugging comments (GET_STACK, GET_INT_STACK). cast.h is identical to current master again, pybind11.h only has the generic_type::initialize(..., &type_caster_generic::local_load) change.
* Purging obsolete pybind11/vptr_holder.h and associated test.
* Moving several tests to github.com/rwgk/rwgk_tbx/tree/main/pybind11_tests
https://github.com/rwgk/rwgk_tbx/commit/a2c2f88174a30f5de80d7d26e0f77c7b60f5fb85
These tests are from experimenting, and for demonstrating UB in pybind11 multiple inheritance handling ("first_base"), to be fixed later.
* Adding py::smart_holder support to py::class_, purging py::classh completely.
* Renaming files in include directory, creating pybind11/smart_holder.h.
* Renaming all "classh" to "smart_holder" in pybind11/detail/smart_holder_type_casters.h.
The user-facing macro is now PYBIND11_SMART_HOLDER_TYPE_CASTERS.
* Systematically renaming tests to use "class_sh" in the name.
* Renaming test_type_caster_bare_interface_demo to test_type_caster_bare_interface.
* Renaming new tests/core subdirectory to tests/pure_cpp.
* Adding new tests to CMake config, resetting CI config.
* Changing CMake file so that test_class_sh_module_local.py actually runs.
* clang-tidy fixes.
* 32-bit compatibility.
* Reusing type_caster_base make_copy_constructor, make_move_constructor with a trick.
* CMake COMPARE NATURAL is not available with older versions.
* Adding copyright notices to new header files.
* Explicitly define copy/move constructors/assignments.
* Adding new header files to tests/extra_python_package/test_files.py.
* Adding tests/pure_cpp/CMakeLists.txt.
* Making use of the new find_existing_python_instance() function factored out with PR #2822.
* Moving define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T) down in the file. NO functional changes. Preparation for follow-up work (to keep that diff smaller).
* Reintroducing py::classh, this time as a simple alias for py::class_<U, py::smart_holder>.
* Replacing detail::is_smart_holder<H> in cast.h with detail::is_smart_holder_type_caster<T>.
Moving get_local_load_function_ptr, init_instance_for_type to smart_holder_type_caster_class_hooks.
Expanding static_assert in py::type::handle_of<> to accommodate smart_holder_type_casters.
* Fixing oversight.
* Adding classu alias for class_<U, std::unique_ptr<U>>.
* Giving up on idea to use legacy init_instance only if is_base_of<type_caster_generic, type_caster<T>. There are use cases in the wild that define both a custom type_caster and class_.
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Moving up is_smart_holder_type_caster, to also use in cast_is_temporary_value_reference.
* Adding smart_holder_type_casters for unique_ptr with custom deleter. SEVERE CODE DUPLICATION. This commit is to establish a baseline for consolidating the unique_ptr code.
* Unification of unique_ptr, unique_ptr_with_deleter code in smart_holder_poc.h. Leads to more fitting error messages. Enables use of unique_ptr<T, D> smart_holder_type_casters also for unique_ptr<T>.
* Copying files as-is from branch test_unique_ptr_member (PR #2672).
* Adding comment, simplifying naming, cmake addition.
* Introducing PYBIND11_USE_SMART_HOLDER_AS_DEFAULT macro (tested only undefined; there are many errors with the macro defined).
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Fixing oversight introduced with commit 95425f13d6c14fcb6ee479b62b602dc8a605ec49.
* Setting record.default_holder correctly for PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
With this test_class.cpp builds and even mostly runs, except
`test_multiple_instances_with_same_pointer`, which segfaults because it is
using a `unique_ptr` holder but `smart_holder` `type_caster`.
Also adding `static_assert`s to generate build errors for such situations,
but guarding with `#if 0` to first pivot to test_factory_constructors.cpp.
* Fixing up cast.h and smart_holder.h after rebase.
* Removing detail/smart_holder_type_casters.h in separate commit.
* Commenting out const in def_buffer(... const). With this, test_buffers builds and runs with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT. Explanation why the const needs to be removed, or fix elsewhere, is still needed, but left for later.
* Adding test_class_sh_factory_constructors, reproducing test_factory_constructors failure. Using py::class_ in this commit, to be changed to py::classh for debugging.
* Removing include/pybind11/detail/smart_holder_type_casters.h from CMakeLists.txt, test_files.py (since it does not exist in this branch).
* Adding // DANGER ZONE reminders.
* Converting as many py::class_ to py::classh as possible, not breaking tests.
* Adding initimpl::construct() overloads, resulting in test_class_sh_factory_constructors feature parity for py::class_ and py::classh.
* Adding enable_if !is_smart_holder_type_caster to existing initimpl::construct(). With this test_factory_constructors.cpp builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Disabling shared_ptr&, shared_ptr* tests when building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT for now, pending work on smart_holder_type_caster<shared_ptr>.
* Factoring out struct and class definitions into anonymous namespace. Preparation for building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Simplifying from_unique_ptr(): typename D = std::default_delete<T> is not needed. Factoring out is_std_default_delete<T>() for consistentcy between ensure_compatible_rtti_uqp_del() and from_unique_ptr().
* Introducing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. Using it in test_smart_ptr.cpp. With this test_smart_ptr builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT and all but one test run successfully.
* Introducing 1. type_caster_for_class_, used in PYBIND11_MAKE_OPAQUE, and 2. default_holder_type, used in stl_bind.h.
* Using __VA_ARGS__ in PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS.
* Replacing condense_for_macro with much simpler approach.
* Softening static_assert, to only check specifically that smart_holder is not mixed with type_caster_base, and unique_ptr/shared_ptr holders are not mixed with smart_holder_type_casters.
* Adding PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS in test_class.cpp (with this all but one test succeed with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT).
* Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for "necessary conditions" for both types of default holder, static_assert for "strict conditions" guarded by new PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX. All tests build & run as before with unique_ptr as the default holder, all tests build for smart_holder as the default holder, even with the strict static_assert.
* Introducing check_is_smart_holder_type_caster() function for runtime check, and reinterpreting record.default_holder as "uses_unique_ptr_holder". With this test_smart_ptr succeeds. (All 42 tests build, 35 tests succeed, 5 run but have some failures, 2 segfault.)
* Bug fix: Adding have_value() to smart_holder_type_caster_load. With this test_builtin_casters succeeds. (All 42 tests build, 36 tests succeed, 5 run but have some failures, 1 segfault.)
* Adding unowned_void_ptr_from_direct_conversion to modified_type_caster_generic_load_impl. This fixes the last remaining segfault (test_numpy_dtypes). New stats for all tests combined: 12 failed, 458 passed.
* Adding "Lazy allocation for unallocated values" (for old-style __init__) into load_value_and_holder. Deferring destruction of disowned holder until clear_instance, to remain inspectable for "uninitialized" or "disowned" detection. New stats for all tests combined: 5 failed, 465 passed.
* Changing std::shared_ptr pointer/reference to const pointer/reference. New stats for all tests combined: 4 failed, 466 passed.
* Adding return_value_policy::move to permissible policies for unique_ptr returns. New stats for all tests combined: 3 failed, 467 passed.
* Overlooked flake8 fixes.
* Manipulating failing ConstructorStats test to pass, to be able to run all tests with ASAN.
This version of the code is ASAN clean with unique_ptr or smart_holder as the default.
This change needs to be reverted after adopting the existing move-only-if-refcount-is-1
logic used by type_caster_base.
* Adding copy constructor and move constructor tracking to atyp. Preparation for a follow-up change in smart_holder_type_caster, to make this test sensitive to the changing behavior.
[skip ci]
* Removing `operator T&&() &&` from smart_holder_type_caster, for compatibility with the behavior of type_caster_base. Enables reverting 2 of 3 test manipulations applied under commit 249df7cbdb09817fed0ddf80f01ba5af12466820. The manipulation in test_factory_constructors.py is NOT reverted in this commit.
[skip ci]
* Fixing unfortunate editing mishap. This reverts the last remaining test manipulation in commit 249df7cbdb09817fed0ddf80f01ba5af12466820 and makes all existing unit tests pass with smart_holder as default holder.
* GitHub CI clang-tidy fixes.
* Adding messages to terse `static_assert`s, for pre-C++17 compatibility.
* Using @pytest.mark.parametrize to run each assert separately (to see all errors, not just the first).
* Systematically removing _atyp from function names, to make the test code simpler.
* Using re.match to accommodate variable number of intermediate MvCtor.
* Also removing `operator T()` from smart_holder_type_caster, to fix gcc compilation errors. The only loss is pass_rref in test_class_sh_basic.
* Systematically replacing `detail::enable_if_t<...smart_holder...>` with `typename std::enable_if<...smart_holder...>::type`. Attempt to work around MSVC 2015 issues, to be tested via GitHub CI. The idea for this change originates from this comment: https://github.com/pybind/pybind11/issues/1616#issuecomment-444536813
* Importing re before pytest after observing a PyPy CI flake when importing pytest first.
* Copying MSVC 2015 compatibility change from branch pr2672_use_smart_holder_as_default.
* Introducing is_smart_holder_type_caster_base_tag, to keep smart_holder code more disconnected.
* Working around MSVC 2015 bug.
* Expanding comment for MSVC 2015 workaround.
* Systematically changing std::enable_if back to detail::enable_if_t, effectively reverting commit 5d4b6890a337ae1bbaec4091f4195606f89a3b06.
* Removing unused smart_holder_type_caster_load::loaded_as_rvalue_ref (it was an oversight that it was not removed with commit 23036a45eb4731a06b488ec1fdf83bca677b7f67).
* Removing py::classu, because it does not seem useful enough.
* Reverting commit 63495313066119dcf7510c2ae8b468b46c12ef8f by un-commenting `const` in `def_buffer(...)`. To make this possible, `operator T const&` and `operator T const*` in `smart_holder_type_caster` need to be marked as `const` member functions.
* Adding construct() overloads for constructing smart_holder from alias unique_ptr, shared_ptr returns.
* Adding test_class_sh_factory_constructors.cpp to tests/CMakeLists.txt (fixes oversight, this should have been added long before).
* Compatibility with old clang versions (clang 3.6, 3.7 C++11).
* Cleaning up changes to existing unit tests.
* Systematically adding SMART_HOLDER_WIP tag. Removing minor UNTESTED tags (only the throw are not actually exercised, investing time there has a high cost but very little benefit).
* Splitting out smart_holder_type_casters again, into new detail/smart_holder_type_casters_inline_include.h.
* Splitting out smart_holder_init_inline_include.h.
* Adding additional new include files to CMakeLists.txt, tests/extra_python_package/test_files.py.
* clang-format cleanup of most smart_holder code.
* Adding source code comments in response to review.
* Simple micro-benchmark ("ubench") comparing runtime performance for several holders.
Tested using github.com/rwgk/pybind11_scons and Google-internal build system.
Sorry, no cmake support at the moment.
First results: https://docs.google.com/spreadsheets/d/1InapCYws2Gt-stmFf_Bwl33eOMo3aLE_gc9adveY7RU/edit#gid=0
* Breaking out number_bucket.h, adding hook for also collecting performance data for PyCLIF.
* Accounting for ubench in MANIFEST.in (simply prune, for now).
* Smarter determination of call_repetitions.
[skip ci]
* Also scaling performance data to PyCLIF.
[skip ci]
* Adding ubench/python/number_bucket.clif here for general visibility.
* Fix after rebase
* Merging detail/smart_holder_init_inline_include.h into detail/init.h.
* Renaming detail/is_smart_holder_type_caster.h -> detail/smart_holder_sfinae_hooks_only.h.
* Renaming is_smart_holder_type_caster -> type_uses_smart_holder_type_caster for clarity.
* Renaming type_caster_type_is_smart_holder_type_caster -> wrapped_type_uses_smart_holder_type_caster for clarity.
* Renaming is_smart_holder_type_caster_base_tag -> smart_holder_type_caster_base_tag for simplicity.
* Adding copyright notices and minor colateral cleanup.
* iwyu cleanup (comprehensive only for cast.h and smart_holder*.h files).
* Fixing `git rebase master` accident.
* Moving large `pragma warning` block from pybind11.h to detail/common.h.
* Fixing another `git rebase master` accident.
2021-02-24 05:50:42 +00:00
|
|
|
// test_mismatched_holder
|
|
|
|
struct MismatchBase1 { };
|
|
|
|
struct MismatchDerived1 : MismatchBase1 { };
|
|
|
|
struct MismatchBase2 { };
|
|
|
|
struct MismatchDerived2 : MismatchBase2 { };
|
|
|
|
|
|
|
|
// test_multiple_instances_with_same_pointer
|
|
|
|
struct SamePointer {};
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchBase1, std::shared_ptr<MismatchBase1>)
|
|
|
|
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchDerived1, std::unique_ptr<MismatchDerived1>)
|
|
|
|
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchBase2, std::unique_ptr<MismatchBase2>)
|
|
|
|
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(MismatchDerived2, std::shared_ptr<MismatchDerived2>)
|
|
|
|
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(SamePointer, std::unique_ptr<SamePointer>)
|
|
|
|
|
2017-06-08 22:44:49 +00:00
|
|
|
TEST_SUBMODULE(class_, m) {
|
|
|
|
// test_instance
|
|
|
|
struct NoConstructor {
|
2017-11-20 13:19:53 +00:00
|
|
|
NoConstructor() = default;
|
|
|
|
NoConstructor(const NoConstructor &) = default;
|
|
|
|
NoConstructor(NoConstructor &&) = default;
|
2017-06-08 22:44:49 +00:00
|
|
|
static NoConstructor *new_instance() {
|
|
|
|
auto *ptr = new NoConstructor();
|
|
|
|
print_created(ptr, "via new_instance");
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
~NoConstructor() { print_destroyed(this); }
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<NoConstructor>(m, "NoConstructor")
|
|
|
|
.def_static("new_instance", &NoConstructor::new_instance, "Return an instance");
|
2017-06-22 21:42:11 +00:00
|
|
|
|
|
|
|
// test_inheritance
|
|
|
|
class Pet {
|
|
|
|
public:
|
|
|
|
Pet(const std::string &name, const std::string &species)
|
|
|
|
: m_name(name), m_species(species) {}
|
|
|
|
std::string name() const { return m_name; }
|
|
|
|
std::string species() const { return m_species; }
|
|
|
|
private:
|
|
|
|
std::string m_name;
|
|
|
|
std::string m_species;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Dog : public Pet {
|
|
|
|
public:
|
|
|
|
Dog(const std::string &name) : Pet(name, "dog") {}
|
|
|
|
std::string bark() const { return "Woof!"; }
|
|
|
|
};
|
|
|
|
|
|
|
|
class Rabbit : public Pet {
|
|
|
|
public:
|
|
|
|
Rabbit(const std::string &name) : Pet(name, "parrot") {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Hamster : public Pet {
|
|
|
|
public:
|
|
|
|
Hamster(const std::string &name) : Pet(name, "rodent") {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Chimera : public Pet {
|
|
|
|
Chimera() : Pet("Kimmy", "chimera") {}
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<Pet> pet_class(m, "Pet");
|
|
|
|
pet_class
|
|
|
|
.def(py::init<std::string, std::string>())
|
|
|
|
.def("name", &Pet::name)
|
|
|
|
.def("species", &Pet::species);
|
|
|
|
|
|
|
|
/* One way of declaring a subclass relationship: reference parent's class_ object */
|
|
|
|
py::class_<Dog>(m, "Dog", pet_class)
|
|
|
|
.def(py::init<std::string>());
|
|
|
|
|
|
|
|
/* Another way of declaring a subclass relationship: reference parent's C++ type */
|
|
|
|
py::class_<Rabbit, Pet>(m, "Rabbit")
|
|
|
|
.def(py::init<std::string>());
|
|
|
|
|
|
|
|
/* And another: list parent in class template arguments */
|
|
|
|
py::class_<Hamster, Pet>(m, "Hamster")
|
|
|
|
.def(py::init<std::string>());
|
|
|
|
|
|
|
|
/* Constructors are not inherited by default */
|
|
|
|
py::class_<Chimera, Pet>(m, "Chimera");
|
|
|
|
|
|
|
|
m.def("pet_name_species", [](const Pet &pet) { return pet.name() + " is a " + pet.species(); });
|
|
|
|
m.def("dog_bark", [](const Dog &dog) { return dog.bark(); });
|
|
|
|
|
|
|
|
// test_automatic_upcasting
|
2017-11-20 13:19:53 +00:00
|
|
|
struct BaseClass {
|
|
|
|
BaseClass() = default;
|
|
|
|
BaseClass(const BaseClass &) = default;
|
|
|
|
BaseClass(BaseClass &&) = default;
|
2020-09-11 03:15:22 +00:00
|
|
|
virtual ~BaseClass() = default;
|
2017-11-20 13:19:53 +00:00
|
|
|
};
|
2017-06-22 21:42:11 +00:00
|
|
|
struct DerivedClass1 : BaseClass { };
|
|
|
|
struct DerivedClass2 : BaseClass { };
|
|
|
|
|
|
|
|
py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
|
|
|
|
py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
|
|
|
|
py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());
|
|
|
|
|
|
|
|
m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); });
|
|
|
|
m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); });
|
|
|
|
m.def("return_class_n", [](int n) -> BaseClass* {
|
|
|
|
if (n == 1) return new DerivedClass1();
|
|
|
|
if (n == 2) return new DerivedClass2();
|
|
|
|
return new BaseClass();
|
|
|
|
});
|
|
|
|
m.def("return_none", []() -> BaseClass* { return nullptr; });
|
|
|
|
|
|
|
|
// test_isinstance
|
|
|
|
m.def("check_instances", [](py::list l) {
|
|
|
|
return py::make_tuple(
|
|
|
|
py::isinstance<py::tuple>(l[0]),
|
|
|
|
py::isinstance<py::dict>(l[1]),
|
|
|
|
py::isinstance<Pet>(l[2]),
|
|
|
|
py::isinstance<Pet>(l[3]),
|
|
|
|
py::isinstance<Dog>(l[4]),
|
|
|
|
py::isinstance<Rabbit>(l[5]),
|
|
|
|
py::isinstance<UnregisteredType>(l[6])
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2020-09-14 22:06:26 +00:00
|
|
|
struct Invalid {};
|
|
|
|
|
|
|
|
// test_type
|
|
|
|
m.def("check_type", [](int category) {
|
|
|
|
// Currently not supported (via a fail at compile time)
|
|
|
|
// See https://github.com/pybind/pybind11/issues/2486
|
|
|
|
// if (category == 2)
|
|
|
|
// return py::type::of<int>();
|
|
|
|
if (category == 1)
|
|
|
|
return py::type::of<DerivedClass1>();
|
|
|
|
else
|
|
|
|
return py::type::of<Invalid>();
|
|
|
|
});
|
|
|
|
|
|
|
|
m.def("get_type_of", [](py::object ob) {
|
|
|
|
return py::type::of(ob);
|
|
|
|
});
|
|
|
|
|
2020-09-17 02:02:09 +00:00
|
|
|
m.def("get_type_classic", [](py::handle h) {
|
|
|
|
return h.get_type();
|
|
|
|
});
|
|
|
|
|
2020-09-14 22:06:26 +00:00
|
|
|
m.def("as_type", [](py::object ob) {
|
2020-10-05 20:48:54 +00:00
|
|
|
return py::type(ob);
|
2020-09-14 22:06:26 +00:00
|
|
|
});
|
|
|
|
|
2017-06-22 21:42:11 +00:00
|
|
|
// test_mismatched_holder
|
|
|
|
m.def("mismatched_holder_1", []() {
|
2020-10-03 17:38:03 +00:00
|
|
|
auto mod = py::module_::import("__main__");
|
2017-06-22 21:42:11 +00:00
|
|
|
py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1");
|
Adding py::smart_holder (for smart-pointer interoperability). (#2672)
* Adding test_unique_ptr_member (for desired PyCLIF behavior).
See also: https://github.com/pybind/pybind11/issues/2583
Does not build with upstream master or
https://github.com/pybind/pybind11/pull/2047, but builds with
https://github.com/RobotLocomotion/pybind11 and almost runs:
```
Running tests in directory "/usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests":
================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.5, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests, inifile: pytest.ini
collected 2 items
test_unique_ptr_member.py .F [100%]
====================================================================================== FAILURES =======================================================================================
_____________________________________________________________________________ test_pointee_and_ptr_owner ______________________________________________________________________________
def test_pointee_and_ptr_owner():
obj = m.pointee()
assert obj.get_int() == 213
m.ptr_owner(obj)
with pytest.raises(ValueError) as exc_info:
> obj.get_int()
E Failed: DID NOT RAISE <class 'ValueError'>
test_unique_ptr_member.py:17: Failed
============================================================================= 1 failed, 1 passed in 0.06s =============================================================================
```
* unique_ptr or shared_ptr return
* new test_variant_unique_shared with vptr_holder prototype
* moving prototype code to pybind11/vptr_holder.h, adding type_caster specialization to make the bindings involving unique_ptr passing compile, but load and cast implementations are missing
* disabling GitHub Actions on pull_request (for this PR)
* disabling AppVeyor (for this PR)
* TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_STACK (pointee)
* adding test_promotion_of_disowned_to_shared
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising returning and passing unique_ptr<T>, shared_ptr<T>
with unique_ptr, shared_ptr holder.
Observations:
test_holder_unique_ptr:
make_unique_pointee OK
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee Abort free(): double free detected
pass_shared_pointee RuntimeError: Unable to load a custom holder type from a default-holder instance
test_holder_shared_ptr:
make_unique_pointee Segmentation fault (#1138)
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee OK
pass_shared_pointee OK
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising casting between shared_ptr<base>, shared_ptr<derived>.
* Demonstration of Undefined Behavior in handling of shared_ptr holder.
Based on https://godbolt.org/z/4fdjaW by jorgbrown@ (thanks Jorg!).
* Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
* fixing up-down mixup in comment
* Demonstration of Undefined Behavior in handling of polymorphic pointers.
(This demo does NOT involve smart pointers at all, unlike the otherwise similar test_smart_ptr_private_first_base.)
* minor test_private_first_base.cpp simplification (after discovering that this can be wrapped with Boost.Python, using boost::noncopyable)
* pybind11 equivalent of Boost.Python test similar to reproducer under #1333
* Snapshot of WIP, TODO: shared_ptr deleter with on/off switch
* Adding vptr_deleter.
* Adding from/as unique_ptr<T> and unique_ptr<T, D>.
* Adding from_shared_ptr. Some polishing.
* New tests/core/smart_holder_poc_test.cpp, using Catch2.
* Adding in vptr_deleter_guard_flag.
* Improved labeling of TEST_CASEs.
* Shuffling existing TEST_CASEs into systematic matrix.
* Implementing all [S]uccess tests.
* Implementing all [E]xception tests.
* Testing of exceptions not covered by the from-as matrix.
* Adding top-level comment.
* Converting from methods to factory functions (no functional change).
* Removing obsolete and very incomplete test (replaced by Catch2-based test).
* Removing stray file.
* Adding type_caster_bare_interface_demo.
* Adding shared_ptr<mpty>, shared_ptr<mpty const> casters.
* Adding unique_ptr<mpty>, unique_ptr<mpty const> casters.
* Pure copy of `class class_` implementation in pybind11.h (master commit 98f1bbb8004f654ba9e26717bdf5912fb899b05a).
* classh.h: renaming of class_ to classh + namespace; forking test_classh_wip from test_type_caster_bare_interface_demo.
* Hard-coding smart_holder into classh.
* Adding mpty::mtxt string member.
* Adding isinstance<mpty> in type_caster::load functions.
* Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing const.
* Retrieving smart_holder pointer in type_caster<mpty>::load, and using it cast_op operators.
* Factoring out smart_holder_type_caster_load.
* Retrieving smart_holder pointer in type_caster<std::shared_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Improved error messaging: Cannot disown nullptr (as_unique_ptr).
* Retrieving smart_holder pointer in type_caster<std::unique_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Pure `clang-format --style=file -i` change.
* Pure `clang-format --style=file -i` change, with two `clang-format off` directives.
* Fixing oversight (discovered by flake8).
* flake8 cleanup
* Systematically setting mtxt for all rtrn_mpty_* functions (preparation, the values are not actually used yet).
* static cast handle for rtrn_cptr works by simply dropping in code from type_caster_base (marked with comments).
* static cast handle for rtrn_cref works by simply dropping in code from type_caster_base (marked with comments). rtrn_mref and rtrn_mptr work via const_cast (to add const).
* static cast handle for rtrn_valu works by simply dropping in code from type_caster_base (marked with comments). rtrn_rref raises a RuntimeError, to be investigated.
* Copying type_caster_generic::cast into type_caster<mpty> as-is (preparation for handling smart pointers).
* Pure clang-format change (applied to original type_caster_generic::cast).
* Adding comment re potential use_count data race.
* static handle cast implementations for rtrn_shmp, rtrn_shcp.
* Adding MISSING comments in operator std::unique_ptr<mpty[ const]>.
* static handle cast implementations for rtrn_uqmp, rtrn_uqcp.
* Bug fix: vptr_deleter_armed_flag_ptr has to live on the heap.
See new bullet point in comment section near the top.
The variable was also renamed to reflect its function more accurately.
* Fixing bugs discovered by ASAN. The code is now ASAN, MSAN, UBSAN clean.
* Making test_type_caster_bare_interface_demo.cpp slightly more realistic, ASAN, MSAN, UBSAN clean.
* Calling deregister_instance after disowning via unique_ptr.
* Removing enable_shared_from_this stub, simplifying existing code, clang-format.
Open question, with respect to the original code:
https://github.com/pybind/pybind11/blob/76a160070b369f8d82b945c97924227e8b835c94/include/pybind11/pybind11.h#L1510
To me it looks like the exact situation marked as `std::shared_ptr<Good> gp1 = not_so_good.getptr();` here: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
The comment there is: `// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)`
Does the existing code have UB pre C++17?
I'll leave handling of enable_shared_from_this for later, as the need arises.
* Cosmetical change around helper functions.
* Using type_caster_base<mpty>::src_and_type directly, removing copy. Also renaming one cast to cast_const_raw_ptr, for clarity.
* Fixing clang-format oversight.
* Using factored-out make_constructor (PR #2798), removing duplicate code.
* Inserting additional assert to ensure a returned unique_ptr is always a new Python instance.
* Adding minor comment (change to internals needed to distinguish uninitialized/disowned in error message).
* Factoring out find_existing_python_instance().
* Moving factored-out make_constructor to test_classh_wip.cpp, restoring previous version of cast.h. This is currently the most practical approach. See PR #2798 for background.
* Copying classh type_casters from test_classh_wip.cpp UNMODIFIED, as a baseline for generalizing the code.
* Using pybind11/detail/classh_type_casters.h from test_classh_wip.cpp.
* Adding & using PYBIND11_CLASSH_TYPE_CASTERS define.
* Adding test_classh_inheritance, currently failing (passes with class_).
* Removing .clang-format before git rebase master (where the file was added).
* Bringing back .clang-format, the previous rm was a bad idea.
* Folding in modified_type_caster_generic_load_impl, just enough to pass test_class_wip. test_classh_inheritance is still failing, but with a different error: [RuntimeError: Incompatible type (as_raw_ptr_unowned).]
* Minimal changes needed to pass test_classh_inheritance.
* First pass adjusting try_implicit_casts and try_load_foreign_module_local to capture loaded_v_h, but untested and guarded with pybind11_failure("Untested"). This was done mainly to determine general feasibility. Note the TODO in pybind11.h, where type_caster_generic::local_load is currently hard-coded. test_classh_wip and test_classh_inheritance still pass, as before.
* Decoupling generic_type from type_caster_generic.
* Changes and tests covering classh_type_casters try_implicit_casts.
* Minimal test covering classh_type_casters load_impl Case 2b.
* Removing stray isinstance<T>(src): it interferes with the py::module_local feature. Adding missing #includes.
* Tests for classh py::module_local() feature.
* Pure renaming of function names in test_classh_inheritance, similar to the systematic approach used in test_class_wip. NO functional changes.
* Pure renaming of function and variable names, for better generalization when convoluting with inheritance. NO functional changes.
* Adopting systematic naming scheme from test_classh_wip. NO functional changes.
* Moving const after type name, for functions that cover a systematic scheme. NO functional changes.
* Adding smart_holder_type_caster_load::loaded_as_shared_ptr, currently bypassing smart_holder shared_ptr tracking completely, but the tests pass and are sanitizer clean.
* Removing rtti_held from smart_holder. See updated comment.
* Cleaning up loaded_as_raw_ptr_unowned, loaded_as_shared_ptr.
* Factoring out convert_type and folding into loaded_as_unique_ptr.
* Folding convert_type into lvalue_ref and rvalue_ref paths. Some smart_holder_type_caster_load cleanup.
* Using unique_ptr in local_load to replace static variable. Also adding local_load_safety_guard.
* Converting test_unique_ptr_member to using classh: fully working, ASAN, MSAN, UBSAN clean.
* Removing debugging comments (GET_STACK, GET_INT_STACK). cast.h is identical to current master again, pybind11.h only has the generic_type::initialize(..., &type_caster_generic::local_load) change.
* Purging obsolete pybind11/vptr_holder.h and associated test.
* Moving several tests to github.com/rwgk/rwgk_tbx/tree/main/pybind11_tests
https://github.com/rwgk/rwgk_tbx/commit/a2c2f88174a30f5de80d7d26e0f77c7b60f5fb85
These tests are from experimenting, and for demonstrating UB in pybind11 multiple inheritance handling ("first_base"), to be fixed later.
* Adding py::smart_holder support to py::class_, purging py::classh completely.
* Renaming files in include directory, creating pybind11/smart_holder.h.
* Renaming all "classh" to "smart_holder" in pybind11/detail/smart_holder_type_casters.h.
The user-facing macro is now PYBIND11_SMART_HOLDER_TYPE_CASTERS.
* Systematically renaming tests to use "class_sh" in the name.
* Renaming test_type_caster_bare_interface_demo to test_type_caster_bare_interface.
* Renaming new tests/core subdirectory to tests/pure_cpp.
* Adding new tests to CMake config, resetting CI config.
* Changing CMake file so that test_class_sh_module_local.py actually runs.
* clang-tidy fixes.
* 32-bit compatibility.
* Reusing type_caster_base make_copy_constructor, make_move_constructor with a trick.
* CMake COMPARE NATURAL is not available with older versions.
* Adding copyright notices to new header files.
* Explicitly define copy/move constructors/assignments.
* Adding new header files to tests/extra_python_package/test_files.py.
* Adding tests/pure_cpp/CMakeLists.txt.
* Making use of the new find_existing_python_instance() function factored out with PR #2822.
* Moving define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T) down in the file. NO functional changes. Preparation for follow-up work (to keep that diff smaller).
* Reintroducing py::classh, this time as a simple alias for py::class_<U, py::smart_holder>.
* Replacing detail::is_smart_holder<H> in cast.h with detail::is_smart_holder_type_caster<T>.
Moving get_local_load_function_ptr, init_instance_for_type to smart_holder_type_caster_class_hooks.
Expanding static_assert in py::type::handle_of<> to accommodate smart_holder_type_casters.
* Fixing oversight.
* Adding classu alias for class_<U, std::unique_ptr<U>>.
* Giving up on idea to use legacy init_instance only if is_base_of<type_caster_generic, type_caster<T>. There are use cases in the wild that define both a custom type_caster and class_.
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Moving up is_smart_holder_type_caster, to also use in cast_is_temporary_value_reference.
* Adding smart_holder_type_casters for unique_ptr with custom deleter. SEVERE CODE DUPLICATION. This commit is to establish a baseline for consolidating the unique_ptr code.
* Unification of unique_ptr, unique_ptr_with_deleter code in smart_holder_poc.h. Leads to more fitting error messages. Enables use of unique_ptr<T, D> smart_holder_type_casters also for unique_ptr<T>.
* Copying files as-is from branch test_unique_ptr_member (PR #2672).
* Adding comment, simplifying naming, cmake addition.
* Introducing PYBIND11_USE_SMART_HOLDER_AS_DEFAULT macro (tested only undefined; there are many errors with the macro defined).
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Fixing oversight introduced with commit 95425f13d6c14fcb6ee479b62b602dc8a605ec49.
* Setting record.default_holder correctly for PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
With this test_class.cpp builds and even mostly runs, except
`test_multiple_instances_with_same_pointer`, which segfaults because it is
using a `unique_ptr` holder but `smart_holder` `type_caster`.
Also adding `static_assert`s to generate build errors for such situations,
but guarding with `#if 0` to first pivot to test_factory_constructors.cpp.
* Fixing up cast.h and smart_holder.h after rebase.
* Removing detail/smart_holder_type_casters.h in separate commit.
* Commenting out const in def_buffer(... const). With this, test_buffers builds and runs with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT. Explanation why the const needs to be removed, or fix elsewhere, is still needed, but left for later.
* Adding test_class_sh_factory_constructors, reproducing test_factory_constructors failure. Using py::class_ in this commit, to be changed to py::classh for debugging.
* Removing include/pybind11/detail/smart_holder_type_casters.h from CMakeLists.txt, test_files.py (since it does not exist in this branch).
* Adding // DANGER ZONE reminders.
* Converting as many py::class_ to py::classh as possible, not breaking tests.
* Adding initimpl::construct() overloads, resulting in test_class_sh_factory_constructors feature parity for py::class_ and py::classh.
* Adding enable_if !is_smart_holder_type_caster to existing initimpl::construct(). With this test_factory_constructors.cpp builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Disabling shared_ptr&, shared_ptr* tests when building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT for now, pending work on smart_holder_type_caster<shared_ptr>.
* Factoring out struct and class definitions into anonymous namespace. Preparation for building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Simplifying from_unique_ptr(): typename D = std::default_delete<T> is not needed. Factoring out is_std_default_delete<T>() for consistentcy between ensure_compatible_rtti_uqp_del() and from_unique_ptr().
* Introducing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. Using it in test_smart_ptr.cpp. With this test_smart_ptr builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT and all but one test run successfully.
* Introducing 1. type_caster_for_class_, used in PYBIND11_MAKE_OPAQUE, and 2. default_holder_type, used in stl_bind.h.
* Using __VA_ARGS__ in PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS.
* Replacing condense_for_macro with much simpler approach.
* Softening static_assert, to only check specifically that smart_holder is not mixed with type_caster_base, and unique_ptr/shared_ptr holders are not mixed with smart_holder_type_casters.
* Adding PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS in test_class.cpp (with this all but one test succeed with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT).
* Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for "necessary conditions" for both types of default holder, static_assert for "strict conditions" guarded by new PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX. All tests build & run as before with unique_ptr as the default holder, all tests build for smart_holder as the default holder, even with the strict static_assert.
* Introducing check_is_smart_holder_type_caster() function for runtime check, and reinterpreting record.default_holder as "uses_unique_ptr_holder". With this test_smart_ptr succeeds. (All 42 tests build, 35 tests succeed, 5 run but have some failures, 2 segfault.)
* Bug fix: Adding have_value() to smart_holder_type_caster_load. With this test_builtin_casters succeeds. (All 42 tests build, 36 tests succeed, 5 run but have some failures, 1 segfault.)
* Adding unowned_void_ptr_from_direct_conversion to modified_type_caster_generic_load_impl. This fixes the last remaining segfault (test_numpy_dtypes). New stats for all tests combined: 12 failed, 458 passed.
* Adding "Lazy allocation for unallocated values" (for old-style __init__) into load_value_and_holder. Deferring destruction of disowned holder until clear_instance, to remain inspectable for "uninitialized" or "disowned" detection. New stats for all tests combined: 5 failed, 465 passed.
* Changing std::shared_ptr pointer/reference to const pointer/reference. New stats for all tests combined: 4 failed, 466 passed.
* Adding return_value_policy::move to permissible policies for unique_ptr returns. New stats for all tests combined: 3 failed, 467 passed.
* Overlooked flake8 fixes.
* Manipulating failing ConstructorStats test to pass, to be able to run all tests with ASAN.
This version of the code is ASAN clean with unique_ptr or smart_holder as the default.
This change needs to be reverted after adopting the existing move-only-if-refcount-is-1
logic used by type_caster_base.
* Adding copy constructor and move constructor tracking to atyp. Preparation for a follow-up change in smart_holder_type_caster, to make this test sensitive to the changing behavior.
[skip ci]
* Removing `operator T&&() &&` from smart_holder_type_caster, for compatibility with the behavior of type_caster_base. Enables reverting 2 of 3 test manipulations applied under commit 249df7cbdb09817fed0ddf80f01ba5af12466820. The manipulation in test_factory_constructors.py is NOT reverted in this commit.
[skip ci]
* Fixing unfortunate editing mishap. This reverts the last remaining test manipulation in commit 249df7cbdb09817fed0ddf80f01ba5af12466820 and makes all existing unit tests pass with smart_holder as default holder.
* GitHub CI clang-tidy fixes.
* Adding messages to terse `static_assert`s, for pre-C++17 compatibility.
* Using @pytest.mark.parametrize to run each assert separately (to see all errors, not just the first).
* Systematically removing _atyp from function names, to make the test code simpler.
* Using re.match to accommodate variable number of intermediate MvCtor.
* Also removing `operator T()` from smart_holder_type_caster, to fix gcc compilation errors. The only loss is pass_rref in test_class_sh_basic.
* Systematically replacing `detail::enable_if_t<...smart_holder...>` with `typename std::enable_if<...smart_holder...>::type`. Attempt to work around MSVC 2015 issues, to be tested via GitHub CI. The idea for this change originates from this comment: https://github.com/pybind/pybind11/issues/1616#issuecomment-444536813
* Importing re before pytest after observing a PyPy CI flake when importing pytest first.
* Copying MSVC 2015 compatibility change from branch pr2672_use_smart_holder_as_default.
* Introducing is_smart_holder_type_caster_base_tag, to keep smart_holder code more disconnected.
* Working around MSVC 2015 bug.
* Expanding comment for MSVC 2015 workaround.
* Systematically changing std::enable_if back to detail::enable_if_t, effectively reverting commit 5d4b6890a337ae1bbaec4091f4195606f89a3b06.
* Removing unused smart_holder_type_caster_load::loaded_as_rvalue_ref (it was an oversight that it was not removed with commit 23036a45eb4731a06b488ec1fdf83bca677b7f67).
* Removing py::classu, because it does not seem useful enough.
* Reverting commit 63495313066119dcf7510c2ae8b468b46c12ef8f by un-commenting `const` in `def_buffer(...)`. To make this possible, `operator T const&` and `operator T const*` in `smart_holder_type_caster` need to be marked as `const` member functions.
* Adding construct() overloads for constructing smart_holder from alias unique_ptr, shared_ptr returns.
* Adding test_class_sh_factory_constructors.cpp to tests/CMakeLists.txt (fixes oversight, this should have been added long before).
* Compatibility with old clang versions (clang 3.6, 3.7 C++11).
* Cleaning up changes to existing unit tests.
* Systematically adding SMART_HOLDER_WIP tag. Removing minor UNTESTED tags (only the throw are not actually exercised, investing time there has a high cost but very little benefit).
* Splitting out smart_holder_type_casters again, into new detail/smart_holder_type_casters_inline_include.h.
* Splitting out smart_holder_init_inline_include.h.
* Adding additional new include files to CMakeLists.txt, tests/extra_python_package/test_files.py.
* clang-format cleanup of most smart_holder code.
* Adding source code comments in response to review.
* Simple micro-benchmark ("ubench") comparing runtime performance for several holders.
Tested using github.com/rwgk/pybind11_scons and Google-internal build system.
Sorry, no cmake support at the moment.
First results: https://docs.google.com/spreadsheets/d/1InapCYws2Gt-stmFf_Bwl33eOMo3aLE_gc9adveY7RU/edit#gid=0
* Breaking out number_bucket.h, adding hook for also collecting performance data for PyCLIF.
* Accounting for ubench in MANIFEST.in (simply prune, for now).
* Smarter determination of call_repetitions.
[skip ci]
* Also scaling performance data to PyCLIF.
[skip ci]
* Adding ubench/python/number_bucket.clif here for general visibility.
* Fix after rebase
* Merging detail/smart_holder_init_inline_include.h into detail/init.h.
* Renaming detail/is_smart_holder_type_caster.h -> detail/smart_holder_sfinae_hooks_only.h.
* Renaming is_smart_holder_type_caster -> type_uses_smart_holder_type_caster for clarity.
* Renaming type_caster_type_is_smart_holder_type_caster -> wrapped_type_uses_smart_holder_type_caster for clarity.
* Renaming is_smart_holder_type_caster_base_tag -> smart_holder_type_caster_base_tag for simplicity.
* Adding copyright notices and minor colateral cleanup.
* iwyu cleanup (comprehensive only for cast.h and smart_holder*.h files).
* Fixing `git rebase master` accident.
* Moving large `pragma warning` block from pybind11.h to detail/common.h.
* Fixing another `git rebase master` accident.
2021-02-24 05:50:42 +00:00
|
|
|
py::class_<MismatchDerived1, std::unique_ptr<MismatchDerived1>,
|
|
|
|
MismatchBase1>(mod, "MismatchDerived1");
|
2017-06-22 21:42:11 +00:00
|
|
|
});
|
|
|
|
m.def("mismatched_holder_2", []() {
|
2020-10-03 17:38:03 +00:00
|
|
|
auto mod = py::module_::import("__main__");
|
Adding py::smart_holder (for smart-pointer interoperability). (#2672)
* Adding test_unique_ptr_member (for desired PyCLIF behavior).
See also: https://github.com/pybind/pybind11/issues/2583
Does not build with upstream master or
https://github.com/pybind/pybind11/pull/2047, but builds with
https://github.com/RobotLocomotion/pybind11 and almost runs:
```
Running tests in directory "/usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests":
================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.5, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests, inifile: pytest.ini
collected 2 items
test_unique_ptr_member.py .F [100%]
====================================================================================== FAILURES =======================================================================================
_____________________________________________________________________________ test_pointee_and_ptr_owner ______________________________________________________________________________
def test_pointee_and_ptr_owner():
obj = m.pointee()
assert obj.get_int() == 213
m.ptr_owner(obj)
with pytest.raises(ValueError) as exc_info:
> obj.get_int()
E Failed: DID NOT RAISE <class 'ValueError'>
test_unique_ptr_member.py:17: Failed
============================================================================= 1 failed, 1 passed in 0.06s =============================================================================
```
* unique_ptr or shared_ptr return
* new test_variant_unique_shared with vptr_holder prototype
* moving prototype code to pybind11/vptr_holder.h, adding type_caster specialization to make the bindings involving unique_ptr passing compile, but load and cast implementations are missing
* disabling GitHub Actions on pull_request (for this PR)
* disabling AppVeyor (for this PR)
* TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_STACK (pointee)
* adding test_promotion_of_disowned_to_shared
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising returning and passing unique_ptr<T>, shared_ptr<T>
with unique_ptr, shared_ptr holder.
Observations:
test_holder_unique_ptr:
make_unique_pointee OK
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee Abort free(): double free detected
pass_shared_pointee RuntimeError: Unable to load a custom holder type from a default-holder instance
test_holder_shared_ptr:
make_unique_pointee Segmentation fault (#1138)
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee OK
pass_shared_pointee OK
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising casting between shared_ptr<base>, shared_ptr<derived>.
* Demonstration of Undefined Behavior in handling of shared_ptr holder.
Based on https://godbolt.org/z/4fdjaW by jorgbrown@ (thanks Jorg!).
* Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
* fixing up-down mixup in comment
* Demonstration of Undefined Behavior in handling of polymorphic pointers.
(This demo does NOT involve smart pointers at all, unlike the otherwise similar test_smart_ptr_private_first_base.)
* minor test_private_first_base.cpp simplification (after discovering that this can be wrapped with Boost.Python, using boost::noncopyable)
* pybind11 equivalent of Boost.Python test similar to reproducer under #1333
* Snapshot of WIP, TODO: shared_ptr deleter with on/off switch
* Adding vptr_deleter.
* Adding from/as unique_ptr<T> and unique_ptr<T, D>.
* Adding from_shared_ptr. Some polishing.
* New tests/core/smart_holder_poc_test.cpp, using Catch2.
* Adding in vptr_deleter_guard_flag.
* Improved labeling of TEST_CASEs.
* Shuffling existing TEST_CASEs into systematic matrix.
* Implementing all [S]uccess tests.
* Implementing all [E]xception tests.
* Testing of exceptions not covered by the from-as matrix.
* Adding top-level comment.
* Converting from methods to factory functions (no functional change).
* Removing obsolete and very incomplete test (replaced by Catch2-based test).
* Removing stray file.
* Adding type_caster_bare_interface_demo.
* Adding shared_ptr<mpty>, shared_ptr<mpty const> casters.
* Adding unique_ptr<mpty>, unique_ptr<mpty const> casters.
* Pure copy of `class class_` implementation in pybind11.h (master commit 98f1bbb8004f654ba9e26717bdf5912fb899b05a).
* classh.h: renaming of class_ to classh + namespace; forking test_classh_wip from test_type_caster_bare_interface_demo.
* Hard-coding smart_holder into classh.
* Adding mpty::mtxt string member.
* Adding isinstance<mpty> in type_caster::load functions.
* Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing const.
* Retrieving smart_holder pointer in type_caster<mpty>::load, and using it cast_op operators.
* Factoring out smart_holder_type_caster_load.
* Retrieving smart_holder pointer in type_caster<std::shared_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Improved error messaging: Cannot disown nullptr (as_unique_ptr).
* Retrieving smart_holder pointer in type_caster<std::unique_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Pure `clang-format --style=file -i` change.
* Pure `clang-format --style=file -i` change, with two `clang-format off` directives.
* Fixing oversight (discovered by flake8).
* flake8 cleanup
* Systematically setting mtxt for all rtrn_mpty_* functions (preparation, the values are not actually used yet).
* static cast handle for rtrn_cptr works by simply dropping in code from type_caster_base (marked with comments).
* static cast handle for rtrn_cref works by simply dropping in code from type_caster_base (marked with comments). rtrn_mref and rtrn_mptr work via const_cast (to add const).
* static cast handle for rtrn_valu works by simply dropping in code from type_caster_base (marked with comments). rtrn_rref raises a RuntimeError, to be investigated.
* Copying type_caster_generic::cast into type_caster<mpty> as-is (preparation for handling smart pointers).
* Pure clang-format change (applied to original type_caster_generic::cast).
* Adding comment re potential use_count data race.
* static handle cast implementations for rtrn_shmp, rtrn_shcp.
* Adding MISSING comments in operator std::unique_ptr<mpty[ const]>.
* static handle cast implementations for rtrn_uqmp, rtrn_uqcp.
* Bug fix: vptr_deleter_armed_flag_ptr has to live on the heap.
See new bullet point in comment section near the top.
The variable was also renamed to reflect its function more accurately.
* Fixing bugs discovered by ASAN. The code is now ASAN, MSAN, UBSAN clean.
* Making test_type_caster_bare_interface_demo.cpp slightly more realistic, ASAN, MSAN, UBSAN clean.
* Calling deregister_instance after disowning via unique_ptr.
* Removing enable_shared_from_this stub, simplifying existing code, clang-format.
Open question, with respect to the original code:
https://github.com/pybind/pybind11/blob/76a160070b369f8d82b945c97924227e8b835c94/include/pybind11/pybind11.h#L1510
To me it looks like the exact situation marked as `std::shared_ptr<Good> gp1 = not_so_good.getptr();` here: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
The comment there is: `// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)`
Does the existing code have UB pre C++17?
I'll leave handling of enable_shared_from_this for later, as the need arises.
* Cosmetical change around helper functions.
* Using type_caster_base<mpty>::src_and_type directly, removing copy. Also renaming one cast to cast_const_raw_ptr, for clarity.
* Fixing clang-format oversight.
* Using factored-out make_constructor (PR #2798), removing duplicate code.
* Inserting additional assert to ensure a returned unique_ptr is always a new Python instance.
* Adding minor comment (change to internals needed to distinguish uninitialized/disowned in error message).
* Factoring out find_existing_python_instance().
* Moving factored-out make_constructor to test_classh_wip.cpp, restoring previous version of cast.h. This is currently the most practical approach. See PR #2798 for background.
* Copying classh type_casters from test_classh_wip.cpp UNMODIFIED, as a baseline for generalizing the code.
* Using pybind11/detail/classh_type_casters.h from test_classh_wip.cpp.
* Adding & using PYBIND11_CLASSH_TYPE_CASTERS define.
* Adding test_classh_inheritance, currently failing (passes with class_).
* Removing .clang-format before git rebase master (where the file was added).
* Bringing back .clang-format, the previous rm was a bad idea.
* Folding in modified_type_caster_generic_load_impl, just enough to pass test_class_wip. test_classh_inheritance is still failing, but with a different error: [RuntimeError: Incompatible type (as_raw_ptr_unowned).]
* Minimal changes needed to pass test_classh_inheritance.
* First pass adjusting try_implicit_casts and try_load_foreign_module_local to capture loaded_v_h, but untested and guarded with pybind11_failure("Untested"). This was done mainly to determine general feasibility. Note the TODO in pybind11.h, where type_caster_generic::local_load is currently hard-coded. test_classh_wip and test_classh_inheritance still pass, as before.
* Decoupling generic_type from type_caster_generic.
* Changes and tests covering classh_type_casters try_implicit_casts.
* Minimal test covering classh_type_casters load_impl Case 2b.
* Removing stray isinstance<T>(src): it interferes with the py::module_local feature. Adding missing #includes.
* Tests for classh py::module_local() feature.
* Pure renaming of function names in test_classh_inheritance, similar to the systematic approach used in test_class_wip. NO functional changes.
* Pure renaming of function and variable names, for better generalization when convoluting with inheritance. NO functional changes.
* Adopting systematic naming scheme from test_classh_wip. NO functional changes.
* Moving const after type name, for functions that cover a systematic scheme. NO functional changes.
* Adding smart_holder_type_caster_load::loaded_as_shared_ptr, currently bypassing smart_holder shared_ptr tracking completely, but the tests pass and are sanitizer clean.
* Removing rtti_held from smart_holder. See updated comment.
* Cleaning up loaded_as_raw_ptr_unowned, loaded_as_shared_ptr.
* Factoring out convert_type and folding into loaded_as_unique_ptr.
* Folding convert_type into lvalue_ref and rvalue_ref paths. Some smart_holder_type_caster_load cleanup.
* Using unique_ptr in local_load to replace static variable. Also adding local_load_safety_guard.
* Converting test_unique_ptr_member to using classh: fully working, ASAN, MSAN, UBSAN clean.
* Removing debugging comments (GET_STACK, GET_INT_STACK). cast.h is identical to current master again, pybind11.h only has the generic_type::initialize(..., &type_caster_generic::local_load) change.
* Purging obsolete pybind11/vptr_holder.h and associated test.
* Moving several tests to github.com/rwgk/rwgk_tbx/tree/main/pybind11_tests
https://github.com/rwgk/rwgk_tbx/commit/a2c2f88174a30f5de80d7d26e0f77c7b60f5fb85
These tests are from experimenting, and for demonstrating UB in pybind11 multiple inheritance handling ("first_base"), to be fixed later.
* Adding py::smart_holder support to py::class_, purging py::classh completely.
* Renaming files in include directory, creating pybind11/smart_holder.h.
* Renaming all "classh" to "smart_holder" in pybind11/detail/smart_holder_type_casters.h.
The user-facing macro is now PYBIND11_SMART_HOLDER_TYPE_CASTERS.
* Systematically renaming tests to use "class_sh" in the name.
* Renaming test_type_caster_bare_interface_demo to test_type_caster_bare_interface.
* Renaming new tests/core subdirectory to tests/pure_cpp.
* Adding new tests to CMake config, resetting CI config.
* Changing CMake file so that test_class_sh_module_local.py actually runs.
* clang-tidy fixes.
* 32-bit compatibility.
* Reusing type_caster_base make_copy_constructor, make_move_constructor with a trick.
* CMake COMPARE NATURAL is not available with older versions.
* Adding copyright notices to new header files.
* Explicitly define copy/move constructors/assignments.
* Adding new header files to tests/extra_python_package/test_files.py.
* Adding tests/pure_cpp/CMakeLists.txt.
* Making use of the new find_existing_python_instance() function factored out with PR #2822.
* Moving define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T) down in the file. NO functional changes. Preparation for follow-up work (to keep that diff smaller).
* Reintroducing py::classh, this time as a simple alias for py::class_<U, py::smart_holder>.
* Replacing detail::is_smart_holder<H> in cast.h with detail::is_smart_holder_type_caster<T>.
Moving get_local_load_function_ptr, init_instance_for_type to smart_holder_type_caster_class_hooks.
Expanding static_assert in py::type::handle_of<> to accommodate smart_holder_type_casters.
* Fixing oversight.
* Adding classu alias for class_<U, std::unique_ptr<U>>.
* Giving up on idea to use legacy init_instance only if is_base_of<type_caster_generic, type_caster<T>. There are use cases in the wild that define both a custom type_caster and class_.
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Moving up is_smart_holder_type_caster, to also use in cast_is_temporary_value_reference.
* Adding smart_holder_type_casters for unique_ptr with custom deleter. SEVERE CODE DUPLICATION. This commit is to establish a baseline for consolidating the unique_ptr code.
* Unification of unique_ptr, unique_ptr_with_deleter code in smart_holder_poc.h. Leads to more fitting error messages. Enables use of unique_ptr<T, D> smart_holder_type_casters also for unique_ptr<T>.
* Copying files as-is from branch test_unique_ptr_member (PR #2672).
* Adding comment, simplifying naming, cmake addition.
* Introducing PYBIND11_USE_SMART_HOLDER_AS_DEFAULT macro (tested only undefined; there are many errors with the macro defined).
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Fixing oversight introduced with commit 95425f13d6c14fcb6ee479b62b602dc8a605ec49.
* Setting record.default_holder correctly for PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
With this test_class.cpp builds and even mostly runs, except
`test_multiple_instances_with_same_pointer`, which segfaults because it is
using a `unique_ptr` holder but `smart_holder` `type_caster`.
Also adding `static_assert`s to generate build errors for such situations,
but guarding with `#if 0` to first pivot to test_factory_constructors.cpp.
* Fixing up cast.h and smart_holder.h after rebase.
* Removing detail/smart_holder_type_casters.h in separate commit.
* Commenting out const in def_buffer(... const). With this, test_buffers builds and runs with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT. Explanation why the const needs to be removed, or fix elsewhere, is still needed, but left for later.
* Adding test_class_sh_factory_constructors, reproducing test_factory_constructors failure. Using py::class_ in this commit, to be changed to py::classh for debugging.
* Removing include/pybind11/detail/smart_holder_type_casters.h from CMakeLists.txt, test_files.py (since it does not exist in this branch).
* Adding // DANGER ZONE reminders.
* Converting as many py::class_ to py::classh as possible, not breaking tests.
* Adding initimpl::construct() overloads, resulting in test_class_sh_factory_constructors feature parity for py::class_ and py::classh.
* Adding enable_if !is_smart_holder_type_caster to existing initimpl::construct(). With this test_factory_constructors.cpp builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Disabling shared_ptr&, shared_ptr* tests when building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT for now, pending work on smart_holder_type_caster<shared_ptr>.
* Factoring out struct and class definitions into anonymous namespace. Preparation for building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Simplifying from_unique_ptr(): typename D = std::default_delete<T> is not needed. Factoring out is_std_default_delete<T>() for consistentcy between ensure_compatible_rtti_uqp_del() and from_unique_ptr().
* Introducing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. Using it in test_smart_ptr.cpp. With this test_smart_ptr builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT and all but one test run successfully.
* Introducing 1. type_caster_for_class_, used in PYBIND11_MAKE_OPAQUE, and 2. default_holder_type, used in stl_bind.h.
* Using __VA_ARGS__ in PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS.
* Replacing condense_for_macro with much simpler approach.
* Softening static_assert, to only check specifically that smart_holder is not mixed with type_caster_base, and unique_ptr/shared_ptr holders are not mixed with smart_holder_type_casters.
* Adding PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS in test_class.cpp (with this all but one test succeed with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT).
* Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for "necessary conditions" for both types of default holder, static_assert for "strict conditions" guarded by new PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX. All tests build & run as before with unique_ptr as the default holder, all tests build for smart_holder as the default holder, even with the strict static_assert.
* Introducing check_is_smart_holder_type_caster() function for runtime check, and reinterpreting record.default_holder as "uses_unique_ptr_holder". With this test_smart_ptr succeeds. (All 42 tests build, 35 tests succeed, 5 run but have some failures, 2 segfault.)
* Bug fix: Adding have_value() to smart_holder_type_caster_load. With this test_builtin_casters succeeds. (All 42 tests build, 36 tests succeed, 5 run but have some failures, 1 segfault.)
* Adding unowned_void_ptr_from_direct_conversion to modified_type_caster_generic_load_impl. This fixes the last remaining segfault (test_numpy_dtypes). New stats for all tests combined: 12 failed, 458 passed.
* Adding "Lazy allocation for unallocated values" (for old-style __init__) into load_value_and_holder. Deferring destruction of disowned holder until clear_instance, to remain inspectable for "uninitialized" or "disowned" detection. New stats for all tests combined: 5 failed, 465 passed.
* Changing std::shared_ptr pointer/reference to const pointer/reference. New stats for all tests combined: 4 failed, 466 passed.
* Adding return_value_policy::move to permissible policies for unique_ptr returns. New stats for all tests combined: 3 failed, 467 passed.
* Overlooked flake8 fixes.
* Manipulating failing ConstructorStats test to pass, to be able to run all tests with ASAN.
This version of the code is ASAN clean with unique_ptr or smart_holder as the default.
This change needs to be reverted after adopting the existing move-only-if-refcount-is-1
logic used by type_caster_base.
* Adding copy constructor and move constructor tracking to atyp. Preparation for a follow-up change in smart_holder_type_caster, to make this test sensitive to the changing behavior.
[skip ci]
* Removing `operator T&&() &&` from smart_holder_type_caster, for compatibility with the behavior of type_caster_base. Enables reverting 2 of 3 test manipulations applied under commit 249df7cbdb09817fed0ddf80f01ba5af12466820. The manipulation in test_factory_constructors.py is NOT reverted in this commit.
[skip ci]
* Fixing unfortunate editing mishap. This reverts the last remaining test manipulation in commit 249df7cbdb09817fed0ddf80f01ba5af12466820 and makes all existing unit tests pass with smart_holder as default holder.
* GitHub CI clang-tidy fixes.
* Adding messages to terse `static_assert`s, for pre-C++17 compatibility.
* Using @pytest.mark.parametrize to run each assert separately (to see all errors, not just the first).
* Systematically removing _atyp from function names, to make the test code simpler.
* Using re.match to accommodate variable number of intermediate MvCtor.
* Also removing `operator T()` from smart_holder_type_caster, to fix gcc compilation errors. The only loss is pass_rref in test_class_sh_basic.
* Systematically replacing `detail::enable_if_t<...smart_holder...>` with `typename std::enable_if<...smart_holder...>::type`. Attempt to work around MSVC 2015 issues, to be tested via GitHub CI. The idea for this change originates from this comment: https://github.com/pybind/pybind11/issues/1616#issuecomment-444536813
* Importing re before pytest after observing a PyPy CI flake when importing pytest first.
* Copying MSVC 2015 compatibility change from branch pr2672_use_smart_holder_as_default.
* Introducing is_smart_holder_type_caster_base_tag, to keep smart_holder code more disconnected.
* Working around MSVC 2015 bug.
* Expanding comment for MSVC 2015 workaround.
* Systematically changing std::enable_if back to detail::enable_if_t, effectively reverting commit 5d4b6890a337ae1bbaec4091f4195606f89a3b06.
* Removing unused smart_holder_type_caster_load::loaded_as_rvalue_ref (it was an oversight that it was not removed with commit 23036a45eb4731a06b488ec1fdf83bca677b7f67).
* Removing py::classu, because it does not seem useful enough.
* Reverting commit 63495313066119dcf7510c2ae8b468b46c12ef8f by un-commenting `const` in `def_buffer(...)`. To make this possible, `operator T const&` and `operator T const*` in `smart_holder_type_caster` need to be marked as `const` member functions.
* Adding construct() overloads for constructing smart_holder from alias unique_ptr, shared_ptr returns.
* Adding test_class_sh_factory_constructors.cpp to tests/CMakeLists.txt (fixes oversight, this should have been added long before).
* Compatibility with old clang versions (clang 3.6, 3.7 C++11).
* Cleaning up changes to existing unit tests.
* Systematically adding SMART_HOLDER_WIP tag. Removing minor UNTESTED tags (only the throw are not actually exercised, investing time there has a high cost but very little benefit).
* Splitting out smart_holder_type_casters again, into new detail/smart_holder_type_casters_inline_include.h.
* Splitting out smart_holder_init_inline_include.h.
* Adding additional new include files to CMakeLists.txt, tests/extra_python_package/test_files.py.
* clang-format cleanup of most smart_holder code.
* Adding source code comments in response to review.
* Simple micro-benchmark ("ubench") comparing runtime performance for several holders.
Tested using github.com/rwgk/pybind11_scons and Google-internal build system.
Sorry, no cmake support at the moment.
First results: https://docs.google.com/spreadsheets/d/1InapCYws2Gt-stmFf_Bwl33eOMo3aLE_gc9adveY7RU/edit#gid=0
* Breaking out number_bucket.h, adding hook for also collecting performance data for PyCLIF.
* Accounting for ubench in MANIFEST.in (simply prune, for now).
* Smarter determination of call_repetitions.
[skip ci]
* Also scaling performance data to PyCLIF.
[skip ci]
* Adding ubench/python/number_bucket.clif here for general visibility.
* Fix after rebase
* Merging detail/smart_holder_init_inline_include.h into detail/init.h.
* Renaming detail/is_smart_holder_type_caster.h -> detail/smart_holder_sfinae_hooks_only.h.
* Renaming is_smart_holder_type_caster -> type_uses_smart_holder_type_caster for clarity.
* Renaming type_caster_type_is_smart_holder_type_caster -> wrapped_type_uses_smart_holder_type_caster for clarity.
* Renaming is_smart_holder_type_caster_base_tag -> smart_holder_type_caster_base_tag for simplicity.
* Adding copyright notices and minor colateral cleanup.
* iwyu cleanup (comprehensive only for cast.h and smart_holder*.h files).
* Fixing `git rebase master` accident.
* Moving large `pragma warning` block from pybind11.h to detail/common.h.
* Fixing another `git rebase master` accident.
2021-02-24 05:50:42 +00:00
|
|
|
py::class_<MismatchBase2, std::unique_ptr<MismatchBase2>>(mod, "MismatchBase2");
|
2017-06-22 21:42:11 +00:00
|
|
|
py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>,
|
|
|
|
MismatchBase2>(mod, "MismatchDerived2");
|
|
|
|
});
|
|
|
|
|
|
|
|
// test_override_static
|
|
|
|
// #511: problem with inheritance + overwritten def_static
|
|
|
|
struct MyBase {
|
|
|
|
static std::unique_ptr<MyBase> make() {
|
|
|
|
return std::unique_ptr<MyBase>(new MyBase());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MyDerived : MyBase {
|
|
|
|
static std::unique_ptr<MyDerived> make() {
|
|
|
|
return std::unique_ptr<MyDerived>(new MyDerived());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<MyBase>(m, "MyBase")
|
|
|
|
.def_static("make", &MyBase::make);
|
|
|
|
|
|
|
|
py::class_<MyDerived, MyBase>(m, "MyDerived")
|
|
|
|
.def_static("make", &MyDerived::make)
|
|
|
|
.def_static("make2", &MyDerived::make);
|
2017-06-26 18:34:06 +00:00
|
|
|
|
|
|
|
// test_implicit_conversion_life_support
|
|
|
|
struct ConvertibleFromUserType {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ConvertibleFromUserType(UserType u) : i(u.value()) { }
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<ConvertibleFromUserType>(m, "AcceptsUserType")
|
|
|
|
.def(py::init<UserType>());
|
|
|
|
py::implicitly_convertible<UserType, ConvertibleFromUserType>();
|
|
|
|
|
|
|
|
m.def("implicitly_convert_argument", [](const ConvertibleFromUserType &r) { return r.i; });
|
|
|
|
m.def("implicitly_convert_variable", [](py::object o) {
|
|
|
|
// `o` is `UserType` and `r` is a reference to a temporary created by implicit
|
|
|
|
// conversion. This is valid when called inside a bound function because the temp
|
|
|
|
// object is attached to the same life support system as the arguments.
|
|
|
|
const auto &r = o.cast<const ConvertibleFromUserType &>();
|
|
|
|
return r.i;
|
|
|
|
});
|
|
|
|
m.add_object("implicitly_convert_variable_fail", [&] {
|
|
|
|
auto f = [](PyObject *, PyObject *args) -> PyObject * {
|
|
|
|
auto o = py::reinterpret_borrow<py::tuple>(args)[0];
|
|
|
|
try { // It should fail here because there is no life support.
|
|
|
|
o.cast<const ConvertibleFromUserType &>();
|
|
|
|
} catch (const py::cast_error &e) {
|
|
|
|
return py::str(e.what()).release().ptr();
|
|
|
|
}
|
|
|
|
return py::str().release().ptr();
|
|
|
|
};
|
|
|
|
|
|
|
|
auto def = new PyMethodDef{"f", f, METH_VARARGS, nullptr};
|
2021-01-01 16:05:22 +00:00
|
|
|
py::capsule def_capsule(def, [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });
|
|
|
|
return py::reinterpret_steal<py::object>(PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));
|
2017-06-26 18:34:06 +00:00
|
|
|
}());
|
2017-07-23 04:32:58 +00:00
|
|
|
|
|
|
|
// test_operator_new_delete
|
|
|
|
struct HasOpNewDel {
|
|
|
|
std::uint64_t i;
|
|
|
|
static void *operator new(size_t s) { py::print("A new", s); return ::operator new(s); }
|
|
|
|
static void *operator new(size_t s, void *ptr) { py::print("A placement-new", s); return ptr; }
|
|
|
|
static void operator delete(void *p) { py::print("A delete"); return ::operator delete(p); }
|
|
|
|
};
|
|
|
|
struct HasOpNewDelSize {
|
|
|
|
std::uint32_t i;
|
|
|
|
static void *operator new(size_t s) { py::print("B new", s); return ::operator new(s); }
|
|
|
|
static void *operator new(size_t s, void *ptr) { py::print("B placement-new", s); return ptr; }
|
|
|
|
static void operator delete(void *p, size_t s) { py::print("B delete", s); return ::operator delete(p); }
|
|
|
|
};
|
|
|
|
struct AliasedHasOpNewDelSize {
|
|
|
|
std::uint64_t i;
|
|
|
|
static void *operator new(size_t s) { py::print("C new", s); return ::operator new(s); }
|
|
|
|
static void *operator new(size_t s, void *ptr) { py::print("C placement-new", s); return ptr; }
|
|
|
|
static void operator delete(void *p, size_t s) { py::print("C delete", s); return ::operator delete(p); }
|
|
|
|
virtual ~AliasedHasOpNewDelSize() = default;
|
2020-07-24 01:16:54 +00:00
|
|
|
AliasedHasOpNewDelSize() = default;
|
|
|
|
AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize&) = delete;
|
2017-07-23 04:32:58 +00:00
|
|
|
};
|
|
|
|
struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {
|
|
|
|
PyAliasedHasOpNewDelSize() = default;
|
|
|
|
PyAliasedHasOpNewDelSize(int) { }
|
|
|
|
std::uint64_t j;
|
|
|
|
};
|
|
|
|
struct HasOpNewDelBoth {
|
|
|
|
std::uint32_t i[8];
|
|
|
|
static void *operator new(size_t s) { py::print("D new", s); return ::operator new(s); }
|
|
|
|
static void *operator new(size_t s, void *ptr) { py::print("D placement-new", s); return ptr; }
|
|
|
|
static void operator delete(void *p) { py::print("D delete"); return ::operator delete(p); }
|
|
|
|
static void operator delete(void *p, size_t s) { py::print("D wrong delete", s); return ::operator delete(p); }
|
|
|
|
};
|
|
|
|
py::class_<HasOpNewDel>(m, "HasOpNewDel").def(py::init<>());
|
|
|
|
py::class_<HasOpNewDelSize>(m, "HasOpNewDelSize").def(py::init<>());
|
|
|
|
py::class_<HasOpNewDelBoth>(m, "HasOpNewDelBoth").def(py::init<>());
|
|
|
|
py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m, "AliasedHasOpNewDelSize");
|
|
|
|
aliased.def(py::init<>());
|
|
|
|
aliased.attr("size_noalias") = py::int_(sizeof(AliasedHasOpNewDelSize));
|
|
|
|
aliased.attr("size_alias") = py::int_(sizeof(PyAliasedHasOpNewDelSize));
|
2017-07-29 02:03:44 +00:00
|
|
|
|
|
|
|
// This test is actually part of test_local_bindings (test_duplicate_local), but we need a
|
|
|
|
// definition in a different compilation unit within the same module:
|
|
|
|
bind_local<LocalExternal, 17>(m, "LocalExternal", py::module_local());
|
2017-08-17 15:03:46 +00:00
|
|
|
|
|
|
|
// test_bind_protected_functions
|
|
|
|
class ProtectedA {
|
|
|
|
protected:
|
|
|
|
int foo() const { return value; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int value = 42;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PublicistA : public ProtectedA {
|
|
|
|
public:
|
|
|
|
using ProtectedA::foo;
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<ProtectedA>(m, "ProtectedA")
|
|
|
|
.def(py::init<>())
|
|
|
|
#if !defined(_MSC_VER) || _MSC_VER >= 1910
|
|
|
|
.def("foo", &PublicistA::foo);
|
|
|
|
#else
|
|
|
|
.def("foo", static_cast<int (ProtectedA::*)() const>(&PublicistA::foo));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class ProtectedB {
|
|
|
|
public:
|
|
|
|
virtual ~ProtectedB() = default;
|
2020-07-24 01:16:54 +00:00
|
|
|
ProtectedB() = default;
|
|
|
|
ProtectedB(const ProtectedB &) = delete;
|
2017-08-17 15:03:46 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual int foo() const { return value; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int value = 42;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TrampolineB : public ProtectedB {
|
|
|
|
public:
|
2020-09-15 12:56:20 +00:00
|
|
|
int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }
|
2017-08-17 15:03:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class PublicistB : public ProtectedB {
|
|
|
|
public:
|
2021-01-15 20:59:47 +00:00
|
|
|
// [workaround(intel)] = default does not work here
|
fix: Intel ICC C++17 compatibility (#2729)
* CI: Intel icc/icpc via oneAPI
Add testing for Intel icc/icpc via the oneAPI images.
Intel oneAPI is in a late beta stage, currently shipping
oneAPI beta09 with ICC 20.2.
CI: Skip Interpreter Tests for Intel
Cannot find how to add this, neiter the package `libc6-dev` nor
`intel-oneapi-mkl-devel` help when installed to solve this:
```
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - not found
CMake Error at /__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:165 (message):
Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
/__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:458 (_FPHSA_FAILURE_MESSAGE)
/__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindThreads.cmake:234 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
tests/test_embed/CMakeLists.txt:17 (find_package)
```
CI: libc6-dev from GCC for ICC
CI: Run bare metal for oneAPI
CI: Ubuntu 18.04 for oneAPI
CI: Intel +Catch -Eigen
CI: CMake from Apt (ICC tests)
CI: Replace Intel Py with GCC Py
CI: Intel w/o GCC's Eigen
CI: ICC with verbose make
[Debug] Find core dump
tests: use arg{} instead of arg() for Intel
tests: adding a few more missing {}
fix: sync with @tobiasleibner's branch
fix: try ubuntu 20-04
fix: drop exit 1
docs: Apply suggestions from code review
Co-authored-by: Tobias Leibner <tobias.leibner@googlemail.com>
Workaround for ICC enable_if issues
Another workaround for ICC's enable_if issues
fix error in previous commit
Disable one test for the Intel compiler in C++17 mode
Add back one instance of py::arg().noconvert()
Add NOLINT to fix clang-tidy check
Work around for ICC internal error in PYBIND11_EXPAND_SIDE_EFFECTS in C++17 mode
CI: Intel ICC with C++17
docs: pybind11/numpy.h does not require numpy at build time. (#2720)
This is nice enough to be mentioned explicitly in the docs.
docs: Update warning about Python 3.9.0 UB, now that 3.9.1 has been released (#2719)
Adjusting `type_caster<std::reference_wrapper<T>>` to support const/non-const propagation in `cast_op`. (#2705)
* Allow type_caster of std::reference_wrapper<T> to be the same as a native reference.
Before, both std::reference_wrapper<T> and std::reference_wrapper<const T> would
invoke cast_op<type>. This doesn't allow the type_caster<> specialization for T
to distinguish reference_wrapper types from value types.
After, the type_caster<> specialization invokes cast_op<type&>, which allows
reference_wrapper to behave in the same way as a native reference type.
* Add tests/examples for std::reference_wrapper<const T>
* Add tests which use mutable/immutable variants
This test is a chimera; it blends the pybind11 casters with a custom
pytype implementation that supports immutable and mutable calls.
In order to detect the immutable/mutable state, the cast_op needs
to propagate it, even through e.g. std::reference<const T>
Note: This is still a work in progress; some things are crashing,
which likely means that I have a refcounting bug or something else
missing.
* Add/finish tests that distinguish const& from &
Fixes the bugs in my custom python type implementation,
demonstrate test that requires const& and reference_wrapper<const T>
being treated differently from Non-const.
* Add passing a const to non-const method.
* Demonstrate non-const conversion of reference_wrapper in tests.
Apply formatting presubmit check.
* Fix build errors from presubmit checks.
* Try and fix a few more CI errors
* More CI fixes.
* More CI fixups.
* Try and get PyPy to work.
* Additional minor fixups. Getting close to CI green.
* More ci fixes?
* fix clang-tidy warnings from presubmit
* fix more clang-tidy warnings
* minor comment and consistency cleanups
* PyDECREF -> Py_DECREF
* copy/move constructors
* Resolve codereview comments
* more review comment fixes
* review comments: remove spurious &
* Make the test fail even when the static_assert is commented out.
This expands the test_freezable_type_caster a bit by:
1/ adding accessors .is_immutable and .addr to compare identity
from python.
2/ Changing the default cast_op of the type_caster<> specialization
to return a non-const value. In normal codepaths this is a reasonable
default.
3/ adding roundtrip variants to exercise the by reference, by pointer
and by reference_wrapper in all call paths. In conjunction with 2/, this
demonstrates the failure case of the existing std::reference_wrpper conversion,
which now loses const in a similar way that happens when using the default cast_op_type<>.
* apply presubmit formatting
* Revert inclusion of test_freezable_type_caster
There's some concern that this test is a bit unwieldly because of the use
of the raw <Python.h> functions. Removing for now.
* Add a test that validates const references propagation.
This test verifies that cast_op may be used to correctly detect
const reference types when used with std::reference_wrapper.
* mend
* Review comments based changes.
1. std::add_lvalue_reference<type> -> type&
2. Simplify the test a little more; we're never returning the ConstRefCaster
type so the class_ definition can be removed.
* formatted files again.
* Move const_ref_caster test to builtin_casters
* Review comments: use cast_op and adjust some comments.
* Simplify ConstRefCasted test
I like this version better as it moves the assertion that matters
back into python.
ci: drop pypy2 linux, PGI 20.7, add Python 10 dev (#2724)
* ci: drop pypy2 linux, add Python 10 dev
* ci: fix mistake
* ci: commented-out PGI 20.11, drop 20.7
fix: regression with installed pybind11 overriding local one (#2716)
* fix: regression with installed pybind11 overriding discovered one
Closes #2709
* docs: wording incorrect
style: remove redundant instance->owned = true (#2723)
which was just before set to True in instance->allocate_layout()
fix: also throw in the move-constructor added by the PYBIND11_OBJECT macro, after the argument has been moved-out (if necessary) (#2701)
Make args_are_all_* ICC workarounds unconditional
Disable test_aligned on Intel ICC
Fix test_aligned on Intel ICC
Skip test_python_alreadyset_in_destructor on Intel ICC
Fix test_aligned again
ICC CI: Downgrade pytest
pytest 6 does not capture the `discard_as_unraisable` stderr and
just writes a warning with its content instead.
* refactor: simpler Intel workaround, suggested by @laramiel
* fix: try version with impl to see if it is easier to compile
* docs: update README for ICC
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2021-01-18 00:53:07 +00:00
|
|
|
// Removing or defaulting this destructor results in linking errors with the Intel compiler
|
|
|
|
// (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)
|
2021-01-15 20:59:47 +00:00
|
|
|
~PublicistB() override {}; // NOLINT(modernize-use-equals-default)
|
2017-08-17 15:03:46 +00:00
|
|
|
using ProtectedB::foo;
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<ProtectedB, TrampolineB>(m, "ProtectedB")
|
|
|
|
.def(py::init<>())
|
|
|
|
#if !defined(_MSC_VER) || _MSC_VER >= 1910
|
|
|
|
.def("foo", &PublicistB::foo);
|
|
|
|
#else
|
|
|
|
.def("foo", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));
|
|
|
|
#endif
|
2017-08-21 20:48:28 +00:00
|
|
|
|
|
|
|
// test_brace_initialization
|
|
|
|
struct BraceInitialization {
|
|
|
|
int field1;
|
|
|
|
std::string field2;
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<BraceInitialization>(m, "BraceInitialization")
|
|
|
|
.def(py::init<int, const std::string &>())
|
|
|
|
.def_readwrite("field1", &BraceInitialization::field1)
|
|
|
|
.def_readwrite("field2", &BraceInitialization::field2);
|
2018-01-11 17:22:13 +00:00
|
|
|
// We *don't* want to construct using braces when the given constructor argument maps to a
|
|
|
|
// constructor, because brace initialization could go to the wrong place (in particular when
|
|
|
|
// there is also an `initializer_list<T>`-accept constructor):
|
|
|
|
py::class_<NoBraceInitialization>(m, "NoBraceInitialization")
|
|
|
|
.def(py::init<std::vector<int>>())
|
|
|
|
.def_readonly("vec", &NoBraceInitialization::vec);
|
2017-08-28 14:34:06 +00:00
|
|
|
|
|
|
|
// test_reentrant_implicit_conversion_failure
|
|
|
|
// #1035: issue with runaway reentrant implicit conversion
|
|
|
|
struct BogusImplicitConversion {
|
2020-09-11 03:15:22 +00:00
|
|
|
BogusImplicitConversion(const BogusImplicitConversion &) = default;
|
2017-08-28 14:34:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<BogusImplicitConversion>(m, "BogusImplicitConversion")
|
|
|
|
.def(py::init<const BogusImplicitConversion &>());
|
|
|
|
|
|
|
|
py::implicitly_convertible<int, BogusImplicitConversion>();
|
2017-11-07 16:33:05 +00:00
|
|
|
|
|
|
|
// test_qualname
|
|
|
|
// #1166: nested class docstring doesn't show nested name
|
|
|
|
// Also related: tests that __qualname__ is set properly
|
|
|
|
struct NestBase {};
|
|
|
|
struct Nested {};
|
|
|
|
py::class_<NestBase> base(m, "NestBase");
|
|
|
|
base.def(py::init<>());
|
|
|
|
py::class_<Nested>(base, "Nested")
|
|
|
|
.def(py::init<>())
|
|
|
|
.def("fn", [](Nested &, int, NestBase &, Nested &) {})
|
|
|
|
.def("fa", [](Nested &, int, NestBase &, Nested &) {},
|
|
|
|
"a"_a, "b"_a, "c"_a);
|
|
|
|
base.def("g", [](NestBase &, Nested &) {});
|
|
|
|
base.def("h", []() { return NestBase(); });
|
2018-09-25 21:55:18 +00:00
|
|
|
|
|
|
|
// test_error_after_conversion
|
|
|
|
// The second-pass path through dispatcher() previously didn't
|
|
|
|
// remember which overload was used, and would crash trying to
|
|
|
|
// generate a useful error message
|
|
|
|
|
|
|
|
struct NotRegistered {};
|
|
|
|
struct StringWrapper { std::string str; };
|
|
|
|
m.def("test_error_after_conversions", [](int) {});
|
|
|
|
m.def("test_error_after_conversions",
|
|
|
|
[](StringWrapper) -> NotRegistered { return {}; });
|
|
|
|
py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>());
|
|
|
|
py::implicitly_convertible<std::string, StringWrapper>();
|
2018-11-09 19:14:53 +00:00
|
|
|
|
|
|
|
#if defined(PYBIND11_CPP17)
|
|
|
|
struct alignas(1024) Aligned {
|
|
|
|
std::uintptr_t ptr() const { return (uintptr_t) this; }
|
|
|
|
};
|
|
|
|
py::class_<Aligned>(m, "Aligned")
|
|
|
|
.def(py::init<>())
|
|
|
|
.def("ptr", &Aligned::ptr);
|
|
|
|
#endif
|
2020-04-05 06:34:00 +00:00
|
|
|
|
|
|
|
// test_final
|
|
|
|
struct IsFinal final {};
|
|
|
|
py::class_<IsFinal>(m, "IsFinal", py::is_final());
|
|
|
|
|
|
|
|
// test_non_final_final
|
|
|
|
struct IsNonFinalFinal {};
|
|
|
|
py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());
|
2020-08-01 00:46:12 +00:00
|
|
|
|
2020-10-08 23:09:56 +00:00
|
|
|
// test_exception_rvalue_abort
|
2020-08-01 00:46:12 +00:00
|
|
|
struct PyPrintDestructor {
|
2020-09-11 03:15:22 +00:00
|
|
|
PyPrintDestructor() = default;
|
2020-08-01 00:46:12 +00:00
|
|
|
~PyPrintDestructor() {
|
|
|
|
py::print("Print from destructor");
|
|
|
|
}
|
|
|
|
void throw_something() { throw std::runtime_error("error"); }
|
|
|
|
};
|
|
|
|
py::class_<PyPrintDestructor>(m, "PyPrintDestructor")
|
|
|
|
.def(py::init<>())
|
|
|
|
.def("throw_something", &PyPrintDestructor::throw_something);
|
2020-10-02 17:06:04 +00:00
|
|
|
|
2020-10-08 23:09:56 +00:00
|
|
|
// test_multiple_instances_with_same_pointer
|
2020-10-02 17:06:04 +00:00
|
|
|
static SamePointer samePointer;
|
|
|
|
py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer")
|
2021-02-01 13:52:20 +00:00
|
|
|
.def(py::init([]() { return &samePointer; }));
|
2020-10-02 17:06:04 +00:00
|
|
|
|
|
|
|
struct Empty {};
|
|
|
|
py::class_<Empty>(m, "Empty")
|
|
|
|
.def(py::init<>());
|
2020-10-08 23:09:56 +00:00
|
|
|
|
|
|
|
// test_base_and_derived_nested_scope
|
|
|
|
struct BaseWithNested {
|
|
|
|
struct Nested {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DerivedWithNested : BaseWithNested {
|
|
|
|
struct Nested {};
|
|
|
|
};
|
|
|
|
|
|
|
|
py::class_<BaseWithNested> baseWithNested_class(m, "BaseWithNested");
|
|
|
|
py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, "DerivedWithNested");
|
|
|
|
py::class_<BaseWithNested::Nested>(baseWithNested_class, "Nested")
|
|
|
|
.def_static("get_name", []() { return "BaseWithNested::Nested"; });
|
|
|
|
py::class_<DerivedWithNested::Nested>(derivedWithNested_class, "Nested")
|
|
|
|
.def_static("get_name", []() { return "DerivedWithNested::Nested"; });
|
|
|
|
|
|
|
|
// test_register_duplicate_class
|
|
|
|
struct Duplicate {};
|
|
|
|
struct OtherDuplicate {};
|
|
|
|
struct DuplicateNested {};
|
|
|
|
struct OtherDuplicateNested {};
|
|
|
|
m.def("register_duplicate_class_name", [](py::module_ m) {
|
|
|
|
py::class_<Duplicate>(m, "Duplicate");
|
|
|
|
py::class_<OtherDuplicate>(m, "Duplicate");
|
|
|
|
});
|
|
|
|
m.def("register_duplicate_class_type", [](py::module_ m) {
|
|
|
|
py::class_<OtherDuplicate>(m, "OtherDuplicate");
|
|
|
|
py::class_<OtherDuplicate>(m, "YetAnotherDuplicate");
|
|
|
|
});
|
|
|
|
m.def("register_duplicate_nested_class_name", [](py::object gt) {
|
|
|
|
py::class_<DuplicateNested>(gt, "DuplicateNested");
|
|
|
|
py::class_<OtherDuplicateNested>(gt, "DuplicateNested");
|
|
|
|
});
|
|
|
|
m.def("register_duplicate_nested_class_type", [](py::object gt) {
|
|
|
|
py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested");
|
|
|
|
py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested");
|
|
|
|
});
|
2017-06-08 22:44:49 +00:00
|
|
|
}
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
|
2020-07-24 01:16:54 +00:00
|
|
|
template <int N> class BreaksBase { public:
|
|
|
|
virtual ~BreaksBase() = default;
|
|
|
|
BreaksBase() = default;
|
|
|
|
BreaksBase(const BreaksBase&) = delete;
|
|
|
|
};
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
template <int N> class BreaksTramp : public BreaksBase<N> {};
|
|
|
|
// These should all compile just fine:
|
2020-09-11 02:57:10 +00:00
|
|
|
using DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;
|
|
|
|
using DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;
|
|
|
|
using DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;
|
|
|
|
using DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;
|
|
|
|
using DoesntBreak5 = py::class_<BreaksBase<5>>;
|
|
|
|
using DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;
|
|
|
|
using DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;
|
|
|
|
using DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
#define CHECK_BASE(N) static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<N>>::value, \
|
|
|
|
"DoesntBreak" #N " has wrong type!")
|
|
|
|
CHECK_BASE(1); CHECK_BASE(2); CHECK_BASE(3); CHECK_BASE(4); CHECK_BASE(5); CHECK_BASE(6); CHECK_BASE(7); CHECK_BASE(8);
|
|
|
|
#define CHECK_ALIAS(N) static_assert(DoesntBreak##N::has_alias && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<N>>::value, \
|
|
|
|
"DoesntBreak" #N " has wrong type_alias!")
|
|
|
|
#define CHECK_NOALIAS(N) static_assert(!DoesntBreak##N::has_alias && std::is_void<typename DoesntBreak##N::type_alias>::value, \
|
|
|
|
"DoesntBreak" #N " has type alias, but shouldn't!")
|
|
|
|
CHECK_ALIAS(1); CHECK_ALIAS(2); CHECK_NOALIAS(3); CHECK_ALIAS(4); CHECK_NOALIAS(5); CHECK_ALIAS(6); CHECK_ALIAS(7); CHECK_NOALIAS(8);
|
|
|
|
#define CHECK_HOLDER(N, TYPE) static_assert(std::is_same<typename DoesntBreak##N::holder_type, std::TYPE##_ptr<BreaksBase<N>>>::value, \
|
|
|
|
"DoesntBreak" #N " has wrong holder_type!")
|
Adding py::smart_holder (for smart-pointer interoperability). (#2672)
* Adding test_unique_ptr_member (for desired PyCLIF behavior).
See also: https://github.com/pybind/pybind11/issues/2583
Does not build with upstream master or
https://github.com/pybind/pybind11/pull/2047, but builds with
https://github.com/RobotLocomotion/pybind11 and almost runs:
```
Running tests in directory "/usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests":
================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.5, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /usr/local/google/home/rwgk/forked/EricCousineau-TRI/pybind11/tests, inifile: pytest.ini
collected 2 items
test_unique_ptr_member.py .F [100%]
====================================================================================== FAILURES =======================================================================================
_____________________________________________________________________________ test_pointee_and_ptr_owner ______________________________________________________________________________
def test_pointee_and_ptr_owner():
obj = m.pointee()
assert obj.get_int() == 213
m.ptr_owner(obj)
with pytest.raises(ValueError) as exc_info:
> obj.get_int()
E Failed: DID NOT RAISE <class 'ValueError'>
test_unique_ptr_member.py:17: Failed
============================================================================= 1 failed, 1 passed in 0.06s =============================================================================
```
* unique_ptr or shared_ptr return
* new test_variant_unique_shared with vptr_holder prototype
* moving prototype code to pybind11/vptr_holder.h, adding type_caster specialization to make the bindings involving unique_ptr passing compile, but load and cast implementations are missing
* disabling GitHub Actions on pull_request (for this PR)
* disabling AppVeyor (for this PR)
* TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_STACK (pointee)
* adding test_promotion_of_disowned_to_shared
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising returning and passing unique_ptr<T>, shared_ptr<T>
with unique_ptr, shared_ptr holder.
Observations:
test_holder_unique_ptr:
make_unique_pointee OK
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee Abort free(): double free detected
pass_shared_pointee RuntimeError: Unable to load a custom holder type from a default-holder instance
test_holder_shared_ptr:
make_unique_pointee Segmentation fault (#1138)
pass_unique_pointee BUILD_FAIL (as documented)
make_shared_pointee OK
pass_shared_pointee OK
* Copying tests as-is from xxx_value_ptr_xxx_holder branch.
https://github.com/rwgk/pybind11/tree/xxx_value_ptr_xxx_holder
Systematically exercising casting between shared_ptr<base>, shared_ptr<derived>.
* Demonstration of Undefined Behavior in handling of shared_ptr holder.
Based on https://godbolt.org/z/4fdjaW by jorgbrown@ (thanks Jorg!).
* Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
* fixing up-down mixup in comment
* Demonstration of Undefined Behavior in handling of polymorphic pointers.
(This demo does NOT involve smart pointers at all, unlike the otherwise similar test_smart_ptr_private_first_base.)
* minor test_private_first_base.cpp simplification (after discovering that this can be wrapped with Boost.Python, using boost::noncopyable)
* pybind11 equivalent of Boost.Python test similar to reproducer under #1333
* Snapshot of WIP, TODO: shared_ptr deleter with on/off switch
* Adding vptr_deleter.
* Adding from/as unique_ptr<T> and unique_ptr<T, D>.
* Adding from_shared_ptr. Some polishing.
* New tests/core/smart_holder_poc_test.cpp, using Catch2.
* Adding in vptr_deleter_guard_flag.
* Improved labeling of TEST_CASEs.
* Shuffling existing TEST_CASEs into systematic matrix.
* Implementing all [S]uccess tests.
* Implementing all [E]xception tests.
* Testing of exceptions not covered by the from-as matrix.
* Adding top-level comment.
* Converting from methods to factory functions (no functional change).
* Removing obsolete and very incomplete test (replaced by Catch2-based test).
* Removing stray file.
* Adding type_caster_bare_interface_demo.
* Adding shared_ptr<mpty>, shared_ptr<mpty const> casters.
* Adding unique_ptr<mpty>, unique_ptr<mpty const> casters.
* Pure copy of `class class_` implementation in pybind11.h (master commit 98f1bbb8004f654ba9e26717bdf5912fb899b05a).
* classh.h: renaming of class_ to classh + namespace; forking test_classh_wip from test_type_caster_bare_interface_demo.
* Hard-coding smart_holder into classh.
* Adding mpty::mtxt string member.
* Adding isinstance<mpty> in type_caster::load functions.
* Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing const.
* Retrieving smart_holder pointer in type_caster<mpty>::load, and using it cast_op operators.
* Factoring out smart_holder_type_caster_load.
* Retrieving smart_holder pointer in type_caster<std::shared_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Improved error messaging: Cannot disown nullptr (as_unique_ptr).
* Retrieving smart_holder pointer in type_caster<std::unique_ptr<mpty[ const]>>::load, and using it cast_op operators.
* Pure `clang-format --style=file -i` change.
* Pure `clang-format --style=file -i` change, with two `clang-format off` directives.
* Fixing oversight (discovered by flake8).
* flake8 cleanup
* Systematically setting mtxt for all rtrn_mpty_* functions (preparation, the values are not actually used yet).
* static cast handle for rtrn_cptr works by simply dropping in code from type_caster_base (marked with comments).
* static cast handle for rtrn_cref works by simply dropping in code from type_caster_base (marked with comments). rtrn_mref and rtrn_mptr work via const_cast (to add const).
* static cast handle for rtrn_valu works by simply dropping in code from type_caster_base (marked with comments). rtrn_rref raises a RuntimeError, to be investigated.
* Copying type_caster_generic::cast into type_caster<mpty> as-is (preparation for handling smart pointers).
* Pure clang-format change (applied to original type_caster_generic::cast).
* Adding comment re potential use_count data race.
* static handle cast implementations for rtrn_shmp, rtrn_shcp.
* Adding MISSING comments in operator std::unique_ptr<mpty[ const]>.
* static handle cast implementations for rtrn_uqmp, rtrn_uqcp.
* Bug fix: vptr_deleter_armed_flag_ptr has to live on the heap.
See new bullet point in comment section near the top.
The variable was also renamed to reflect its function more accurately.
* Fixing bugs discovered by ASAN. The code is now ASAN, MSAN, UBSAN clean.
* Making test_type_caster_bare_interface_demo.cpp slightly more realistic, ASAN, MSAN, UBSAN clean.
* Calling deregister_instance after disowning via unique_ptr.
* Removing enable_shared_from_this stub, simplifying existing code, clang-format.
Open question, with respect to the original code:
https://github.com/pybind/pybind11/blob/76a160070b369f8d82b945c97924227e8b835c94/include/pybind11/pybind11.h#L1510
To me it looks like the exact situation marked as `std::shared_ptr<Good> gp1 = not_so_good.getptr();` here: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
The comment there is: `// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)`
Does the existing code have UB pre C++17?
I'll leave handling of enable_shared_from_this for later, as the need arises.
* Cosmetical change around helper functions.
* Using type_caster_base<mpty>::src_and_type directly, removing copy. Also renaming one cast to cast_const_raw_ptr, for clarity.
* Fixing clang-format oversight.
* Using factored-out make_constructor (PR #2798), removing duplicate code.
* Inserting additional assert to ensure a returned unique_ptr is always a new Python instance.
* Adding minor comment (change to internals needed to distinguish uninitialized/disowned in error message).
* Factoring out find_existing_python_instance().
* Moving factored-out make_constructor to test_classh_wip.cpp, restoring previous version of cast.h. This is currently the most practical approach. See PR #2798 for background.
* Copying classh type_casters from test_classh_wip.cpp UNMODIFIED, as a baseline for generalizing the code.
* Using pybind11/detail/classh_type_casters.h from test_classh_wip.cpp.
* Adding & using PYBIND11_CLASSH_TYPE_CASTERS define.
* Adding test_classh_inheritance, currently failing (passes with class_).
* Removing .clang-format before git rebase master (where the file was added).
* Bringing back .clang-format, the previous rm was a bad idea.
* Folding in modified_type_caster_generic_load_impl, just enough to pass test_class_wip. test_classh_inheritance is still failing, but with a different error: [RuntimeError: Incompatible type (as_raw_ptr_unowned).]
* Minimal changes needed to pass test_classh_inheritance.
* First pass adjusting try_implicit_casts and try_load_foreign_module_local to capture loaded_v_h, but untested and guarded with pybind11_failure("Untested"). This was done mainly to determine general feasibility. Note the TODO in pybind11.h, where type_caster_generic::local_load is currently hard-coded. test_classh_wip and test_classh_inheritance still pass, as before.
* Decoupling generic_type from type_caster_generic.
* Changes and tests covering classh_type_casters try_implicit_casts.
* Minimal test covering classh_type_casters load_impl Case 2b.
* Removing stray isinstance<T>(src): it interferes with the py::module_local feature. Adding missing #includes.
* Tests for classh py::module_local() feature.
* Pure renaming of function names in test_classh_inheritance, similar to the systematic approach used in test_class_wip. NO functional changes.
* Pure renaming of function and variable names, for better generalization when convoluting with inheritance. NO functional changes.
* Adopting systematic naming scheme from test_classh_wip. NO functional changes.
* Moving const after type name, for functions that cover a systematic scheme. NO functional changes.
* Adding smart_holder_type_caster_load::loaded_as_shared_ptr, currently bypassing smart_holder shared_ptr tracking completely, but the tests pass and are sanitizer clean.
* Removing rtti_held from smart_holder. See updated comment.
* Cleaning up loaded_as_raw_ptr_unowned, loaded_as_shared_ptr.
* Factoring out convert_type and folding into loaded_as_unique_ptr.
* Folding convert_type into lvalue_ref and rvalue_ref paths. Some smart_holder_type_caster_load cleanup.
* Using unique_ptr in local_load to replace static variable. Also adding local_load_safety_guard.
* Converting test_unique_ptr_member to using classh: fully working, ASAN, MSAN, UBSAN clean.
* Removing debugging comments (GET_STACK, GET_INT_STACK). cast.h is identical to current master again, pybind11.h only has the generic_type::initialize(..., &type_caster_generic::local_load) change.
* Purging obsolete pybind11/vptr_holder.h and associated test.
* Moving several tests to github.com/rwgk/rwgk_tbx/tree/main/pybind11_tests
https://github.com/rwgk/rwgk_tbx/commit/a2c2f88174a30f5de80d7d26e0f77c7b60f5fb85
These tests are from experimenting, and for demonstrating UB in pybind11 multiple inheritance handling ("first_base"), to be fixed later.
* Adding py::smart_holder support to py::class_, purging py::classh completely.
* Renaming files in include directory, creating pybind11/smart_holder.h.
* Renaming all "classh" to "smart_holder" in pybind11/detail/smart_holder_type_casters.h.
The user-facing macro is now PYBIND11_SMART_HOLDER_TYPE_CASTERS.
* Systematically renaming tests to use "class_sh" in the name.
* Renaming test_type_caster_bare_interface_demo to test_type_caster_bare_interface.
* Renaming new tests/core subdirectory to tests/pure_cpp.
* Adding new tests to CMake config, resetting CI config.
* Changing CMake file so that test_class_sh_module_local.py actually runs.
* clang-tidy fixes.
* 32-bit compatibility.
* Reusing type_caster_base make_copy_constructor, make_move_constructor with a trick.
* CMake COMPARE NATURAL is not available with older versions.
* Adding copyright notices to new header files.
* Explicitly define copy/move constructors/assignments.
* Adding new header files to tests/extra_python_package/test_files.py.
* Adding tests/pure_cpp/CMakeLists.txt.
* Making use of the new find_existing_python_instance() function factored out with PR #2822.
* Moving define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T) down in the file. NO functional changes. Preparation for follow-up work (to keep that diff smaller).
* Reintroducing py::classh, this time as a simple alias for py::class_<U, py::smart_holder>.
* Replacing detail::is_smart_holder<H> in cast.h with detail::is_smart_holder_type_caster<T>.
Moving get_local_load_function_ptr, init_instance_for_type to smart_holder_type_caster_class_hooks.
Expanding static_assert in py::type::handle_of<> to accommodate smart_holder_type_casters.
* Fixing oversight.
* Adding classu alias for class_<U, std::unique_ptr<U>>.
* Giving up on idea to use legacy init_instance only if is_base_of<type_caster_generic, type_caster<T>. There are use cases in the wild that define both a custom type_caster and class_.
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Moving up is_smart_holder_type_caster, to also use in cast_is_temporary_value_reference.
* Adding smart_holder_type_casters for unique_ptr with custom deleter. SEVERE CODE DUPLICATION. This commit is to establish a baseline for consolidating the unique_ptr code.
* Unification of unique_ptr, unique_ptr_with_deleter code in smart_holder_poc.h. Leads to more fitting error messages. Enables use of unique_ptr<T, D> smart_holder_type_casters also for unique_ptr<T>.
* Copying files as-is from branch test_unique_ptr_member (PR #2672).
* Adding comment, simplifying naming, cmake addition.
* Introducing PYBIND11_USE_SMART_HOLDER_AS_DEFAULT macro (tested only undefined; there are many errors with the macro defined).
* Removing test_type_caster_bare_interface, which was moved to the separate PR #2834.
* Fixing oversight introduced with commit 95425f13d6c14fcb6ee479b62b602dc8a605ec49.
* Setting record.default_holder correctly for PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
With this test_class.cpp builds and even mostly runs, except
`test_multiple_instances_with_same_pointer`, which segfaults because it is
using a `unique_ptr` holder but `smart_holder` `type_caster`.
Also adding `static_assert`s to generate build errors for such situations,
but guarding with `#if 0` to first pivot to test_factory_constructors.cpp.
* Fixing up cast.h and smart_holder.h after rebase.
* Removing detail/smart_holder_type_casters.h in separate commit.
* Commenting out const in def_buffer(... const). With this, test_buffers builds and runs with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT. Explanation why the const needs to be removed, or fix elsewhere, is still needed, but left for later.
* Adding test_class_sh_factory_constructors, reproducing test_factory_constructors failure. Using py::class_ in this commit, to be changed to py::classh for debugging.
* Removing include/pybind11/detail/smart_holder_type_casters.h from CMakeLists.txt, test_files.py (since it does not exist in this branch).
* Adding // DANGER ZONE reminders.
* Converting as many py::class_ to py::classh as possible, not breaking tests.
* Adding initimpl::construct() overloads, resulting in test_class_sh_factory_constructors feature parity for py::class_ and py::classh.
* Adding enable_if !is_smart_holder_type_caster to existing initimpl::construct(). With this test_factory_constructors.cpp builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Disabling shared_ptr&, shared_ptr* tests when building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT for now, pending work on smart_holder_type_caster<shared_ptr>.
* Factoring out struct and class definitions into anonymous namespace. Preparation for building with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT.
* Simplifying from_unique_ptr(): typename D = std::default_delete<T> is not needed. Factoring out is_std_default_delete<T>() for consistentcy between ensure_compatible_rtti_uqp_del() and from_unique_ptr().
* Introducing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. Using it in test_smart_ptr.cpp. With this test_smart_ptr builds with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT and all but one test run successfully.
* Introducing 1. type_caster_for_class_, used in PYBIND11_MAKE_OPAQUE, and 2. default_holder_type, used in stl_bind.h.
* Using __VA_ARGS__ in PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS.
* Replacing condense_for_macro with much simpler approach.
* Softening static_assert, to only check specifically that smart_holder is not mixed with type_caster_base, and unique_ptr/shared_ptr holders are not mixed with smart_holder_type_casters.
* Adding PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS in test_class.cpp (with this all but one test succeed with PYBIND11_USE_SMART_HOLDER_AS_DEFAULT).
* Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for "necessary conditions" for both types of default holder, static_assert for "strict conditions" guarded by new PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX. All tests build & run as before with unique_ptr as the default holder, all tests build for smart_holder as the default holder, even with the strict static_assert.
* Introducing check_is_smart_holder_type_caster() function for runtime check, and reinterpreting record.default_holder as "uses_unique_ptr_holder". With this test_smart_ptr succeeds. (All 42 tests build, 35 tests succeed, 5 run but have some failures, 2 segfault.)
* Bug fix: Adding have_value() to smart_holder_type_caster_load. With this test_builtin_casters succeeds. (All 42 tests build, 36 tests succeed, 5 run but have some failures, 1 segfault.)
* Adding unowned_void_ptr_from_direct_conversion to modified_type_caster_generic_load_impl. This fixes the last remaining segfault (test_numpy_dtypes). New stats for all tests combined: 12 failed, 458 passed.
* Adding "Lazy allocation for unallocated values" (for old-style __init__) into load_value_and_holder. Deferring destruction of disowned holder until clear_instance, to remain inspectable for "uninitialized" or "disowned" detection. New stats for all tests combined: 5 failed, 465 passed.
* Changing std::shared_ptr pointer/reference to const pointer/reference. New stats for all tests combined: 4 failed, 466 passed.
* Adding return_value_policy::move to permissible policies for unique_ptr returns. New stats for all tests combined: 3 failed, 467 passed.
* Overlooked flake8 fixes.
* Manipulating failing ConstructorStats test to pass, to be able to run all tests with ASAN.
This version of the code is ASAN clean with unique_ptr or smart_holder as the default.
This change needs to be reverted after adopting the existing move-only-if-refcount-is-1
logic used by type_caster_base.
* Adding copy constructor and move constructor tracking to atyp. Preparation for a follow-up change in smart_holder_type_caster, to make this test sensitive to the changing behavior.
[skip ci]
* Removing `operator T&&() &&` from smart_holder_type_caster, for compatibility with the behavior of type_caster_base. Enables reverting 2 of 3 test manipulations applied under commit 249df7cbdb09817fed0ddf80f01ba5af12466820. The manipulation in test_factory_constructors.py is NOT reverted in this commit.
[skip ci]
* Fixing unfortunate editing mishap. This reverts the last remaining test manipulation in commit 249df7cbdb09817fed0ddf80f01ba5af12466820 and makes all existing unit tests pass with smart_holder as default holder.
* GitHub CI clang-tidy fixes.
* Adding messages to terse `static_assert`s, for pre-C++17 compatibility.
* Using @pytest.mark.parametrize to run each assert separately (to see all errors, not just the first).
* Systematically removing _atyp from function names, to make the test code simpler.
* Using re.match to accommodate variable number of intermediate MvCtor.
* Also removing `operator T()` from smart_holder_type_caster, to fix gcc compilation errors. The only loss is pass_rref in test_class_sh_basic.
* Systematically replacing `detail::enable_if_t<...smart_holder...>` with `typename std::enable_if<...smart_holder...>::type`. Attempt to work around MSVC 2015 issues, to be tested via GitHub CI. The idea for this change originates from this comment: https://github.com/pybind/pybind11/issues/1616#issuecomment-444536813
* Importing re before pytest after observing a PyPy CI flake when importing pytest first.
* Copying MSVC 2015 compatibility change from branch pr2672_use_smart_holder_as_default.
* Introducing is_smart_holder_type_caster_base_tag, to keep smart_holder code more disconnected.
* Working around MSVC 2015 bug.
* Expanding comment for MSVC 2015 workaround.
* Systematically changing std::enable_if back to detail::enable_if_t, effectively reverting commit 5d4b6890a337ae1bbaec4091f4195606f89a3b06.
* Removing unused smart_holder_type_caster_load::loaded_as_rvalue_ref (it was an oversight that it was not removed with commit 23036a45eb4731a06b488ec1fdf83bca677b7f67).
* Removing py::classu, because it does not seem useful enough.
* Reverting commit 63495313066119dcf7510c2ae8b468b46c12ef8f by un-commenting `const` in `def_buffer(...)`. To make this possible, `operator T const&` and `operator T const*` in `smart_holder_type_caster` need to be marked as `const` member functions.
* Adding construct() overloads for constructing smart_holder from alias unique_ptr, shared_ptr returns.
* Adding test_class_sh_factory_constructors.cpp to tests/CMakeLists.txt (fixes oversight, this should have been added long before).
* Compatibility with old clang versions (clang 3.6, 3.7 C++11).
* Cleaning up changes to existing unit tests.
* Systematically adding SMART_HOLDER_WIP tag. Removing minor UNTESTED tags (only the throw are not actually exercised, investing time there has a high cost but very little benefit).
* Splitting out smart_holder_type_casters again, into new detail/smart_holder_type_casters_inline_include.h.
* Splitting out smart_holder_init_inline_include.h.
* Adding additional new include files to CMakeLists.txt, tests/extra_python_package/test_files.py.
* clang-format cleanup of most smart_holder code.
* Adding source code comments in response to review.
* Simple micro-benchmark ("ubench") comparing runtime performance for several holders.
Tested using github.com/rwgk/pybind11_scons and Google-internal build system.
Sorry, no cmake support at the moment.
First results: https://docs.google.com/spreadsheets/d/1InapCYws2Gt-stmFf_Bwl33eOMo3aLE_gc9adveY7RU/edit#gid=0
* Breaking out number_bucket.h, adding hook for also collecting performance data for PyCLIF.
* Accounting for ubench in MANIFEST.in (simply prune, for now).
* Smarter determination of call_repetitions.
[skip ci]
* Also scaling performance data to PyCLIF.
[skip ci]
* Adding ubench/python/number_bucket.clif here for general visibility.
* Fix after rebase
* Merging detail/smart_holder_init_inline_include.h into detail/init.h.
* Renaming detail/is_smart_holder_type_caster.h -> detail/smart_holder_sfinae_hooks_only.h.
* Renaming is_smart_holder_type_caster -> type_uses_smart_holder_type_caster for clarity.
* Renaming type_caster_type_is_smart_holder_type_caster -> wrapped_type_uses_smart_holder_type_caster for clarity.
* Renaming is_smart_holder_type_caster_base_tag -> smart_holder_type_caster_base_tag for simplicity.
* Adding copyright notices and minor colateral cleanup.
* iwyu cleanup (comprehensive only for cast.h and smart_holder*.h files).
* Fixing `git rebase master` accident.
* Moving large `pragma warning` block from pybind11.h to detail/common.h.
* Fixing another `git rebase master` accident.
2021-02-24 05:50:42 +00:00
|
|
|
#define CHECK_SMART_HOLDER(N) static_assert(std::is_same<typename DoesntBreak##N::holder_type, py::smart_holder>::value, \
|
|
|
|
"DoesntBreak" #N " has wrong holder_type!")
|
|
|
|
CHECK_HOLDER(1, unique); CHECK_HOLDER(2, unique); CHECK_HOLDER(3, unique);
|
|
|
|
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
|
|
|
|
CHECK_HOLDER(4, unique); CHECK_HOLDER(5, unique);
|
|
|
|
#else
|
|
|
|
CHECK_SMART_HOLDER(4); CHECK_SMART_HOLDER(5);
|
|
|
|
#endif
|
Allow arbitrary class_ template option ordering
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
2016-09-06 16:17:06 +00:00
|
|
|
CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared);
|
|
|
|
|
|
|
|
// There's no nice way to test that these fail because they fail to compile; leave them here,
|
|
|
|
// though, so that they can be manually tested by uncommenting them (and seeing that compilation
|
|
|
|
// failures occurs).
|
|
|
|
|
|
|
|
// We have to actually look into the type: the typedef alone isn't enough to instantiate the type:
|
|
|
|
#define CHECK_BROKEN(N) static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-N>>::value, \
|
|
|
|
"Breaks1 has wrong type!");
|
|
|
|
|
|
|
|
//// Two holder classes:
|
|
|
|
//typedef py::class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> Breaks1;
|
|
|
|
//CHECK_BROKEN(1);
|
|
|
|
//// Two aliases:
|
|
|
|
//typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;
|
|
|
|
//CHECK_BROKEN(2);
|
|
|
|
//// Holder + 2 aliases
|
|
|
|
//typedef py::class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3;
|
|
|
|
//CHECK_BROKEN(3);
|
|
|
|
//// Alias + 2 holders
|
|
|
|
//typedef py::class_<BreaksBase<-4>, std::unique_ptr<BreaksBase<-4>>, BreaksTramp<-4>, std::shared_ptr<BreaksBase<-4>>> Breaks4;
|
|
|
|
//CHECK_BROKEN(4);
|
|
|
|
//// Invalid option (not a subclass or holder)
|
|
|
|
//typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;
|
|
|
|
//CHECK_BROKEN(5);
|
|
|
|
//// Invalid option: multiple inheritance not supported:
|
|
|
|
//template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};
|
|
|
|
//typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;
|
|
|
|
//CHECK_BROKEN(8);
|