Skip to content

pybind11 doesn't allow same name nested class defined in different scope #310

@jslee02

Description

@jslee02

Given the following code, pybind11 generates binding code correctly and builds with no errors.

class Base
{
public:
    Base() = default;
    class Option
    {
    public:
        Option() = default;
    };
};

class Derived : public Base
{
public:
    Derived() = default;
    class Option : public Base::Option
    {
    public:
        Option() = default;
    };
};

// Binding code
{
    auto sm = m.def_submodule("common");
    auto attr = sm;
    ::pybind11::class_<chimera_test::common::Base >(attr, "Base")
        .def(::pybind11::init<>());
}
{
    auto sm = m.def_submodule("common");
    auto attr = sm.attr("Base");
    ::pybind11::class_<chimera_test::common::Base::Option >(attr, "Option")
        .def(::pybind11::init<>());
}
{
    auto sm = m.def_submodule("common");
    auto attr = sm;
    ::pybind11::class_<chimera_test::common::CommonDerivedA, chimera_test::common::Base >(attr, "CommonDerivedA")
        .def(::pybind11::init<>());
}
{
    auto sm = m.def_submodule("common");
    auto attr = sm.attr("CommonDerivedA");
    ::pybind11::class_<chimera_test::common::CommonDerivedA::Option, chimera_test::common::Base::Option >(attr, "Option")  // works if changed to "Option2"
        .def(::pybind11::init<>());
}

However, module loading fails saying:

ImportError: generic_type: cannot initialize type "Option": an object with that name is already defined

Boost.Python works fine.


Additional findings:

  1. This issue happens even Base and Derived is in different namespace.
  2. This issue only happens when Option is at the same level. For example, this issue disappear in the following case:
class Base
{
public:
    Base() = default;
    class Option
    {
    public:
        Option() = default;
    };
};

class Derived : public Base
{
public:
    Derived() = default;
    class NestedClass
    {
	public:
        class Option : public Base::Option
        {
        public:
            Option() = default;
        };
    };
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions