make bytes the common type of char* and bytes literal in comparisons (ticket #582)
authorStefan Behnel <scoder@users.berlios.de>
Sat, 30 Oct 2010 20:19:11 +0000 (22:19 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Sat, 30 Oct 2010 20:19:11 +0000 (22:19 +0200)
Cython/Compiler/ExprNodes.py
tests/run/charptr_comparison_T582.pyx

index 62de863ceb03ca53e5b45e8c69e71ccbd7118226..50ee5a74dc9c1bfb5dd15a6496d20f70bb37655a 100755 (executable)
@@ -6031,6 +6031,12 @@ class CmpNode(object):
                 self.invalid_types_error(operand1, op, operand2)
                 new_common_type = error_type
 
+        if new_common_type.is_string and (isinstance(operand1, BytesNode) or
+                                          isinstance(operand2, BytesNode)):
+            # special case when comparing char* to bytes literal: must
+            # compare string values!
+            new_common_type = bytes_type
+
         # recursively merge types
         if common_type is None or new_common_type.is_error:
             common_type = new_common_type
index c30a431c6945b706d9a5c5ec066a80484b63625a..aecb5b92b1ef6f6bf1f96cf0b3f31ebb4b5e5639 100644 (file)
@@ -1,6 +1,85 @@
 
 cimport cython
 
+################################################################################
+## plain char*
+
+@cython.test_assert_path_exists('//SingleAssignmentNode')
+#@cython.test_fail_if_path_exists('//SingleAssignmentNode//CoerceFromPyTypeNode')
+def charptr_equals_literal(char* s):
+    """
+    >>> charptr_equals_literal('abc'.encode('ASCII'))
+    True
+    >>> charptr_equals_literal('aabc'.encode('ASCII'))
+    False
+    >>> charptr_equals_literal('abcx'.encode('ASCII'))
+    False
+    >>> charptr_equals_literal('bcx'.encode('ASCII'))
+    False
+    """
+    cdef bint result = (s == b"abc")
+    return result
+
+def charptr_gt_literal(char* s):
+    """
+    >>> charptr_gt_literal('abc'.encode('ASCII'))
+    False
+    >>> charptr_gt_literal('aabc'.encode('ASCII'))
+    False
+    >>> charptr_gt_literal('abcx'.encode('ASCII'))
+    True
+    >>> charptr_gt_literal('bcx'.encode('ASCII'))
+    True
+    """
+    cdef bint result = (s > b"abc")
+    return result
+
+def charptr_lt_literal(char* s):
+    """
+    >>> charptr_lt_literal('abc'.encode('ASCII'))
+    False
+    >>> charptr_lt_literal('aabc'.encode('ASCII'))
+    True
+    >>> charptr_lt_literal('abcx'.encode('ASCII'))
+    False
+    >>> charptr_lt_literal('bcx'.encode('ASCII'))
+    False
+    """
+    cdef bint result = (s < b"abc")
+    return result
+
+def charptr_ge_literal(char* s):
+    """
+    >>> charptr_ge_literal('abc'.encode('ASCII'))
+    True
+    >>> charptr_ge_literal('aabc'.encode('ASCII'))
+    False
+    >>> charptr_ge_literal('abcx'.encode('ASCII'))
+    True
+    >>> charptr_ge_literal('bcx'.encode('ASCII'))
+    True
+    """
+    cdef bint result = (s >= b"abc")
+    return result
+
+def charptr_le_literal(char* s):
+    """
+    >>> charptr_le_literal('abc'.encode('ASCII'))
+    True
+    >>> charptr_le_literal('aabc'.encode('ASCII'))
+    True
+    >>> charptr_le_literal('abcx'.encode('ASCII'))
+    False
+    >>> charptr_le_literal('bcx'.encode('ASCII'))
+    False
+    """
+    cdef bint result = (s <= b"abc")
+    return result
+
+
+################################################################################
+## slices
+
 @cython.test_assert_path_exists('//SingleAssignmentNode')
 #FIXME: optimise me!
 #@cython.test_fail_if_path_exists('//SingleAssignmentNode//CoerceFromPyTypeNode')