mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 05:42:30 +00:00
Integrated Scott Snyder's nested class patch
[SVN r12080]
This commit is contained in:
@@ -98,6 +98,12 @@ Notes:<ul>
|
||||
|
||||
<li>Any function added to a class whose initial argument matches the class (or
|
||||
any base) will act like a member function in Python.
|
||||
|
||||
<li>To define a nested class, just pass the enclosing
|
||||
<tt>class_builder</tt> (instead of a <tt>module_builder</tt>) as the
|
||||
first argument to the nested <tt>class_builder</tt>'s constructor.
|
||||
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
We can even make a subclass of <code>hello.world</code>:
|
||||
|
||||
@@ -25,6 +25,22 @@ class class_builder
|
||||
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
template <class OtherT, class OtherU>
|
||||
class_builder(class_builder<OtherT, OtherU>& cls, const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
cls.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
template <class OtherT, class OtherU>
|
||||
class_builder(detail::extension_class<OtherT, OtherU>* cls,
|
||||
const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
cls->set_attribute(name,
|
||||
ref(as_object(m_class.get()), ref::increment_count));
|
||||
}
|
||||
|
||||
~class_builder()
|
||||
{}
|
||||
|
||||
|
||||
@@ -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::Foo_A> foo_a(*this, "Foo_A");
|
||||
foo_a.def(boost::python::constructor<>());
|
||||
foo_a.def(&Foo::Foo_A::mumble, "mumble");
|
||||
|
||||
boost::python::class_builder<Foo::Foo_B> 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <barry@scottb.demon.co.
|
||||
... '__doc__', '__module__', 'fred', 'i_am_derived_from_base']
|
||||
... else:
|
||||
... assert dir(df) == [
|
||||
... '__del__', '__doc__', '__init__', '__module__', 'add_len',
|
||||
... 'Foo_A', 'Foo_B', '__del__', '__doc__', '__init__', '__module__', 'add_len',
|
||||
... 'call_add_len', 'call_pure', 'fred', 'mumble', 'set']
|
||||
... assert dir(db) == ['__doc__', '__module__', 'fred'
|
||||
... , 'i_am_base', 'i_am_derived_from_base']
|
||||
|
||||
Reference in New Issue
Block a user