diff --git a/build/Attic/python_v1.zip b/build/Attic/python_v1.zip deleted file mode 100644 index 0377a07b..00000000 Binary files a/build/Attic/python_v1.zip and /dev/null differ diff --git a/build/Jamfile b/build/Jamfile deleted file mode 100644 index 92f715c2..00000000 --- a/build/Jamfile +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright David Abrahams 2001-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) -# -# Boost.Python library Jamfile - - -# declare the location of this subproject relative to the root -subproject libs/python/build ; - -# bring in the rules for python -import python ; - -if [ check-python-config ] -{ - - local bpl-linkflags ; - - if $(UNIX) && ( $(OS) = AIX ) - { - bpl-linkflags = "-e initlibboost_python" ; - } - - # Enabling intrinsics (/0i) or maximize speed (/02) seem to cause - # internal compiler errors with this toolset. - local msvc-stlport-workarounds - = off "-Ogty -O1 -Gs" ; - - local sources = - numeric.cpp - list.cpp - long.cpp - dict.cpp - tuple.cpp - str.cpp - slice.cpp - - aix_init_module.cpp - converter/from_python.cpp - converter/registry.cpp - converter/type_id.cpp - object/enum.cpp - object/class.cpp - object/function.cpp - object/inheritance.cpp - object/life_support.cpp - object/pickle_support.cpp - errors.cpp - module.cpp - converter/builtin_converters.cpp - converter/arg_to_python_base.cpp - object/iterator.cpp - object/stl_iterator.cpp - object_protocol.cpp - object_operators.cpp - wrapper.cpp - exec.cpp - import.cpp - ; - - dll boost_python - : ../src/$(sources) - : $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - $(bpl-linkflags) - $(msvc-stlport-workarounds) - <*>-bind_at_load - <*>-bind_at_load - ; - - template extension - : boost_python - : ../../.. - ; - - lib boost_python - : # sources - ../src/$(sources) - - : # requirements - $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - BOOST_STATIC_LIB - $(bpl-linkflags) - $(msvc-stlport-workarounds) - ; - - stage bin-stage : boost_python boost_python - : "_debug" - "_pydebug" - : - debug release - ; - - install python lib - : boost_python boost_python - ; -} diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 deleted file mode 100644 index 3987bb15..00000000 --- a/build/Jamfile.v2 +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright David Abrahams 2001-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) - -import os ; -import modules ; - -import python ; - -if [ python.configured ] { - - -project boost/python - : source-location ../src - : requirements - #$(PYTHON_PATH)/include - # $(lib_condition)$(PYTHON_PATH)/libs - # shared:$(PYTHON_LIB) - # $(defines) - #: usage-requirements # requirement that will be propageted to *users* of this library - # $(PYTHON_PATH)/include - -# We have a bug which causes us to conclude that conditionalized -# properties in this section are not free. -# $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config -# true:$(PYTHON_LIB) - - # $(PYTHON_PATH)/lib/python2.2/config - # $(PYTHON_LIB) - ; - -lib boost_python - : # sources - numeric.cpp - list.cpp - long.cpp - dict.cpp - tuple.cpp - str.cpp - slice.cpp - - aix_init_module.cpp - converter/from_python.cpp - converter/registry.cpp - converter/type_id.cpp - object/enum.cpp - object/class.cpp - object/function.cpp - object/inheritance.cpp - object/life_support.cpp - object/pickle_support.cpp - errors.cpp - module.cpp - converter/builtin_converters.cpp - converter/arg_to_python_base.cpp - object/iterator.cpp - object/stl_iterator.cpp - object_protocol.cpp - object_operators.cpp - wrapper.cpp - import.cpp - exec.cpp - : # requirements - static:BOOST_PYTHON_STATIC_LIB - BOOST_PYTHON_SOURCE - # On Linux, we don't link to Python library itself. If - # Boost.Python is used for extension, all Python - # symbols are available in Python interpreter. - # If Boost.Python is used for extending, client - # is required to link to /python//python itself. - # On Windows, all code using Python has to link - # to python import library. The 'python_for_extension' - # is the target that's setup to provide either just - # include paths, or import library. - /python//python_for_extensions - : # default build - shared - : # usage requirements - static:BOOST_PYTHON_STATIC_LIB - shared:BOOST_PYTHON_DYNAMIC_LIB - ; -} -else -{ - ECHO "warning: Python location is not configured" ; - ECHO "warning: the Boost.Python library won't be built" ; -} diff --git a/build/VisualStudio/boost_python.dsp b/build/VisualStudio/boost_python.dsp deleted file mode 100644 index b05e91bf..00000000 --- a/build/VisualStudio/boost_python.dsp +++ /dev/null @@ -1,910 +0,0 @@ -# Microsoft Developer Studio Project File - Name="boost_python" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=BOOST_PYTHON - WIN32 RELEASE -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "boost_python.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "boost_python.mak" CFG="BOOST_PYTHON - WIN32 RELEASE" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "boost_python - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "boost_python - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "boost_python - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "../bin-stage" -# PROP Intermediate_Dir "release-obj" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -F90=df.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /c -# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1409 /d "NDEBUG" -# ADD RSC /l 0x1409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386 - -!ELSEIF "$(CFG)" == "boost_python - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "../bin-stage" -# PROP Intermediate_Dir "debug-obj" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -F90=df.exe -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /GZ /c -# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "../../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1409 /d "_DEBUG" -# ADD RSC /l 0x1409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"../bin-stage/boost_python_debug.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "boost_python - Win32 Release" -# Name "boost_python - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\aix_init_module.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\arg_to_python_base.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\builtin_converters.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\class.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\dict.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\enum.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\errors.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\from_python.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\function.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\inheritance.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\iterator.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\life_support.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\list.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\long.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\module.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\numeric.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object_operators.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object_protocol.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\pickle_support.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\registry.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\slice.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\stl_iterator.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\str.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\tuple.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\type_id.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\wrapper.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\import.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\exec.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Group "detail" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\arg_tuple_size.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\borrowed_ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\call_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\caller.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\char_array.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\config.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\construct.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\convertible.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\cv_category.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\decorated_type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\def_helper.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\defaults_def.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\defaults_gen.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\dependent.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\destroy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\exception_handler.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\force_instantiate.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\if_else.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\indirect_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\make_keyword_range_fn.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\make_tuple.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\map_entry.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\member_function_cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\module_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\module_init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\msvc_typeinfo.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\none.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\not_specified.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\operator_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\overloads_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\preprocessor.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\python22_fixed.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\raw_pyobject.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\referent_storage.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\result.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\returning.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\scope.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\string_literal.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\target.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\translate_exception.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_impl.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_impl_no_pts.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_utils.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\unwind_type.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\void_ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\void_return.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\wrap_python.hpp -# End Source File -# End Group -# Begin Group "converter" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_to_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_to_python_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\builtin_converters.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\constructor_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\convertible_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\implicit.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\obj_mgr_arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\object_manager.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pointer_type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pyobject_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pyobject_type.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pytype_arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pytype_object_mgr_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registered.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registered_pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registrations.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registry.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\return_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\rvalue_from_python_data.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\to_python_function_type.hpp -# End Source File -# End Group -# Begin Group "object" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\add_to_namespace.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_converters.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_detail.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_wrapper.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\construct.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\enum_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\find_instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\forward.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function_handle.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\inheritance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\iterator_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\life_support.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\make_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\make_instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\pickle_support.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\pointer_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\py_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\select_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\stl_iterator_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\value_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\value_holder_fwd.hpp -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\..\..\boost\python\arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\args.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\args_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\back_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\base_type_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\bases.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\borrowed.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\call.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\call_method.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\class_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\copy_const_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\copy_non_const_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\data_members.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\def.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\default_call_policies.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\dict.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\enum.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\errors.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\exception_translator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\extract.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\handle.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\handle_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\has_back_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\implicit.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\instance_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\list.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\long.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\lvalue_from_pytype.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\make_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\manage_new_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\module.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\module_init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\numeric.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_attributes.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_call.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_items.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_protocol.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_protocol_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_slices.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\operators2.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\other.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\overloads.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\proxy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\refcount.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\reference_existing_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\return_internal_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\return_value_policy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\scope.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\self.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\signature.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\slice_nil.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\stl_iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\str.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\tag.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_converter.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_indirect.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_value.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\tuple.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\with_custodian_and_ward.hpp -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/VisualStudio/boost_python.dsw b/build/VisualStudio/boost_python.dsw deleted file mode 100644 index 574c3bf8..00000000 --- a/build/VisualStudio/boost_python.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "boost_python"=".\boost_python.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/build/python_v1.zip b/build/python_v1.zip deleted file mode 100644 index 0377a07b..00000000 Binary files a/build/python_v1.zip and /dev/null differ diff --git a/doc/PyConDC_2003/bpl.html b/doc/PyConDC_2003/bpl.html deleted file mode 100755 index 32b655bd..00000000 --- a/doc/PyConDC_2003/bpl.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - Loading: “Building Hybrid Systems With Boost.Python” - - - - Loading...; if nothing happens, please go to http://www.boost-consulting.com/writing/bpl.html. - - - diff --git a/doc/PyConDC_2003/bpl.pdf b/doc/PyConDC_2003/bpl.pdf deleted file mode 100755 index 09827aff..00000000 Binary files a/doc/PyConDC_2003/bpl.pdf and /dev/null differ diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt deleted file mode 100644 index d6921b12..00000000 --- a/doc/PyConDC_2003/bpl.txt +++ /dev/null @@ -1,5 +0,0 @@ -.. 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) - -This file has been moved to http://www.boost-consulting.com/writing/bpl.txt. diff --git a/doc/PyConDC_2003/bpl_mods.txt b/doc/PyConDC_2003/bpl_mods.txt deleted file mode 100644 index 299e71b8..00000000 --- a/doc/PyConDC_2003/bpl_mods.txt +++ /dev/null @@ -1,912 +0,0 @@ -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) - -.. This is a comment. Note how any initial comments are moved by - transforms to after the document title, subtitle, and docinfo. - -.. Need intro and conclusion -.. Exposing classes - .. Constructors - .. Overloading - .. Properties and data members - .. Inheritance - .. Operators and Special Functions - .. Virtual Functions -.. Call Policies - -++++++++++++++++++++++++++++++++++++++++++++++ - Introducing Boost.Python (Extended Abstract) -++++++++++++++++++++++++++++++++++++++++++++++ - - -.. bibliographic fields (which also require a transform): - -:Author: David Abrahams -:Address: 45 Walnut Street - Somerville, MA 02143 -:Contact: dave@boost-consulting.com -:organization: `Boost Consulting`_ -:date: $Date$ -:status: This is a "work in progress" -:version: 1 -:copyright: Copyright David Abrahams 2002. All rights reserved - -:Dedication: - - For my girlfriend, wife, and partner Luann - -:abstract: - - This paper describes the Boost.Python library, a system for - C++/Python interoperability. - -.. meta:: - :keywords: Boost,python,Boost.Python,C++ - :description lang=en: C++/Python interoperability with Boost.Python - -.. contents:: Table of Contents -.. section-numbering:: - - -.. _`Boost Consulting`: http://www.boost-consulting.com - -============== - Introduction -============== - -Python and C++ are in many ways as different as two languages could -be: while C++ is usually compiled to machine-code, Python is -interpreted. Python's dynamic type system is often cited as the -foundation of its flexibility, while in C++ static typing is the -cornerstone of its efficiency. C++ has an intricate and difficult -meta-language to support compile-time polymorphism, while Python is -a uniform language with convenient runtime polymorphism. - -Yet for many programmers, these very differences mean that Python and -C++ complement one another perfectly. Performance bottlenecks in -Python programs can be rewritten in C++ for maximal speed, and -authors of powerful C++ libraries choose Python as a middleware -language for its flexible system integration capabilities. -Furthermore, the surface differences mask some strong similarities: - -* 'C'-family control structures (if, while, for...) - -* Support for object-orientation, functional programming, and generic - programming (these are both *multi-paradigm* programming languages.) - -* Comprehensive operator overloading facilities, recognizing the - importance of syntactic variability for readability and - expressivity. - -* High-level concepts such as collections and iterators. - -* High-level encapsulation facilities (C++: namespaces, Python: modules) - to support the design of re-usable libraries. - -* Exception-handling for effective management of error conditions. - -* C++ idioms in common use, such as handle/body classes and - reference-counted smart pointers mirror Python reference semantics. - -Python provides a rich 'C' API for writers of 'C' extension modules. -Unfortunately, using this API directly for exposing C++ type and -function interfaces to Python is much more tedious than it should be. -This is mainly due to the limitations of the 'C' language. Compared to -C++ and Python, 'C' has only very rudimentary abstraction facilities. -Support for exception-handling is completely missing. One important -undesirable consequence is that 'C' extension module writers are -required to manually manage Python reference counts. Another unpleasant -consequence is a very high degree of repetition of similar code in 'C' -extension modules. Of course highly redundant code does not only cause -frustration for the module writer, but is also very difficult to -maintain. - -The limitations of the 'C' API have lead to the development of a -variety of wrapping systems. SWIG_ is probably the most popular package -for the integration of C/C++ and Python. A more recent development is -the SIP_ package, which is specifically designed for interfacing Python -with the Qt_ graphical user interface library. Both SWIG and SIP -introduce a new specialized language for defining the inter-language -bindings. Of course being able to use a specialized language has -advantages, but having to deal with three different languages (Python, -C/C++ and the interface language) also introduces practical and mental -difficulties. The CXX_ package demonstrates an interesting alternative. -It shows that at least some parts of Python's 'C' API can be wrapped -and presented through a much more user-friendly C++ interface. However, -unlike SWIG and SIP, CXX does not include support for wrapping C++ -classes as new Python types. CXX is also no longer actively developed. - -In some respects Boost.Python combines ideas from SWIG and SIP with -ideas from CXX. Like SWIG and SIP, Boost.Python is a system for -wrapping C++ classes as new Python "built-in" types, and C/C++ -functions as Python functions. Like CXX, Boost.Python presents Python's -'C' API through a C++ interface. Boost.Python goes beyond the scope of -other systems with the unique support for C++ virtual functions that -are overrideable in Python, support for organizing extensions as Python -packages with a central registry for inter-language type conversions, -and a convenient mechanism for tying into Python's serialization engine -(pickle). Importantly, all this is achieved without introducing a new -syntax. Boost.Python leverages the power of C++ meta-programming -techniques to introspect about the C++ type system, and presents a -simple, IDL-like C++ interface for exposing C/C++ code in extension -modules. Boost.Python is a pure C++ library, the inter-language -bindings are defined in pure C++, and other than a C++ compiler only -Python itself is required to get started with Boost.Python. Last but -not least, Boost.Python is an unrestricted open source library. There -are no strings attached even for commercial applications. - -.. _SWIG: http://www.swig.org/ -.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php -.. _Qt: http://www.trolltech.com/ -.. _CXX: http://cxx.sourceforge.net/ - -=========================== - Boost.Python Design Goals -=========================== - -The primary goal of Boost.Python is to allow users to expose C++ -classes and functions to Python using nothing more than a C++ -compiler. In broad strokes, the user experience should be one of -directly manipulating C++ objects from Python. - -However, it's also important not to translate all interfaces *too* -literally: the idioms of each language must be respected. For -example, though C++ and Python both have an iterator concept, they are -expressed very differently. Boost.Python has to be able to bridge the -interface gap. - -It must be possible to insulate Python users from crashes resulting -from trivial misuses of C++ interfaces, such as accessing -already-deleted objects. By the same token the library should -insulate C++ users from low-level Python 'C' API, replacing -error-prone 'C' interfaces like manual reference-count management and -raw ``PyObject`` pointers with more-robust alternatives. - -Support for component-based development is crucial, so that C++ types -exposed in one extension module can be passed to functions exposed in -another without loss of crucial information like C++ inheritance -relationships. - -Finally, all wrapping must be *non-intrusive*, without modifying or -even seeing the original C++ source code. Existing C++ libraries have -to be wrappable by third parties who only have access to header files -and binaries. - -========================== - Hello Boost.Python World -========================== - -And now for a preview of Boost.Python, and how it improves on the raw -facilities offered by Python. Here's a function we might want to -expose:: - - char const* greet(unsigned x) - { - static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; - - if (x > 2) - throw std::range_error("greet: index out of range"); - - return msgs[x]; - } - -To wrap this function in standard C++ using the Python 'C' API, we'd -need something like this:: - - extern "C" // all Python interactions use 'C' linkage and calling convention - { - // Wrapper to handle argument/result conversion and checking - PyObject* greet_wrap(PyObject* args, PyObject * keywords) - { - int x; - if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments - { - char const* result = greet(x); // invoke wrapped function - return PyString_FromString(result); // convert result to Python - } - return 0; // error occurred - } - - // Table of wrapped functions to be exposed by the module - static PyMethodDef methods[] = { - { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } - , { NULL, NULL, 0, NULL } // sentinel - }; - - // module initialization function - DL_EXPORT init_hello() - { - (void) Py_InitModule("hello", methods); // add the methods to the module - } - } - -Now here's the wrapping code we'd use to expose it with Boost.Python:: - - #include - using namespace boost::python; - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet, "return one of 3 parts of a greeting"); - } - -and here it is in action:: - - >>> import hello - >>> for x in range(3): - ... print hello.greet(x) - ... - hello - Boost.Python - world! - -Aside from the fact that the 'C' API version is much more verbose than -the BPL one, it's worth noting that it doesn't handle a few things -correctly: - -* The original function accepts an unsigned integer, and the Python - 'C' API only gives us a way of extracting signed integers. The - Boost.Python version will raise a Python exception if we try to pass - a negative number to ``hello.greet``, but the other one will proceed - to do whatever the C++ implementation does when converting an - negative integer to unsigned (usually wrapping to some very large - number), and pass the incorrect translation on to the wrapped - function. - -* That brings us to the second problem: if the C++ ``greet()`` - function is called with a number greater than 2, it will throw an - exception. Typically, if a C++ exception propagates across the - boundary with code generated by a 'C' compiler, it will cause a - crash. As you can see in the first version, there's no C++ - scaffolding there to prevent this from happening. Functions wrapped - by Boost.Python automatically include an exception-handling layer - which protects Python users by translating unhandled C++ exceptions - into a corresponding Python exception. - -* A slightly more-subtle limitation is that the argument conversion - used in the Python 'C' API case can only get that integer ``x`` in - *one way*. PyArg_ParseTuple can't convert Python ``long`` objects - (arbitrary-precision integers) which happen to fit in an ``unsigned - int`` but not in a ``signed long``, nor will it ever handle a - wrapped C++ class with a user-defined implicit ``operator unsigned - int()`` conversion. The BPL's dynamic type conversion registry - allows users to add arbitrary conversion methods. - -================== - Library Overview -================== - -This section outlines some of the library's major features. Except as -necessary to avoid confusion, details of library implementation are -omitted. - -------------------------------------------- - The fundamental type-conversion mechanism -------------------------------------------- - -XXX This needs to be rewritten. - -Every argument of every wrapped function requires some kind of -extraction code to convert it from Python to C++. Likewise, the -function return value has to be converted from C++ to Python. -Appropriate Python exceptions must be raised if the conversion fails. -Argument and return types are part of the function's type, and much of -this tedium can be relieved if the wrapping system can extract that -information through introspection. - -Passing a wrapped C++ derived class instance to a C++ function -accepting a pointer or reference to a base class requires knowledge of -the inheritance relationship and how to translate the address of a base -class into that of a derived class. - ------------------- - Exposing Classes ------------------- - -C++ classes and structs are exposed with a similarly-terse interface. -Given:: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -The following code will expose it in our extension module:: - - #include - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Although this code has a certain pythonic familiarity, people -sometimes find the syntax bit confusing because it doesn't look like -most of the C++ code they're used to. All the same, this is just -standard C++. Because of their flexible syntax and operator -overloading, C++ and Python are great for defining domain-specific -(sub)languages -(DSLs), and that's what we've done in BPL. To break it down:: - - class_("World") - -constructs an unnamed object of type ``class_`` and passes -``"World"`` to its constructor. This creates a new-style Python class -called ``World`` in the extension module, and associates it with the -C++ type ``World`` in the BPL type conversion registry. We might have -also written:: - - class_ w("World"); - -but that would've been more verbose, since we'd have to name ``w`` -again to invoke its ``def()`` member function:: - - w.def("greet", &World::greet) - -There's nothing special about the location of the dot for member -access in the original example: C++ allows any amount of whitespace on -either side of a token, and placing the dot at the beginning of each -line allows us to chain as many successive calls to member functions -as we like with a uniform syntax. The other key fact that allows -chaining is that ``class_<>`` member functions all return a reference -to ``*this``. - -So the example is equivalent to:: - - class_ w("World"); - w.def("greet", &World::greet); - w.def("set", &World::set); - -It's occasionally useful to be able to break down the components of a -Boost.Python class wrapper in this way, but the rest of this paper -will tend to stick to the terse syntax. - -For completeness, here's the wrapped class in use: - ->>> import hello ->>> planet = hello.World() ->>> planet.set('howdy') ->>> planet.greet() -'howdy' - -Constructors -============ - -Since our ``World`` class is just a plain ``struct``, it has an -implicit no-argument (nullary) constructor. Boost.Python exposes the -nullary constructor by default, which is why we were able to write: - ->>> planet = hello.World() - -However, well-designed classes in any language may require constructor -arguments in order to establish their invariants. Unlike Python, -where ``__init__`` is just a specially-named method, In C++ -constructors cannot be handled like ordinary member functions. In -particular, we can't take their address: ``&World::World`` is an -error. The library provides a different interface for specifying -constructors. Given:: - - struct World - { - World(std::string msg); // added constructor - ... - -we can modify our wrapping code as follows:: - - class_("World", init()) - ... - -of course, a C++ class may have additional constructors, and we can -expose those as well by passing more instances of ``init<...>`` to -``def()``:: - - class_("World", init()) - .def(init()) - ... - -Boost.Python allows wrapped functions, member functions, and -constructors to be overloaded to mirror C++ overloading. - -Data Members and Properties -=========================== - -Any publicly-accessible data members in a C++ class can be easily -exposed as either ``readonly`` or ``readwrite`` attributes:: - - class_("World", init()) - .def_readonly("msg", &World::msg) - ... - -and can be used directly in Python: - ->>> planet = hello.World('howdy') ->>> planet.msg -'howdy' - -This does *not* result in adding attributes to the ``World`` instance -``__dict__``, which can result in substantial memory savings when -wrapping large data structures. In fact, no instance ``__dict__`` -will be created at all unless attributes are explicitly added from -Python. BPL owes this capability to the new Python 2.2 type system, -in particular the descriptor interface and ``property`` type. - -In C++, publicly-accessible data members are considered a sign of poor -design because they break encapsulation, and style guides usually -dictate the use of "getter" and "setter" functions instead. In -Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, -``property`` mean that attribute access is just one more -well-encapsulated syntactic tool at the programmer's disposal. BPL -bridges this idiomatic gap by making Python ``property`` creation -directly available to users. So if ``msg`` were private, we could -still expose it as attribute in Python as follows:: - - class_("World", init()) - .add_property("msg", &World::greet, &World::set) - ... - -The example above mirrors the familiar usage of properties in Python -2.2+: - ->>> class World(object): -... __init__(self, msg): -... self.__msg = msg -... def greet(self): -... return self.__msg -... def set(self, msg): -... self.__msg = msg -... msg = property(greet, set) - -Operators and Special Functions -=============================== - -The ability to write arithmetic operators for user-defined types that -C++ and Python both allow the definition of has been a major factor in -the popularity of both languages for scientific computing. The -success of packages like NumPy attests to the power of exposing -operators in extension modules. In this example we'll wrap a class -representing a position in a large file:: - - class FilePos { /*...*/ }; - - // Linear offset - FilePos operator+(FilePos, int); - FilePos operator+(int, FilePos); - FilePos operator-(FilePos, int); - - // Distance between two FilePos objects - int operator-(FilePos, FilePos); - - // Offset with assignment - FilePos& operator+=(FilePos&, int); - FilePos& operator-=(FilePos&, int); - - // Comparison - bool operator<(FilePos, FilePos); - -The wrapping code looks like this:: - - class_("FilePos") - .def(self + int()) // __add__ - .def(int() + self) // __radd__ - .def(self - int()) // __sub__ - - .def(self - self) // __sub__ - - .def(self += int()) // __iadd__ - .def(self -= int()) // __isub__ - - .def(self < self); // __lt__ - ; - -The magic is performed using a simplified application of "expression -templates" [VELD1995]_, a technique originally developed by for -optimization of high-performance matrix algebra expressions. The -essence is that instead of performing the computation immediately, -operators are overloaded to construct a type *representing* the -computation. In matrix algebra, dramatic optimizations are often -available when the structure of an entire expression can be taken into -account, rather than processing each operation "greedily". -Boost.Python uses the same technique to build an appropriate Python -callable object based on an expression involving ``self``, which is -then added to the class. - -Inheritance -=========== - -C++ inheritance relationships can be represented to Boost.Python by adding -an optional ``bases<...>`` argument to the ``class_<...>`` template -parameter list as follows:: - - class_ >("Derived") - ... - -This has two effects: - -1. When the ``class_<...>`` is created, Python type objects - corresponding to ``Base1`` and ``Base2`` are looked up in the BPL - registry, and are used as bases for the new Python ``Derived`` type - object [#mi]_, so methods exposed for the Python ``Base1`` and - ``Base2`` types are automatically members of the ``Derived`` type. - Because the registry is global, this works correctly even if - ``Derived`` is exposed in a different module from either of its - bases. - -2. C++ conversions from ``Derived`` to its bases are added to the - Boost.Python registry. Thus wrapped C++ methods expecting (a - pointer or reference to) an object of either base type can be - called with an object wrapping a ``Derived`` instance. Wrapped - member functions of class ``T`` are treated as though they have an - implicit first argument of ``T&``, so these conversions are - necessary to allow the base class methods to be called for derived - objects. - -Of course it's possible to derive new Python classes from wrapped C++ -class instances. Because Boost.Python uses the new-style class -system, that works very much as for the Python built-in types. There -is one significant detail in which it differs: the built-in types -generally establish their invariants in their ``__new__`` function, so -that derived classes do not need to call ``__init__`` on the base -class before invoking its methods : - ->>> class L(list): -... def __init__(self): -... pass -... ->>> L().reverse() ->>> - -Because C++ object construction is a one-step operation, C++ instance -data cannot be constructed until the arguments are available, in the -``__init__`` function: - ->>> class D(SomeBPLClass): -... def __init__(self): -... pass -... ->>> D().some_bpl_method() -Traceback (most recent call last): - File "", line 1, in ? -TypeError: bad argument type for built-in operation - -This happened because Boost.Python couldn't find instance data of type -``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__`` -function masked construction of the base class. It could be corrected -by either removing ``D``'s ``__init__`` function or having it call -``SomeBPLClass.__init__(...)`` explicitly. - -Virtual Functions -================= - -Deriving new types in Python from extension classes is not very -interesting unless they can be used polymorphically from C++. In -other words, Python method implementations should appear to override -the implementation of C++ virtual functions when called *through base -class pointers/references from C++*. Since the only way to alter the -behavior of a virtual function is to override it in a derived class, -the user must build a special derived class to dispatch a polymorphic -class' virtual functions:: - - // - // interface to wrap: - // - class Base - { - public: - virtual int f(std::string x) { return 42; } - virtual ~Base(); - }; - - int calls_f(Base const& b, std::string x) { return b.f(x); } - - // - // Wrapping Code - // - - // Dispatcher class - struct BaseWrap : Base - { - // Store a pointer to the Python object - BaseWrap(PyObject* self_) : self(self_) {} - PyObject* self; - - // Default implementation, for when f is not overridden - int f_default(std::string x) { return this->Base::f(x); } - // Dispatch implementation - int f(std::string x) { return call_method(self, "f", x); } - }; - - ... - def("calls_f", calls_f); - class_("Base") - .def("f", &Base::f, &BaseWrap::f_default) - ; - -Now here's some Python code which demonstrates: - ->>> class Derived(Base): -... def f(self, s): -... return len(s) -... ->>> calls_f(Base(), 'foo') -42 ->>> calls_f(Derived(), 'forty-two') -9 - -Things to notice about the dispatcher class: - -* The key element which allows overriding in Python is the - ``call_method`` invocation, which uses the same global type - conversion registry as the C++ function wrapping does to convert its - arguments from C++ to Python and its return type from Python to C++. - -* Any constructor signatures you wish to wrap must be replicated with - an initial ``PyObject*`` argument - -* The dispatcher must store this argument so that it can be used to - invoke ``call_method`` - -* The ``f_default`` member function is needed when the function being - exposed is not pure virtual; there's no other way ``Base::f`` can be - called on an object of type ``BaseWrap``, since it overrides ``f``. - -Admittedly, this formula is tedious to repeat, especially on a project -with many polymorphic classes; that it is necessary reflects -limitations in C++'s compile-time reflection capabilities. Several -efforts are underway to write front-ends for Boost.Python which can -generate these dispatchers (and other wrapping code) automatically. -If these are successful it will mark a move away from wrapping -everything directly in pure C++ for many of our users. - ---------------- - Serialization ---------------- - -*Serialization* is the process of converting objects in memory to a -form that can be stored on disk or sent over a network connection. The -serialized object (most often a plain string) can be retrieved and -converted back to the original object. A good serialization system will -automatically convert entire object hierarchies. Python's standard -``pickle`` module is such a system. It leverages the language's strong -runtime introspection facilities for serializing practically arbitrary -user-defined objects. With a few simple and unintrusive provisions this -powerful machinery can be extended to also work for wrapped C++ objects. -Here is an example:: - - #include - - struct World - { - World(std::string a_msg) : msg(a_msg) {} - std::string greet() const { return msg; } - std::string msg; - }; - - #include - using namespace boost::python; - - struct World_picklers : pickle_suite - { - static tuple - getinitargs(World const& w) { return make_tuple(w.greet()); } - }; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def_pickle(World_picklers()) - ; - } - -Now let's create a ``World`` object and put it to rest on disk:: - - >>> import hello - >>> import pickle - >>> a_world = hello.World("howdy") - >>> pickle.dump(a_world, open("my_world", "w")) - -In a potentially *different script* on a potentially *different -computer* with a potentially *different operating system*:: - - >>> import pickle - >>> resurrected_world = pickle.load(open("my_world", "r")) - >>> resurrected_world.greet() - 'howdy' - -Of course the ``cPickle`` module can also be used for faster -processing. - -Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol -defined in the standard Python documentation. There is a one-to-one -correspondence between the standard pickling methods (``__getinitargs__``, -``__getstate__``, ``__setstate__``) and the functions defined by the -user in the class derived from ``pickle_suite`` (``getinitargs``, -``getstate``, ``setstate``). The ``class_::def_pickle()`` member function -is used to establish the Python bindings for all user-defined functions -simultaneously. Correct signatures for these functions are enforced at -compile time. Non-sensical combinations of the three pickle functions -are also rejected at compile time. These measures are designed to -help the user in avoiding obvious errors. - -Enabling serialization of more complex C++ objects requires a little -more work than is shown in the example above. Fortunately the -``object`` interface (see next section) greatly helps in keeping the -code manageable. - ------------------- - Object interface ------------------- - -Experienced extension module authors will be familiar with the 'C' view -of Python objects, the ubiquitous ``PyObject*``. Most if not all Python -'C' API functions involve ``PyObject*`` as arguments or return type. A -major complication is the raw reference counting interface presented to -the 'C' programmer. E.g. some API functions return *new references* and -others return *borrowed references*. It is up to the extension module -writer to properly increment and decrement reference counts. This -quickly becomes cumbersome and error prone, especially if there are -multiple execution paths. - -Boost.Python provides a type ``object`` which is essentially a high -level wrapper around ``PyObject*``. ``object`` automates reference -counting as much as possible. It also provides the facilities for -converting arbitrary C++ types to Python objects and vice versa. -This significantly reduces the learning effort for prospective -extension module writers. - -Creating an ``object`` from any other type is extremely simple:: - - object o(3); - -``object`` has templated interactions with all other types, with -automatic to-python conversions. It happens so naturally that it's -easily overlooked. - -The ``extract`` class template can be used to convert Python objects -to C++ types:: - - double x = extract(o); - -All registered user-defined conversions are automatically accessible -through the ``object`` interface. With reference to the ``World`` class -defined in previous examples:: - - object as_python_object(World("howdy")); - World back_as_c_plus_plus_object = extract(as_python_object); - -If a C++ type cannot be converted to a Python object an appropriate -exception is thrown at runtime. Similarly, an appropriate exception is -thrown if a C++ type cannot be extracted from a Python object. -``extract`` provides facilities for avoiding exceptions if this is -desired. - -The ``object::attr()`` member function is available for accessing -and manipulating attributes of Python objects. For example:: - - object planet(World()); - planet.attr("set")("howdy"); - -``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is -converted to a Python string object which is then passed as an argument -to the ``set`` method. - -The ``object`` type is accompanied by a set of derived types -that mirror the Python built-in types such as ``list``, ``dict``, -``tuple``, etc. as much as possible. This enables convenient -manipulation of these high-level types from C++:: - - dict d; - d["some"] = "thing"; - d["lucky_number"] = 13; - list l = d.keys(); - -This almost looks and works like regular Python code, but it is pure C++. - -================= - Thinking hybrid -================= - -For many applications runtime performance considerations are very -important. This is particularly true for most scientific applications. -Often the performance considerations dictate the use of a compiled -language for the core algorithms. Traditionally the decision to use a -particular programming language is an exclusive one. Because of the -practical and mental difficulties of combining different languages many -systems are written in just one language. This is quite unfortunate -because the price payed for runtime performance is typically a -significant overhead due to static typing. For example, our experience -shows that developing maintainable C++ code is typically much more -time-consuming and requires much more hard-earned working experience -than developing useful Python code. A related observation is that many -compiled packages are augmented by some type of rudimentary scripting -layer. These ad hoc solutions clearly show that many times a compiled -language alone does not get the job done. On the other hand it is also -clear that a pure Python implementation is too slow for numerically -intensive production code. - -Boost.Python enables us to *think hybrid* when developing new -applications. Python can be used for rapidly prototyping a -new application. Python's ease of use and the large pool of standard -libraries give us a head start on the way to a first working system. If -necessary, the working procedure can be used to discover the -rate-limiting algorithms. To maximize performance these can be -reimplemented in C++, together with the Boost.Python bindings needed to -tie them back into the existing higher-level procedure. - -Of course, this *top-down* approach is less attractive if it is clear -from the start that many algorithms will eventually have to be -implemented in a compiled language. Fortunately Boost.Python also -enables us to pursue a *bottom-up* approach. We have used this approach -very successfully in the development of a toolbox for scientific -applications (scitbx) that we will describe elsewhere. The toolbox -started out mainly as a library of C++ classes with Boost.Python -bindings, and for a while the growth was mainly concentrated on the C++ -parts. However, as the toolbox is becoming more complete, more and more -newly added functionality can be implemented in Python. We expect this -trend to continue, as illustrated qualitatively in this figure: - -.. image:: python_cpp_mix.png - -This figure shows the ratio of newly added C++ and Python code over -time as new algorithms are implemented. We expect this ratio to level -out near 70% Python. The increasing ability to solve new problems -mostly with the easy-to-use Python language rather than a necessarily -more arcane statically typed language is the return on the investment -of learning how to use Boost.Python. The ability to solve some problems -entirely using only Python will enable a larger group of people to -participate in the rapid development of new applications. - -============= - Conclusions -============= - -The examples in this paper illustrate that Boost.Python enables -seamless interoperability between C++ and Python. Importantly, this is -achieved without introducing a third syntax: the Python/C++ interface -definitions are written in pure C++. This avoids any problems with -parsing the C++ code to be interfaced to Python, yet the interface -definitions are concise and maintainable. Freed from most of the -development-time penalties of crossing a language boundary, software -designers can take full advantage of two rich and complimentary -language environments. In practice it turns out that some things are -very difficult to do with pure Python/C (e.g. an efficient array -library with an intuitive interface in the compiled language) and -others are very difficult to do with pure C++ (e.g. serialization). -If one has the luxury of being able to design a software system as a -hybrid system from the ground up there are many new ways of avoiding -road blocks in one language or the other. - -.. I'm not ready to give up on all of this quite yet - -.. Perhaps one day we'll have a language with the simplicity and - expressive power of Python and the compile-time muscle of C++. Being - able to take advantage of all of these facilities without paying the - mental and development-time penalties of crossing a language barrier - would bring enormous benefits. Until then, interoperability tools - like Boost.Python can help lower the barrier and make the benefits of - both languages more accessible to both communities. - -=========== - Footnotes -=========== - -.. [#mi] For hard-core new-style class/extension module writers it is - worth noting that the normal requirement that all extension classes - with data form a layout-compatible single-inheritance chain is - lifted for Boost.Python extension classes. Clearly, either - ``Base1`` or ``Base2`` has to occupy a different offset in the - ``Derived`` class instance. This is possible because the wrapped - part of BPL extension class instances is never assumed to have a - fixed offset within the wrapper. - -=========== - Citations -=========== - -.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, - Vol. 7 No. 5 June 1995, pp. 26-31. - http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html diff --git a/doc/PyConDC_2003/default.css b/doc/PyConDC_2003/default.css deleted file mode 100644 index 6a1adb08..00000000 --- a/doc/PyConDC_2003/default.css +++ /dev/null @@ -1,190 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date$ -:version: $Revision$ -:copyright: This stylesheet has been placed in the public domain. - -boostinspect:nolicense - -Default cascading style sheet for the HTML output of Docutils. -*/ - -.first { - margin-top: 0 } - -.last { - margin-bottom: 0 } - -a.toc-backref { - text-decoration: none ; - color: black } - -dd { - margin-bottom: 0.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - font-size: smaller } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.title { - text-align: center } - -h2.subtitle { - text-align: center } - -hr { - width: 75% } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.label { - white-space: nowrap } - -p.topic-title { - font-weight: bold } - -pre.address { - margin-bottom: 0 ; - margin-top: 0 ; - font-family: serif ; - font-size: 100% } - -pre.line-block { - font-family: serif ; - font-size: 100% } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.interpreted { - font-family: sans-serif } - -span.option-argument { - font-style: italic } - -span.pre { - white-space: pre } - -span.problematic { - color: red } - -table { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.citation { - border-left: solid thin gray ; - padding-left: 0.5ex } - -table.docinfo { - margin: 2em 4em } - -table.footnote { - border-left: solid thin black ; - padding-left: 0.5ex } - -td, th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: top } - -th.docinfo-name, th.field-name { - font-weight: bold ; - text-align: left ; - white-space: nowrap } - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - font-size: 100% } - -tt { - background-color: #eeeeee } - -ul.auto-toc { - list-style-type: none } diff --git a/doc/PyConDC_2003/python_cpp_mix.jpg b/doc/PyConDC_2003/python_cpp_mix.jpg deleted file mode 100755 index 755a9605..00000000 Binary files a/doc/PyConDC_2003/python_cpp_mix.jpg and /dev/null differ diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png deleted file mode 100755 index fd74cbb2..00000000 Binary files a/doc/PyConDC_2003/python_cpp_mix.png and /dev/null differ diff --git a/doc/boost.css b/doc/boost.css deleted file mode 100644 index 6c3e9808..00000000 --- a/doc/boost.css +++ /dev/null @@ -1,63 +0,0 @@ -/* 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) -*/ -H1 -{ - FONT-SIZE: 200% - COLOR: #00007f -} -H2 -{ - FONT-SIZE: 150%; -} -H3 -{ - FONT-SIZE: 125%; -} -H4 -{ - FONT-SIZE: 108%; -} -BODY -{ - FONT-SIZE: 100%; - BACKGROUND-COLOR: #ffffff -} -PRE -{ - MARGIN-LEFT: 2pc; - FONT-SIZE: 80%; - BACKGROUND-COLOR: #dfffff -} -CODE -{ - FONT-SIZE: 95%; - white-space: pre -} -.index -{ - TEXT-ALIGN: left -} -.page-index -{ - TEXT-ALIGN: left -} -.definition -{ - TEXT-ALIGN: left -} -.footnote -{ - FONT-SIZE: 66%; - VERTICAL-ALIGN: super; - TEXT-DECORATION: none -} -.function-semantics -{ - CLEAR: left -} -.metafunction-semantics -{ - CLEAR: left -} diff --git a/doc/building.html b/doc/building.html deleted file mode 100644 index 51562b8a..00000000 --- a/doc/building.html +++ /dev/null @@ -1,463 +0,0 @@ - - - - - - - - - - - - Boost.Python - Building and Testing - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Building and Testing

