init_builtin_funcs()
init_builtin_types()
init_builtin_structs()
- global list_type, tuple_type, dict_type, set_type, type_type
- global bytes_type, str_type, unicode_type, float_type, bool_type
+ global list_type, tuple_type, dict_type, set_type, frozenset_type
+ global bytes_type, str_type, unicode_type
+ global float_type, bool_type, type_type
type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type
set_type = builtin_scope.lookup('set').type
+ frozenset_type = builtin_scope.lookup('frozenset').type
bytes_type = builtin_scope.lookup('bytes').type
str_type = builtin_scope.lookup('str').type
unicode_type = builtin_scope.lookup('unicode').type
PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_char_ptr_type, None)
])
+ PyObject_Size_func_type = PyrexTypes.CFuncType(
+ PyrexTypes.c_py_ssize_t_type, [
+ PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None)
+ ])
+
+ _map_to_capi_len_function = {
+ Builtin.unicode_type : "PyUnicode_GET_SIZE",
+ Builtin.str_type : "Py_SIZE",
+ Builtin.bytes_type : "__Pyx_PyBytes_GET_SIZE",
+ Builtin.list_type : "PyList_GET_SIZE",
+ Builtin.tuple_type : "PyTuple_GET_SIZE",
+ Builtin.dict_type : "PyDict_Size",
+ Builtin.set_type : "PySet_Size",
+ Builtin.frozenset_type : "PySet_Size",
+ }.get
+
def _handle_simple_function_len(self, node, pos_args):
"""Replace len(char*) by the equivalent call to strlen().
"""
arg = pos_args[0]
if isinstance(arg, ExprNodes.CoerceToPyTypeNode):
arg = arg.arg
- if not arg.type.is_string:
+ if arg.type.is_string:
+ new_node = ExprNodes.PythonCapiCallNode(
+ node.pos, "strlen", self.Pyx_strlen_func_type,
+ args = [arg],
+ is_temp = node.is_temp,
+ utility_code = include_string_h_utility_code)
+ elif arg.type.is_pyobject:
+ if isinstance(arg, ExprNodes.NoneNode):
+ error(node.pos, "object of type 'NoneType' has no len()")
+ return node
+ cfunc_name = self._map_to_capi_len_function(arg.type)
+ if cfunc_name is None:
+ return node
+ if not arg.is_literal:
+ arg = ExprNodes.NoneCheckNode(
+ arg, "PyExc_TypeError",
+ "object of type 'NoneType' has no len()")
+ new_node = ExprNodes.PythonCapiCallNode(
+ node.pos, cfunc_name, self.PyObject_Size_func_type,
+ args = [arg],
+ is_temp = node.is_temp)
+ else:
return node
- new_node = ExprNodes.PythonCapiCallNode(
- node.pos, "strlen", self.Pyx_strlen_func_type,
- args = [arg],
- is_temp = node.is_temp,
- utility_code = include_string_h_utility_code
- )
if node.type not in (PyrexTypes.c_size_t_type, PyrexTypes.c_py_ssize_t_type):
new_node = new_node.coerce_to(node.type, self.env_stack[-1])
return new_node
#define __Pyx_PyBytes_FromString PyString_FromString
#define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize
#define __Pyx_PyBytes_AsString PyString_AsString
+#define __Pyx_PyBytes_GET_SIZE PyString_GET_SIZE
#else
#define __Pyx_PyBytes_FromString PyBytes_FromString
#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
#define __Pyx_PyBytes_AsString PyBytes_AsString
+#define __Pyx_PyBytes_GET_SIZE PyBytes_GET_SIZE
#endif
#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((char*)s)