1 // Copyright David Abrahams 2001.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #include <boost/python/detail/prefix.hpp>
7 #include <boost/mpl/lambda.hpp> // #including this first is an intel6 workaround
9 #include <boost/python/object/class.hpp>
10 #include <boost/python/object/instance.hpp>
11 #include <boost/python/object/class_detail.hpp>
12 #include <boost/python/scope.hpp>
13 #include <boost/python/converter/registry.hpp>
14 #include <boost/python/object/find_instance.hpp>
15 #include <boost/python/object/pickle_support.hpp>
16 #include <boost/python/detail/map_entry.hpp>
17 #include <boost/python/object.hpp>
18 #include <boost/python/object_protocol.hpp>
19 #include <boost/detail/binary_search.hpp>
20 #include <boost/python/self.hpp>
21 #include <boost/python/dict.hpp>
22 #include <boost/python/str.hpp>
23 #include <boost/python/ssize_t.hpp>
28 #include <structmember.h>
30 namespace boost
{ namespace python
{
32 # ifdef BOOST_PYTHON_SELF_IS_CLASS
39 instance_holder::instance_holder()
44 instance_holder::~instance_holder()
50 // This is copied from typeobject.c in the Python sources. Even though
51 // class_metatype_object doesn't set Py_TPFLAGS_HAVE_GC, that bit gets
52 // filled in by the base class initialization process in
53 // PyType_Ready(). However, tp_is_gc is *not* copied from the base
54 // type, making it assume that classes are GC-able even if (like
55 // class_type_object) they're statically allocated.
57 type_is_gc(PyTypeObject
*python_type
)
59 return python_type
->tp_flags
& Py_TPFLAGS_HEAPTYPE
;
62 // This is also copied from the Python sources. We can't implement
63 // static_data as a subclass property effectively without it.
73 // Copied from Python source and removed the part for setting docstring,
74 // since we don't have a setter for __doc__ and trying to set it will
75 // cause the init fail.
76 static int property_init(PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
78 PyObject
*get
= NULL
, *set
= NULL
, *del
= NULL
, *doc
= NULL
;
79 static const char *kwlist
[] = {"fget", "fset", "fdel", "doc", 0};
80 propertyobject
*prop
= (propertyobject
*)self
;
82 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|OOOO:property",
83 const_cast<char **>(kwlist
), &get
, &set
, &del
, &doc
))
100 prop
->prop_del
= del
;
101 prop
->prop_doc
= doc
;
102 prop
->getter_doc
= 0;
109 static_data_descr_get(PyObject
*self
, PyObject
* /*obj*/, PyObject
* /*type*/)
111 propertyobject
*gs
= (propertyobject
*)self
;
113 return PyObject_CallFunction(gs
->prop_get
, const_cast<char*>("()"));
117 static_data_descr_set(PyObject
*self
, PyObject
* /*obj*/, PyObject
*value
)
119 propertyobject
*gs
= (propertyobject
*)self
;
120 PyObject
*func
, *res
;
127 PyErr_SetString(PyExc_AttributeError
,
129 "can't delete attribute" :
130 "can't set attribute");
134 res
= PyObject_CallFunction(func
, const_cast<char*>("()"));
136 res
= PyObject_CallFunction(func
, const_cast<char*>("(O)"), value
);
144 static PyTypeObject static_data_object
= {
145 PyVarObject_HEAD_INIT(NULL
, 0)
146 const_cast<char*>("Boost.Python.StaticProperty"),
147 sizeof(propertyobject
),
155 0, /* tp_as_number */
156 0, /* tp_as_sequence */
157 0, /* tp_as_mapping */
163 0, /* tp_as_buffer */
164 Py_TPFLAGS_DEFAULT
// | Py_TPFLAGS_HAVE_GC
165 | Py_TPFLAGS_BASETYPE
, /* tp_flags */
169 0, /* tp_richcompare */
170 0, /* tp_weaklistoffset */
176 0, //&PyProperty_Type, /* tp_base */
178 static_data_descr_get
, /* tp_descr_get */
179 static_data_descr_set
, /* tp_descr_set */
180 0, /* tp_dictoffset */
181 property_init
, /* tp_init */
183 0, // filled in with type_new /* tp_new */
184 0, // filled in with __PyObject_GC_Del /* tp_free */
189 0, /* tp_subclasses */
191 #if PYTHON_API_VERSION >= 1012
198 #if PY_VERSION_HEX < 0x03000000
199 // XXX Not sure why this run into compiling error in Python 3
202 // This declaration needed due to broken Python 2.2 headers
203 extern DL_IMPORT(PyTypeObject
) PyProperty_Type
;
207 BOOST_PYTHON_DECL PyObject
* static_data()
209 if (static_data_object
.tp_dict
== 0)
211 Py_TYPE(&static_data_object
) = &PyType_Type
;
212 static_data_object
.tp_base
= &PyProperty_Type
;
213 if (PyType_Ready(&static_data_object
))
216 return upcast
<PyObject
>(&static_data_object
);
222 // Ordinarily, descriptors have a certain assymetry: you can use
223 // them to read attributes off the class object they adorn, but
224 // writing the same attribute on the class object always replaces
225 // the descriptor in the class __dict__. In order to properly
226 // represent C++ static data members, we need to allow them to be
227 // written through the class instance. This function of the
228 // metaclass makes it possible.
230 class_setattro(PyObject
*obj
, PyObject
*name
, PyObject
* value
)
232 // Must use "private" Python implementation detail
233 // _PyType_Lookup instead of PyObject_GetAttr because the
234 // latter will always end up calling the descr_get function on
235 // any descriptor it finds; we need the unadulterated
237 PyObject
* a
= _PyType_Lookup(downcast
<PyTypeObject
>(obj
), name
);
239 // a is a borrowed reference or 0
241 // If we found a static data descriptor, call it directly to
242 // force it to set the static data member
243 if (a
!= 0 && PyObject_IsInstance(a
, objects::static_data()))
244 return Py_TYPE(a
)->tp_descr_set(a
, obj
, value
);
246 return PyType_Type
.tp_setattro(obj
, name
, value
);
250 static PyTypeObject class_metatype_object
= {
251 PyVarObject_HEAD_INIT(NULL
, 0)
252 const_cast<char*>("Boost.Python.class"),
253 PyType_Type
.tp_basicsize
,
261 0, /* tp_as_number */
262 0, /* tp_as_sequence */
263 0, /* tp_as_mapping */
268 class_setattro
, /* tp_setattro */
269 0, /* tp_as_buffer */
270 Py_TPFLAGS_DEFAULT
// | Py_TPFLAGS_HAVE_GC
271 | Py_TPFLAGS_BASETYPE
, /* tp_flags */
275 0, /* tp_richcompare */
276 0, /* tp_weaklistoffset */
282 0, //&PyType_Type, /* tp_base */
284 0, /* tp_descr_get */
285 0, /* tp_descr_set */
286 0, /* tp_dictoffset */
289 0, // filled in with type_new /* tp_new */
290 0, // filled in with __PyObject_GC_Del /* tp_free */
291 (inquiry
)type_is_gc
, /* tp_is_gc */
295 0, /* tp_subclasses */
297 #if PYTHON_API_VERSION >= 1012
302 // Install the instance data for a C++ object into a Python instance
304 void instance_holder::install(PyObject
* self
) throw()
306 assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self
)), &class_metatype_object
));
307 m_next
= ((objects::instance
<>*)self
)->objects
;
308 ((objects::instance
<>*)self
)->objects
= this;
314 // Get the metatype object for all extension classes.
315 BOOST_PYTHON_DECL type_handle
class_metatype()
317 if (class_metatype_object
.tp_dict
== 0)
319 Py_TYPE(&class_metatype_object
) = &PyType_Type
;
320 class_metatype_object
.tp_base
= &PyType_Type
;
321 if (PyType_Ready(&class_metatype_object
))
322 return type_handle();
324 return type_handle(borrowed(&class_metatype_object
));
328 static void instance_dealloc(PyObject
* inst
)
330 instance
<>* kill_me
= (instance
<>*)inst
;
332 for (instance_holder
* p
= kill_me
->objects
, *next
; p
!= 0; p
= next
)
335 p
->~instance_holder();
336 instance_holder::deallocate(inst
, dynamic_cast<void*>(p
));
339 // Python 2.2.1 won't add weak references automatically when
340 // tp_itemsize > 0, so we need to manage that
341 // ourselves. Accordingly, we also have to clean up the
342 // weakrefs ourselves.
343 if (kill_me
->weakrefs
!= NULL
)
344 PyObject_ClearWeakRefs(inst
);
346 Py_XDECREF(kill_me
->dict
);
348 Py_TYPE(inst
)->tp_free(inst
);
352 instance_new(PyTypeObject
* type_
, PyObject
* /*args*/, PyObject
* /*kw*/)
354 // Attempt to find the __instance_size__ attribute. If not present, no problem.
355 PyObject
* d
= type_
->tp_dict
;
356 PyObject
* instance_size_obj
= PyObject_GetAttrString(d
, const_cast<char*>("__instance_size__"));
358 ssize_t instance_size
= instance_size_obj
?
359 #if PY_VERSION_HEX >= 0x03000000
360 PyLong_AsSsize_t(instance_size_obj
) : 0;
362 PyInt_AsLong(instance_size_obj
) : 0;
365 if (instance_size
< 0)
368 PyErr_Clear(); // Clear any errors that may have occurred.
370 instance
<>* result
= (instance
<>*)type_
->tp_alloc(type_
, instance_size
);
373 // Guido says we can use ob_size for any purpose we
374 // like, so we'll store the total size of the object
375 // there. A negative number indicates that the extra
376 // instance memory is not yet allocated to any holders.
377 #if PY_VERSION_HEX >= 0x02060000
382 -(static_cast<int>(offsetof(instance
<>,storage
) + instance_size
));
384 return (PyObject
*)result
;
387 static PyObject
* instance_get_dict(PyObject
* op
, void*)
389 instance
<>* inst
= downcast
<instance
<> >(op
);
391 inst
->dict
= PyDict_New();
392 return python::xincref(inst
->dict
);
395 static int instance_set_dict(PyObject
* op
, PyObject
* dict
, void*)
397 instance
<>* inst
= downcast
<instance
<> >(op
);
398 python::xdecref(inst
->dict
);
399 inst
->dict
= python::incref(dict
);
406 static PyGetSetDef instance_getsets
[] = {
407 {const_cast<char*>("__dict__"), instance_get_dict
, instance_set_dict
, NULL
, 0},
412 static PyMemberDef instance_members
[] = {
413 {const_cast<char*>("__weakref__"), T_OBJECT
, offsetof(instance
<>, weakrefs
), 0, 0},
417 static PyTypeObject class_type_object
= {
418 PyVarObject_HEAD_INIT(NULL
, 0)
419 const_cast<char*>("Boost.Python.instance"),
420 offsetof(instance
<>,storage
), /* tp_basicsize */
422 instance_dealloc
, /* tp_dealloc */
428 0, /* tp_as_number */
429 0, /* tp_as_sequence */
430 0, /* tp_as_mapping */
436 0, /* tp_as_buffer */
437 Py_TPFLAGS_DEFAULT
// | Py_TPFLAGS_HAVE_GC
438 | Py_TPFLAGS_BASETYPE
, /* tp_flags */
442 0, /* tp_richcompare */
443 offsetof(instance
<>,weakrefs
), /* tp_weaklistoffset */
447 instance_members
, /* tp_members */
448 instance_getsets
, /* tp_getset */
449 0, //&PyBaseObject_Type, /* tp_base */
451 0, /* tp_descr_get */
452 0, /* tp_descr_set */
453 offsetof(instance
<>,dict
), /* tp_dictoffset */
455 PyType_GenericAlloc
, /* tp_alloc */
456 instance_new
, /* tp_new */
462 0, /* tp_subclasses */
464 #if PYTHON_API_VERSION >= 1012
469 BOOST_PYTHON_DECL type_handle
class_type()
471 if (class_type_object
.tp_dict
== 0)
473 Py_TYPE(&class_type_object
) = incref(class_metatype().get());
474 class_type_object
.tp_base
= &PyBaseObject_Type
;
475 if (PyType_Ready(&class_type_object
))
476 return type_handle();
477 // class_type_object.tp_setattro = class_setattro;
479 return type_handle(borrowed(&class_type_object
));
482 BOOST_PYTHON_DECL
void*
483 find_instance_impl(PyObject
* inst
, type_info type
, bool null_shared_ptr_only
)
485 if (!Py_TYPE(Py_TYPE(inst
)) ||
486 !PyType_IsSubtype(Py_TYPE(Py_TYPE(inst
)), &class_metatype_object
))
489 instance
<>* self
= reinterpret_cast<instance
<>*>(inst
);
491 for (instance_holder
* match
= self
->objects
; match
!= 0; match
= match
->next())
493 void* const found
= match
->holds(type
, null_shared_ptr_only
);
500 object
module_prefix()
503 PyObject_IsInstance(scope().ptr(), upcast
<PyObject
>(&PyModule_Type
))
504 ? object(scope().attr("__name__"))
505 : api::getattr(scope(), "__module__", str())
511 // Find a registered class object corresponding to id. Return a
512 // null handle if no such class is registered.
513 inline type_handle
query_class(type_info id
)
515 converter::registration
const* p
= converter::registry::query(id
);
518 python::allow_null(p
? p
->m_class_object
: 0))
522 // Find a registered class corresponding to id. If not found,
523 // throw an appropriate exception.
524 type_handle
get_class(type_info id
)
526 type_handle
result(query_class(id
));
528 if (result
.get() == 0)
530 object
report("extension class wrapper for base class ");
531 report
= report
+ id
.name() + " has not been created yet";
532 PyErr_SetObject(PyExc_RuntimeError
, report
.ptr());
533 throw_error_already_set();
538 // class_base constructor
540 // name - the name of the new Python class
542 // num_types - one more than the number of declared bases
544 // types - array of python::type_info, the first item
545 // corresponding to the class being created, and the
546 // rest corresponding to its declared bases.
549 new_class(char const* name
, std::size_t num_types
, type_info
const* const types
, char const* doc
)
551 assert(num_types
>= 1);
553 // Build a tuple of the base Python type objects. If no bases
554 // were declared, we'll use our class_type() as the single base
556 ssize_t
const num_bases
= (std::max
)(num_types
- 1, static_cast<std::size_t>(1));
557 handle
<> bases(PyTuple_New(num_bases
));
559 for (ssize_t i
= 1; i
<= num_bases
; ++i
)
561 type_handle c
= (i
>= static_cast<ssize_t
>(num_types
)) ? class_type() : get_class(types
[i
]);
562 // PyTuple_SET_ITEM steals this reference
563 PyTuple_SET_ITEM(bases
.get(), static_cast<ssize_t
>(i
- 1), upcast
<PyObject
>(c
.release()));
566 // Call the class metatype to create a new class
569 object m
= module_prefix();
570 if (m
) d
["__module__"] = m
;
575 object result
= object(class_metatype())(name
, bases
, d
);
576 assert(PyType_IsSubtype(Py_TYPE(result
.ptr()), &PyType_Type
));
578 if (scope().ptr() != Py_None
)
579 scope().attr(name
) = result
;
581 // For pickle. Will lead to informative error messages if pickling
583 result
.attr("__reduce__") = object(make_instance_reduce_function());
589 class_base::class_base(
590 char const* name
, std::size_t num_types
, type_info
const* const types
, char const* doc
)
591 : object(new_class(name
, num_types
, types
, doc
))
593 // Insert the new class object in the registry
594 converter::registration
& converters
= const_cast<converter::registration
&>(
595 converter::registry::lookup(types
[0]));
597 // Class object is leaked, for now
598 converters
.m_class_object
= (PyTypeObject
*)incref(this->ptr());
601 BOOST_PYTHON_DECL
void copy_class_object(type_info
const& src
, type_info
const& dst
)
603 converter::registration
& dst_converters
604 = const_cast<converter::registration
&>(converter::registry::lookup(dst
));
606 converter::registration
const& src_converters
= converter::registry::lookup(src
);
608 dst_converters
.m_class_object
= src_converters
.m_class_object
;
611 void class_base::set_instance_size(std::size_t instance_size
)
613 this->attr("__instance_size__") = instance_size
;
616 void class_base::add_property(
617 char const* name
, object
const& fget
, char const* docstr
)
620 (python::detail::new_reference
)
621 PyObject_CallFunction((PyObject
*)&PyProperty_Type
, const_cast<char*>("Osss"), fget
.ptr(), 0, 0, docstr
));
623 this->setattr(name
, property
);
626 void class_base::add_property(
627 char const* name
, object
const& fget
, object
const& fset
, char const* docstr
)
630 (python::detail::new_reference
)
631 PyObject_CallFunction((PyObject
*)&PyProperty_Type
, const_cast<char*>("OOss"), fget
.ptr(), fset
.ptr(), 0, docstr
));
633 this->setattr(name
, property
);
636 void class_base::add_static_property(char const* name
, object
const& fget
)
639 (python::detail::new_reference
)
640 PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget
.ptr())
643 this->setattr(name
, property
);
646 void class_base::add_static_property(char const* name
, object
const& fget
, object
const& fset
)
649 (python::detail::new_reference
)
650 PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget
.ptr(), fset
.ptr()));
652 this->setattr(name
, property
);
655 void class_base::setattr(char const* name
, object
const& x
)
657 if (PyObject_SetAttrString(this->ptr(), const_cast<char*>(name
), x
.ptr()) < 0)
658 throw_error_already_set();
663 extern "C" PyObject
* no_init(PyObject
*, PyObject
*)
665 ::PyErr_SetString(::PyExc_RuntimeError
, const_cast<char*>("This class cannot be instantiated from Python"));
668 static ::PyMethodDef no_init_def
= {
669 const_cast<char*>("__init__"), no_init
, METH_VARARGS
,
670 const_cast<char*>("Raises an exception\n"
671 "This class cannot be instantiated from Python\n")
675 void class_base::def_no_init()
677 handle
<> f(::PyCFunction_New(&no_init_def
, 0));
678 this->setattr("__init__", object(f
));
681 void class_base::enable_pickling_(bool getstate_manages_dict
)
683 setattr("__safe_for_unpickling__", object(true));
685 if (getstate_manages_dict
)
687 setattr("__getstate_manages_dict__", object(true));
693 PyObject
* callable_check(PyObject
* callable
)
695 if (PyCallable_Check(expect_non_null(callable
)))
700 , const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
701 , Py_TYPE(callable
)->tp_name
704 throw_error_already_set();
709 void class_base::make_method_static(const char * method_name
)
711 PyTypeObject
* self
= downcast
<PyTypeObject
>(this->ptr());
712 dict
d((handle
<>(borrowed(self
->tp_dict
))));
714 object
method(d
[method_name
]);
716 this->attr(method_name
) = object(
718 PyStaticMethod_New((callable_check
)(method
.ptr()) )
722 BOOST_PYTHON_DECL type_handle
registered_class_object(type_info id
)
724 return query_class(id
);
726 } // namespace objects
729 void* instance_holder::allocate(PyObject
* self_
, std::size_t holder_offset
, std::size_t holder_size
)
731 assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_
)), &class_metatype_object
));
732 objects::instance
<>* self
= (objects::instance
<>*)self_
;
734 int total_size_needed
= holder_offset
+ holder_size
;
736 if (-Py_SIZE(self
) >= total_size_needed
)
738 // holder_offset should at least point into the variable-sized part
739 assert(holder_offset
>= offsetof(objects::instance
<>,storage
));
741 // Record the fact that the storage is occupied, noting where it starts
742 Py_SIZE(self
) = holder_offset
;
743 return (char*)self
+ holder_offset
;
747 void* const result
= PyMem_Malloc(holder_size
);
749 throw std::bad_alloc();
754 void instance_holder::deallocate(PyObject
* self_
, void* storage
) throw()
756 assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_
)), &class_metatype_object
));
757 objects::instance
<>* self
= (objects::instance
<>*)self_
;
758 if (storage
!= (char*)self
+ Py_SIZE(self
))
764 }} // namespace boost::python