-
-
- -

Contents

- -
-
Requirements
- -
Building Boost.Python
- -
-
-
Configuration
- -
Configuration for Cygwin GCC - from a Windows prompt
- -
Results
- -
Notes for Cygwin GCC Users
- -
Notes for MinGW (and Cygwin with -mno-cygwin) - GCC Users
- -
Testing
-
-
- -
Building your Extension Module
- -
Build Variants
- -
Building Using the Microsoft Visual Studio - IDE
-
-
- -

Requirements

- Boost.Python version 2 requires Python 2.2 or newer. An unsupported archive of - Boost.Python version 1, which works with versions of Python since 1.5.2, - is available here. - -

Building Boost.Python

- -

Normally, Boost.Python extension modules must be linked with the - boost_python shared library. In special circumstances you - may want to link to a static version of the boost_python - library, but if multiple Boost.Python extension modules are used - together, it will prevent sharing of types across extension modules, and - consume extra code space. To build boost_python, use Boost.Build in the - usual way from the libs/python/build subdirectory of your - boost installation (if you have already built boost from the top level - this may have no effect, since the work is already done).

- -

Basic Configuration

You may - need to configure the following variables to point Boost.Build at - your Python installation. Variables can be either set in the - environment or passed on the bjam command-line - as -sname=value. Variable - names are case-sensitive. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variable NameSemanticsDefaultNotes
PYTHON_VERSIONThe The 2-part python Major.Minor version number2.4Be sure not to include a third number, e.g. not - "2.2.1", even if that's the version you have.
PYTHON_ROOTThe root directory of your Python installationWindows: c:/Python(10*Version), e.g. c:/Python24 -
- *nix/Cygwin: /usr
On *nix, this should be the --prefix= directory used - to configure Python when it was built and installed.
PYTHON_INCLUDESpath to Python #include directoriesAutoconfigured from PYTHON_ROOT. Try the default - before attempting to set it yourself.
PYTHON_LIB_PATHpath to Python library object.Autoconfigured from PYTHON_ROOT. Try the default - before attempting to set it yourself.
- -

