1
2cimport cython
3
4import sys
5IS_PY3 = sys.version_info[0] >= 3
6
7ustring = u'abcdef'
8sstring =  'abcdef'
9bstring = b'abcdef'
10
11
12def isinstance_basestring(obj):
13    """
14    >>> isinstance_basestring(ustring)
15    True
16    >>> isinstance_basestring(sstring)
17    True
18    >>> if IS_PY3: print(not isinstance_basestring(bstring))
19    ... else: print(isinstance_basestring(bstring))
20    True
21    """
22    return isinstance(obj, basestring)
23
24
25def basestring_is_unicode_in_py3():
26    """
27    >>> basestring_is_unicode_in_py3()
28    True
29    """
30    if IS_PY3:
31        return basestring is unicode
32    else:
33        return basestring is not unicode
34
35
36def unicode_subtypes_basestring():
37    """
38    >>> unicode_subtypes_basestring()
39    True
40    """
41    return issubclass(unicode, basestring)
42
43
44def basestring_typed_variable(obj):
45    """
46    >>> basestring_typed_variable(None) is None
47    True
48    >>> basestring_typed_variable(ustring) is ustring
49    True
50    >>> basestring_typed_variable(sstring) is sstring
51    True
52    >>> if IS_PY3: print(True)
53    ... else: print(basestring_typed_variable(bstring) is bstring)
54    True
55    >>> class S(str): pass
56    >>> basestring_typed_variable(S())   # doctest: +ELLIPSIS
57    Traceback (most recent call last):
58    TypeError: ...got S...
59    """
60    cdef basestring s
61    s = u'abc'
62    assert s
63    s = 'abc'
64    assert s
65    # make sure coercion also works in conditional expressions
66    s = u'abc' if obj else 'abc'
67    assert s
68    s = obj
69    return s
70
71
72def basestring_typed_argument(basestring obj):
73    """
74    >>> basestring_typed_argument(None) is None
75    True
76    >>> basestring_typed_argument(ustring) is ustring
77    True
78    >>> basestring_typed_argument(sstring) is sstring
79    True
80    >>> if IS_PY3: print(True)
81    ... else: print(basestring_typed_argument(bstring) is bstring)
82    True
83    >>> class S(str): pass
84    >>> basestring_typed_argument(S())   # doctest: +ELLIPSIS
85    Traceback (most recent call last):
86    TypeError: ...got S...
87    """
88    return obj
89
90
91@cython.test_assert_path_exists(
92    "//SimpleCallNode",
93    "//SimpleCallNode//NoneCheckNode",
94    "//SimpleCallNode//AttributeNode[@is_py_attr = false]")
95def basestring_join(basestring s, *values):
96    """
97    >>> print(basestring_join(ustring, 'a', 'b', 'c'))
98    aabcdefbabcdefc
99    >>> print(basestring_join(sstring, 'a', 'b', 'c'))
100    aabcdefbabcdefc
101    >>> if IS_PY3: print('abcdefabcdefabcdef')
102    ... else: print(basestring_join(bstring, bstring, bstring).decode('utf8'))
103    abcdefabcdefabcdef
104    >>> basestring_join(None, 'a', 'b', 'c')
105    Traceback (most recent call last):
106    AttributeError: 'NoneType' object has no attribute 'join'
107    """
108    return s.join(values)
109