No subject


Tue Oct 14 00:29:20 CEST 2008


creates a submodule of whatever the current outer module is (whatever was
passed to BOOST_PYTHON_MODULE_INIT). The benefits of being able to drop
*just* the outer module name seem questionable to me; I think people will
be confused by the lack of uniformity. I think I'd rather see a simple and
straightforward approach where the full module qualification is supplied. I
guess the question is, "how much work is it to make a submodule of an
extension module that may be located anywhere in the package hierarchy?"
OK, now I think I see why Dave wants to support '.'-prefixed module names.

Because this usage creates a temporary which is destroyed immediately, I
also take it that there's a "current inner module" into which new def()s
and class_<> instances stick their Python results. At this point,
python::module might as well be a function. One thing I dislike about that
is that (if my assumptions are correct) some obvious usages give an
unexpected result:

    void initialize_inner()
    {
        module(".inner");
        def("g", g);
    }

    BOOST_PYTHON_MODULE_INIT(outer)
    {
        def("f", f);
        initialize_inner();
        def("h", h);        // creates outer.inner.h!
    }

So we could return to the current syntax for inner modules:

    void initialize_inner()
    {
        module("outer.inner")
            .def("g", g)
            ;
    }

    BOOST_PYTHON_MODULE_INIT(outer)
    {
        def("f", f);
        initialize_inner();
        def("h", h);       // ok
    }

I'm beginning to settle on the following conclusions:

. module is a class derived from object. That makes constructs like:

    m.attr("x") = 1

possible.

. It takes a single string in its constructor.

. The name in the string is an absolute path if it does not begin with a
'.'

. Otherwise, the name in the string supplies a path relative to whatever is
being constructed with BOOST_PYTHON_MODULE_INIT.

. I am not convinced of the utility of auto-creating missing intermediate
modules in:

    module("w.x.y.z")

I'd be just as happy with a runtime error if it simplifies the code even a
little. In fact, I take it back: not giving a runtime error could mask
errors. I want to require that parent modules be constructed already.

. What about auto-creating child modules? Clearly we want to be able to
say:

  module(".x")

and have it create the x submodule. However I think I would be very unhappy
if module("sys") did anything other than retrieving (loading, if
neccessary) the built-in "sys" module. Conclusion: when the constructor arg
begins with '.', we auto-construct leaf modules. Otherwise, we don't. That
leaves out the ability to build new modules with an absolute package path
using module(...). Oh, well, no great loss.

. BOOST_PYTHON_MODULE_INIT(...) creates a "module context", inside which
def() and class_<> normally place their definitions. *If* we want to get
around the class<> ordering problems for inner modules, we ought to provide
a "module_scope" class which changes the target module of def() and
class_<>... Why not just use module() itself, so that the last module
created will always be the target?

    module("sys").attr("argv")

is one good argument against it.

. All of the stuff "above the line" can be done very cleanly; there are
almost no questions about how it should work. We can afford to let the
stuff "below the line" percolate a little bit before adding it.

After we've had a round of comments on this message, we can discuss inner
classes.

Thanks for listening,
Dave







More information about the Cplusplus-sig mailing list