@@ -42,13 +42,15 @@ using make_caster = type_caster<intrinsic_t<type>>;
4242// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
4343template <typename T>
4444typename make_caster<T>::template cast_op_type<T> cast_op (make_caster<T> &caster) {
45- return caster.operator typename make_caster<T>::template cast_op_type<T>();
45+ using result_t = typename make_caster<T>::template cast_op_type<T>; // See PR #4893
46+ return caster.operator result_t ();
4647}
4748template <typename T>
4849typename make_caster<T>::template cast_op_type<typename std::add_rvalue_reference<T>::type>
4950cast_op (make_caster<T> &&caster) {
50- return std::move (caster).operator typename make_caster<T>::
51- template cast_op_type<typename std::add_rvalue_reference<T>::type>();
51+ using result_t = typename make_caster<T>::template cast_op_type<
52+ typename std::add_rvalue_reference<T>::type>; // See PR #4893
53+ return std::move (caster).operator result_t ();
5254}
5355
5456template <typename type>
@@ -156,7 +158,7 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_t
156158 } else {
157159 handle src_or_index = src;
158160 // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
159- #if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
161+ #if defined(PYPY_VERSION)
160162 object index;
161163 if (!PYBIND11_LONG_CHECK (src.ptr ())) { // So: index_check(src.ptr())
162164 index = reinterpret_steal<object>(PyNumber_Index (src.ptr ()));
@@ -325,8 +327,9 @@ class type_caster<bool> {
325327 value = false ;
326328 return true ;
327329 }
328- if (convert || (std::strcmp (" numpy.bool_" , Py_TYPE (src.ptr ())->tp_name ) == 0 )) {
329- // (allow non-implicit conversion for numpy booleans)
330+ if (convert || is_numpy_bool (src)) {
331+ // (allow non-implicit conversion for numpy booleans), use strncmp
332+ // since NumPy 1.x had an additional trailing underscore.
330333
331334 Py_ssize_t res = -1 ;
332335 if (src.is_none ()) {
@@ -358,6 +361,15 @@ class type_caster<bool> {
358361 return handle (src ? Py_True : Py_False).inc_ref ();
359362 }
360363 PYBIND11_TYPE_CASTER (bool , const_name(" bool" ));
364+
365+ private:
366+ // Test if an object is a NumPy boolean (without fetching the type).
367+ static inline bool is_numpy_bool (handle object) {
368+ const char *type_name = Py_TYPE (object.ptr ())->tp_name ;
369+ // Name changed to `numpy.bool` in NumPy 2, `numpy.bool_` is needed for 1.x support
370+ return std::strcmp (" numpy.bool" , type_name) == 0
371+ || std::strcmp (" numpy.bool_" , type_name) == 0 ;
372+ }
361373};
362374
363375// Helper class for UTF-{8,16,32} C++ stl strings:
@@ -660,8 +672,9 @@ class tuple_caster {
660672 return cast (*src, policy, parent);
661673 }
662674
663- static constexpr auto name
664- = const_name(" Tuple[" ) + concat(make_caster<Ts>::name...) + const_name(" ]" );
675+ static constexpr auto name = const_name(" tuple[" )
676+ + ::pybind11::detail::concat(make_caster<Ts>::name...)
677+ + const_name(" ]" );
665678
666679 template <typename T>
667680 using cast_op_type = type;
@@ -727,6 +740,13 @@ class type_caster<std::pair<T1, T2>> : public tuple_caster<std::pair, T1, T2> {}
727740template <typename ... Ts>
728741class type_caster <std::tuple<Ts...>> : public tuple_caster<std::tuple, Ts...> {};
729742
743+ template <>
744+ class type_caster <std::tuple<>> : public tuple_caster<std::tuple> {
745+ public:
746+ // PEP 484 specifies this syntax for an empty tuple
747+ static constexpr auto name = const_name(" tuple[()]" );
748+ };
749+
730750// / Helper class which abstracts away certain actions. Users can provide specializations for
731751// / custom holders, but it's only necessary if the type has a non-standard interface.
732752template <typename T>
@@ -774,11 +794,11 @@ struct copyable_holder_caster : public type_caster_base<type> {
774794 }
775795 }
776796
777- bool load_value (value_and_holder &&v_h) {
797+ void load_value (value_and_holder &&v_h) {
778798 if (v_h.holder_constructed ()) {
779799 value = v_h.value_ptr ();
780800 holder = v_h.template holder <holder_type>();
781- return true ;
801+ return ;
782802 }
783803 throw cast_error (" Unable to cast from non-held to held instance (T& to Holder<T>) "
784804#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
@@ -869,10 +889,53 @@ struct is_holder_type
869889template <typename base, typename deleter>
870890struct is_holder_type <base, std::unique_ptr<base, deleter>> : std::true_type {};
871891
892+ #ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888
893+
894+ // This leads to compilation errors if a specialization is missing.
895+ template <typename T>
896+ struct handle_type_name ;
897+
898+ #else
899+
872900template <typename T>
873901struct handle_type_name {
874902 static constexpr auto name = const_name<T>();
875903};
904+
905+ #endif
906+
907+ template <>
908+ struct handle_type_name <object> {
909+ static constexpr auto name = const_name(" object" );
910+ };
911+ template <>
912+ struct handle_type_name <list> {
913+ static constexpr auto name = const_name(" list" );
914+ };
915+ template <>
916+ struct handle_type_name <dict> {
917+ static constexpr auto name = const_name(" dict" );
918+ };
919+ template <>
920+ struct handle_type_name <anyset> {
921+ static constexpr auto name = const_name(" Union[set, frozenset]" );
922+ };
923+ template <>
924+ struct handle_type_name <set> {
925+ static constexpr auto name = const_name(" set" );
926+ };
927+ template <>
928+ struct handle_type_name <frozenset> {
929+ static constexpr auto name = const_name(" frozenset" );
930+ };
931+ template <>
932+ struct handle_type_name <str> {
933+ static constexpr auto name = const_name(" str" );
934+ };
935+ template <>
936+ struct handle_type_name <tuple> {
937+ static constexpr auto name = const_name(" tuple" );
938+ };
876939template <>
877940struct handle_type_name <bool_> {
878941 static constexpr auto name = const_name(" bool" );
@@ -882,6 +945,10 @@ struct handle_type_name<bytes> {
882945 static constexpr auto name = const_name(PYBIND11_BYTES_NAME);
883946};
884947template <>
948+ struct handle_type_name <buffer> {
949+ static constexpr auto name = const_name(" Buffer" );
950+ };
951+ template <>
885952struct handle_type_name <int_> {
886953 static constexpr auto name = const_name(" int" );
887954};
@@ -902,17 +969,77 @@ struct handle_type_name<function> {
902969 static constexpr auto name = const_name(" Callable" );
903970};
904971template <>
972+ struct handle_type_name <handle> {
973+ static constexpr auto name = handle_type_name<object>::name;
974+ };
975+ template <>
905976struct handle_type_name <none> {
906977 static constexpr auto name = const_name(" None" );
907978};
908979template <>
980+ struct handle_type_name <sequence> {
981+ static constexpr auto name = const_name(" Sequence" );
982+ };
983+ template <>
984+ struct handle_type_name <bytearray> {
985+ static constexpr auto name = const_name(" bytearray" );
986+ };
987+ template <>
988+ struct handle_type_name <memoryview> {
989+ static constexpr auto name = const_name(" memoryview" );
990+ };
991+ template <>
992+ struct handle_type_name <slice> {
993+ static constexpr auto name = const_name(" slice" );
994+ };
995+ template <>
996+ struct handle_type_name <type> {
997+ static constexpr auto name = const_name(" type" );
998+ };
999+ template <>
1000+ struct handle_type_name <capsule> {
1001+ static constexpr auto name = const_name(" capsule" );
1002+ };
1003+ template <>
1004+ struct handle_type_name <ellipsis> {
1005+ static constexpr auto name = const_name(" ellipsis" );
1006+ };
1007+ template <>
1008+ struct handle_type_name <weakref> {
1009+ static constexpr auto name = const_name(" weakref" );
1010+ };
1011+ template <>
9091012struct handle_type_name <args> {
9101013 static constexpr auto name = const_name(" *args" );
9111014};
9121015template <>
9131016struct handle_type_name <kwargs> {
9141017 static constexpr auto name = const_name(" **kwargs" );
9151018};
1019+ template <>
1020+ struct handle_type_name <obj_attr_accessor> {
1021+ static constexpr auto name = const_name<obj_attr_accessor>();
1022+ };
1023+ template <>
1024+ struct handle_type_name <str_attr_accessor> {
1025+ static constexpr auto name = const_name<str_attr_accessor>();
1026+ };
1027+ template <>
1028+ struct handle_type_name <item_accessor> {
1029+ static constexpr auto name = const_name<item_accessor>();
1030+ };
1031+ template <>
1032+ struct handle_type_name <sequence_accessor> {
1033+ static constexpr auto name = const_name<sequence_accessor>();
1034+ };
1035+ template <>
1036+ struct handle_type_name <list_accessor> {
1037+ static constexpr auto name = const_name<list_accessor>();
1038+ };
1039+ template <>
1040+ struct handle_type_name <tuple_accessor> {
1041+ static constexpr auto name = const_name<tuple_accessor>();
1042+ };
9161043
9171044template <typename type>
9181045struct pyobject_caster {
@@ -1219,13 +1346,24 @@ enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,
12191346// static_assert, even though if it's in dead code, so we provide a "trampoline" to pybind11::cast
12201347// that only does anything in cases where pybind11::cast is valid.
12211348template <typename T>
1222- enable_if_t <cast_is_temporary_value_reference<T>::value, T> cast_safe (object &&) {
1349+ enable_if_t <cast_is_temporary_value_reference<T>::value
1350+ && !detail::is_same_ignoring_cvref<T, PyObject *>::value,
1351+ T>
1352+ cast_safe (object &&) {
12231353 pybind11_fail (" Internal error: cast_safe fallback invoked" );
12241354}
12251355template <typename T>
12261356enable_if_t <std::is_void<T>::value, void > cast_safe (object &&) {}
12271357template <typename T>
1228- enable_if_t <detail::none_of<cast_is_temporary_value_reference<T>, std::is_void<T>>::value, T>
1358+ enable_if_t <detail::is_same_ignoring_cvref<T, PyObject *>::value, PyObject *>
1359+ cast_safe (object &&o) {
1360+ return o.release ().ptr ();
1361+ }
1362+ template <typename T>
1363+ enable_if_t <detail::none_of<cast_is_temporary_value_reference<T>,
1364+ detail::is_same_ignoring_cvref<T, PyObject *>,
1365+ std::is_void<T>>::value,
1366+ T>
12291367cast_safe (object &&o) {
12301368 return pybind11::cast<T>(std::move (o));
12311369}
@@ -1365,7 +1503,7 @@ struct kw_only {};
13651503
13661504// / \ingroup annotations
13671505// / Annotation indicating that all previous arguments are positional-only; the is the equivalent of
1368- // / an unnamed '/' argument (in Python 3.8)
1506+ // / an unnamed '/' argument
13691507struct pos_only {};
13701508
13711509template <typename T>
@@ -1450,7 +1588,8 @@ class argument_loader {
14501588 static_assert (args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(),
14511589 " py::args cannot be specified more than once" );
14521590
1453- static constexpr auto arg_names = concat(type_descr(make_caster<Args>::name)...);
1591+ static constexpr auto arg_names
1592+ = ::pybind11::detail::concat(type_descr(make_caster<Args>::name)...);
14541593
14551594 bool load_args (function_call &call) { return load_impl_sequence (call, indices{}); }
14561595
0 commit comments