From f9a67b34b2ca4dc2fad96f8207dee8091a6956d6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 18:36:14 +0000 Subject: [PATCH] Roll back most of Dave Hawkes' changes for the time being. [SVN r14501] --- include/boost/python/class.hpp | 38 +----- include/boost/python/detail/module_base.hpp | 16 --- include/boost/python/detail/module_init.hpp | 18 +-- include/boost/python/module.hpp | 27 +--- include/boost/python/object/class.hpp | 5 - src/module.cpp | 137 +------------------- src/object/class.cpp | 117 +---------------- test/Jamfile | 2 +- 8 files changed, 19 insertions(+), 341 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index d2a4a2f0..861d8e72 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -14,7 +14,6 @@ # include # include # include -# include # include # include # include @@ -87,12 +86,12 @@ class class_ : public objects::class_base public: // Automatically derive the class name - only works on some // compilers because type_info::name is sometimes mangled (gcc) - class_(base const& parent_class = empty_class_base()); + class_(); // Construct with the class name. [ Would have used a default // argument but gcc-2.95.2 choked on typeid(T).name() as a default // parameter value] - class_(char const* name, base const& parent_class = empty_class_base()); + class_(char const* name); // Wrap a member function or a non-member function which can take @@ -196,22 +195,6 @@ class class_ : public objects::class_base self& setattr(char const* name, handle<> const&); - // add to module - self& add(module &m) - { - // redundant - // m.add(*this); - return *this; - } - - // add to current module - self& add() - { - // redundant - // boost::python::add(*this); - return *this; - } - private: // types typedef objects::class_id class_id; @@ -248,7 +231,7 @@ class class_ : public objects::class_base // implementations // template -inline class_::class_(base const& parent_class) +inline class_::class_() : base(typeid(T).name(), id_vector::size, id_vector().ids) { // register converters @@ -258,16 +241,10 @@ inline class_::class_(base const& parent_class) mpl::bool_t() , objects::select_holder((held_type*)0).get() , this->object()); - - // get the context to add the class to - handle<> parent(parent_class.object() ? handle<>(parent_class.object()) : - base::get_class_context_object(typeid(T).name(), object())); - // add the class to the current module - boost::python::detail::module_base::add(object(), parent); } template -inline class_::class_(char const* name, base const& parent_class) +inline class_::class_(char const* name) : base(name, id_vector::size, id_vector().ids) { // register converters @@ -277,14 +254,9 @@ inline class_::class_(char const* name, base const& parent_class) mpl::bool_t() , objects::select_holder((held_type*)0).get() , this->object()); - - // get the context to add the class to - handle<> parent(parent_class.object() ? handle<>(parent_class.object()) : - base::get_class_context_object(name, object())); - // add the class to the current module - boost::python::detail::module_base::add(object(), parent); } + template inline class_& class_::add_property(char const* name, handle<> const& fget) { diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index 71044c96..aaa6a135 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -10,8 +10,6 @@ namespace boost { namespace python { namespace detail { -class module_info; - class BOOST_PYTHON_DECL module_base { public: @@ -23,22 +21,14 @@ class BOOST_PYTHON_DECL module_base void setattr(const char* name, PyObject*); void setattr(const char* name, handle<> const&); void add(type_handle const&); // just use the type's name - static module_info* get_module_info(); - static void set_module_info(module_info& mi); - static handle<> get_prior_module(); - static void set_prior_module(handle<> const& m); - static void add(type_handle const& class_obj, handle<> const& context); // Return a reference to the Python module object being built inline handle<> object() const; protected: - module_base(handle<> const &m) : m_module(m) {} void add_class(type_handle const& class_obj); - void add_class(type_handle const& class_obj, handle<> const& context); private: - static module_info*& get_module_info_ref(); handle<> m_module; static PyMethodDef initial_methods[1]; }; @@ -51,12 +41,6 @@ inline handle<> module_base::object() const return m_module; } -inline void module_base::add(type_handle const& class_obj, handle<> const& context) -{ - module_base mb(get_prior_module()); - mb.add_class(class_obj, context); -} - }}} // namespace boost::python::detail #endif // MODULE_BASE_DWA2002227_HPP diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp index 79a55119..5b5ce9f5 100644 --- a/include/boost/python/detail/module_init.hpp +++ b/include/boost/python/detail/module_init.hpp @@ -8,23 +8,13 @@ # ifndef BOOST_PYTHON_MODULE_INIT -# define PRE_INIT_FUNC(name) \ -void init_module_base_##name() \ -{ \ - boost::python::detail::module_info mi(#name); \ - boost::python::detail::module_base::set_module_info(mi); \ - boost::python::module(); \ - init_module_##name(); \ -} - # if defined(_WIN32) || defined(__CYGWIN__) # define BOOST_PYTHON_MODULE_INIT(name) \ void init_module_##name(); \ -PRE_INIT_FUNC(name) \ extern "C" __declspec(dllexport) void init##name() \ { \ - boost::python::handle_exception(&init_module_base_##name); \ + boost::python::handle_exception(&init_module_##name); \ } \ void init_module_##name() @@ -32,14 +22,13 @@ void init_module_##name() # include # define BOOST_PYTHON_MODULE_INIT(name) \ -PRE_INIT_FUNC(name) \ void init_module_##name(); \ extern "C" \ { \ extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ void init##name() \ { \ - boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_base_##name); \ + boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ } \ } \ void init_module_##name() @@ -47,11 +36,10 @@ void init_module_##name() # else # define BOOST_PYTHON_MODULE_INIT(name) \ -PRE_INIT_FUNC(name) \ void init_module_##name(); \ extern "C" void init##name() \ { \ - boost::python::handle_exception(&init_module_base_##name); \ + boost::python::handle_exception(&init_module_##name); \ } \ void init_module_##name() diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index d32e0935..8ee63485 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -13,7 +13,6 @@ # include # include # include -# include namespace boost { namespace python { @@ -22,7 +21,7 @@ class module : public detail::module_base public: typedef detail::module_base base; - module(const char* name = "") + module(const char* name) : base(name) {} // Add elements to the module @@ -34,8 +33,7 @@ class module : public detail::module_base template module& add(class_ const& c) { - // redundant - // this->add_class(c.object()); + this->add_class(c.object()); return *this; } @@ -53,14 +51,6 @@ class module : public detail::module_base this->setattr(name, boost::python::make_function(fn, handler)); return *this; } - - static module get_prior_module() - { - return module(module_base::get_prior_module()); - } - - private: - module(handle<> const& m) : base(m) {} }; // @@ -90,19 +80,6 @@ inline module& module::add(PyTypeObject* x) return *this; } -template -inline void def(char const* name, Fn fn) -{ - module::get_prior_module().def(name, fn); -} - - -template -inline void def(char const* name, Fn fn, ResultHandler handler) -{ - module::get_prior_module().def(name, fn, handler); -} - }} // namespace boost::python #endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 8e4cf586..8cf29b23 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,12 +39,7 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable void add_property(char const* name, handle<> const& fget); void add_property(char const* name, handle<> const& fget, handle<> const& fset); void setattr(char const* name, handle<> const&); - static handle<> get_class_context_object(const char* name, type_handle const& class_obj); - protected: - static class_base const& empty_class_base(); private: - // construct an empty base class - class_base(); type_handle m_object; }; diff --git a/src/module.cpp b/src/module.cpp index 9fe86adf..f7edf39e 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -7,107 +7,16 @@ // producing this work. #include -#include -#include #include -#include #include namespace boost { namespace python { namespace detail { -namespace { - -object getattr_or_none(object const &obj, const char *name) -{ - if(PyObject_HasAttrString(obj.ptr(), const_cast(name))) - return obj.attr(name); - else - return object(); -} - -// Initialise a new sub-module, or return an existing one. -// This will also create any missing parents along the way. -handle<> init_sub_module(const char* name, PyMethodDef *initial_methods, module_info* pmi) -{ - if(name == NULL) - // just create a dummy module with an empty reference - return handle<>(); - // initialise various iterators, etc. - object parent_module(pmi->get_module()), current_module(parent_module); - std::string s_name(name), b_name; - if(s_name.size() == 0) - // use the default module name if it is not supplied - s_name = pmi->get_module_name(); - std::string::size_type p_pos(0); - for(int l = 0;;++l) { - // find the next module name in the 'dotted' name - std::string::size_type dot_pos = s_name.find('.', p_pos); - // p_pos is the absolute position, but the length is needed - if(dot_pos != std::string::npos) - dot_pos -= p_pos; - // the current module name being processed, iterating from the parent - // to the right hand sub-modules - b_name = s_name.substr(p_pos, dot_pos); - if(l == 0) { - // process the top level parent module name - if(dot_pos == 0) - // allow a shortcut module notation so we can do module(".submodule") - b_name = pmi->get_module_name(); - // check the base name is the correct parent name else assert - assert(b_name.compare(pmi->get_module_name()) == 0); - if(!parent_module) { - // The main parent module does not exist yet, so create it here - parent_module = object(python::borrowed(Py_InitModule( - const_cast(b_name.c_str()), - initial_methods))); - // and set up the module iterator - current_module = parent_module; - // initialise the global parent module so it can be found later - pmi->set_module(parent_module); - } - } else { - // now processing a sub-module - // try to find and verify an existing sub-module of the correct name and type - object existing_sub_module(getattr_or_none(current_module, b_name.c_str())); - if(existing_sub_module) { - // An attribute of the same name has been found - object module_type((python::detail::new_reference)PyObject_Type(parent_module.ptr())); - // test its type against the parent - if(!PyObject_IsSubclass(existing_sub_module.ptr(), module_type.ptr())) - // not actually a module, so it can't be used - existing_sub_module = object(); - } - // was an existing sub-module found ? - if(!existing_sub_module) { - // no, then it is created here - // build up the full path name up to and including the current sub-module - std::string full_name(s_name.substr(0, dot_pos)); - // create the module - existing_sub_module = object(python::borrowed(Py_InitModule( - const_cast(full_name.c_str()), - initial_methods))); - // add the sub-module to the attributes of its immediate parent - current_module.attr(b_name.c_str()) = existing_sub_module; - } - // we now have a new current module to iterate - current_module = existing_sub_module; - } - // no more modules ? - if(dot_pos == std::string::npos) - break; - // advance over the dot - p_pos += dot_pos + 1; - } - // return the actual sub-module that was either found or created - return handle<>(python::borrowed(current_module.ptr())); -} - -} - module_base::module_base(const char* name) - : m_module(init_sub_module(name, initial_methods, get_module_info())) + : m_module( + python::borrowed(Py_InitModule(const_cast(name), initial_methods)) + ) { - set_prior_module(m_module); } module_base::~module_base() @@ -133,16 +42,7 @@ void module_base::add(type_handle const& x) void module_base::add_class(type_handle const& class_obj) { - add_class(class_obj, objects::class_base:: - get_class_context_object(class_obj.get()->tp_name, class_obj)); -} - -void module_base::add_class(type_handle const& class_obj, handle<> const& context) -{ - if(context.get()) { - objects::function:: - add_to_namespace(context, ((PyTypeObject*)class_obj.get())->tp_name, class_obj); - } + this->add(class_obj); handle<> module_name( PyObject_GetAttrString( @@ -150,38 +50,13 @@ void module_base::add_class(type_handle const& class_obj, handle<> const& contex ); int status = PyObject_SetAttrString( - handle<>(class_obj).get(), const_cast("__module__"), module_name.get()); + python::upcast(class_obj.get()) + , const_cast("__module__"), module_name.get()); if (status == -1) throw_error_already_set(); } -void module_base::set_module_info(module_info & mi) -{ - get_module_info_ref() = &mi; -} - -module_info* module_base::get_module_info() -{ - return get_module_info_ref(); -} - -module_info*& module_base::get_module_info_ref() -{ - static module_info* pmi = NULL; - return pmi; -} - -void module_base::set_prior_module(handle<> const& m) -{ - get_module_info()->set_prior_module(python::object(m)); -} - -handle<> module_base::get_prior_module() -{ - return handle<>(python::borrowed(get_module_info()->get_prior_module().ptr())); -} - PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; }}} // namespace boost::python::detail diff --git a/src/object/class.cpp b/src/object/class.cpp index f2c602f6..e49df96f 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,13 +3,10 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include #include #include #include #include -#include -#include #include #include #include @@ -249,12 +246,6 @@ namespace objects char const* name, std::size_t num_types, class_id const* const types) { assert(num_types >= 1); - - // is this class already registered? - m_object = query_class(types[0]); - if(m_object.get()) { - return; - } // Build a tuple of the base Python type objects. If no bases // were declared, we'll use our class_type() as the single base @@ -269,15 +260,9 @@ namespace objects PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } - // we now need just the base name - std::string base_name(name); - std::string::size_type dot_pos = base_name.rfind('.'); - if(dot_pos != std::string::npos) - base_name = base_name.substr(dot_pos + 1); - // Build the (name, bases, dict) tuple for creating the new class handle<> args(PyTuple_New(3)); - PyTuple_SET_ITEM(args.get(), 0, incref(python::object(base_name.c_str()).ptr())); + PyTuple_SET_ITEM(args.get(), 0, incref(python::object(name).ptr())); PyTuple_SET_ITEM(args.get(), 1, bases.release()); handle<> d(PyDict_New()); PyTuple_SET_ITEM(args.get(), 2, d.release()); @@ -319,107 +304,9 @@ namespace objects throw_error_already_set(); } - namespace { - class empty_class {}; - - void transfer_attributes(object const& src, object const& dst) - { - object attrs((python::detail::new_reference)PyObject_Dir(src.ptr())); - if(PyList_Check(attrs.ptr())) { - int sz = PyList_Size(attrs.ptr()); - for(int i = 0; i < sz; i++) { - PyObject *attr_name = PyList_GET_ITEM(attrs.ptr(), i); - object attr((python::detail::new_reference)PyObject_GetAttr(src.ptr(), attr_name)); - // only transfer boost classes - if(attr.ptr()->ob_type == &class_metatype_object) - PyObject_SetAttr(dst.ptr(), attr_name, attr.ptr()); - } - } - } - - - object getattr_or_none(object const &obj, const char *name) - { - if(PyObject_HasAttrString(obj.ptr(), const_cast(name))) - return obj.attr(name); - else - return object(); - } - - } - - // get a class context for nested classes - handle<> class_base::get_class_context_object(const char* name, type_handle const& class_obj) - { - // initialise various iterators, etc. - std::string s_name(name), b_name; - std::string::size_type p_pos(0); - python::object current_object(python::detail::module_base::get_prior_module()); - for(;;) { - // find the next class name in the 'dotted' name - std::string::size_type dot_pos = s_name.find('.', p_pos); - // have we completed up to the current class ? - // p_pos is the absolute position, but the length is needed - if(dot_pos != std::string::npos) - dot_pos -= p_pos; - // the current class name being processed, iterating from left to right - b_name = s_name.substr(p_pos, dot_pos); - if(dot_pos == std::string::npos) { - // this is the last class in the chain, is it here already - python::object existing_object(getattr_or_none(current_object, b_name.c_str())); - if(existing_object) { - // yes - if(PyObject_TypeCheck(existing_object.ptr(), &PyType_Type)) { - PyTypeObject *pType = (PyTypeObject *) existing_object.ptr(); - // is it one of ours? - if(pType->ob_type == &class_metatype_object) { - // then lets see if its our empty_class - type_handle r = query_class(python::type_id()); - // is it registered as the empty_class? - if(r.get() == pType) { - // yes, then we can transfer attributes - transfer_attributes(python::object(handle<>(r)), python::object(handle<>(class_obj))); - } else { - // the user must have created it already. - // so we don't need to add it - return handle<>(); - } - } - } - } - break; - } - // try to find an existing parent of the nested class - current_object = getattr_or_none(current_object, b_name.c_str()); - if(!current_object) { - // If we can't find it then insert a temporary class as a marker - std::string full_name(s_name.substr(0, dot_pos)); - current_object = python::object(handle<>(boost::python::class_(full_name.c_str()).object())); - } - // we now have a new current object to iterate - // note that we could attach the nested class to something other - // than a parent class here as we are not testing the type, - // does this really matter? - // advance over the dot - p_pos += dot_pos + 1; - } - // return the actual sub-module that was either found or created - return handle<>(python::borrowed(current_object.ptr())); - } - - class_base::class_base() - { - } - - class_base const& class_base::empty_class_base() - { - static class_base ecb; - return ecb; - } - BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { - return query_class(id); + return objects::query_class(id); } } // namespace objects diff --git a/test/Jamfile b/test/Jamfile index 0bde874d..db78d895 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -93,7 +93,7 @@ run bases.cpp ; run if_else.cpp ; run pointee.cpp ; run result.cpp ; -run submod_subclass_api.cpp ../bpl : : : $(PYTHON_PROPERTIES) ; + compile string_literal.cpp ; compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ;