specifying libcpp.string type for __contains__ in cython
<p>I'm implementing a cython wrapper for some C++ data structure which will have c++ strings as both keys and values.</p>

<p>I have the C++ methods prototyped in a pxd, for a class with templated key/value types (sorry, I've never worked with C++, only C, so I'm not sure of the right terminology, let me know if this is unclear)</p>

<p>I am then defining a class in a .pyx file for the ability to call from python, which wraps an instance of <code>my_type[string, string]</code>:</p>

<pre><code>from libcpp.string cimport string
cdef class MyType:
    ## This field is declared in .pxd:
    # cdef my_type[string, string]* thisptr

    def __cinit__(self, f=None):
        self.thisptr = new my_type[string, string]()

    def __init__(self, arg=None):
        if hasattr(arg, 'fileno'):
            self.load(arg)
        elif isinstance(arg, int):
            self.thisptr.resize(arg)
        elif isinstance(arg, str):
            with open(arg, 'rb') as f:
                self.load(f)
        elif arg is not None:
            raise ValueError("Cannot interpret argument of type %s" % type(arg))        

    def __contains__(self, string item):
        return self.thisptr.count(item) &gt; 0
</code></pre>

<p>now, I have another .pyx script in which I am testing this functionality, in which I define a python string, assign the bytes to a C++ string, and attempt to use the <code>in</code> operator:</p>

<pre><code>from libcpp.string cimport string

def test():
    m = MyType()
    bytes_key = 'asdf'
    bytes_val = 'jkl;'
    cdef string key = bytes_key
    cdef string val = bytes_val
    m[key] = val
    print('len(): %d' % len(m))
    assert len(m) == 1, len(m)
    print('__repr__(): %r' % (m, ))
    assert key in m
</code></pre>

<p>if I comment out the last line, everything compiles and I get output</p>

<pre><code>len(): 0
len(): 1
__repr__(): {'asdf': 'jkl;'}
</code></pre>

<p>however, with the <code>assert</code> statement included, I get the following error during compilation:</p>

<pre><code>Error compiling Cython file:
------------------------------------------------------------
...
    cdef string val = bytes_val
    m[key] = val
    print('len(): %d' % len(m))
    assert len(m) == 1, len(m)
    print('__repr__(): %r' % (m, ))
    assert key in m
              ^
------------------------------------------------------------

test_internal.pyx:72:15: Invalid types for 'in' (string, MyType)
</code></pre>

<p>If I replace <code>libcpp.string.string</code> with, for example, <code>libc.stdint.uint16_t</code>, everything works fine. Looking for how to fix this. Thank you!</p>

<p>EDIT
To further the mystery, if I change the offending line to <code>assert m.__contains__(key)</code>, it compiles and runs fine.</p>

<p>However, if I then go to another directory, and cimport MyType, and try <code>if not my_obj.__contains__(key)</code> (where <code>key</code> is <code>cdef</code>'d to be a <code>string</code>), I get a runtime error, <code>TypeError: an integer is required</code>...</p>