Configuration for Cygwin GCC from a - Windows prompt

- The following settings may be useful when building with Cygwin GCC (not MinGW) from a Windows command - shell using a Windows build of bjam. If - "bjam -v" does not report "OS=NT", these - settings do not apply to you; you should use the normal configuration variables instead. They are - only useful when building and testing with multiple toolsets on Windows - using a single build command, since Cygwin GCC requires a different build - of Python. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variable NameSemanticsDefault
CYGWIN_PYTHON_[DEBUG_]VERSIONThe version of python being used under Cygwin.$(PYTHON_VERSION)
CYGWIN_PYTHON_[DEBUG_]ROOT*nix-style path containing the include/ directory - containing - python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h.$(PYTHON_ROOT)
CYGWIN_PYTHON_[DEBUG_]LIB_PATHpath containing the user's Cygwin Python import lib - libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.aAutoconfigured from CYGWIN_PYTHON_ROOT
CYGWIN_PYTHON_[DEBUG_]DLL_PATHpath containing the user's Cygwin Python dll - (libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll)/bin
- -

Notes for Cygwin GCC Users

- -

If you are using Cygwin GCC to build extension modules, you must use a - Cygwin build of Python. The regular Win32 Python installation that you - can download from python.org will not - work with your compiler because the dynamic linking conventions are - different (you can use MinGW GCC if - you want to build extension modules which are compatible with a stock - Win32 Python). The Cygwin installer may be able to install an appropriate - version of Python, or you can follow the traditional Unix installation - process to build Python from source.

- -

The special build configuration variables listed above make it possible to use a regular Win32 - build of bjam to build and test Boost.Python and Boost.Python extensions - using Cygwin GCC and targeting a Cygwin build of Python.

- -

Notes for MinGW (and Cygwin with -mno-cygwin) GCC - Users

- -

If you are using a version of Python prior to 2.4.1 with a - MinGW prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will - need to create a MinGW-compatible version of the Python library; - the one shipped with Python will only work with a - Microsoft-compatible linker. Follow the instructions in the - "Non-Microsoft" section of the "Building Extensions: Tips And Tricks" - chapter in Installing Python - Modules to create libpythonXX.a, where XX - corresponds to the major and minor version numbers of your Python - installation.

- -

Results

- -

The build process will create a - libs/python/build/bin-stage subdirectory of the boost root - (or of $(ALL_LOCATE_TARGET), if you have set that variable), - containing the built libraries. The libraries are actually built to - unique directories for each toolset and variant elsewhere in the - filesystem, and copied to the bin-stage directory as a - convenience, so if you build with multiple toolsets at once, the product - of later toolsets will overwrite that of earlier toolsets in - bin-stage.

- -

Testing

- -

To build and test Boost.Python, start from the - libs/python/test directory and invoke

- -
-
-bjam -sTOOLS=toolset test
-
-
- This will update all of the Boost.Python v1 test and example targets. The - tests are relatively verbose by default. To get less-verbose output, you - might try - -
-
-bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS= test
-
-
- By default, PYTHON_TEST_ARGS is set to -v. - -

Building your Extension Module

- Though there are other approaches, the smoothest and most reliable way to - build an extension module using Boost.Python is with Boost.Build. If you - have to use another build system, you should use Boost.Build at least - once with the "-n" option so you can see the - command-lines it uses, and replicate them. You are likely to run into - compilation or linking problems otherwise. - -

The files required to build a Boost.Python extension module using bjam - are the "local" files Jamfile, Jamrules, and - boost_build.jam, and the boost/ - and tools/build/v1/ subdirectories of your Boost - tree. The latter directory contains the source code of the - Boost.Build system, which is used to generate the correct build - commands for your extension module. The 'v1' refers to - Boost.Build version 1. Version 2 is pre-release and currently not - ready for general use. - -

- The libs/python/example/ project we're going to build is - set up to automatically rebuild the Boost.Python library in place - whenever it's out-of-date rather than just reusing an existing - library, so you'll also need the Boost.Python library sources in - boost/python/src/. -

- -
- Note: Third-party package and distribution maintainers - for various operating systems sometimes split up Boost's - structure or omit parts of it, so if you didn't download an - official Boost - release you might want to browse our CVS - structure to make sure you have everything you need, and in the - right places. -
- -

The libs/python/example - subdirectory of your boost installation contains a small example which - builds and tests two extensions. To build your own extensions copy the - example subproject and make the following two edits:

- -
    -
  1. - boost-build.jam - edit - the line which reads - -
    -
    -boost-build ../../../tools/build/v1 ;
    -
    -
    - so that the path refers to the tools/build/v1 - subdirectory of your Boost installation. -
  2. - -
  3. - Jamrules - edit - the line which reads - -
    -
    -path-global BOOST_ROOT : ../../.. ;
    -
    -
    - so that the path refers to the root directory of your Boost - installation. -
  4. -
- -

The instructions above for testing Boost.Python - apply equally to your new extension modules in this subproject.

- -

Build Variants

- Three variant - configurations of all python-related targets are supported, and can be - selected by setting the BUILD - variable: - -
    -
  • release (optimization, -DNDEBUG)
  • - -
  • debug (no optimization -D_DEBUG)
  • - -
  • debug-python (no optimization, -D_DEBUG - -DBOOST_DEBUG_PYTHON)
  • -
- -

The first two variants of the boost_python library are - built by default, and are compatible with the default Python - distribution. The debug-python variant corresponds to a - specially-built debugging version of Python. On *nix platforms, this - python is built by adding --with-pydebug when configuring - the Python build. On Windows, the debugging version of Python is - generated by the "Win32 Debug" target of the PCBuild.dsw - Visual C++ 6.0 project in the PCBuild subdirectory of your - Python distribution. Extension modules built with Python debugging - enabled are not link-compatible with a non-debug build of Python. - Since few people actually have a debug build of Python (it doesn't come - with the standard distribution), the normal debug variant - builds modules which are compatible with ordinary Python.

- -

On many windows compilers, when extension modules are built with - -D_DEBUG, Python defaults to force linking with a special - debugging version of the Python DLL. Since this debug DLL isn't supplied - with the default Python installation for Windows, Boost.Python uses - boost/python/detail/wrap_python.hpp - to temporarily undefine _DEBUG when Python.h is - #included - unless BOOST_DEBUG_PYTHON is - defined.

- -

If you want the extra runtime checks available with the debugging - version of the library, #define BOOST_DEBUG_PYTHON to re-enable - python debuggin, and link with the debug-python variant of - boost_python.

- -

If you do not #define BOOST_DEBUG_PYTHON, be sure that any - source files in your extension module #include <boost/python/detail/wrap_python.hpp> - instead of the usual Python.h, or you will have link - incompatibilities.
-

- -

Building Using the Microsoft Visual Studio - IDE

- -

For the those of you who feel more comfortable in the IDE world, a - workspace and project file have been included in the - libs/python/build/VisualStudio subdirectory. - It builds release and debug versions of the Boost.Python libraries and - places them and the same directory as Jamfile build does, though the - intermediate object files are placed in a different directory. The files - have been created using Microsoft Visual C++ version 6, but they should - work for later versions as well. You will need to tell the IDE where to - find the Python Include/ and Libs/ directories. - Under Tools>Options>Directories, add an entry for the Python - include dir (i.e. c:/Python22/Include), and one for the Lib - (i.e. c:/Python/Libs. Make sure it is Libs with - an "s" and not just Lib).

- -

Using the IDE for your own projects

- -

Building your own projects using the IDE is slightly more complicated. - Firstly, you need to make sure that the project you create as the right - kind. It should be a "Win32 Dynamic-Link Library". The default one that - Visual Studio 6 creates needs some modifications: turn on RTTI, and - change the debug and release builds to use the respective debug and - release Multithreaded DLL versions. You should probably turn off - incremental linking too -- I believe it a bit flaky. If you do this, then - change the "Debug Info" to "Program Database" to get rid of the Edit and - Continue warning.

- -

You'll need to add the Boost root directory under - Tools>Options>Directories to get your code compiling. To - make it link, add the above boost_python.dsp file to your - workspace, and make your project depend upon it (under - Project>Dependencies). You should be able to build now.

- -

Lastly, go to the Project Settings>Debug Page and add the - Python.exe as the executable for the project. Set a startup - directory, and make sure that your current project's output dll, the - boost_python.dll and the python22.dll are on - the current PATH. If you have a python script that tests - your dll, then add it in the "Program Arguments". Now, if all went well, - you should be able to hit the Run (F5) button, and debug your code.

- -
- The Visual Studio project files are graciously contributed and - maintained by Brett - Calcott. -
-
- -

© Copyright David Abrahams 2002-2004. Permission to copy, - use, modify, sell and distribute this document is granted provided - this copyright notice appears in all copies. This document is - provided ``as is'' without express or implied warranty, and with - no claim as to its suitability for any purpose.

- -

Updated: 13 April 2004 (David Abrahams)

- - - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index d8795e92..00000000 --- a/doc/index.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - Boost.Python - - - - - - - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Index

-
- -
-

- - Search - -
-
- - - - - -
- - - GooglePowered - - - - - - -
- - -

-
- -
-
- - -

Synopsis

- Welcome to version 2 of Boost.Python, a C++ library which enables - seamless interoperability between C++ and the Python programming language. The new version - has been rewritten from the ground up, with a more convenient and - flexible interface, and many new capabilities, including support for: - -
    -
  • References and Pointers
  • - -
  • Globally Registered Type Coercions
  • - -
  • Automatic Cross-Module Type Conversions
  • - -
  • Efficient Function Overloading
  • - -
  • C++ to Python Exception Translation
  • - -
  • Default Arguments
  • - -
  • Keyword Arguments
  • - -
  • Manipulating Python objects in C++
  • - -
  • Exporting C++ Iterators as Python Iterators
  • - -
  • Documentation Strings
  • -
- The development of these features was funded in part by grants to Boost Consulting from the Lawrence Livermore National Laboratories - and by the Computational Crystallography - Initiative at Lawrence Berkeley National Laboratories. - -
- -

Contents

- -
-
Tutorial Introduction
- -
Building and Testing
- -
Reference Manual
- -
Suites:
-
- -
- -
Configuration Information
- -
Known Working Platforms and - Compilers
- -
Definitions
- -
Projects using Boost.Python
- -
Support Resources
- -
Frequently Asked Questions (FAQs)
- -
Pyste (Boost.Python code generator)
- -
Internals Documentation
- -
News/Change Log
- -
TODO list
- -
LLNL Progress Reports
- -
Acknowledgments
-
-
- -

Articles

- - "Building Hybrid - Systems With Boost Python", by Dave Abrahams and Ralf - W. Grosse-Kunstleve (PDF) - -
- -

Revised - - 26 August, 2003 - -

- -

© Copyright Dave - Abrahams 2002-2003.

- - - diff --git a/doc/internals.html b/doc/internals.html deleted file mode 100755 index 2f7d7607..00000000 --- a/doc/internals.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - -Boost.Python Internals Boost - - - - - - - - diff --git a/doc/internals.rst b/doc/internals.rst deleted file mode 100755 index 2438d5ff..00000000 --- a/doc/internals.rst +++ /dev/null @@ -1,182 +0,0 @@ -=================================== - Boost.Python_ Internals |(logo)|__ -=================================== - -.. |(logo)| image:: ../../../boost.png - :alt: Boost - :class: boost-logo - -__ ../../../index.htm - -.. _`Boost.Python`: index.html - -.. _license: ../../../LICENSE_1_0.txt - - -------------------------------------------------------- -A conversation between Brett Calcott and David Abrahams -------------------------------------------------------- - -:copyright: Copyright David Abrahams and Brett Calcott 2003. See - accompanying license_ for terms of use. - -In both of these cases, I'm quite capable of reading code - but the -thing I don't get from scanning the source is a sense of the -architecture, both structurally, and temporally (er, I mean in what -order things go on). - -1) What happens when you do the following:: - - struct boring {}; - ...etc... - class_("boring") - ; - -There seems to be a fair bit going on. - - - Python needs a new ClassType to be registered. - - We need to construct a new type that can hold our boring struct. - - Inward and outward converters need to be registered for the type. - -Can you gesture in the general direction where these things are done? - - I only have time for a "off-the-top-of-my-head" answer at the moment; - I suggest you step through the code with a debugger after reading this - to see how it works, fill in details, and make sure I didn't forget - anything. - - A new (Python) subclass of Boost.Python.Instance (see - libs/python/src/object/class.cpp) is created by invoking - Boost.Python.class, the metatype:: - - >>> boring = Boost.Python.class( - ... 'boring' - ... , bases_tuple # in this case, just () - ... , { - ... '__module__' : module_name - ... , '__doc__' : doc_string # optional - ... } - ... ) - - A handle to this object is stuck in the m_class_object field - of the registration associated with ``typeid(boring)``. The - registry will keep that object alive forever, even if you - wipe out the 'boring' attribute of the extension module - (probably not a good thing). - - Because you didn't specify ``class``, a to-python converter for boring is registered which - copies its argument into a value_holder held by the the - Python boring object. - - Because you didn't specify ``class(no_init)``, - an ``__init__`` function object is added to the class - dictionary which default-constructs a boring in a - value_holder (because you didn't specify some smart pointer - or derived wrapper class as a holder) held by the Python - boring object. - - ``register_class_from_python`` is used to register a - from-python converter for ``shared_ptr``. - ``boost::shared_ptr``\ s are special among smart pointers - because their Deleter argument can be made to manage the - whole Python object, not just the C++ object it contains, no - matter how the C++ object is held. - - If there were any ``bases<>``, we'd also be registering the - relationship between these base classes and boring in the - up/down cast graph (``inheritance.[hpp/cpp]``). - - In earlier versions of the code, we'd be registering lvalue - from-python converters for the class here, but now - from-python conversion for wrapped classes is handled as a - special case, before consulting the registry, if the source - Python object's metaclass is the Boost.Python metaclass. - - Hmm, that from-python converter probably ought to be handled - the way class converters are, with no explicit conversions - registered. - -2) Can you give a brief overview of the data structures that are - present in the registry - - The registry is simple: it's just a map from typeid -> - registration (see boost/python/converter/registrations.hpp). - ``lvalue_chain`` and ``rvalue_chain`` are simple endogenous - linked lists. - - If you want to know more, just ask. - - If you want to know about the cast graph, ask me something specific in - a separate message. - - and an overview of the process that happens as a type makes its - way from c++ to python and back again. - - Big subject. I suggest some background reading: look for relevant - info in the LLNL progress reports and the messages they link to. - Also, - - http://mail.python.org/pipermail/c++-sig/2002-May/001023.html - - http://mail.python.org/pipermail/c++-sig/2002-December/003115.html - - http://aspn.activestate.com/ASPN/Mail/Message/1280898 - - http://mail.python.org/pipermail/c++-sig/2002-July/001755.html - - from c++ to python: - - It depends on the type and the call policies in use or, for - ``call<>(...)``, ``call_method<>(...)``, or ``object(...)``, if - ``ref`` or ``ptr`` is used. There are also two basic - categories to to-python conversion, "return value" conversion - (for Python->C++ calls) and "argument" conversion (for - C++->Python calls and explicit ``object()`` conversions). The - behavior of these two categories differs subtly in various ways - whose details I forget at the moment. You can probably find - the answers in the above references, and certainly in the code. - - The "default" case is by-value (copying) conversion, which uses - to_python_value as a to-python converter. - - Since there can sensibly be only one way to convert any type - to python (disregarding the idea of scoped registries for the - moment), it makes sense that to-python conversions can be - handled by specializing a template. If the type is one of - the types handled by a built-in conversion - (builtin_converters.hpp), the corresponding template - specialization of to_python_value gets used. - - Otherwise, to_python_value uses the ``m_to_python`` - function in the registration for the C++ type. - - Other conversions, like by-reference conversions, are only - available for wrapped classes, and are requested explicitly by - using ``ref(...)``, ``ptr(...)``, or by specifying different - CallPolicies for a call, which can cause a different to-python - converter to be used. These conversions are never registered - anywhere, though they do need to use the registration to find - the Python class corresponding to the C++ type being referred - to. They just build a new Python instance and stick the - appropriate Holder instance in it. - - - from python to C++: - - Once again I think there is a distinction between "return value" - and "argument" conversions, and I forget exactly what that is. - - What happens depends on whether an lvalue conversion is needed - (see http://mail.python.org/pipermail/c++-sig/2002-May/001023.html) - All lvalue conversions are also registered in a type's rvalue - conversion chain, since when an rvalue will do, an lvalue is - certainly good enough. - - An lvalue conversion can be done in one step (just get me the - pointer to the object - it can be ``NULL`` if no conversion is - possible) while an rvalue conversion requires two steps to - support wrapped function overloading and multiple converters for - a given C++ target type: first tell me if a conversion is - possible, then construct the converted object as a second step. - diff --git a/doc/news.html b/doc/news.html deleted file mode 100644 index ce4ead50..00000000 --- a/doc/news.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - - - - Boost.Python - News/Change Log - - - - - - - - - -
-

