Boost logo

Boost-Commit :

From: rwgk_at_[hidden]
Date: 2007-09-11 12:54:04


Author: rwgk
Date: 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
New Revision: 39191
URL: http://svn.boost.org/trac/boost/changeset/39191

Log:
Patches by Nikolay Mladenov (nickm at sitius com): new pythonic signatures; docstring support for enums; fix unrelated Visual C++ 6 problem
Added:
   trunk/boost/python/converter/pytype_function.hpp (contents, props changed)
   trunk/boost/python/detail/python_type.hpp (contents, props changed)
   trunk/boost/python/detail/unwind_type.hpp (contents, props changed)
   trunk/boost/python/object/function_doc_signature.hpp (contents, props changed)
   trunk/libs/python/doc/v2/function_doc_signature.html (contents, props changed)
   trunk/libs/python/doc/v2/pytype_function.html (contents, props changed)
   trunk/libs/python/src/object/function_doc_signature.cpp (contents, props changed)
   trunk/libs/python/test/a_map_indexing_suite.cpp (contents, props changed)
   trunk/libs/python/test/pytype_function.cpp (contents, props changed)
   trunk/libs/python/test/pytype_function.py (contents, props changed)
Text files modified:
   trunk/boost/python/converter/as_to_python_function.hpp | 3 +
   trunk/boost/python/converter/builtin_converters.hpp | 48 +++++++++------
   trunk/boost/python/converter/pyobject_traits.hpp | 3 +
   trunk/boost/python/converter/pyobject_type.hpp | 5 +
   trunk/boost/python/converter/registrations.hpp | 9 +++
   trunk/boost/python/converter/registry.hpp | 6 +
   trunk/boost/python/converter/shared_ptr_from_python.hpp | 9 ++
   trunk/boost/python/default_call_policies.hpp | 7 ++
   trunk/boost/python/detail/caller.hpp | 45 ++++++++++++++-
   trunk/boost/python/detail/config.hpp | 4 +
   trunk/boost/python/detail/defaults_def.hpp | 2
   trunk/boost/python/detail/defaults_gen.hpp | 4
   trunk/boost/python/detail/make_keyword_range_fn.hpp | 3 +
   trunk/boost/python/detail/signature.hpp | 28 ++++++++-
   trunk/boost/python/docstring_options.hpp | 73 +++++++++++++++++++++---
   trunk/boost/python/enum.hpp | 8 +-
   trunk/boost/python/implicit.hpp | 9 ++
   trunk/boost/python/init.hpp | 6 +-
   trunk/boost/python/lvalue_from_pytype.hpp | 17 ++++-
   trunk/boost/python/make_constructor.hpp | 10 +++
   trunk/boost/python/object/class_metadata.hpp | 16 +++++
   trunk/boost/python/object/class_wrapper.hpp | 13 +++
   trunk/boost/python/object/enum_base.hpp | 4 +
   trunk/boost/python/object/function.hpp | 2
   trunk/boost/python/object/make_holder.hpp | 10 +++
   trunk/boost/python/object/make_ptr_instance.hpp | 7 ++
   trunk/boost/python/object/py_function.hpp | 23 +++++--
   trunk/boost/python/object_core.hpp | 3 +
   trunk/boost/python/opaque_pointer_converter.hpp | 8 ++
   trunk/boost/python/return_arg.hpp | 14 ++++
   trunk/boost/python/to_python_converter.hpp | 71 ++++++++++++++++++++++--
   trunk/boost/python/to_python_indirect.hpp | 12 +++
   trunk/boost/python/to_python_value.hpp | 54 ++++++++++++++++++
   trunk/libs/python/build/Jamfile.v2 | 1
   trunk/libs/python/doc/news.html | 38 ++++++++++++
   trunk/libs/python/doc/v2/CallPolicies.html | 14 ++++
   trunk/libs/python/doc/v2/ResultConverter.html | 21 +++++-
   trunk/libs/python/doc/v2/configuration.html | 35 ++++++++++++
   trunk/libs/python/doc/v2/default_call_policies.html | 3
   trunk/libs/python/doc/v2/docstring_options.html | 57 ++++++++++++++++++-
   trunk/libs/python/doc/v2/enum.html | 8 +-
   trunk/libs/python/doc/v2/reference.html | 60 ++++++++++++++++++++
   trunk/libs/python/doc/v2/return_arg.html | 2
   trunk/libs/python/doc/v2/to_python_converter.html | 27 ++++++++-
   trunk/libs/python/example/std_pair.cpp | 5 +
   trunk/libs/python/src/converter/builtin_converters.cpp | 20 ++++++
   trunk/libs/python/src/converter/registry.cpp | 52 ++++++++++++++---
   trunk/libs/python/src/dict.cpp | 10 +++
   trunk/libs/python/src/list.cpp | 10 +++
   trunk/libs/python/src/object/enum.cpp | 7 +
   trunk/libs/python/src/object/function.cpp | 43 ++++++++++++++
   trunk/libs/python/src/str.cpp | 10 +++
   trunk/libs/python/src/tuple.cpp | 11 +++
   trunk/libs/python/test/Jamfile.v2 | 3
   trunk/libs/python/test/args.cpp | 24 ++++----
   trunk/libs/python/test/args.py | 66 ++++------------------
   trunk/libs/python/test/auto_ptr.py | 18 ++++++
   trunk/libs/python/test/back_reference.py | 3 +
   trunk/libs/python/test/data_members.cpp | 3
   trunk/libs/python/test/defaults.cpp | 6 +-
   trunk/libs/python/test/defaults.py | 35 ++++-------
   trunk/libs/python/test/docstring.cpp | 53 ++++++++++++-----
   trunk/libs/python/test/docstring.py | 115 ++++++++++++++++++++++-----------------
   trunk/libs/python/test/implicit.py | 13 ++++
   trunk/libs/python/test/keywords_test.py | 4
   trunk/libs/python/test/m1.cpp | 5 +
   trunk/libs/python/test/map_indexing_suite.cpp | 69 +----------------------
   trunk/libs/python/test/newtest.py | 2
   trunk/libs/python/test/pickle1.cpp | 3
   trunk/libs/python/test/pickle2.cpp | 3
   trunk/libs/python/test/pickle3.cpp | 3
   trunk/libs/python/test/pickle4.cpp | 3
   72 files changed, 1056 insertions(+), 345 deletions(-)

Modified: trunk/boost/python/converter/as_to_python_function.hpp
==============================================================================
--- trunk/boost/python/converter/as_to_python_function.hpp (original)
+++ trunk/boost/python/converter/as_to_python_function.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -39,6 +39,9 @@
         // but c'est la vie.
         return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
     }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const * get_pytype() { return ToPython::get_pytype(); }
+#endif
 };
 
 }}} // namespace boost::python::converter

Modified: trunk/boost/python/converter/builtin_converters.hpp
==============================================================================
--- trunk/boost/python/converter/builtin_converters.hpp (original)
+++ trunk/boost/python/converter/builtin_converters.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -47,7 +47,7 @@
 }
 
 // Use expr to create the PyObject corresponding to x
-# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
+# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr, pytype)\
     template <> struct to_python_value<T&> \
         : detail::builtin_to_python \
     { \
@@ -55,6 +55,10 @@
         { \
             return (expr); \
         } \
+ inline PyTypeObject const* get_pytype() const \
+ { \
+ return (pytype); \
+ } \
     }; \
     template <> struct to_python_value<T const&> \
         : detail::builtin_to_python \
@@ -63,6 +67,10 @@
         { \
             return (expr); \
         } \
+ inline PyTypeObject const* get_pytype() const \
+ { \
+ return (pytype); \
+ } \
     };
 
 # define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
@@ -77,25 +85,25 @@
     }
 
 // Specialize argument and return value converters for T using expr
-# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
- BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \
+# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
+ BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
         BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
 
 // Specialize converters for signed and unsigned T to Python Int
 # define BOOST_PYTHON_TO_INT(T) \
- BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x)) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
     BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
         unsigned T \
         , static_cast<unsigned long>(x) > static_cast<unsigned long>( \
                 (std::numeric_limits<long>::max)()) \
         ? ::PyLong_FromUnsignedLong(x) \
- : ::PyInt_FromLong(x))
+ : ::PyInt_FromLong(x), &PyInt_Type)
 
 // Bool is not signed.
 #if PY_VERSION_HEX >= 0x02030000
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x))
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
 #else
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x), &PyInt_Type)
 #endif
   
 // note: handles signed char and unsigned char, but not char (see below)
@@ -108,25 +116,25 @@
 // using Python's macro instead of Boost's - we don't seem to get the
 // config right all the time.
 # ifdef HAVE_LONG_LONG
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
 # endif
     
 # undef BOOST_TO_PYTHON_INT
 
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())))
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
 #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())))
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
 # endif
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
-BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x), &PyFloat_Type)
+BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x), 0)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
 
 # undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
 # undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE

Modified: trunk/boost/python/converter/pyobject_traits.hpp
==============================================================================
--- trunk/boost/python/converter/pyobject_traits.hpp (original)
+++ trunk/boost/python/converter/pyobject_traits.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -18,6 +18,9 @@
     // All objects are convertible to PyObject
     static bool check(PyObject*) { return true; }
     static PyObject* checked_downcast(PyObject* x) { return x; }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const* get_pytype() { return 0; }
+#endif
 };
 
 //

Modified: trunk/boost/python/converter/pyobject_type.hpp
==============================================================================
--- trunk/boost/python/converter/pyobject_type.hpp (original)
+++ trunk/boost/python/converter/pyobject_type.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -14,7 +14,7 @@
 // Used as a base class for specializations which need to provide
 // Python type checking capability.
 template <class Object, PyTypeObject* pytype>
-struct pyobject_type
+struct pyobject_type
 {
     static bool check(PyObject* x)
     {
@@ -27,6 +27,9 @@
             (checked_downcast_impl)(x, pytype)
             );
     }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const* get_pytype() { return pytype; }
+#endif
 };
 
 }}} // namespace boost::python::converter

Added: trunk/boost/python/converter/pytype_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/python/converter/pytype_function.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,132 @@
+// Copyright David Abrahams 2002, Nikolay Mladenov 2007.
+// 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)
+#ifndef WRAP_PYTYPE_NM20070606_HPP
+# define WRAP_PYTYPE_NM20070606_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/converter/registered.hpp>
+# include <boost/python/detail/unwind_type.hpp>
+
+
+namespace boost { namespace python {
+
+namespace converter
+{
+template <PyTypeObject const* python_type>
+struct wrap_pytype
+{
+ static PyTypeObject const* get_pytype()
+ {
+ return python_type;
+ }
+};
+
+typedef PyTypeObject const* (*pytype_function)();
+
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+
+
+
+namespace detail
+{
+struct unwind_type_id_helper{
+ typedef python::type_info result_type;
+ template <class U>
+ static result_type execute(U* ){
+ return python::type_id<U>();
+ }
+};
+
+template <class T>
+inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
+{
+ return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
+}
+
+inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
+{
+ return type_id<void>();
+}
+
+template <class T>
+inline python::type_info unwind_type_id(boost::type<T>* p= 0)
+{
+ return unwind_type_id_(p, (mpl::bool_<boost::is_void<T>::value >*)0 );
+}
+}
+
+
+template <class T>
+struct expected_pytype_for_arg
+{
+ static PyTypeObject const *get_pytype()
+ {
+ const converter::registration *r=converter::registry::query(
+ detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
+ );
+ return r ? r->expected_from_python_type(): 0;
+ }
+};
+
+
+template <class T>
+struct registered_pytype
+{
+ static PyTypeObject const *get_pytype()
+ {
+ const converter::registration *r=converter::registry::query(
+ detail::unwind_type_id_((boost::type<T>*) 0, (mpl::bool_<boost::is_void<T>::value >*)0 )
+ );
+ return r ? r->m_class_object: 0;
+ }
+};
+
+
+template <class T>
+struct registered_pytype_direct
+{
+ static PyTypeObject const* get_pytype()
+ {
+ return registered<T>::converters.m_class_object;
+ }
+};
+
+template <class T>
+struct expected_from_python_type : expected_pytype_for_arg<T>{};
+
+template <class T>
+struct expected_from_python_type_direct
+{
+ static PyTypeObject const* get_pytype()
+ {
+ return registered<T>::converters.expected_from_python_type();
+ }
+};
+
+template <class T>
+struct to_python_target_type
+{
+ static PyTypeObject const *get_pytype()
+ {
+ const converter::registration *r=converter::registry::query(
+ detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
+ );
+ return r ? r->to_python_target_type(): 0;
+ }
+};
+
+template <class T>
+struct to_python_target_type_direct
+{
+ static PyTypeObject const *get_pytype()
+ {
+ return registered<T>::converters.to_python_target_type();
+ }
+};
+#endif
+
+}}} // namespace boost::python
+
+#endif // WRAP_PYTYPE_NM20070606_HPP

Modified: trunk/boost/python/converter/registrations.hpp
==============================================================================
--- trunk/boost/python/converter/registrations.hpp (original)
+++ trunk/boost/python/converter/registrations.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -27,6 +27,7 @@
 {
     convertible_function convertible;
     constructor_function construct;
+ PyTypeObject const* (*expected_pytype)();
     rvalue_from_python_chain* next;
 };
 
@@ -43,6 +44,11 @@
     // exception if no class has been registered.
     PyTypeObject* get_class_object() const;
 
+ // Return common denominator of the python class objects,
+ // convertable to target. Inspects the m_class_object and the value_chains.
+ PyTypeObject const* expected_from_python_type() const;
+ PyTypeObject const* to_python_target_type() const;
+
  public: // data members. So sue me.
     const python::type_info target_type;
 
@@ -57,6 +63,8 @@
 
     // The unique to_python converter for the associated C++ type.
     to_python_function_t m_to_python;
+ PyTypeObject const* (*m_to_python_target_type)();
+
 
     // True iff this type is a shared_ptr. Needed for special rvalue
     // from_python handling.
@@ -77,6 +85,7 @@
       , rvalue_chain(0)
       , m_class_object(0)
       , m_to_python(0)
+ , m_to_python_target_type(0)
       , is_shared_ptr(is_shared_ptr)
 {}
 

Modified: trunk/boost/python/converter/registry.hpp
==============================================================================
--- trunk/boost/python/converter/registry.hpp (original)
+++ trunk/boost/python/converter/registry.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -27,16 +27,17 @@
   // Return a pointer to the corresponding registration, if one exists
   BOOST_PYTHON_DECL registration const* query(type_info);
   
- BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);
+ BOOST_PYTHON_DECL void insert(to_python_function_t, type_info, PyTypeObject const* (*to_python_target_type)() = 0);
 
   // Insert an lvalue from_python converter
- BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info);
+ BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info, PyTypeObject const* (*expected_pytype)() = 0);
 
   // Insert an rvalue from_python converter
   BOOST_PYTHON_DECL void insert(
       convertible_function
       , constructor_function
       , type_info
+ , PyTypeObject const* (*expected_pytype)() = 0
       );
   
   // Insert an rvalue from_python converter at the tail of the
@@ -45,6 +46,7 @@
       convertible_function
       , constructor_function
       , type_info
+ , PyTypeObject const* (*expected_pytype)() = 0
       );
 }
 

