In [1]:
%load_ext cython

Auto-conversion of strings


In [2]:
%%cython
# cython: language_level=3

def f(char* text):
    print(text)

In [3]:
f('It is I, Arthur, son of Uther Pendragon')


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-643a100ec88f> in <module>()
----> 1 f('It is I, Arthur, son of Uther Pendragon')

_cython_magic_5df60722ac0c014e3de5966c7d110f5d.pyx in _cython_magic_5df60722ac0c014e3de5966c7d110f5d.f (/Users/siuser/.ipython/cython/_cython_magic_5df60722ac0c014e3de5966c7d110f5d.c:806)()

TypeError: expected bytes, str found

Must use bytes!


In [4]:
f(b'It is I, Arthur, son of Uther Pendragon')


b'It is I, Arthur, son of Uther Pendragon'

Passing Python strings in


In [9]:
%%cython
# cython: language_level=3

def g(str text):
    print(text)

In [10]:
g('It is I, Arthur, son of Uther Pendragon')


It is I, Arthur, son of Uther Pendragon

Passing Python strings, working with C strings

Assigning Python unicode string to a C string


In [11]:
%%cython

def f(str text):
    cdef char *s
    s = text
    print(s)
    
f('What? A swallow carrying a coconut?')


Error compiling Cython file:
------------------------------------------------------------
...

def f(str text):
    cdef char *s
    s = text
           ^
------------------------------------------------------------

/Users/siuser/.ipython/cython/_cython_magic_e32ae8706e38c4844fed7603e03bb50e.pyx:4:12: Unicode objects only support coercion to Py_UNICODE*.

Even assign after encode fails...


In [12]:
%%cython

def f(str text):
    cdef char *s
    s = text.encode('utf-8')
    print(s)
    
f('A five ounce bird could not carry a 1 pound coconut.')


Error compiling Cython file:
------------------------------------------------------------
...

def f(str text):
    cdef char *s
    s = text.encode('utf-8')
                  ^
------------------------------------------------------------

/Users/siuser/.ipython/cython/_cython_magic_45a0cff11ee3f0a86a00924d0a9e28fc.pyx:4:19: Storing unsafe C derivative of temporary Python reference

You must have a Python unicode string variable


In [13]:
%%cython

def f(str text):
    cdef char *s
    bstr = text.encode('utf-8')
    s = bstr
    print(s)
    
f('It could be carried by an African swallow!')


b'It could be carried by an African swallow!'

Just use Python strings


In [14]:
%%cython
from libc.string cimport strcat

def f1(a, b):
    """ A lot of effort to use strcat """
    cdef:
        char* ca  # Declare C strings
        char* cb
    pa = a.encode('utf-8')  # Make a bytes object
    pb = b.encode('utf-8')
    ca = pa  # Assign bytes to the C strings
    cb = pb
    strcat(ca, cb)  # Call the API method
    pout = ca.decode('utf-8')
    return pout

def f2(a, b):
    """ Python: much easier """
    return a + b

In [15]:
%timeit -n 1000 f1('first part', 'second part')
%timeit -n 1000 f2('first part', 'second part')


1000 loops, best of 3: 472 ns per loop
1000 loops, best of 3: 135 ns per loop

In [ ]: