From: Stefan Behnel Date: Thu, 22 Oct 2009 09:24:48 +0000 (+0200) Subject: fix intern() optimisation X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=b67f30bed05e8e8abe91462a9260f2520793d436;p=cython.git fix intern() optimisation --- diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index 69f160a1..494057bd 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -28,7 +28,7 @@ builtin_function_table = [ #('hex', "", "", ""), #('id', "", "", ""), #('input', "", "", ""), - #('intern', "s", "O", "__Pyx_InternFromString"), # Doesn't work for Python str objects with null characters. + ('intern', "O", "O", "__Pyx_Intern"), ('isinstance', "OO", "b", "PyObject_IsInstance"), ('issubclass', "OO", "b", "PyObject_IsSubclass"), ('iter', "O", "O", "PyObject_GetIter"), @@ -237,12 +237,23 @@ bad: intern_utility_code = UtilityCode( proto = """ -#if PY_MAJOR_VERSION >= 3 -# define __Pyx_InternFromString(s) PyUnicode_InternFromString(s) -#else -# define __Pyx_InternFromString(s) PyString_InternFromString(s) -#endif -""") +static PyObject* __Pyx_Intern(PyObject* s); /* proto */ +""", +impl = ''' +static PyObject* __Pyx_Intern(PyObject* s) { + if (!(likely(PyString_CheckExact(s)))) { + PyErr_Format(PyExc_TypeError, "Expected str, got %s", Py_TYPE(s)->tp_name); + return 0; + } + Py_INCREF(s); + #if PY_MAJOR_VERSION >= 3 + PyUnicode_InternInPlace(&s); + #else + PyString_InternInPlace(&s); + #endif + return s; +} +''') def put_py23_set_init_utility_code(code, pos): code.putln("#if PY_VERSION_HEX < 0x02040000") diff --git a/tests/run/intern_T431.pyx b/tests/run/intern_T431.pyx new file mode 100644 index 00000000..dfdff19d --- /dev/null +++ b/tests/run/intern_T431.pyx @@ -0,0 +1,16 @@ +__doc__ = u""" +>>> s == s_interned +True +>>> intern(s) is s_interned +True +>>> intern('abc') is s_interned +True +>>> intern('abc') is s_interned_dynamic +True +""" + +s = 'abc' + +s_interned = intern(s) + +s_interned_dynamic = intern('a'+'b'+'c')