Modified: trunk/boost/python/converter/shared_ptr_from_python.hpp
==============================================================================
--- trunk/boost/python/converter/shared_ptr_from_python.hpp (original)
+++ trunk/boost/python/converter/shared_ptr_from_python.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -10,6 +10,9 @@
 # include <boost/python/converter/from_python.hpp>
 # include <boost/python/converter/rvalue_from_python_data.hpp>
 # include <boost/python/converter/registered.hpp>
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
 # include <boost/shared_ptr.hpp>
 
 namespace boost { namespace python { namespace converter {
@@ -19,7 +22,11 @@
 {
     shared_ptr_from_python()
     {
- converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
+ converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &converter::expected_from_python_type_direct<T>::get_pytype
+#endif
+ );
     }
 
  private:

Modified: trunk/boost/python/default_call_policies.hpp
==============================================================================
--- trunk/boost/python/default_call_policies.hpp (original)
+++ trunk/boost/python/default_call_policies.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -13,6 +13,7 @@
 # include <boost/type_traits/is_pointer.hpp>
 # include <boost/type_traits/is_reference.hpp>
 # include <boost/mpl/or.hpp>
+# include <boost/mpl/front.hpp>
 
 namespace boost { namespace python {
 
@@ -49,6 +50,12 @@
 
     typedef default_result_converter result_converter;
     typedef PyObject* argument_package;
+
+ template <class Sig>
+ struct extract_return_type : mpl::front<Sig>
+ {
+ };
+
 };
 
 struct default_result_converter

Modified: trunk/boost/python/detail/caller.hpp
==============================================================================
--- trunk/boost/python/detail/caller.hpp (original)
+++ trunk/boost/python/detail/caller.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -11,12 +11,15 @@
 # include <boost/python/type_id.hpp>
 # include <boost/python/handle.hpp>
 
+# include <boost/detail/indirect_traits.hpp>
+
 # include <boost/python/detail/invoke.hpp>
 # include <boost/python/detail/signature.hpp>
 # include <boost/python/detail/preprocessor.hpp>
 
 # include <boost/python/arg_from_python.hpp>
 # include <boost/python/converter/context_result_converter.hpp>
+# include <boost/python/converter/builtin_converters.hpp>
 
 # include <boost/preprocessor/iterate.hpp>
 # include <boost/preprocessor/cat.hpp>
@@ -89,6 +92,27 @@
 {
     return ResultConverter();
 }
+
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+template <class ResultConverter>
+struct converter_target_type
+{
+ static PyTypeObject const *get_pytype()
+ {
+ return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
+ }
+};
+
+template < >
+struct converter_target_type <void_result_to_python >
+{
+ static PyTypeObject const *get_pytype()
+ {
+ return 0;
+ }
+};
+#endif
+
     
 template <unsigned> struct caller_arity;
 
@@ -203,11 +227,26 @@
 
         static unsigned min_arity() { return N; }
         
- static signature_element const* signature()
+ static py_func_sig_info signature()
         {
- return detail::signature<Sig>::elements();
+ const signature_element * sig = detail::signature<Sig>::elements();
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+
+ typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
+ typedef typename select_result_converter<Policies, rtype>::type result_converter;
+
+ static const signature_element ret = {
+ (boost::is_void<rtype>::value ? "void" : type_id<rtype>().name())
+ , &detail::converter_target_type<result_converter>::get_pytype
+ , boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
+ };
+ py_func_sig_info res = {sig, &ret };
+#else
+ py_func_sig_info res = {sig, sig };
+#endif
+
+ return res;
         }
-
      private:
         compressed_pair<F,Policies> m_data;
     };

Modified: trunk/boost/python/detail/config.hpp
==============================================================================
--- trunk/boost/python/detail/config.hpp (original)
+++ trunk/boost/python/detail/config.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -134,4 +134,8 @@
 #include <boost/config/auto_link.hpp>
 #endif // auto-linking disabled
 
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
+#endif
+
 #endif // CONFIG_DWA052200_H_

Modified: trunk/boost/python/detail/defaults_def.hpp
==============================================================================
--- trunk/boost/python/detail/defaults_def.hpp (original)
+++ trunk/boost/python/detail/defaults_def.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -168,7 +168,7 @@
           char const* doc)
       {
           // define the NTH stub function of stubs
- define_stub_function<N>::define(name, stubs, kw, policies, name_space, 0);
+ define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
 
           if (kw.second > kw.first)
               --kw.second;

Modified: trunk/boost/python/detail/defaults_gen.hpp
==============================================================================
--- trunk/boost/python/detail/defaults_gen.hpp (original)
+++ trunk/boost/python/detail/defaults_gen.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -248,7 +248,7 @@
         BOOST_PYTHON_GEN_MEM_FUNCTION( \
             fname, void_return_type, n_args, n_dflts, ;) \
                                                                                         \
- BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
+ BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
     };
 
 # else // !defined(BOOST_NO_VOID_RETURNS)
@@ -273,7 +273,7 @@
             fname, non_void_return_type, n_args, n_dflts, return) \
                                                                                         \
         typedef non_void_return_type void_return_type; \
- BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
+ BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
     };
 
 # endif // !defined(BOOST_NO_VOID_RETURNS)

Modified: trunk/boost/python/detail/make_keyword_range_fn.hpp
==============================================================================
--- trunk/boost/python/detail/make_keyword_range_fn.hpp (original)
+++ trunk/boost/python/detail/make_keyword_range_fn.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -57,6 +57,9 @@
     , Holder* = 0
     , ArgList* = 0, Arity* = 0)
 {
+#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
+ python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
+#endif
     return detail::make_keyword_range_function(
         objects::make_holder<Arity::value>
             ::template apply<Holder,ArgList>::execute

Added: trunk/boost/python/detail/python_type.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/python/detail/python_type.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,37 @@
+// Copyright Nikolay Mladenov 2007.
+// 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)
+#ifndef BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
+#define BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
+
+#include <boost/python/converter/registered.hpp>
+
+namespace boost {namespace python {namespace detail{
+
+
+template <class T> struct python_class : PyObject
+{
+ typedef python_class<T> this_type;
+
+ typedef T type;
+
+ static void *converter (PyObject *p){
+ return p;
+ }
+
+ static void register_()
+ {
+ static bool first_time = true;
+
+ if ( !first_time ) return;
+
+ first_time = false;
+ converter::registry::insert(&converter, boost::python::type_id<this_type>(), &converter::registered_pytype_direct<T>::get_pytype);
+ }
+};
+
+
+}}} //namespace boost :: python :: detail
+
+#endif //BOOST_PYTHON_OBJECT_PYTHON_TYPE_H

Modified: trunk/boost/python/detail/signature.hpp
==============================================================================
--- trunk/boost/python/detail/signature.hpp (original)
+++ trunk/boost/python/detail/signature.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -12,6 +12,7 @@
 
 # include <boost/python/detail/preprocessor.hpp>
 # include <boost/python/detail/indirect_traits.hpp>
+# include <boost/python/converter/pytype_function.hpp>
 
 # include <boost/preprocessor/iterate.hpp>
 # include <boost/preprocessor/iteration/local.hpp>
@@ -24,9 +25,16 @@
 struct signature_element
 {
     char const* basename;
+ converter::pytype_function pytype_f;
     bool lvalue;
 };
 
+struct py_func_sig_info
+{
+ signature_element const *signature;
+ signature_element const *ret;
+};
+
 template <unsigned> struct signature_arity;
 
 # define BOOST_PP_ITERATION_PARAMS_1 \
@@ -68,15 +76,25 @@
         {
             static signature_element const result[N+2] = {
                 
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# define BOOST_PP_LOCAL_MACRO(i) \
+ { \
+ type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
+ , &converter::expected_pytype_for_arg<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::get_pytype \
+ , indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
+ },
+#else
 # define BOOST_PP_LOCAL_MACRO(i) \
- { \
- type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
- , indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
- },
+ { \
+ type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
+ , 0 \
+ , indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
+ },
+#endif
                 
 # define BOOST_PP_LOCAL_LIMITS (0, N)
 # include BOOST_PP_LOCAL_ITERATE()
- {0,0}
+ {0,0,0}
             };
             return result;
         }

Added: trunk/boost/python/detail/unwind_type.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/python/detail/unwind_type.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,170 @@
+// Copyright David Abrahams 2002.
+// 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)
+#ifndef UNWIND_TYPE_DWA200222_HPP
+# define UNWIND_TYPE_DWA200222_HPP
+
+# include <boost/python/detail/cv_category.hpp>
+# include <boost/python/detail/indirect_traits.hpp>
+# include <boost/type_traits/object_traits.hpp>
+
+namespace boost { namespace python { namespace detail {
+
+#ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline
+// forward declaration, required (at least) by Tru64 cxx V6.5-042
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_type(U const& p, Generator* = 0);
+
+// forward declaration, required (at least) by Tru64 cxx V6.5-042
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_type(boost::type<U>*p = 0, Generator* = 0);
+#endif
+
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
+{
+ return Generator::execute(p);
+}
+
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_type_cv(U const* p, const_, Generator* = 0)
+{
+ return unwind_type(const_cast<U*>(p), (Generator*)0);
+}
+
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
+{
+ return unwind_type(const_cast<U*>(p), (Generator*)0);
+}
+
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
+{
+ return unwind_type(const_cast<U*>(p), (Generator*)0);
+}
+
+template <class Generator, class U>
+inline typename Generator::result_type
+unwind_ptr_type(U* p, Generator* = 0)
+{
+ typedef typename cv_category<U>::type tag;
+ return unwind_type_cv<Generator>(p, tag());
+}
+
+template <bool is_ptr>
+struct unwind_helper
+{
+ template <class Generator, class U>
+ static typename Generator::result_type
+ execute(U p, Generator* = 0)
+ {
+ return unwind_ptr_type(p, (Generator*)0);
+ }
+};
+
+template <>
+struct unwind_helper<false>
+{
+ template <class Generator, class U>
+ static typename Generator::result_type
+ execute(U& p, Generator* = 0)
+ {
+ return unwind_ptr_type(&p, (Generator*)0);
+ }
+};
+
+template <class Generator, class U>
+inline typename Generator::result_type
+#ifndef _MSC_VER
+unwind_type(U const& p, Generator*)
+#else
+unwind_type(U const& p, Generator* = 0)
+#endif
+{
+ return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
+}
+
+enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
+template <int indirection> struct unwind_helper2;
+
+template <>
+struct unwind_helper2<direct_>
+{
+ template <class Generator, class U>
+ static typename Generator::result_type
+ execute(U(*)(), Generator* = 0)
+ {
+ return unwind_ptr_type((U*)0, (Generator*)0);
+ }
+};
+
+template <>
+struct unwind_helper2<pointer_>
+{
+ template <class Generator, class U>
+ static typename Generator::result_type
+ execute(U*(*)(), Generator* = 0)
+ {
+ return unwind_ptr_type((U*)0, (Generator*)0);
+ }
+};
+
+template <>
+struct unwind_helper2<reference_>
+{
+ template <class Generator, class U>
+ static typename Generator::result_type
+ execute(U&(*)(), Generator* = 0)
+ {
+ return unwind_ptr_type((U*)0, (Generator*)0);
+ }
+};
+
+template <>
+struct unwind_helper2<reference_to_pointer_>
+{
+ template <class Generator, class U>
+ static typename Generator::result_type
+ execute(U&(*)(), Generator* = 0)
+ {
+ return unwind_ptr_type(U(0), (Generator*)0);
+ }
+};
+
+// Call this one with both template parameters explicitly specified
+// and no function arguments:
+//
+// return unwind_type<my_generator,T>();
+//
+// Doesn't work if T is an array type; we could handle that case, but
+// why bother?
+template <class Generator, class U>
+inline typename Generator::result_type
+#ifndef _MSC_VER
+unwind_type(boost::type<U>*p, Generator*)
+#else
+unwind_type(boost::type<U>*p =0, Generator* =0)
+#endif
+{
+ BOOST_STATIC_CONSTANT(int, indirection
+ = (boost::is_pointer<U>::value ? pointer_ : 0)
+ + (indirect_traits::is_reference_to_pointer<U>::value
+ ? reference_to_pointer_
+ : boost::is_reference<U>::value
+ ? reference_
+ : 0));
+
+ return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
+}
+
+}}} // namespace boost::python::detail
+
+#endif // UNWIND_TYPE_DWA200222_HPP

Modified: trunk/boost/python/docstring_options.hpp
==============================================================================
--- trunk/boost/python/docstring_options.hpp (original)
+++ trunk/boost/python/docstring_options.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -17,23 +17,38 @@
       docstring_options(bool show_all=true)
       {
           previous_show_user_defined_ = show_user_defined_;
- previous_show_signatures_ = show_signatures_;
+ previous_show_py_signatures_ = show_py_signatures_;
+ previous_show_cpp_signatures_ = show_cpp_signatures_;
           show_user_defined_ = show_all;
- show_signatures_ = show_all;
+ show_cpp_signatures_ = show_all;
+ show_py_signatures_ = show_all;
       }
 
       docstring_options(bool show_user_defined, bool show_signatures)
       {
           previous_show_user_defined_ = show_user_defined_;
- previous_show_signatures_ = show_signatures_;
+ previous_show_cpp_signatures_ = show_cpp_signatures_;
+ previous_show_py_signatures_ = show_py_signatures_;
           show_user_defined_ = show_user_defined;
- show_signatures_ = show_signatures;
+ show_cpp_signatures_ = show_signatures;
+ show_py_signatures_ = show_signatures;
+ }
+
+ docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures)
+ {
+ previous_show_user_defined_ = show_user_defined_;
+ previous_show_cpp_signatures_ = show_cpp_signatures_;
+ previous_show_py_signatures_ = show_py_signatures_;
+ show_user_defined_ = show_user_defined;
+ show_cpp_signatures_ = show_cpp_signatures;
+ show_py_signatures_ = show_py_signatures;
       }
 
       ~docstring_options()
       {
           show_user_defined_ = previous_show_user_defined_;
- show_signatures_ = previous_show_signatures_;
+ show_cpp_signatures_ = previous_show_cpp_signatures_;
+ show_py_signatures_ = previous_show_py_signatures_;
       }
 
       void
@@ -43,32 +58,68 @@
       enable_user_defined() { show_user_defined_ = true; }
 
       void
- disable_signatures() { show_signatures_ = false; }
+ disable_py_signatures()
+ {
+ show_py_signatures_ = false;
+ }
 
       void
- enable_signatures() { show_signatures_ = true; }
+ enable_py_signatures()
+ {
+ show_py_signatures_ = true;
+ }
+
+ void
+ disable_cpp_signatures()
+ {
+ show_cpp_signatures_ = false;
+ }
+
+ void
+ enable_cpp_signatures()
+ {
+ show_cpp_signatures_ = true;
+ }
+
+ void
+ disable_signatures()
+ {
+ show_cpp_signatures_ = false;
+ show_py_signatures_ = false;
+ }
+
+ void
+ enable_signatures()
+ {
+ show_cpp_signatures_ = true;
+ show_py_signatures_ = true;
+ }
 
       void
       disable_all()
       {
         show_user_defined_ = false;
- show_signatures_ = false;
+ show_cpp_signatures_ = false;
+ show_py_signatures_ = false;
       }
 
       void
       enable_all()
       {
         show_user_defined_ = true;
- show_signatures_ = true;
+ show_cpp_signatures_ = true;
+ show_py_signatures_ = true;
       }
 
       friend struct objects::function;
 
   private:
       static volatile bool show_user_defined_;
- static volatile bool show_signatures_;
+ static volatile bool show_cpp_signatures_;
+ static volatile bool show_py_signatures_;
       bool previous_show_user_defined_;
- bool previous_show_signatures_;
+ bool previous_show_cpp_signatures_;
+ bool previous_show_py_signatures_;
 };
 
 }} // namespace boost::python

Modified: trunk/boost/python/enum.hpp
==============================================================================
--- trunk/boost/python/enum.hpp (original)
+++ trunk/boost/python/enum.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -19,7 +19,7 @@
     typedef objects::enum_base base;
 
     // Declare a new enumeration type in the current scope()
- enum_(char const* name);
+ enum_(char const* name, char const* doc = 0);
 
     // Add a new enumeration value with the given name and value.
     inline enum_<T>& value(char const* name, T);
@@ -34,13 +34,15 @@
 };
 
 template <class T>
-inline enum_<T>::enum_(char const* name)
+inline enum_<T>::enum_(char const* name, char const* doc )
     : base(
         name
         , &enum_<T>::to_python
         , &enum_<T>::convertible_from_python
         , &enum_<T>::construct
- , type_id<T>())
+ , type_id<T>()
+ , doc
+ )
 {
 }
 

Modified: trunk/boost/python/implicit.hpp
==============================================================================
--- trunk/boost/python/implicit.hpp (original)
+++ trunk/boost/python/implicit.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -9,6 +9,9 @@
 # include <boost/type.hpp>
 # include <boost/python/converter/implicit.hpp>
 # include <boost/python/converter/registry.hpp>
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
 # include <boost/python/type_id.hpp>
 
 namespace boost { namespace python {
@@ -21,7 +24,11 @@
     converter::registry::push_back(
           &functions::convertible
         , &functions::construct
- , type_id<Target>());
+ , type_id<Target>()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &converter::expected_from_python_type_direct<Source>::get_pytype
+#endif
+ );
 }
 
 }} // namespace boost::python

Modified: trunk/boost/python/init.hpp
==============================================================================
--- trunk/boost/python/init.hpp (original)
+++ trunk/boost/python/init.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -245,7 +245,7 @@
         : base(doc_, kw.range())
     {
         typedef typename detail::error::more_keywords_than_init_arguments<
- N, n_arguments::value
+ N, n_arguments::value + 1
>::too_many_keywords assertion;
     }
 
