\rst Create and return a new Python submodule with the given name and docstring. This also works recursively, i.e. .. code-block:: cpp py::module_ m("example", "pybind11 example plugin"); py::module_ m2 = m.def_submodule("sub", "A submodule of 'example'"); py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
| 1627 | py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); |
| 1628 | \endrst */ |
| 1629 | module_ def_submodule(const char *name, const char *doc = nullptr) { |
| 1630 | const char *this_name = PyModule_GetName(m_ptr); |
| 1631 | if (this_name == nullptr) { |
| 1632 | throw error_already_set(); |
| 1633 | } |
| 1634 | std::string full_name = std::string(this_name) + '.' + name; |
| 1635 | handle submodule = PyImport_AddModule(full_name.c_str()); |
| 1636 | if (!submodule) { |
| 1637 | throw error_already_set(); |
| 1638 | } |
| 1639 | auto result = reinterpret_borrow<module_>(submodule); |
| 1640 | if (doc && options::show_user_defined_docstrings()) { |
| 1641 | result.attr("__doc__") = pybind11::str(doc); |
| 1642 | } |
| 1643 | |
| 1644 | #if defined(GRAALVM_PYTHON) && (!defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM < 0x190000) |
| 1645 | // GraalPy doesn't support PyModule_GetFilenameObject, |
| 1646 | // so getting by attribute (see PR #5584) |
| 1647 | handle this_module = m_ptr; |
| 1648 | if (object this_file = getattr(this_module, "__file__", none())) { |
| 1649 | result.attr("__file__") = this_file; |
| 1650 | } |
| 1651 | #else |
| 1652 | handle this_file = PyModule_GetFilenameObject(m_ptr); |
| 1653 | if (this_file) { |
| 1654 | result.attr("__file__") = this_file; |
| 1655 | } else if (PyErr_ExceptionMatches(PyExc_SystemError) != 0) { |
| 1656 | PyErr_Clear(); |
| 1657 | } else { |
| 1658 | throw error_already_set(); |
| 1659 | } |
| 1660 | #endif |
| 1661 | attr(name) = result; |
| 1662 | return result; |
| 1663 | } |
| 1664 | |
| 1665 | /// Import and return a module or throws `error_already_set`. |
| 1666 | static module_ import(const char *name) { |