Wrapping C++ control objects

C++ control objects defined using the LSST_CONTROL_FIELD macro in lsst/pex/config.h can be wrapped using pybind11 and the functions in lsst.pex.config.wrap, creating an equivalent Python Config object. The Config will automatically create and set values in the C++ object, will provide access to the doc strings from C++, and will even call the C++ class’s validate method, if one exists. This helps to minimize duplication of code.

For example, here is a C++ control object:

struct FooControl {
    LSST_CONTROL_FIELD(bar, int, "documentation for field 'bar'");
    LSST_CONTROL_FIELD(baz, double, "documentation for field 'baz'");

    FooControl() : bar(0), baz(0.0) {}
};

Note that only bool, int, double, and std::string fields, along with std::list and std::vector objects of those types, are fully supported. Nested control objects are not supported.

After using pybind11, the preferred way to create the Config is via the wrap decorator:

import lsst.pex.config as pexConfig

@pexConfig.wrap(FooControl)
class FooConfig(pexConfig.Config):
    pass