-

-
-

Boost.Python

- -

News/Change Log

-
-
- -
-
Current CVS
- -
-
    -
  • C++ signatures are now automatically appended to the - docstrings. - -
  • New docstring_options.hpp header to - control the content of docstrings. - -
  • Support for converting void* to/from python, - with opaque_pointer_converter - as the return value policy. Thanks to Niall Douglas for the - initial patch. -
-
- -
19 October 2005 - 1.33.1 release
- -
-
    -
  • wrapper<T> can now be used as expected with a - held type of some-smart-pointer<T>
  • - -
  • The build now assumes Python 2.4 by default, rather than 2.2
  • - -
  • Support Python that's built without Unicode support
  • - -
  • Support for wrapping classes with overloaded address-of - (&) operators
  • -
-
- -
14 August 2005 - 1.33 release
- -
-
    -
  • Support for docstrings on nonstatic properties.
  • - -
  • We now export the client-provided docstrings for - init<optional<> > and - XXX_FUNCTION_OVERLOADS() for only the last - overload.
  • - -
  • Fixed some support for Embedded VC++ 4
  • - -
  • Better support for rvalue from-python conversions of shared_ptr: - always return a pointer that holds the owning python object *unless* - the python object contains a NULL shared_ptr holder of the right - type.
  • - -
  • Support for exposing vector<T*> with the - indexing suite.
  • - -
  • Support for GCC-3.3 on MacOS.
  • - -
  • updated visual studio project build file to include two new files - (slice.cpp and wrapper.cpp)
  • - -
  • Added search feature to the index page.
  • - -
  • Numerous fixes to the tutorial
  • - -
  • Numerous workarounds for MSVC 6 and 7, GCC 2.96, and EDG - 2.45
  • -
-
- -
11 March 2005
- -
-
    -
  • Added a hack that will fool PyDoc into working with Boost.Python, - thanks to Nick Rasmussen
  • -
-
- -
19 November 2004 - 1.32 release
- -
-
    -
  • Updated to use the Boost Software License.
  • - -
  • A new, - better method of wrapping classes with virtual functions has been - implemented.
  • - -
  • Support for upcoming GCC symbol export control features have been - folded in, thanks to Niall Douglas.
  • - -
  • Improved support for std::auto_ptr-like types.
  • - -
  • The Visual C++ bug that makes top-level cv-qualification - of function parameter types part of the function type has been worked - around.
  • - -
  • Components used by other libraries have been moved out of - python/detail and into boost/detail to - improve dependency relationships.
  • - -
  • Miscellaneous bug fixes and compiler workarounds.
  • -
-
- -
8 Sept 2004
- -
Support for Python's Bool type, thanks to Daniel Holth.
- -
11 Sept 2003
- -
-
    -
  • Changed the response to multiple to-python converters being - registered for the same type from a hard error into warning; - Boost.Python now reports the offending type in the message.
  • - -
  • Added builtin std::wstring conversions
  • - -
  • Added std::out_of_range => Python - IndexError exception conversion, thanks to Raoul Gough
  • -
-
- -
9 Sept 2003
- -
Added new str
- -
constructors which take a range of characters, allowing strings - containing nul ('\0') characters.
- -
8 Sept 2003
- -
Added the ability to create methods from function objects (with an - operator()); see the make_function docs for - more info.
- -
10 August 2003
- -
Added the new properties unit tests contributed by - Roman Yakovenko and - documented add_static_property at his urging.
- -
1 August 2003
- -
- Added the new arg class contributed by Nikolay Mladenov which supplies the - ability to wrap functions that can be called with ommitted arguments in - the middle: -
-void f(int x = 0, double y = 3.14, std::string z = std::string("foo"));
-
-BOOST_PYTHON_MODULE(test)
-{
-   def("f", f
-       , (arg("x", 0), arg("y", 3.14), arg("z", "foo")));
-}
- 
-
And in Python: -
->>> import test
->>> f(0, z = "bar")
->>> f(z = "bar", y = 0.0)
-
Thanks, Nikolay! -
- -
22 July 2003
- -
Killed the dreaded "bad argument type for builtin operation" error. - Argument errors now show the actual and expected argument types!
- -
19 July 2003
- -
Added the new return_arg policy from Nikolay Mladenov. Thanks, Nikolay!
- -
18 March, 2003
- -
Gottfried - Ganßauge has contributed opaque pointer support.
- Bruno da Silva de - Oliveira has contributed the exciting Pyste ("Pie-steh") package.
- -
24 February 2003
- -
Finished improved support for boost::shared_ptr. Now any - wrapped object of C++ class X can be converted automatically - to shared_ptr<X>, regardless of how it was wrapped. - The shared_ptr will manage the lifetime of the Python object - which supplied the X, rather than just the X - object itself, and when such a shared_ptr is converted back - to Python, the original Python object will be returned.
- -
19 January 2003
- -
Integrated staticmethod support from Nikolay Mladenov. Thanks, Nikolay!
- -
29 December 2002
- -
Added Visual Studio project file and instructions from Brett Calcott. - Thanks, Brett!
- -
20 December 2002
- -
Added automatic downcasting for pointers, references, and smart - pointers to polymorphic class types upon conversion to python
- -
18 December 2002
- -
Optimized from_python conversions for wrapped classes by putting the - conversion logic in the shared library instead of registering separate - converters for each class in each extension module
- -
19 November 2002
- -
Removed the need for users to cast base class member function - pointers when used as arguments to add_property
- -
13 December 2002
- -
Allow exporting of enum_ values into enclosing - scope.
- Fixed unsigned integer conversions to deal correctly with numbers that - are out-of-range of signed long.
- -
14 November 2002
- -
Auto-detection of class data members wrapped with make_getter
- -
13 November 2002
- -
Full Support for std::auto_ptr<> added.
- -
October 2002
- -
Ongoing updates and improvements to tutorial documentation
- -
10 October 2002
- -
Boost.Python V2 is released!
-
-
- -

Revised - - 19 November 2004 -

- -

© Copyright Dave - Abrahams 2002-2003.

- - diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt deleted file mode 100644 index 38e2f691..00000000 --- a/doc/polymorphism.txt +++ /dev/null @@ -1,222 +0,0 @@ -.. 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) - -How Runtime Polymorphism is expressed in Boost.Python: ------------------------------------------------------ - - struct A { virtual std::string f(); virtual ~A(); }; - - std::string call_f(A& x) { return x.f(); } - - struct B { virtual std::string f() { return "B"; } }; - - struct Bcb : B - { - Bcb(PyObject* self) : m_self(self) {} - - virtual std::string f() { return call_method(m_sef, "f"); } - static std::string f_default(B& b) { return b.B::f(); } - - PyObject* m_self; - }; - - struct C : B - { - virtual std::string f() { return "C"; } - }; - - >>> class D(B): - ... def f(): - ... return 'D' - ... - >>> class E(B): pass - ... - - -When we write, "invokes B::f non-virtually", we mean: - - void g(B& x) { x.B::f(); } - -This will call B::f() regardless of the dynamic type of x. Any other -way of invoking B::f, including through a function pointer, is a -"virtual invocation", and will call the most-derived override of f(). - -Case studies - - C++\Python class - \___A_____B_____C_____D____E___ - | - A | 1 - | - B | 2 3 - | - Bcb | 4 5 6 - | - C | 7 8 - | - - -1. Simple case - -2. Python A holds a B*. Probably won't happen once we have forced - downcasting. - - Requires: - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: A.f invokes A::f() (virtually or otherwise) - -3. Python B holds a B*. - - Requires: - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f (virtually or otherwise) - - -4. B constructed from Python - - Requires: - - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f non-virtually. Bcb::f invokes B::f - non-virtually. - - Question: Does it help if we arrange for Python B construction to - build a true B object? Then this case doesn't arise. - - -5. D is a Python class derived from B - - Requires: - - x.f() -> 'D' - call_f(x) -> 'D' - - Implies: Bcb::f must invoke call_method to look up the Python - method override, otherwise call_f wouldn't work. - -6. E is like D, but doesn't override f - - Requires: - - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f non-virtually. If it were virtual, x.f() - would cause infinite recursion, because we've already - determined that Bcb::f must invoke call_method to look up - the Python method override. - -7. Python B object holds a C* - - Requires: - - x.f() -> 'C' - call_f(x) -> 'C' - - Implies: B.f invokes B::f virtually. - -8. C object constructed from Python - - Requires: - - x.f() -> 'C' - call_f(x) -> 'C' - - Implies: nothing new. - ------- - -Total implications: - -2: A.f invokes A::f() (virtually or otherwise) -3: B.f invokes B::f (virtually or otherwise) -4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually -6: B.f invokes B::f non-virtually. -7: B.f invokes B::f virtually. - -5: Bcb::f invokes call_method to look up the Python method - -Though (4) is avoidable, clearly 6 and 7 are not, and they -conflict. The implication is that B.f must choose its behavior -according to the type of the contained C++ object. If it is Bcb, a -non-virtual call to B::f must occur. Otherwise, a virtual call to B::f -must occur. This is essentially the same scheme we had with -Boost.Python v1. - -Note: in early versions of Boost.Python v1, we solved this problem by -introducing a new Python class in the hierarchy, so that D and E -actually derive from a B', and B'.f invokes B::f non-virtually, while -B.f invokes B::f virtually. However, people complained about the -artificial class in the hierarchy, which was revealed when they tried -to do normal kinds of Python introspection. - -------- - -Assumption: we will have a function which builds a virtual function -dispatch callable Python object. - - make_virtual_function(pvmf, default_impl, call_policies, dispatch_type) - -Pseudocode: - - Get first argument from Python arg tuple - if it contains dispatch_type - call default_impl - else - call through pvmf - - -Open questions: - - 1. What about Python multiple inheritance? Do we have the right - check in the if clause above? - - A: Not quite. The correct test looks like: - - Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN). - Find holder in first argument which holds T - if it holds dispatch_type... - - 2. Can we make this more efficient? - - The current "returning" mechanism will look up a holder for T - again. I don't know if we know how to avoid that. - - - OK, the solution involves reworking the call mechanism. This is - neccesary anyway in order to enable wrapping of function objects. - - It can result in a reduction in the overall amount of source code, - because returning<> won't need to be specialized for every - combination of function and member function... though it will still - need a void specialization. We will still need a way to dispatch to - member functions through a regular function interface. mem_fn is - almost the right tool, but it only goes up to 8 - arguments. Forwarding is tricky if you don't want to incur copies. - I think the trick is to use arg_from_python::result_type for each - argument to the forwarder. - - Another option would be to use separate function, function object, - and member function dispatchers. Once you know you have a member - function, you don't need cv-qualified overloads to call it. - - Hmm, while we're at this, maybe we should solve the write-back - converter problem. Can we do it? Maybe not. Ralf doesn't want to - write special write-back functions here, does he? He wants the - converter to do the work automatically. We could add - cleanup/destructor registration. That would relieve the client from - having accessible destructors for types which are being converted by - rvalue. I'm not sure that this will really save any code, - however. It rather depends on the linker, doesn't it? I wonder if - this can be done in a backwards-compatible fashion by generating the - delete function when it's not supplied? - - diff --git a/doc/projects.html b/doc/projects.html deleted file mode 100644 index 4b4b5084..00000000 --- a/doc/projects.html +++ /dev/null @@ -1,445 +0,0 @@ - - - - - - - - - - - - Boost.Python - Projects using Boost.Python - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Projects using Boost.Python

-
-
- -

Introduction

- -

This is a partial list of projects using Boost.Python. If you are using - Boost.Python as your Python/C++ binding solution, we'd be proud to list - your project on this page. Just post a short description of your project - and how Boost.Python helps you get the job done, and we'll add it to this - page .

-
- -

Data Analysis

- -
-
NeuraLab
- -
Neuralab is a data analysis environment specifically tailored for - neural data from Neuralynx - acquisition systems. Neuralab combines presentation quality graphics, a - numerical analysis library, and the Python scripting engine in a single - application. With Neuralab, Neuralynx users can perform common analysis - tasks with just a few mouse clicks. More advanced users can create custom - Python scripts, which can optionally be assigned to menus and mouse - clicks.
-
- -
-
TSLib - Fortress - Investment Group LLC
- -
- Fortress Investment Group has contracted Boost Consulting to develop core - internal financial analysis tools in C++ and to prepare Python bindings - for them using Boost.Python. - -

Tom Barket of Fortress writes:

- -
- We have a large C++ analytical library specialized for research in - finance and economics, built for speed and mission critical - stability. Yet Python offers us the flexibility to test out new ideas - quickly and increase the productivity of our time versus working in - C++. There are several key features which make Python stand out. Its - elegance, stability, and breadth of resources on the web are all - valuable, but the most important is its extensibility, due to its - open source transparency. Boost.Python makes Python extensibility - extremely simple and straightforward, yet preserves a great deal of - power and control. -
-
-
- -

Educational

- -
-
Kig
- -
-

KDE Interactive Geometry is a high-school level educational tool, - built for the KDE desktop. It is a nice tool to let students work with - geometrical constructions. It is meant to be the most intuitive, yet - featureful application of its kind.

- -

Versions after 0.6.x (will) support objects built by the user - himself in the Python language. The exporting of the relevant internal - API's were done using Boost.Python, which made the process very - easy.

-
-
- -

Enterprise Software

- -
-
OpenWBEM
- -
- The OpenWBEM project is an effort to develop an open-source - implementation of Web Based Enterprise Management suitable for - commercial and non-commercial application - -

Dan Nuffer writes:

- -
- I'm using Boost.Python to wrap the client API of OpenWBEM.This will - make it easier to do rapid prototyping, testing, and scripting when - developing management solutions that use WBEM. -
-
- -
Metafaq
- -
- Metafaq, from Transversal, - Inc., is an enterprise level online knowledge base management - system. - -

Ben Young - writes:

- -
- Boost.Python is used in an automated process to generate python - bindings to our api which is exposed though multiple backends and - frontends. This allows us to write quick tests and bespoke scripts to - perform one off tasks without having to go through the full - compilation cycle. -
-
-
- -

Games

- -
-
Civilization IV
-
- -
- “The fourth game in the PC strategy series that has sold over five - million copies, Sid Meier's Civilization IV is a bold step forward for - the franchise, with spectacular new 3D graphics and all-new single and - multiplayer content. Civilization IV will also set a new standard for - user-modification, allowing gamers to create their own add-ons using - Python and XML. - -

Sid Meier's Civilization IV will be released for PC in late 2005. For - more information please visit http://www.firaxis.com or write kgilmore@firaxis.com

-
- -

Boost.Python is used as the interface layer between the C++ game code - and Python. Python is used for many purposes in the game, including map - generation, interface screens, game events, tools, tutorials, etc. Most - high-level game operations have been exposed to Python in order to give - modders the power they need to customize the game.

- -
- -Mustafa Thamer, Civ4 Lead Programmer -
- -
-
Vega - Strike
- -
- Vega Strike is the 3D - Space Simulator that allows you to trade and bounty hunt in a vast - universe. Players face dangers, decisions, piracy, and aliens. - -

Vega Strike has - decided to base its scripting on python, using boost as the layer - between the class hierarchy in python and the class hierarchy in C++. - The result is a very flexible scripting system that treats units as - native python classes when designing missions or writing AI's.

- -

A large economic and planetary simulation is currently being run in - the background in python and the results are returned back into C++ in - the form of various factions' spaceships appearing near worlds that - they are simulated to be near in python if the player is in the general - neighborhood.

-
-
- -

Graphics

- -
-
OpenSceneGraph - Bindings
- -
Gideon May has created a set - of bindings for OpenSceneGraph, a cross-platform - C++/OpenGL library for the real-time visualization.
-  
- -
HippoDraw
- -
- HippoDraw is a data analysis environment consisting of a canvas upon - which graphs such as histograms, scattter plots, etc, are prsented. It - has a highly interactive GUI interface, but some things you need to do - with scripts. HippoDraw can be run as Python extension module so that - all the manipulation can be done from either Python or the GUI. - -

Before the web page came online, Paul F. Kunz wrote:

- -
- Don't have a web page for the project, but the organization's is - http://www.slac.stanford.edu (the - first web server site in America, I installed it). -
Which was just too cool a piece of trivia to omit.
-   -
- -
IPLT
- -
- Ansgar Philippsen - writes: - -
- IPLT is an image processing library and toolbox for the structural - biology electron microscopy community. I would call it a - budding/evolving project, since it is currently not in production - stage, but rather under heavy development. Python is used as the main - scripting/interaction level, but also for rapid prototyping, since - the underlying C++ class library is pretty much fully exposed via - boost.python (at least the high-level interface). The combined power - of C++ and Python for this project turned out to be just awesome. -

-   -
- -
PythonMagick
- -
PythonMagick binds the GraphicsMagick image manipulation - library to Python.
-  
- -
VPython
- -
- Bruce Sherwood writes: - -
- VPython is an extension for Python that makes it easy to create - navigable 3D animations, which are generated as a side effect of - computational code. VPython is used in education for various - purposes, including teaching physics and programming, but it has also - been used by research scientists to visualize systems or data in 3D. -

-   -
-
- -

Scientific Computing

- -
-
CAMFR
- -
- CAMFR is a photonics and electromagnetics modelling tool. Python is - used for computational steering. - -

Peter Bienstman - writes:

- -
- Thanks for providing such a great tool! -
-
- -
cctbx - Computational - Crystallography Toolbox
- -
- Computational Crystallography is concerned with the derivation of - atomic models of crystal structures, given experimental X-ray - diffraction data. The cctbx is an open-source library of fundamental - algorithms for crystallographic computations. The core algorithms are - implemented in C++ and accessed through higher-level Python interfaces. - -

The cctbx grew together with Boost.Python and is designed from the - ground up as a hybrid Python/C++ system. With one minor exception, - run-time polymorphism is completely handled by Python. C++ compile-time - polymorphism is used to implement performance critical algorithms. The - Python and C++ layers are seamlessly integrated using Boost.Python.

- -

The SourceForge cctbx project is organized in modules to facilitate - use in non-crystallographic applications. The scitbx module implements - a general purpose array family for scientific applications and pure C++ - ports of FFTPACK and the L-BFGS quasi-Newton minimizer.

-
- -
EMSolve
- -
EMSolve is a provably stable, charge conserving, and energy - conserving solver for Maxwell's equations.
-  
- -
Gaudi and RootPython
- -
- Gaudi is a framework for particle physics collision data processing - applications developed in the context of the LHCb and ATLAS experiments - at CERN. - -

Pere Mato Vila writes:

- -
- We are using Boost.Python to provide scripting/interactive capability - to our framework. We have a module called "GaudiPython" implemented - using Boost.Python that allows the interaction with any framework - service or algorithm from python. RootPython also uses Boost.Python - to provide a generic "gateway" between the ROOT framework and python - -

Boost.Python is great. We managed very quickly to interface our - framework to python, which is great language. We are trying to - facilitate to our physicists (end-users) a rapid analysis application - development environment based on python. For that, Boost.Python plays - and essential role.

