Commit 140a9be0 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents 609ed2ca 9d5aaeab
......@@ -1996,6 +1996,15 @@ class IndexNode(ExprNode):
elif not skip_child_analysis:
self.index.analyse_types(env)
self.original_index_type = self.index.type
if base_type is PyrexTypes.c_py_unicode_type:
# we infer Py_UNICODE for unicode strings in some
# cases, but indexing must still work for them
if self.index.constant_result in (0, -1):
# FIXME: we know that this node is redundant -
# currently, this needs to get handled in Optimize.py
pass
self.base = self.base.coerce_to_pyobject(env)
base_type = self.base.type
if base_type.is_pyobject:
if self.index.type.is_int:
if (not setting
......
......@@ -1616,7 +1616,6 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
_map_to_capi_len_function = {
Builtin.unicode_type : "PyUnicode_GET_SIZE",
Builtin.str_type : "Py_SIZE", # works in Py2 and Py3
Builtin.bytes_type : "PyBytes_GET_SIZE",
Builtin.list_type : "PyList_GET_SIZE",
Builtin.tuple_type : "PyTuple_GET_SIZE",
......@@ -1645,13 +1644,15 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
cfunc_name = self._map_to_capi_len_function(arg.type)
if cfunc_name is None:
return node
if not arg.is_literal:
arg = arg.as_none_safe_node(
"object of type 'NoneType' has no len()")
arg = arg.as_none_safe_node(
"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)
elif arg.type is PyrexTypes.c_py_unicode_type:
return ExprNodes.IntNode(node.pos, value='1', constant_result=1,
type=node.type)
else:
return node
if node.type not in (PyrexTypes.c_size_t_type, PyrexTypes.c_py_ssize_t_type):
......
......@@ -38,9 +38,9 @@ def len_bytes(bytes s):
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
#@cython.test_assert_path_exists(
# "//CoerceToPyTypeNode",
# "//PythonCapiCallNode")
def len_str(str s):
"""
>>> len('abcdefg')
......
......@@ -119,3 +119,46 @@ def unicode_methods(Py_UNICODE uchar):
uchar.upper(),
uchar.title(),
]
@cython.test_assert_path_exists('//IntNode')
@cython.test_fail_if_path_exists('//SimpleCallNode',
'//PythonCapiCallNode')
def len_uchar(Py_UNICODE uchar):
"""
>>> len_uchar(ord('A'))
1
"""
return len(uchar)
def index_uchar(Py_UNICODE uchar, Py_ssize_t i):
"""
>>> index_uchar(ord('A'), 0) == ('A', 'A', 'A')
True
>>> index_uchar(ord('A'), -1) == ('A', 'A', 'A')
True
>>> index_uchar(ord('A'), 1)
Traceback (most recent call last):
IndexError: string index out of range
"""
return uchar[0], uchar[-1], uchar[i]
mixed_ustring = u'AbcDefGhIjKlmnoP'
lower_ustring = mixed_ustring.lower()
upper_ustring = mixed_ustring.lower()
@cython.test_assert_path_exists('//PythonCapiCallNode',
'//ForFromStatNode')
@cython.test_fail_if_path_exists('//SimpleCallNode',
'//ForInStatNode')
def count_lower_case_characters(unicode ustring):
"""
>>> count_lower_case_characters(mixed_ustring)
10
>>> count_lower_case_characters(lower_ustring)
16
"""
cdef Py_ssize_t count = 0
for uchar in ustring:
if uchar.islower():
count += 1
return count
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment