diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html
index e5932e70..61c5ef88 100644
--- a/doc/exporting_classes.html
+++ b/doc/exporting_classes.html
@@ -98,6 +98,12 @@ Notes:
- Any function added to a class whose initial argument matches the class (or
any base) will act like a member function in Python.
+
+
- To define a nested class, just pass the enclosing
+class_builder (instead of a module_builder) as the
+first argument to the nested class_builder's constructor.
+
+
We can even make a subclass of hello.world:
diff --git a/include/boost/python/class_builder.hpp b/include/boost/python/class_builder.hpp
index 4a9ec1b2..fe2a7b74 100644
--- a/include/boost/python/class_builder.hpp
+++ b/include/boost/python/class_builder.hpp
@@ -25,6 +25,22 @@ class class_builder
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
}
+ template
+ class_builder(class_builder& cls, const char* name)
+ : m_class(new detail::extension_class(name))
+ {
+ cls.add(ref(as_object(m_class.get()), ref::increment_count), name);
+ }
+
+ template
+ class_builder(detail::extension_class* cls,
+ const char* name)
+ : m_class(new detail::extension_class(name))
+ {
+ cls->set_attribute(name,
+ ref(as_object(m_class.get()), ref::increment_count));
+ }
+
~class_builder()
{}
diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp
index d25b131a..6c7cc4d3 100644
--- a/test/comprehensive.cpp
+++ b/test/comprehensive.cpp
@@ -67,6 +67,16 @@ Foo::PythonClass::PythonClass(boost::python::module_builder& m)
def(&Foo::add_len, "add_len", &FooCallback::default_add_len);
// Since pure() is pure virtual, we are leaving it undefined.
+
+ // And the nested classes.
+ boost::python::class_builder foo_a(*this, "Foo_A");
+ foo_a.def(boost::python::constructor<>());
+ foo_a.def(&Foo::Foo_A::mumble, "mumble");
+
+ boost::python::class_builder foo_b(get_extension_class(),
+ "Foo_B");
+ foo_b.def(boost::python::constructor<>());
+ foo_b.def(&Foo::Foo_B::mumble, "mumble");
}
BarPythonClass::BarPythonClass(boost::python::module_builder& m)
@@ -223,6 +233,16 @@ const char* Foo::mumble()
return "mumble";
}
+const char* Foo::Foo_A::mumble()
+{
+ return "mumble a";
+}
+
+const char* Foo::Foo_B::mumble()
+{
+ return "mumble b";
+}
+
void Foo::set(long x)
{
m_x = x;
diff --git a/test/comprehensive.hpp b/test/comprehensive.hpp
index ed90f061..deb68a88 100644
--- a/test/comprehensive.hpp
+++ b/test/comprehensive.hpp
@@ -42,6 +42,10 @@ class Foo // prohibit copying, proving that it doesn't choke
std::string call_pure(); // call a pure virtual fuction
int call_add_len(const char* s) const; // virtual function with a default implementation
+ // A couple nested classs.
+ struct Foo_A { const char* mumble(); };
+ struct Foo_B { const char* mumble(); };
+
private:
// by default, sum the held value and the length of s
virtual int add_len(const char* s) const;
diff --git a/test/comprehensive.py b/test/comprehensive.py
index c49a4add..7d0bec79 100644
--- a/test/comprehensive.py
+++ b/test/comprehensive.py
@@ -230,6 +230,14 @@ Polymorphism also works:
>>> baz.get_foo_value(polymorphic_foo)
1000
+Simple nested class test:
+ >>> foo_a = Foo.Foo_A()
+ >>> foo_a.mumble()
+ 'mumble a'
+ >>> foo_b = Foo.Foo_B()
+ >>> foo_b.mumble()
+ 'mumble b'
+
Pickling tests:
>>> world.__module__
@@ -343,7 +351,7 @@ Special member attributes. Tests courtesy of Barry Scott