-
-
- -
ESSS
- -
- ESSS (Engineering Simulation and Scientific Software) is a company that - provides engineering solutions and acts in the brazilian and - south-american market providing products and services related to - Computational Fluid Dynamics and Image Analysis. - -

Bruno da Silva de Oliveira - writes:

- -
- Recently we moved our work from working exclusively with C++ to an - hybrid-language approach, using Python and C++, with Boost.Python - providing the layer between the two. The results are great so far! -
- -

Two projects have been developed so far with this technology:

- -

Simba - provides 3D visualization of geological formations gattered from the - simulation of the evolution of oil systems, allowing the user to - analyse various aspects of the simulation, like deformation, pressure - and fluids, along the time of the simulation.

- -

Aero aims to - construct a CFD with brazilian technology, which involves various - companies and universities. ESSS is responsible for various of the - application modules, including GUI and post-processing of results.

-
- -
Rational Discovery - LLC
- -
- Rational Discovery provides computational modeling, combinatorial - library design and custom software development services to the - pharmaceutical, biotech and chemical industries. We do a substantial - amount of internal research to develop new approaches for applying - machine-learning techniques to solve chemical problems. Because we're a - small organization and chemistry is a large and complex field, it is - essential that we be able to quickly and easily prototype and test new - algorithms. - -

