1# mode: run
2# tag: special_method
3
4cimport cython
5
6text = u'ab jd  sdflk as sa  sadas asdas fsdf '
7
8
9@cython.test_fail_if_path_exists(
10    "//CoerceFromPyTypeNode")
11@cython.test_assert_path_exists(
12    "//CoerceToPyTypeNode",
13    "//AttributeNode",
14    "//AttributeNode[@entry.cname = 'PyUnicode_Contains']")
15def unicode_contains(unicode s, substring):
16    """
17    >>> unicode_contains(text, 'fl')
18    True
19    >>> unicode_contains(text, 'XYZ')
20    False
21    >>> unicode_contains(None, 'XYZ')
22    Traceback (most recent call last):
23    AttributeError: 'NoneType' object has no attribute '__contains__'
24    """
25    return s.__contains__(substring)
26
27
28@cython.test_fail_if_path_exists(
29    "//CoerceFromPyTypeNode")
30@cython.test_assert_path_exists(
31#    "//CoerceToPyTypeNode",
32    "//NameNode[@entry.cname = 'PyUnicode_Contains']")
33def unicode_contains_unbound(unicode s, substring):
34    """
35    >>> unicode_contains_unbound(text, 'fl')
36    True
37    >>> unicode_contains_unbound(text, 'XYZ')
38    False
39    >>> unicode_contains_unbound(None, 'XYZ')   # doctest: +ELLIPSIS
40    Traceback (most recent call last):
41    TypeError: descriptor '__contains__' requires a '...' object but received a 'NoneType'
42    """
43    return unicode.__contains__(s, substring)
44
45
46cdef class UnicodeSubclass(unicode):
47    """
48    >>> u = UnicodeSubclass(text)
49    >>> 'fl' in u
50    False
51    >>> 'XYZ' in u
52    True
53    >>> u.method('fl')
54    False
55    >>> u.method('XYZ')
56    True
57    >>> u.operator('fl')
58    False
59    >>> u.operator('XYZ')
60    True
61    """
62    def __contains__(self, substring):
63        return substring not in (self + u'x')
64
65    def method(self, other):
66        return self.__contains__(other)
67
68    def operator(self, other):
69        return other in self
70