{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Namespaces\n", "\n", "It is possible to define a \"root\" namespace, for which no submodule is emitted. Thanks to the option below, the \"Main\" namespace will not be outputted as a submodule. However its content is exported.\n", "```python\n", " options.namespaces_root = [\"Main\"]\n", " ```\n", "\n", "\n", "For other namespace, litgen will output them as python submodules. If a namespace occurs twice in the C++ code, its content will grouped in the Python stubs\n", "\n", "_Note: in the python stub file, a namespace is shown as a fake class (although it is really a python submodule). This avoids the creation of an additional stub file, while maintaining a perfect code completion inside IDEs!_\n", "\n", "In the example below:\n", "* the namespace \"details\" is ignored\n", "* any anonymous namespace is ignored\n", "* occurrences of the namespace \"Inner\" are grouped\n", "* namespaces names are converted to snake_case" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", " \n", "\n", "\n", " \n", " \n", "
\n", "
\n", " \n", "
\n", "
    void FooRoot();  // A function in the root namespace\n",
       "\n",
       "    namespace details // This namespace should be excluded (see options.namespace_exclude__regex)\n",
       "    {\n",
       "        void FooDetails();\n",
       "    }\n",
       "\n",
       "    namespace // This anonymous namespace should be excluded\n",
       "    {\n",
       "        void LocalFunction();\n",
       "    }\n",
       "\n",
       "    // This namespace should not be outputted as a submodule,\n",
       "    // since it is present in options.namespaces_root \n",
       "    namespace Main\n",
       "    {\n",
       "        // this is an inner namespace (this comment should become the namespace doc)\n",
       "        namespace Inner\n",
       "        {\n",
       "            void FooInner();\n",
       "        }\n",
       "\n",
       "        // This is a second occurrence of the same inner namespace\n",
       "        // The generated python module will merge these occurrences\n",
       "        // (and this comment will be ignored, since the Inner namespace already has a doc)\n",
       "        namespace Inner\n",
       "        {\n",
       "            void FooInner2();\n",
       "        }\n",
       "    }\n",
       "
\n", "\n", "
\n", " \n", " \n", " \n", " \n", " \n", "
\n", "
\n", "
\n", " \n", "\n", "\n", " \n", " \n", "
\n", "
\n", " \n", "
\n", "
def foo_root() -> None:\n",
       "    """ A function in the root namespace"""\n",
       "    pass\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "# <submodule inner>\n",
       "class inner:  # Proxy class that introduces typings for the *submodule* inner\n",
       "    pass  # (This corresponds to a C++ namespace. All method are static!)\n",
       "    """ this is an inner namespace (this comment should become the namespace doc)"""\n",
       "    @staticmethod\n",
       "    def foo_inner() -> None:\n",
       "        pass\n",
       "    @staticmethod\n",
       "    def foo_inner2() -> None:\n",
       "        pass\n",
       "\n",
       "# </submodule inner>\n",
       "
\n", "\n", "
\n", " \n", " \n", " \n", " \n", " \n", "
\n", "
\n", "
\n", "\n", "\n", " \n", " \n", "
\n", "
\n", " \n", "
\n", "
m.def("foo_root",\n",
       "    FooRoot, "A function in the root namespace");\n",
       "\n",
       "{ // <namespace Inner>\n",
       "    py::module_ pyNsInner = m.def_submodule("inner", "this is an inner namespace (this comment should become the namespace doc)");\n",
       "    pyNsInner.def("foo_inner",\n",
       "        Main::Inner::FooInner);\n",
       "    pyNsInner.def("foo_inner2",\n",
       "        Main::Inner::FooInner2);\n",
       "} // </namespace Inner>\n",
       "
\n", "\n", "
\n", " \n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cpp_code = \"\"\"\n", "\n", " void FooRoot(); // A function in the root namespace\n", "\n", " namespace details // This namespace should be excluded (see options.namespace_exclude__regex)\n", " {\n", " void FooDetails();\n", " }\n", "\n", " namespace // This anonymous namespace should be excluded\n", " {\n", " void LocalFunction();\n", " }\n", "\n", " // This namespace should not be outputted as a submodule,\n", " // since it is present in options.namespaces_root \n", " namespace Main\n", " {\n", " // this is an inner namespace (this comment should become the namespace doc)\n", " namespace Inner\n", " {\n", " void FooInner();\n", " }\n", "\n", " // This is a second occurrence of the same inner namespace\n", " // The generated python module will merge these occurrences\n", " // (and this comment will be ignored, since the Inner namespace already has a doc)\n", " namespace Inner\n", " {\n", " void FooInner2();\n", " }\n", " }\n", "\"\"\"\n", "\n", "import litgen\n", "from litgen.demo import litgen_demo\n", "\n", "options = litgen.LitgenOptions()\n", "options.namespaces_root = [\"Main\"]\n", "# options.namespace_exclude__regex = r\"[Ii]nternal|[Dd]etail\" # this is the default!\n", "options.python_run_black_formatter = True\n", "# options.python_convert_to_snake_case = False # uncomment this in order to keep the original namespaces and functions names\n", "litgen_demo.demo(options, cpp_code)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "venv311", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.0" } }, "nbformat": 4, "nbformat_minor": 2 }