File tree 4 files changed +35
-2
lines changed
4 files changed +35
-2
lines changed Original file line number Diff line number Diff line change @@ -218,6 +218,8 @@ class type_caster_generic {
218
218
if (!src || !typeinfo)
219
219
return false ;
220
220
if (src.is_none ()) {
221
+ // Defer accepting None to other overloads (if we aren't in convert mode):
222
+ if (!convert) return false ;
221
223
value = nullptr ;
222
224
return true ;
223
225
}
@@ -978,6 +980,8 @@ struct copyable_holder_caster : public type_caster_base<type> {
978
980
if (!src || !typeinfo)
979
981
return false ;
980
982
if (src.is_none ()) {
983
+ // Defer accepting None to other overloads (if we aren't in convert mode):
984
+ if (!convert) return false ;
981
985
value = nullptr ;
982
986
return true ;
983
987
}
Original file line number Diff line number Diff line change @@ -22,9 +22,12 @@ struct type_caster<std::function<Return(Args...)>> {
22
22
using function_type = Return (*) (Args...);
23
23
24
24
public:
25
- bool load (handle src, bool ) {
26
- if (src.is_none ())
25
+ bool load (handle src, bool convert) {
26
+ if (src.is_none ()) {
27
+ // Defer accepting None to other overloads (if we aren't in convert mode):
28
+ if (!convert) return false ;
27
29
return true ;
30
+ }
28
31
29
32
if (!isinstance<function>(src))
30
33
return false ;
Original file line number Diff line number Diff line change @@ -499,6 +499,18 @@ test_initializer python_types([](py::module &m) {
499
499
m.def (" return_none_int" , []() -> int * { return nullptr ; });
500
500
m.def (" return_none_float" , []() -> float * { return nullptr ; });
501
501
502
+ m.def (" defer_none_cstring" , [](char *) { return false ; });
503
+ m.def (" defer_none_cstring" , [](py::none) { return true ; });
504
+ m.def (" defer_none_custom" , [](ExamplePythonTypes *) { return false ; });
505
+ m.def (" defer_none_custom" , [](py::none) { return true ; });
506
+ // void and optional, however, don't defer:
507
+ m.def (" nodefer_none_void" , [](void *) { return true ; });
508
+ m.def (" nodefer_none_void" , [](py::none) { return false ; });
509
+ #ifdef PYBIND11_HAS_OPTIONAL
510
+ m.def (" nodefer_none_optional" , [](std::optional<int >) { return true ; });
511
+ m.def (" nodefer_none_optional" , [](py::none) { return false ; });
512
+ #endif
513
+
502
514
m.def (" return_capsule_with_destructor" ,
503
515
[]() {
504
516
py::print (" creating capsule" );
Original file line number Diff line number Diff line change @@ -549,8 +549,22 @@ def test_builtins_cast_return_none():
549
549
assert m .return_none_float () is None
550
550
551
551
552
+ def test_none_deferred ():
553
+ """None passed as various argument types should defer to other overloads"""
554
+ import pybind11_tests as m
555
+
556
+ assert not m .defer_none_cstring ("abc" )
557
+ assert m .defer_none_cstring (None )
558
+ assert not m .defer_none_custom (m .ExamplePythonTypes .new_instance ())
559
+ assert m .defer_none_custom (None )
560
+ assert m .nodefer_none_void (None )
561
+ if has_optional :
562
+ assert m .nodefer_none_optional (None )
563
+
564
+
552
565
def test_capsule_with_destructor (capture ):
553
566
import pybind11_tests as m
567
+ pytest .gc_collect ()
554
568
with capture :
555
569
a = m .return_capsule_with_destructor ()
556
570
del a
You can’t perform that action at this time.
0 commit comments