@@ -254,7 +254,7 @@
         : base(doc_, kw.range())
     {
         typedef typename detail::error::more_keywords_than_init_arguments<
- N, n_arguments::value
+ N, n_arguments::value + 1
>::too_many_keywords assertion;
     }
 
@@ -363,7 +363,7 @@
           , char const* doc
           , detail::keyword_range keywords)
       {
- detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
+ detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
 
           if (keywords.second > keywords.first)
               --keywords.second;

Modified: trunk/boost/python/lvalue_from_pytype.hpp
==============================================================================
--- trunk/boost/python/lvalue_from_pytype.hpp (original)
+++ trunk/boost/python/lvalue_from_pytype.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -6,6 +6,9 @@
 # define LVALUE_FROM_PYTYPE_DWA2002130_HPP
 
 # include <boost/python/detail/prefix.hpp>
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
 
 # include <boost/python/type_id.hpp>
 # include <boost/python/converter/registry.hpp>
@@ -81,12 +84,17 @@
 // Extractor's static execute function from Python objects whose type
 // object is python_type.
 template <class Extractor, PyTypeObject const* python_type>
-struct lvalue_from_pytype
+struct lvalue_from_pytype
 {
     lvalue_from_pytype()
     {
- converter::registry::insert(
- &extract, detail::extractor_type_id(&Extractor::execute));
+ converter::registry::insert
+ ( &extract
+ , detail::extractor_type_id(&Extractor::execute)
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &get_pytype
+#endif
+ );
     }
  private:
     static void* extract(PyObject* op)
@@ -98,6 +106,9 @@
             : 0
             ;
     }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const*get_pytype() { return python_type; }
+#endif
 };
 
 }} // namespace boost::python

Modified: trunk/boost/python/make_constructor.hpp
==============================================================================
--- trunk/boost/python/make_constructor.hpp (original)
+++ trunk/boost/python/make_constructor.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -104,6 +104,14 @@
       
       // If the BasePolicy_ supplied a result converter it would be
       // ignored; issue an error if it's not the default.
+#if defined _MSC_VER && _MSC_VER < 1300
+ typedef is_same<
+ typename BasePolicy_::result_converter
+ , default_result_converter
+ > same_result_converter;
+ //see above for explanation
+ BOOST_STATIC_ASSERT(same_result_converter::value) ;
+#else
       BOOST_MPL_ASSERT_MSG(
          (is_same<
               typename BasePolicy_::result_converter
@@ -112,7 +120,7 @@
         , MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
         , (typename BasePolicy_::result_converter)
       );
-
+#endif
       typedef constructor_result_converter result_converter;
       typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
   };

Modified: trunk/boost/python/object/class_metadata.hpp
==============================================================================
--- trunk/boost/python/object/class_metadata.hpp (original)
+++ trunk/boost/python/object/class_metadata.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -238,6 +238,14 @@
     //
     inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
 
+#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
+ inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
+ {
+ objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
+ objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T &> >());
+ }
+#endif
+
     template <class T2>
     inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
     {
@@ -247,6 +255,10 @@
               , make_ptr_instance<T2, pointer_holder<held_type, T2> >
>()
         );
+#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
+ // explicit qualification of type_id makes msvc6 happy
+ objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
+#endif
     }
     //
     // Support for registering to-python converters
@@ -258,6 +270,10 @@
     inline static void maybe_register_class_to_python(T2*, mpl::false_)
     {
         python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
+#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
+ // explicit qualification of type_id makes msvc6 happy
+ objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
+#endif
     }
 
     //

Modified: trunk/boost/python/object/class_wrapper.hpp
==============================================================================
--- trunk/boost/python/object/class_wrapper.hpp (original)
+++ trunk/boost/python/object/class_wrapper.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -6,6 +6,9 @@
 # define CLASS_WRAPPER_DWA20011221_HPP
 
 # include <boost/python/to_python_converter.hpp>
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
 # include <boost/ref.hpp>
 
 namespace boost { namespace python { namespace objects {
@@ -19,22 +22,28 @@
 
 template <class Src, class MakeInstance>
 struct class_cref_wrapper
- : to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> >
+ : to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> ,true>
 {
     static PyObject* convert(Src const& x)
     {
         return MakeInstance::execute(boost::ref(x));
     }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const *get_pytype() { return converter::registered_pytype_direct<Src>::get_pytype(); }
+#endif
 };
 
 template <class Src, class MakeInstance>
 struct class_value_wrapper
- : to_python_converter<Src,class_value_wrapper<Src,MakeInstance> >
+ : to_python_converter<Src,class_value_wrapper<Src,MakeInstance> ,true>
 {
     static PyObject* convert(Src x)
     {
         return MakeInstance::execute(x);
     }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const *get_pytype() { return MakeInstance::get_pytype(); }
+#endif
 };
 
 }}} // namespace boost::python::objects

Modified: trunk/boost/python/object/enum_base.hpp
==============================================================================
--- trunk/boost/python/object/enum_base.hpp (original)
+++ trunk/boost/python/object/enum_base.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -21,7 +21,9 @@
         , converter::to_python_function_t
         , converter::convertible_function
         , converter::constructor_function
- , type_info);
+ , type_info
+ , const char *doc = 0
+ );
 
     void add_value(char const* name, long value);
     void export_values();

Modified: trunk/boost/python/object/function.hpp
==============================================================================
--- trunk/boost/python/object/function.hpp (original)
+++ trunk/boost/python/object/function.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -14,6 +14,7 @@
 
 namespace boost { namespace python { namespace objects {
 
+
 struct BOOST_PYTHON_DECL function : PyObject
 {
     function(
@@ -53,6 +54,7 @@
     object m_doc;
     object m_arg_names;
     unsigned m_nkeyword_values;
+ friend class function_doc_signature_generator;
 };
 
 //

Added: trunk/boost/python/object/function_doc_signature.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/python/object/function_doc_signature.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,36 @@
+// Copyright Nikolay Mladenov 2007.
+// 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)
+#ifndef FUNCTION_SIGNATURE_20070531_HPP
+# define FUNCTION_SIGNATURE_20070531_HPP
+
+#include <boost/python/object/function.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/str.hpp>
+#include <boost/python/tuple.hpp>
+
+#include <boost/python/detail/signature.hpp>
+
+
+#include <vector>
+
+namespace boost { namespace python { namespace objects {
+
+class function_doc_signature_generator{
+ static const char * py_type_str(const python::detail::signature_element &s);
+ static bool arity_cmp( function const *f1, function const *f2 );
+ static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
+ static std::vector<function const*> flatten(function const *f);
+ static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
+ static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
+ static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
+ static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
+
+public:
+ static list function_doc_signatures( function const * f);
+};
+
+}}}//end of namespace boost::python::objects
+
+#endif //FUNCTION_SIGNATURE_20070531_HPP

Modified: trunk/boost/python/object/make_holder.hpp
==============================================================================
--- trunk/boost/python/object/make_holder.hpp (original)
+++ trunk/boost/python/object/make_holder.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -11,6 +11,10 @@
 # include <boost/python/detail/prefix.hpp>
 
 # include <boost/python/object/instance.hpp>
+# include <boost/python/converter/registry.hpp>
+#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
+# include <boost/python/detail/python_type.hpp>
+#endif
 
 # include <boost/python/object/forward.hpp>
 # include <boost/python/detail/preprocessor.hpp>
@@ -74,7 +78,11 @@
 # endif
         
         static void execute(
- PyObject* p
+#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
+ boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
+#else
+ PyObject *p
+#endif
             BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
         {
             typedef instance<Holder> instance_t;

Modified: trunk/boost/python/object/make_ptr_instance.hpp
==============================================================================
--- trunk/boost/python/object/make_ptr_instance.hpp (original)
+++ trunk/boost/python/object/make_ptr_instance.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -29,7 +29,12 @@
     {
         return get_class_object_impl(get_pointer(x));
     }
-
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static inline PyTypeObject const* get_pytype()
+ {
+ return converter::registered<T>::converters.get_class_object();
+ }
+#endif
  private:
     template <class U>
     static inline PyTypeObject* get_class_object_impl(U const volatile* p)

Modified: trunk/boost/python/object/py_function.hpp
==============================================================================
--- trunk/boost/python/object/py_function.hpp (original)
+++ trunk/boost/python/object/py_function.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -23,7 +23,7 @@
     virtual PyObject* operator()(PyObject*, PyObject*) = 0;
     virtual unsigned min_arity() const = 0;
     virtual unsigned max_arity() const;
- virtual python::detail::signature_element const* signature() const = 0;
+ virtual python::detail::py_func_sig_info signature() const = 0;
 };
 
 template <class Caller>
@@ -43,7 +43,7 @@
         return m_caller.min_arity();
     }
     
- virtual python::detail::signature_element const* signature() const
+ virtual python::detail::py_func_sig_info signature() const
     {
         return m_caller.signature();
     }
@@ -69,9 +69,11 @@
         return mpl::size<Sig>::value - 1;
     }
     
- virtual python::detail::signature_element const* signature() const
+ virtual python::detail::py_func_sig_info signature() const
     {
- return python::detail::signature<Sig>::elements();
+ python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
+ python::detail::py_func_sig_info res = {sig, sig};
+ return res;
     }
 
  private:
@@ -102,9 +104,11 @@
         return m_max_arity;
     }
     
- virtual python::detail::signature_element const* signature() const
+ virtual python::detail::py_func_sig_info signature() const
     {
- return python::detail::signature<Sig>::elements();
+ python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
+ python::detail::py_func_sig_info res = {sig, sig};
+ return res;
     }
 
  private:
@@ -151,7 +155,12 @@
 
     python::detail::signature_element const* signature() const
     {
- return m_impl->signature();
+ return m_impl->signature().signature;
+ }
+
+ python::detail::signature_element const& get_return_type() const
+ {
+ return *m_impl->signature().ret;
     }
     
  private:

Modified: trunk/boost/python/object_core.hpp
==============================================================================
--- trunk/boost/python/object_core.hpp (original)
+++ trunk/boost/python/object_core.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -470,6 +470,9 @@
       {
           return python::detail::new_non_null_reference(x);
       }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const *get_pytype() {return 0;}
+#endif
   };
 }
 

Modified: trunk/boost/python/opaque_pointer_converter.hpp
==============================================================================
--- trunk/boost/python/opaque_pointer_converter.hpp (original)
+++ trunk/boost/python/opaque_pointer_converter.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -93,8 +93,13 @@
 
         if ((existing == 0) || (existing->m_to_python == 0))
         {
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ converter::registry::insert(&extract, type_id<Pointee>(), &get_pytype);
+ converter::registry::insert(&wrap, type_id<Pointee*>(), &get_pytype);
+#else
             converter::registry::insert(&extract, type_id<Pointee>());
             converter::registry::insert(&wrap, type_id<Pointee*>());
+#endif
         }
     }
 
@@ -105,6 +110,9 @@
     };
     
     static PyTypeObject type_object;
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const *get_pytype(){return &type_object; }
+#endif
 };
 
 template <class Pointee>

Modified: trunk/boost/python/return_arg.hpp
==============================================================================
--- trunk/boost/python/return_arg.hpp (original)
+++ trunk/boost/python/return_arg.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -8,10 +8,15 @@
 # include <boost/python/detail/none.hpp>
 # include <boost/python/detail/value_arg.hpp>
 
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
+
 # include <boost/type_traits/add_reference.hpp>
 # include <boost/type_traits/add_const.hpp>
 
 # include <boost/mpl/int.hpp>
+# include <boost/mpl/at.hpp>
 
 # include <boost/static_assert.hpp>
 # include <boost/python/refcount.hpp>
@@ -44,6 +49,9 @@
               {
                   return none();
               }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ PyTypeObject const *get_pytype() const { return converter::expected_pytype_for_arg<T>::get_pytype() ; }
+#endif
           };
       };
   };
@@ -82,6 +90,12 @@
         Py_DECREF(result);
         return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
     }
+
+ template <class Sig>
+ struct extract_return_type : mpl::at_c<Sig, arg_pos>
+ {
+ };
+
 };
 
 template <

Modified: trunk/boost/python/to_python_converter.hpp
==============================================================================
--- trunk/boost/python/to_python_converter.hpp (original)
+++ trunk/boost/python/to_python_converter.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -9,13 +9,67 @@
 
 # include <boost/python/converter/registry.hpp>
 # include <boost/python/converter/as_to_python_function.hpp>
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
 # include <boost/python/type_id.hpp>
 
 namespace boost { namespace python {
 
-template <class T, class Conversion>
-struct to_python_converter
+#if 0 //get_pytype member detection
+namespace detail
 {
+ typedef char yes_type;
+ typedef struct {char a[2]; } no_type;
+ template<PyTypeObject const * (*f)()> struct test_get_pytype1 { };
+ template<PyTypeObject * (*f)()> struct test_get_pytype2 { };
+
+ template<class T> yes_type tester(test_get_pytype1<&T::get_pytype>*);
+
+ template<class T> yes_type tester(test_get_pytype2<&T::get_pytype>*);
+
+ template<class T> no_type tester(...);
+
+ template<class T>
+ struct test_get_pytype_base
+ {
+ BOOST_STATIC_CONSTANT(bool, value= (sizeof(detail::tester<T>(0)) == sizeof(yes_type)));
+ };
+
+ template<class T>
+ struct test_get_pytype : boost::mpl::bool_<test_get_pytype_base<T>::value>
+ {
+ };
+
+}
+#endif
+
+template < class T, class Conversion, bool has_get_pytype=false >
+struct to_python_converter
+{
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+#if 0 //defined _MSC_VER && _MSC_VER >=1310
+ //probably other compilers could come here as well
+ typedef typename detail::test_get_pytype<Conversion> HasGetPytype;
+#else
+ typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;
+#endif
+
+ static PyTypeObject const* get_pytype_1(boost::mpl::true_ *)
+ {
+ return Conversion::get_pytype();
+ }
+
+ static PyTypeObject const* get_pytype_1(boost::mpl::false_ *)
+ {
+ return 0;
+ }
+ static PyTypeObject const* get_pytype_impl()
+ {
+ return get_pytype_1((HasGetPytype*)0);
+ }
+#endif
+
     to_python_converter();
 };
 
@@ -23,18 +77,23 @@
 // implementation
 //
 
-template <class T, class Conversion>
-to_python_converter<T,Conversion>::to_python_converter()
+template <class T, class Conversion ,bool has_get_pytype>
+to_python_converter<T,Conversion, has_get_pytype>::to_python_converter()
 {
     typedef converter::as_to_python_function<
         T, Conversion
> normalized;
-
+
     converter::registry::insert(
         &normalized::convert
- , type_id<T>());
+ , type_id<T>()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &get_pytype_impl
+#endif
+ );
 }
 
 }} // namespace boost::python
 
 #endif // TO_PYTHON_CONVERTER_DWA200221_HPP
+

Modified: trunk/boost/python/to_python_indirect.hpp
==============================================================================
--- trunk/boost/python/to_python_indirect.hpp (original)
+++ trunk/boost/python/to_python_indirect.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -12,6 +12,10 @@
 
 # include <boost/python/detail/none.hpp>
 
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
+
 # include <boost/python/refcount.hpp>
 
 # include <boost/type_traits/is_pointer.hpp>
@@ -36,7 +40,13 @@
     {
         return this->execute(const_cast<U&>(ref), is_pointer<U>());
     }
-
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ inline PyTypeObject const*
+ get_pytype()const
+ {
+ return converter::registered_pytype<T>::get_pytype();
+ }
+#endif
  private:
     template <class U>
     inline PyObject* execute(U* ptr, mpl::true_) const

Modified: trunk/boost/python/to_python_value.hpp
==============================================================================
--- trunk/boost/python/to_python_value.hpp (original)
+++ trunk/boost/python/to_python_value.hpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -9,12 +9,12 @@
 
 # include <boost/python/refcount.hpp>
 # include <boost/python/tag.hpp>
+# include <boost/python/handle.hpp>
 
 # include <boost/python/converter/registry.hpp>
 # include <boost/python/converter/registered.hpp>
 # include <boost/python/converter/builtin_converters.hpp>
 # include <boost/python/converter/object_manager.hpp>
-# include <boost/python/converter/object_manager.hpp>
 # include <boost/python/converter/shared_ptr_to_python.hpp>
 
 # include <boost/python/detail/value_is_shared_ptr.hpp>
