Re: [C++-sig] export custom C++ exception to Python so it can be raisedby python
On 05/11/2012 18:51, Martin Hellmich wrote: Hi, I have a custom exception in C++ that I would like to use in Python. Let's call it MyException with custom constructor and members (an implementation is below). I would like to expose it to python so that I can raise it: > raise MyException(-1, 'tragic error') The perfect way that I can imagine is to tell boost::python to base the class on PyExc_Exception, but that doesn't seem to work. Furthermore I have found various solutions how to translate exceptions thrown in C++ into proper Python exceptions, but in my case these solutions sit at the wrong place. I've based my code on. http://stackoverflow.com/questions/9620268/boost-python-custom-exception-class I would like to avoid to create a corresponding python class to the C++ exception, because there would be added effort to keep the two descriptions consistent. True. class MyException: public std::exception { MyException(); MyException(int code, const std::string &string); int code(); const char* what(); int errorCode; std::string errorMessage; }; The only unusual stuff is that you need both code and message. 2 ideas come to mind. 1) you can base the python exception not on PyExc_Exception but on a custom class which can handle both error code and message, so the exception translator can do both a PyErr_SetString and a "PyErr_SetCode". This way you can use the exception in both C and Python in the same style, no need to keep anything in sync. 2) you can base the Python exception on the standard PyExc_Exception but use PyErr_SetObject in the exception translator. A quick search finds this http://stackoverflow.com/questions/2261858/boostpython-export-custom-exception (does not inherit from Exception, though) -- Giuseppe Corbelli WASP Software Engineer, Copan Italia S.p.A Phone: +390303666318 Fax: +390302659932 E-mail: giuseppe.corbe...@copanitalia.com ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] how to boost.build using two different python versions
Dear all, I need to cross compile a python extension using boost.build. I have Python 2.6 (32 and 64 Bit) and Python 2.7 (64 Bit) installed on my computer. I compiled boost with Python 2.6 (32Bit). My goal is to compile the python extension for Python 2.7 (64Bit). The problem is that it does not try to not find the python27.lib. Is there a way to do this without re-compiling Boost with Python 2.7? Thanks, Ronny Jamroot: # 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) # using msvc ; # Make the definition of the python-extension rule available import python ; #using python : 2.6 : c:/Python26/python.exe #: c:/Python26/include #: c:/Python26/libs #: 32 #; using python : 2.7 : c:/Python27_64/python.exe : c:/Python27_64/include : c:/Python27_64/libs : 64 ; # Specify the path to the Boost project. If you move this project, # adjust the path to refer to the Boost root directory. use-project boost : c:/boost_1_50_0 ; # Set up the project-wide requirements that everything uses the # boost_python library defined in the project whose global ID is # /boost/python. project boost-python-quickstart : requirements /boost/python//boost_python ; # Declare a Python extension python-extension calcsf : lipidxexception.cpp CalcSF.cpp ; install convenient_copy : calcsf : on SHARED_LIB PYTHON_EXTENSION 32:c:/users/duke/my_projects/lipidxplorer/trunk/lx/mfql/calcsf26_32 64:c:/users/duke/my_projects/lipidxplorer/trunk/lx/mfql/calcsf27_64 ; The output: C:\Users\Duke\My_Projects\boost_python\calcsf>bjam address-model=64 release link =static -d+2 file bin\msvc-9.0\release\address-model-64\link-static\threading-multi\calcsf.py d.rsp "bin\msvc-9.0\release\address-model-64\link-static\threading-multi\lipidxexcepti on.obj" "bin\msvc-9.0\release\address-model-64\link-static\threading-multi\CalcSF.obj" "C:\boost_1_50_0\bin.v2\libs\python\build\msvc-9.0\release\address-model-64\link -static\threading-multi\libboost_python-vc90-mt-1_50.lib" "python26.lib" msvc.link.dll bin\msvc-9.0\release\address-model-64\link-static\threading-multi\ calcsf.pyd call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86 _amd64 >nul link /NOLOGO /INCREMENTAL:NO /DLL /MACHINE:X64 /subsystem:console /out:"bin\msvc -9.0\release\address-model-64\link-static\threading-multi\calcsf.pyd" /IMPLIB:"b in\msvc-9.0\release\address-model-64\link-static\threading-multi\calcsf.lib" /LI BPATH:"c:\Python64\libs" @"bin\msvc-9.0\release\address-model-64\link-static\t hreading-multi\calcsf.pyd.rsp" if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL% LINK : fatal error LNK1104: cannot open file 'python27.lib' ...skipped ca lcsf.pyd for lack of ng-multi>calcsf.pyd... ...failed updating 2 targets... <>___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] export custom C++ exception to Python so it can be raisedby python
Hi Giuseppe, On 11/06/2012 10:08 AM, Giuseppe Corbelli wrote: On 05/11/2012 18:51, Martin Hellmich wrote: Hi, I have a custom exception in C++ that I would like to use in Python. Let's call it MyException with custom constructor and members (an implementation is below). I would like to expose it to python so that I can raise it: > raise MyException(-1, 'tragic error') The perfect way that I can imagine is to tell boost::python to base the class on PyExc_Exception, but that doesn't seem to work. Furthermore I have found various solutions how to translate exceptions thrown in C++ into proper Python exceptions, but in my case these solutions sit at the wrong place. I've based my code on. http://stackoverflow.com/questions/9620268/boost-python-custom-exception-class I have used the same reference and also this suggestion for including the other attributes shown here: http://stackoverflow.com/questions/11448735/boostpython-export-custom-exception-and-inherit-from-pythons-exception However, this doesn't solve my problem. It works fine when I throw the MyException in C++, but when I raise the MyCPPException in Python, the translator is not called (which makes sense), so the attribute 'cause' does not change. Actually, before I throw the MyException for the first time in C++, MyCPPException does not have the attribute 'cause' at all. This issue should be the same, if I set the exception with PyErr_SetObject, since the translator is not called, when I 'raise' it. My current attempt is quite different (and all in Python): import exc class MyException(Exception): def __init__(self, *args): self.e = exc.MyException(*args) def __getattr__(self, name): return self.e.__getattribute__(name) def __str__(self): return type(self).__name__ + ': ' + self.e.what() e=MyException(1, 'bla') I can 'raise MyException(1, 'some error')' and get the attributes I have in C++. If the attributes change, it should all work except for the __str__ function, which is hardcoded. The drawback is that it's in python. The python part will be developed by third parties and I then have to make sure that they see and use this provided exception ... Also I don't know yet how translating this back to C++ will play out. I guess I am jumping a bit ahead ... is it correct from me to assume that this behaviour is not possible with the solutions posted on stackoverflow or am I overlooking something? I am very happy about any replies :) Cheers Martin I would like to avoid to create a corresponding python class to the C++ exception, because there would be added effort to keep the two descriptions consistent. True. class MyException: public std::exception { MyException(); MyException(int code, const std::string &string); int code(); const char* what(); int errorCode; std::string errorMessage; }; The only unusual stuff is that you need both code and message. 2 ideas come to mind. 1) you can base the python exception not on PyExc_Exception but on a custom class which can handle both error code and message, so the exception translator can do both a PyErr_SetString and a "PyErr_SetCode". This way you can use the exception in both C and Python in the same style, no need to keep anything in sync. 2) you can base the Python exception on the standard PyExc_Exception but use PyErr_SetObject in the exception translator. A quick search finds this http://stackoverflow.com/questions/2261858/boostpython-export-custom-exception (does not inherit from Exception, though) -- Martin HellmichInformation Technology Department mhell...@cern.chCERN +41 22 76 765 26 CH-1211 Geneva 23 ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] problem embedding python - very simple example
I downloaded and installed the 32-bit version of Python 3.3. I downloaded and compiled boost-1.52.0. I've been able to build and run the tutorial Python extension but haven't been able to get anything but the most trivial example of embedding to work. My code (which compiles with no warnings): #include using namespace boost::python; int main() { Py_Initialize(); object main_module = import("__main__"); object main_namespace = main_module.attr("__dict__"); exec("print('hello')\n", main_namespace); exec("print('world')\n", main_namespace); exec("f = file('hello.txt', 'w')\n", main_namespace); return 0; } It prints "hello\nworld\n" then throws an exception executing the line that creates the hello.txt file: First-chance exception at 0x755ac41f in Test.exe: Microsoft C++ exception: boost::python::error_already_set at memory location 0x0039fb60.. Unhandled exception at 0x773915de (ntdll.dll) in Test.exe: Microsoft C++ exception: boost::python::error_already_set at memory location 0x0039fb60.. In the exec method, the exception is being thrown when result comes back as null: PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr()); if (!result) throw_error_already_set(); I'm using VS2010SP1 on Windows7 which I believe is what Python 3.3 is built with. I'm dynamically linking against boost. Any suggestions? ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] problem embedding python - very simple example
Argh! I didn't notice that the example code I was trying was using file() rather than open(). Sheeesh. After correcting this, I was able to get it to work successfully! Step one on the thousand mile journey is complete! Cory On 11/6/2012 1:40 PM, Cory Riddell wrote: > I downloaded and installed the 32-bit version of Python 3.3. I > downloaded and compiled boost-1.52.0. I've been able to build and run > the tutorial Python extension but haven't been able to get anything but > the most trivial example of embedding to work. > > My code (which compiles with no warnings): > > #include > > using namespace boost::python; > > int main() > { > Py_Initialize(); > object main_module = import("__main__"); > object main_namespace = main_module.attr("__dict__"); > > exec("print('hello')\n", main_namespace); > exec("print('world')\n", main_namespace); > exec("f = file('hello.txt', 'w')\n", main_namespace); > > return 0; > } > > It prints "hello\nworld\n" then throws an exception executing the line > that creates the hello.txt file: > First-chance exception at 0x755ac41f in Test.exe: Microsoft C++ > exception: boost::python::error_already_set at memory location 0x0039fb60.. > Unhandled exception at 0x773915de (ntdll.dll) in Test.exe: Microsoft > C++ exception: boost::python::error_already_set at memory location > 0x0039fb60.. > > In the exec method, the exception is being thrown when result comes back > as null: > PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), > local.ptr()); > if (!result) throw_error_already_set(); > > I'm using VS2010SP1 on Windows7 which I believe is what Python 3.3 is > built with. I'm dynamically linking against boost. > > Any suggestions? > > ___ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] problem embedding python - very simple example
On 11/06/2012 02:40 PM, Cory Riddell wrote: > It prints "hello\nworld\n" then throws an exception executing the line > that creates the hello.txt file: > First-chance exception at 0x755ac41f in Test.exe: Microsoft C++ > exception: boost::python::error_already_set at memory location 0x0039fb60.. > Unhandled exception at 0x773915de (ntdll.dll) in Test.exe: Microsoft > C++ exception: boost::python::error_already_set at memory location > 0x0039fb60.. > > In the exec method, the exception is being thrown when result comes back > as null: > PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), > local.ptr()); > if (!result) throw_error_already_set(); I suggest you wrap your C++ code in a try block, then catch the error_already_set error and inspect the Python exception using PyErr_Print() or somesuch. Stefan -- ...ich hab' noch einen Koffer in Berlin... ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] export custom C++ exception to Python so it can beraisedby python
On 06/11/2012 15:35, Martin Hellmich wrote: I've based my code on. http://stackoverflow.com/questions/9620268/boost-python-custom-exception-class I have used the same reference and also this suggestion for including the other attributes shown here: http://stackoverflow.com/questions/11448735/boostpython-export-custom-exception-and-inherit-from-pythons-exception However, this doesn't solve my problem. It works fine when I throw the MyException in C++, but when I raise the MyCPPException in Python, the translator is not called (which makes sense), so the attribute 'cause' does not change. Actually, before I throw the MyException for the first time in C++, MyCPPException does not have the attribute 'cause' at all. Of course. This issue should be the same, if I set the exception with PyErr_SetObject, since the translator is not called, when I 'raise' it. Very likely the SetString uses SetObject under the hood, but I never used SetObject. I'd try to: *) As you were writing before, declare a C++ class MyException: public std::exception { MyException(); MyException(int code, const std::string &string); int code(); const char* what(); int errorCode; std::string errorMessage; }; *) Wrap it as a bpy::class_ so you can use it like a standard exception with all the attributes you need. *) Register an exception translator as defined before. Maybe the to-python conversion performed in the exception translator does work even if you have wrapped MyException as a standard class. -- Giuseppe Corbelli WASP Software Engineer, Copan Italia S.p.A Phone: +390303666318 Fax: +390302659932 E-mail: giuseppe.corbe...@copanitalia.com ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig