Pure way to convert Python 3 Unicode to std :: string

I am porting a lot of C ++ using the Python 2 API (I cannot use things like swig or boost.python for various technical reasons). When I need to pass a string (usually a path, always ASCII) to C / C ++, I use something like this:

std::string file_name = PyString_AsString(py_file_name); if (PyErr_Occurred()) return NULL; 

Now I'm considering upgrading to Python 3, where the PyString_* methods PyString_* not exist. I found one solution that says I should do something like this:

 PyObject* bytes = PyUnicode_AsUTF8String(py_file_name); std::string file_name = PyBytes_AsString(bytes); if (PyErr_Occurred()) return NULL; Py_DECREF(bytes); 

However, this is twice as many lines and seems a little ugly (not to mention that it could introduce a memory leak if I forget the last line).

Another option is to override python functions to work with bytes objects and call them as follows

 def some_function(path_name): _some_function(path_name.encode('utf8')) 

It's not scary, but for every function a shell is required on the python side.

Is there a cleaner way to handle this?

+6
source share
2 answers

It seems like a solution exists in python 3.3, char* PyUnicode_AsUTF8(PyObject* unicode) . This should be exactly the same behavior as the PyString_AsString() function from python 2.

+2
source

If you know (and, of course, you can verify with a statement or similar) that all this is ASCII, then you can simply create it as follows:

 std::string py_string_to_std_string(PyUnicode_string py_file_name) { len = length of py_file_name; // Not sure how you write that in python. std::string str(len); for(int i = 0; i < len; i++) str += py_file_name[i]; return str; } 
+1
source

Source: https://habr.com/ru/post/948902/


All Articles