@@ -24,17 +24,57 @@
 
 # include <boost/mpl/if.hpp>
 # include <boost/mpl/or.hpp>
+# include <boost/type_traits/is_const.hpp>
 
 namespace boost { namespace python {
 
 namespace detail
 {
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+
+template <bool is_const_ref>
+struct object_manager_get_pytype
+{
+ template <class U>
+ static PyTypeObject const* get( U& (*p)() =0)
+ {
+ return converter::object_manager_traits<U>::get_pytype();
+ }
+};
+
+template <>
+struct object_manager_get_pytype<true>
+{
+ template <class U>
+ static PyTypeObject const* get( U const& (*p)() =0)
+ {
+ return converter::object_manager_traits<U>::get_pytype();
+ }
+};
+
+#endif
+
   template <class T>
   struct object_manager_to_python_value
   {
       typedef typename value_arg<T>::type argument_type;
     
       PyObject* operator()(argument_type) const;
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
+ typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
+ PyTypeObject const* get_pytype() const {
+ return get_pytype_aux((is_t_handle*)0);
+ }
+
+ inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
+
+ inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
+ {
+ return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
+ }
+
+#endif
 
       // This information helps make_getter() decide whether to try to
       // return an internal reference or not. I don't like it much,
@@ -49,6 +89,9 @@
       typedef typename value_arg<T>::type argument_type;
     
       PyObject* operator()(argument_type) const;
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
+#endif
 
       // This information helps make_getter() decide whether to try to
       // return an internal reference or not. I don't like it much,
@@ -62,11 +105,18 @@
       typedef typename value_arg<T>::type argument_type;
     
       PyObject* operator()(argument_type) const;
-
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ PyTypeObject const* get_pytype() const {return get_pytype((boost::type<T>*)0);}
+#endif
       // This information helps make_getter() decide whether to try to
       // return an internal reference or not. I don't like it much,
       // but it will have to serve for now.
       BOOST_STATIC_CONSTANT(bool, uses_registry = false);
+ private:
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ template <class U>
+ PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
+#endif
   };
 }
 

Modified: trunk/libs/python/build/Jamfile.v2
==============================================================================
--- trunk/libs/python/build/Jamfile.v2 (original)
+++ trunk/libs/python/build/Jamfile.v2 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -45,6 +45,7 @@
     wrapper.cpp
     import.cpp
     exec.cpp
+ object/function_doc_signature.cpp
     : # requirements
         <link>static:<define>BOOST_PYTHON_STATIC_LIB
         <define>BOOST_PYTHON_SOURCE

Modified: trunk/libs/python/doc/news.html
==============================================================================
--- trunk/libs/python/doc/news.html (original)
+++ trunk/libs/python/doc/news.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -32,7 +32,43 @@
   <hr>
 
   <dl class="page-index">
- <dt>Current CVS</dt>
+ <dt>Current SVN</dt>
+
+ <dd>
+ <ul>
+ <li>Pythonic signatures are now automatically appended to the
+ docstrings.
+
+ <li>Use <a href="v2/docstring_options.html"
+ ><code>docstring_options.hpp</code></a> header
+ control the content of docstrings.
+
+ <li>This new feature increases the size of the modules by about 14%.
+ If this is not acceptable it can be turned off by defining the macro
+ BOOST_PYTHON_NO_PY_SIGNATURES. Modules compiled with and without the macro
+ defined are compatible.
+ </li>
+ <li> If BOOST_PYTHON_NO_PY_SIGNATURES is undefined, this version defines the
+ macro BOOST_PYTHON_SUPPORTS_PY_SIGNATURES. This allows writing code that will compile
+ with older version of Boost.Python (see here).
+ </li>
+ <li>By defining BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE, and at a cost
+ of another 14% size increase, proper pythonic type is generated for the "self"
+ parameter of the __init__ methods.
+ </li>
+
+ <li> To support this new feature changes were made to the
+ to_python_converter.hpp,
+ default_call_policies,
+ ResultConverter,
+ CallPolicies and some others.
+ Efforts were made not to have interface breaking changes.
+ </li>
+
+ </ul>
+ </dd>
+
+ <dt>12 May 2007 - 1.34.0 release</dt>
 
     <dd>
       <ul>

Modified: trunk/libs/python/doc/v2/CallPolicies.html
==============================================================================
--- trunk/libs/python/doc/v2/CallPolicies.html (original)
+++ trunk/libs/python/doc/v2/CallPolicies.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -8,7 +8,7 @@
     <meta name="generator" content=
     "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <link rel="stylesheet" type="text/css" href=../../../../boost.css>
+ <link rel="stylesheet" type="text/css" href="../../../../boost.css">
 
     <title>Boost.Python - CallPolicies Concept</title>
   </head>
@@ -60,6 +60,7 @@
 
       <li><code>postcall</code> - Python argument tuple and result management
       after the wrapped object is invoked</li>
+ <li><code>extract_return_type</code> - metafunction for extracting the return type from a given signature type sequence</li>
     </ol>
 
     <h2><a name="composition"></a>CallPolicies Composition</h2>
@@ -132,7 +133,16 @@
         reference count must be decremented; if another existing object is
         returned, its reference count must be incremented.</td>
       </tr>
- </table>
+ <tr>
+ <td valign="top"><code>P::extract_return_type</code></td>
+
+ <td>A model of <a href=
+ "../../../doc/refmanual/metafunction.html">Metafunction</a>.</td>
+
+ <td>An MPL unary <a href=
+ "../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>
+ </tr>
+ </table>
     Models of CallPolicies are required to be <a href=
     "../../../utility/CopyConstructible.html">CopyConstructible</a>.
     <hr>

Modified: trunk/libs/python/doc/v2/ResultConverter.html
==============================================================================
--- trunk/libs/python/doc/v2/ResultConverter.html (original)
+++ trunk/libs/python/doc/v2/ResultConverter.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -1,10 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
 <!-- Copyright David Abrahams 2006. 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) -->
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" type="text/css" href=../../../../boost.css>
+<link rel="stylesheet" type="text/css" href="../../../../boost.css">
 <title>Boost.Python - ResultConverter Concept</title>
 </head>
 <body link="#0000ff" vlink="#800080">
@@ -24,10 +26,12 @@
 <dl class="page-index">
   <dt>Introduction</dt>
   <dt>Concept Requirements</dt>
- <dl class="page-index">
- <dt>ResultConverter Concept</dt>
- <dt>ResultConverterGenerator Concept</dt>
- </dl>
+ <dd>
+ <dl class="page-index">
+ <dt>ResultConverter Concept</dt>
+ <dt>ResultConverterGenerator Concept</dt>
+ </dl>
+ </dd>
 </dl>
 
 <h2><a name="introduction"></a>Introduction</h2>
@@ -79,6 +83,13 @@
     href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
     should return non-zero.</td>
   </tr>
+ <tr>
+ <td valign="top"><code>c.get_pytype()</code></td>
+ <td><code>PyTypeObject const*</code></td>
+ <td>A pointer to a Python Type object corresponding to result of the conversion,
+ or <code>0</code>. Used for documentation generation. If <code>0</code> is returned
+ the generated type in the documentation will be <b>object</b> .</td>
+ </tr>
 </table>
 
 <h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>

Modified: trunk/libs/python/doc/v2/configuration.html
==============================================================================
--- trunk/libs/python/doc/v2/configuration.html (original)
+++ trunk/libs/python/doc/v2/configuration.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -139,6 +139,41 @@
         compares <code>typeid(T).name()</code> instead of using and comparing
         the <code>std::type_info</code> objects directly.</td>
       </tr>
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_NO_PY_SIGNATURES</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined for a module no pythonic signatures are generated
+ for the docstrings of the module functions, and no python type is associated with any
+ of the converters registered by the module. This also reduces the binary size of the
+ module by about 14% (gcc compiled).<br>
+ If defined for the boost_python runtime library, the default for the
+ <code>docstring_options.enable_py_signatures()</code> is set to <code>false</code>.
+ </td>
+
+ </tr>
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code></td>
+
+ <td valign="top" align="center"><i>defined if <code>BOOST_PYTHON_NO_PY_SIGNATURES</code> is undefined</i></td>
+
+ <td valign="top">This macro is defined to enable a smooth transition from older Boost.Python versions
+ which do not support pythonic signatures. For example usage see
+ here.
+ </td>
+
+ </tr>
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined the python type of <code>__init__</code> method "self" parameters
+ is properly generated, otherwise <code><b>object</b></code> is used. It is undefined
+ by default because it increases the binary size of the module by about 14% (gcc compiled).</td>
+
+ </tr>
     </table>
     <hr>
 

Modified: trunk/libs/python/doc/v2/default_call_policies.html
==============================================================================
--- trunk/libs/python/doc/v2/default_call_policies.html (original)
+++ trunk/libs/python/doc/v2/default_call_policies.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -82,6 +82,7 @@
         static PyObject* postcall(PyObject*, PyObject* result);
         typedef <a href=
 "#default_result_converter-spec">default_result_converter</a> result_converter;
+ template &lt;class Sig&gt; struct extract_return_type : mpl::front&lt;Sig&gt;{};
     };
 }}
 </pre>
@@ -161,7 +162,7 @@
 
     <p>Revised
     <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
- 13 November, 2002
+ 11 June, 2007
   <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
 
 

Modified: trunk/libs/python/doc/v2/docstring_options.html
==============================================================================
--- trunk/libs/python/doc/v2/docstring_options.html (original)
+++ trunk/libs/python/doc/v2/docstring_options.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -103,6 +103,8 @@
 
           docstring_options(bool show_user_defined, bool show_signatures);
 
+ docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
+
           ~docstring_options();
 
           void
@@ -118,6 +120,18 @@
           enable_signatures();
 
           void
+ disable_py_signatures();
+
+ void
+ enable_py_signatures();
+
+ void
+ disable_cpp_signatures();
+
+ void
+ enable_cpp_signatures();
+
+ void
           disable_all();
 
           void
@@ -139,7 +153,7 @@
     object which controls the appearance of function and
     member-function docstrings defined in the code that follows. If
     <code>show_all</code> is <code>true</code>, both the
- user-defined docstrings and the automatically generated C++
+ user-defined docstrings and the automatically generated Python and C++
     signatures are shown. If <code>show_all</code> is
     <code>false</code> the <code>__doc__</code> attributes are
     <code>None</code>.</dt>
@@ -154,12 +168,29 @@
     member-function docstrings defined in the code that follows.
     Iff <code>show_user_defined</code> is <code>true</code>, the
     user-defined docstrings are shown. Iff
- <code>show_signatures</code> is <code>true</code>, C++
+ <code>show_signatures</code> is <code>true</code>, Python and C++
     signatures are automatically added. If both
     <code>show_user_defined</code> and <code>show_signatures</code>
     are <code>false</code>, the <code>__doc__</code> attributes are
     <code>None</code>.</dt>
   </dl>
+ <pre>
+docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Constructs a <code>docstring_options</code>
+ object which controls the appearance of function and
+ member-function docstrings defined in the code that follows.
+ Iff <code>show_user_defined</code> is <code>true</code>, the
+ user-defined docstrings are shown. Iff
+ <code>show_py_signatures</code> is <code>true</code>, Python
+ signatures are automatically added. Iff
+ <code>show_cpp_signatures</code> is <code>true</code>, C++
+ signatures are automatically added. If all parameters are
+ <code>false</code>, the <code>__doc__</code> attributes are
+ <code>None</code>.</dt>
+ </dl>
 
   <h4><a name="docstring_options-spec-dtors" id=
   "docstring_options-spec-dtors"></a>Class
@@ -186,6 +217,10 @@
 void enable_user_defined();
 void disable_signatures();
 void enable_signatures();
+void disable_py_signatures();
+void enable_py_signatures();
+void disable_cpp_signatures();
+void enable_cpp_signatures();
 void disable_all();
 void enable_all();
 </pre>
@@ -196,7 +231,7 @@
     <code>*_user_defined()</code> and <code>*_signatures()</code>
     member functions are provided for fine-grained control. The
     <code>*_all()</code> member functions are convenient shortcuts
- to manipulate both settings simultaneously.</dt>
+ to manipulate all settings simultaneously.</dt>
   </dl>
 
   <h2><a name="examples" id="examples"></a>Examples</h2>
@@ -219,7 +254,7 @@
   <pre>
 &gt;&gt;&gt; import demo
 &gt;&gt;&gt; print demo.foo.__doc__
-foo doc
+foo() -&gt; None : foo doc
 C++ signature:
     foo(void) -&gt; void
 </pre>If compiled with
@@ -253,21 +288,33 @@
     def("foo3", foo3, arg("f"), "foo3 doc");
     doc_options.enable_user_defined();
     def("foo4", foo4, arg("d"), "foo4 doc");
+ doc_options.enable_py_signatures();
+ def("foo5", foo4, arg("d"), "foo5 doc");
+ doc_options.disable_py_signatures();
+ doc_options.enable_cpp_signatures();
+ def("foo6", foo4, arg("d"), "foo6 doc");
 }
 </pre>Python code:
   <pre>
 &gt;&gt;&gt; import demo
 &gt;&gt;&gt; print demo.foo1.__doc__
-foo1 doc
+foo1( (int)i) -&gt; int : foo1 doc
 C++ signature:
     foo1(int i) -&gt; int
 &gt;&gt;&gt; print demo.foo2.__doc__
+foo2( (int)l) -&gt; int :
 C++ signature:
     foo2(long l) -&gt; int
 &gt;&gt;&gt; print demo.foo3.__doc__
 None
 &gt;&gt;&gt; print demo.foo4.__doc__
 foo4 doc
+&gt;&gt;&gt; print demo.foo5.__doc__
+foo5( (float)d) -&gt; int : foo5 doc
+&gt;&gt;&gt; print demo.foo6.__doc__
+foo6 doc
+C++ signature:
+ foo6(double d) -&gt; int
 </pre>
 
   <h4>Wrapping from multiple C++ scopes</h4>

Modified: trunk/libs/python/doc/v2/enum.html
==============================================================================
--- trunk/libs/python/doc/v2/enum.html (original)
+++ trunk/libs/python/doc/v2/enum.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -89,7 +89,7 @@
   template &lt;class T&gt;
   class enum_ : public object
   {
- enum_(char const* name);
+ enum_(char const* name, char const* doc = 0);
     enum_&lt;T&gt;&amp; value(char const* name, T);
     enum_&lt;T&gt;&amp; export_values();
   };
@@ -99,7 +99,7 @@
     <h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
     constructors</h4>
 <pre>
-enum_(char const* name);
+enum_(char const* name, char const* doc=0);
 </pre>
 
     <dl class="function-semantics">
@@ -131,7 +131,7 @@
 
       <dt><b>Effects:</b> adds an instance of the wrapped enumeration
       type with value <code>x</code> to the type's dictionary as the
- <code>name</code>d attribute</dt>.
+ <code>name</code>d attribute.</dt>
 
       <dt><b>Returns:</b> <code>*this</code></dt>
 
@@ -146,7 +146,7 @@
       <dt><b>Effects:</b> sets attributes in the current <a
         href="scope.html#scope-spec"><code>scope</code></a> with the
         same names and values as all enumeration values exposed so far
- by calling <code>value()</code></dt>.
+ by calling <code>value()</code>.</dt>
 
       <dt><b>Returns:</b> <code>*this</code></dt>
 

