Exceptions between C++ and Python

Exceptions between C++ and Python

In this post, the tale of the friendship between C++ and Python will be the surprisingly little use of Boost Python. Exceptions to transfer back and forth is indeed the weak point of this library. Let’s go native Python API, and wherever possible use the Boost Python.

Boost nonetheless. Python creates an environment in which C++ exceptions fall into Python as a standard, and Runtime Error back from Python to C++ exception is thrown type error_already_set, which means “something you flew, go Sam read what is there. And here we will just do not use C-Python API, to deduct the necessary information about the exception and convert it into the appropriate class for logic applications.

What such complexity? -The fact of the matter is that in Python, unlike C++, in addition to the text of the exception and its type also comes a traceback — stack up to the location of the exception. Let’s extend the standard std: exception additional parameter for this report, as well as write exception converter back and forth from C++ classes in Python exception classes.

In the previous series

Boost Python. Introduction. C++ wrapper in Python.

Boost Python. Wrapper particular C++ classes.

Boost Python. Create type converters between C++ and Python.

Introduction

Suppose there is a particular hierarchy of exceptions, which you need to submit it unambiguously as the corresponding class in the C++ and Python when handling an exception. It’s especially true if you combine application logic in C++ and complex scripting in Python binding, or if you write a module for Python in C++ with complex logic. Sooner or later we set against the processing of exceptions coming from C++ to Python or vice versa.

Of course, in most cases, you will only need a standard mechanism to Boost. Python conversion exceptions from C++ to Python as a RuntimeException with text came from exception: what (). C++ side needs to catch an exception of type error_already_set and use the native Python API, but you can deduct only the type and not the exception text but is in fact history exception traceback.But everything in order.

The journey of a small exception from C++ to Python

So you’ve written a module in C++ using Boost. Python hooked it in Python code through regular import and used one of these wrappers functions or methods. Valid in C++ code throws an exception through the most usual equally reasonable throw. In Python code, you will receive a RuntimeException with text derived from exception: what if this exception originated from STD:: exception.If you are satisfied with what you except the exception text will get nothing, you can even do nothing more. If, however, you will need to catch an exception class defined errors strictly, it will need a little work.

Boost.Python provides the ability to register their broadcast exceptions leaving native penates module written in C++.All you need to do: call the module declaration in a function template function boost:p python: register_exception_translator<T, F>(F), where T is the type of C++ exceptions. F is a function that takes a reference to an exception of this kind andsomehow performing its duty to transfer the desired type of derogations from the external code is in Python. In general terms, like so:

Here, we used a standard exception type Exception built into Python, but you can use absolutely any exception: standard external connected via import obtaining PyObject * through an object:: p, tr () or even your own created right here on the spot, via PyErr_NewException.

Let’s add a couple of completeness of sensations classes which will be given to both analog and ValueError ZeroDivisionError and full of happiness will inherit them from our error, we’ll call them accordingly and zero_division_error value_error:

Script output:

ZeroDivisionError Is OK

ValueError Is OK

Exception — OK

The adventures of our exclusion from Python to C++

Let’s select in a separate project exception types and test functions and will collect from them a distinct dynamic-link library error_types. Python module will receive separately in draft python_module.And now let’s C++ application where we will catch exceptions from Python, let’s call it catch_exceptions.All you need is to connect our module via import (“python_module»), then get access to module functions through the attr (” divide “) attr (” to_num “), attr (” test “). We will call them; they will generate C++ code level exclusions, will be held in the Python interpreter further into the C++ application by calling exception error_already_set Boost library exception.Python-penned just for such cases.

Itself an object of type error_already_set, it is important just to catch an exception. In General, the handling of such an exception is as follows:

So we get an exception always of the same type, but at least we will be able to retrieve the text of the exception.</string> But we come to the exception type in the variable etc., himself an exception object in the variable var and even object with a stack exception that occurred in a variable too. Let’s convert the exception that took place in the zero_division_error and value_error if it’s ZeroDivisionError or ValueError respectively.

Stop! Not everything is clear to everyone that these two functions, why all the PyObject * where exceptions in C-API if they don’t exist in c, let us read more.Yes, in pure Si no exceptions, but they are in Python, and its API provides the ability to pull information about the exception. Python, C API all values and types, generally almost everything is represented as PyObject *, so the exception E-type T is a pair of type PyObject *, add to this another PyObject * for traceback — saved stack where the exception occurred.Pull information about the exception can be a function PyErr_Fetch, then information about the exception you can normalize (if you do not want to work in the internal representation in the tuple form) PyErr_NormalizeException function.After calling couples these features we fill three values of type PyObject * respectively: exception class instance (object) of the exception and stack (traceback) saved at the moment of throwing an exception.

Further, where it is more convenient to work with Boost Python wrap PyObject * boost:: p then: handle, compatible < > with any object libraries Boost Python, we just need a boost:: p then: str. After conversion to analog lines of Python in Boost. Python we can pull the standard native string to STDs:: string C++ language. If you prefer, you can pick and the usual cast chair *.

With the first two parameters, everything is clear, they converted to a string, but still have to convert to traceback. The easiest way to do this using a traceback, passing our three format_exception parameters to a function. Trackback function. format_exception (ex, Val, TB) return to us an array of strings in the form of a standard list of Python, which remarkably will be in one big thick line.On the side of C++, using the Boost. Python, it will look like this:

You can make a helper function to generate rows from exception.</string> The problem, however, is that calling import () to work each time will lead to a high call, so the object derived from import (“trackback”).Attr (“format_exception) best save the result of the function in a separate object, also we need to store the result of the import (” python_module “). Given that it takes to make somewhere between Py_Initialize () and Py_Finalize (), there is nothing better to hold such a singleton field variable in the head does come.

Working with Python APIs via singleton

So let’s Let’s Singleton, it would complicate the application, but few will simplify the code and will initialize correctly work with the interpreter, keep all supporting objects and complete everything properly:

The constructor will initialize the work with the interpreter and the destructor roughen up the saved fields and de-initialize interpreter work methods and import format_error python_module COOtvetstvujushhie modules only once:

Epilogue

Total: we got the mechanism map conversion exceptions from Python to C++ and vice versa.

Minus is evident immediately is a different entirely unconnected entity. It’s because a c++ class cannot inherit from a class of Python, as well as vice versa. There is an option with “encapsulation” the right exception class in the C++ class wrapper for Python, but it’s still different levels that directly converted to everyone in their language.

If you have a complex hierarchy of exceptions in C++, the easiest way to make equivalent in Python in a separate.Py module, because create through PyErr_NewException and then stored somewhere quite costly and will not add the readability of code.

I don’t know about you, but I’m looking forward to when the Boost. Python has a decent translator exceptions, or at least analogous to increase: p then: bases for deriving a class from the Python wrapper. In General a Boost.

Python is an excellent library, but this aspect adds hemorrhoid parsing exceptions from Python to C++ side. Broadcast in Python via registration functions-register_exception_translator translator<E, F>(F) looks quite good and allows you to convert A type in C++ exception, in an entirely different class B on the side of the Python, but at least automatically.

The principle does not necessarily respond to error_already_set exactly as described above, can choose a recipe behavior of your application using the Python API for Python exception handling.

The Founder of Smart Spate. His role involves creating work to the highest standards, supporting other members of the team, and researching techniques and systems to keep SmartSpate at the forefront of digital. We spend a lot of time to making sure that the topics quality was high and with a most informative approach.
He has an unhealthy love of IT and Online Marketing and enjoys exploring the ever-changing world of online advertising.

Find Us At:

error: This Content is Protected! All Rights belong to Smart Spate Ltd.

This website uses cookies. By continuing to use this website you are giving consent to cookies being used. For information on a cookie and how it impacts on users, you can visit our Privacy Policy and Cookie Policy.AcceptCloseRead more