Namespaces

Namespaces#

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.

     options.namespaces_root = ["Main"]

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

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!

In the example below:

  • the namespace “details” is ignored

  • any anonymous namespace is ignored

  • occurrences of the namespace “Inner” are grouped

  • namespaces names are converted to snake_case

cpp_code = """

    void FooRoot();  // A function in the root namespace

    namespace details // This namespace should be excluded (see options.namespace_exclude__regex)
    {
        void FooDetails();
    }

    namespace // This anonymous namespace should be excluded
    {
        void LocalFunction();
    }

    // This namespace should not be outputted as a submodule,
    // since it is present in options.namespaces_root 
    namespace Main
    {
        // this is an inner namespace (this comment should become the namespace doc)
        namespace Inner
        {
            void FooInner();
        }

        // This is a second occurrence of the same inner namespace
        // The generated python module will merge these occurrences
        // (and this comment will be ignored, since the Inner namespace already has a doc)
        namespace Inner
        {
            void FooInner2();
        }
    }
"""

import litgen
from litgen.demo import litgen_demo

options = litgen.LitgenOptions()
options.namespaces_root = ["Main"]
# options.namespace_exclude__regex = r"[Ii]nternal|[Dd]etail"  # this is the default!
options.python_run_black_formatter = True
# options.python_convert_to_snake_case = False  # uncomment this in order to keep the original namespaces and functions names
litgen_demo.demo(options, cpp_code)
    void FooRoot();  // A function in the root namespace

    namespace details // This namespace should be excluded (see options.namespace_exclude__regex)
    {
        void FooDetails();
    }

    namespace // This anonymous namespace should be excluded
    {
        void LocalFunction();
    }

    // This namespace should not be outputted as a submodule,
    // since it is present in options.namespaces_root 
    namespace Main
    {
        // this is an inner namespace (this comment should become the namespace doc)
        namespace Inner
        {
            void FooInner();
        }

        // This is a second occurrence of the same inner namespace
        // The generated python module will merge these occurrences
        // (and this comment will be ignored, since the Inner namespace already has a doc)
        namespace Inner
        {
            void FooInner2();
        }
    }
def foo_root() -> None:
    """ A function in the root namespace"""
    pass






# <submodule inner>
class inner:  # Proxy class that introduces typings for the *submodule* inner
    pass  # (This corresponds to a C++ namespace. All method are static!)
    """ this is an inner namespace (this comment should become the namespace doc)"""
    @staticmethod
    def foo_inner() -> None:
        pass
    @staticmethod
    def foo_inner2() -> None:
        pass

# </submodule inner>


m.def("foo_root",
    FooRoot, "A function in the root namespace");

{ // <namespace Inner>
    py::module_ pyNsInner = m.def_submodule("inner", "this is an inner namespace (this comment should become the namespace doc)");
    pyNsInner.def("foo_inner",
        Main::Inner::FooInner);
    pyNsInner.def("foo_inner2",
        Main::Inner::FooInner2);
} // </namespace Inner>
m.def("foo_root",
    FooRoot, "A function in the root namespace");

{ // <namespace Inner>
    nb::module_ pyNsInner = m.def_submodule("inner", "this is an inner namespace (this comment should become the namespace doc)");
    pyNsInner.def("foo_inner",
        Main::Inner::FooInner);
    pyNsInner.def("foo_inner2",
        Main::Inner::FooInner2);
} // </namespace Inner>