Added: trunk/libs/python/doc/v2/function_doc_signature.html
==============================================================================
--- (empty file)
+++ trunk/libs/python/doc/v2/function_doc_signature.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright Nikolay Mladenov 2007. 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) -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/doobject/function_doc_signature.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href=
+ "../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/object/function_doc_signature.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt>Introduction</dt>
+
+ <dt>Classes</dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#function_doc_signature_generator-spec">Class
+ <code>function_doc_signature_generator</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#function_doc_signature_generator-spec-synopsis">Class
+ <code>function_doc_signature_generator</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt>Examples</dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id=
+ "introduction"></a>Introduction</h2>
+
+ <p>Boost.Python supports docstrings with automatic
+ appending of Pythonic and C++ signatures. This feature is implemented
+ by <code>class function_doc_signature_generator</code>
+ The class uses all of the overloads, supplied arg names and default values, as well as
+ the user-defined docstrings, to generate documentation for a given function.</p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="function_doc_signature_generator-spec" id=
+ "function_doc_signature_generator-spec"></a>Class
+ <code>function_doc_signature_generator</code></h3>
+
+ <p>
+ The class has only one public function which returns a list of strings documenting the
+ overloads of a function.
+ </p>
+
+ <h4><a name="function_doc_signature_generator-spec-synopsis" id=
+ "function_doc_signature_generator-spec-synopsis"></a>Class
+ <code>function_doc_signature_generator</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace objects {
+
+ class function_doc_signature_generator
+ {
+ public:
+ static list function_doc_signatures(function const *f);
+ };
+
+}}}
+</pre>
+
+
+ <h2><a name="examples" id="examples"></a>Examples</h2>
+
+ <h4>Docstrings generated with <code>function_doc_signature_generator</code></h4>
+ <pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/args.hpp&gt;
+#include &lt;boost/python/tuple.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/overloads.hpp&gt;
+#include &lt;boost/python/raw_function.hpp&gt;
+
+using namespace boost::python;
+
+tuple f(int x = 1, double y = 4.25, char const* z = "wow")
+{
+ return make_tuple(x, y, z);
+}
+
+BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
+
+
+struct X
+{
+ tuple f(int x = 1, double y = 4.25, char const* z = "wow")
+ {
+ return make_tuple(x, y, z);
+ }
+};
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
+
+tuple raw_func(tuple args, dict kw)
+{
+ return make_tuple(args, kw);
+}
+
+BOOST_PYTHON_MODULE(args_ext)
+{
+ def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
+ , "This is f's docstring"
+ );
+
+ def("raw", raw_function(raw_func));
+
+ def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
+
+
+ class_&lt;X&gt;("X", "This is X's docstring", init&lt;&gt;(args("self")))
+ .def("f", &amp;X::f
+ , "This is X.f's docstring"
+ , args("self","x", "y", "z"))
+
+ ;
+
+}
+
+</pre>
+Python code:
+ <pre>
+&gt;&gt;&gt; import args_ext
+&gt;&gt;&gt; help(args_ext)
+Help on module args_ext:
+
+NAME
+ args_ext
+
+FILE
+ args_ext.pyd
+
+CLASSES
+ Boost.Python.instance(__builtin__.object)
+ X
+
+ class X(Boost.Python.instance)
+ | This is X's docstring
+ |
+ | Method resolution order:
+ | X
+ | Boost.Python.instance
+ | __builtin__.object
+ |
+ | Methods defined here:
+ |
+ | __init__(...)
+ | __init__( (object)self) -> None :
+ | C++ signature:
+ | void __init__(struct _object *)
+ |
+ | f(...)
+ | f( (X)self, (int)x, (float)y, (str)z) -> tuple : This is X.f's docstring
+ | C++ signature:
+ | class boost::python::tuple f(struct X {lvalue},int,double,char const *)
+ |
+ | .................
+ |
+FUNCTIONS
+ f(...)
+ f([ (int)x=1 [, (float)y=4.25 [, (str)z='wow']]]) -> tuple : This is f's docstring
+ C++ signature:
+ class boost::python::tuple f([ int=1 [,double=4.25 [,char const *='wow']]])
+
+ f1(...)
+ f1([ (int)x [, (float)y [, (str)z]]]) -> tuple : f1's docstring
+ C++ signature:
+ class boost::python::tuple f1([ int [,double [,char const *]]])
+
+ raw(...)
+ object raw(tuple args, dict kwds) :
+ C++ signature:
+ object raw(tuple args, dict kwds)
+
+
+</pre>
+
+ <p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
+</body>
+</html>

Added: trunk/libs/python/doc/v2/pytype_function.html
==============================================================================
--- (empty file)
+++ trunk/libs/python/doc/v2/pytype_function.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,370 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright Nikolay Mladenov 2007. 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) -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/doobject/pytype_function.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href=
+ "../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/converter/pytype_function.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt>Introduction</dt>
+
+ <dt>Classes</dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#wrap_pytype-spec">Class
+ <code>wrap_pytype</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#wrap_pytype-spec-synopsis">Class
+ <code>wrap_pytype</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#registered_pytype-spec">Class
+ <code>registered_pytype</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#registered_pytype-spec-synopsis">Class
+ <code>registered_pytype</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#expected_from_python_type-spec">Class
+ <code>expected_from_python_type</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#expected_from_python_type-spec-synopsis">Class
+ <code>expected_from_python_type</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_target_type-spec">Class
+ <code>to_python_target_type</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_target_type-spec-synopsis">Class
+ <code>to_python_target_type</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt>Examples</dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id=
+ "introduction"></a>Introduction</h2>
+
+ <p>To support Pythonic signatures the converters should supply a <code>get_pytype</code> function
+ returning a pointer to the associated <code>PyTypeObject</code>. See for example
+ ResultConverter or
+ to_python_converter.
+ The classes in this header file are meant to be used when implmenting <code>get_pytype</code>.
+ There are also <code>_direct</code> versions of the templates of <code>class T</code> which
+ should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
+ </p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="wrap_pytype-spec" id=
+ "wrap_pytype-spec"></a>Class
+ <code>wrap_pytype</code></h3>
+
+ <p>
+ This template generates a static <code>get_pytype</code> member returning the template parameter.
+ </p>
+
+ <h4><a name="wrap_pytype-spec-synopsis" id=
+ "wrap_pytype-spec-synopsis"></a>Class
+ <code>wrap_pytype</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; PyTypeObject const *pytype &gt;
+ class wrap_pytype
+ {
+ public:
+ static PyTypeObject const *get_pytype(){return pytype; }
+ };
+
+}}}
+</pre>
+
+
+ <h3><a name="registered_pytype-spec" id=
+ "registered_pytype-spec"></a>Class
+ <code>registered_pytype</code></h3>
+
+ <p>
+ This template should be used with template parameters which are (possibly decorated)
+ types exported to python using class_.
+ The generated a static <code>get_pytype</code> member
+ returns the corresponding python type.
+ </p>
+
+ <h4><a name="registered_pytype-spec-synopsis" id=
+ "registered_pytype-spec-synopsis"></a>Class
+ <code>registered_pytype</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; class T &gt;
+ class registered_pytype
+ {
+ public:
+ static PyTypeObject const *get_pytype();
+ };
+
+}}}
+</pre>
+
+
+ <h3><a name="expected_from_python_type-spec" id=
+ "expected_from_python_type-spec"></a>Class
+ <code>expected_from_python_type</code></h3>
+
+ <p>
+ This template generates a static <code>get_pytype</code> member which inspects the registered
+ <code>from_python</code> converters for the type <code>T</code> and returns a matching python type.
+ </p>
+
+ <h4><a name="expected_from_python_type-spec-synopsis" id=
+ "expected_from_python_type-spec-synopsis"></a>Class
+ <code>expected_from_python_type</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; class T &gt;
+ class expected_from_python_type
+ {
+ public:
+ static PyTypeObject const *get_pytype();
+ };
+
+}}}
+</pre>
+
+
+ <h3><a name="to_python_target_type-spec" id=
+ "to_python_target_type-spec"></a>Class
+ <code>to_python_target_type</code></h3>
+
+ <p>
+ This template generates a static <code>get_pytype</code> member returning the
+ python type to which T can be converted.
+ </p>
+
+ <h4><a name="to_python_target_type-spec-synopsis" id=
+ "to_python_target_type-spec-synopsis"></a>Class
+ <code>to_python_target_type</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; class T &gt;
+ class to_python_target_type
+ {
+ public:
+ static PyTypeObject const *get_pytype();
+ };
+
+}}}
+</pre>
+
+
+ <h2><a name="examples" id="examples"></a>Examples</h2>
+
+ This example presumes that someone has implemented the standard <a href=
+ "http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
+ module</a> from the Python documentation, and placed the corresponding
+ declarations in <code>"noddy.h"</code>. Because
+ <code>noddy_NoddyObject</code> is the ultimate trivial extension type,
+ the example is a bit contrived: it wraps a function for which all
+ information is contained in the <i>type</i> of its return value.
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/reference.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include "noddy.h"
+
+struct tag {};
+tag make_tag() { return tag(); }
+
+using namespace boost::python;
+
+struct tag_to_noddy
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
+: wrap_pytype<&amp;noddy_NoddyType> //inherits get_pytype from wrap_pytype
+#endif
+{
+ static PyObject* convert(tag const&amp; x)
+ {
+ return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
+ }
+};
+
+BOOST_PYTHON_MODULE(to_python_converter)
+{
+ def("make_tag", make_tag);
+ to_python_converter&lt;tag, tag_to_noddy
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
+ , true
+#endif
+ &gt;(); //"true" because tag_to_noddy has member get_pytype
+}
+</pre>
+
+
+<p>The following example registers to and from python converters using the templates
+<code>expected_from_python_type</code> and <code>to_pyhton_target_type</code>.
+</p>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/extract.hpp&gt;
+#include &lt;boost/python/to_python_converter.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+
+using namespace boost::python;
+
+struct A
+{
+};
+
+struct B
+{
+ A a;
+ B(const A& a_):a(a_){}
+};
+
+// Converter from A to python int
+struct BToPython
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
+ : converter::to_python_target_type&lt;A&gt; //inherits get_pytype
+#endif
+{
+ static PyObject* convert(const B& b)
+ {
+ return incref(object(b.a).ptr());
+ }
+};
+
+// Conversion from python int to A
+struct BFromPython
+{
+ BFromPython()
+ {
+ boost::python::converter::registry::push_back
+ ( &amp;convertible
+ , &amp;construct
+ , type_id&lt; B &gt;()
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
+ , &amp;converter::expected_from_python_type&lt;A&gt;::get_pytype//convertible to A can be converted to B
+#endif
+ );
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ extract&lt;const A&&gt; ex(obj_ptr);
+ if (!ex.check()) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ converter::rvalue_from_python_stage1_data* data)
+ {
+ void* storage = (
+ (converter::rvalue_from_python_storage&lt; B &gt;*)data)-&gt; storage.bytes;
+
+ extract&lt;const A&&gt; ex(obj_ptr);
+ new (storage) B(ex());
+ data->convertible = storage;
+ }
+};
+
+
+B func(const B& b) { return b ; }
+
+BOOST_PYTHON_MODULE(pytype_function_ext)
+{
+ to_python_converter&lt; B , BToPython
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
+ ,true
+#endif
+ &gt;(); //has get_pytype
+ BFromPython();
+
+ class_&lt;A&gt;("A") ;
+
+ def("func", &amp;func);
+
+}
+
+
+
+&gt;&gt;&gt; from pytype_function_ext import *
+&gt;&gt;&gt; print func.__doc__
+func( (A)arg1) -> A :
+ C++ signature:
+ struct B func(struct B)
+</pre>
+
+
+ <p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
+</body>
+</html>

Modified: trunk/libs/python/doc/v2/reference.html
==============================================================================
--- trunk/libs/python/doc/v2/reference.html (original)
+++ trunk/libs/python/doc/v2/reference.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -610,6 +610,66 @@
       </dd>
 
       <dd>
+ <a name="function_documentation"></a>
+
+ <h3>Function documentation</h3>
+
+ <dl class="index">
+ <dt><a href=
+ "function_doc_signature.html">function_doc_signature.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "function_doc_signature.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "function_doc_signature.html#function_doc_signature_generator-spec">function_doc_signature_generator</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html">pytype_function.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#wrap_pytype-spec">wrap_pytype</a></dt>
+
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#expected_from_python_type-spec">expected_from_python_type</a></dt>
+
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#to_python_target_type-spec">to_python_target_type</a></dt>
+
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#registered_pytype-spec">registered_pytype</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
         <a name="models_of_call_policies"></a>
 
         <h3>Models of CallPolicies</h3>

Modified: trunk/libs/python/doc/v2/return_arg.html
==============================================================================
--- trunk/libs/python/doc/v2/return_arg.html (original)
+++ trunk/libs/python/doc/v2/return_arg.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -125,6 +125,8 @@
    {
       static PyObject* postcall(PyObject*, PyObject* result);
       struct result_converter{ template &lt;class T&gt; struct apply; };
+ template &lt;class Sig&gt; struct extract_return_type : mpl::at_c&lt;Sig, arg_pos&gt;{};
+
    };
 }}
 </pre>

Modified: trunk/libs/python/doc/v2/to_python_converter.html
==============================================================================
--- trunk/libs/python/doc/v2/to_python_converter.html (original)
+++ trunk/libs/python/doc/v2/to_python_converter.html 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -108,6 +108,23 @@
         <td>A class type whose static member function <code>convert</code>
         does the real work of the conversion.</td>
       </tr>
+ <tr>
+ <td><code>bool has_get_pytype = false</code></td>
+
+ <td>
+ <code>PyTypeObject const * p = Conversion::get_pytype() </code>.</td>
+
+ <td><b>Optional member</b> - if <code>Conversion</code> has <code>get_pytype</code> member supply
+ <code>true</code> for this parameters.
+ If present <code>get_pytype</code> is used to document the return type
+ of functions using this conversion. The <code>get_pytype</code> may be implemented
+ using the classes and functions
+ from pytype_function.hpp
+ <b>NOTE :</b> For backward compatibility this parameter may be passed after
+ checking if <code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code> is defined (see
+ here).
+ </td>
+ </tr>
     </table>
 
     <h4><a name="to_python_converter-spec-synopsis"></a>Class template
@@ -115,7 +132,7 @@
 <pre>
 namespace boost { namespace python
 {
- template &lt;class T, class Conversion&gt;
+ template &lt;class T, class Conversion, bool convertion_has_get_pytype_member=false&gt;
   struct to_python_converter
   {
       to_python_converter();
@@ -160,12 +177,16 @@
     {
         return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
     }
+ static PyTypeObject const* get_pytype()
+ {
+ return &amp;noddy_NoddyType;
+ }
 };
 
 BOOST_PYTHON_MODULE(to_python_converter)
 {
     def("make_tag", make_tag);
- to_python_converter&lt;tag, tag_to_noddy&gt;();
+ to_python_converter&lt;tag, tag_to_noddy, true&gt;(); //"true" because tag_to_noddy has member get_pytype
 }
 </pre>
 
@@ -195,7 +216,7 @@
 
     <p>Revised
     <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
- 13 November, 2002
+ 11 June, 2007
   <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
     </p>
 

Modified: trunk/libs/python/example/std_pair.cpp
==============================================================================
--- trunk/libs/python/example/std_pair.cpp (original)
+++ trunk/libs/python/example/std_pair.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -18,6 +18,7 @@
       return boost::python::incref(
         boost::python::make_tuple(p.first, p.second).ptr());
     }
+ static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
   };
 
   // Helper for convenience.
@@ -28,7 +29,9 @@
     {
       boost::python::to_python_converter<
         std::pair<T1, T2>,
- std_pair_to_tuple<T1, T2> >();
+ std_pair_to_tuple<T1, T2>,
+ true //std_pair_to_tuple has get_pytype
+ >();
     }
   };
 

Modified: trunk/libs/python/src/converter/builtin_converters.cpp
==============================================================================
--- trunk/libs/python/src/converter/builtin_converters.cpp (original)
+++ trunk/libs/python/src/converter/builtin_converters.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -16,6 +16,7 @@
 #include <boost/python/converter/registry.hpp>
 #include <boost/python/converter/registrations.hpp>
 #include <boost/python/converter/shared_ptr_deleter.hpp>
+#include <boost/python/converter/pytype_function.hpp>
 
 #include <boost/cast.hpp>
 #include <string>
@@ -56,6 +57,7 @@
               &slot_rvalue_from_python<T,SlotPolicy>::convertible
               , &slot_rvalue_from_python<T,SlotPolicy>::construct
               , type_id<T>()
+ , &SlotPolicy::get_pytype
               );
       }
       
@@ -100,6 +102,7 @@
           return (PyInt_Check(obj) || PyLong_Check(obj))
               ? &number_methods->nb_int : 0;
       }
+ static PyTypeObject const* get_pytype() { return &PyInt_Type;}
   };
 
   template <class T>
@@ -135,6 +138,7 @@
           return (PyInt_Check(obj) || PyLong_Check(obj))
               ? &py_object_identity : 0;
       }
+ static PyTypeObject const* get_pytype() { return &PyInt_Type;}
   };
 
   template <class T>
@@ -173,6 +177,7 @@
           else
               return 0;
       }
+ static PyTypeObject const* get_pytype() { return &PyInt_Type;}
   };
   
   struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
@@ -228,6 +233,15 @@
       {
           return PyObject_IsTrue(intermediate);
       }
