[C++-sig] BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS with default args dumps core
Hi all,
I'm having trouble wrapping a very simple member function with Boost.Python
using the
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS macro, getting a segmentation fault.
I run into the problem both with Boost 1.44.0 and 1.46.1, running on
Solaris 10/Sparc
using gcc 4.5.1 and Python 2.7.1.
What's a bit strange is that I can run the offending Python code snippet
successfully
iff there is a Boost.Python induced exception raised before this code gets
invoked,
i.e. there are reproducable situations where the same code does not suffer
the segfault;
see "# test runs" below.
# wrapped class
$ cat default_arguments_class.hpp
class DefaultArgs {
public: // member functions
int foo(int arg1=100, int arg2=10) { return arg1 - arg2; };
};
# wrapper code
$ cat default_arguments_wrap.cpp
// file default_arguments_wrap.cpp
#include
#include "default_arguments_class.hpp"
namespace bp = boost::python;
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(DefaultArgs_foo_overloads,
DefaultArgs::foo, 0, 2)
BOOST_PYTHON_MODULE(defaultargs)
{
bp::class_("DefaultArgs", "DefaultArgs class docstring")
.def("foo", &DefaultArgs::foo, (bp::arg("arg1")=100,
bp::arg("arg2")=10))
.def("foo_macro", &DefaultArgs::foo, DefaultArgs_foo_overloads())
.def("foo_macro_a1_a2_with_defaults", &DefaultArgs::foo,
DefaultArgs_foo_overloads((bp::arg("arg1")=100, bp::arg("arg2")=10)))
.def("foo_macro_a2", &DefaultArgs::foo,
DefaultArgs_foo_overloads((bp::arg("arg2"
;
};
# the Jamroot file
$ cat Jamroot
# get the environment variable "USER"
import os ;
local _USER = [ os.environ USER ] ;
#ECHO $(_USER) ;
local _BOOST_ROOT = /var/tmp/$(_USER)/boost_apps/boost ;
local _BOOST_VERSION = boost_1_46_1 ;
#local _BOOST_VERSION = boost_1_44_0 ;
#ECHO $(_BOOST_ROOT) ;
use-project boost : $(_BOOST_ROOT)/$(_BOOST_VERSION) ;
# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.
project minimal
: requirements /boost/python//boost_python
debug:$(_BOOST_ROOT)/build/$(_BOOST_VERSION)/py2.7/stage/debug/lib
release:$(_BOOST_ROOT)/build/$(_BOOST_VERSION)/py2.7/stage/release/lib
;
python-extension defaultargs
: # sources + // Add all files here otherwise we get undefined
symbol errors like
default_arguments_wrap.cpp
: # requirements *
: # default-build *
: # usage-requirements *
;
# simple test script
$ cat test_defaultargs2.py
#!/apps/local/gcc/4.5.1/bin/python2.7
import os
import sys
import argparse
_USER=os.getenv("USER")
parser = argparse.ArgumentParser()
parser.add_argument(
'--path', type=str,
help='lib installation base path (default: %(default)s)',
default='/var/tmp/%s/boost_apps/boost/build/boost_1_44_0/py2.7/'
'minimal/gcc-4.5.1' % (_USER),)
parser.add_argument(
'--variant', type=str, default='debug',
help='lib installation path variant (default: %(default)s)')
parser.add_argument(
'--with-exception', action='store_true',
help='prepend a test with successful Boost exception')
args = parser.parse_args()
EXPATH = os.path.join(args.path, args.variant)
sys.path.insert(1, EXPATH)
try:
import defaultargs
except:
print "sys.path set correctly?", sys.path
raise
d = defaultargs.DefaultArgs()
if args.with_exception:
try:
print "d.foo_macro_a2(1, 2, 3):", d.foo_macro_a2(1, 2, 3)
except Exception, e:
print e
print "d.foo_macro_a2(arg2=60):", d.foo_macro_a2(arg2=60)
# Test run
$ ./test_defaultargs2.py
--path=/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
--with-exception
d.foo_macro_a2(1, 2, 3): Python argument types in
DefaultArgs.foo_macro_a2(DefaultArgs, int, int, int)
did not match C++ signature:
foo_macro_a2(DefaultArgs {lvalue})
foo_macro_a2(DefaultArgs {lvalue}, int)
foo_macro_a2(DefaultArgs {lvalue}, int, int arg2)
d.foo_macro_a2(arg2=60):
Traceback (most recent call last):
File "./test_defaultargs2.py", line 42, in
print "d.foo_macro_a2(arg2=60):", d.foo_macro_a2(arg2=60)
Boost.Python.ArgumentError: Python argument types in
DefaultArgs.foo_macro_a2(DefaultArgs)
did not match C++ signature:
foo_macro_a2(DefaultArgs {lvalue})
foo_macro_a2(DefaultArgs {lvalue}, int)
foo_macro_a2(DefaultArgs {lvalue}, int, int arg2)
1 $ ./test_defaultargs2.py
--path=/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
Segmentation Fault (core dumped)
139 $ /apps/local/gcc/4.5.1/bin/gdb /apps/local/gcc/4.5.1/bin/python2.7 -c
core
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "sparc-s
[C++-sig] BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS with default args dumps core
[ 2nd try due to user stupidity, please ignore if this is being delivered
twice ]
Hi all,
I'm having trouble wrapping a very simple member function with Boost.Python
using the
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS macro, getting a segmentation fault.
I run into the problem both with Boost 1.44.0 and 1.46.1, running on
Solaris 10/Sparc
using gcc 4.5.1 and Python 2.7.1.
What's a bit strange is that I can run the offending Python code snippet
successfully
iff there is a Boost.Python induced exception raised before this code gets
invoked,
i.e. there are reproducable situations where the same code does not suffer
the segfault;
see "# test runs" below.
# wrapped class
$ cat default_arguments_class.hpp
class DefaultArgs {
public: // member functions
int foo(int arg1=100, int arg2=10) { return arg1 - arg2; };
};
# wrapper code
$ cat default_arguments_wrap.cpp
// file default_arguments_wrap.cpp
#include
#include "default_arguments_class.hpp"
namespace bp = boost::python;
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(DefaultArgs_foo_overloads,
DefaultArgs::foo, 0, 2)
BOOST_PYTHON_MODULE(defaultargs)
{
bp::class_("DefaultArgs", "DefaultArgs class docstring")
.def("foo", &DefaultArgs::foo, (bp::arg("arg1")=100,
bp::arg("arg2")=10))
.def("foo_macro", &DefaultArgs::foo, DefaultArgs_foo_overloads())
.def("foo_macro_a1_a2_with_defaults", &DefaultArgs::foo,
DefaultArgs_foo_overloads((bp::arg("arg1")=100, bp::arg("arg2")=10)))
.def("foo_macro_a2", &DefaultArgs::foo,
DefaultArgs_foo_overloads((bp::arg("arg2"
;
};
# the Jamroot file
$ cat Jamroot
# get the environment variable "USER"
import os ;
local _USER = [ os.environ USER ] ;
#ECHO $(_USER) ;
local _BOOST_ROOT = /var/tmp/$(_USER)/boost_apps/boost ;
local _BOOST_VERSION = boost_1_46_1 ;
#local _BOOST_VERSION = boost_1_44_0 ;
#ECHO $(_BOOST_ROOT) ;
use-project boost : $(_BOOST_ROOT)/$(_BOOST_VERSION) ;
# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.
project minimal
: requirements /boost/python//boost_python
debug:$(_BOOST_ROOT)/build/$(_BOOST_VERSION)/py2.7/stage/debug/lib
release:$(_BOOST_ROOT)/build/$(_BOOST_VERSION)/py2.7/stage/release/lib
;
python-extension defaultargs
: # sources + // Add all files here otherwise we get undefined
symbol errors like
default_arguments_wrap.cpp
: # requirements *
: # default-build *
: # usage-requirements *
;
# simple test script
$ cat test_defaultargs2.py
#!/apps/local/gcc/4.5.1/bin/python2.7
import os
import sys
import argparse
_USER=os.getenv("USER")
parser = argparse.ArgumentParser()
parser.add_argument(
'--path', type=str,
help='lib installation base path (default: %(default)s)',
default='/var/tmp/%s/boost_apps/boost/build/boost_1_44_0/py2.7/'
'minimal/gcc-4.5.1' % (_USER),)
parser.add_argument(
'--variant', type=str, default='debug',
help='lib installation path variant (default: %(default)s)')
parser.add_argument(
'--with-exception', action='store_true',
help='prepend a test with successful Boost exception')
args = parser.parse_args()
EXPATH = os.path.join(args.path, args.variant)
sys.path.insert(1, EXPATH)
try:
import defaultargs
except:
print "sys.path set correctly?", sys.path
raise
d = defaultargs.DefaultArgs()
if args.with_exception:
try:
print "d.foo_macro_a2(1, 2, 3):", d.foo_macro_a2(1, 2, 3)
except Exception, e:
print e
print "d.foo_macro_a2(arg2=60):", d.foo_macro_a2(arg2=60)
# Test run
$ ./test_defaultargs2.py
--path=/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
--with-exception
d.foo_macro_a2(1, 2, 3): Python argument types in
DefaultArgs.foo_macro_a2(DefaultArgs, int, int, int)
did not match C++ signature:
foo_macro_a2(DefaultArgs {lvalue})
foo_macro_a2(DefaultArgs {lvalue}, int)
foo_macro_a2(DefaultArgs {lvalue}, int, int arg2)
d.foo_macro_a2(arg2=60):
Traceback (most recent call last):
File "./test_defaultargs2.py", line 42, in
print "d.foo_macro_a2(arg2=60):", d.foo_macro_a2(arg2=60)
Boost.Python.ArgumentError: Python argument types in
DefaultArgs.foo_macro_a2(DefaultArgs)
did not match C++ signature:
foo_macro_a2(DefaultArgs {lvalue})
foo_macro_a2(DefaultArgs {lvalue}, int)
foo_macro_a2(DefaultArgs {lvalue}, int, int arg2)
1 $ ./test_defaultargs2.py
--path=/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
Segmentation Fault (core dumped)
139 $ /apps/local/gcc/4.5.1/bin/gdb /apps/local/gcc/4.5.1/bin/python2.7 -c
core
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <
http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type
