Skip to content

[smart_holder] Simple experiment related to PR #4022 #4028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
aacf679
Insert type_caster_odr_guard<> (an empty struct to start with).
rwgk Jun 11, 2022
2b604e0
Add odr_guard_registry() used in type_caster_odr_guard() default cons…
rwgk Jun 12, 2022
3657253
Add minimal_real_caster (from PR #3862) to test_async, test_buffers
rwgk Jun 12, 2022
48e3e5c
VERY MESSY SNAPSHOT of WIP, this was the starting point for cl/454658…
rwgk Jun 14, 2022
5c8183e
Restore original test_async, test_buffers from current smart_holder HEAD
rwgk Jun 20, 2022
3a6b99a
Copy from cl/454991845 snapshot Jun 14, 5:08 PM
rwgk Jun 20, 2022
526d3e3
Cleanup of tests. Systematically insert `if (make_caster<T>::translat…
rwgk Jun 20, 2022
d85a9e9
Small simplification of odr_guard_impl()
rwgk Jun 20, 2022
e126f3d
WIP
rwgk Jun 21, 2022
3656270
Add PYBIND11_SOURCE_FILE_LINE macro.
rwgk Jun 21, 2022
c571fe5
Replace PYBIND11_TYPE_CASTER_UNIQUE_IDENTIFIER with PYBIND11_TYPE_CAS…
rwgk Jun 21, 2022
74892f0
Add more PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL; r…
rwgk Jun 21, 2022
f5a1124
load_type fixes & follow-on cleanup
rwgk Jun 21, 2022
c5c606a
Strip ./ from source_file_line
rwgk Jun 21, 2022
d29c9d3
Add new tests to CMakeLists.txt, disable PYBIND11_WERROR
rwgk Jun 21, 2022
3509807
Replace C++17 syntax. Compiles with Debian clang 13 C++11 mode, but f…
rwgk Jun 21, 2022
f8e1260
Show C++ version along with ODR VIOLATION DETECTED message.
rwgk Jun 21, 2022
c474184
Add source_file_line_basename()
rwgk Jun 21, 2022
c36911b
Introduce PYBIND11_TYPE_CASTER_ODR_GUARD_ON (but not set automatically).
rwgk Jun 21, 2022
156946e
Minor cleanup.
rwgk Jun 21, 2022
5d77dc3
Set PYBIND11_TYPE_CASTER_ODR_GUARD_ON automatically.
rwgk Jun 21, 2022
eb4df06
Resolve clang-tidy error.
rwgk Jun 21, 2022
74010af
Compatibility with old compilers.
rwgk Jun 21, 2022
98a56fc
Fix off-by-one in source_file_line_basename()
rwgk Jun 22, 2022
73f96ff
Report PYBIND11_INTERNALS_ID & C++ Version from pytest_configure()
rwgk Jun 22, 2022
f32f6d9
Restore use of PYBIND11_WERROR
rwgk Jun 22, 2022
608aed1
Move cpp_version_in_use() from cast.h to pybind11_tests.cpp
rwgk Jun 22, 2022
36d754d
define PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED true in test_odr…
rwgk Jun 22, 2022
5eba806
IWYU cleanup of detail/type_caster_odr_guard.h
rwgk Jun 22, 2022
d146576
Replace `throw err;` to resolve clang-tidy error.
rwgk Jun 22, 2022
d7ae4b5
Add new header filename to CMakeLists.txt, test_files.py
rwgk Jun 22, 2022
90c970a
Experiment: Try any C++17 compiler.
rwgk Jun 22, 2022
da965b0
Fix ifdef for pragma GCC diagnostic.
rwgk Jun 22, 2022
9e703e5
type_caster_odr_guard_impl() cleanup
rwgk Jun 22, 2022
adde3b0
Move type_caster_odr_guard to type_caster_odr_guard.h
rwgk Jun 22, 2022
b2cb899
Rename test_odr_guard* to test_type_caster_odr_guard*
rwgk Jun 22, 2022
6657156
Remove comments that are (now) more distracting than helpful.
rwgk Jun 22, 2022
779f991
Mark tu_local_no_data_always_false operator bool as explicit (clang-t…
rwgk Jun 22, 2022
adffb5e
New PYBIND11_TYPE_CASTER_ODR_GUARD_STRICT option (current on by defau…
rwgk Jun 22, 2022
cf63b9a
Add test_type_caster_odr_registry_values(), test_type_caster_odr_viol…
rwgk Jun 22, 2022
1bfb95a
Report UNEXPECTED: test_type_caster_odr_guard_2.cpp prevailed (but do…
rwgk Jun 22, 2022
12c80bc
Apply clang-tidy suggestion.
rwgk Jun 22, 2022
1aa7742
Attempt to handle valgrind behavior.
rwgk Jun 22, 2022
1634d1b
Another attempt to handle valgrind behavior.
rwgk Jun 22, 2022
44dba11
Yet another attempt to handle valgrind behavior.
rwgk Jun 22, 2022
93bff3c
Trying a new direction: show compiler info & std for UNEXPECTED: type…
rwgk Jun 23, 2022
b3c2184
compiler_info MSVC fix. num_violations == 0 condition.
rwgk Jun 23, 2022
dda1b41
assert pybind11_tests.compiler_info is not None
rwgk Jun 23, 2022
92021f3
try_builtin_file_line() just to probe what compilers support it.
rwgk Jun 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ set(PYBIND11_HEADERS
include/pybind11/detail/smart_holder_sfinae_hooks_only.h
include/pybind11/detail/smart_holder_type_casters.h
include/pybind11/detail/type_caster_base.h
include/pybind11/detail/type_caster_odr_guard.h
include/pybind11/detail/typeid.h
include/pybind11/attr.h
include/pybind11/buffer_info.h
Expand Down
61 changes: 54 additions & 7 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "detail/descr.h"
#include "detail/smart_holder_sfinae_hooks_only.h"
#include "detail/type_caster_base.h"
#include "detail/type_caster_odr_guard.h"
#include "detail/typeid.h"
#include "pytypes.h"

Expand Down Expand Up @@ -44,9 +45,18 @@ class type_caster_for_class_ : public type_caster_base<T> {};
template <typename type, typename SFINAE = void>
class type_caster : public type_caster_for_class_<type> {};

#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON

template <typename type>
using make_caster = type_caster_odr_guard<intrinsic_t<type>, type_caster<intrinsic_t<type>>>;

#else

template <typename type>
using make_caster = type_caster<intrinsic_t<type>>;

#endif

template <typename T>
struct type_uses_smart_holder_type_caster {
static constexpr bool value
Expand All @@ -56,11 +66,13 @@ struct type_uses_smart_holder_type_caster {
// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
template <typename T>
typename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
return caster.operator typename make_caster<T>::template cast_op_type<T>();
}
template <typename T>
typename make_caster<T>::template cast_op_type<typename std::add_rvalue_reference<T>::type>
cast_op(make_caster<T> &&caster) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
return std::move(caster).operator typename make_caster<T>::
template cast_op_type<typename std::add_rvalue_reference<T>::type>();
}
Expand All @@ -80,10 +92,15 @@ class type_caster<std::reference_wrapper<type>> {
"`operator T &()` or `operator const T &()`");

public:
bool load(handle src, bool convert) { return subcaster.load(src, convert); }
bool load(handle src, bool convert) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(type)
return subcaster.load(src, convert);
}
static constexpr auto name = caster_t::name;
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE
static handle
cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(type)
// It is definitely wrong to take ownership of this pointer, so mask that rvp
if (policy == return_value_policy::take_ownership
|| policy == return_value_policy::automatic) {
Expand All @@ -96,12 +113,13 @@ class type_caster<std::reference_wrapper<type>> {
explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
};

#define PYBIND11_TYPE_CASTER(type, py_name) \
#define PYBIND11_DETAIL_TYPE_CASTER_HEAD(type, py_name) \
protected: \
type value; \
\
public: \
static constexpr auto name = py_name; \
static constexpr auto name = py_name;
#define PYBIND11_DETAIL_TYPE_CASTER_TAIL(type) \
template <typename T_, \
::pybind11::detail::enable_if_t< \
std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value, \
Expand All @@ -123,6 +141,22 @@ public:
template <typename T_> \
using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>

#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON

# define PYBIND11_TYPE_CASTER(type, py_name) \
PYBIND11_DETAIL_TYPE_CASTER_HEAD(type, py_name) \
static constexpr auto source_file_line \
= ::pybind11::detail::tu_local_const_name(__FILE__ ":" PYBIND11_TOSTRING(__LINE__)); \
PYBIND11_DETAIL_TYPE_CASTER_TAIL(type)

#else

# define PYBIND11_TYPE_CASTER(type, py_name) \
PYBIND11_DETAIL_TYPE_CASTER_HEAD(type, py_name) \
PYBIND11_DETAIL_TYPE_CASTER_TAIL(type)

#endif

template <typename CharT>
using is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */
#if defined(PYBIND11_HAS_U8STRING)
Expand Down Expand Up @@ -315,6 +349,7 @@ class type_caster<void> : public type_caster<void_type> {
using cast_op_type = void *&;
explicit operator void *&() { return value; }
static constexpr auto name = const_name("capsule");
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

private:
void *value = nullptr;
Expand Down Expand Up @@ -542,6 +577,7 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {

public:
bool load(handle src, bool convert) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(StringType)
if (!src) {
return false;
}
Expand All @@ -557,13 +593,15 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
}

static handle cast(const CharT *src, return_value_policy policy, handle parent) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(StringType)
if (src == nullptr) {
return pybind11::none().inc_ref();
}
return StringCaster::cast(StringType(src), policy, parent);
}

static handle cast(CharT src, return_value_policy policy, handle parent) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(StringType)
if (std::is_same<char, CharT>::value) {
handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr);
if (!s) {
Expand Down Expand Up @@ -635,6 +673,7 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
}

static constexpr auto name = const_name(PYBIND11_STRING_NAME);
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE
template <typename _T>
using cast_op_type = pybind11::detail::cast_op_type<_T>;
};
Expand Down Expand Up @@ -679,6 +718,7 @@ class tuple_caster {

static constexpr auto name
= const_name("Tuple[") + concat(make_caster<Ts>::name...) + const_name("]");
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

template <typename T>
using cast_op_type = type;
Expand Down Expand Up @@ -851,6 +891,7 @@ struct move_only_holder_caster {
return type_caster_base<type>::cast_holder(ptr, std::addressof(src));
}
static constexpr auto name = type_caster_base<type>::name;
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE
};

#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
Expand Down Expand Up @@ -1035,8 +1076,8 @@ struct return_value_policy_override<
};

// Basic python -> C++ casting; throws if casting fails
template <typename T, typename SFINAE>
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
template <typename T>
make_caster<T> &load_type(make_caster<T> &conv, const handle &handle) {
static_assert(!detail::is_pyobject<T>::value,
"Internal error: type_caster should only be used for C++ types");
if (!conv.load(handle, true)) {
Expand All @@ -1054,8 +1095,9 @@ type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &ha
// Wrapper around the above that also constructs and returns a type_caster
template <typename T>
make_caster<T> load_type(const handle &handle) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
make_caster<T> conv;
load_type(conv, handle);
load_type<T>(conv, handle);
return conv;
}

Expand Down Expand Up @@ -1091,6 +1133,7 @@ object cast(T &&value,
: std::is_lvalue_reference<T>::value ? return_value_policy::copy
: return_value_policy::move;
}
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
return reinterpret_steal<object>(
detail::make_caster<T>::cast(std::forward<T>(value), policy, parent));
}
Expand Down Expand Up @@ -1191,7 +1234,8 @@ using override_caster_t = conditional_t<cast_is_temporary_value_reference<ret_ty
template <typename T>
enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o,
make_caster<T> &caster) {
return cast_op<T>(load_type(caster, o));
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
return cast_op<T>(load_type<T>(caster, o));
}
template <typename T>
enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,
Expand Down Expand Up @@ -1302,6 +1346,7 @@ struct arg_v : arg {
type(type_id<T>())
#endif
{
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
// Workaround! See:
// https://github.com/pybind/pybind11/issues/2336
// https://github.com/pybind/pybind11/pull/2685#issuecomment-731286700
Expand Down Expand Up @@ -1532,6 +1577,7 @@ class unpacking_collector {
private:
template <typename T>
void process(list &args_list, T &&x) {
PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
auto o = reinterpret_steal<object>(
detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
if (!o) {
Expand Down Expand Up @@ -1676,6 +1722,7 @@ handle type::handle_of() {
detail::type_uses_smart_holder_type_caster<T>>::value,
"py::type::of<T> only supports the case where T is a registered C++ types.");

PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(T)
return detail::get_type_handle(typeid(T), true);
}

Expand Down
1 change: 1 addition & 0 deletions include/pybind11/detail/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class type_caster<value_and_holder> {
using cast_op_type = value_and_holder &;
explicit operator value_and_holder &() { return *value; }
static constexpr auto name = const_name<value_and_holder>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

private:
value_and_holder *value = nullptr;
Expand Down
5 changes: 5 additions & 0 deletions include/pybind11/detail/smart_holder_type_casters.h
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ template <typename T>
struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
smart_holder_type_caster_class_hooks {
static constexpr auto name = const_name<T>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

// static handle cast(T, ...)
// is redundant (leads to ambiguous overloads).
Expand Down Expand Up @@ -777,6 +778,7 @@ template <typename T>
struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_load<T>,
smart_holder_type_caster_class_hooks {
static constexpr auto name = const_name<T>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

static handle cast(const std::shared_ptr<T> &src, return_value_policy policy, handle parent) {
switch (policy) {
Expand Down Expand Up @@ -841,6 +843,7 @@ template <typename T>
struct smart_holder_type_caster<std::shared_ptr<T const>> : smart_holder_type_caster_load<T>,
smart_holder_type_caster_class_hooks {
static constexpr auto name = const_name<T>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

static handle
cast(const std::shared_ptr<T const> &src, return_value_policy policy, handle parent) {
Expand All @@ -861,6 +864,7 @@ template <typename T, typename D>
struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caster_load<T>,
smart_holder_type_caster_class_hooks {
static constexpr auto name = const_name<T>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

static handle cast(std::unique_ptr<T, D> &&src, return_value_policy policy, handle parent) {
if (policy != return_value_policy::automatic
Expand Down Expand Up @@ -944,6 +948,7 @@ template <typename T, typename D>
struct smart_holder_type_caster<std::unique_ptr<T const, D>>
: smart_holder_type_caster_load<T>, smart_holder_type_caster_class_hooks {
static constexpr auto name = const_name<T>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

static handle
cast(std::unique_ptr<T const, D> &&src, return_value_policy policy, handle parent) {
Expand Down
2 changes: 2 additions & 0 deletions include/pybind11/detail/type_caster_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "common.h"
#include "descr.h"
#include "internals.h"
#include "type_caster_odr_guard.h"
#include "typeid.h"

#include <cstdint>
Expand Down Expand Up @@ -911,6 +912,7 @@ class type_caster_base : public type_caster_generic {

public:
static constexpr auto name = const_name<type>();
PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE

type_caster_base() : type_caster_base(typeid(type)) {}
explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) {}
Expand Down
Loading