+
+ static PyTypeObject const* get_pytype()
+ {
+#if PY_VERSION_HEX >= 0x02030000
+ return &PyBool_Type;
+#else
+ return &PyInt_Type;
+#endif
+ }
   };
 
   // A SlotPolicy for extracting floating types from Python objects.
@@ -259,6 +273,7 @@
               return PyFloat_AS_DOUBLE(intermediate);
           }
       }
+ static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
   };
 
   // A SlotPolicy for extracting C++ strings from Python objects.
@@ -276,6 +291,7 @@
       {
           return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
       }
+ static PyTypeObject const* get_pytype() { return &PyString_Type;}
   };
 
 #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
@@ -316,6 +332,7 @@
           }
           return result;
       }
+ static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
   };
 #endif
 
@@ -346,6 +363,7 @@
               return PyFloat_AS_DOUBLE(intermediate);
           }
       }
+ static PyTypeObject const* get_pytype() { return &PyComplex_Type;}
   };
 }
 
@@ -411,7 +429,7 @@
     slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
     
     // Add an lvalue converter for char which gets us char const*
- registry::insert(convert_to_cstring,type_id<char>());
+ registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
 
     // Register by-value converters to std::string, std::wstring
 #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)

Modified: trunk/libs/python/src/converter/registry.cpp
==============================================================================
--- trunk/libs/python/src/converter/registry.cpp (original)
+++ trunk/libs/python/src/converter/registry.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -20,6 +20,35 @@
 #endif
 
 namespace boost { namespace python { namespace converter {
+BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
+{
+ if (this->m_class_object != 0)
+ return this->m_class_object;
+
+ std::set<PyTypeObject const*> pool;
+
+ for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
+ if(r->expected_pytype)
+ pool.insert(r->expected_pytype());
+
+ //for now I skip the search for common base
+ if (pool.size()==1)
+ return *pool.begin();
+
+ return 0;
+
+}
+
+BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
+{
+ if (this->m_class_object != 0)
+ return this->m_class_object;
+
+ if (this->m_to_python_target_type != 0)
+ return this->m_to_python_target_type();
+
+ return 0;
+}
 
 BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
 {
@@ -168,15 +197,15 @@
 
 namespace registry
 {
- void insert(to_python_function_t f, type_info source_t)
+ void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
   {
 # ifdef BOOST_PYTHON_TRACE_REGISTRY
       std::cout << "inserting to_python " << source_t << "\n";
 # endif
- to_python_function_t& slot = get(source_t)->m_to_python;
+ entry* slot = get(source_t);
       
- assert(slot == 0); // we have a problem otherwise
- if (slot != 0)
+ assert(slot->m_to_python == 0); // we have a problem otherwise
+ if (slot->m_to_python != 0)
       {
           std::string msg = (
               std::string("to-Python converter for ")
@@ -189,11 +218,12 @@
               throw_error_already_set();
           }
       }
- slot = f;
+ slot->m_to_python = f;
+ slot->m_to_python_target_type = to_python_target_type;
   }
 
   // Insert an lvalue from_python converter
- void insert(convertible_function convert, type_info key)
+ void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
   {
 # ifdef BOOST_PYTHON_TRACE_REGISTRY
       std::cout << "inserting lvalue from_python " << key << "\n";
@@ -204,13 +234,14 @@
       registration->next = found->lvalue_chain;
       found->lvalue_chain = registration;
       
- insert(convert, 0, key);
+ insert(convert, 0, key,exp_pytype);
   }
 
   // Insert an rvalue from_python converter
   void insert(void* (*convertible)(PyObject*)
               , constructor_function construct
- , type_info key)
+ , type_info key
+ , PyTypeObject const* (*exp_pytype)())
   {
 # ifdef BOOST_PYTHON_TRACE_REGISTRY
       std::cout << "inserting rvalue from_python " << key << "\n";
@@ -219,6 +250,7 @@
       rvalue_from_python_chain *registration = new rvalue_from_python_chain;
       registration->convertible = convertible;
       registration->construct = construct;
+ registration->expected_pytype = exp_pytype;
       registration->next = found->rvalue_chain;
       found->rvalue_chain = registration;
   }
@@ -226,7 +258,8 @@
   // Insert an rvalue from_python converter
   void push_back(void* (*convertible)(PyObject*)
               , constructor_function construct
- , type_info key)
+ , type_info key
+ , PyTypeObject const* (*exp_pytype)())
   {
 # ifdef BOOST_PYTHON_TRACE_REGISTRY
       std::cout << "push_back rvalue from_python " << key << "\n";
@@ -238,6 +271,7 @@
       rvalue_from_python_chain *registration = new rvalue_from_python_chain;
       registration->convertible = convertible;
       registration->construct = construct;
+ registration->expected_pytype = exp_pytype;
       registration->next = 0;
       *found = registration;
   }

Modified: trunk/libs/python/src/dict.cpp
==============================================================================
--- trunk/libs/python/src/dict.cpp (original)
+++ trunk/libs/python/src/dict.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -171,4 +171,14 @@
     }
 }
 
+static struct register_dict_pytype_ptr
+{
+ register_dict_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::dict>())
+ ).m_class_object = &PyDict_Type;
+ }
+}register_dict_pytype_ptr_;
+
 }}} // namespace boost::python

Modified: trunk/libs/python/src/list.cpp
==============================================================================
--- trunk/libs/python/src/list.cpp (original)
+++ trunk/libs/python/src/list.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -137,4 +137,14 @@
     return result;
 }
 
+static struct register_list_pytype_ptr
+{
+ register_list_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::list>())
+ ).m_class_object = &PyList_Type;
+ }
+}register_list_pytype_ptr_;
+
 }}} // namespace boost::python

Modified: trunk/libs/python/src/object/enum.cpp
==============================================================================
--- trunk/libs/python/src/object/enum.cpp (original)
+++ trunk/libs/python/src/object/enum.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -121,7 +121,7 @@
 
 namespace
 {
- object new_enum_type(char const* name)
+ object new_enum_type(char const* name, char const *doc)
   {
       if (enum_type_object.tp_dict == 0)
       {
@@ -143,6 +143,8 @@
       object module_name = module_prefix();
       if (module_name)
          d["__module__"] = module_name;
+ if (doc)
+ d["__doc__"] = doc;
       
       object result = (object(metatype))(name, make_tuple(base), d);
       
@@ -158,8 +160,9 @@
     , converter::convertible_function convertible
     , converter::constructor_function construct
     , type_info id
+ , char const *doc
     )
- : object(new_enum_type(name))
+ : object(new_enum_type(name, doc))
 {
     converter::registration& converters
         = const_cast<converter::registration&>(

Modified: trunk/libs/python/src/object/function.cpp
==============================================================================
--- trunk/libs/python/src/object/function.cpp (original)
+++ trunk/libs/python/src/object/function.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -6,6 +6,7 @@
 #include <boost/python/docstring_options.hpp>
 #include <boost/python/object/function_object.hpp>
 #include <boost/python/object/function_handle.hpp>
+#include <boost/python/object/function_doc_signature.hpp>
 #include <boost/python/errors.hpp>
 #include <boost/python/str.hpp>
 #include <boost/python/object_attributes.hpp>
@@ -17,6 +18,7 @@
 #include <boost/python/ssize_t.hpp>
 
 #include <boost/python/detail/signature.hpp>
+#include <boost/python/detail/none.hpp>
 #include <boost/mpl/vector/vector10.hpp>
 
 #include <boost/bind.hpp>
@@ -30,7 +32,12 @@
 
 namespace boost { namespace python {
   volatile bool docstring_options::show_user_defined_ = true;
- volatile bool docstring_options::show_signatures_ = true;
+ volatile bool docstring_options::show_cpp_signatures_ = true;
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ volatile bool docstring_options::show_py_signatures_ = true;
+#else
+ volatile bool docstring_options::show_py_signatures_ = false;
+#endif
 }}
 
 namespace boost { namespace python { namespace objects {
@@ -411,6 +418,12 @@
     add_to_namespace(name_space, name_, attribute, 0);
 }
 
+namespace detail
+{
+ extern char py_signature_tag[];
+ extern char cpp_signature_tag[];
+}
+
 void function::add_to_namespace(
     object const& name_space, char const* name_, object const& attribute, char const* doc)
 {
@@ -487,6 +500,7 @@
         throw_error_already_set();
 
     object mutable_attribute(attribute);
+/*
     if (doc != 0 && docstring_options::show_user_defined_)
     {
         // Accumulate documentation
@@ -517,6 +531,28 @@
         mutable_attribute.attr("__doc__") += str("\n ").join(make_tuple(
           "C++ signature:", f->signature(true)));
     }
+ */
+ str _doc;
+
+ if (docstring_options::show_py_signatures_)
+ {
+ _doc += str(reinterpret_cast<const char*>(detail::py_signature_tag));
+ }
+ if (doc != 0 && docstring_options::show_user_defined_)
+ _doc += doc;
+
+ if (docstring_options::show_cpp_signatures_)
+ {
+ if(len(_doc))
+ _doc += "\n "+str(reinterpret_cast<const char*>(detail::cpp_signature_tag));
+ else
+ _doc += " "+str(reinterpret_cast<const char*>(detail::cpp_signature_tag));
+ }
+ if(_doc)
+ {
+ object mutable_attribute(attribute);
+ mutable_attribute.attr("__doc__")= _doc;
+ }
 }
 
 BOOST_PYTHON_DECL void add_to_namespace(
@@ -591,7 +627,10 @@
     static PyObject* function_get_doc(PyObject* op, void*)
     {
         function* f = downcast<function>(op);
- return python::incref(f->doc().ptr());
+ list signatures = function_doc_signature_generator::function_doc_signatures(f);
+ if(!signatures) return python::detail::none();
+ signatures.reverse();
+ return python::incref( str("\n ").join(signatures).ptr());
     }
     
     static int function_set_doc(PyObject* op, PyObject* doc, void*)

Added: trunk/libs/python/src/object/function_doc_signature.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/python/src/object/function_doc_signature.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,314 @@
+// Copyright Nikolay Mladenov 2007.
+// 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/converter/registrations.hpp>
+#include <boost/python/object/function_doc_signature.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/str.hpp>
+#include <boost/python/args.hpp>
+#include <boost/python/tuple.hpp>
+
+#include <boost/python/detail/signature.hpp>
+
+
+#include <vector>
+
+namespace boost { namespace python { namespace objects {
+
+ bool function_doc_signature_generator::arity_cmp( function const *f1, function const *f2 )
+ {
+ return f1->m_fn.max_arity() < f2->m_fn.max_arity();
+ }
+
+ bool function_doc_signature_generator::are_seq_overloads( function const *f1, function const *f2 , bool check_docs)
+ {
+ py_function const & impl1 = f1->m_fn;
+ py_function const & impl2 = f2->m_fn;
+
+ //the number of parameters differs by 1
+ if (impl2.max_arity()-impl1.max_arity() != 1)
+ return false;
+
+ // if check docs then f1 shold not have docstring or have the same docstring as f2
+ if (check_docs && f2->doc() != f1->doc() && f1->doc())
+ return false;
+
+ python::detail::signature_element const* s1 = impl1.signature();
+ python::detail::signature_element const* s2 = impl2.signature();
+
+ unsigned size = impl1.max_arity()+1;
+
+ for (unsigned i = 0; i != size; ++i)
+ {
+ //check if the argument types are the same
+ if (s1[i].basename != s2[i].basename)
+ return false;
+
+ //return type
+ if (!i) continue;
+
+ //check if the argument default values are the same
+ bool f1_has_names = bool(f1->m_arg_names);
+ bool f2_has_names = bool(f2->m_arg_names);
+ if ( f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1]
+ || f1_has_names && !f2_has_names
+ || !f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object()
+ )
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<function const*> function_doc_signature_generator::flatten(function const *f)
+ {
+ object name = f->name();
+
+ std::vector<function const*> res;
+
+ while (f) {
+
+ //this if takes out the not_implemented_function
+ if (f->name() == name)
+ res.push_back(f);
+
+ f=f->m_overloads.get();
+ }
+
+ //std::sort(res.begin(),res.end(), &arity_cmp);
+
+ return res;
+ }
+ std::vector<function const*> function_doc_signature_generator::split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change)
+ {
+ std::vector<function const*> res;
+
+ std::vector<function const*>::const_iterator fi = funcs.begin();
+
+ function const * last = *fi;
+
+ while (++fi != funcs.end()){
+
+ //check if fi starts a new chain of overloads
+ if (!are_seq_overloads( last, *fi, split_on_doc_change ))
+ res.push_back(last);
+
+ last = *fi;
+ }
+
+ if (last)
+ res.push_back(last);
+
+ return res;
+ }
+
+ str function_doc_signature_generator::raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
+ {
+ str res("object");
+
+ res = str("%s %s(%s)" % make_tuple( res, f->m_name, str("tuple args, dict kwds")) );
+
+ return res;
+ }
+
+ const char * function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
+ {
+ if (s.basename==std::string("void")){
+ static const char * none = "None";
+ return none;
+ }
+
+ PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
+ if ( py_type )
+ return py_type->tp_name;
+ else{
+ static const char * object = "object";
+ return object;
+ }
+ }
+
+ str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
+ {
+ str param;
+
+ python::detail::signature_element const * s = f.signature();
+ if (cpp_types)
+ {
+ if(!n)
+ s = &f.get_return_type();
+ if (s[n].basename == 0)
+ {
+ return str("...");
+ }
+
+ param = str(s[n].basename);
+
+ if (s[n].lvalue)
+ param += " {lvalue}";
+
+ }
+ else
+ {
+ if (n) //we are processing an argument and trying to come up with a name for it
+ {
+ object kv;
+ if ( arg_names && (kv = arg_names[n-1]) )
+ param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
+ else
+ param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
+ }
+ else //we are processing the return type
+ param = py_type_str(f.get_return_type());
+ }
+
+ //an argument - check for default value and append it
+ if(n && arg_names)
+ {
+ object kv(arg_names[n-1]);
+ if (kv && len(kv) == 2)
+ {
+ param = str("%s=%r" % make_tuple(param, kv[1]));
+ }
+ }
+ return param;
+ }
+
+ str function_doc_signature_generator::pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
+ {
+ py_function
+ const& impl = f->m_fn;
+ ;
+
+
+ unsigned arity = impl.max_arity();
+
+ if(arity == unsigned(-1))// is this the proper raw function test?
+ {
+ return raw_function_pretty_signature(f,n_overloads,cpp_types);
+ }
+
+ list formal_params;
+
+ size_t n_extra_default_args=0;
+
+ for (unsigned n = 0; n <= arity; ++n)
+ {
+ str param;
+
+ formal_params.append(
+ parameter_string(impl, n, f->m_arg_names, cpp_types)
+ );
+
+ // find all the arguments with default values preceeding the arity-n_overloads
+ if (n && f->m_arg_names)
+ {
+ object kv(f->m_arg_names[n-1]);
+
+ if (kv && len(kv) == 2)
+ {
+ //default argument preceeding the arity-n_overloads
+ if( n <= arity-n_overloads)
+ ++n_extra_default_args;
+ }
+ else
+ //argument without default, preceeding the arity-n_overloads
+ if( n <= arity-n_overloads)
+ n_extra_default_args = 0;
+ }
+ }
+
+ n_overloads+=n_extra_default_args;
+
+ if (!arity && cpp_types)
+ formal_params.append("void");
+
+ str ret_type (formal_params.pop(0));
+ if (cpp_types )
+ {
+ return str(
+ "%s %s(%s%s%s%s)"
+ % make_tuple
+ ( ret_type
+ , f->m_name
+ , str(",").join(formal_params.slice(0,arity-n_overloads))
+ , n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
+ , str(" [,").join(formal_params.slice(arity-n_overloads,arity))
+ , std::string(n_overloads,']')
+ ));
+ }else{
+ return str(
+ "%s(%s%s%s%s) -> %s"
+ % make_tuple
+ ( f->m_name
+ , str(",").join(formal_params.slice(0,arity-n_overloads))
+ , n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
+ , str(" [,").join(formal_params.slice(arity-n_overloads,arity))
+ , std::string(n_overloads,']')
+ , ret_type
+ ));
+ }
+
+ return str(
+ "%s %s(%s%s%s%s) %s"
+ % make_tuple
+ ( cpp_types?ret_type:str("")
+ , f->m_name
+ , str(",").join(formal_params.slice(0,arity-n_overloads))
+ , n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
+ , str(" [,").join(formal_params.slice(arity-n_overloads,arity))
+ , std::string(n_overloads,']')
+ , cpp_types?str(""):ret_type
+ ));
+
+ }
+
+ namespace detail {
+ char py_signature_tag[] = "PY signature : ";
+ char cpp_signature_tag[] = "C++ signature:";
+ }
+
+ list function_doc_signature_generator::function_doc_signatures( function const * f)
+ {
+ list signatures;
+ std::vector<function const*> funcs = flatten( f);
+ std::vector<function const*> split_funcs = split_seq_overloads( funcs, true);
+ std::vector<function const*>::const_iterator sfi=split_funcs.begin(), fi;
+ size_t n_overloads=0;
+ for (fi=funcs.begin(); fi!=funcs.end(); ++fi)
+ {
+ if(*sfi == *fi){
+ if((*fi)->doc()){
+ str func_doc = str((*fi)->doc());
+ int doc_len = len(func_doc);
+ bool show_py_signature = doc_len >=int(sizeof(detail::py_signature_tag)/sizeof(char)-1)
+ && str(detail::py_signature_tag)==func_doc.slice(0, int(sizeof(detail::py_signature_tag)/sizeof(char))-1);
+ bool show_cpp_signature = doc_len >=int(sizeof(detail::cpp_signature_tag)/sizeof(char))
+ && str(detail::cpp_signature_tag)==func_doc.slice(- int(sizeof(detail::cpp_signature_tag)/sizeof(char))+1, _);
+
+ str res;
+ if(show_py_signature)
+ {
+ str sig = pretty_signature(*fi, n_overloads,false);
+ res+=sig;
+ if(doc_len > int(sizeof(detail::py_signature_tag)/sizeof(char))-1 )
+ res+=" : "+func_doc.slice(int(sizeof(detail::py_signature_tag)/sizeof(char))-1,_);
+ }else
+ res+=func_doc;
+
+ if( show_cpp_signature)
+ res+=str("\n ")+pretty_signature(*fi, n_overloads,true);
+
+ signatures.append(res);
+ }
+ ++sfi;
+ n_overloads = 0;
+ }else
+ ++n_overloads ;
+ }
+ return signatures;
+ }
+
+
+}}}
+

Modified: trunk/libs/python/src/str.cpp
==============================================================================
--- trunk/libs/python/src/str.cpp (original)
+++ trunk/libs/python/src/str.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -349,5 +349,15 @@
 BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1)
 BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2)
 BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0)
+
+static struct register_str_pytype_ptr
+{
+ register_str_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::str>())
+ ).m_class_object = &PyString_Type;
+ }
+}register_str_pytype_ptr_;
     
 }}} // namespace boost::python

