optimise 'x in unicode' a bit
authorStefan Behnel <stefan_ml@behnel.de>
Fri, 22 Feb 2013 00:11:27 +0000 (01:11 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Fri, 22 Feb 2013 00:11:27 +0000 (01:11 +0100)
Cython/Compiler/ExprNodes.py
Cython/Utility/StringTools.c
tests/run/unicodemethods.pyx

index 7ef8faa..f984904 100755 (executable)
@@ -9155,6 +9155,11 @@ class CmpNode(object):
                 self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyDictContains", "ObjectHandling.c")
                 self.special_bool_cmp_function = "__Pyx_PyDict_Contains"
                 return True
+            elif self.operand2.type is Builtin.unicode_type:
+                self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
+                self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyUnicodeContains", "StringTools.c")
+                self.special_bool_cmp_function = "__Pyx_PyUnicode_Contains"
+                return True
             else:
                 if not self.operand2.type.is_pyobject:
                     self.operand2 = self.operand2.coerce_to_pyobject(env)
index 6466d16..546cf26 100644 (file)
@@ -109,6 +109,14 @@ static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, P
 }
 
 
+//////////////////// PyUnicodeContains.proto ////////////////////
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Contains(PyObject* substring, PyObject* text, int eq) {
+    int result = PyUnicode_Contains(text, substring);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+
 //////////////////// StrEquals.proto ////////////////////
 //@requires: BytesEquals
 //@requires: UnicodeEquals
index 8e4595d..72606e7 100644 (file)
@@ -364,6 +364,25 @@ def endswith_start_end(unicode s, sub, start, end):
         return 'NO MATCH'
 
 
+# unicode.__contains__(s, sub)
+
+@cython.test_fail_if_path_exists(
+    "//CoerceFromPyTypeNode", "//AttributeNode")
+@cython.test_assert_path_exists(
+    "//CoerceToPyTypeNode", "//PrimaryCmpNode")
+def in_test(unicode s, substring):
+    """
+    >>> in_test(text, 'sa')
+    True
+    >>> in_test(text, 'XYZ')
+    False
+    >>> in_test(None, 'sa')
+    Traceback (most recent call last):
+    TypeError: 'NoneType' object is not iterable
+    """
+    return substring in s
+
+
 # unicode.find(s, sub, [start, [end]])
 
 @cython.test_fail_if_path_exists(