I am implemeting a function in Cython that requires, at some point to remove some char
from a C++ std::string
. For this, I would use std::string::erase()
. However, when I try to use it, Cython forces the object to be bytes()
instead of std::string()
, at which point it cannot find .erase()
.
To illustrate the issue, here is a minimal example (using IPython + Cython magic):
%load_ext Cython
%%cython --cplus -c-O3 -c-march=native -a
from libcpp.string cimport string
cdef string my_func(string s):
cdef char c = b'\0'
cdef size_t s_size = s.length()
cdef size_t i = 0
while i + 1 <= s_size:
if s[i] == c:
s.erase(i, 1)
i += 1
return s
def cy_func(string b):
return my_func(b)
This compiles, but it indicates Python interaction on the .remove()
line, and when I try to use it, e.g.
b = b'ciao\0pippo\0'
print(b)
cy_func(b)
I get:
AttributeError Traceback (most recent call last) AttributeError: 'bytes' object has no attribute 'erase'
Exception ignored in: '_cython_magic_5beaeb4004c3afc6d85b9b158c654cb6.my_func' AttributeError: 'bytes' object has no attribute 'erase'
How could I solve this?
Notes
- If I replace the
s.erase(i, 1)
with says[i] == 10
, I getmy_func()
with no Python interaction (can even use thenogil
directive). - I know I could this in Python with
.replace(b'\0', b'')
, but it is part of a longer algorithm I hope to optimize with Cython.