Modified: trunk/libs/python/src/tuple.cpp
==============================================================================
--- trunk/libs/python/src/tuple.cpp (original)
+++ trunk/libs/python/src/tuple.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -21,4 +21,15 @@
     : object(call(sequence))
 {}
 
+static struct register_tuple_pytype_ptr
+{
+ register_tuple_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::tuple>())
+ ).m_class_object = &PyTuple_Type;
+ }
+}register_tuple_pytype_ptr_;
+
+
 }}} // namespace boost::python

Modified: trunk/libs/python/test/Jamfile.v2
==============================================================================
--- trunk/libs/python/test/Jamfile.v2 (original)
+++ trunk/libs/python/test/Jamfile.v2 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -135,6 +135,7 @@
 [ bpl-test nested ]
 
 [ bpl-test docstring ]
+[ bpl-test pytype_function ]
 
 [ bpl-test vector_indexing_suite ]
 
@@ -147,7 +148,7 @@
     <toolset>hp_cxx:<build>no ]
 
 [ python-extension map_indexing_suite_ext
- : map_indexing_suite.cpp int_map_indexing_suite.cpp
+ : map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp
     /boost/python//boost_python ]
 [ bpl-test
     map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]

Added: trunk/libs/python/test/a_map_indexing_suite.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/python/test/a_map_indexing_suite.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,84 @@
+// Copyright Joel de Guzman 2004. 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/suite/indexing/map_indexing_suite.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/implicit.hpp>
+
+using namespace boost::python;
+
+struct A
+{
+ int value;
+ A() : value(0){};
+ A(int v) : value(v) {};
+};
+
+bool operator==(const A& v1, const A& v2)
+{
+ return (v1.value == v2.value);
+}
+
+struct B
+{
+ A a;
+};
+
+// Converter from A to python int
+struct AToPython
+{
+ static PyObject* convert(const A& s)
+ {
+ return boost::python::incref(boost::python::object((int)s.value).ptr());
+ }
+};
+
+// Conversion from python int to A
+struct AFromPython
+{
+ AFromPython()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id< A >());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ if (!PyInt_Check(obj_ptr)) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage< A >*)
+ data)-> storage.bytes;
+
+ new (storage) A((int)PyInt_AsLong(obj_ptr));
+ data->convertible = storage;
+ }
+};
+
+void a_map_indexing_suite()
+{
+
+ to_python_converter< A , AToPython >();
+ AFromPython();
+
+ class_< std::map<int, A> >("AMap")
+ .def(map_indexing_suite<std::map<int, A>, true >())
+ ;
+
+ class_< B >("B")
+ .add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
+ make_setter(&B::a, return_value_policy<return_by_value>()))
+ ;
+}
+
+

Modified: trunk/libs/python/test/args.cpp
==============================================================================
--- trunk/libs/python/test/args.cpp (original)
+++ trunk/libs/python/test/args.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -51,7 +51,7 @@
 
 BOOST_PYTHON_MODULE(args_ext)
 {
- def("f", f, args("x", "y", "z")
+ def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
         , "This is f's docstring"
         );
 
@@ -72,24 +72,24 @@
         .def("raw", raw_function(raw_func))
         ;
             
- class_<X>("X", "This is X's docstring")
- .def(init<int, optional<int> >(args("a0", "a1")))
+ class_<X>("X", "This is X's docstring", init<>(args("self")))
+ .def(init<int, optional<int> >(args("self", "a0", "a1")))
         .def("f", &X::f
              , "This is X.f's docstring"
- , args("x", "y", "z"))
+ , args("self","x", "y", "z"))
 
         // Just to prove that all the different argument combinations work
- .def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring")
- .def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n"))
+ .def("inner0", &X::inner, return_internal_reference<>(), args("self", "n"), "docstring")
+ .def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("self", "n"))
 
- .def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring")
- .def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n"))
+ .def("inner2", &X::inner, args("self", "n"), return_internal_reference<>(), "docstring")
+ .def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("self", "n"))
 
- .def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>())
- .def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>())
+ .def("inner4", &X::inner, args("self", "n"), "docstring", return_internal_reference<>())
+ .def("inner5", &X::inner, "docstring", args("self", "n"), return_internal_reference<>())
 
- .def("f1", &X::f, X_f_overloads(args("x", "y", "z")))
- .def("f2", &X::f, X_f_overloads(args("x", "y", "z"), "f2's docstring"))
+ .def("f1", &X::f, X_f_overloads(args("self", "x", "y", "z")))
+ .def("f2", &X::f, X_f_overloads(args("self", "x", "y", "z"), "f2's docstring"))
         ;
 
     def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());

Modified: trunk/libs/python/test/args.py
==============================================================================
--- trunk/libs/python/test/args.py (original)
+++ trunk/libs/python/test/args.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -84,24 +84,24 @@
 (2, 4.25, 'wow')
>>> q.f1()
 (1, 4.25, 'wow')
->>> q.f2.__doc__.splitlines()[-4]
-"f2's docstring"
+>>> q.f2.__doc__.splitlines()[-3]
+"f2( (X)self [, (int)x [, (float)y [, (str)z]]]) -> tuple : f2's docstring"
 
->>> X.f.__doc__.splitlines()[:3]
-["This is X.f's docstring", '', 'C++ signature:']
+>>> X.f.__doc__.splitlines()[:2]
+["f( (X)self, (int)x, (float)y, (str)z) -> tuple : This is X.f's docstring", ' C++ signature:']
 
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
>>> for f in xfuncs:
 ... print f(q,1).value(),
 ... print f(q, n = 1).value(),
 ... print f(q, n = 0).value(),
-... print f.__doc__.splitlines()[:3]
-1 1 0 ['docstring', '', 'C++ signature:']
-1 1 0 ['docstring', '', 'C++ signature:']
-1 1 0 ['docstring', '', 'C++ signature:']
-1 1 0 ['docstring', '', 'C++ signature:']
-1 1 0 ['docstring', '', 'C++ signature:']
-1 1 0 ['docstring', '', 'C++ signature:']
+... print f.__doc__.splitlines()[:2]
+1 1 0 ['inner0( (X)self, (bool)n) -> Y : docstring', ' C++ signature:']
+1 1 0 ['inner1( (X)self, (bool)n) -> Y : docstring', ' C++ signature:']
+1 1 0 ['inner2( (X)self, (bool)n) -> Y : docstring', ' C++ signature:']
+1 1 0 ['inner3( (X)self, (bool)n) -> Y : docstring', ' C++ signature:']
+1 1 0 ['inner4( (X)self, (bool)n) -> Y : docstring', ' C++ signature:']
+1 1 0 ['inner5( (X)self, (bool)n) -> Y : docstring', ' C++ signature:']
 
>>> x = X(a1 = 44, a0 = 22)
>>> x.inner0(0).value()
@@ -136,49 +136,9 @@
     import sys
     status = run()[0]
     if (status == 0): print "Done."
+ import args_ext
+ help(args_ext)
     sys.exit(status)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

Modified: trunk/libs/python/test/auto_ptr.py
==============================================================================
--- trunk/libs/python/test/auto_ptr.py (original)
+++ trunk/libs/python/test/auto_ptr.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -64,6 +64,24 @@
 ... except TypeError: pass
 ... else: print 'expected a TypeError exception'
 
+>>> print look.__doc__.splitlines()[0]
+look( (X)arg1) -> int :
+
+>>> print steal.__doc__.splitlines()[0]
+steal( (X)arg1) -> int :
+
+>>> print maybe_steal.__doc__.splitlines()[0]
+maybe_steal( (X)arg1, (bool)arg2) -> int :
+
+>>> print make.__doc__.splitlines()[0]
+make() -> X :
+
+>>> print callback.__doc__.splitlines()[0]
+callback( (object)arg1) -> X :
+
+>>> print extract.__doc__.splitlines()[0]
+extract( (object)arg1) -> X :
+
 '''
 
 def run(args = None):

Modified: trunk/libs/python/test/back_reference.py
==============================================================================
--- trunk/libs/python/test/back_reference.py (original)
+++ trunk/libs/python/test/back_reference.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -16,6 +16,9 @@
>>> assert y_identity(y) is y
>>> y_equality(y, y)
 1
+
+>>> print y_identity.__doc__.splitlines()[0]
+y_identity( (Y)arg1) -> object :
 '''
 
 def run(args = None):

Modified: trunk/libs/python/test/data_members.cpp
==============================================================================
--- trunk/libs/python/test/data_members.cpp (original)
+++ trunk/libs/python/test/data_members.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -52,7 +52,7 @@
 Y Var::static2(0);
 
 // Compilability regression tests
