cython-devel
changeset 1376:e490ccfecad0
handle value coercion correctly in dict iteration
| author | Stefan Behnel <scoder@users.berlios.de> |
|---|---|
| date | Tue Nov 25 18:24:52 2008 +0100 (3 years ago) |
| parents | 9e5fcb49d029 |
| children | 9f94f4e5b3d7 |
| files | Cython/Compiler/ExprNodes.py Cython/Compiler/Optimize.py tests/run/iterdict.pyx |
line diff
1.1 --- a/Cython/Compiler/ExprNodes.py Tue Nov 25 15:56:09 2008 +0100
1.2 +++ b/Cython/Compiler/ExprNodes.py Tue Nov 25 18:24:52 2008 +0100
1.3 @@ -4504,8 +4504,6 @@
1.4 self.type = dst_type
1.5 self.gil_check(env)
1.6 self.result_ctype = arg.ctype()
1.7 - if not dst_type.is_builtin_type:
1.8 - env.use_utility_code(type_test_utility_code)
1.9
1.10 gil_message = "Python type test"
1.11
1.12 @@ -4523,6 +4521,8 @@
1.13
1.14 def generate_result_code(self, code):
1.15 if self.type.typeobj_is_available():
1.16 + if not dst_type.is_builtin_type:
1.17 + code.globalstate.use_utility_code(type_test_utility_code)
1.18 code.putln(
1.19 "if (!(%s)) %s" % (
1.20 self.type.type_test_code(self.arg.py_result()),
2.1 --- a/Cython/Compiler/Optimize.py Tue Nov 25 15:56:09 2008 +0100
2.2 +++ b/Cython/Compiler/Optimize.py Tue Nov 25 18:24:52 2008 +0100
2.3 @@ -111,16 +111,25 @@
2.4 else:
2.5 tuple_target = node.target
2.6
2.7 - if keys:
2.8 - key_cast = ExprNodes.TypecastNode(
2.9 - pos = key_target.pos,
2.10 - operand = key_temp,
2.11 - type = key_target.type)
2.12 - if values:
2.13 - value_cast = ExprNodes.TypecastNode(
2.14 - pos = value_target.pos,
2.15 - operand = value_temp,
2.16 - type = value_target.type)
2.17 + def coerce_object_to(obj_node, dest_type):
2.18 + class FakeEnv(object):
2.19 + nogil = False
2.20 + if dest_type.is_pyobject:
2.21 + if dest_type.is_extension_type or dest_type.is_builtin_type:
2.22 + return (obj_node, ExprNodes.PyTypeTestNode(obj_node, dest_type, FakeEnv()))
2.23 + else:
2.24 + return (obj_node, None)
2.25 + else:
2.26 + temp = UtilNodes.TempHandle(dest_type)
2.27 + temps.append(temp)
2.28 + temp_result = temp.ref(obj_node.pos)
2.29 + class CoercedTempNode(ExprNodes.CoerceFromPyTypeNode):
2.30 + # FIXME: remove this after result-code refactoring
2.31 + def result(self):
2.32 + return temp_result.result()
2.33 + def generate_execution_code(self, code):
2.34 + self.generate_result_code(code)
2.35 + return (temp_result, CoercedTempNode(dest_type, obj_node, FakeEnv()))
2.36
2.37 if isinstance(node.body, Nodes.StatListNode):
2.38 body = node.body
2.39 @@ -129,7 +138,7 @@
2.40 stats = [node.body])
2.41
2.42 if tuple_target:
2.43 - temp = UtilNodes.TempHandle(py_object_ptr)
2.44 + temp = UtilNodes.TempHandle(PyrexTypes.py_object_type)
2.45 temps.append(temp)
2.46 temp_tuple = temp.ref(tuple_target.pos)
2.47 class TempTupleNode(ExprNodes.TupleNode):
2.48 @@ -139,7 +148,7 @@
2.49
2.50 tuple_result = TempTupleNode(
2.51 pos = tuple_target.pos,
2.52 - args = [key_cast, value_cast],
2.53 + args = [key_temp, value_temp],
2.54 is_temp = 1,
2.55 type = Builtin.tuple_type,
2.56 )
2.57 @@ -148,18 +157,30 @@
2.58 lhs = tuple_target,
2.59 rhs = tuple_result))
2.60 else:
2.61 + # execute all coercions before the assignments
2.62 + coercion_stats = []
2.63 + assign_stats = []
2.64 + if keys:
2.65 + temp_result, coercion = coerce_object_to(
2.66 + key_temp, key_target.type)
2.67 + if coercion:
2.68 + coercion_stats.append(coercion)
2.69 + assign_stats.append(
2.70 + Nodes.SingleAssignmentNode(
2.71 + pos = key_temp.pos,
2.72 + rhs = temp_result,
2.73 + lhs = key_target))
2.74 if values:
2.75 - body.stats.insert(
2.76 - 0, Nodes.SingleAssignmentNode(
2.77 - pos = value_target.pos,
2.78 - lhs = value_target,
2.79 - rhs = value_cast))
2.80 - if keys:
2.81 - body.stats.insert(
2.82 - 0, Nodes.SingleAssignmentNode(
2.83 - pos = key_target.pos,
2.84 - lhs = key_target,
2.85 - rhs = key_cast))
2.86 + temp_result, coercion = coerce_object_to(
2.87 + value_temp, value_target.type)
2.88 + if coercion:
2.89 + coercion_stats.append(coercion)
2.90 + assign_stats.append(
2.91 + Nodes.SingleAssignmentNode(
2.92 + pos = value_temp.pos,
2.93 + rhs = temp_result,
2.94 + lhs = value_target))
2.95 + body.stats[0:0] = coercion_stats + assign_stats
2.96
2.97 result_code = [
2.98 Nodes.SingleAssignmentNode(
3.1 --- a/tests/run/iterdict.pyx Tue Nov 25 15:56:09 2008 +0100
3.2 +++ b/tests/run/iterdict.pyx Tue Nov 25 18:24:52 2008 +0100
3.3 @@ -6,14 +6,22 @@
3.4 [(10, 0), (11, 1), (12, 2), (13, 3)]
3.5 >>> iteritems(d)
3.6 [(10, 0), (11, 1), (12, 2), (13, 3)]
3.7 +>>> iteritems_int(d)
3.8 +[(10, 0), (11, 1), (12, 2), (13, 3)]
3.9 >>> iteritems_tuple(d)
3.10 [(10, 0), (11, 1), (12, 2), (13, 3)]
3.11 >>> iterkeys(d)
3.12 [10, 11, 12, 13]
3.13 +>>> iterkeys_int(d)
3.14 +[10, 11, 12, 13]
3.15 >>> iterdict(d)
3.16 [10, 11, 12, 13]
3.17 +>>> iterdict_int(d)
3.18 +[10, 11, 12, 13]
3.19 >>> itervalues(d)
3.20 [0, 1, 2, 3]
3.21 +>>> itervalues_int(d)
3.22 +[0, 1, 2, 3]
3.23 """
3.24
3.25 def items(dict d):
3.26 @@ -30,6 +38,14 @@
3.27 l.sort()
3.28 return l
3.29
3.30 +def iteritems_int(dict d):
3.31 + cdef int k,v
3.32 + l = []
3.33 + for k,v in d.iteritems():
3.34 + l.append((k,v))
3.35 + l.sort()
3.36 + return l
3.37 +
3.38 def iteritems_tuple(dict d):
3.39 l = []
3.40 for t in d.iteritems():
3.41 @@ -44,6 +60,14 @@
3.42 l.sort()
3.43 return l
3.44
3.45 +def iterkeys_int(dict d):
3.46 + cdef int k
3.47 + l = []
3.48 + for k in d.iterkeys():
3.49 + l.append(k)
3.50 + l.sort()
3.51 + return l
3.52 +
3.53 def iterdict(dict d):
3.54 l = []
3.55 for k in d:
3.56 @@ -51,9 +75,25 @@
3.57 l.sort()
3.58 return l
3.59
3.60 +def iterdict_int(dict d):
3.61 + cdef int k
3.62 + l = []
3.63 + for k in d:
3.64 + l.append(k)
3.65 + l.sort()
3.66 + return l
3.67 +
3.68 def itervalues(dict d):
3.69 l = []
3.70 for v in d.itervalues():
3.71 l.append(v)
3.72 l.sort()
3.73 return l
3.74 +
3.75 +def itervalues_int(dict d):
3.76 + cdef int v
3.77 + l = []
3.78 + for v in d.itervalues():
3.79 + l.append(v)
3.80 + l.sort()
3.81 + return l