For our internal software, we implement core data structures in C - and expose them to Python using Boost.Python. Algorithm development is - done in Python and then translated to C if required (often it's not). - This hybrid development approach not only greatly increases our - productivity, but it also allows "non-developers" (people without C - experience) to take part in method development. Learning C is a - daunting task, but "Python fits your brain." (Thanks to Bruce Eckel for - the quote.)

-
-
- -

Systems Libraries

- -
-
Fusion
- -
-

Fusion is a library that supports implementing protocols in C++ for - use with Twisted, allowing control over memory allocation strategies, - fast method calls internally, etc.. Fusion supports TCP, UDP and - multicast, and is implemented using the Boost.Python python - bindings.

- -

Fusion is licensed under the MIT license, and available for download - from http://itamarst.org/software.

-
-
- -

Tools

- -
-
Jayacard
- -
- Jayacard aims at developing a secure portable open source operating - system for contactless smart cards and a complete suite of high quality - development tools to ease smart card OS and application development. - -

The core of the smart card reader management is written in C++ but - all the development tools are written in the friendly Python language. - Boost plays the fundamental role of binding the tools to our core smart - card reader library.

-
-
-
- -

Revised - - 15 July, 2003

- -

© Copyright Dave - Abrahams 2002-2003.

- - diff --git a/doc/support.html b/doc/support.html deleted file mode 100644 index a71e9ecd..00000000 --- a/doc/support.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - Boost.Python - Support Resources - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Support Resources

-
-
- -

Synopsis

- -

This is a list of available resources for support with Boost.Python - problems and feature requests. Please try to resist emailing the - Boost.Python developers directly for support. Use the following - resources instead; the developers are listening!

-
- -
-
Boost - Consulting - Commercial support, development, training, and - distribution for all the Boost libraries, from the people who brought - you Boost.Python.
-  
- -
The Python - C++-sig mailing list is a forum for discussing Python/C++ - interoperability, and Boost.Python in particular. Post your - Boost.Python questions here.
-  
- -
The Boost.Python Wiki - Pages established by Mike Rovner as part of the PythonInfo Wiki serves as - a forum to gather peoples' experience and as a cookbook.
-  
-
-
- -

Revised - - 12 Sept, 2003 -

- -

© Copyright Dave - Abrahams 2003.

- - - diff --git a/doc/tutorial/doc/Jamfile.v2 b/doc/tutorial/doc/Jamfile.v2 deleted file mode 100644 index 963f9346..00000000 --- a/doc/tutorial/doc/Jamfile.v2 +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright Joel de Guzman 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) -project boost/libs/python/doc/tutorial/doc ; - -import boostbook : boostbook ; -using quickbook ; - -boostbook tutorial - : - tutorial.qbk - : - boost.root=../../../../../.. - boost.libraries=../../../../../../libs/libraries.htm - ; diff --git a/doc/tutorial/doc/html/boostbook.css b/doc/tutorial/doc/html/boostbook.css deleted file mode 100644 index d84d5384..00000000 --- a/doc/tutorial/doc/html/boostbook.css +++ /dev/null @@ -1,511 +0,0 @@ -/*============================================================================= - Copyright (c) 2004 Joel de Guzman - http://spirit.sourceforge.net/ - - Use, modification and distribution is subject to 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) -=============================================================================*/ - -/*============================================================================= - Body defaults -=============================================================================*/ - - body - { - margin: 1em; - font-family: sans-serif; - } - -/*============================================================================= - Paragraphs -=============================================================================*/ - - p - { - text-align: left; - font-size: 10pt; - line-height: 1.15; - } - -/*============================================================================= - Program listings -=============================================================================*/ - - /* Code on paragraphs */ - p tt.computeroutput - { - font-size: 9pt; - } - - pre.synopsis - { - font-size: 90%; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - .programlisting, - .screen - { - font-size: 9pt; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - /* Program listings in tables don't get borders */ - td .programlisting, - td .screen - { - margin: 0pc 0pc 0pc 0pc; - padding: 0pc 0pc 0pc 0pc; - } - -/*============================================================================= - Headings -=============================================================================*/ - - h1, h2, h3, h4, h5, h6 - { - text-align: left; - margin: 1em 0em 0.5em 0em; - font-weight: bold; - } - - h1 { font: 140% } - h2 { font: bold 140% } - h3 { font: bold 130% } - h4 { font: bold 120% } - h5 { font: italic 110% } - h6 { font: italic 100% } - - /* Top page titles */ - title, - h1.title, - h2.title - h3.title, - h4.title, - h5.title, - h6.title, - .refentrytitle - { - font-weight: bold; - margin-bottom: 1pc; - } - - h1.title { font-size: 140% } - h2.title { font-size: 140% } - h3.title { font-size: 130% } - h4.title { font-size: 120% } - h5.title { font-size: 110% } - h6.title { font-size: 100% } - - .section h1 - { - margin: 0em 0em 0.5em 0em; - font-size: 140%; - } - - .section h2 { font-size: 140% } - .section h3 { font-size: 130% } - .section h4 { font-size: 120% } - .section h5 { font-size: 110% } - .section h6 { font-size: 100% } - - /* Code on titles */ - h1 tt.computeroutput { font-size: 140% } - h2 tt.computeroutput { font-size: 140% } - h3 tt.computeroutput { font-size: 130% } - h4 tt.computeroutput { font-size: 120% } - h5 tt.computeroutput { font-size: 110% } - h6 tt.computeroutput { font-size: 100% } - -/*============================================================================= - Author -=============================================================================*/ - - h3.author - { - font-size: 100% - } - -/*============================================================================= - Lists -=============================================================================*/ - - li - { - font-size: 10pt; - line-height: 1.3; - } - - /* Unordered lists */ - ul - { - text-align: left; - } - - /* Ordered lists */ - ol - { - text-align: left; - } - -/*============================================================================= - Links -=============================================================================*/ - - a - { - text-decoration: none; /* no underline */ - } - - a:hover - { - text-decoration: underline; - } - -/*============================================================================= - Spirit style navigation -=============================================================================*/ - - .spirit-nav - { - text-align: right; - } - - .spirit-nav a - { - color: white; - padding-left: 0.5em; - } - - .spirit-nav img - { - border-width: 0px; - } - -/*============================================================================= - Table of contents -=============================================================================*/ - - .toc - { - margin: 1pc 4% 0pc 4%; - padding: 0.1pc 1pc 0.1pc 1pc; - font-size: 80%; - line-height: 1.15; - } - - .boost-toc - { - float: right; - padding: 0.5pc; - } - -/*============================================================================= - Tables -=============================================================================*/ - - .table-title, - div.table p.title - { - margin-left: 4%; - padding-right: 0.5em; - padding-left: 0.5em; - } - - .informaltable table, - .table table - { - width: 92%; - margin-left: 4%; - margin-right: 4%; - } - - div.informaltable table, - div.table table - { - padding: 4px; - } - - /* Table Cells */ - div.informaltable table tr td, - div.table table tr td - { - padding: 0.5em; - text-align: left; - font-size: 9pt; - } - - div.informaltable table tr th, - div.table table tr th - { - padding: 0.5em 0.5em 0.5em 0.5em; - border: 1pt solid white; - font-size: 80%; - } - -/*============================================================================= - Blurbs -=============================================================================*/ - - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - font-size: 9pt; /* A little bit smaller than the main text */ - line-height: 1.2; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - p.blurb img - { - padding: 1pt; - } - -/*============================================================================= - Variable Lists -=============================================================================*/ - - /* Make the terms in definition lists bold */ - div.variablelist dl dt, - span.term - { - font-weight: bold; - font-size: 10pt; - } - - div.variablelist table tbody tr td - { - text-align: left; - vertical-align: top; - padding: 0em 2em 0em 0em; - font-size: 10pt; - margin: 0em 0em 0.5em 0em; - line-height: 1; - } - - div.variablelist dl dt - { - margin-bottom: 0.2em; - } - - div.variablelist dl dd - { - margin: 0em 0em 0.5em 2em; - font-size: 10pt; - } - - div.variablelist table tbody tr td p, - div.variablelist dl dd p - { - margin: 0em 0em 0.5em 0em; - line-height: 1; - } - -/*============================================================================= - Misc -=============================================================================*/ - - /* Title of books and articles in bibliographies */ - span.title - { - font-style: italic; - } - - span.underline - { - text-decoration: underline; - } - - span.strikethrough - { - text-decoration: line-through; - } - - /* Copyright, Legal Notice */ - div div.legalnotice p - { - text-align: left - } - -/*============================================================================= - Colors -=============================================================================*/ - - @media screen - { - /* Links */ - a - { - color: #005a9c; - } - - a:visited - { - color: #9c5a9c; - } - - h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, - h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, - h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited - { - text-decoration: none; /* no underline */ - color: #000000; - } - - /* Syntax Highlighting */ - .keyword { color: #0000AA; } - .identifier { color: #000000; } - .special { color: #707070; } - .preprocessor { color: #402080; } - .char { color: teal; } - .comment { color: #800000; } - .string { color: teal; } - .number { color: teal; } - .white_bkd { background-color: #FFFFFF; } - .dk_grey_bkd { background-color: #999999; } - - /* Copyright, Legal Notice */ - .copyright - { - color: #666666; - font-size: small; - } - - div div.legalnotice p - { - color: #666666; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid #DCDCDC; - } - - .programlisting, - .screen - { - border: 1px solid #DCDCDC; - } - - td .programlisting, - td .screen - { - border: 0px solid #DCDCDC; - } - - /* Blurbs */ - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - border: 1px solid #DCDCDC; - } - - /* Table of contents */ - .toc - { - border: 1px solid #DCDCDC; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid #DCDCDC; - } - - div.informaltable table tr th, - div.table table tr th - { - background-color: #F0F0F0; - border: 1px solid #DCDCDC; - } - - /* Misc */ - span.highlight - { - color: #00A000; - } - } - - @media print - { - /* Links */ - a - { - color: black; - } - - a:visited - { - color: black; - } - - .spirit-nav - { - display: none; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid gray; - } - - .programlisting, - .screen - { - border: 1px solid gray; - } - - td .programlisting, - td .screen - { - border: 0px solid #DCDCDC; - } - - /* Table of contents */ - .toc - { - border: 1px solid gray; - } - - .informaltable table, - .table table - { - border: 1px solid gray; - border-collapse: collapse; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid gray; - } - - div.informaltable table tr th, - div.table table tr th - { - border: 1px solid gray; - } - - /* Misc */ - span.highlight - { - font-weight: bold; - } - } diff --git a/doc/tutorial/doc/html/images/alert.png b/doc/tutorial/doc/html/images/alert.png deleted file mode 100755 index b4645bc7..00000000 Binary files a/doc/tutorial/doc/html/images/alert.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/home.png b/doc/tutorial/doc/html/images/home.png deleted file mode 100755 index 5584aacb..00000000 Binary files a/doc/tutorial/doc/html/images/home.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/jam.png b/doc/tutorial/doc/html/images/jam.png deleted file mode 100644 index 224ed791..00000000 Binary files a/doc/tutorial/doc/html/images/jam.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/next.png b/doc/tutorial/doc/html/images/next.png deleted file mode 100755 index 59800b4e..00000000 Binary files a/doc/tutorial/doc/html/images/next.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/note.png b/doc/tutorial/doc/html/images/note.png deleted file mode 100755 index 3ed047ca..00000000 Binary files a/doc/tutorial/doc/html/images/note.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/prev.png b/doc/tutorial/doc/html/images/prev.png deleted file mode 100755 index d88a40f9..00000000 Binary files a/doc/tutorial/doc/html/images/prev.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/python.png b/doc/tutorial/doc/html/images/python.png deleted file mode 100644 index cc2ff1d5..00000000 Binary files a/doc/tutorial/doc/html/images/python.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/smiley.png b/doc/tutorial/doc/html/images/smiley.png deleted file mode 100644 index 30a77f71..00000000 Binary files a/doc/tutorial/doc/html/images/smiley.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/tip.png b/doc/tutorial/doc/html/images/tip.png deleted file mode 100755 index 9f596b0b..00000000 Binary files a/doc/tutorial/doc/html/images/tip.png and /dev/null differ diff --git a/doc/tutorial/doc/html/images/up.png b/doc/tutorial/doc/html/images/up.png deleted file mode 100755 index 17d9c3ec..00000000 Binary files a/doc/tutorial/doc/html/images/up.png and /dev/null differ diff --git a/doc/tutorial/doc/html/index.html b/doc/tutorial/doc/html/index.html deleted file mode 100644 index ffe9a7c1..00000000 --- a/doc/tutorial/doc/html/index.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - -Chapter 1. python 1.0 - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
Next
-
-
-

-Chapter 1. python 1.0

-

-Joel de Guzman -

-

-David Abrahams -

-
-
-

- 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 ) -

-
-
- -
-

-QuickStart

-

- The Boost Python Library is a framework for interfacing Python and C++. It - allows you to quickly and seamlessly expose C++ classes functions and objects - to Python, and vice-versa, using no special tools -- just your C++ compiler. - It is designed to wrap C++ interfaces non-intrusively, so that you should not - have to change the C++ code at all in order to wrap it, making Boost.Python - ideal for exposing 3rd-party libraries to Python. The library's use of advanced - metaprogramming techniques simplifies its syntax for users, so that wrapping - code takes on the look of a kind of declarative interface definition language - (IDL). -

-

- - Hello World -

-

- Following C/C++ tradition, let's start with the "hello, world". A - C++ Function: -

-
-char const* greet()
-{
-   return "hello, world";
-}
-
-

- can be exposed to Python by writing a Boost.Python wrapper: -

-
-#include <boost/python.hpp>
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE(hello)
-{
-    def("greet", greet);
-}
-
-

- That's it. We're done. We can now build this as a shared library. The resulting - DLL is now visible to Python. Here's a sample Python session: -

-

-

-
->>> import hello
->>> print hello.greet()
-hello, world
-
-

-

-

- Next stop... Building your Hello World module - from start to finish... -

-
-
- - - -

Last revised: August 31, 2006 at 05:59:58 GMT

-
-
Next
- - diff --git a/doc/tutorial/doc/html/python/embedding.html b/doc/tutorial/doc/html/python/embedding.html deleted file mode 100644 index 79971d82..00000000 --- a/doc/tutorial/doc/html/python/embedding.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - - -Embedding - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

-Embedding

- -

- By now you should know how to use Boost.Python to call your C++ code from Python. - However, sometimes you may need to do the reverse: call Python code from the - C++-side. This requires you to embed the Python interpreter - into your C++ program. -

-

- Currently, Boost.Python does not directly support everything you'll need when - embedding. Therefore you'll need to use the Python/C - API to fill in the gaps. However, Boost.Python already makes embedding - a lot easier and, in a future version, it may become unnecessary to touch the - Python/C API at all. So stay tuned... smiley -

-

- - Building embedded programs -

-

- To be able to use embedding in your programs, they have to be linked to both - Boost.Python's and Python's static link library. -

-

- Boost.Python's static link library comes in two variants. Both are located - in Boost's /libs/python/build/bin-stage subdirectory. On - Windows, the variants are called boost_python.lib (for release - builds) and boost_python_debug.lib (for debugging). If you - can't find the libraries, you probably haven't built Boost.Python yet. See - Building and Testing on how to - do this. -

-

- Python's static link library can be found in the /libs subdirectory - of your Python directory. On Windows it is called pythonXY.lib where X.Y is - your major Python version number. -

-

- Additionally, Python's /include subdirectory has to be added - to your include path. -

-

- In a Jamfile, all the above boils down to: -

-
projectroot c:\projects\embedded_program ; # location of the program
-
-# bring in the rules for python
-SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-include python.jam ;
-
-exe embedded_program # name of the executable
-  : #sources
-     embedded_program.cpp
-  : # requirements
-     <find-library>boost_python <library-path>c:\boost\libs\python
-  $(PYTHON_PROPERTIES)
-    <library-path>$(PYTHON_LIB_PATH)
-    <find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
-
-

- - Getting started -

-

- Being able to build is nice, but there is nothing to build yet. Embedding the - Python interpreter into one of your C++ programs requires these 4 steps: -

-
    -
  1. - #include <boost/python.hpp>

    -
  2. -
  3. - Call Py_Initialize() - to start the interpreter and create the _main_ - module.

    -
  4. -
  5. - Call other Python C API routines to use the interpreter.

    -
  6. -
  7. - Call Py_Finalize() - to stop the interpreter and release its resources. -
  8. -
-

- (Of course, there can be other C++ code between all of these steps.) -

-

- Now that we can embed the interpreter in - our programs, lets see how to put it to use... -

-
-

-Using the interpreter

-

- As you probably already know, objects in Python are reference-counted. Naturally, - the PyObjects of the Python/C API are also reference-counted. - There is a difference however. While the reference-counting is fully automatic - in Python, the Python/C API requires you to do it by - hand. This is messy and especially hard to get right in the presence - of C++ exceptions. Fortunately Boost.Python provides the handle - and object class templates to - automate the process. -

-

- - Reference-counting handles and objects -

-

- There are two ways in which a function in the Python/C API can return a - PyObject*: as a borrowed reference - or as a new reference. Which of these a function uses, - is listed in that function's documentation. The two require slightely different - approaches to reference-counting but both can be 'handled' by Boost.Python. -

-

- For a function returning a borrowed reference we'll - have to tell the handle that the PyObject* - is borrowed with the aptly named borrowed - function. Two functions returning borrowed references are PyImport_AddModule - and PyModule_GetDict. - The former returns a reference to an already imported module, the latter - retrieves a module's namespace dictionary. Let's use them to retrieve the - namespace of the _main_ - module: -

-
-object main_module((
-    handle<>(borrowed(PyImport_AddModule("__main__")))));
-
-object main_namespace = main_module.attr("__dict__");
-
-

- For a function returning a new reference we can just - create a handle out of the raw PyObject* - without wrapping it in a call to borrowed. One such function that returns - a new reference is PyRun_String - which we'll discuss in the next section. -

-

- note Handle is a class template, - so why haven't we been using any template parameters?

- handle has a single template parameter specifying the - type of the managed object. This type is PyObject 99% - of the time, so the parameter was defaulted to PyObject - for convenience. Therefore we can use the shorthand handle<> - instead of the longer, but equivalent, handle<PyObject>. -

-

- - Running Python code -

-

- To run Python code from C++ there is a family of functions in the API starting - with the PyRun prefix. You can find the full list of these functions here. They - all work similarly so we will look at only one of them, namely: -

-
-PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
-
-

- PyRun_String - takes the code to execute as a null-terminated (C-style) string in its str - parameter. The function returns a new reference to a Python object. Which - object is returned depends on the start paramater. -

-

- The start parameter is the start symbol from the Python - grammar to use for interpreting the code. The possible values are: -

-
-

- - Start symbols -

- ---- - - - - - - - - - - - - - - -
Py_eval_inputfor - interpreting isolated expressions
Py_file_inputfor - interpreting sequences of statements
Py_single_inputfor - interpreting a single statement
-
-

- When using Py_eval_input, - the input string must contain a single expression and its result is returned. - When using Py_file_input, - the string can contain an abitrary number of statements and None is returned. - Py_single_input - works in the same way as Py_file_input - but only accepts a single statement. -

-

- Lastly, the globals and locals parameters - are Python dictionaries containing the globals and locals of the context - in which to run the code. For most intents and purposes you can use the namespace - dictionary of the _main_ - module for both parameters. -

-

- We have already seen how to get the _main_ - module's namespace so let's run some Python code in it: -

-
-object main_module((
-    handle<>(borrowed(PyImport_AddModule("__main__")))));
-
-object main_namespace = main_module.attr("__dict__");
-
-handle<> ignored((PyRun_String(
-
-    "hello = file('hello.txt', 'w')\n"
-    "hello.write('Hello world!')\n"
-    "hello.close()"
-
-  , Py_file_input
-  , main_namespace.ptr()
-  , main_namespace.ptr())
-));
-
-

- Because the Python/C API doesn't know anything about objects, - we used the object's ptr member function to retrieve the - PyObject*. -

-

- This should create a file called 'hello.txt' in the current directory containing - a phrase that is well-known in programming circles. -

-

- note Note that we wrap - the return value of PyRun_String - in a (nameless) handle even though we are not interested - in it. If we didn't do this, the the returned object would be kept alive - unnecessarily. Unless you want to be a Dr. Frankenstein, always wrap PyObject*s - in handles. -

-

- - Beyond handles -

-

- It's nice that handle manages the reference counting details - for us, but other than that it doesn't do much. Often we'd like to have a - more useful class to manipulate Python objects. But we have already seen - such a class above, and in the previous section: - the aptly named object class and it's derivatives. We've - already seen that they can be constructed from a handle. - The following examples should further illustrate this fact: -

-
-object main_module((
-     handle<>(borrowed(PyImport_AddModule("__main__")))));
-
-object main_namespace = main_module.attr("__dict__");
-
-handle<> ignored((PyRun_String(
-
-    "result = 5 ** 2"
-
-    , Py_file_input
-    , main_namespace.ptr()
-    , main_namespace.ptr())
-));
-
-int five_squared = extract<int>(main_namespace["result"]);
-
-

- Here we create a dictionary object for the _main_ - module's namespace. Then we assign 5 squared to the result variable and read - this variable from the dictionary. Another way to achieve the same result - is to let PyRun_String - return the result directly with Py_eval_input: -

-
-object result((handle<>(
-    PyRun_String("5 ** 2"
-        , Py_eval_input
-        , main_namespace.ptr()
-        , main_namespace.ptr()))
-));
-
-int five_squared = extract<int>(result);
-
-

- note Note that object's - member function to return the wrapped PyObject* is called - ptr instead of get. This makes sense - if you take into account the different functions that object - and handle perform. -

-

- - Exception handling -

-

- If an exception occurs in the execution of some Python code, the PyRun_String - function returns a null pointer. Constructing a handle - out of this null pointer throws error_already_set, - so basically, the Python exception is automatically translated into a C++ - exception when using handle: -

-
-try
-{
-    object result((handle<>(PyRun_String(
-        "5/0"
-      , Py_eval_input
-      , main_namespace.ptr()
-      , main_namespace.ptr()))
-    ));
-
-    // execution will never get here:
-    int five_divided_by_zero = extract<int>(result);
-}
-catch(error_already_set)
-{
-    // handle the exception in some way
-}
-
-

- The error_already_set exception class doesn't carry any - information in itself. To find out more about the Python exception that occurred, - you need to use the exception - handling functions of the Python/C API in your catch-statement. This - can be as simple as calling PyErr_Print() - to print the exception's traceback to the console, or comparing the type - of the exception with those of the standard - exceptions: -

-
-catch(error_already_set)
-{
-    if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
-    {
-        // handle ZeroDivisionError specially
-    }
-    else
-    {
-        // print all other errors to stderr
-        PyErr_Print();
-    }
-}
-
-

- (To retrieve even more information from the exception you can use some of - the other exception handling functions listed here.) -

-

- If you'd rather not have handle throw a C++ exception - when it is constructed, you can use the allow_null - function in the same way you'd use borrowed: -

-
-handle<> result((allow_null(PyRun_String(
-    "5/0"
-   , Py_eval_input
-   , main_namespace.ptr()
-   , main_namespace.ptr()))));
-
-if (!result)
-    // Python exception occurred
-else
-    // everything went okay, it's safe to use the result
-
-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/exception.html b/doc/tutorial/doc/html/python/exception.html deleted file mode 100644 index 04033f03..00000000 --- a/doc/tutorial/doc/html/python/exception.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - Exception Translation - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

- Exception Translation

-

- All C++ exceptions must be caught at the boundary with Python code. This boundary - is the point where C++ meets Python. Boost.Python provides a default exception - handler that translates selected standard exceptions, then gives up: -

-
-raise RuntimeError, 'unidentifiable C++ Exception'
-
-

- Users may provide custom translation. Here's an example: -

-
-struct PodBayDoorException;
-void translator(PodBayDoorException const& x) {
-    PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
-}
-BOOST_PYTHON_MODULE(kubrick) {
-     register_exception_translator<
-          PodBayDoorException>(translator);
-     ...
-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/exposing.html b/doc/tutorial/doc/html/python/exposing.html deleted file mode 100644 index 42f188f3..00000000 --- a/doc/tutorial/doc/html/python/exposing.html +++ /dev/null @@ -1,609 +0,0 @@ - - - - - - - Exposing Classes - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

- Exposing Classes

- -

- Now let's expose a C++ class to Python. -

-

- Consider a C++ class/struct that we want to expose to Python: -

-
-struct World
-{
-    void set(std::string msg) { this->msg = msg; }
-    std::string greet() { return msg; }
-    std::string msg;
-};
-
-

- We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper: -

-
-#include <boost/python.hpp>
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE(hello)
-{
-    class_<World>("World")
-        .def("greet", &World::greet)
-        .def("set", &World::set)
-    ;
-}
-
-

- Here, we wrote a C++ class wrapper that exposes the member functions greet - and set. Now, after building our module as a shared library, - we may use our class World in Python. Here's a sample Python - session: -

-

-

-
->>> import hello
->>> planet = hello.World()
->>> planet.set('howdy')
->>> planet.greet()
-'howdy'
-
-
-

-Constructors

-

- Our previous example didn't have any explicit constructors. Since World - is declared as a plain struct, it has an implicit default constructor. Boost.Python - exposes the default constructor by default, which is why we were able to - write -

-
->>> planet = hello.World()
-
-

- We may wish to wrap a class with a non-default constructor. Let us build - on our previous example: -

-

-

-
-struct World
-{
-    World(std::string msg): msg(msg) {} // added constructor
-    void set(std::string msg) { this->msg = msg; }
-    std::string greet() { return msg; }
-    std::string msg;
-};
-
-

- This time World has no default constructor; our previous - wrapping code would fail to compile when the library tried to expose it. - We have to tell class_<World> about the constructor - we want to expose instead. -

-
-#include <boost/python.hpp>
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE(hello)
-{
-    class_<World>("World", init<std::string>())
-        .def("greet", &World::greet)
-        .def("set", &World::set)
-    ;
-}
-
-

- init<std::string>() exposes the constructor taking - in a std::string (in Python, constructors are spelled - ""_init_""). -

-

- We can expose additional constructors by passing more init<...>s - to the def() member function. Say for example we have - another World constructor taking in two doubles: -

-
-class_<World>("World", init<std::string>())
-    .def(init<double, double>())
-    .def("greet", &World::greet)
-    .def("set", &World::set)
-;
-
-

- On the other hand, if we do not wish to expose any constructors at all, we - may use no_init instead: -

-
-class_<Abstract>("Abstract", no_init)
-
-

- This actually adds an _init_ - method which always raises a Python RuntimeError exception. -

-
-
-

-Class Data Members

-

- Data members may also be exposed to Python so that they can be accessed as - attributes of the corresponding Python class. Each data member that we wish - to be exposed may be regarded as read-only - or read-write. Consider this class Var: -

-
-struct Var
-{
-    Var(std::string name) : name(name), value() {}
-    std::string const name;
-    float value;
-};
-
-

- Our C++ Var class and its data members can be exposed - to Python: -

-
-class_<Var>("Var", init<std::string>())
-    .def_readonly("name", &Var::name)
-    .def_readwrite("value", &Var::value);
-
-

- Then, in Python, assuming we have placed our Var class inside the namespace - hello as we did before: -

-

-

-
->>> x = hello.Var('pi')
->>> x.value = 3.14
->>> print x.name, 'is around', x.value
-pi is around 3.14
-
-

- Note that name is exposed as read-only - while value is exposed as read-write. -

-
->>> x.name = 'e' # can't change name
-Traceback (most recent call last):
-  File "<stdin>", line 1, in #
-AttributeError: can#t set attribute
-
-
-
-

-Class Properties

-

- In C++, classes with public data members are usually frowned upon. Well designed - classes that take advantage of encapsulation hide the class' data members. - The only way to access the class' data is through access (getter/setter) - functions. Access functions expose class properties. Here's an example: -

-

-

-
-struct Num
-{
-    Num();
-    float get() const;
-    void set(float value);
-    ...
-};
-
-

- However, in Python attribute access is fine; it doesn't neccessarily break - encapsulation to let users handle attributes directly, because the attributes - can just be a different syntax for a method call. Wrapping our Num - class using Boost.Python: -

-
-class_<Num>("Num")
-    .add_property("rovalue", &Num::get)
-    .add_property("value", &Num::get, &Num::set);
-
-

- And at last, in Python: -

-

-

-
->>> x = Num()
->>> x.value = 3.14
->>> x.value, x.rovalue
-(3.14, 3.14)
->>> x.rovalue = 2.17 # error!
-
-

- Take note that the class property rovalue is exposed as - read-only since the rovalue - setter member function is not passed in: -

-

-

-
-.add_property("rovalue", &Num::get)
-
-
-
-

-Inheritance

-

- In the previous examples, we dealt with classes that are not polymorphic. - This is not often the case. Much of the time, we will be wrapping polymorphic - classes and class hierarchies related by inheritance. We will often have - to write Boost.Python wrappers for classes that are derived from abstract - base classes. -

-

- Consider this trivial inheritance structure: -

-
-struct Base { virtual ~Base(); };
-struct Derived : Base {};
-
-

- And a set of C++ functions operating on Base and Derived - object instances: -

-
-void b(Base*);
-void d(Derived*);
-Base* factory() { return new Derived; }
-
-

- We've seen how we can wrap the base class Base: -

-
-class_<Base>("Base")
-    /*...*/
-    ;
-
-

- Now we can inform Boost.Python of the inheritance relationship between Derived - and its base class Base. Thus: -

-
-class_<Derived, bases<Base> >("Derived")
-    /*...*/
-    ;
-
-

- Doing so, we get some things for free: -

-
    -
  1. - Derived automatically inherits all of Base's Python methods (wrapped C++ - member functions) -
  2. -
  3. -If Base is polymorphic, Derived - objects which have been passed to Python via a pointer or reference to - Base can be passed where a pointer or reference to - Derived is expected. -
  4. -
-

- Now, we shall expose the C++ free functions b and d - and factory: -

-
-def("b", b);
-def("d", d);
-def("factory", factory);
-
-

- Note that free function factory is being used to generate - new instances of class Derived. In such cases, we use - return_value_policy<manage_new_object> to instruct - Python to adopt the pointer to Base and hold the instance - in a new Python Base object until the the Python object - is destroyed. We shall see more of Boost.Python call - policies later. -

-
-// Tell Python to take ownership of factory's result
-def("factory", factory,
-    return_value_policy<manage_new_object>());
-
-
-
-

-Class Virtual Functions

-

- In this section, we shall learn how to make functions behave polymorphically - through virtual functions. Continuing our example, let us add a virtual function - to our Base class: -

-
-struct Base
-{
-    virtual ~Base() {}
-    virtual int f() = 0;
-};
-
-

- One of the goals of Boost.Python is to be minimally intrusive on an existing - C++ design. In principle, it should be possible to expose the interface for - a 3rd party library without changing it. It is not ideal to add anything - to our class Base. Yet, when - you have a virtual function that's going to be overridden in Python and called - polymorphically from C++, we'll need to - add some scaffoldings to make things work properly. What we'll do is write - a class wrapper that derives from Base - that will unintrusively hook into the virtual functions so that a Python - override may be called: -

-
-struct BaseWrap : Base, wrapper<Base>
-{
-    int f()
-    {
-        return this->get_override("f")();
-    }
-};
-
-

- Notice too that in addition to inheriting from Base, - we also multiply- inherited wrapper<Base> (See Wrapper). - The wrapper template makes - the job of wrapping classes that are meant to overridden in Python, easier. -

-

- alert MSVC6/7 Workaround
-
If you are using Microsoft Visual C++ 6 or 7, you have to write f as:

return call<int>(this->get_override("f").ptr());. -

-

- BaseWrap's overridden virtual member function f - in effect calls the corresponding method of the Python object through get_override. -

-

- Finally, exposing Base: -

-
-class_<BaseWrap, boost::noncopyable>("Base")
-    .def("f", pure_virtual(&Base::f))
-    ;
-
-

- pure_virtual signals Boost.Python - that the function f is a - pure virtual function. -

-

- note member function and methods
-
Python, like many object oriented languages uses the term methods. Methods correspond roughly to C++'s member functions -

-
-
-

-Virtual Functions with Default Implementations

-

- We've seen in the previous section how classes with pure virtual functions - are wrapped using Boost.Python's class - wrapper facilities. If we wish to wrap non-pure-virtual - functions instead, the mechanism is a bit different. -

-

- Recall that in the previous - section, we wrapped a class with a pure virtual function that we then - implemented in C++, or Python classes derived from it. Our base class: -

-
-struct Base
-{
-    virtual int f() = 0;
-};
-
-

- had a pure virtual function f. If, however, its member - function f was not declared as pure virtual: -

-
-struct Base
-{
-    virtual ~Base() {}
-    virtual int f() { return 0; }
-};
-
-

- We wrap it this way: -

-
-struct BaseWrap : Base, wrapper<Base>
-{
-    int f()
-    {
-        if (override f = this->get_override("f"))
-            return f(); // *note*
-        return Base::f();
-    }
-
-    int default_f() { return this->Base::f(); }
-};
-
-

- Notice how we implemented BaseWrap::f. Now, - we have to check if there is an override for f. - If none, then we call Base::f(). -

-

- alert MSVC6/7 Workaround
-
If you are using Microsoft Visual C++ 6 or 7, you have to rewrite - the line with the *note* as:

return call<char const*>(f.ptr());. -

-

- Finally, exposing: -

-
-class_<BaseWrap, boost::noncopyable>("Base")
-    .def("f", &Base::f, &BaseWrap::default_f)
-    ;
-
-

- Take note that we expose both &Base::f and &BaseWrap::default_f. Boost.Python needs to keep track - of 1) the dispatch function f and 2) the forwarding function - to its default implementation default_f. There's a special - def function for this purpose. -

-

- In Python, the results would be as expected: -

-

-

-
->>> base = Base()
->>> class Derived(Base):
-...     def f(self):
-...         return 42
-...
->>> derived = Derived()
-
-

- Calling base.f(): -

-
->>> base.f()
-0
-
-

- Calling derived.f(): -

-
->>> derived.f()
-42
-
-
-
-

-Class Operators/Special Functions

-

- - Python Operators -

-

- C is well known for the abundance of operators. C++ extends this to the extremes - by allowing operator overloading. Boost.Python takes advantage of this and - makes it easy to wrap C++ operator-powered classes. -

-

- Consider a file position class FilePos and a set of operators - that take on FilePos instances: -

-

-

-
-class FilePos { /*...*/ };
-
-FilePos     operator+(FilePos, int);
-FilePos     operator+(int, FilePos);
-int         operator-(FilePos, FilePos);
-FilePos     operator-(FilePos, int);
-FilePos&    operator+=(FilePos&, int);
-FilePos&    operator-=(FilePos&, int);
-bool        operator<(FilePos, FilePos);
-
-

- The class and the various operators can be mapped to Python rather easily - and intuitively: -

-
-class_<FilePos>("FilePos")
-    .def(self + int())          // __add__
-    .def(int() + self)          // __radd__
-    .def(self - self)           // __sub__
-    .def(self - int())          // __sub__
-    .def(self += int())         // __iadd__
-    .def(self -= other<int>())
-    .def(self < self);          // __lt__
-
-

- The code snippet above is very clear and needs almost no explanation at all. - It is virtually the same as the operators' signatures. Just take note that - self refers to FilePos object. Also, not every class - T that you might need to interact with in an operator - expression is (cheaply) default-constructible. You can use other<T>() - in place of an actual T instance when writing "self - expressions". -

-

- - Special Methods -

-

- Python has a few more Special Methods. Boost.Python - supports all of the standard special method names supported by real Python - class instances. A similar set of intuitive interfaces can also be used to - wrap C++ functions that correspond to these Python special functions. - Example: -

-
-class Rational
-{ public: operator double() const; };
-
-Rational pow(Rational, Rational);
-Rational abs(Rational);
-ostream& operator<<(ostream&,Rational);
-
-class_<Rational>("Rational")
-    .def(float_(self))                  // __float__
-    .def(pow(self, other<Rational>))    // __pow__
-    .def(abs(self))                     // __abs__
-    .def(str(self))                     // __str__
-    ;
-
-

- Need we say more? -

-

- note What is the business of operator<<? Well, the method str - requires the operator<< - to do its work (i.e. operator<< is used by the method defined by - def(str(self)). -

-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/functions.html b/doc/tutorial/doc/html/python/functions.html deleted file mode 100644 index 3a9b53b3..00000000 --- a/doc/tutorial/doc/html/python/functions.html +++ /dev/null @@ -1,606 +0,0 @@ - - - - - - -Functions - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

-Functions

- -

- In this chapter, we'll look at Boost.Python powered functions in closer detail. - We shall see some facilities to make exposing C++ functions to Python safe - from potential pifalls such as dangling pointers and references. We shall also - see facilities that will make it even easier for us to expose C++ functions - that take advantage of C++ features such as overloading and default arguments. -

-

- Read on... -

-

- But before you do, you might want to fire up Python 2.2 or later and type - >>> import this. -

-
>>> import this
-The Zen of Python, by Tim Peters
-Beautiful is better than ugly.
-Explicit is better than implicit.
-Simple is better than complex.
-Complex is better than complicated.
-Flat is better than nested.
-Sparse is better than dense.
-Readability counts.
-Special cases aren't special enough to break the rules.
-Although practicality beats purity.
-Errors should never pass silently.
-Unless explicitly silenced.
-In the face of ambiguity, refuse the temptation to guess.
-There should be one-- and preferably only one --obvious way to do it
-Although that way may not be obvious at first unless you're Dutch.
-Now is better than never.
-Although never is often better than right now.
-If the implementation is hard to explain, it's a bad idea.
-If the implementation is easy to explain, it may be a good idea.
-Namespaces are one honking great idea -- let's do more of those!
-
-
-

-Call Policies

-

- In C++, we often deal with arguments and return types such as pointers and - references. Such primitive types are rather, ummmm, low level and they really - don't tell us much. At the very least, we don't know the owner of the pointer - or the referenced object. No wonder languages such as Java and Python never - deal with such low level entities. In C++, it's usually considered a good - practice to use smart pointers which exactly describe ownership semantics. - Still, even good C++ interfaces use raw references and pointers sometimes, - so Boost.Python must deal with them. To do this, it may need your help. Consider - the following C++ function: -

-
-X& f(Y& y, Z* z);
-
-

- How should the library wrap this function? A naive approach builds a Python - X object around result reference. This strategy might or might not work out. - Here's an example where it didn't -

-
->>> x = f(y, z) # x refers to some C++ X
->>> del y
->>> x.some_method() # CRASH!
-
-

- What's the problem? -

-

- Well, what if f() was implemented as shown below: -

-
-X& f(Y& y, Z* z)
-{
-    y.z = z;
-    return y.x;
-}
-
-

- The problem is that the lifetime of result X& is tied to the lifetime - of y, because the f() returns a reference to a member of the y object. This - idiom is is not uncommon and perfectly acceptable in the context of C++. - However, Python users should not be able to crash the system just by using - our C++ interface. In this case deleting y will invalidate the reference - to X. We have a dangling reference. -

-

- Here's what's happening: -

-
    -
  1. -f is called passing in a reference to y - and a pointer to z -
  2. -
  3. - A reference to y.x is returned -
  4. -
  5. -y is deleted. x is a dangling reference -
  6. -
  7. -x.some_method() is called -
  8. -
  9. BOOM!
  10. -
-

- We could copy result into a new object: -

-

-

-
->>> f(y, z).set(42) # Result disappears
->>> y.x.get()       # No crash, but still bad
-3.14
-
-

- This is not really our intent of our C++ interface. We've broken our promise - that the Python interface should reflect the C++ interface as closely as - possible. -

-

- Our problems do not end there. Suppose Y is implemented as follows: -

-

-

-
-struct Y
-{
-    X x; Z* z;
-    int z_value() { return z->value(); }
-};
-
-

- Notice that the data member z is held by class Y using - a raw pointer. Now we have a potential dangling pointer problem inside Y: -

-
->>> x = f(y, z) # y refers to z
->>> del z       # Kill the z object
->>> y.z_value() # CRASH!
-
-

- For reference, here's the implementation of f again: -

-
-X& f(Y& y, Z* z)
-{
-    y.z = z;
-    return y.x;
-}
-
-

- Here's what's happening: -

-
    -
  1. -f is called passing in a reference to y - and a pointer to z -
  2. -
  3. - A pointer to z is held by y -
  4. -
  5. - A reference to y.x is returned -
  6. -
  7. -z is deleted. y.z is a dangling pointer -
  8. -
  9. -y.z_value() is called -
  10. -
  11. -z->value() is called -
  12. -
  13. BOOM!
  14. -
-

- - Call Policies -

-

- Call Policies may be used in situations such as the example detailed above. - In our example, return_internal_reference and with_custodian_and_ward - are our friends: -

-
-def("f", f,
-    return_internal_reference<1,
-        with_custodian_and_ward<1, 2> >());
-
-

- What are the 1 and 2 parameters, you - ask? -

-
-return_internal_reference<1
-
-

- Informs Boost.Python that the first argument, in our case Y& - y, is the owner of the returned reference: X&. - The "1" simply specifies the first argument. - In short: "return an internal reference X& owned - by the 1st argument Y& y". -

-
-with_custodian_and_ward<1, 2>
-
-

- Informs Boost.Python that the lifetime of the argument indicated by ward - (i.e. the 2nd argument: Z* z) is dependent on the lifetime - of the argument indicated by custodian (i.e. the 1st argument: Y& - y). -

-

- It is also important to note that we have defined two policies above. Two - or more policies can be composed by chaining. Here's the general syntax: -

-
-policy1<args...,
-    policy2<args...,
-        policy3<args...> > >
-
-

- Here is the list of predefined call policies. A complete reference detailing - these can be found here. -

-
    -
  • -with_custodian_and_ward
    Ties lifetimes - of the arguments -
  • -
  • -with_custodian_and_ward_postcall
    - Ties lifetimes of the arguments and results -
  • -
  • -return_internal_reference
    Ties lifetime - of one argument to that of result -
  • -
  • -return_value_policy<T> with T one of:
    -
  • -
  • -reference_existing_object
    naive - (dangerous) approach -
  • -
  • -copy_const_reference
    Boost.Python - v1 approach -
  • -
  • -copy_non_const_reference
    -
  • -
  • -manage_new_object
    Adopt a pointer - and hold the instance -
  • -
-

- smiley Remember the Zen, Luke:
-
"Explicit is better than implicit"
"In the face - of ambiguity, refuse the temptation to guess"
-

-
-
-

-Overloading

-

- The following illustrates a scheme for manually wrapping an overloaded member - functions. Of course, the same technique can be applied to wrapping overloaded - non-member functions. -

-

- We have here our C++ class: -

-
-struct X
-{
-    bool f(int a)
-    {
-        return true;
-    }
-
-    bool f(int a, double b)
-    {
-        return true;
-    }
-
-    bool f(int a, double b, char c)
-    {
-        return true;
-    }
-
-    int f(int a, int b, int c)
-    {
-        return a + b + c;
-    };
-};
-
-

- Class X has 4 overloaded functions. We shall start by introducing some member - function pointer variables: -

-
-bool    (X::*fx1)(int)              = &X::f;
-bool    (X::*fx2)(int, double)      = &X::f;
-bool    (X::*fx3)(int, double, char)= &X::f;
-int     (X::*fx4)(int, int, int)    = &X::f;
-
-

- With these in hand, we can proceed to define and wrap this for Python: -

-
-.def("f", fx1)
-.def("f", fx2)
-.def("f", fx3)
-.def("f", fx4)
-
-
-
-

-Default Arguments

-

- Boost.Python wraps (member) function pointers. Unfortunately, C++ function - pointers carry no default argument info. Take a function f - with default arguments: -

-
-int f(int, double = 3.14, char const* = "hello");
-
-

- But the type of a pointer to the function f has no information - about its default arguments: -

-
-int(*g)(int,double,char const*) = f;    // defaults lost!
-
-

- When we pass this function pointer to the def function, - there is no way to retrieve the default arguments: -

-
-def("f", f);                            // defaults lost!
-
-

- Because of this, when wrapping C++ code, we had to resort to manual wrapping - as outlined in the previous section, - or writing thin wrappers: -

-
-// write "thin wrappers"
-int f1(int x) { f(x); }
-int f2(int x, double y) { f(x,y); }
-
-/*...*/
-
-    // in module init
-    def("f", f);  // all arguments
-    def("f", f2); // two arguments
-    def("f", f1); // one argument
-
-

- When you want to wrap functions (or member functions) that either: -

-
    -
  • - have default arguments, or -
  • -
  • - are overloaded with a common sequence of initial arguments -
  • -
-

- - BOOST_PYTHON_FUNCTION_OVERLOADS -

-

- Boost.Python now has a way to make it easier. For instance, given a function: -

-
-int foo(int a, char b = 1, unsigned c = 2, double d = 3)
-{
-    /*...*/
-}
-
-

- The macro invocation: -

-
-BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)
-
-

- will automatically create the thin wrappers for us. This macro will create - a class foo_overloads that can be passed on to def(...). - The third and fourth macro argument are the minimum arguments and maximum - arguments, respectively. In our foo function the minimum - number of arguments is 1 and the maximum number of arguments is 4. The def(...) - function will automatically add all the foo variants for us: -

-
-def("foo", foo, foo_overloads());
-
-

- - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS -

-

- Objects here, objects there, objects here there everywhere. More frequently - than anything else, we need to expose member functions of our classes to - Python. Then again, we have the same inconveniences as before when default - arguments or overloads with a common sequence of initial arguments come into - play. Another macro is provided to make this a breeze. -

-

- Like BOOST_PYTHON_FUNCTION_OVERLOADS, BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - may be used to automatically create the thin wrappers for wrapping member - functions. Let's have an example: -

-
-struct george
-{
-    void
-    wack_em(int a, int b = 0, char c = 'x')
-    {
-        /*...*/
-    }
-};
-
-

- The macro invocation: -

-
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
-
-

- will generate a set of thin wrappers for george's wack_em - member function accepting a minimum of 1 and a maximum of 3 arguments (i.e. - the third and fourth macro argument). The thin wrappers are all enclosed - in a class named george_overloads that can then be used - as an argument to def(...): -

-
-.def("wack_em", &george::wack_em, george_overloads());
-
-

- See the overloads - reference for details. -

-

- - init and optional -

-

- A similar facility is provided for class constructors, again, with default - arguments or a sequence of overloads. Remember init<...>? - For example, given a class X with a constructor: -

-
-struct X
-{
-    X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
-    /*...*/
-}
-
-

- You can easily add this constructor to Boost.Python in one shot: -

-
-.def(init<int, optional<char, std::string, double> >())
-
-

- Notice the use of init<...> and optional<...> - to signify the default (optional arguments). -

-
-
-

-Auto-Overloading

-

- It was mentioned in passing in the previous section that BOOST_PYTHON_FUNCTION_OVERLOADS - and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS can also be - used for overloaded functions and member functions with a common sequence - of initial arguments. Here is an example: -

-
-void foo()
-{
-   /*...*/
-}
-
-void foo(bool a)
-{
-   /*...*/
-}
-
-void foo(bool a, int b)
-{
-   /*...*/
-}
-
-void foo(bool a, int b, char c)
-{
-   /*...*/
-}
-
-

- Like in the previous section, we can generate thin wrappers for these overloaded - functions in one-shot: -

-
-BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
-
-

- Then... -

-
-.def("foo", (void(*)(bool, int, char))0, foo_overloads());
-
-

- Notice though that we have a situation now where we have a minimum of zero - (0) arguments and a maximum of 3 arguments. -

-

- - Manual Wrapping -

-

- It is important to emphasize however that the overloaded - functions must have a common sequence of initial arguments. Otherwise, - our scheme above will not work. If this is not the case, we have to wrap - our functions manually. -

-

- Actually, we can mix and match manual wrapping of overloaded functions and - automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - and its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following - up on our example presented in the section on - overloading, since the first 4 overload functins have a common sequence - of initial arguments, we can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - to automatically wrap the first three of the defs and - manually wrap just the last. Here's how we'll do this: -

-
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
-
-

- Create a member function pointers as above for both X::f overloads: -

-
-bool    (X::*fx1)(int, double, char)    = &X::f;
-int     (X::*fx2)(int, int, int)        = &X::f;
-
-

- Then... -

-
-.def("f", fx1, xf_overloads());
-.def("f", fx2)
-
-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/hello.html b/doc/tutorial/doc/html/python/hello.html deleted file mode 100644 index efdba8c2..00000000 --- a/doc/tutorial/doc/html/python/hello.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - - Building Hello World - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

- Building Hello World

-

- - From Start To Finish -

-

- Now the first thing you'd want to do is to build the Hello World module and - try it for yourself in Python. In this section, we shall outline the steps - necessary to achieve that. We shall use the build tool that comes bundled with - every boost distribution: bjam. -

-

- note Building without bjam
-
Besides bjam, there are of course other ways to get your module built. - What's written here should not be taken as "the one and only way". - There are of course other build tools apart from bjam.
-
Take note however that the preferred build tool for Boost.Python is - bjam. There are so many ways to set up the build incorrectly. Experience shows - that 90% of the "I can't build Boost.Python" problems come from people - who had to use a different tool. -

-

- We shall skip over the details. Our objective will be to simply create the - hello world module and run it in Python. For a complete reference to building - Boost.Python, check out: building.html. - After this brief bjam tutorial, we should have built two - DLLs: -

-
    -
  • - boost_python.dll -
  • -
  • - hello.pyd -
  • -
-

- if you are on Windows, and -

-
    -
  • - libboost_python.so -
  • -
  • - hello.so -
  • -
-

- if you are on Unix. -

-

- The tutorial example can be found in the directory: libs/python/example/tutorial. - There, you can find: -

-
    -
  • - hello.cpp -
  • -
  • - Jamfile -
  • -
-

- The hello.cpp file is our C++ hello world example. The - Jamfile is a minimalist bjam script - that builds the DLLs for us. -

-

- Before anything else, you should have the bjam executable in your boost directory - or somewhere in your path such that bjam can be executed - in the command line. Pre-built Boost.Jam executables are available for most - platforms. The complete list of Bjam executables can be found here. -

-

- - Let's Jam! -

-

- jam -

-

- Here is our minimalist Jamfile: -

-
# This is the top of our own project tree
-project-root ;
-
-import python ;
-
-extension hello                     # Declare a Python extension called hello
-:   hello.cpp                       # source
-    # requirements and dependencies for Boost.Python extensions
-    <template>@boost/libs/python/build/extension
-    ;
-
-

- First, we need to specify our location. You may place your project anywhere. - project-root allows you to do that. -

-
project-root ;
-
-

- By doing so, you'll need a Jamrules file. Simply copy the one in the example/tutorial directory - and tweak the path-global BOOST_ROOT to where your boost - root directory is. The file has detailed - instructions you can follow. -

-

- Then we will import the definitions needed by Python modules: -

-
import python ;
-
-

- Finally we declare our hello extension: -

-
extension hello                     # Declare a Python extension called hello
-:   hello.cpp                       # source
-
-    # requirements and dependencies for Boost.Python extensions
-    <template>@boost/libs/python/build/extension
-    ;
-
-

- The last part tells BJam that we are depending on the Boost Python Library. -

-

- - Running bjam -

-

- bjam is run using your operating system's command line - interpreter. -

-

- Start it up. -

-

- Make sure that the environment is set so that we can invoke the C++ compiler. - With MSVC, that would mean running the Vcvars32.bat batch - file. For instance: -

-
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
-
-

- Some environment variables will have to be setup for proper building of our - Python modules. Example: -

-
set PYTHON_ROOT=c:/dev/tools/python
-set PYTHON_VERSION=2.2
-
-

- The above assumes that the Python installation is in c:/dev/tools/python - and that we are using Python version 2.2. You'll have to tweak these appropriately. -

-

- tip Be sure not to include a third number, e.g. not "2.2.1", even if that's the version you - have. -

-

- Take note that you may also do that through the Jamrules file we put in our - project as detailed above. The file has detailed - instructions you can follow. -

-

- Now we are ready... Be sure to cd to libs/python/example/tutorial - where the tutorial "hello.cpp" and the "Jamfile" - is situated. -

-

- Finally: -

-
-bjam -sTOOLS=vc-7_1
-
-

- We are again assuming that we are using Microsoft Visual C++ version 7.1. If - not, then you will have to specify the appropriate tool. See Building - Boost Libraries for further details. -

-

- It should be building now: -

-
cd C:\dev\boost\libs\python\example\tutorial
-bjam -sTOOLS=msvc
-...patience...
-...found 1703 targets...
-...updating 40 targets...
-
-

- And so on... Finally: -

-
Creating library bin\boost\libs\python\build\boost_python.dll\vc-7_1\debug\th
-reading-multi\boost_python.lib and object bin\boost\libs\python\build\boost_pyth
-on.dll\vc-7_1\debug\threading-multi\boost_python.exp
-vc-C++ bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.obj
-hello.cpp
-vc-Link bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.pyd bin\tutori
-al\hello.pyd\vc-7_1\debug\threading-multi\hello.lib
-   Creating library bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.li
-b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
-...updated 31 targets...
-
-

- If all is well, you should now have: -

-
    -
  • - boost_python.dll -
  • -
  • - hello.pyd -
  • -
-

- if you are on Windows, and -

-
    -
  • - libboost_python.so -
  • -
  • - hello.so -
  • -
-

- if you are on Unix. -

-

- boost_python.dll and hello.pyd can be - found somewhere in your project's bin directory. After a - successful build, you make it possible for the system to find boost_python.dll - or libboost_python.so (usually done with LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, - or some other variable on *nix and with PATH on Windows) and for Python to - find the hello module (Done with PYTHONPATH on all systems.) -

-

- You may now fire up Python and run our hello module: -

-

-

-
->>> import hello
->>> print hello.greet()
-hello, world
-
-

-

-

- There you go... Have fun! -

-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/iterators.html b/doc/tutorial/doc/html/python/iterators.html deleted file mode 100644 index bbe42b0f..00000000 --- a/doc/tutorial/doc/html/python/iterators.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Iterators - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

-Iterators

-

- In C++, and STL in particular, we see iterators everywhere. Python also has - iterators, but these are two very different beasts. -

-

- C++ iterators: -

-
    -
  • - C++ has 5 type categories (random-access, bidirectional, forward, input, - output) -
  • -
  • - There are 2 Operation categories: reposition, access -
  • -
  • - A pair of iterators is needed to represent a (first/last) range. -
  • -
-

- Python Iterators: -

-
    -
  • - 1 category (forward) -
  • -
  • - 1 operation category (next()) -
  • -
  • - Raises StopIteration exception at end -
  • -
-

- The typical Python iteration protocol: for y - in x... is as follows: -

-

-

-
-iter = x.__iter__()         # get iterator
-try:
-    while 1:
-    y = iter.next()         # get each item
-    ...                     # process y
-except StopIteration: pass  # iterator exhausted
-
-

- Boost.Python provides some mechanisms to make C++ iterators play along nicely - as Python iterators. What we need to do is to produce appropriate __iter__ function from C++ iterators that - is compatible with the Python iteration protocol. For example: -

-

-

-
-object get_iterator = iterator<vector<int> >();
-object iter = get_iterator(v);
-object first = iter.next();
-
-

- Or for use in class_<>: -

-
-.def("__iter__", iterator<vector<int> >())
-
-

- range -

-

- We can create a Python savvy iterator using the range function: -

-
    -
  • - range(start, finish) -
  • -
  • - range<Policies,Target>(start, finish) -
  • -
-

- Here, start/finish may be one of: -

-
    -
  • - member data pointers -
  • -
  • - member function pointers -
  • -
  • - adaptable function object (use Target parameter) -
  • -
-

- iterator -

-
  • - iterator<T, Policies>() -
-

- Given a container T, iterator is a shortcut that simply - calls range with &T::begin, &T::end. -

-

- Let's put this into action... Here's an example from some hypothetical bogon - Particle accelerator code: -

-

-

-
-f = Field()
-for x in f.pions:
-    smash(x)
-for y in f.bogons:
-    count(y)
-
-

- Now, our C++ Wrapper: -

-

-

-
-class_<F>("Field")
-    .property("pions", range(&F::p_begin, &F::p_end))
-    .property("bogons", range(&F::b_begin, &F::b_end));
-
-

- stl_input_iterator -

-

- So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes - we wish to go the other way, though: we'd like to pass a Python sequence to - an STL algorithm or use it to initialize an STL container. We need to make - a Python iterator look like an STL iterator. For that, we use stl_input_iterator<>. - Consider how we might implement a function that exposes std::list<int>::assign() to Python: -

-

-

-
-template<typename T>
-void list_assign(std::list<T>& l, object o) {
-    // Turn a Python sequence into an STL input range
-    stl_input_iterator<T> begin(o), end;
-    l.assign(begin, end);
-}
-
-// Part of the wrapper for list<int>
-class_<std::list<int> >("list_int")
-    .def("assign", &list_assign<int>)
-    // ...
-    ;
-
-

- Now in Python, we can assign any integer sequence to list_int - objects: -

-

-

-
-x = list_int();
-x.assign([1,2,3,4,5])
-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/object.html b/doc/tutorial/doc/html/python/object.html deleted file mode 100644 index 583a4779..00000000 --- a/doc/tutorial/doc/html/python/object.html +++ /dev/null @@ -1,345 +0,0 @@ - - - - - - - Object Interface - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

- Object Interface

- -

- Python is dynamically typed, unlike C++ which is statically typed. Python variables - may hold an integer, a float, list, dict, tuple, str, long etc., among other - things. In the viewpoint of Boost.Python and C++, these Pythonic variables - are just instances of class object. We shall see in this - chapter how to deal with Python objects. -

-

- As mentioned, one of the goals of Boost.Python is to provide a bidirectional - mapping between C++ and Python while maintaining the Python feel. Boost.Python - C++ objects are as close as possible to Python. This should - minimize the learning curve significantly. -

-

- python -

-
-

-Basic Interface

-

- Class object wraps PyObject*. All the - intricacies of dealing with PyObjects such as managing - reference counting are handled by the object class. C++ - object interoperability is seamless. Boost.Python C++ objects - can in fact be explicitly constructed from any C++ object. -

-

- To illustrate, this Python code snippet: -

-

-

-
-def f(x, y):
-     if (y == 'foo'):
-         x[3:7] = 'bar'
-     else:
-         x.items += y(3, x)
-     return x
-
-def getfunc():
-   return f;
-
-

- Can be rewritten in C++ using Boost.Python facilities this way: -

-

-

-
-object f(object x, object y) {
-     if (y == "foo")
-         x.slice(3,7) = "bar";
-     else
-         x.attr("items") += y(3, x);
-     return x;
-}
-object getfunc() {
-    return object(f);
-}
-
-

- Apart from cosmetic differences due to the fact that we are writing the code - in C++, the look and feel should be immediately apparent to the Python coder. -

-
-
-

-Derived Object types

-

- Boost.Python comes with a set of derived object types - corresponding to that of Python's: -

-
    -
  • - list -
  • -
  • - dict -
  • -
  • - tuple -
  • -
  • - str -
  • -
  • - long_ -
  • -
  • - enum -
  • -
-

- These derived object types act like real Python types. - For instance: -

-
-str(1) ==> "1"
-
-

- Wherever appropriate, a particular derived object has - corresponding Python type's methods. For instance, dict - has a keys() method: -

-
-d.keys()
-
-

- make_tuple is provided for declaring tuple literals. - Example: -

-
-make_tuple(123, 'D', "Hello, World", 0.0);
-
-

- In C++, when Boost.Python objects are used as arguments - to functions, subtype matching is required. For example, when a function - f, as declared below, is wrapped, it will only accept - instances of Python's str type and subtypes. -

-
-void f(str name)
-{
-    object n2 = name.attr("upper")();   // NAME = name.upper()
-    str NAME = name.upper();            // better
-    object msg = "%s is bigger than %s" % make_tuple(NAME,name);
-}
-
-

- In finer detail: -

-
-str NAME = name.upper();
-
-

- Illustrates that we provide versions of the str type's methods as C++ member - functions. -

-
-object msg = "%s is bigger than %s" % make_tuple(NAME,name);
-
-

- Demonstrates that you can write the C++ equivalent of "format" - % x,y,z in Python, which is useful since there's no easy way to - do that in std C++. -

-

- alert Beware the common - pitfall of forgetting that the constructors of most of Python's mutable types - make copies, just as in Python. -

-

- Python: -

-
->>> d = dict(x.__dict__)     # copies x.__dict__
->>> d['whatever'] = 3        # modifies the copy
-
-

- C++: -

-
-dict d(x.attr("__dict__"));  // copies x.__dict__
-d['whatever'] = 3;           // modifies the copy
-
-

- - class_<T> as objects -

-

- Due to the dynamic nature of Boost.Python objects, any class_<T> - may also be one of these types! The following code snippet wraps the class - (type) object. -

-

- We can use this to create wrapped instances. Example: -

-
-object vec345 = (
-    class_<Vec2>("Vec2", init<double, double>())
-        .def_readonly("length", &Point::length)
-        .def_readonly("angle", &Point::angle)
-    )(3.0, 4.0);
-
-assert(vec345.attr("length") == 5.0);
-
-
-
-

-Extracting C++ objects

-

- At some point, we will need to get C++ values out of object instances. This - can be achieved with the extract<T> function. Consider - the following: -

-
-double x = o.attr("length"); // compile error
-
-

- In the code above, we got a compiler error because Boost.Python object - can't be implicitly converted to doubles. Instead, what - we wanted to do above can be achieved by writing: -

-
-double l = extract<double>(o.attr("length"));
-Vec2& v = extract<Vec2&>(o);
-assert(l == v.length());
-
-

- The first line attempts to extract the "length" attribute of the - Boost.Python object. The second line attempts to extract - the Vec2 object from held by the Boost.Python object. -

-

- Take note that we said "attempt to" above. What if the Boost.Python - object does not really hold a Vec2 - type? This is certainly a possibility considering the dynamic nature of Python - objects. To be on the safe side, if the C++ type can't - be extracted, an appropriate exception is thrown. To avoid an exception, - we need to test for extractibility: -

-
-extract<Vec2&> x(o);
-if (x.check()) {
-    Vec2& v = x(); ...
-
-

- tip The astute reader might have noticed that the extract<T> - facility in fact solves the mutable copying problem: -

-
-dict d = extract<dict>(x.attr("__dict__"));
-d["whatever"] = 3;          // modifies x.__dict__ !
-
-
-
-

-Enums

-

- Boost.Python has a nifty facility to capture and wrap C++ enums. While Python - has no enum type, we'll often want to expose our C++ enums - to Python as an int. Boost.Python's enum facility makes - this easy while taking care of the proper conversions from Python's dynamic - typing to C++'s strong static typing (in C++, ints cannot be implicitly converted - to enums). To illustrate, given a C++ enum: -

-
-enum choice { red, blue };
-
-

- the construct: -

-
-enum_<choice>("choice")
-    .value("red", red)
-    .value("blue", blue)
-    ;
-
-

- can be used to expose to Python. The new enum type is created in the current - scope(), which is usually the current module. The snippet - above creates a Python class derived from Python's int - type which is associated with the C++ type passed as its first parameter. -

-

- note what is a scope?
-
The scope is a class that has an associated global Python object which - controls the Python namespace in which new extension classes and wrapped - functions will be defined as attributes. Details can be found here. -

-

- You can access those values in Python as -

-

-

-
->>> my_module.choice.red
-my_module.choice.red
-
-

- where my_module is the module where the enum is declared. You can also create - a new scope around a class: -

-

-

-
-scope in_X = class_<X>("X")
-                .def( ... )
-                .def( ... )
-            ;
-
-// Expose X::nested as X.nested
-enum_<X::nested>("nested")
-    .value("red", red)
-    .value("blue", blue)
-    ;
-
-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHomeNext -
- - diff --git a/doc/tutorial/doc/html/python/techniques.html b/doc/tutorial/doc/html/python/techniques.html deleted file mode 100644 index a60b7278..00000000 --- a/doc/tutorial/doc/html/python/techniques.html +++ /dev/null @@ -1,453 +0,0 @@ - - - - - - - General Techniques - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHome -
-
-

- General Techniques

- -

- Here are presented some useful techniques that you can use while wrapping code - with Boost.Python. -

-
-

-Creating Packages

-

- A Python package is a collection of modules that provide to the user a certain - functionality. If you're not familiar on how to create packages, a good introduction - to them is provided in the Python - Tutorial. -

-

- But we are wrapping C++ code, using Boost.Python. How can we provide a nice - package interface to our users? To better explain some concepts, let's work - with an example. -

-

- We have a C++ library that works with sounds: reading and writing various - formats, applying filters to the sound data, etc. It is named (conveniently) - sounds. Our library already has a neat C++ namespace hierarchy, - like so: -

-
-sounds::core
-sounds::io
-sounds::filters
-
-

- We would like to present this same hierarchy to the Python user, allowing - him to write code like this: -

-
-import sounds.filters
-sounds.filters.echo(...) # echo is a C++ function
-
-

- The first step is to write the wrapping code. We have to export each module - separately with Boost.Python, like this: -

-
-/* file core.cpp */
-BOOST_PYTHON_MODULE(core)
-{
-    /* export everything in the sounds::core namespace */
-    ...
-}
-
-/* file io.cpp */
-BOOST_PYTHON_MODULE(io)
-{
-    /* export everything in the sounds::io namespace */
-    ...
-}
-
-/* file filters.cpp */
-BOOST_PYTHON_MODULE(filters)
-{
-    /* export everything in the sounds::filters namespace */
-    ...
-}
-
-

- Compiling these files will generate the following Python extensions: core.pyd, - io.pyd and filters.pyd. -

-

- note The extension .pyd is used for python - extension modules, which are just shared libraries. Using the default for - your system, like .so for Unix and .dll - for Windows, works just as well. -

-

- Now, we create this directory structure for our Python package: -

-
sounds/
-    __init__.py
-    core.pyd
-    filters.pyd
-    io.pyd
-
-

- The file __init__.py is what tells Python that the directory - sounds/ is actually a Python package. It can be a empty - file, but can also perform some magic, that will be shown later. -

-

- Now our package is ready. All the user has to do is put sounds - into his PYTHONPATH - and fire up the interpreter: -

-

-

-
->>> import sounds.io
->>> import sounds.filters
->>> sound = sounds.io.open('file.mp3')
->>> new_sound = sounds.filters.echo(sound, 1.0)
-
-

- Nice heh? -

-

- This is the simplest way to create hierarchies of packages, but it is not - very flexible. What if we want to add a pure Python - function to the filters package, for instance, one that applies 3 filters - in a sound object at once? Sure, you can do this in C++ and export it, but - why not do so in Python? You don't have to recompile the extension modules, - plus it will be easier to write it. -

-

- If we want this flexibility, we will have to complicate our package hierarchy - a little. First, we will have to change the name of the extension modules: -

-

-

-
-/* file core.cpp */
-BOOST_PYTHON_MODULE(_core)
-{
-    ...
-    /* export everything in the sounds::core namespace */
-}
-
-

- Note that we added an underscore to the module name. The filename will have - to be changed to _core.pyd as well, and we do the same - to the other extension modules. Now, we change our package hierarchy like - so: -

-
sounds/
-    __init__.py
-    core/
-        __init__.py
-        _core.pyd
-    filters/
-        __init__.py
-        _filters.pyd
-    io/
-        __init__.py
-        _io.pyd
-
-

- Note that we created a directory for each extension module, and added a __init__.py - to each one. But if we leave it that way, the user will have to access the - functions in the core module with this syntax: -

-

-

-
->>> import sounds.core._core
->>> sounds.core._core.foo(...)
-
-

- which is not what we want. But here enters the __init__.py - magic: everything that is brought to the __init__.py namespace - can be accessed directly by the user. So, all we have to do is bring the - entire namespace from _core.pyd to core/__init__.py. - So add this line of code to soundscore__init__.py: -

-
-from _core import *
-
-

- We do the same for the other packages. Now the user accesses the functions - and classes in the extension modules like before: -

-
->>> import sounds.filters
->>> sounds.filters.echo(...)
-
-

- with the additional benefit that we can easily add pure Python functions - to any module, in a way that the user can't tell the difference between a - C++ function and a Python function. Let's add a pure - Python function, echo_noise, to the filters - package. This function applies both the echo and noise - filters in sequence in the given sound object. We create - a file named sounds/filters/echo_noise.py and code our - function: -

-
-import _filters
-def echo_noise(sound):
-    s = _filters.echo(sound)
-    s = _filters.noise(sound)
-    return s
-
-

- Next, we add this line to soundsfilters__init__.py: -

-
-from echo_noise import echo_noise
-
-

- And that's it. The user now accesses this function like any other function - from the filters package: -

-
->>> import sounds.filters
->>> sounds.filters.echo_noise(...)
-
-
-
-

-Extending Wrapped Objects in Python

-

- Thanks to Python's flexibility, you can easily add new methods to a class, - even after it was already created: -

-
->>> class C(object): pass
->>>
->>> # a regular function
->>> def C_str(self): return 'A C instance!'
->>>
->>> # now we turn it in a member function
->>> C.__str__ = C_str
->>>
->>> c = C()
->>> print c
-A C instance!
->>> C_str(c)
-A C instance!
-
-

- Yes, Python rox. smiley -

-

- We can do the same with classes that were wrapped with Boost.Python. Suppose - we have a class point in C++: -

-

-

-
-class point {...};
-
-BOOST_PYTHON_MODULE(_geom)
-{
-    class_<point>("point")...;
-}
-
-

- If we are using the technique from the previous session, Creating - Packages, we can code directly into geom/__init__.py: -

-

-

-
-from _geom import *
-
-# a regular function
-def point_str(self):
-    return str((self.x, self.y))
-
-# now we turn it into a member function
-point.__str__ = point_str
-
-

- All point instances created from C++ will - also have this member function! This technique has several advantages: -

-
    -
  • - Cut down compile times to zero for these additional functions -
  • -
  • - Reduce the memory footprint to virtually zero -
  • -
  • - Minimize the need to recompile -
  • -
  • - Rapid prototyping (you can move the code to C++ if required without changing - the interface) -
  • -
-

- You can even add a little syntactic sugar with the use of metaclasses. Let's - create a special metaclass that "injects" methods in other classes. -

-
-# The one Boost.Python uses for all wrapped classes.
-# You can use here any class exported by Boost instead of "point"
-BoostPythonMetaclass = point.__class__
-
-class injector(object):
-    class __metaclass__(BoostPythonMetaclass):
-        def __init__(self, name, bases, dict):
-            for b in bases:
-                if type(b) not in (self, type):
-                    for k,v in dict.items():
-                        setattr(b,k,v)
-            return type.__init__(self, name, bases, dict)
-
-# inject some methods in the point foo
-class more_point(injector, point):
-    def __repr__(self):
-        return 'Point(x=%s, y=%s)' % (self.x, self.y)
-    def foo(self):
-        print 'foo!'
-
-

- Now let's see how it got: -

-
->>> print point()
-Point(x=10, y=10)
->>> point().foo()
-foo!
-
-

- Another useful idea is to replace constructors with factory functions: -

-
-_point = point
-
-def point(x=0, y=0):
-    return _point(x, y)
-
-

- In this simple case there is not much gained, but for constructurs with many - overloads and/or arguments this is often a great simplification, again with - virtually zero memory footprint and zero compile-time overhead for the keyword - support. -

-
-
-

-Reducing Compiling Time

-

- If you have ever exported a lot of classes, you know that it takes quite - a good time to compile the Boost.Python wrappers. Plus the memory consumption - can easily become too high. If this is causing you problems, you can split - the class_ definitions in multiple files: -

-

-

-
-/* file point.cpp */
-#include <point.h>
-#include <boost/python.hpp>
-
-void export_point()
-{
-    class_<point>("point")...;
-}
-
-/* file triangle.cpp */
-#include <triangle.h>
-#include <boost/python.hpp>
-
-void export_triangle()
-{
-    class_<triangle>("triangle")...;
-}
-
-

- Now you create a file main.cpp, which contains the BOOST_PYTHON_MODULE - macro, and call the various export functions inside it. -

-
-void export_point();
-void export_triangle();
-
-BOOST_PYTHON_MODULE(_geom)
-{
-    export_point();
-    export_triangle();
-}
-
-

- Compiling and linking together all this files produces the same result as - the usual approach: -

-
-#include <boost/python.hpp>
-#include <point.h>
-#include <triangle.h>
-
-BOOST_PYTHON_MODULE(_geom)
-{
-    class_<point>("point")...;
-    class_<triangle>("triangle")...;
-}
-
-

- but the memory is kept under control. -

-

- This method is recommended too if you are developing the C++ library and - exporting it to Python at the same time: changes in a class will only demand - the compilation of a single cpp, instead of the entire wrapper code. -

-

- note If you're exporting your classes with Pyste, - take a look at the --multiple option, that generates the - wrappers in various files as demonstrated here. -

-

- note This method is useful too if you are getting the error - message "fatal error C1204:Compiler limit:internal structure - overflow" when compiling a large source file, as explained - in the FAQ. -

-
-
- - - -
Copyright © 2002-2005 Joel - de Guzman, David Abrahams
-
-
-PrevUpHome -
- - diff --git a/doc/tutorial/doc/tutorial.qbk b/doc/tutorial/doc/tutorial.qbk deleted file mode 100644 index c90db572..00000000 --- a/doc/tutorial/doc/tutorial.qbk +++ /dev/null @@ -1,2150 +0,0 @@ -[library python - [version 1.0] - [authors [de Guzman, Joel], [Abrahams, David]] - [copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams] - [category inter-language support] - [purpose - Reflects C++ classes and functions into Python - ] - [license - 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 - ) - ] -] - -[/ QuickBook Document version 0.9 ] - -[def __note__ [$images/note.png]] -[def __alert__ [$images/alert.png]] -[def __tip__ [$images/tip.png]] -[def :-) [$images/smiley.png]] -[def __jam__ [$images/jam.png]] - -[section QuickStart] - -The Boost Python Library is a framework for interfacing Python and -C++. It allows you to quickly and seamlessly expose C++ classes -functions and objects to Python, and vice-versa, using no special -tools -- just your C++ compiler. It is designed to wrap C++ interfaces -non-intrusively, so that you should not have to change the C++ code at -all in order to wrap it, making Boost.Python ideal for exposing -3rd-party libraries to Python. The library's use of advanced -metaprogramming techniques simplifies its syntax for users, so that -wrapping code takes on the look of a kind of declarative interface -definition language (IDL). - -[h2 Hello World] - -Following C/C++ tradition, let's start with the "hello, world". A C++ -Function: - - char const* greet() - { - return "hello, world"; - } - -can be exposed to Python by writing a Boost.Python wrapper: - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet); - } - -That's it. We're done. We can now build this as a shared library. The -resulting DLL is now visible to Python. Here's a sample Python session: - -[python] - - >>> import hello - >>> print hello.greet() - hello, world - -[c++] - -[:['[*Next stop... Building your Hello World module from start to finish...]]] - -[endsect] -[section:hello Building Hello World] - -[h2 From Start To Finish] - -Now the first thing you'd want to do is to build the Hello World module and -try it for yourself in Python. In this section, we shall outline the steps -necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: [*bjam]. - -[blurb __note__ [*Building without bjam]\n\n - Besides bjam, there are of course other ways to get your module built. - What's written here should not be taken as "the one and only way". - There are of course other build tools apart from [^bjam].\n\n - Take note however that the preferred build tool for Boost.Python is bjam. - There are so many ways to set up the build incorrectly. Experience shows - that 90% of the "I can't build Boost.Python" problems come from people - who had to use a different tool. -] - -We shall skip over the details. Our objective will be to simply create the -hello world module and run it in Python. For a complete reference to -building Boost.Python, check out: [@../../../building.html building.html]. -After this brief ['bjam] tutorial, we should have built two DLLs: - -* boost_python.dll -* hello.pyd - -if you are on Windows, and - -* libboost_python.so -* hello.so - -if you are on Unix. - -The tutorial example can be found in the directory: -[^libs/python/example/tutorial]. There, you can find: - -* hello.cpp -* Jamfile - -The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a -minimalist ['bjam] script that builds the DLLs for us. - -Before anything else, you should have the bjam executable in your boost -directory or somewhere in your path such that [^bjam] can be executed in -the command line. Pre-built Boost.Jam executables are available for most -platforms. The complete list of Bjam executables can be found -[@http://sourceforge.net/project/showfiles.php?group_id=7586 here]. - -[h2 Let's Jam!] -__jam__ - -Here is our minimalist Jamfile: - -[pre -# This is the top of our own project tree -project-root ; - -import python ; - -extension hello # Declare a Python extension called hello -: hello.cpp # source - # requirements and dependencies for Boost.Python extensions -