diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index c96f479a055875ff114bef66bce4753e989f0031..bb42a235b68737a8c644ce51dabf9f345502ccca 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -276,7 +276,10 @@ builtin_types_table = [ BuiltinAttribute('imag', 'cval.imag', field_type = PyrexTypes.c_double_type), ]), - ("basestring", "PyBaseString_Type", []), + ("basestring", "PyBaseString_Type", [ + BuiltinMethod("join", "TO", "T", "__Pyx_PyBaseString_Join", + utility_code=UtilityCode.load("StringJoin", "StringTools.c")), + ]), ("bytearray", "PyByteArray_Type", []), ("bytes", "PyBytes_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), BuiltinMethod("join", "TO", "O", "__Pyx_PyBytes_Join", diff --git a/Cython/Utility/StringTools.c b/Cython/Utility/StringTools.c index 88f59963a1353ece301a2855dc9f978716c14eaa..67b36d37dd5f30f8ea8d3797a7cc9f919e995182 100644 --- a/Cython/Utility/StringTools.c +++ b/Cython/Utility/StringTools.c @@ -654,8 +654,10 @@ static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* bytes, Py_ssize_t i #if PY_MAJOR_VERSION < 3 #define __Pyx_PyString_Join __Pyx_PyBytes_Join +#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v)) #else #define __Pyx_PyString_Join PyUnicode_Join +#define __Pyx_PyBaseString_Join PyUnicode_Join #endif #if CYTHON_COMPILING_IN_CPYTHON diff --git a/tests/run/builtin_basestring.pyx b/tests/run/builtin_basestring.pyx index d1e0e1c56acfd60ea829196ff137a811ed14f426..ceaa3212d4940247cd1cc68fd1eb45b5f576df94 100644 --- a/tests/run/builtin_basestring.pyx +++ b/tests/run/builtin_basestring.pyx @@ -1,4 +1,6 @@ +cimport cython + import sys IS_PY3 = sys.version_info[0] >= 3 @@ -84,3 +86,23 @@ def basestring_typed_argument(basestring obj): TypeError: ...got S... """ return obj + + +@cython.test_assert_path_exists( + "//SimpleCallNode", + "//SimpleCallNode//NoneCheckNode", + "//SimpleCallNode//AttributeNode[@is_py_attr = false]") +def basestring_join(basestring s, *values): + """ + >>> print(basestring_join(ustring, 'a', 'b', 'c')) + aabcdefbabcdefc + >>> print(basestring_join(sstring, 'a', 'b', 'c')) + aabcdefbabcdefc + >>> if IS_PY3: print('abcdefabcdefabcdef') + ... else: print(basestring_join(bstring, bstring, bstring).decode('utf8')) + abcdefabcdefabcdef + >>> basestring_join(None, 'a', 'b', 'c') + Traceback (most recent call last): + AttributeError: 'NoneType' object has no attribute 'join' + """ + return s.join(values)