Register a function call with Python (generic non-templated code goes here)
| 674 | |
| 675 | /// Register a function call with Python (generic non-templated code goes here) |
| 676 | void initialize_generic(unique_function_record &&unique_rec, |
| 677 | const char *text, |
| 678 | const std::type_info *const *types, |
| 679 | size_t args) { |
| 680 | // Do NOT receive `unique_rec` by value. If this function fails to move out the unique_ptr, |
| 681 | // we do not want this to destruct the pointer. `initialize` (the caller) still relies on |
| 682 | // the pointee being alive after this call. Only move out if a `capsule` is going to keep |
| 683 | // it alive. |
| 684 | auto *rec = unique_rec.get(); |
| 685 | |
| 686 | // Keep track of strdup'ed strings, and clean them up as long as the function's capsule |
| 687 | // has not taken ownership yet (when `unique_rec.release()` is called). |
| 688 | // Note: This cannot easily be fixed by a `unique_ptr` with custom deleter, because the |
| 689 | // strings are only referenced before strdup'ing. So only *after* the following block could |
| 690 | // `destruct` safely be called, but even then, `repr` could still throw in the middle of |
| 691 | // copying all strings. |
| 692 | strdup_guard guarded_strdup; |
| 693 | |
| 694 | /* Create copies of all referenced C-style strings */ |
| 695 | rec->name = guarded_strdup(rec->name ? rec->name : ""); |
| 696 | if (rec->doc) { |
| 697 | rec->doc = guarded_strdup(rec->doc); |
| 698 | } |
| 699 | for (auto &a : rec->args) { |
| 700 | if (a.name) { |
| 701 | a.name = guarded_strdup(a.name); |
| 702 | } |
| 703 | if (a.descr) { |
| 704 | a.descr = guarded_strdup(a.descr); |
| 705 | } else if (a.value) { |
| 706 | a.descr = guarded_strdup(repr(a.value).cast<std::string>().c_str()); |
| 707 | } |
| 708 | } |
| 709 | |
| 710 | rec->is_constructor = (std::strcmp(rec->name, "__init__") == 0) |
| 711 | || (std::strcmp(rec->name, "__setstate__") == 0); |
| 712 | |
| 713 | #if defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING) |
| 714 | if (rec->is_constructor && !rec->is_new_style_constructor) { |
| 715 | const auto class_name |
| 716 | = detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr()); |
| 717 | const auto func_name = std::string(rec->name); |
| 718 | PyErr_WarnEx(PyExc_FutureWarning, |
| 719 | ("pybind11-bound class '" + class_name |
| 720 | + "' is using an old-style " |
| 721 | "placement-new '" |
| 722 | + func_name |
| 723 | + "' which has been deprecated. See " |
| 724 | "the upgrade guide in pybind11's docs. This message is only visible " |
| 725 | "when compiled in debug mode.") |
| 726 | .c_str(), |
| 727 | 0); |
| 728 | } |
| 729 | #endif |
| 730 | |
| 731 | size_t type_index = 0, arg_index = 0; |
| 732 | std::string signature |
| 733 | = detail::generate_function_signature(text, rec, types, type_index, arg_index); |
nothing calls this directly
no test coverage detected