@@ -118,31 +118,31 @@ class cpp_function : public function {
118
118
" The number of named arguments does not match the function signature" );
119
119
120
120
/* Dispatch code which converts function arguments and performs the actual function call */
121
- rec->impl = [](detail::function_record *rec, detail::function_arguments args, handle parent ) -> handle {
121
+ rec->impl = [](detail::function_call &call ) -> handle {
122
122
cast_in args_converter;
123
123
124
124
/* Try to cast the function arguments into the C++ domain */
125
- if (!args_converter.load_args (args))
125
+ if (!args_converter.load_args (call. args ))
126
126
return PYBIND11_TRY_NEXT_OVERLOAD;
127
127
128
128
/* Invoke call policy pre-call hook */
129
- detail::process_attributes<Extra...>::precall (args );
129
+ detail::process_attributes<Extra...>::precall (call );
130
130
131
131
/* Get a pointer to the capture object */
132
- capture *cap = (capture *) (sizeof (capture) <= sizeof (rec-> data )
133
- ? &rec-> data : rec-> data [0 ]);
132
+ capture *cap = (capture *) (sizeof (capture) <= sizeof (call. func . data )
133
+ ? &call. func . data : call. func . data [0 ]);
134
134
135
135
/* Override policy for rvalues -- always move */
136
136
constexpr auto is_rvalue = !std::is_pointer<Return>::value
137
137
&& !std::is_lvalue_reference<Return>::value;
138
- const auto policy = is_rvalue ? return_value_policy::move : rec-> policy ;
138
+ const auto policy = is_rvalue ? return_value_policy::move : call. func . policy ;
139
139
140
140
/* Perform the function call */
141
141
handle result = cast_out::cast (args_converter.template call <Return>(cap->f ),
142
- policy, parent);
142
+ policy, call. parent );
143
143
144
144
/* Invoke call policy post-call hook */
145
- detail::process_attributes<Extra...>::postcall (args , result);
145
+ detail::process_attributes<Extra...>::postcall (call , result);
146
146
147
147
return result;
148
148
};
@@ -381,9 +381,11 @@ class cpp_function : public function {
381
381
382
382
// / Main dispatch logic for calls to functions bound using pybind11
383
383
static PyObject *dispatcher (PyObject *self, PyObject *args_in, PyObject *kwargs_in) {
384
+ using namespace detail ;
385
+
384
386
/* Iterator over the list of potentially admissible overloads */
385
- detail:: function_record *overloads = (detail:: function_record *) PyCapsule_GetPointer (self, nullptr ),
386
- *it = overloads;
387
+ function_record *overloads = (function_record *) PyCapsule_GetPointer (self, nullptr ),
388
+ *it = overloads;
387
389
388
390
/* Need to know how many arguments + keyword arguments there are to pick the right overload */
389
391
const size_t n_args_in = (size_t ) PyTuple_GET_SIZE (args_in);
@@ -411,18 +413,18 @@ class cpp_function : public function {
411
413
result other than PYBIND11_TRY_NEXT_OVERLOAD.
412
414
*/
413
415
414
- size_t pos_args = it->nargs ; // Number of positional arguments that we need
415
- if (it->has_args ) --pos_args; // (but don't count py::args
416
- if (it->has_kwargs ) --pos_args; // or py::kwargs)
416
+ function_record &func = *it;
417
+ size_t pos_args = func.nargs ; // Number of positional arguments that we need
418
+ if (func.has_args ) --pos_args; // (but don't count py::args
419
+ if (func.has_kwargs ) --pos_args; // or py::kwargs)
417
420
418
- if (!it-> has_args && n_args_in > pos_args)
421
+ if (!func. has_args && n_args_in > pos_args)
419
422
continue ; // Too many arguments for this overload
420
423
421
- if (n_args_in < pos_args && it-> args .size () < pos_args)
424
+ if (n_args_in < pos_args && func. args .size () < pos_args)
422
425
continue ; // Not enough arguments given, and not enough defaults to fill in the blanks
423
426
424
- std::vector<handle> pass_args;
425
- pass_args.reserve (it->nargs );
427
+ function_call call (func, parent);
426
428
427
429
size_t args_to_copy = std::min (pos_args, n_args_in);
428
430
size_t args_copied = 0 ;
@@ -440,7 +442,7 @@ class cpp_function : public function {
440
442
std::string (it->args [args_copied].name ) + " '" );
441
443
}
442
444
443
- pass_args .push_back (PyTuple_GET_ITEM (args_in, args_copied));
445
+ call. args .push_back (PyTuple_GET_ITEM (args_in, args_copied));
444
446
}
445
447
446
448
// We'll need to copy this if we steal some kwargs for defaults
@@ -470,7 +472,7 @@ class cpp_function : public function {
470
472
}
471
473
472
474
if (value)
473
- pass_args .push_back (value);
475
+ call. args .push_back (value);
474
476
else
475
477
break ;
476
478
}
@@ -502,22 +504,26 @@ class cpp_function : public function {
502
504
extra_args[i] = item.inc_ref ().ptr ();
503
505
}
504
506
}
505
- pass_args .push_back (extra_args);
507
+ call. args .push_back (extra_args);
506
508
}
507
509
508
510
// 4b. If we have a py::kwargs, pass on any remaining kwargs
509
511
if (it->has_kwargs ) {
510
512
if (!kwargs.ptr ())
511
513
kwargs = dict (); // If we didn't get one, send an empty one
512
- pass_args .push_back (kwargs);
514
+ call. args .push_back (kwargs);
513
515
}
514
516
515
- // 5. Put everything in a big tuple. Not technically step 5, we've been building it
516
- // in `pass_args` all along.
517
+ // 5. Put everything in a vector. Not technically step 5, we've been building it
518
+ // in `call.args` all along.
519
+ #if !defined(NDEBUG)
520
+ if (call.args .size () != call.func .nargs )
521
+ pybind11_fail (" Internal error: function call dispatcher inserted wrong number of arguments!" );
522
+ #endif
517
523
518
524
// 6. Call the function.
519
525
try {
520
- result = it->impl (it, pass_args, parent );
526
+ result = it->impl (call );
521
527
} catch (reference_cast_error &) {
522
528
result = PYBIND11_TRY_NEXT_OVERLOAD;
523
529
}
@@ -541,7 +547,7 @@ class cpp_function : public function {
541
547
- delegate translation to the next translator by throwing a new type of exception. */
542
548
543
549
auto last_exception = std::current_exception ();
544
- auto ®istered_exception_translators = pybind11::detail:: get_internals ().registered_exception_translators ;
550
+ auto ®istered_exception_translators = get_internals ().registered_exception_translators ;
545
551
for (auto & translator : registered_exception_translators) {
546
552
try {
547
553
translator (last_exception);
@@ -564,7 +570,7 @@ class cpp_function : public function {
564
570
" arguments. The following argument types are supported:\n " ;
565
571
566
572
int ctr = 0 ;
567
- for (detail:: function_record *it2 = overloads; it2 != nullptr ; it2 = it2->next ) {
573
+ for (function_record *it2 = overloads; it2 != nullptr ; it2 = it2->next ) {
568
574
msg += " " + std::to_string (++ctr) + " . " ;
569
575
570
576
bool wrote_sig = false ;
@@ -609,7 +615,7 @@ class cpp_function : public function {
609
615
if (overloads->is_constructor ) {
610
616
/* When a constructor ran successfully, the corresponding
611
617
holder type (e.g. std::unique_ptr) must still be initialized. */
612
- auto tinfo = detail:: get_type_info (Py_TYPE (parent.ptr ()));
618
+ auto tinfo = get_type_info (Py_TYPE (parent.ptr ()));
613
619
tinfo->init_holder (parent.ptr (), nullptr );
614
620
}
615
621
return result.ptr ();
@@ -1477,10 +1483,10 @@ inline void keep_alive_impl(handle nurse, handle patient) {
1477
1483
(void ) wr.release ();
1478
1484
}
1479
1485
1480
- PYBIND11_NOINLINE inline void keep_alive_impl (size_t Nurse, size_t Patient, function_arguments args , handle ret) {
1486
+ PYBIND11_NOINLINE inline void keep_alive_impl (size_t Nurse, size_t Patient, function_call &call , handle ret) {
1481
1487
keep_alive_impl (
1482
- Nurse == 0 ? ret : Nurse <= args.size () ? args[Nurse - 1 ] : handle (),
1483
- Patient == 0 ? ret : Patient <= args.size () ? args[Patient - 1 ] : handle ()
1488
+ Nurse == 0 ? ret : Nurse <= call. args .size () ? call. args [Nurse - 1 ] : handle (),
1489
+ Patient == 0 ? ret : Patient <= call. args .size () ? call. args [Patient - 1 ] : handle ()
1484
1490
);
1485
1491
}
1486
1492
0 commit comments