safety fix
authorStefan Behnel <scoder@users.berlios.de>
Thu, 25 Feb 2010 12:08:20 +0000 (13:08 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Thu, 25 Feb 2010 12:08:20 +0000 (13:08 +0100)
Cython/Compiler/Optimize.py
tests/run/charptr_len.pyx

index c3730cbe65ee6d31f4ba8200c7be029399eed7b4..45642a57e554948827c1d477435c21c28d4d07d1 100644 (file)
@@ -1205,10 +1205,6 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
             ])
 
     def _handle_simple_function_len(self, node, pos_args):
-        # note: this only works because we already replaced len() by
-        # PyObject_Length() which returns a Py_ssize_t instead of a
-        # Python object, so we can return a plain size_t instead
-        # without caring about Python object conversion etc.
         if len(pos_args) != 1:
             self._error_wrong_arg_count('len', node, pos_args, 1)
             return node
@@ -1217,6 +1213,13 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
             arg = arg.arg
         if not arg.type.is_string:
             return node
+        if not node.type.is_numeric:
+            # this optimisation only works when we already replaced
+            # len() by PyObject_Length() which returns a Py_ssize_t
+            # instead of a Python object, so we can return a plain
+            # size_t instead without caring about Python object
+            # conversion etc.
+            return node
         node = ExprNodes.PythonCapiCallNode(
             node.pos, "strlen", self.Pyx_strlen_func_type,
             args = [arg],
index 84c94008463b37ae1f9eb1409405dc8eeb8d5911..f1372ec0657721ba726397eb9ac3f4def7346101 100644 (file)
@@ -3,6 +3,10 @@ __doc__ = """
 7
 >>> lentest_char_c()
 7
+>>> lentest_char_c_short()
+7
+>>> lentest_char_c_float()
+7.0
 
 >>> lentest_uchar()
 7
@@ -36,6 +40,20 @@ def lentest_char_c():
     cdef Py_ssize_t l = len(s)
     return l
 
+@cython.test_assert_path_exists(
+    "//PythonCapiCallNode",
+    )
+def lentest_char_c_short():
+    cdef short l = len(s)
+    return l
+
+@cython.test_assert_path_exists(
+    "//PythonCapiCallNode",
+    )
+def lentest_char_c_float():
+    cdef float l = len(s)
+    return l
+
 
 @cython.test_assert_path_exists(
     "//PythonCapiCallNode",