|
| 1 | +// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and |
| 2 | +// distribute this software is granted provided this copyright notice appears |
| 3 | +// in all copies. This software is provided "as is" without express or implied |
| 4 | +// warranty, and with no claim as to its suitability for any purpose. |
| 5 | +// |
| 6 | +// The author gratefully acknowleges the support of Dragon Systems, Inc., in |
| 7 | +// producing this work. |
| 8 | + |
| 9 | +#include <boost/python/module.hpp> |
| 10 | +#include <boost/python/errors.hpp> |
| 11 | + |
| 12 | +namespace boost { namespace python { |
| 13 | + |
| 14 | +namespace { |
| 15 | + ref name_holder; |
| 16 | +} |
| 17 | + |
| 18 | +bool module_base::initializing() |
| 19 | +{ |
| 20 | + return name_holder.get() != 0; |
| 21 | +} |
| 22 | + |
| 23 | +string module_base::name() |
| 24 | +{ |
| 25 | + // If this fails, you haven't created a module object |
| 26 | + assert(initializing()); |
| 27 | + return string(name_holder); |
| 28 | +} |
| 29 | + |
| 30 | +module_base::module_base(const char* name) |
| 31 | + : m_module(Py_InitModule(const_cast<char*>(name), initial_methods)) |
| 32 | +{ |
| 33 | + // If this fails, you've created more than 1 module object in your module |
| 34 | + assert(name_holder.get() == 0); |
| 35 | + name_holder = ref(PyObject_GetAttrString(m_module, const_cast<char*>("__name__"))); |
| 36 | +} |
| 37 | + |
| 38 | +module_base::~module_base() |
| 39 | +{ |
| 40 | + name_holder.reset(); |
| 41 | +} |
| 42 | + |
| 43 | +void module_base::add(PyObject* x, const char* name) |
| 44 | +{ |
| 45 | + add(ref(x), name); |
| 46 | +} |
| 47 | + |
| 48 | +void module_base::add(ref x, const char* name) |
| 49 | +{ |
| 50 | + ref f(x); // First take possession of the object. |
| 51 | + if (PyObject_SetAttrString(m_module, const_cast<char*>(name), x.get()) < 0) |
| 52 | + throw error_already_set(); |
| 53 | +} |
| 54 | + |
| 55 | +void module_base::add(PyTypeObject* x, const char* name /*= 0*/) |
| 56 | +{ |
| 57 | + this->add((PyObject*)x, name ? name : x->tp_name); |
| 58 | +} |
| 59 | + |
| 60 | +void module_base::add_overload(objects::function* x, const char* name) |
| 61 | +{ |
| 62 | + PyObject* existing = PyObject_HasAttrString(m_module, const_cast<char*>(name)) |
| 63 | + ? PyObject_GetAttrString(m_module, const_cast<char*>(name)) |
| 64 | + : 0; |
| 65 | + |
| 66 | + if (existing != 0 && existing->ob_type == &objects::function_type) |
| 67 | + { |
| 68 | + static_cast<objects::function*>(existing)->add_overload(x); |
| 69 | + } |
| 70 | + else |
| 71 | + { |
| 72 | + add(x, name); |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; |
| 77 | + |
| 78 | +}} // namespace boost::python |
0 commit comments