-namespace
+namespace boost_python_test
 {
   struct trivial
   {
@@ -86,6 +86,7 @@
 
 BOOST_PYTHON_MODULE(data_members_ext)
 {
+ using namespace boost_python_test;
     class_<X>("X", init<int>())
         .def("value", &X::value)
         .def("set", &X::set)

Modified: trunk/libs/python/test/defaults.cpp
==============================================================================
--- trunk/libs/python/test/defaults.cpp (original)
+++ trunk/libs/python/test/defaults.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -159,10 +159,10 @@
         .def("get_state", &Y::get_state)
         ;
 
- class_<X>("X")
+ class_<X>("X",no_init)
 
- .def(init<int, optional<char, std::string, double> >("doc of init"))
- .def(init<std::string, bool>()[default_call_policies()]) // what's a good policy here?
+ .def(init<optional<int, char, std::string, double> >("doc of init", args("self", "a", "b", "c", "d")))
+ .def(init<std::string, bool>(args("self", "s", "b"))[default_call_policies()]) // what's a good policy here?
         .def("get_state", &X::get_state)
         .def("bar", &X::bar, X_bar_stubs())
         .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()])

Modified: trunk/libs/python/test/defaults.py
==============================================================================
--- trunk/libs/python/test/defaults.py (original)
+++ trunk/libs/python/test/defaults.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -113,28 +113,19 @@
 ... doc = obj.__doc__.splitlines()
 ... return "\\n".join(["|"+doc[i] for i in args])
 
->>> print selected_doc(X.__init__, 0, 3, 6, 9, 11, 12, 14, 17)
-|C++ signature:
-|C++ signature:
-|C++ signature:
-|C++ signature:
-|
-|doc of init
-|C++ signature:
-|C++ signature:
-
->>> print selected_doc(Y.__init__, 0, 2)
-|doc of Y init
-|C++ signature:
-
->>> print selected_doc(X.bar2, 0, 3, 6, 9, 11, 12, 14)
-|C++ signature:
-|C++ signature:
-|C++ signature:
-|C++ signature:
-|
-|doc of X::bar2
-|C++ signature:
+>>> print selected_doc(X.__init__, 0, 1, 3, 4)
+|__init__( (object)self [, (int)a [, (str)b [, (str)c [, (float)d]]]]) -> None : doc of init
+| C++ signature:
+| __init__( (object)self, (str)s, (bool)b) -> None :
+| C++ signature:
+
+>>> print selected_doc(Y.__init__, 0, 1)
+|__init__( (object)arg1) -> None : doc of Y init
+| C++ signature:
+
+>>> print selected_doc(X.bar2, 0, 1)
+|bar2( (X)arg1 [, (int)arg2 [, (str)arg3 [, (str)arg4 [, (float)arg5]]]]) -> Y : doc of X::bar2
+| C++ signature:
 
 """
 def run(args = None):

Modified: trunk/libs/python/test/docstring.cpp
==============================================================================
--- trunk/libs/python/test/docstring.cpp (original)
+++ trunk/libs/python/test/docstring.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -43,55 +43,74 @@
               , init<int>(
                   "this is the __init__ function\n"
                   "its documentation has two lines."
+ , args("self", "value")
                 )
 
         )
         .def("value", &X::value,
- "gets the value of the object")
+ "gets the value of the object"
+ , args("self"))
         .def( "value", &X::value,
- "also gets the value of the object")
+ "also gets the value of the object"
+ , args("self"))
         ;
 
     def("create", create, return_value_policy<manage_new_object>(),
- "creates a new X object");
+ "creates a new X object", args("value"));
 
- def("fact", fact, "compute the factorial");
+ def("fact", fact, "compute the factorial", args("n"));
 
     {
       docstring_options doc_options;
       doc_options.disable_user_defined();
- def("fact_usr_off_1", fact, "usr off 1");
+ def("fact_usr_off_1", fact, "usr off 1", args("n"));
       doc_options.enable_user_defined();
- def("fact_usr_on_1", fact, "usr on 1");
+ def("fact_usr_on_1", fact, "usr on 1", args("n"));
       doc_options.disable_user_defined();
- def("fact_usr_off_2", fact, "usr off 2");
+ def("fact_usr_off_2", fact, "usr off 2", args("n"));
     }
- def("fact_usr_on_2", fact, "usr on 2");
+ def("fact_usr_on_2", fact, "usr on 2", args("n"));
 
     {
       docstring_options doc_options(true, false);
- def("fact_sig_off_1", fact, "sig off 1");
+ def("fact_sig_off_1", fact, "sig off 1", args("n"));
       doc_options.enable_signatures();
- def("fact_sig_on_1", fact, "sig on 1");
+ def("fact_sig_on_1", fact, "sig on 1", args("n"));
       doc_options.disable_signatures();
- def("fact_sig_off_2", fact, "sig off 2");
+ def("fact_sig_off_2", fact, "sig off 2", args("n"));
     }
- def("fact_sig_on_2", fact, "sig on 2");
+ def("fact_sig_on_2", fact, "sig on 2", args("n"));
 
     {
       docstring_options doc_options(false);
- def("fact_usr_off_sig_off_1", fact, "usr off sig off 1");
+ def("fact_usr_off_sig_off_1", fact, "usr off sig off 1", args("n"));
       {
         docstring_options nested_doc_options;
- def("fact_usr_on_sig_on_1", fact, "usr on sig on 1");
+ def("fact_usr_on_sig_on_1", fact, "usr on sig on 1", args("n"));
         nested_doc_options.disable_all();
         nested_doc_options.enable_user_defined();
- def("fact_usr_on_sig_off_1", fact, "usr on sig off 1");
+ def("fact_usr_on_sig_off_1", fact, "usr on sig off 1", args("n"));
         nested_doc_options.enable_all();
- def("fact_usr_on_sig_on_2", fact, "usr on sig on 2");
+ def("fact_usr_on_sig_on_2", fact, "usr on sig on 2", args("n"));
       }
- def("fact_usr_off_sig_off_2", fact, "usr off sig off 2");
+ def("fact_usr_off_sig_off_2", fact, "usr off sig off 2", args("n"));
     }
+
+ {
+ docstring_options doc_options(true);
+ doc_options.disable_cpp_signatures();
+ def("fact_usr_on_psig_on_csig_off_1", fact, "usr on psig on csig off 1", args("n"));
+ doc_options.enable_cpp_signatures();
+ doc_options.disable_py_signatures();
+ def("fact_usr_on_psig_off_csig_on_1", fact, "usr on psig off csig on 1", args("n"));
+ doc_options.enable_py_signatures();
+ doc_options.disable_user_defined();
+ doc_options.disable_cpp_signatures();
+ def("fact_usr_off_psig_on_csig_off_1", fact, "usr off psig on csig off 1", args("n"));
+ doc_options.enable_cpp_signatures();
+ doc_options.disable_py_signatures();
+ def("fact_usr_off_psig_off_csig_on_1", fact, "usr off psig off csig on 1", args("n"));
+ }
 }
 
 #include "module_tail.cpp"

Modified: trunk/libs/python/test/docstring.py
==============================================================================
--- trunk/libs/python/test/docstring.py (original)
+++ trunk/libs/python/test/docstring.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -8,82 +8,99 @@
 ... doc = obj.__doc__.splitlines()
 ... return "\\n".join(["|"+doc[i] for i in args])
 
->>> print selected_doc(X.__init__, 0, 1, 3)
-|this is the __init__ function
+>>> print selected_doc(X.__init__, 0, 1, 2)
+|__init__( (object)self, (int)value) -> None : this is the __init__ function
 |its documentation has two lines.
-|C++ signature:
+| C++ signature:
 
->>> print selected_doc(X.value, 0, 2, 4, 5, 7)
-|gets the value of the object
-|C++ signature:
-|
-|also gets the value of the object
-|C++ signature:
-
->>> print selected_doc(create, 0, 2)
-|creates a new X object
-|C++ signature:
-
->>> print selected_doc(fact, 0, 2)
-|compute the factorial
-|C++ signature:
+>>> print selected_doc(X.value, 0, 1, 3, 4)
+|value( (X)self) -> int : gets the value of the object
+| C++ signature:
+| value( (X)self) -> int : also gets the value of the object
+| C++ signature:
+
+>>> print selected_doc(create, 0, 1)
+|create( (int)value) -> X : creates a new X object
+| C++ signature:
+
+>>> print selected_doc(fact, 0, 1)
+|fact( (int)n) -> int : compute the factorial
+| C++ signature:
 
>>> len(fact_usr_off_1.__doc__.splitlines())
-2
->>> print selected_doc(fact_usr_off_1, 0)
-|C++ signature:
+3
+>>> print selected_doc(fact_usr_off_1, 0, 1)
+|fact_usr_off_1( (int)n) -> int :
+| C++ signature:
>>> len(fact_usr_on_1.__doc__.splitlines())
-4
->>> print selected_doc(fact_usr_on_1, 0, 2)
-|usr on 1
-|C++ signature:
+3
+>>> print selected_doc(fact_usr_on_1, 0, 1)
+|fact_usr_on_1( (int)n) -> int : usr on 1
+| C++ signature:
>>> len(fact_usr_off_2.__doc__.splitlines())
-2
->>> print selected_doc(fact_usr_off_2, 0)
-|C++ signature:
+3
+>>> print selected_doc(fact_usr_off_2, 0,1)
+|fact_usr_off_2( (int)n) -> int :
+| C++ signature:
>>> len(fact_usr_on_2.__doc__.splitlines())
-4
->>> print selected_doc(fact_usr_on_2, 0, 2)
-|usr on 2
-|C++ signature:
+3
+>>> print selected_doc(fact_usr_on_2, 0, 1)
+|fact_usr_on_2( (int)n) -> int : usr on 2
+| C++ signature:
+
 
>>> len(fact_sig_off_1.__doc__.splitlines())
 1
>>> print selected_doc(fact_sig_off_1, 0)
 |sig off 1
>>> len(fact_sig_on_1.__doc__.splitlines())
-4
->>> print selected_doc(fact_sig_on_1, 0, 2)
-|sig on 1
-|C++ signature:
+3
+>>> print selected_doc(fact_sig_on_1, 0, 1)
+|fact_sig_on_1( (int)n) -> int : sig on 1
+| C++ signature:
+
>>> len(fact_sig_off_2.__doc__.splitlines())
 1
>>> print selected_doc(fact_sig_off_2, 0)
 |sig off 2
>>> len(fact_sig_on_2.__doc__.splitlines())
-4
->>> print selected_doc(fact_sig_on_2, 0, 2)
-|sig on 2
-|C++ signature:
+3
+>>> print selected_doc(fact_sig_on_2, 0, 1)
+|fact_sig_on_2( (int)n) -> int : sig on 2
+| C++ signature:
+
 
>>> print fact_usr_off_sig_off_1.__doc__
 None
>>> len(fact_usr_on_sig_on_1.__doc__.splitlines())
-4
->>> print selected_doc(fact_usr_on_sig_on_1, 0, 2)
-|usr on sig on 1
-|C++ signature:
+3
+>>> print selected_doc(fact_usr_on_sig_on_1, 0, 1)
+|fact_usr_on_sig_on_1( (int)n) -> int : usr on sig on 1
+| C++ signature:
+
>>> len(fact_usr_on_sig_off_1.__doc__.splitlines())
 1
>>> print selected_doc(fact_usr_on_sig_off_1, 0)
 |usr on sig off 1
>>> len(fact_usr_on_sig_on_2.__doc__.splitlines())
-4
->>> print selected_doc(fact_usr_on_sig_on_2, 0, 2)
-|usr on sig on 2
-|C++ signature:
->>> print fact_usr_off_sig_off_2.__doc__
-None
+3
+>>> print selected_doc(fact_usr_on_sig_on_2, 0, 1)
+|fact_usr_on_sig_on_2( (int)n) -> int : usr on sig on 2
+| C++ signature:
+
+>>> print fact_usr_on_psig_on_csig_off_1.__doc__
+fact_usr_on_psig_on_csig_off_1( (int)n) -> int : usr on psig on csig off 1
+
+>>> print selected_doc(fact_usr_on_psig_off_csig_on_1, 0, 1)
+|usr on psig off csig on 1
+| C++ signature:
+
+>>> print fact_usr_off_psig_on_csig_off_1.__doc__
+fact_usr_off_psig_on_csig_off_1( (int)n) -> int
+
+>>> print selected_doc(fact_usr_off_psig_off_csig_on_1,0)
+| C++ signature:
+
 
 '''
 

Modified: trunk/libs/python/test/implicit.py
==============================================================================
--- trunk/libs/python/test/implicit.py (original)
+++ trunk/libs/python/test/implicit.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -13,6 +13,19 @@
>>> try: make_x('fool')
 ... except TypeError: pass
 ... else: print 'no error'
+
+>>> print x_value.__doc__.splitlines()[0]
+x_value( (X)arg1) -> int :
+
+>>> print make_x.__doc__.splitlines()[0]
+make_x( (object)arg1) -> X :
+
+>>> print X.value.__doc__.splitlines()[0]
+value( (X)arg1) -> int :
+
+>>> print X.set.__doc__.splitlines()[0]
+set( (X)arg1, (object)arg2) -> None :
+
 '''
 
 def run(args = None):

Modified: trunk/libs/python/test/keywords_test.py
==============================================================================
--- trunk/libs/python/test/keywords_test.py (original)
+++ trunk/libs/python/test/keywords_test.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -80,8 +80,8 @@
>>> f.set(1,1.0,"1")
>>> f.a(), f.b(), f.n()
 (1, 1.0, '1')
->>> f.set2.__doc__.splitlines()[-4]
-"set2's docstring"
+>>> f.set2.__doc__.splitlines()[-3]
+"set2( (Bar)arg1 [, (int)arg2 [, (float)arg3 [, (str)arg4]]]) -> None : set2's docstring"
 '''
 
 

Modified: trunk/libs/python/test/m1.cpp
==============================================================================
--- trunk/libs/python/test/m1.cpp (original)
+++ trunk/libs/python/test/m1.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -13,6 +13,7 @@
 #include <boost/python/to_python_converter.hpp>
 #include <boost/python/errors.hpp>
 #include <boost/python/manage_new_object.hpp>
+#include <boost/python/converter/pytype_function.hpp>
 #include <string.h>
 #include "simple_type.hpp"
 #include "complicated.hpp"
@@ -170,7 +171,8 @@
 
 // Wrap a simple by copying it into a Simple
 struct simple_to_python
- : to_python_converter<simple, simple_to_python>
+ : to_python_converter<simple, simple_to_python, true>
+ //, boost::python::converter::wrap_pytype<&SimpleType>
 {
     static PyObject* convert(simple const& x)
     {
@@ -178,6 +180,7 @@
         p->x = x;
         return (PyObject*)p;
     }
+ static PyTypeObject const *get_pytype(){return &SimpleType; }
 };
 
 struct int_from_noddy

Modified: trunk/libs/python/test/map_indexing_suite.cpp
==============================================================================
--- trunk/libs/python/test/map_indexing_suite.cpp (original)
+++ trunk/libs/python/test/map_indexing_suite.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -26,61 +26,6 @@
     return "gotya " + x.s;
 }
 
-struct A
-{
- int value;
- A() : value(0){};
- A(int v) : value(v) {};
-};
-
-bool operator==(const A& v1, const A& v2)
-{
- return (v1.value == v2.value);
-}
-
-struct B
-{
- A a;
-};
-
-// Converter from A to python int
-struct AToPython
-{
- static PyObject* convert(const A& s)
- {
- return boost::python::incref(boost::python::object((int)s.value).ptr());
- }
-};
-
-// Conversion from python int to A
-struct AFromPython
-{
- AFromPython()
- {
- boost::python::converter::registry::push_back(
- &convertible,
- &construct,
- boost::python::type_id< A >());
- }
-
- static void* convertible(PyObject* obj_ptr)
- {
- if (!PyInt_Check(obj_ptr)) return 0;
- return obj_ptr;
- }
-
- static void construct(
- PyObject* obj_ptr,
- boost::python::converter::rvalue_from_python_stage1_data* data)
- {
- void* storage = (
- (boost::python::converter::rvalue_from_python_storage< A >*)
- data)-> storage.bytes;
-
- new (storage) A((int)PyInt_AsLong(obj_ptr));
- data->convertible = storage;
- }
-};
 
 BOOST_PYTHON_MODULE(map_indexing_suite_ext)
 {
@@ -115,17 +60,9 @@
         .def(map_indexing_suite<std::map<std::string, boost::shared_ptr<X> >, true>())
     ;
 
- to_python_converter< A , AToPython >();
- AFromPython();
-
- class_< std::map<int, A> >("AMap")
- .def(map_indexing_suite<std::map<int, A>, true >())
- ;
-
- class_< B >("B")
- .add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
- make_setter(&B::a, return_value_policy<return_by_value>()))
- ;
+ void a_map_indexing_suite(); // moved to a_map_indexing_suite.cpp to
+ a_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
+
 }
 
 #include "module_tail.cpp"

Modified: trunk/libs/python/test/newtest.py
==============================================================================
--- trunk/libs/python/test/newtest.py (original)
+++ trunk/libs/python/test/newtest.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -183,6 +183,8 @@
>>> dd = take_d(d_as_a)
>>> dd.name()
 'D'
+>>> print g.__doc__.splitlines()[0]
+g( (Simple)arg1) -> Simple :
 
 """
 

Modified: trunk/libs/python/test/pickle1.cpp
==============================================================================
--- trunk/libs/python/test/pickle1.cpp (original)
+++ trunk/libs/python/test/pickle1.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -19,7 +19,7 @@
 
 #include <string>
 
-namespace {
+namespace boost_python_test {
 
   // A friendly class.
   class world
@@ -52,6 +52,7 @@
 BOOST_PYTHON_MODULE(pickle1_ext)
 {
   using namespace boost::python;
+ using namespace boost_python_test;
   class_<world>("world", init<const std::string&>())
       .def("greet", &world::greet)
       .def_pickle(world_pickle_suite())

Modified: trunk/libs/python/test/pickle2.cpp
==============================================================================
--- trunk/libs/python/test/pickle2.cpp (original)
+++ trunk/libs/python/test/pickle2.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -28,7 +28,7 @@
 #include <boost/python/tuple.hpp>
 #include <boost/python/extract.hpp>
 
-namespace { // Avoid cluttering the global namespace.
+namespace boost_python_test {
 
   // A friendly class.
   class world
@@ -88,6 +88,7 @@
 
 BOOST_PYTHON_MODULE(pickle2_ext)
 {
+ using namespace boost_python_test;
     boost::python::class_<world>(
         "world", boost::python::init<const std::string&>())
         .def("greet", &world::greet)

Modified: trunk/libs/python/test/pickle3.cpp
==============================================================================
--- trunk/libs/python/test/pickle3.cpp (original)
+++ trunk/libs/python/test/pickle3.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -29,7 +29,7 @@
 # define make_tuple boost::python::make_tuple
 #endif
 
-namespace { // Avoid cluttering the global namespace.
+namespace boost_python_test {
 
   // A friendly class.
   class world
@@ -100,6 +100,7 @@
 
 BOOST_PYTHON_MODULE(pickle3_ext)
 {
+ using namespace boost_python_test;
     boost::python::class_<world>(
         "world", boost::python::init<const std::string&>())
         .def("greet", &world::greet)

Modified: trunk/libs/python/test/pickle4.cpp
==============================================================================
--- trunk/libs/python/test/pickle4.cpp (original)
+++ trunk/libs/python/test/pickle4.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -15,7 +15,7 @@
 
 #include <string>
 
-namespace {
+namespace boost_python_test {
 
   // A friendly class.
   class world
@@ -35,6 +35,7 @@
 BOOST_PYTHON_MODULE(pickle4_ext)
 {
   using namespace boost::python;
+ using namespace boost_python_test;
   class_<world>("world", init<const std::string&>())
       .enable_pickling()
       .def("greet", &world::greet)

Added: trunk/libs/python/test/pytype_function.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/python/test/pytype_function.cpp 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,85 @@
+// Copyright Joel de Guzman 2004. 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/extract.hpp>
+#include <boost/python/to_python_converter.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+struct A
+{
+};
+
+struct B
+{
+ A a;
+ B(const A& a_):a(a_){}
+};
+
+// Converter from A to python int
+struct BToPython
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ : converter::to_python_target_type<A> //inherits get_pytype
+#endif
+{
+ static PyObject* convert(const B& b)
+ {
+ return boost::python::incref(boost::python::object(b.a).ptr());
+ }
+};
+
+// Conversion from python int to A
+struct BFromPython
+{
+ BFromPython()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id< B >()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &converter::expected_from_python_type<A>::get_pytype//convertible to A can be converted to B
+#endif
+ );
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ extract<const A&> ex(obj_ptr);
+ if (!ex.check()) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage< B >*)data)-> storage.bytes;
+
+ extract<const A&> ex(obj_ptr);
+ new (storage) B(ex());
+ data->convertible = storage;
+ }
+};
+
+
+B func(const B& b) { return b ; }
+
+
+BOOST_PYTHON_MODULE(pytype_function_ext)
+{
+ to_python_converter< B , BToPython,true >(); //has get_pytype
+ BFromPython();
+
+ class_<A>("A") ;
+
+ def("func", &func);
+
+}
+
+#include "module_tail.cpp"

Added: trunk/libs/python/test/pytype_function.py
==============================================================================
--- (empty file)
+++ trunk/libs/python/test/pytype_function.py 2007-09-11 12:53:50 EDT (Tue, 11 Sep 2007)
@@ -0,0 +1,27 @@
+# Copyright David Abrahams 2004. 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 pytype_function_ext import *
+
+>>> print (' ').join(func.__doc__.splitlines())
+func( (A)arg1) -> A : C++ signature: struct B func(struct B)
+
+"""
+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)
+
+
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk