From 6e06ff048d2b8d6fff93194a81ed94d0d6bc947a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Aug 2002 06:26:33 +0000 Subject: [PATCH] Automatic class def_init(), abstract class __init__ errors Fixed line endings Suppressed warnings [SVN r14828] --- include/boost/python/args.hpp | 16 +- include/boost/python/class.hpp | 145 +++++--- include/boost/python/detail/defaults_def.hpp | 172 ++++++++++ include/boost/python/detail/defaults_gen.hpp | 320 ++++++++++++++++++ .../python/detail/translate_exception.hpp | 3 +- include/boost/python/object/class.hpp | 1 + include/boost/python/object/iterator.hpp | 2 +- include/boost/python/signature.hpp | 266 +++++++++++++++ src/object/class.cpp | 20 ++ src/object/function.cpp | 5 +- test/back_reference.cpp | 6 +- test/bienstman1.cpp | 2 +- test/bienstman3.cpp | 5 +- test/bienstman3.py | 10 + test/bienstman4.cpp | 7 +- test/callbacks.cpp | 3 +- test/data_members.cpp | 6 +- test/defaults.py | 90 +++++ test/docstring.cpp | 8 +- test/extract.cpp | 15 +- test/implicit.cpp | 3 +- test/iterator.cpp | 3 - test/list.cpp | 3 +- test/m1.cpp | 8 +- test/multi_arg_constructor.cpp | 9 +- test/operators.cpp | 6 +- test/pickle1.cpp | 4 +- test/pickle2.cpp | 4 +- test/pickle3.cpp | 4 +- test/test_pointer_adoption.cpp | 5 +- test/virtual_functions.cpp | 9 +- 31 files changed, 1045 insertions(+), 115 deletions(-) create mode 100644 include/boost/python/detail/defaults_def.hpp create mode 100644 include/boost/python/detail/defaults_gen.hpp create mode 100644 include/boost/python/signature.hpp create mode 100644 test/defaults.py diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index d3b7c5d9..841d70d2 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -16,13 +16,25 @@ # include # include +namespace boost { namespace python { + +enum no_init_t { no_init }; + +namespace detail +{ + template + struct args_base {}; +} +}} + # if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 namespace boost { namespace python { // A type list for specifying arguments template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > -struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type +struct args : detail::args_base > + , boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type {}; }} // namespace boost::python @@ -36,7 +48,7 @@ struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_AR namespace boost { namespace python { template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > -struct args +struct args : detail::args_base > {}; }} // namespace boost::python diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 4af8d3e7..f56bc7b1 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -28,6 +28,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -58,7 +59,9 @@ namespace detail template static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const&, T* = 0) { - } + } + + template int assert_default_constructible(T const&); } // @@ -75,7 +78,8 @@ template < > class class_ : public objects::class_base { - typedef objects::class_base base; + private: // types + typedef objects::class_base base; typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); @@ -86,17 +90,67 @@ class class_ : public objects::class_base X3 >::type>::type>::type held_type; + typedef objects::class_id class_id; + + typedef typename detail::select_bases::type + >::type + >::type bases; + + // A helper class which will contain an array of id objects to be + // passed to the base class constructor + struct id_vector + { + typedef objects::class_id class_id; + id_vector() + { + // Stick the derived class id into the first element of the array + ids[0] = type_id(); + + // Write the rest of the elements into succeeding positions. + class_id* p = ids + 1; + mpl::for_each::execute(&p); + } + + BOOST_STATIC_CONSTANT( + std::size_t, size = mpl::size::value + 1); + class_id ids[size]; + }; + friend struct id_vector; + public: // Automatically derive the class name - only works on some // compilers because type_info::name is sometimes mangled (gcc) - class_(); + class_(); // With default-constructor init function + class_(no_init_t); // With no init function - // 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] + // Construct with the class name, with or without docstring, and default init() function class_(char const* name, char const* doc = 0); + // Construct with class name, no docstring, and no init() function + class_(char const* name, no_init_t); + + // Construct with class name, docstring, and no init() function + class_(char const* name, char const* doc, no_init_t); + template + inline class_(char const* name, detail::args_base const&) + : base(name, id_vector::size, id_vector().ids) + { + this->register_(); + this->def_init(InitArgs()); + } + + + template + inline class_(char const* name, char const* doc, detail::args_base const&, char const* initdoc = 0) + : base(name, id_vector::size, id_vector().ids, doc) + { + this->register_(); + this->def_init(InitArgs(), initdoc); + } + // Wrap a member function or a non-member function which can take // a T, T cv&, or T cv* as its first parameter, or a callable // python object. @@ -224,46 +278,17 @@ class class_ : public objects::class_base objects::add_to_namespace(*this, name, f, doc); } - private: // types - typedef objects::class_id class_id; - - typedef typename detail::select_bases::type - >::type - >::type bases; - - // A helper class which will contain an array of id objects to be - // passed to the base class constructor - struct id_vector - { - typedef objects::class_id class_id; - id_vector() - { - // Stick the derived class id into the first element of the array - ids[0] = type_id(); - - // Write the rest of the elements into succeeding positions. - class_id* p = ids + 1; - mpl::for_each::execute(&p); - } - - BOOST_STATIC_CONSTANT( - std::size_t, size = mpl::size::value + 1); - class_id ids[size]; - }; - friend struct id_vector; + inline void register_() const; }; // // implementations // + // register converters template -inline class_::class_() - : base(typeid(T).name(), id_vector::size, id_vector().ids) +inline void class_::register_() const { - // register converters objects::register_class_from_python(); detail::register_copy_constructor( @@ -272,19 +297,49 @@ inline class_::class_() , *this); } + + +template +inline class_::class_() + : base(typeid(T).name(), id_vector::size, id_vector().ids) +{ + this->register_(); + detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); + this->def_init(); +} + +template +inline class_::class_(no_init_t) + : base(typeid(T).name(), id_vector::size, id_vector().ids) +{ + this->register_(); + this->def_no_init(); +} + template inline class_::class_(char const* name, char const* doc) : base(name, id_vector::size, id_vector().ids, doc) { - // register converters - objects::register_class_from_python(); - - detail::register_copy_constructor( - mpl::bool_t() - , objects::select_holder((held_type*)0).get() - , *this); + this->register_(); + detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); + this->def_init(); } +template +inline class_::class_(char const* name, no_init_t) + : base(name, id_vector::size, id_vector().ids) +{ + this->register_(); + this->def_no_init(); +} + +template +inline class_::class_(char const* name, char const* doc, no_init_t) + : base(name, id_vector::size, id_vector().ids, doc) +{ + this->register_(); + this->def_no_init(); +} template inline class_& class_::add_property(char const* name, object const& fget) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp new file mode 100644 index 00000000..44a1939b --- /dev/null +++ b/include/boost/python/detail/defaults_def.hpp @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// 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. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef DEFAULTS_DEF_JDG20020811_HPP +#define DEFAULTS_DEF_JDG20020811_HPP + +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace python { + +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// +// This Boost PP code generates expansions for +// +// template +// inline void +// define_stub_function( +// char const* name, StubsT s, HolderT& holder, boost::mpl::int_t) +// { +// holder.def(name, &StubsT::func_N); +// } +// +// where N runs from 0 to BOOST_PYTHON_MAX_ARITY +// +// The set of overloaded functions (define_stub_function) expects: +// +// 1. char const* name: function name that will be visible to python +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// 4. int_t: the Nth overloaded function (StubsT::func_N) +// (see defaults_gen.hpp) +// 5. char const* name: doc string +// +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_STUB_FUNC_DEF(INDEX, DATA) \ + \ + template \ + inline void \ + define_stub_function \ + ( \ + char const* name, \ + StubsT, \ + HolderT& holder, \ + boost::mpl::int_t, \ + char const* doc \ + ) \ + { \ + holder.def( \ + name, \ + &StubsT::BOOST_PP_CAT(func_, INDEX), \ + default_call_policies(), \ + doc); \ + } \ + +BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY) + +#undef BPL_IMPL_STUB_FUNC_DEF +/////////////////////////////////////////////////////////////////////////////// +// +// define_with_defaults_helper +// +// This helper template struct does the actual recursive definition. +// There's a generic version define_with_defaults_helper and a +// terminal case define_with_defaults_helper<0>. The struct and its +// specialization has a sole static member function def that expects: +// +// 1. char const* name: function name that will be visible to python +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// 4. char const* name: doc string +// +// The def static member function calls a corresponding +// define_stub_function. The general case recursively calls +// define_with_defaults_helper::def until it reaches the +// terminal case case define_with_defaults_helper<0>. +// +/////////////////////////////////////////////////////////////////////////////// + template + struct define_with_defaults_helper { + + template + static void + def(char const* name, StubsT stubs, HolderT& holder, char const* doc) + { + // define the NTH stub function of stubs + define_stub_function(name, stubs, holder, boost::mpl::int_t(), doc); + // call the next define_with_defaults_helper + define_with_defaults_helper::def(name, stubs, holder, doc); + } + }; + +/////////////////////////////////////// + template <> + struct define_with_defaults_helper<0> { + + template + static void + def(char const* name, StubsT stubs, HolderT& holder, char const* doc) + { + // define the Oth stub function of stubs + define_stub_function(name, stubs, holder, boost::mpl::int_t<0>(), doc); + // return + } + }; + +/////////////////////////////////////////////////////////////////////////////// +// +// define_with_defaults +// +// 1. char const* name: function name that will be visible to python +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// 4. SigT sig: Function signature typelist (see defaults_gen.hpp) +// 5. char const* name: doc string +// +// This is the main entry point. This function recursively defines all +// stub functions of StubT (see defaults_gen.hpp) in HolderT holder which +// can be either a python::class_ or a python::module. The sig argument +// is a typelist that specifies the return type, the class (for member +// functions, and the arguments. Here are some SigT examples: +// +// int foo(int) mpl::type_list +// void bar(int, int) mpl::type_list +// void C::foo(int) mpl::type_list +// +/////////////////////////////////////////////////////////////////////////////// + template + inline void + define_with_defaults( + char const* name, + StubsT, + HolderT& holder, + SigT sig, + char const* doc) + { + typedef typename mpl::select_type + < + boost::is_same::type>::value, + typename StubsT::v_type, + typename StubsT::nv_type + > + ::type stubs_type; + + BOOST_STATIC_ASSERT( + (stubs_type::max_args + 1) <= boost::mpl::size::value); + + typedef stubs_type::template gen gen_type; + define_with_defaults_helper::def + (name, gen_type(), holder, doc); + } + +} // namespace detail + +}} // namespace boost::python + +/////////////////////////////////////////////////////////////////////////////// +#endif // DEFAULTS_DEF_JDG20020811_HPP + + diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp new file mode 100644 index 00000000..0f580d94 --- /dev/null +++ b/include/boost/python/detail/defaults_gen.hpp @@ -0,0 +1,320 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// 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. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef DEFAULTS_GEN_JDG20020807_HPP +#define DEFAULTS_GEN_JDG20020807_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace python { namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// +// func_stubs_base is used as a base class for all function +// stubs. This technique uses the "Curiously recurring template +// pattern" to disambiguate function calls. For instance, the +// interface: +// +// template +// void foo(func_stubs_base const&) +// +// will accept only subclasses of func_stubs_base. +// +/////////////////////////////////////////////////////////////////////////////// +template +struct func_stubs_base { + + typedef DerivedT derived_t; + + DerivedT& derived() + { return *static_cast(this); } + + DerivedT const& derived() const + { return *static_cast(this); } +}; + +}}} // namespace boost::python::detail + +/////////////////////////////////////////////////////////////////////////////// +// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/ + +#ifndef BOOST_PP_FIX_REPEAT_2ND +#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \ + BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \ + /**/ +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_TYPEDEF_GEN(INDEX, DATA) \ + typedef typename boost::mpl::at \ + < \ + BOOST_PP_ADD(INDEX, DATA), \ + SigT \ + >::type BOOST_PP_CAT(T, INDEX); \ + +#define BPL_IMPL_ARGS_GEN(INDEX, DATA) \ + BOOST_PP_CAT(T, INDEX) BOOST_PP_CAT(arg, INDEX) \ + +#define BPL_IMPL_FUNC_WRAPPER_GEN(INDEX, DATA) \ + static RT BOOST_PP_CAT(func_, INDEX) \ + ( \ + BOOST_PP_ENUM \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + BPL_IMPL_ARGS_GEN, \ + BOOST_PP_EMPTY \ + ) \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ + BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ + ( \ + BOOST_PP_ENUM_PARAMS \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + arg \ + ) \ + ); \ + } \ + +#define BPL_IMPL_GEN_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ + struct FSTUBS_NAME { \ + \ + BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \ + BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \ + \ + template \ + struct gen { \ + \ + typedef typename boost::mpl::at<0, SigT>::type RT; \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_TYPEDEF_GEN, \ + 1 \ + ) \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_FUNC_WRAPPER_GEN, \ + (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ + ) \ + }; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \ + static RT BOOST_PP_CAT(func_, INDEX) \ + ( \ + ClassT& obj, \ + BOOST_PP_ENUM \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + BPL_IMPL_ARGS_GEN, \ + BOOST_PP_EMPTY \ + ) \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(3, 2, DATA) obj. \ + BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ + ( \ + BOOST_PP_ENUM_PARAMS \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + arg \ + ) \ + ); \ + } \ + +#define BPL_IMPL_GEN_MEM_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ + struct FSTUBS_NAME { \ + \ + BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \ + BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \ + \ + template \ + struct gen { \ + \ + typedef typename boost::mpl::at<0, SigT>::type RT; \ + typedef typename boost::mpl::at<1, SigT>::type ClassT; \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_TYPEDEF_GEN, \ + 2 \ + ) \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_MEM_FUNC_WRAPPER_GEN, \ + (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ + ) \ + }; \ + }; \ + \ + +/////////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_MSVC) + +#define BPL_IMPL_GEN_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ + BPL_IMPL_GEN_FUNCTION \ + (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ + BPL_IMPL_GEN_FUNCTION \ + (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \ + struct FSTUBS_NAME \ + : public boost::python::detail::func_stubs_base { \ + \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GEN_MEM_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ + BPL_IMPL_GEN_MEM_FUNCTION \ + (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ + BPL_IMPL_GEN_MEM_FUNCTION \ + (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \ + struct FSTUBS_NAME \ + : public boost::python::detail::func_stubs_base { \ + \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \ + }; \ + +#else + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GEN_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ + BPL_IMPL_GEN_FUNCTION \ + (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ + struct FSTUBS_NAME \ + : public boost::python::detail::func_stubs_base { \ + \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GEN_MEM_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ + BPL_IMPL_GEN_MEM_FUNCTION \ + (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ + struct FSTUBS_NAME \ + : public boost::python::detail::func_stubs_base { \ + \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ + typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \ + }; \ + +#endif // defined(BOOST_MSVC) + +/////////////////////////////////////////////////////////////////////////////// +// +// MAIN MACROS +// +// Given GENERATOR_NAME, FNAME, MIN_ARGS and MAX_ARGS, These macros +// generate function stubs that forward to a function or member function +// named FNAME. MAX_ARGS is the arity of the function or member function +// FNAME. FNAME can have default arguments. MIN_ARGS is the minimum +// arity that FNAME can accept. +// +// There are two versions: +// +// 1. BOOST_PYTHON_FUNCTION_GENERATOR for free functions +// 2. BOOST_PYTHON_MEM_FUN_GENERATOR for member functions. +// +// For instance, given a function: +// +// int +// foo(int a, char b = 1, unsigned c = 2, double d = 3) +// { +// return a + b + c + int(d); +// } +// +// The macro invocation: +// +// BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) +// +// Generates this code: +// +// struct foo_stubs_NV { +// +// static const int n_funcs = 4; +// static const int max_args = n_funcs; +// +// template +// struct gen { +// +// typedef typename mpl::at<0, SigT>::type RT; +// typedef typename mpl::at<1, SigT>::type T0; +// typedef typename mpl::at<2, SigT>::type T1; +// typedef typename mpl::at<3, SigT>::type T2; +// typedef typename mpl::at<4, SigT>::type T3; +// +// static RT func_0(T0 arg0) +// { return foo(arg0); } +// static RT func_1(T0 arg0,T1 arg1) +// { return foo(arg0, arg1); } +// static RT func_2(T0 arg0, T1 arg1, T2 arg2) +// { return foo(arg0, arg1, arg2); } +// static RT func_3(T0 arg0, T1 arg1, T2 arg2,T3 arg3) +// { return foo (arg0, arg1, arg2, arg3); } +// }; +// }; +// +// struct foo_stubs +// : public boost::python::detail::func_stubs_base { +// +// typedef foo_stubs_NV nv_type; +// typedef foo_stubs_NV v_type; +// }; +// +// The typedefs nv_type and v_type are used to handle compilers that +// do not support void returns. The example above typedefs nv_type +// and v_type to foo_stubs_NV. On compilers that do not support +// void returns, there are two versions: foo_stubs_NV and foo_stubs_V. +// The "V" version is almost identical to the "NV" version except +// for the return type (void) and the lack of the return keyword. +// +/////////////////////////////////////////////////////////////////////////////// +#define BOOST_PYTHON_FUNCTION_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ + BPL_IMPL_GEN_FUNCTION_STUB \ + ( \ + FNAME, \ + GENERATOR_NAME, \ + MAX_ARGS, \ + BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ + ) \ + +#define BOOST_PYTHON_MEM_FUN_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ + BPL_IMPL_GEN_MEM_FUNCTION_STUB \ + ( \ + FNAME, \ + GENERATOR_NAME, \ + MAX_ARGS, \ + BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ + ) \ + +/////////////////////////////////////////////////////////////////////////////// +#endif // DEFAULTS_GEN_JDG20020807_HPP + + diff --git a/include/boost/python/detail/translate_exception.hpp b/include/boost/python/detail/translate_exception.hpp index ea4d5056..aa617a2a 100644 --- a/include/boost/python/detail/translate_exception.hpp +++ b/include/boost/python/detail/translate_exception.hpp @@ -6,13 +6,12 @@ #ifndef TRANSLATE_EXCEPTION_DWA2002810_HPP # define TRANSLATE_EXCEPTION_DWA2002810_HPP +# include # include # include namespace boost { namespace python { namespace detail { -struct exception_handler; - // A ternary function object used to translate C++ exceptions of type // ExceptionType into Python exceptions by invoking an object of type // Translate. Typically the translate function will be curried with diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 44aa31f6..cd7c25f4 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -41,6 +41,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object void add_property(char const* name, object const& fget, object const& fset); void setattr(char const* name, object const&); void enable_pickling(bool getstate_manages_dict); + void def_no_init(); }; BOOST_PYTHON_DECL type_handle registered_class_object(class_id id); diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 13862e6f..b41ba621 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -131,7 +131,7 @@ namespace detail bind(&detail::iterator_next::execute, _1, _2, policies) , 1); - return class_(name) + return class_(name, no_init) .def("__iter__", identity_function()) .setattr("next", next_function) ; diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp new file mode 100644 index 00000000..d83071a1 --- /dev/null +++ b/include/boost/python/signature.hpp @@ -0,0 +1,266 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// 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. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef SIGNATURE_JDG20020813_HPP +#define SIGNATURE_JDG20020813_HPP + +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace python { + +/////////////////////////////////////////////////////////////////////////////// +// +// signature +// +// This template struct acts as a type holder for the signature of a +// function or member function. This struct is used to pass in the +// return type, class (for member functions) and arguments of a +// function or member function. Examples: +// +// signature int foo(int) +// signature void foo(int, int) +// signature void C::foo(int, int) +// signature void C::foo(int, int) const +// +/////////////////////////////////////////////////////////////////////////////// +template +struct signature {}; + +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/ + +#ifndef BOOST_PP_FIX_REPEAT_2ND +#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \ + BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \ + /**/ +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// The following macros generate expansions for: +// +// template +// inline boost::mpl::type_list +// get_signature(signature) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(RT(*)(T0...TN)) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(signature) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(signature) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(RT(ClassT::*)(T0...TN))) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(RT(ClassT::*)(T0...TN) const)) +// { +// return boost::mpl::type_list(); +// } +// +// These functions extract the return type, class (for member functions) +// and arguments of the input signature and stuffs them in an mpl::type_list. +// +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX) + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GET_FUNCTION_SIGNATURE(INDEX, DATA) \ + \ + template \ + < \ + typename RT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(signature) \ + { \ + return boost::mpl::type_list \ + (); \ + } \ + \ + template \ + < \ + typename RT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \ + { \ + return boost::mpl::type_list \ + (); \ + } \ + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE(INDEX, DATA) \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(signature) \ + { \ + return boost::mpl::type_list \ + \ + (); \ + } \ + \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature( \ + signature) \ + { \ + return boost::mpl::type_list \ + < \ + RT, ClassT const \ + BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + >(); \ + } \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \ + { \ + return boost::mpl::type_list \ + \ + (); \ + } \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT const \ + BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T)) const) \ + { \ + return boost::mpl::type_list \ + < \ + RT, ClassT const \ + BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + >(); \ + } \ + +/////////////////////////////////////////////////////////////////////////////// + +BOOST_PP_FIX_REPEAT_2ND \ +( \ + BOOST_PP_SUB(BOOST_PYTHON_MAX_ARITY, 1), \ + BPL_IMPL_GET_FUNCTION_SIGNATURE, BOOST_PP_EMPTY \ +) + +BOOST_PP_FIX_REPEAT_2ND \ +( \ + BOOST_PP_SUB(BOOST_PYTHON_MAX_ARITY, 2), \ + BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE, BOOST_PP_EMPTY \ +) + +#undef BPL_IMPL_GET_FUNCTION_SIGNATURE +#undef BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE +#undef BPL_IMPL_TEMPLATE_GEN + +} + +}} // namespace boost::python + +/////////////////////////////////////////////////////////////////////////////// +#endif // SIGNATURE_JDG20020813_HPP + + diff --git a/src/object/class.cpp b/src/object/class.cpp index 83287125..c6420a76 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -323,6 +323,26 @@ namespace objects throw_error_already_set(); } + namespace + { + extern "C" PyObject* no_init(PyObject*, PyObject*) + { + ::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python"); + return NULL; + } + static ::PyMethodDef no_init_def = { + "__init__", no_init, METH_VARARGS, + "Raises an exception\n" + "This class cannot be instantiated from Python\n" + }; + } + + void class_base::def_no_init() + { + handle<> f(::PyCFunction_New(&no_init_def, 0)); + this->setattr("__init__", object(f)); + } + void class_base::enable_pickling(bool getstate_manages_dict) { setattr("__reduce__", object(make_instance_reduce_function())); diff --git a/src/object/function.cpp b/src/object/function.cpp index c2d36075..187becc9 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -195,9 +195,8 @@ void function::add_to_namespace( { // Binary operators need an additional overload which // returns NotImplemented, so that Python will try the - // lxxx functions on the other operand. We add this - // overload already when no overloads for the operator - // already exist. + // lxxx functions on the other operand. We add this when + // no overloads for the operator already exist. new_func->add_overload(not_implemented_function()); } diff --git a/test/back_reference.cpp b/test/back_reference.cpp index 39f9127e..22477646 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -93,15 +93,13 @@ BOOST_PYTHON_MODULE_INIT(back_reference_ext) .def("copy_Z", copy_Z, return_value_policy()) .def("x_instances", &X::count) .add( - class_("Y") - .def_init(args()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) ) .add( - class_ >("Z") - .def_init(args()) + class_ >("Z", args()) .def("value", &Z::value) .def("set", &Z::set) ) diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp index ab184b22..e6d5e42f 100644 --- a/test/bienstman1.cpp +++ b/test/bienstman1.cpp @@ -30,7 +30,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman1_ext) .add(class_ >("A")) .add( - class_("V") + class_("V", no_init) .def("inside", &V::inside, return_value_policy()) .def("outside", outside, diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index eb2bb30a..494965a2 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -19,12 +19,11 @@ BOOST_PYTHON_MODULE_INIT(bienstman3_ext) m .add( - class_("V") + class_("V", no_init) ) .add( - class_("B") - .def_init(args()) + class_("B", args()) ) ; } diff --git a/test/bienstman3.py b/test/bienstman3.py index 8a14c8ff..90efdd53 100644 --- a/test/bienstman3.py +++ b/test/bienstman3.py @@ -1,5 +1,15 @@ ''' >>> from bienstman3_ext import * + +>>> try: +... V() +... except RuntimeError, x: +... print x +... else: +... print 'expected an exception' +... +This class cannot be instantiated from Python + ''' def run(args = None): import sys diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 29e971d8..b44b4bf8 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -7,7 +7,6 @@ #include #include #include -#include struct Type1 {}; @@ -24,12 +23,10 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) module("bienstman4_ext") .add(class_("Expression") - .def_init() .def("add", &Expression::add)) .add(class_("T1") - .def_init()) - .add(class_("Term") - .def_init(type_list())) + .add(class_("Term" + , args())) ; diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 6e916367..230d1a3e 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -137,8 +137,7 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) .def("apply_to_string_literal", apply_to_string_literal) .add( - class_("X") - .def_init(args()) + class_("X", args()) .def_init(args()) .def("value", &X::value) .def("set", &X::set) diff --git a/test/data_members.cpp b/test/data_members.cpp index 06148835..30c8d22f 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -24,16 +24,14 @@ BOOST_PYTHON_MODULE_INIT(data_members_ext) { module("data_members_ext") .add( - class_("X") - .def_init(args()) + class_("X", args()) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) .add_property("get_fair_value", object(&get_fair_value)) ) .add( - class_("Y") - .def_init(args()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) .def_readwrite("x", &Y::x) diff --git a/test/defaults.py b/test/defaults.py new file mode 100644 index 00000000..b72cea4f --- /dev/null +++ b/test/defaults.py @@ -0,0 +1,90 @@ +""" + +>>> from defaults_ext import * +>>> bar(1) +'int(1); char(D); string(default); double(0.0); ' +>>> bar(2, 'X') +'int(2); char(X); string(default); double(0.0); ' +>>> bar(3, 'Y', "Hello World") +'int(3); char(Y); string(Hello World); double(0.0); ' +>>> bar(4, 'Z', "Hi There", 3.3) +'int(4); char(Z); string(Hi There); double(3.3); ' +>>> foo(1) +'int(1); char(D); string(default); double(0.0); ' +>>> foo(2, 'X') +'int(2); char(X); string(default); double(0.0); ' +>>> foo(3, 'Y', "Hello World") +'int(3); char(Y); string(Hello World); double(0.0); ' +>>> foo(4, 'Z', "Hi There", 3.3) +'int(4); char(Z); string(Hi There); double(3.3); ' +>>> x = X() +>>> x.bar(1) +'int(1); char(D); string(default); double(0.0); ' +>>> x.bar(2, 'X') +'int(2); char(X); string(default); double(0.0); ' +>>> x.bar(3, 'Y', "Hello World") +'int(3); char(Y); string(Hello World); double(0.0); ' +>>> x.bar(4, 'Z', "Hi There", 3.3) +'int(4); char(Z); string(Hi There); double(3.3); ' +>>> + + + +""" +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 + sys.exit(run()[0]) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/docstring.cpp b/test/docstring.cpp index e8f63971..9642c636 100644 --- a/test/docstring.cpp +++ b/test/docstring.cpp @@ -40,12 +40,12 @@ BOOST_PYTHON_MODULE_INIT(docstring_ext) class_("X", "A simple class wrapper around a C++ int\n" "includes some error-checking" - ) - - .def_init(args(), + + , args(), "this is the __init__ function\n" "its documentation has two lines." - ) + + ) .def("value", &X::value, "gets the value of the object") diff --git a/test/extract.cpp b/test/extract.cpp index ae9b5c17..aec75308 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -47,7 +47,19 @@ std::string extract_string(object x) std::string const& extract_string_cref(object x) { +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +# pragma warning(push) +# pragma warning(disable:4172) // msvc lies about returning a reference to temporary +#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 600 +# pragma warning(push) +# pragma warning(disable:473) // intel/win32 does too +#endif + return extract(x); + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 600 +# pragma warning(pop) +#endif } X extract_X(object x) @@ -87,10 +99,9 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) { implicitly_convertible(); - class_ x_class("X"); + class_ x_class("X", args()); x_class - .def_init(args()) .def( "__repr__", x_rep) ; diff --git a/test/implicit.cpp b/test/implicit.cpp index 50479158..ca250b9e 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -26,8 +26,7 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext) .def("x_value", x_value) .def("make_x", make_x) .add( - class_("X") - .def_init(args()) + class_("X", args()) .def("value", &X::value) .def("set", &X::set) ) diff --git a/test/iterator.cpp b/test/iterator.cpp index aeb35648..c5ce6f32 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -76,7 +76,6 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) .def("range", &::range) .add( class_("list_int") - .def_init() .def("push_back", push_back) .def("back", back) .def("__iter__", iterator()) @@ -90,7 +89,6 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) ) .add( class_("two_lists") - .def_init() // We can spcify member functions .add_property( @@ -118,7 +116,6 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) ) .add( class_("list_list") - .def_init() .def("push_back", push_list_back) .def("__iter__", iterator >()) ) diff --git a/test/list.cpp b/test/list.cpp index 7b0d2645..2e6c2ee7 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -138,8 +138,7 @@ BOOST_PYTHON_MODULE_INIT(list_ext) .def("exercise", exercise) - .add(class_("X") - .def_init(args()) + .add(class_("X", args()) .def( "__repr__", x_rep)) ; } diff --git a/test/m1.cpp b/test/m1.cpp index ada4707e..71bc3af1 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -242,7 +242,6 @@ BOOST_PYTHON_MODULE_INIT(m1) .add( class_ >("A") - .def_init() .def("name", &A::name) ) @@ -253,13 +252,11 @@ BOOST_PYTHON_MODULE_INIT(m1) m1 .add( class_, shared_ptr >("B") - .def_init() .def("name", &B::name) ) .add( class_, shared_ptr >("C") - .def_init() .def("name", &C::name) ) ; @@ -267,13 +264,12 @@ BOOST_PYTHON_MODULE_INIT(m1) m1 .add( class_, bases >("D") - .def_init() .def("name", &D::name) ) .add( - class_("complicated") - .def_init(args()) + class_("complicated", + args()) .def_init(args()) .def("get_n", &complicated::get_n) ) diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index c4c91aea..0114e151 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -16,11 +16,10 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) module("multi_arg_constructor_ext") - .add(class_ >("A") - .def_init(args()) + .add(class_ >( + "A" + , args() + ) ) ; diff --git a/test/operators.cpp b/test/operators.cpp index 336207f4..9b2afc3e 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -60,8 +60,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) { module("operators_ext") .add( - class_("X") - .def_init(args()) + class_("X", args()) .def("value", &X::value) .def(self - self) .def(self - int()) @@ -79,8 +78,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(pow(int(),self)) ) .add( - class_ >("Z") - .def_init(args()) + class_ >("Z", args()) .def(int_(self)) .def(float_(self)) .def(complex_(self)) diff --git a/test/pickle1.cpp b/test/pickle1.cpp index cecb9c6a..6edec23a 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -51,8 +51,8 @@ BOOST_PYTHON_MODULE_INIT(pickle1_ext) { using namespace boost::python; module("pickle1_ext") - .add(class_("world") - .def_init(args()) + .add(class_("world" + , args()) .def("greet", &world::greet) .def_pickle(world_pickle_suite()) ) diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 47d655c6..62c7c4b5 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -90,8 +90,8 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2_ext) { boost::python::module("pickle2_ext") - .add(boost::python::class_("world") - .def_init(boost::python::args()) + .add(boost::python::class_("world" + , boost::python::args()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 911eb7b8..4aaaecb5 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -96,8 +96,8 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3_ext) { boost::python::module("pickle3_ext") - .add(boost::python::class_("world") - .def_init(boost::python::args()) + .add(boost::python::class_("world" + , boost::python::args()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 74c869ed..2bbf84e2 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -87,19 +87,18 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) .add( - class_() + class_(no_init) .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) ) .add( - class_() + class_(no_init) .def("change", &inner::change) ) .add( class_("B") - .def_init() .def_init(args(), with_custodian_and_ward_postcall<1,2>()) .def("adopt", &B::adopt diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 3f516bf7..45fe3636 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -90,8 +90,7 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { module("virtual_functions_ext") .add( - class_("concrete") - .def_init(args()) + class_("concrete", args()) .def("value", &concrete::value) .def("set", &concrete::set) .def("call_f", &concrete::call_f) @@ -99,16 +98,14 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) .add( class_ - >("abstract") + >("abstract", args()) - .def_init(args()) .def("value", &abstract::value) .def("call_f", &abstract::call_f) .def("set", &abstract::set)) .add( - class_("Y") - .def_init(args()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) )