$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r69551 - in trunk/libs/python: . src/object test
From: rwgk_at_[hidden]
Date: 2011-03-04 12:32:44
Author: rwgk
Date: 2011-03-04 12:32:41 EST (Fri, 04 Mar 2011)
New Revision: 69551
URL: http://svn.boost.org/trac/boost/changeset/69551
Log:
libs/python/src/object/class.cpp: metaclass fixes by James Emerton: james at emdata dot net
Added:
   trunk/libs/python/class.cpp   (contents, props changed)
   trunk/libs/python/test/class.cpp   (contents, props changed)
   trunk/libs/python/test/class.py   (contents, props changed)
Text files modified: 
   trunk/libs/python/src/object/class.cpp |     9 +++++----                               
   trunk/libs/python/test/Jamfile.v2      |     1 +                                       
   2 files changed, 6 insertions(+), 4 deletions(-)
Added: trunk/libs/python/class.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/python/class.cpp	2011-03-04 12:32:41 EST (Fri, 04 Mar 2011)
@@ -0,0 +1,28 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+struct X
+{
+    int x;
+    X(int n) : x(n) { }
+};
+
+int x_function(X& x)
+{   return x.x;
+}
+
+
+BOOST_PYTHON_MODULE(class_ext)
+{
+    class_<X>("X", init<int>());
+    def("x_function", x_function);
+}
+
+#include "module_tail.cpp"
Modified: trunk/libs/python/src/object/class.cpp
==============================================================================
--- trunk/libs/python/src/object/class.cpp	(original)
+++ trunk/libs/python/src/object/class.cpp	2011-03-04 12:32:41 EST (Fri, 04 Mar 2011)
@@ -303,7 +303,7 @@
 // object.
 void instance_holder::install(PyObject* self) throw()
 {
-    assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
+    assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self)), &class_metatype_object));
     m_next = ((objects::instance<>*)self)->objects;
     ((objects::instance<>*)self)->objects = this;
 }
@@ -482,7 +482,8 @@
   BOOST_PYTHON_DECL void*
   find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
   {
-      if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
+      if (!Py_TYPE(Py_TYPE(inst)) ||
+              !PyType_IsSubtype(Py_TYPE(Py_TYPE(inst)), &class_metatype_object))
           return 0;
     
       instance<>* self = reinterpret_cast<instance<>*>(inst);
@@ -727,7 +728,7 @@
 
 void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
 {
-    assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
+    assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
     objects::instance<>* self = (objects::instance<>*)self_;
     
     int total_size_needed = holder_offset + holder_size;
@@ -752,7 +753,7 @@
 
 void instance_holder::deallocate(PyObject* self_, void* storage) throw()
 {
-    assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
+    assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
     objects::instance<>* self = (objects::instance<>*)self_;
     if (storage != (char*)self + Py_SIZE(self))
     {
Modified: trunk/libs/python/test/Jamfile.v2
==============================================================================
--- trunk/libs/python/test/Jamfile.v2	(original)
+++ trunk/libs/python/test/Jamfile.v2	2011-03-04 12:32:41 EST (Fri, 04 Mar 2011)
@@ -117,6 +117,7 @@
  [ bpl-test defaults ]
 
 [ bpl-test object ]
+[ bpl-test class ]
 [ bpl-test list ]
 [ bpl-test long ]
 [ bpl-test dict ]
Added: trunk/libs/python/test/class.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/python/test/class.cpp	2011-03-04 12:32:41 EST (Fri, 04 Mar 2011)
@@ -0,0 +1,28 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+struct X
+{
+    int x;
+    X(int n) : x(n) { }
+};
+
+int x_function(X& x)
+{   return x.x;
+}
+
+
+BOOST_PYTHON_MODULE(class_ext)
+{
+    class_<X>("X", init<int>());
+    def("x_function", x_function);
+}
+
+#include "module_tail.cpp"
Added: trunk/libs/python/test/class.py
==============================================================================
--- (empty file)
+++ trunk/libs/python/test/class.py	2011-03-04 12:32:41 EST (Fri, 04 Mar 2011)
@@ -0,0 +1,40 @@
+# Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from class_ext import *
+
+Ensure sanity:
+
+    >>> x = X(42)
+    >>> x_function(x)
+    42
+
+Demonstrate extraction in the presence of metaclass changes:
+
+    >>> class MetaX(X.__class__):
+    ...     def __new__(cls, *args):
+    ...         return super(MetaX, cls).__new__(cls, *args)
+    >>> class XPlusMetatype(X):
+    ...     __metaclass__ = MetaX
+    >>> x = XPlusMetatype(42)
+    >>> x_function(x)
+    42
+
+
+'''
+
+def run(args = None):
+    import sys
+    import doctest
+
+    if args is not None:
+        sys.argv = args
+    return doctest.testmod(sys.modules.get(__name__))
+
+if __name__ == '__main__':
+    print "running..."
+    import sys
+    status = run()[0]
+    if (status == 0): print "Done."
+    sys.exit(status)