Cython has moved to github.

cython-devel

view Cython/Compiler/ExprNodes.py @ 2658:4208042ceeae

Fix bug #252, mangle illegal optional c argument names.
author Robert Bradshaw <robertwb@math.washington.edu>
date Wed Nov 04 21:41:14 2009 -0800 (2 years ago)
parents 59db41e37a49
children 2266c6948c98 b9710187b2c8
line source
1 #
2 # Pyrex - Parse tree nodes for expressions
3 #
5 import operator
7 from Errors import error, warning, warn_once, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Code import UtilityCode
10 import StringEncoding
11 import Naming
12 import Nodes
13 from Nodes import Node
14 import PyrexTypes
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, unspecified_type
16 from Builtin import list_type, tuple_type, set_type, dict_type, \
17 unicode_type, str_type, bytes_type, type_type
18 import Builtin
19 import Symtab
20 import Options
21 from Annotate import AnnotationItem
23 from Cython.Debugging import print_call_chain
24 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
25 debug_coercion
27 try:
28 set
29 except NameError:
30 from sets import Set as set
32 class NotConstant(object): pass # just for the name
33 not_a_constant = NotConstant()
34 constant_value_not_set = object()
36 # error messages when coercing from key[0] to key[1]
37 find_coercion_error = {
38 # string related errors
39 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
40 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
41 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
42 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
43 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
44 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
45 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
46 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
47 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
48 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
49 }.get
52 class ExprNode(Node):
53 # subexprs [string] Class var holding names of subexpr node attrs
54 # type PyrexType Type of the result
55 # result_code string Code fragment
56 # result_ctype string C type of result_code if different from type
57 # is_temp boolean Result is in a temporary variable
58 # is_sequence_constructor
59 # boolean Is a list or tuple constructor expression
60 # is_starred boolean Is a starred expression (e.g. '*a')
61 # saved_subexpr_nodes
62 # [ExprNode or [ExprNode or None] or None]
63 # Cached result of subexpr_nodes()
64 # use_managed_ref boolean use ref-counted temps/assignments/etc.
66 result_ctype = None
67 type = None
68 temp_code = None
69 old_temp = None # error checker for multiple frees etc.
70 use_managed_ref = True # can be set by optimisation transforms
72 # The Analyse Expressions phase for expressions is split
73 # into two sub-phases:
74 #
75 # Analyse Types
76 # Determines the result type of the expression based
77 # on the types of its sub-expressions, and inserts
78 # coercion nodes into the expression tree where needed.
79 # Marks nodes which will need to have temporary variables
80 # allocated.
81 #
82 # Allocate Temps
83 # Allocates temporary variables where needed, and fills
84 # in the result_code field of each node.
85 #
86 # ExprNode provides some convenience routines which
87 # perform both of the above phases. These should only
88 # be called from statement nodes, and only when no
89 # coercion nodes need to be added around the expression
90 # being analysed. In that case, the above two phases
91 # should be invoked separately.
92 #
93 # Framework code in ExprNode provides much of the common
94 # processing for the various phases. It makes use of the
95 # 'subexprs' class attribute of ExprNodes, which should
96 # contain a list of the names of attributes which can
97 # hold sub-nodes or sequences of sub-nodes.
98 #
99 # The framework makes use of a number of abstract methods.
100 # Their responsibilities are as follows.
101 #
102 # Declaration Analysis phase
103 #
104 # analyse_target_declaration
105 # Called during the Analyse Declarations phase to analyse
106 # the LHS of an assignment or argument of a del statement.
107 # Nodes which cannot be the LHS of an assignment need not
108 # implement it.
109 #
110 # Expression Analysis phase
111 #
112 # analyse_types
113 # - Call analyse_types on all sub-expressions.
114 # - Check operand types, and wrap coercion nodes around
115 # sub-expressions where needed.
116 # - Set the type of this node.
117 # - If a temporary variable will be required for the
118 # result, set the is_temp flag of this node.
119 #
120 # analyse_target_types
121 # Called during the Analyse Types phase to analyse
122 # the LHS of an assignment or argument of a del
123 # statement. Similar responsibilities to analyse_types.
124 #
125 # target_code
126 # Called by the default implementation of allocate_target_temps.
127 # Should return a C lvalue for assigning to the node. The default
128 # implementation calls calculate_result_code.
129 #
130 # check_const
131 # - Check that this node and its subnodes form a
132 # legal constant expression. If so, do nothing,
133 # otherwise call not_const.
134 #
135 # The default implementation of check_const
136 # assumes that the expression is not constant.
137 #
138 # check_const_addr
139 # - Same as check_const, except check that the
140 # expression is a C lvalue whose address is
141 # constant. Otherwise, call addr_not_const.
142 #
143 # The default implementation of calc_const_addr
144 # assumes that the expression is not a constant
145 # lvalue.
146 #
147 # Code Generation phase
148 #
149 # generate_evaluation_code
150 # - Call generate_evaluation_code for sub-expressions.
151 # - Perform the functions of generate_result_code
152 # (see below).
153 # - If result is temporary, call generate_disposal_code
154 # on all sub-expressions.
155 #
156 # A default implementation of generate_evaluation_code
157 # is provided which uses the following abstract methods:
158 #
159 # generate_result_code
160 # - Generate any C statements necessary to calculate
161 # the result of this node from the results of its
162 # sub-expressions.
163 #
164 # calculate_result_code
165 # - Should return a C code fragment evaluating to the
166 # result. This is only called when the result is not
167 # a temporary.
168 #
169 # generate_assignment_code
170 # Called on the LHS of an assignment.
171 # - Call generate_evaluation_code for sub-expressions.
172 # - Generate code to perform the assignment.
173 # - If the assignment absorbed a reference, call
174 # generate_post_assignment_code on the RHS,
175 # otherwise call generate_disposal_code on it.
176 #
177 # generate_deletion_code
178 # Called on an argument of a del statement.
179 # - Call generate_evaluation_code for sub-expressions.
180 # - Generate code to perform the deletion.
181 # - Call generate_disposal_code on all sub-expressions.
182 #
183 #
185 is_sequence_constructor = 0
186 is_attribute = 0
188 saved_subexpr_nodes = None
189 is_temp = 0
190 is_target = 0
191 is_starred = 0
193 constant_result = constant_value_not_set
195 try:
196 _get_child_attrs = operator.attrgetter('subexprs')
197 except AttributeError:
198 # Python 2.3
199 def _get_child_attrs(self):
200 return self.subexprs
201 child_attrs = property(fget=_get_child_attrs)
203 def not_implemented(self, method_name):
204 print_call_chain(method_name, "not implemented") ###
205 raise InternalError(
206 "%s.%s not implemented" %
207 (self.__class__.__name__, method_name))
209 def is_lvalue(self):
210 return 0
212 def is_ephemeral(self):
213 # An ephemeral node is one whose result is in
214 # a Python temporary and we suspect there are no
215 # other references to it. Certain operations are
216 # disallowed on such values, since they are
217 # likely to result in a dangling pointer.
218 return self.type.is_pyobject and self.is_temp
220 def subexpr_nodes(self):
221 # Extract a list of subexpression nodes based
222 # on the contents of the subexprs class attribute.
223 nodes = []
224 for name in self.subexprs:
225 item = getattr(self, name)
226 if item is not None:
227 if type(item) is list:
228 nodes.extend(item)
229 else:
230 nodes.append(item)
231 return nodes
233 def result(self):
234 if self.is_temp:
235 return self.temp_code
236 else:
237 return self.calculate_result_code()
239 def result_as(self, type = None):
240 # Return the result code cast to the specified C type.
241 return typecast(type, self.ctype(), self.result())
243 def py_result(self):
244 # Return the result code cast to PyObject *.
245 return self.result_as(py_object_type)
247 def ctype(self):
248 # Return the native C type of the result (i.e. the
249 # C type of the result_code expression).
250 return self.result_ctype or self.type
252 def get_constant_c_result_code(self):
253 # Return the constant value of this node as a result code
254 # string, or None if the node is not constant. This method
255 # can be called when the constant result code is required
256 # before the code generation phase.
257 #
258 # The return value is a string that can represent a simple C
259 # value, a constant C name or a constant C expression. If the
260 # node type depends on Python code, this must return None.
261 return None
263 def calculate_constant_result(self):
264 # Calculate the constant compile time result value of this
265 # expression and store it in ``self.constant_result``. Does
266 # nothing by default, thus leaving ``self.constant_result``
267 # unknown. If valid, the result can be an arbitrary Python
268 # value.
269 #
270 # This must only be called when it is assured that all
271 # sub-expressions have a valid constant_result value. The
272 # ConstantFolding transform will do this.
273 pass
275 def compile_time_value(self, denv):
276 # Return value of compile-time expression, or report error.
277 error(self.pos, "Invalid compile-time expression")
279 def compile_time_value_error(self, e):
280 error(self.pos, "Error in compile-time expression: %s: %s" % (
281 e.__class__.__name__, e))
283 # ------------- Declaration Analysis ----------------
285 def analyse_target_declaration(self, env):
286 error(self.pos, "Cannot assign to or delete this")
288 # ------------- Expression Analysis ----------------
290 def analyse_const_expression(self, env):
291 # Called during the analyse_declarations phase of a
292 # constant expression. Analyses the expression's type,
293 # checks whether it is a legal const expression,
294 # and determines its value.
295 self.analyse_types(env)
296 return self.check_const()
298 def analyse_expressions(self, env):
299 # Convenience routine performing both the Type
300 # Analysis and Temp Allocation phases for a whole
301 # expression.
302 self.analyse_types(env)
304 def analyse_target_expression(self, env, rhs):
305 # Convenience routine performing both the Type
306 # Analysis and Temp Allocation phases for the LHS of
307 # an assignment.
308 self.analyse_target_types(env)
310 def analyse_boolean_expression(self, env):
311 # Analyse expression and coerce to a boolean.
312 self.analyse_types(env)
313 bool = self.coerce_to_boolean(env)
314 return bool
316 def analyse_temp_boolean_expression(self, env):
317 # Analyse boolean expression and coerce result into
318 # a temporary. This is used when a branch is to be
319 # performed on the result and we won't have an
320 # opportunity to ensure disposal code is executed
321 # afterwards. By forcing the result into a temporary,
322 # we ensure that all disposal has been done by the
323 # time we get the result.
324 self.analyse_types(env)
325 bool = self.coerce_to_boolean(env)
326 temp_bool = bool.coerce_to_temp(env)
327 return temp_bool
329 # --------------- Type Inference -----------------
331 def type_dependencies(self, env):
332 # Returns the list of entries whose types must be determined
333 # before the type of self can be infered.
334 if hasattr(self, 'type') and self.type is not None:
335 return ()
336 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
338 def infer_type(self, env):
339 # Attempt to deduce the type of self.
340 # Differs from analyse_types as it avoids unnecessary
341 # analysis of subexpressions, but can assume everything
342 # in self.type_dependencies() has been resolved.
343 if hasattr(self, 'type') and self.type is not None:
344 return self.type
345 elif hasattr(self, 'entry') and self.entry is not None:
346 return self.entry.type
347 else:
348 self.not_implemented("infer_type")
350 # --------------- Type Analysis ------------------
352 def analyse_as_module(self, env):
353 # If this node can be interpreted as a reference to a
354 # cimported module, return its scope, else None.
355 return None
357 def analyse_as_type(self, env):
358 # If this node can be interpreted as a reference to a
359 # type, return that type, else None.
360 return None
362 def analyse_as_extension_type(self, env):
363 # If this node can be interpreted as a reference to an
364 # extension type, return its type, else None.
365 return None
367 def analyse_types(self, env):
368 self.not_implemented("analyse_types")
370 def analyse_target_types(self, env):
371 self.analyse_types(env)
373 def nogil_check(self, env):
374 # By default, any expression based on Python objects is
375 # prevented in nogil environments. Subtypes must override
376 # this if they can work without the GIL.
377 if self.type.is_pyobject:
378 self.gil_error()
380 def gil_assignment_check(self, env):
381 if env.nogil and self.type.is_pyobject:
382 error(self.pos, "Assignment of Python object not allowed without gil")
384 def check_const(self):
385 self.not_const()
386 return False
388 def not_const(self):
389 error(self.pos, "Not allowed in a constant expression")
391 def check_const_addr(self):
392 self.addr_not_const()
393 return False
395 def addr_not_const(self):
396 error(self.pos, "Address is not constant")
398 # ----------------- Result Allocation -----------------
400 def result_in_temp(self):
401 # Return true if result is in a temporary owned by
402 # this node or one of its subexpressions. Overridden
403 # by certain nodes which can share the result of
404 # a subnode.
405 return self.is_temp
407 def target_code(self):
408 # Return code fragment for use as LHS of a C assignment.
409 return self.calculate_result_code()
411 def calculate_result_code(self):
412 self.not_implemented("calculate_result_code")
414 # def release_target_temp(self, env):
415 # # Release temporaries used by LHS of an assignment.
416 # self.release_subexpr_temps(env)
418 def allocate_temp_result(self, code):
419 if self.temp_code:
420 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
421 type = self.type
422 if not type.is_void:
423 if type.is_pyobject:
424 type = PyrexTypes.py_object_type
425 self.temp_code = code.funcstate.allocate_temp(
426 type, manage_ref=self.use_managed_ref)
427 else:
428 self.temp_code = None
430 def release_temp_result(self, code):
431 if not self.temp_code:
432 if self.old_temp:
433 raise RuntimeError("temp %s released multiple times in %s" % (
434 self.old_temp, self.__class__.__name__))
435 else:
436 raise RuntimeError("no temp, but release requested in %s" % (
437 self.__class__.__name__))
438 code.funcstate.release_temp(self.temp_code)
439 self.old_temp = self.temp_code
440 self.temp_code = None
442 # ---------------- Code Generation -----------------
444 def make_owned_reference(self, code):
445 # If result is a pyobject, make sure we own
446 # a reference to it.
447 if self.type.is_pyobject and not self.result_in_temp():
448 code.put_incref(self.result(), self.ctype())
450 def generate_evaluation_code(self, code):
451 code.mark_pos(self.pos)
453 # Generate code to evaluate this node and
454 # its sub-expressions, and dispose of any
455 # temporary results of its sub-expressions.
456 self.generate_subexpr_evaluation_code(code)
458 if self.is_temp:
459 self.allocate_temp_result(code)
461 self.generate_result_code(code)
462 if self.is_temp:
463 # If we are temp we do not need to wait until this node is disposed
464 # before disposing children.
465 self.generate_subexpr_disposal_code(code)
466 self.free_subexpr_temps(code)
468 def generate_subexpr_evaluation_code(self, code):
469 for node in self.subexpr_nodes():
470 node.generate_evaluation_code(code)
472 def generate_result_code(self, code):
473 self.not_implemented("generate_result_code")
475 def generate_disposal_code(self, code):
476 if self.is_temp:
477 if self.type.is_pyobject:
478 code.put_decref_clear(self.result(), self.ctype())
479 else:
480 # Already done if self.is_temp
481 self.generate_subexpr_disposal_code(code)
483 def generate_subexpr_disposal_code(self, code):
484 # Generate code to dispose of temporary results
485 # of all sub-expressions.
486 for node in self.subexpr_nodes():
487 node.generate_disposal_code(code)
489 def generate_post_assignment_code(self, code):
490 if self.is_temp:
491 if self.type.is_pyobject:
492 code.putln("%s = 0;" % self.result())
493 else:
494 self.generate_subexpr_disposal_code(code)
496 def generate_assignment_code(self, rhs, code):
497 # Stub method for nodes which are not legal as
498 # the LHS of an assignment. An error will have
499 # been reported earlier.
500 pass
502 def generate_deletion_code(self, code):
503 # Stub method for nodes that are not legal as
504 # the argument of a del statement. An error
505 # will have been reported earlier.
506 pass
508 def free_temps(self, code):
509 if self.is_temp:
510 if not self.type.is_void:
511 self.release_temp_result(code)
512 else:
513 self.free_subexpr_temps(code)
515 def free_subexpr_temps(self, code):
516 for sub in self.subexpr_nodes():
517 sub.free_temps(code)
519 # ---------------- Annotation ---------------------
521 def annotate(self, code):
522 for node in self.subexpr_nodes():
523 node.annotate(code)
525 # ----------------- Coercion ----------------------
527 def coerce_to(self, dst_type, env):
528 # Coerce the result so that it can be assigned to
529 # something of type dst_type. If processing is necessary,
530 # wraps this node in a coercion node and returns that.
531 # Otherwise, returns this node unchanged.
532 #
533 # This method is called during the analyse_expressions
534 # phase of the src_node's processing.
535 src = self
536 src_type = self.type
537 src_is_py_type = src_type.is_pyobject
538 dst_is_py_type = dst_type.is_pyobject
540 if self.check_for_coercion_error(dst_type):
541 return self
543 if dst_type.is_pyobject:
544 if not src.type.is_pyobject:
545 src = CoerceToPyTypeNode(src, env)
546 if not src.type.subtype_of(dst_type):
547 if not isinstance(src, NoneNode):
548 src = PyTypeTestNode(src, dst_type, env)
549 elif src.type.is_pyobject:
550 src = CoerceFromPyTypeNode(dst_type, src, env)
551 elif (dst_type.is_complex
552 and src_type != dst_type
553 and dst_type.assignable_from(src_type)):
554 src = CoerceToComplexNode(src, dst_type, env)
555 else: # neither src nor dst are py types
556 # Added the string comparison, since for c types that
557 # is enough, but Cython gets confused when the types are
558 # in different pxi files.
559 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
560 self.fail_assignment(dst_type)
561 return src
563 def fail_assignment(self, dst_type):
564 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
566 def check_for_coercion_error(self, dst_type, fail=False, default=None):
567 if fail and not default:
568 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
569 message = find_coercion_error((self.type, dst_type), default)
570 if message is not None:
571 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
572 return True
573 if fail:
574 self.fail_assignment(dst_type)
575 return True
576 return False
578 def coerce_to_pyobject(self, env):
579 return self.coerce_to(PyrexTypes.py_object_type, env)
581 def coerce_to_boolean(self, env):
582 # Coerce result to something acceptable as
583 # a boolean value.
584 type = self.type
585 if type.is_pyobject or type.is_ptr or type.is_float:
586 return CoerceToBooleanNode(self, env)
587 else:
588 if not type.is_int and not type.is_error:
589 error(self.pos,
590 "Type '%s' not acceptable as a boolean" % type)
591 return self
593 def coerce_to_integer(self, env):
594 # If not already some C integer type, coerce to longint.
595 if self.type.is_int:
596 return self
597 else:
598 return self.coerce_to(PyrexTypes.c_long_type, env)
600 def coerce_to_temp(self, env):
601 # Ensure that the result is in a temporary.
602 if self.result_in_temp():
603 return self
604 else:
605 return CoerceToTempNode(self, env)
607 def coerce_to_simple(self, env):
608 # Ensure that the result is simple (see is_simple).
609 if self.is_simple():
610 return self
611 else:
612 return self.coerce_to_temp(env)
614 def is_simple(self):
615 # A node is simple if its result is something that can
616 # be referred to without performing any operations, e.g.
617 # a constant, local var, C global var, struct member
618 # reference, or temporary.
619 return self.result_in_temp()
621 def as_cython_attribute(self):
622 return None
624 class AtomicExprNode(ExprNode):
625 # Abstract base class for expression nodes which have
626 # no sub-expressions.
628 subexprs = []
630 # Override to optimize -- we know we have no children
631 def generate_subexpr_evaluation_code(self, code):
632 pass
633 def generate_subexpr_disposal_code(self, code):
634 pass
636 class PyConstNode(AtomicExprNode):
637 # Abstract base class for constant Python values.
639 is_literal = 1
640 type = py_object_type
642 def is_simple(self):
643 return 1
645 def analyse_types(self, env):
646 pass
648 def calculate_result_code(self):
649 return self.value
651 def generate_result_code(self, code):
652 pass
655 class NoneNode(PyConstNode):
656 # The constant value None
658 value = "Py_None"
660 constant_result = None
662 nogil_check = None
664 def compile_time_value(self, denv):
665 return None
667 class EllipsisNode(PyConstNode):
668 # '...' in a subscript list.
670 value = "Py_Ellipsis"
672 constant_result = Ellipsis
674 def compile_time_value(self, denv):
675 return Ellipsis
678 class ConstNode(AtomicExprNode):
679 # Abstract base type for literal constant nodes.
680 #
681 # value string C code fragment
683 is_literal = 1
684 nogil_check = None
686 def is_simple(self):
687 return 1
689 def analyse_types(self, env):
690 pass # Types are held in class variables
692 def check_const(self):
693 return True
695 def get_constant_c_result_code(self):
696 return self.calculate_result_code()
698 def calculate_result_code(self):
699 return str(self.value)
701 def generate_result_code(self, code):
702 pass
705 class BoolNode(ConstNode):
706 type = PyrexTypes.c_bint_type
707 # The constant value True or False
709 def calculate_constant_result(self):
710 self.constant_result = self.value
712 def compile_time_value(self, denv):
713 return self.value
715 def calculate_result_code(self):
716 return str(int(self.value))
719 class NullNode(ConstNode):
720 type = PyrexTypes.c_null_ptr_type
721 value = "NULL"
722 constant_result = 0
724 def get_constant_c_result_code(self):
725 return self.value
728 class CharNode(ConstNode):
729 type = PyrexTypes.c_char_type
731 def calculate_constant_result(self):
732 self.constant_result = ord(self.value)
734 def compile_time_value(self, denv):
735 return ord(self.value)
737 def calculate_result_code(self):
738 return "'%s'" % StringEncoding.escape_char(self.value)
741 class IntNode(ConstNode):
743 # unsigned "" or "U"
744 # longness "" or "L" or "LL"
746 unsigned = ""
747 longness = ""
748 type = PyrexTypes.c_long_type
750 def coerce_to(self, dst_type, env):
751 if dst_type.is_numeric and not dst_type.is_complex:
752 self.type = PyrexTypes.c_long_type
753 return self
754 # Arrange for a Python version of the number to be pre-allocated
755 # when coercing to a Python type.
756 if dst_type.is_pyobject:
757 self.type = PyrexTypes.py_object_type
758 # We still need to perform normal coerce_to processing on the
759 # result, because we might be coercing to an extension type,
760 # in which case a type test node will be needed.
761 return ConstNode.coerce_to(self, dst_type, env)
763 def coerce_to_boolean(self, env):
764 self.type = PyrexTypes.c_bint_type
765 return self
767 def generate_evaluation_code(self, code):
768 if self.type.is_pyobject:
769 self.result_code = code.get_py_num(self.value, self.longness)
770 else:
771 self.result_code = self.get_constant_c_result_code()
773 def get_constant_c_result_code(self):
774 return str(self.value) + self.unsigned + self.longness
776 def calculate_result_code(self):
777 return self.result_code
779 def calculate_constant_result(self):
780 self.constant_result = int(self.value, 0)
782 def compile_time_value(self, denv):
783 return int(self.value, 0)
786 class FloatNode(ConstNode):
787 type = PyrexTypes.c_double_type
789 def calculate_constant_result(self):
790 self.constant_result = float(self.value)
792 def compile_time_value(self, denv):
793 return float(self.value)
795 def calculate_result_code(self):
796 strval = repr(float(self.value))
797 if strval == 'nan':
798 return "(Py_HUGE_VAL * 0)"
799 elif strval == 'inf':
800 return "Py_HUGE_VAL"
801 elif strval == '-inf':
802 return "(-Py_HUGE_VAL)"
803 else:
804 return strval
807 class BytesNode(ConstNode):
808 # A char* or bytes literal
809 #
810 # value BytesLiteral
812 type = PyrexTypes.c_char_ptr_type
814 def compile_time_value(self, denv):
815 return self.value
817 def analyse_as_type(self, env):
818 type = PyrexTypes.parse_basic_type(self.value)
819 if type is not None:
820 return type
821 from TreeFragment import TreeFragment
822 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
823 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
824 sizeof_node = declaration.root.stats[0].expr
825 sizeof_node.analyse_types(env)
826 if isinstance(sizeof_node, SizeofTypeNode):
827 return sizeof_node.arg_type
829 def can_coerce_to_char_literal(self):
830 return len(self.value) == 1
832 def coerce_to(self, dst_type, env):
833 if dst_type == PyrexTypes.c_char_ptr_type:
834 self.type = PyrexTypes.c_char_ptr_type
835 return self
836 elif dst_type == PyrexTypes.c_uchar_ptr_type:
837 self.type = PyrexTypes.c_char_ptr_type
838 return CastNode(self, PyrexTypes.c_uchar_ptr_type)
840 if dst_type.is_int:
841 if not self.can_coerce_to_char_literal():
842 error(self.pos, "Only single-character strings can be coerced into ints.")
843 return self
844 return CharNode(self.pos, value=self.value)
846 node = self
847 if not self.type.is_pyobject:
848 if dst_type in (py_object_type, Builtin.bytes_type):
849 node = self.as_py_string_node(env)
850 elif dst_type.is_pyobject:
851 self.fail_assignment(dst_type)
852 return self
853 else:
854 node = self
855 elif dst_type.is_pyobject and dst_type is not py_object_type:
856 self.check_for_coercion_error(dst_type, fail=True)
857 return self
859 # We still need to perform normal coerce_to processing on the
860 # result, because we might be coercing to an extension type,
861 # in which case a type test node will be needed.
862 return ConstNode.coerce_to(node, dst_type, env)
864 def as_py_string_node(self, env):
865 # Return a new BytesNode with the same value as this node
866 # but whose type is a Python type instead of a C type.
867 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
869 def generate_evaluation_code(self, code):
870 if self.type.is_pyobject:
871 self.result_code = code.get_py_string_const(self.value)
872 else:
873 self.result_code = code.get_string_const(self.value)
875 def get_constant_c_result_code(self):
876 return None # FIXME
878 def calculate_result_code(self):
879 return self.result_code
882 class UnicodeNode(PyConstNode):
883 # A Python unicode object
884 #
885 # value EncodedString
887 type = unicode_type
889 def coerce_to(self, dst_type, env):
890 if dst_type is self.type:
891 pass
892 elif not dst_type.is_pyobject:
893 error(self.pos, "Unicode objects do not support coercion to C types.")
894 elif dst_type is not py_object_type:
895 if not self.check_for_coercion_error(dst_type):
896 self.fail_assignment(dst_type)
897 return self
899 def generate_evaluation_code(self, code):
900 self.result_code = code.get_py_string_const(self.value)
902 def calculate_result_code(self):
903 return self.result_code
905 def compile_time_value(self, env):
906 return self.value
909 class StringNode(PyConstNode):
910 # A Python str object, i.e. a byte string in Python 2.x and a
911 # unicode string in Python 3.x
912 #
913 # value BytesLiteral or EncodedString
914 # is_identifier boolean
916 type = str_type
917 is_identifier = None
919 def coerce_to(self, dst_type, env):
920 if dst_type is not py_object_type and dst_type is not str_type:
921 # if dst_type is Builtin.bytes_type:
922 # # special case: bytes = 'str literal'
923 # return BytesNode(self.pos, value=self.value)
924 if not dst_type.is_pyobject:
925 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
926 self.check_for_coercion_error(dst_type, fail=True)
928 # this will be a unicode string in Py3, so make sure we can decode it
929 if self.value.encoding:
930 encoding = self.value.encoding
931 try:
932 self.value.decode(encoding)
933 except UnicodeDecodeError:
934 error(self.pos, "String decoding as '%s' failed. Consider using a byte string or unicode string explicitly, or adjust the source code encoding." % encoding)
936 return self
938 def can_coerce_to_char_literal(self):
939 return not self.is_identifier and len(self.value) == 1
941 def generate_evaluation_code(self, code):
942 self.result_code = code.get_py_string_const(
943 self.value, identifier=self.is_identifier, is_str=True)
945 def get_constant_c_result_code(self):
946 return None
948 def calculate_result_code(self):
949 return self.result_code
951 def compile_time_value(self, env):
952 return self.value
955 class IdentifierStringNode(StringNode):
956 # A special str value that represents an identifier (bytes in Py2,
957 # unicode in Py3).
958 is_identifier = True
961 class LongNode(AtomicExprNode):
962 # Python long integer literal
963 #
964 # value string
966 type = py_object_type
968 def calculate_constant_result(self):
969 self.constant_result = long(self.value)
971 def compile_time_value(self, denv):
972 return long(self.value)
974 def analyse_types(self, env):
975 self.is_temp = 1
977 gil_message = "Constructing Python long int"
979 def generate_result_code(self, code):
980 code.putln(
981 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
982 self.result(),
983 self.value,
984 code.error_goto_if_null(self.result(), self.pos)))
985 code.put_gotref(self.py_result())
988 class ImagNode(AtomicExprNode):
989 # Imaginary number literal
990 #
991 # value float imaginary part
993 type = PyrexTypes.c_double_complex_type
995 def calculate_constant_result(self):
996 self.constant_result = complex(0.0, self.value)
998 def compile_time_value(self, denv):
999 return complex(0.0, self.value)
1001 def analyse_types(self, env):
1002 self.type.create_declaration_utility_code(env)
1004 def coerce_to(self, dst_type, env):
1005 # Arrange for a Python version of the number to be pre-allocated
1006 # when coercing to a Python type.
1007 if dst_type.is_pyobject:
1008 self.is_temp = 1
1009 self.type = PyrexTypes.py_object_type
1010 # We still need to perform normal coerce_to processing on the
1011 # result, because we might be coercing to an extension type,
1012 # in which case a type test node will be needed.
1013 return AtomicExprNode.coerce_to(self, dst_type, env)
1015 gil_message = "Constructing complex number"
1017 def calculate_result_code(self):
1018 if self.type.is_pyobject:
1019 return self.result()
1020 else:
1021 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1023 def generate_result_code(self, code):
1024 if self.type.is_pyobject:
1025 code.putln(
1026 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1027 self.result(),
1028 float(self.value),
1029 code.error_goto_if_null(self.result(), self.pos)))
1030 code.put_gotref(self.py_result())
1034 class NameNode(AtomicExprNode):
1035 # Reference to a local or global variable name.
1037 # name string Python name of the variable
1038 # entry Entry Symbol table entry
1039 # type_entry Entry For extension type names, the original type entry
1041 is_name = True
1042 is_cython_module = False
1043 cython_attribute = None
1044 lhs_of_first_assignment = False
1045 is_used_as_rvalue = 0
1046 entry = None
1047 type_entry = None
1049 def create_analysed_rvalue(pos, env, entry):
1050 node = NameNode(pos)
1051 node.analyse_types(env, entry=entry)
1052 return node
1054 def as_cython_attribute(self):
1055 return self.cython_attribute
1057 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1059 def type_dependencies(self, env):
1060 if self.entry is None:
1061 self.entry = env.lookup(self.name)
1062 if self.entry is not None and self.entry.type.is_unspecified:
1063 return (self.entry,)
1064 else:
1065 return ()
1067 def infer_type(self, env):
1068 if self.entry is None:
1069 self.entry = env.lookup(self.name)
1070 if self.entry is None:
1071 return py_object_type
1072 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1073 self.name == self.entry.type.name:
1074 # Unfortunately the type attribute of type objects
1075 # is used for the pointer to the type the represent.
1076 return type_type
1077 else:
1078 return self.entry.type
1080 def compile_time_value(self, denv):
1081 try:
1082 return denv.lookup(self.name)
1083 except KeyError:
1084 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1086 def get_constant_c_result_code(self):
1087 if not self.entry or self.entry.type.is_pyobject:
1088 return None
1089 return self.entry.cname
1091 def coerce_to(self, dst_type, env):
1092 # If coercing to a generic pyobject and this is a builtin
1093 # C function with a Python equivalent, manufacture a NameNode
1094 # referring to the Python builtin.
1095 #print "NameNode.coerce_to:", self.name, dst_type ###
1096 if dst_type is py_object_type:
1097 entry = self.entry
1098 if entry and entry.is_cfunction:
1099 var_entry = entry.as_variable
1100 if var_entry:
1101 if var_entry.is_builtin and Options.cache_builtins:
1102 var_entry = env.declare_builtin(var_entry.name, self.pos)
1103 node = NameNode(self.pos, name = self.name)
1104 node.entry = var_entry
1105 node.analyse_rvalue_entry(env)
1106 return node
1107 return super(NameNode, self).coerce_to(dst_type, env)
1109 def analyse_as_module(self, env):
1110 # Try to interpret this as a reference to a cimported module.
1111 # Returns the module scope, or None.
1112 entry = self.entry
1113 if not entry:
1114 entry = env.lookup(self.name)
1115 if entry and entry.as_module:
1116 return entry.as_module
1117 return None
1119 def analyse_as_type(self, env):
1120 if self.cython_attribute:
1121 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1122 else:
1123 type = PyrexTypes.parse_basic_type(self.name)
1124 if type:
1125 return type
1126 entry = self.entry
1127 if not entry:
1128 entry = env.lookup(self.name)
1129 if entry and entry.is_type:
1130 return entry.type
1131 else:
1132 return None
1134 def analyse_as_extension_type(self, env):
1135 # Try to interpret this as a reference to an extension type.
1136 # Returns the extension type, or None.
1137 entry = self.entry
1138 if not entry:
1139 entry = env.lookup(self.name)
1140 if entry and entry.is_type and entry.type.is_extension_type:
1141 return entry.type
1142 else:
1143 return None
1145 def analyse_target_declaration(self, env):
1146 if not self.entry:
1147 self.entry = env.lookup_here(self.name)
1148 if not self.entry:
1149 if env.directives['infer_types']:
1150 type = unspecified_type
1151 else:
1152 type = py_object_type
1153 self.entry = env.declare_var(self.name, type, self.pos)
1154 env.control_flow.set_state(self.pos, (self.name, 'initalized'), True)
1155 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1156 if self.entry.is_declared_generic:
1157 self.result_ctype = py_object_type
1159 def analyse_types(self, env):
1160 if self.entry is None:
1161 self.entry = env.lookup(self.name)
1162 if not self.entry:
1163 self.entry = env.declare_builtin(self.name, self.pos)
1164 if not self.entry:
1165 self.type = PyrexTypes.error_type
1166 return
1167 entry = self.entry
1168 if entry:
1169 entry.used = 1
1170 if entry.type.is_buffer:
1171 import Buffer
1172 Buffer.used_buffer_aux_vars(entry)
1173 if entry.utility_code:
1174 env.use_utility_code(entry.utility_code)
1175 self.analyse_rvalue_entry(env)
1177 def analyse_target_types(self, env):
1178 self.analyse_entry(env)
1179 if not self.is_lvalue():
1180 error(self.pos, "Assignment to non-lvalue '%s'"
1181 % self.name)
1182 self.type = PyrexTypes.error_type
1183 self.entry.used = 1
1184 if self.entry.type.is_buffer:
1185 import Buffer
1186 Buffer.used_buffer_aux_vars(self.entry)
1188 def analyse_rvalue_entry(self, env):
1189 #print "NameNode.analyse_rvalue_entry:", self.name ###
1190 #print "Entry:", self.entry.__dict__ ###
1191 self.analyse_entry(env)
1192 entry = self.entry
1193 if entry.is_declared_generic:
1194 self.result_ctype = py_object_type
1195 if entry.is_pyglobal or entry.is_builtin:
1196 if Options.cache_builtins and entry.is_builtin:
1197 self.is_temp = 0
1198 else:
1199 self.is_temp = 1
1200 self.is_used_as_rvalue = 1
1201 env.use_utility_code(get_name_interned_utility_code)
1203 def nogil_check(self, env):
1204 if self.is_used_as_rvalue:
1205 entry = self.entry
1206 if entry.is_builtin:
1207 # if not Options.cache_builtins: # cached builtins are ok
1208 self.gil_error()
1209 elif entry.is_pyglobal:
1210 self.gil_error()
1212 gil_message = "Accessing Python global or builtin"
1214 def analyse_entry(self, env):
1215 #print "NameNode.analyse_entry:", self.name ###
1216 self.check_identifier_kind()
1217 entry = self.entry
1218 type = entry.type
1219 self.type = type
1221 def check_identifier_kind(self):
1222 # Check that this is an appropriate kind of name for use in an
1223 # expression. Also finds the variable entry associated with
1224 # an extension type.
1225 entry = self.entry
1226 if entry.is_type and entry.type.is_extension_type:
1227 self.type_entry = entry
1228 if not (entry.is_const or entry.is_variable
1229 or entry.is_builtin or entry.is_cfunction):
1230 if self.entry.as_variable:
1231 self.entry = self.entry.as_variable
1232 else:
1233 error(self.pos,
1234 "'%s' is not a constant, variable or function identifier" % self.name)
1236 def is_simple(self):
1237 # If it's not a C variable, it'll be in a temp.
1238 return 1
1240 def calculate_target_results(self, env):
1241 pass
1243 def check_const(self):
1244 entry = self.entry
1245 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1246 self.not_const()
1247 return False
1248 return True
1250 def check_const_addr(self):
1251 entry = self.entry
1252 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1253 self.addr_not_const()
1254 return False
1255 return True
1257 def is_lvalue(self):
1258 return self.entry.is_variable and \
1259 not self.entry.type.is_array and \
1260 not self.entry.is_readonly
1262 def is_ephemeral(self):
1263 # Name nodes are never ephemeral, even if the
1264 # result is in a temporary.
1265 return 0
1267 def calculate_result_code(self):
1268 entry = self.entry
1269 if not entry:
1270 return "<error>" # There was an error earlier
1271 return entry.cname
1273 def generate_result_code(self, code):
1274 assert hasattr(self, 'entry')
1275 entry = self.entry
1276 if entry is None:
1277 return # There was an error earlier
1278 if entry.is_builtin and Options.cache_builtins:
1279 return # Lookup already cached
1280 elif entry.is_pyglobal or entry.is_builtin:
1281 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1282 interned_cname = code.intern_identifier(self.entry.name)
1283 if entry.is_builtin:
1284 namespace = Naming.builtins_cname
1285 else: # entry.is_pyglobal
1286 namespace = entry.scope.namespace_cname
1287 code.putln(
1288 '%s = __Pyx_GetName(%s, %s); %s' % (
1289 self.result(),
1290 namespace,
1291 interned_cname,
1292 code.error_goto_if_null(self.result(), self.pos)))
1293 code.put_gotref(self.py_result())
1295 elif entry.is_local and False:
1296 # control flow not good enough yet
1297 assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1298 if assigned is False:
1299 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1300 elif not Options.init_local_none and assigned is None:
1301 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1302 (entry.cname, entry.name, code.error_goto(self.pos)))
1303 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True)
1305 def generate_assignment_code(self, rhs, code):
1306 #print "NameNode.generate_assignment_code:", self.name ###
1307 entry = self.entry
1308 if entry is None:
1309 return # There was an error earlier
1311 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1312 and not self.lhs_of_first_assignment):
1313 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1315 # is_pyglobal seems to be True for module level-globals only.
1316 # We use this to access class->tp_dict if necessary.
1317 if entry.is_pyglobal:
1318 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1319 interned_cname = code.intern_identifier(self.entry.name)
1320 namespace = self.entry.scope.namespace_cname
1321 if entry.is_member:
1322 # if the entry is a member we have to cheat: SetAttr does not work
1323 # on types, so we create a descriptor which is then added to tp_dict
1324 code.put_error_if_neg(self.pos,
1325 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1326 namespace,
1327 interned_cname,
1328 rhs.py_result()))
1329 rhs.generate_disposal_code(code)
1330 rhs.free_temps(code)
1331 # in Py2.6+, we need to invalidate the method cache
1332 code.putln("PyType_Modified(%s);" %
1333 entry.scope.parent_type.typeptr_cname)
1334 else:
1335 code.put_error_if_neg(self.pos,
1336 'PyObject_SetAttr(%s, %s, %s)' % (
1337 namespace,
1338 interned_cname,
1339 rhs.py_result()))
1340 if debug_disposal_code:
1341 print("NameNode.generate_assignment_code:")
1342 print("...generating disposal code for %s" % rhs)
1343 rhs.generate_disposal_code(code)
1344 rhs.free_temps(code)
1345 else:
1346 if self.type.is_buffer:
1347 # Generate code for doing the buffer release/acquisition.
1348 # This might raise an exception in which case the assignment (done
1349 # below) will not happen.
1351 # The reason this is not in a typetest-like node is because the
1352 # variables that the acquired buffer info is stored to is allocated
1353 # per entry and coupled with it.
1354 self.generate_acquire_buffer(rhs, code)
1356 if self.type.is_pyobject:
1357 #print "NameNode.generate_assignment_code: to", self.name ###
1358 #print "...from", rhs ###
1359 #print "...LHS type", self.type, "ctype", self.ctype() ###
1360 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1361 if self.use_managed_ref:
1362 rhs.make_owned_reference(code)
1363 if entry.is_cglobal:
1364 code.put_gotref(self.py_result())
1365 if self.use_managed_ref and not self.lhs_of_first_assignment:
1366 if entry.is_local and not Options.init_local_none:
1367 initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1368 if initalized is True:
1369 code.put_decref(self.result(), self.ctype())
1370 elif initalized is None:
1371 code.put_xdecref(self.result(), self.ctype())
1372 else:
1373 code.put_decref(self.result(), self.ctype())
1374 if self.use_managed_ref:
1375 if entry.is_cglobal:
1376 code.put_giveref(rhs.py_result())
1377 code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
1378 if debug_disposal_code:
1379 print("NameNode.generate_assignment_code:")
1380 print("...generating post-assignment code for %s" % rhs)
1381 rhs.generate_post_assignment_code(code)
1382 rhs.free_temps(code)
1384 def generate_acquire_buffer(self, rhs, code):
1385 # rhstmp is only used in case the rhs is a complicated expression leading to
1386 # the object, to avoid repeating the same C expression for every reference
1387 # to the rhs. It does NOT hold a reference.
1388 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1389 if pretty_rhs:
1390 rhstmp = rhs.result_as(self.ctype())
1391 else:
1392 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1393 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1395 buffer_aux = self.entry.buffer_aux
1396 bufstruct = buffer_aux.buffer_info_var.cname
1397 import Buffer
1398 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1399 is_initialized=not self.lhs_of_first_assignment,
1400 pos=self.pos, code=code)
1402 if not pretty_rhs:
1403 code.putln("%s = 0;" % rhstmp)
1404 code.funcstate.release_temp(rhstmp)
1406 def generate_deletion_code(self, code):
1407 if self.entry is None:
1408 return # There was an error earlier
1409 if not self.entry.is_pyglobal:
1410 error(self.pos, "Deletion of local or C global name not supported")
1411 return
1412 code.put_error_if_neg(self.pos,
1413 '__Pyx_DelAttrString(%s, "%s")' % (
1414 Naming.module_cname,
1415 self.entry.name))
1417 def annotate(self, code):
1418 if hasattr(self, 'is_called') and self.is_called:
1419 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1420 if self.type.is_pyobject:
1421 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1422 else:
1423 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1425 class BackquoteNode(ExprNode):
1426 # `expr`
1428 # arg ExprNode
1430 type = py_object_type
1432 subexprs = ['arg']
1434 def analyse_types(self, env):
1435 self.arg.analyse_types(env)
1436 self.arg = self.arg.coerce_to_pyobject(env)
1437 self.is_temp = 1
1439 gil_message = "Backquote expression"
1441 def calculate_constant_result(self):
1442 self.constant_result = repr(self.arg.constant_result)
1444 def generate_result_code(self, code):
1445 code.putln(
1446 "%s = PyObject_Repr(%s); %s" % (
1447 self.result(),
1448 self.arg.py_result(),
1449 code.error_goto_if_null(self.result(), self.pos)))
1450 code.put_gotref(self.py_result())
1454 class ImportNode(ExprNode):
1455 # Used as part of import statement implementation.
1456 # Implements result =
1457 # __import__(module_name, globals(), None, name_list)
1459 # module_name StringNode dotted name of module
1460 # name_list ListNode or None list of names to be imported
1462 type = py_object_type
1464 subexprs = ['module_name', 'name_list']
1466 def analyse_types(self, env):
1467 self.module_name.analyse_types(env)
1468 self.module_name = self.module_name.coerce_to_pyobject(env)
1469 if self.name_list:
1470 self.name_list.analyse_types(env)
1471 self.name_list.coerce_to_pyobject(env)
1472 self.is_temp = 1
1473 env.use_utility_code(import_utility_code)
1475 gil_message = "Python import"
1477 def generate_result_code(self, code):
1478 if self.name_list:
1479 name_list_code = self.name_list.py_result()
1480 else:
1481 name_list_code = "0"
1482 code.putln(
1483 "%s = __Pyx_Import(%s, %s); %s" % (
1484 self.result(),
1485 self.module_name.py_result(),
1486 name_list_code,
1487 code.error_goto_if_null(self.result(), self.pos)))
1488 code.put_gotref(self.py_result())
1491 class IteratorNode(ExprNode):
1492 # Used as part of for statement implementation.
1494 # allocate_counter_temp/release_counter_temp needs to be called
1495 # by parent (ForInStatNode)
1497 # Implements result = iter(sequence)
1499 # sequence ExprNode
1501 type = py_object_type
1503 subexprs = ['sequence']
1505 def analyse_types(self, env):
1506 self.sequence.analyse_types(env)
1507 self.sequence = self.sequence.coerce_to_pyobject(env)
1508 self.is_temp = 1
1510 gil_message = "Iterating over Python object"
1512 def allocate_counter_temp(self, code):
1513 self.counter_cname = code.funcstate.allocate_temp(
1514 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1516 def release_counter_temp(self, code):
1517 code.funcstate.release_temp(self.counter_cname)
1519 def generate_result_code(self, code):
1520 is_builtin_sequence = self.sequence.type is list_type or \
1521 self.sequence.type is tuple_type
1522 may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1523 if is_builtin_sequence:
1524 code.putln(
1525 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1526 elif may_be_a_sequence:
1527 code.putln(
1528 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1529 self.sequence.py_result(),
1530 self.sequence.py_result()))
1531 if may_be_a_sequence:
1532 code.putln(
1533 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1534 self.counter_cname,
1535 self.result(),
1536 self.sequence.py_result(),
1537 self.result()))
1538 code.putln("} else {")
1539 if is_builtin_sequence:
1540 code.putln(
1541 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1542 code.error_goto(self.pos))
1543 else:
1544 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1545 self.counter_cname,
1546 self.result(),
1547 self.sequence.py_result(),
1548 code.error_goto_if_null(self.result(), self.pos)))
1549 code.put_gotref(self.py_result())
1550 if may_be_a_sequence:
1551 code.putln("}")
1554 class NextNode(AtomicExprNode):
1555 # Used as part of for statement implementation.
1556 # Implements result = iterator.next()
1557 # Created during analyse_types phase.
1558 # The iterator is not owned by this node.
1560 # iterator ExprNode
1562 type = py_object_type
1564 def __init__(self, iterator, env):
1565 self.pos = iterator.pos
1566 self.iterator = iterator
1567 self.is_temp = 1
1569 def generate_result_code(self, code):
1570 sequence_type = self.iterator.sequence.type
1571 if sequence_type is list_type:
1572 type_checks = [(list_type, "List")]
1573 elif sequence_type is tuple_type:
1574 type_checks = [(tuple_type, "Tuple")]
1575 elif not sequence_type.is_builtin_type:
1576 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1577 else:
1578 type_checks = []
1580 for py_type, prefix in type_checks:
1581 if len(type_checks) > 1:
1582 code.putln(
1583 "if (likely(Py%s_CheckExact(%s))) {" % (
1584 prefix, self.iterator.py_result()))
1585 code.putln(
1586 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1587 self.iterator.counter_cname,
1588 prefix,
1589 self.iterator.py_result()))
1590 code.putln(
1591 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1592 self.result(),
1593 prefix,
1594 self.iterator.py_result(),
1595 self.iterator.counter_cname,
1596 self.result(),
1597 self.iterator.counter_cname))
1598 if len(type_checks) > 1:
1599 code.put("} else ")
1600 if len(type_checks) == 1:
1601 return
1602 code.putln("{")
1603 code.putln(
1604 "%s = PyIter_Next(%s);" % (
1605 self.result(),
1606 self.iterator.py_result()))
1607 code.putln(
1608 "if (!%s) {" %
1609 self.result())
1610 code.putln(code.error_goto_if_PyErr(self.pos))
1611 code.putln("break;")
1612 code.putln("}")
1613 code.put_gotref(self.py_result())
1614 code.putln("}")
1617 class ExcValueNode(AtomicExprNode):
1618 # Node created during analyse_types phase
1619 # of an ExceptClauseNode to fetch the current
1620 # exception value.
1622 type = py_object_type
1624 def __init__(self, pos, env):
1625 ExprNode.__init__(self, pos)
1627 def set_var(self, var):
1628 self.var = var
1630 def calculate_result_code(self):
1631 return self.var
1633 def generate_result_code(self, code):
1634 pass
1636 def analyse_types(self, env):
1637 pass
1640 class TempNode(ExprNode):
1641 # Node created during analyse_types phase
1642 # of some nodes to hold a temporary value.
1644 # Note: One must call "allocate" and "release" on
1645 # the node during code generation to get/release the temp.
1646 # This is because the temp result is often used outside of
1647 # the regular cycle.
1649 subexprs = []
1651 def __init__(self, pos, type, env):
1652 ExprNode.__init__(self, pos)
1653 self.type = type
1654 if type.is_pyobject:
1655 self.result_ctype = py_object_type
1656 self.is_temp = 1
1658 def analyse_types(self, env):
1659 return self.type
1661 def generate_result_code(self, code):
1662 pass
1664 def allocate(self, code):
1665 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1667 def release(self, code):
1668 code.funcstate.release_temp(self.temp_cname)
1669 self.temp_cname = None
1671 def result(self):
1672 try:
1673 return self.temp_cname
1674 except:
1675 assert False, "Remember to call allocate/release on TempNode"
1676 raise
1678 # Do not participate in normal temp alloc/dealloc:
1679 def allocate_temp_result(self, code):
1680 pass
1682 def release_temp_result(self, code):
1683 pass
1685 class PyTempNode(TempNode):
1686 # TempNode holding a Python value.
1688 def __init__(self, pos, env):
1689 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1691 class RawCNameExprNode(ExprNode):
1692 subexprs = []
1694 def __init__(self, pos, type=None):
1695 self.pos = pos
1696 self.type = type
1698 def analyse_types(self, env):
1699 return self.type
1701 def set_cname(self, cname):
1702 self.cname = cname
1704 def result(self):
1705 return self.cname
1707 def generate_result_code(self, code):
1708 pass
1711 #-------------------------------------------------------------------
1713 # Trailer nodes
1715 #-------------------------------------------------------------------
1717 class IndexNode(ExprNode):
1718 # Sequence indexing.
1720 # base ExprNode
1721 # index ExprNode
1722 # indices [ExprNode]
1723 # is_buffer_access boolean Whether this is a buffer access.
1725 # indices is used on buffer access, index on non-buffer access.
1726 # The former contains a clean list of index parameters, the
1727 # latter whatever Python object is needed for index access.
1729 subexprs = ['base', 'index', 'indices']
1730 indices = None
1732 def __init__(self, pos, index, *args, **kw):
1733 ExprNode.__init__(self, pos, index=index, *args, **kw)
1734 self._index = index
1736 def calculate_constant_result(self):
1737 self.constant_result = \
1738 self.base.constant_result[self.index.constant_result]
1740 def compile_time_value(self, denv):
1741 base = self.base.compile_time_value(denv)
1742 index = self.index.compile_time_value(denv)
1743 try:
1744 return base[index]
1745 except Exception, e:
1746 self.compile_time_value_error(e)
1748 def is_ephemeral(self):
1749 return self.base.is_ephemeral()
1751 def analyse_target_declaration(self, env):
1752 pass
1754 def analyse_as_type(self, env):
1755 base_type = self.base.analyse_as_type(env)
1756 if base_type and not base_type.is_pyobject:
1757 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1758 return None
1760 def type_dependencies(self, env):
1761 return self.base.type_dependencies(env)
1763 def infer_type(self, env):
1764 if isinstance(self.base, (StringNode, UnicodeNode)): # FIXME: BytesNode?
1765 return py_object_type
1766 base_type = self.base.infer_type(env)
1767 if base_type.is_ptr or base_type.is_array:
1768 return base_type.base_type
1769 else:
1770 # TODO: Handle buffers (hopefully without too much redundancy).
1771 return py_object_type
1773 def analyse_types(self, env):
1774 self.analyse_base_and_index_types(env, getting = 1)
1776 def analyse_target_types(self, env):
1777 self.analyse_base_and_index_types(env, setting = 1)
1779 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
1780 # Note: This might be cleaned up by having IndexNode
1781 # parsed in a saner way and only construct the tuple if
1782 # needed.
1784 # Note that this function must leave IndexNode in a cloneable state.
1785 # For buffers, self.index is packed out on the initial analysis, and
1786 # when cloning self.indices is copied.
1787 self.is_buffer_access = False
1789 self.base.analyse_types(env)
1790 if self.base.type.is_error:
1791 # Do not visit child tree if base is undeclared to avoid confusing
1792 # error messages
1793 self.type = PyrexTypes.error_type
1794 return
1796 # Handle the case where base is a literal char* (and we expect a string, not an int)
1797 if isinstance(self.base, BytesNode):
1798 self.base = self.base.coerce_to_pyobject(env)
1800 skip_child_analysis = False
1801 buffer_access = False
1802 if self.base.type.is_buffer:
1803 assert hasattr(self.base, "entry") # Must be a NameNode-like node
1804 if self.indices:
1805 indices = self.indices
1806 else:
1807 if isinstance(self.index, TupleNode):
1808 indices = self.index.args
1809 else:
1810 indices = [self.index]
1811 if len(indices) == self.base.type.ndim:
1812 buffer_access = True
1813 skip_child_analysis = True
1814 for x in indices:
1815 x.analyse_types(env)
1816 if not x.type.is_int:
1817 buffer_access = False
1819 # On cloning, indices is cloned. Otherwise, unpack index into indices
1820 assert not (buffer_access and isinstance(self.index, CloneNode))
1822 if buffer_access:
1823 self.indices = indices
1824 self.index = None
1825 self.type = self.base.type.dtype
1826 self.is_buffer_access = True
1827 self.buffer_type = self.base.entry.type
1829 if getting and self.type.is_pyobject:
1830 self.is_temp = True
1831 if setting:
1832 if not self.base.entry.type.writable:
1833 error(self.pos, "Writing to readonly buffer")
1834 else:
1835 self.base.entry.buffer_aux.writable_needed = True
1836 else:
1837 if isinstance(self.index, TupleNode):
1838 self.index.analyse_types(env, skip_children=skip_child_analysis)
1839 elif not skip_child_analysis:
1840 self.index.analyse_types(env)
1841 self.original_index_type = self.index.type
1842 if self.base.type.is_pyobject:
1843 if self.index.type.is_int:
1844 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
1845 else:
1846 self.index = self.index.coerce_to_pyobject(env)
1847 self.type = py_object_type
1848 self.is_temp = 1
1849 else:
1850 if self.base.type.is_ptr or self.base.type.is_array:
1851 self.type = self.base.type.base_type
1852 else:
1853 error(self.pos,
1854 "Attempting to index non-array type '%s'" %
1855 self.base.type)
1856 self.type = PyrexTypes.error_type
1857 if self.index.type.is_pyobject:
1858 self.index = self.index.coerce_to(
1859 PyrexTypes.c_py_ssize_t_type, env)
1860 if not self.index.type.is_int:
1861 error(self.pos,
1862 "Invalid index type '%s'" %
1863 self.index.type)
1864 gil_message = "Indexing Python object"
1866 def nogil_check(self, env):
1867 if self.is_buffer_access:
1868 if env.directives['boundscheck']:
1869 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
1870 return
1871 elif self.type.is_pyobject:
1872 error(self.pos, "Cannot access buffer with object dtype without gil")
1873 return
1874 super(IndexNode, self).nogil_check(env)
1877 def check_const_addr(self):
1878 return self.base.check_const_addr() and self.index.check_const()
1880 def is_lvalue(self):
1881 return 1
1883 def calculate_result_code(self):
1884 if self.is_buffer_access:
1885 return "(*%s)" % self.buffer_ptr_code
1886 else:
1887 return "(%s[%s])" % (
1888 self.base.result(), self.index.result())
1890 def extra_index_params(self):
1891 if self.index.type.is_int:
1892 if self.original_index_type.signed:
1893 size_adjustment = ""
1894 else:
1895 size_adjustment = "+1"
1896 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
1897 else:
1898 return ""
1900 def generate_subexpr_evaluation_code(self, code):
1901 self.base.generate_evaluation_code(code)
1902 if not self.indices:
1903 self.index.generate_evaluation_code(code)
1904 else:
1905 for i in self.indices:
1906 i.generate_evaluation_code(code)
1908 def generate_subexpr_disposal_code(self, code):
1909 self.base.generate_disposal_code(code)
1910 if not self.indices:
1911 self.index.generate_disposal_code(code)
1912 else:
1913 for i in self.indices:
1914 i.generate_disposal_code(code)
1916 def free_subexpr_temps(self, code):
1917 self.base.free_temps(code)
1918 if not self.indices:
1919 self.index.free_temps(code)
1920 else:
1921 for i in self.indices:
1922 i.free_temps(code)
1924 def generate_result_code(self, code):
1925 if self.is_buffer_access:
1926 if code.globalstate.directives['nonecheck']:
1927 self.put_nonecheck(code)
1928 self.buffer_ptr_code = self.buffer_lookup_code(code)
1929 if self.type.is_pyobject:
1930 # is_temp is True, so must pull out value and incref it.
1931 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
1932 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
1933 elif self.type.is_pyobject:
1934 if self.index.type.is_int:
1935 index_code = self.index.result()
1936 if self.base.type is list_type:
1937 function = "__Pyx_GetItemInt_List"
1938 elif self.base.type is tuple_type:
1939 function = "__Pyx_GetItemInt_Tuple"
1940 else:
1941 function = "__Pyx_GetItemInt"
1942 code.globalstate.use_utility_code(getitem_int_utility_code)
1943 else:
1944 function = "PyObject_GetItem"
1945 index_code = self.index.py_result()
1946 sign_code = ""
1947 code.putln(
1948 "%s = %s(%s, %s%s); if (!%s) %s" % (
1949 self.result(),
1950 function,
1951 self.base.py_result(),
1952 index_code,
1953 self.extra_index_params(),
1954 self.result(),
1955 code.error_goto(self.pos)))
1956 code.put_gotref(self.py_result())
1958 def generate_setitem_code(self, value_code, code):
1959 if self.index.type.is_int:
1960 function = "__Pyx_SetItemInt"
1961 index_code = self.index.result()
1962 code.globalstate.use_utility_code(setitem_int_utility_code)
1963 else:
1964 index_code = self.index.py_result()
1965 if self.base.type is dict_type:
1966 function = "PyDict_SetItem"
1967 # It would seem that we could specalized lists/tuples, but that
1968 # shouldn't happen here.
1969 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
1970 # not a PyObject*, and bad conversion here would give the wrong
1971 # exception. Also, tuples are supposed to be immutable, and raise
1972 # TypeErrors when trying to set their entries (PyTuple_SetItem
1973 # is for creating new tuples from).
1974 else:
1975 function = "PyObject_SetItem"
1976 code.putln(
1977 "if (%s(%s, %s, %s%s) < 0) %s" % (
1978 function,
1979 self.base.py_result(),
1980 index_code,
1981 value_code,
1982 self.extra_index_params(),
1983 code.error_goto(self.pos)))
1985 def generate_buffer_setitem_code(self, rhs, code, op=""):
1986 # Used from generate_assignment_code and InPlaceAssignmentNode
1987 if code.globalstate.directives['nonecheck']:
1988 self.put_nonecheck(code)
1989 ptrexpr = self.buffer_lookup_code(code)
1990 if self.buffer_type.dtype.is_pyobject:
1991 # Must manage refcounts. Decref what is already there
1992 # and incref what we put in.
1993 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
1994 rhs_code = rhs.result()
1995 code.putln("%s = %s;" % (ptr, ptrexpr))
1996 code.put_gotref("*%s" % ptr)
1997 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
1998 ptr, rhs_code
1999 ))
2000 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2001 code.put_giveref("*%s" % ptr)
2002 code.funcstate.release_temp(ptr)
2003 else:
2004 # Simple case
2005 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2007 def generate_assignment_code(self, rhs, code):
2008 self.generate_subexpr_evaluation_code(code)
2009 if self.is_buffer_access:
2010 self.generate_buffer_setitem_code(rhs, code)
2011 elif self.type.is_pyobject:
2012 self.generate_setitem_code(rhs.py_result(), code)
2013 else:
2014 code.putln(
2015 "%s = %s;" % (
2016 self.result(), rhs.result()))
2017 self.generate_subexpr_disposal_code(code)
2018 self.free_subexpr_temps(code)
2019 rhs.generate_disposal_code(code)
2020 rhs.free_temps(code)
2022 def generate_deletion_code(self, code):
2023 self.generate_subexpr_evaluation_code(code)
2024 #if self.type.is_pyobject:
2025 if self.index.type.is_int:
2026 function = "__Pyx_DelItemInt"
2027 index_code = self.index.result()
2028 code.globalstate.use_utility_code(delitem_int_utility_code)
2029 else:
2030 index_code = self.index.py_result()
2031 if self.base.type is dict_type:
2032 function = "PyDict_DelItem"
2033 else:
2034 function = "PyObject_DelItem"
2035 code.putln(
2036 "if (%s(%s, %s%s) < 0) %s" % (
2037 function,
2038 self.base.py_result(),
2039 index_code,
2040 self.extra_index_params(),
2041 code.error_goto(self.pos)))
2042 self.generate_subexpr_disposal_code(code)
2043 self.free_subexpr_temps(code)
2045 def buffer_lookup_code(self, code):
2046 # Assign indices to temps
2047 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2048 for temp, index in zip(index_temps, self.indices):
2049 code.putln("%s = %s;" % (temp, index.result()))
2050 # Generate buffer access code using these temps
2051 import Buffer
2052 # The above could happen because child_attrs is wrong somewhere so that
2053 # options are not propagated.
2054 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2055 index_signeds=[i.type.signed for i in self.indices],
2056 index_cnames=index_temps,
2057 directives=code.globalstate.directives,
2058 pos=self.pos, code=code)
2060 def put_nonecheck(self, code):
2061 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2062 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2063 code.putln("__Pyx_RaiseNoneIndexingError();")
2064 code.putln(code.error_goto(self.pos))
2065 code.putln("}")
2067 class SliceIndexNode(ExprNode):
2068 # 2-element slice indexing
2070 # base ExprNode
2071 # start ExprNode or None
2072 # stop ExprNode or None
2074 subexprs = ['base', 'start', 'stop']
2076 def calculate_constant_result(self):
2077 self.constant_result = self.base.constant_result[
2078 self.start.constant_result : self.stop.constant_result]
2080 def compile_time_value(self, denv):
2081 base = self.base.compile_time_value(denv)
2082 if self.start is None:
2083 start = 0
2084 else:
2085 start = self.start.compile_time_value(denv)
2086 if self.stop is None:
2087 stop = None
2088 else:
2089 stop = self.stop.compile_time_value(denv)
2090 try:
2091 return base[start:stop]
2092 except Exception, e:
2093 self.compile_time_value_error(e)
2095 def analyse_target_declaration(self, env):
2096 pass
2098 def analyse_target_types(self, env):
2099 self.analyse_types(env)
2100 # when assigning, we must accept any Python type
2101 if self.type.is_pyobject:
2102 self.type = py_object_type
2104 def analyse_types(self, env):
2105 self.base.analyse_types(env)
2106 if self.start:
2107 self.start.analyse_types(env)
2108 if self.stop:
2109 self.stop.analyse_types(env)
2110 base_type = self.base.type
2111 if base_type.is_string:
2112 self.type = bytes_type
2113 elif base_type.is_array or base_type.is_ptr:
2114 # we need a ptr type here instead of an array type, as
2115 # array types can result in invalid type casts in the C
2116 # code
2117 self.type = PyrexTypes.CPtrType(base_type.base_type)
2118 else:
2119 self.base = self.base.coerce_to_pyobject(env)
2120 self.type = py_object_type
2121 if base_type.is_builtin_type:
2122 # slicing builtin types returns something of the same type
2123 self.type = base_type
2124 c_int = PyrexTypes.c_py_ssize_t_type
2125 if self.start:
2126 self.start = self.start.coerce_to(c_int, env)
2127 if self.stop:
2128 self.stop = self.stop.coerce_to(c_int, env)
2129 self.is_temp = 1
2131 nogil_check = Node.gil_error
2132 gil_message = "Slicing Python object"
2134 def generate_result_code(self, code):
2135 if not self.type.is_pyobject:
2136 error(self.pos,
2137 "Slicing is not currently supported for '%s'." % self.type)
2138 return
2139 if self.base.type.is_string:
2140 if self.stop is None:
2141 code.putln(
2142 "%s = __Pyx_PyBytes_FromString(%s + %s); %s" % (
2143 self.result(),
2144 self.base.result(),
2145 self.start_code(),
2146 code.error_goto_if_null(self.result(), self.pos)))
2147 else:
2148 code.putln(
2149 "%s = __Pyx_PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2150 self.result(),
2151 self.base.result(),
2152 self.start_code(),
2153 self.stop_code(),
2154 self.start_code(),
2155 code.error_goto_if_null(self.result(), self.pos)))
2156 else:
2157 code.putln(
2158 "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
2159 self.result(),
2160 self.base.py_result(),
2161 self.start_code(),
2162 self.stop_code(),
2163 code.error_goto_if_null(self.result(), self.pos)))
2164 code.put_gotref(self.py_result())
2166 def generate_assignment_code(self, rhs, code):
2167 self.generate_subexpr_evaluation_code(code)
2168 if self.type.is_pyobject:
2169 code.put_error_if_neg(self.pos,
2170 "PySequence_SetSlice(%s, %s, %s, %s)" % (
2171 self.base.py_result(),
2172 self.start_code(),
2173 self.stop_code(),
2174 rhs.result()))
2175 else:
2176 start_offset = ''
2177 if self.start:
2178 start_offset = self.start_code()
2179 if start_offset == '0':
2180 start_offset = ''
2181 else:
2182 start_offset += '+'
2183 if rhs.type.is_array:
2184 array_length = rhs.type.size
2185 self.generate_slice_guard_code(code, array_length)
2186 else:
2187 error(self.pos,
2188 "Slice assignments from pointers are not yet supported.")
2189 # FIXME: fix the array size according to start/stop
2190 array_length = self.base.type.size
2191 for i in range(array_length):
2192 code.putln("%s[%s%s] = %s[%d];" % (
2193 self.base.result(), start_offset, i,
2194 rhs.result(), i))
2195 self.generate_subexpr_disposal_code(code)
2196 self.free_subexpr_temps(code)
2197 rhs.generate_disposal_code(code)
2198 rhs.free_temps(code)
2200 def generate_deletion_code(self, code):
2201 if not self.base.type.is_pyobject:
2202 error(self.pos,
2203 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2204 return
2205 self.generate_subexpr_evaluation_code(code)
2206 code.put_error_if_neg(self.pos,
2207 "PySequence_DelSlice(%s, %s, %s)" % (
2208 self.base.py_result(),
2209 self.start_code(),
2210 self.stop_code()))
2211 self.generate_subexpr_disposal_code(code)
2213 def generate_slice_guard_code(self, code, target_size):
2214 if not self.base.type.is_array:
2215 return
2216 slice_size = self.base.type.size
2217 start = stop = None
2218 if self.stop:
2219 stop = self.stop.result()
2220 try:
2221 stop = int(stop)
2222 if stop < 0:
2223 slice_size = self.base.type.size + stop
2224 else:
2225 slice_size = stop
2226 stop = None
2227 except ValueError:
2228 pass
2229 if self.start:
2230 start = self.start.result()
2231 try:
2232 start = int(start)
2233 if start < 0:
2234 start = self.base.type.size + start
2235 slice_size -= start
2236 start = None
2237 except ValueError:
2238 pass
2239 check = None
2240 if slice_size < 0:
2241 if target_size > 0:
2242 error(self.pos, "Assignment to empty slice.")
2243 elif start is None and stop is None:
2244 # we know the exact slice length
2245 if target_size != slice_size:
2246 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2247 slice_size, target_size))
2248 elif start is not None:
2249 if stop is None:
2250 stop = slice_size
2251 check = "(%s)-(%s)" % (stop, start)
2252 else: # stop is not None:
2253 check = stop
2254 if check:
2255 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2256 code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%"PY_FORMAT_SIZE_T"d, got %%"PY_FORMAT_SIZE_T"d", (Py_ssize_t)%d, (Py_ssize_t)(%s));' % (
2257 target_size, check))
2258 code.putln(code.error_goto(self.pos))
2259 code.putln("}")
2261 def start_code(self):
2262 if self.start:
2263 return self.start.result()
2264 else:
2265 return "0"
2267 def stop_code(self):
2268 if self.stop:
2269 return self.stop.result()
2270 elif self.base.type.is_array:
2271 return self.base.type.size
2272 else:
2273 return "PY_SSIZE_T_MAX"
2275 def calculate_result_code(self):
2276 # self.result() is not used, but this method must exist
2277 return "<unused>"
2280 class SliceNode(ExprNode):
2281 # start:stop:step in subscript list
2283 # start ExprNode
2284 # stop ExprNode
2285 # step ExprNode
2287 type = py_object_type
2288 is_temp = 1
2290 def calculate_constant_result(self):
2291 self.constant_result = self.base.constant_result[
2292 self.start.constant_result : \
2293 self.stop.constant_result : \
2294 self.step.constant_result]
2296 def compile_time_value(self, denv):
2297 start = self.start.compile_time_value(denv)
2298 if self.stop is None:
2299 stop = None
2300 else:
2301 stop = self.stop.compile_time_value(denv)
2302 if self.step is None:
2303 step = None
2304 else:
2305 step = self.step.compile_time_value(denv)
2306 try:
2307 return slice(start, stop, step)
2308 except Exception, e:
2309 self.compile_time_value_error(e)
2311 subexprs = ['start', 'stop', 'step']
2313 def analyse_types(self, env):
2314 self.start.analyse_types(env)
2315 self.stop.analyse_types(env)
2316 self.step.analyse_types(env)
2317 self.start = self.start.coerce_to_pyobject(env)
2318 self.stop = self.stop.coerce_to_pyobject(env)
2319 self.step = self.step.coerce_to_pyobject(env)
2321 gil_message = "Constructing Python slice object"
2323 def generate_result_code(self, code):
2324 code.putln(
2325 "%s = PySlice_New(%s, %s, %s); %s" % (
2326 self.result(),
2327 self.start.py_result(),
2328 self.stop.py_result(),
2329 self.step.py_result(),
2330 code.error_goto_if_null(self.result(), self.pos)))
2331 code.put_gotref(self.py_result())
2334 class CallNode(ExprNode):
2336 def analyse_as_type_constructor(self, env):
2337 type = self.function.analyse_as_type(env)
2338 if type and type.is_struct_or_union:
2339 args, kwds = self.explicit_args_kwds()
2340 items = []
2341 for arg, member in zip(args, type.scope.var_entries):
2342 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2343 if kwds:
2344 items += kwds.key_value_pairs
2345 self.key_value_pairs = items
2346 self.__class__ = DictNode
2347 self.analyse_types(env)
2348 self.coerce_to(type, env)
2349 return True
2351 def nogil_check(self, env):
2352 func_type = self.function_type()
2353 if func_type.is_pyobject:
2354 self.gil_error()
2355 elif not getattr(func_type, 'nogil', False):
2356 self.gil_error()
2358 gil_message = "Calling gil-requiring function"
2361 class SimpleCallNode(CallNode):
2362 # Function call without keyword, * or ** args.
2364 # function ExprNode
2365 # args [ExprNode]
2366 # arg_tuple ExprNode or None used internally
2367 # self ExprNode or None used internally
2368 # coerced_self ExprNode or None used internally
2369 # wrapper_call bool used internally
2370 # has_optional_args bool used internally
2372 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2374 self = None
2375 coerced_self = None
2376 arg_tuple = None
2377 wrapper_call = False
2378 has_optional_args = False
2380 def compile_time_value(self, denv):
2381 function = self.function.compile_time_value(denv)
2382 args = [arg.compile_time_value(denv) for arg in self.args]
2383 try:
2384 return function(*args)
2385 except Exception, e:
2386 self.compile_time_value_error(e)
2388 def type_dependencies(self, env):
2389 # TODO: Update when Danilo's C++ code merged in to handle the
2390 # the case of function overloading.
2391 return self.function.type_dependencies(env)
2393 def infer_type(self, env):
2394 func_type = self.function.infer_type(env)
2395 if func_type.is_ptr:
2396 func_type = func_type.base_type
2397 if func_type.is_cfunction:
2398 return func_type.return_type
2399 else:
2400 return py_object_type
2402 def analyse_as_type(self, env):
2403 attr = self.function.as_cython_attribute()
2404 if attr == 'pointer':
2405 if len(self.args) != 1:
2406 error(self.args.pos, "only one type allowed.")
2407 else:
2408 type = self.args[0].analyse_as_type(env)
2409 if not type:
2410 error(self.args[0].pos, "Unknown type")
2411 else:
2412 return PyrexTypes.CPtrType(type)
2414 def explicit_args_kwds(self):
2415 return self.args, None
2417 def analyse_types(self, env):
2418 if self.analyse_as_type_constructor(env):
2419 return
2420 function = self.function
2421 function.is_called = 1
2422 self.function.analyse_types(env)
2423 if function.is_attribute and function.entry and function.entry.is_cmethod:
2424 # Take ownership of the object from which the attribute
2425 # was obtained, because we need to pass it as 'self'.
2426 self.self = function.obj
2427 function.obj = CloneNode(self.self)
2428 func_type = self.function_type()
2429 if func_type.is_pyobject:
2430 self.arg_tuple = TupleNode(self.pos, args = self.args)
2431 self.arg_tuple.analyse_types(env)
2432 self.args = None
2433 if function.is_name and function.type_entry:
2434 # We are calling an extension type constructor. As
2435 # long as we do not support __new__(), the result type
2436 # is clear
2437 self.type = function.type_entry.type
2438 self.result_ctype = py_object_type
2439 else:
2440 self.type = py_object_type
2441 self.is_temp = 1
2442 else:
2443 for arg in self.args:
2444 arg.analyse_types(env)
2445 if self.self and func_type.args:
2446 # Coerce 'self' to the type expected by the method.
2447 expected_type = func_type.args[0].type
2448 self.coerced_self = CloneNode(self.self).coerce_to(
2449 expected_type, env)
2450 # Insert coerced 'self' argument into argument list.
2451 self.args.insert(0, self.coerced_self)
2452 self.analyse_c_function_call(env)
2454 def function_type(self):
2455 # Return the type of the function being called, coercing a function
2456 # pointer to a function if necessary.
2457 func_type = self.function.type
2458 if func_type.is_ptr:
2459 func_type = func_type.base_type
2460 return func_type
2462 def analyse_c_function_call(self, env):
2463 func_type = self.function_type()
2464 # Check function type
2465 if not func_type.is_cfunction:
2466 if not func_type.is_error:
2467 error(self.pos, "Calling non-function type '%s'" %
2468 func_type)
2469 self.type = PyrexTypes.error_type
2470 self.result_code = "<error>"
2471 return
2472 # Check no. of args
2473 max_nargs = len(func_type.args)
2474 expected_nargs = max_nargs - func_type.optional_arg_count
2475 actual_nargs = len(self.args)
2476 if actual_nargs < expected_nargs \
2477 or (not func_type.has_varargs and actual_nargs > max_nargs):
2478 expected_str = str(expected_nargs)
2479 if func_type.has_varargs:
2480 expected_str = "at least " + expected_str
2481 elif func_type.optional_arg_count:
2482 if actual_nargs < max_nargs:
2483 expected_str = "at least " + expected_str
2484 else:
2485 expected_str = "at most " + str(max_nargs)
2486 error(self.pos,
2487 "Call with wrong number of arguments (expected %s, got %s)"
2488 % (expected_str, actual_nargs))
2489 self.args = None
2490 self.type = PyrexTypes.error_type
2491 self.result_code = "<error>"
2492 return
2493 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2494 self.has_optional_args = 1
2495 self.is_temp = 1
2496 # Coerce arguments
2497 for i in range(min(max_nargs, actual_nargs)):
2498 formal_type = func_type.args[i].type
2499 self.args[i] = self.args[i].coerce_to(formal_type, env)
2500 for i in range(max_nargs, actual_nargs):
2501 if self.args[i].type.is_pyobject:
2502 error(self.args[i].pos,
2503 "Python object cannot be passed as a varargs parameter")
2504 # Calc result type and code fragment
2505 self.type = func_type.return_type
2506 if self.type.is_pyobject:
2507 self.result_ctype = py_object_type
2508 self.is_temp = 1
2509 elif func_type.exception_value is not None \
2510 or func_type.exception_check:
2511 self.is_temp = 1
2512 # C++ exception handler
2513 if func_type.exception_check == '+':
2514 if func_type.exception_value is None:
2515 env.use_utility_code(cpp_exception_utility_code)
2517 def calculate_result_code(self):
2518 return self.c_call_code()
2520 def c_call_code(self):
2521 func_type = self.function_type()
2522 if self.args is None or not func_type.is_cfunction:
2523 return "<error>"
2524 formal_args = func_type.args
2525 arg_list_code = []
2526 args = zip(formal_args, self.args)
2527 max_nargs = len(func_type.args)
2528 expected_nargs = max_nargs - func_type.optional_arg_count
2529 actual_nargs = len(self.args)
2530 for formal_arg, actual_arg in args[:expected_nargs]:
2531 arg_code = actual_arg.result_as(formal_arg.type)
2532 arg_list_code.append(arg_code)
2534 if func_type.is_overridable:
2535 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2537 if func_type.optional_arg_count:
2538 if expected_nargs == actual_nargs:
2539 optional_args = 'NULL'
2540 else:
2541 optional_args = "&%s" % self.opt_arg_struct
2542 arg_list_code.append(optional_args)
2544 for actual_arg in self.args[len(formal_args):]:
2545 arg_list_code.append(actual_arg.result())
2546 result = "%s(%s)" % (self.function.result(),
2547 ', '.join(arg_list_code))
2548 return result
2550 def generate_result_code(self, code):
2551 func_type = self.function_type()
2552 if func_type.is_pyobject:
2553 arg_code = self.arg_tuple.py_result()
2554 code.putln(
2555 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2556 self.result(),
2557 self.function.py_result(),
2558 arg_code,
2559 code.error_goto_if_null(self.result(), self.pos)))
2560 code.put_gotref(self.py_result())
2561 elif func_type.is_cfunction:
2562 if self.has_optional_args:
2563 actual_nargs = len(self.args)
2564 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2565 self.opt_arg_struct = code.funcstate.allocate_temp(
2566 func_type.op_arg_struct.base_type, manage_ref=True)
2567 code.putln("%s.%s = %s;" % (
2568 self.opt_arg_struct,
2569 Naming.pyrex_prefix + "n",
2570 len(self.args) - expected_nargs))
2571 args = zip(func_type.args, self.args)
2572 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2573 code.putln("%s.%s = %s;" % (
2574 self.opt_arg_struct,
2575 func_type.opt_arg_cname(formal_arg.name),
2576 actual_arg.result_as(formal_arg.type)))
2577 exc_checks = []
2578 if self.type.is_pyobject:
2579 exc_checks.append("!%s" % self.result())
2580 else:
2581 exc_val = func_type.exception_value
2582 exc_check = func_type.exception_check
2583 if exc_val is not None:
2584 exc_checks.append("%s == %s" % (self.result(), exc_val))
2585 if exc_check:
2586 exc_checks.append("PyErr_Occurred()")
2587 if self.is_temp or exc_checks:
2588 rhs = self.c_call_code()
2589 if self.result():
2590 lhs = "%s = " % self.result()
2591 if self.is_temp and self.type.is_pyobject:
2592 #return_type = self.type # func_type.return_type
2593 #print "SimpleCallNode.generate_result_code: casting", rhs, \
2594 # "from", return_type, "to pyobject" ###
2595 rhs = typecast(py_object_type, self.type, rhs)
2596 else:
2597 lhs = ""
2598 if func_type.exception_check == '+':
2599 if func_type.exception_value is None:
2600 raise_py_exception = "__Pyx_CppExn2PyErr()"
2601 elif func_type.exception_value.type.is_pyobject:
2602 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
2603 func_type.exception_value.entry.cname,
2604 func_type.exception_value.entry.cname)
2605 else:
2606 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
2607 code.putln(
2608 "try {%s%s;} catch(...) {%s; %s}" % (
2609 lhs,
2610 rhs,
2611 raise_py_exception,
2612 code.error_goto(self.pos)))
2613 else:
2614 if exc_checks:
2615 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
2616 else:
2617 goto_error = ""
2618 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
2619 if self.type.is_pyobject and self.result():
2620 code.put_gotref(self.py_result())
2621 if self.has_optional_args:
2622 code.funcstate.release_temp(self.opt_arg_struct)
2625 class PythonCapiFunctionNode(ExprNode):
2626 subexprs = []
2627 def __init__(self, pos, name, func_type, utility_code = None):
2628 self.pos = pos
2629 self.name = name
2630 self.type = func_type
2631 self.utility_code = utility_code
2633 def generate_result_code(self, code):
2634 if self.utility_code:
2635 code.globalstate.use_utility_code(self.utility_code)
2637 def calculate_result_code(self):
2638 return self.name
2640 class PythonCapiCallNode(SimpleCallNode):
2641 # Python C-API Function call (only created in transforms)
2643 def __init__(self, pos, function_name, func_type,
2644 utility_code = None, **kwargs):
2645 self.type = func_type.return_type
2646 self.result_ctype = self.type
2647 self.function = PythonCapiFunctionNode(
2648 pos, function_name, func_type,
2649 utility_code = utility_code)
2650 # call this last so that we can override the constructed
2651 # attributes above with explicit keyword arguments if required
2652 SimpleCallNode.__init__(self, pos, **kwargs)
2655 class GeneralCallNode(CallNode):
2656 # General Python function call, including keyword,
2657 # * and ** arguments.
2659 # function ExprNode
2660 # positional_args ExprNode Tuple of positional arguments
2661 # keyword_args ExprNode or None Dict of keyword arguments
2662 # starstar_arg ExprNode or None Dict of extra keyword args
2664 type = py_object_type
2666 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
2668 nogil_check = Node.gil_error
2670 def compile_time_value(self, denv):
2671 function = self.function.compile_time_value(denv)
2672 positional_args = self.positional_args.compile_time_value(denv)
2673 keyword_args = self.keyword_args.compile_time_value(denv)
2674 starstar_arg = self.starstar_arg.compile_time_value(denv)
2675 try:
2676 keyword_args.update(starstar_arg)
2677 return function(*positional_args, **keyword_args)
2678 except Exception, e:
2679 self.compile_time_value_error(e)
2681 def explicit_args_kwds(self):
2682 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
2683 raise PostParseError(self.pos,
2684 'Compile-time keyword arguments must be explicit.')
2685 return self.positional_args.args, self.keyword_args
2687 def analyse_types(self, env):
2688 if self.analyse_as_type_constructor(env):
2689 return
2690 self.function.analyse_types(env)
2691 self.positional_args.analyse_types(env)
2692 if self.keyword_args:
2693 self.keyword_args.analyse_types(env)
2694 if self.starstar_arg:
2695 self.starstar_arg.analyse_types(env)
2696 if not self.function.type.is_pyobject:
2697 if self.function.type.is_error:
2698 self.type = error_type
2699 return error_type
2700 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
2701 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
2702 else:
2703 self.function = self.function.coerce_to_pyobject(env)
2704 self.positional_args = \
2705 self.positional_args.coerce_to_pyobject(env)
2706 if self.starstar_arg:
2707 self.starstar_arg = \
2708 self.starstar_arg.coerce_to_pyobject(env)
2709 function = self.function
2710 if function.is_name and function.type_entry:
2711 # We are calling an extension type constructor. As long
2712 # as we do not support __new__(), the result type is clear
2713 self.type = function.type_entry.type
2714 self.result_ctype = py_object_type
2715 else:
2716 self.type = py_object_type
2717 self.is_temp = 1
2719 def generate_result_code(self, code):
2720 if self.type.is_error: return
2721 if self.keyword_args and self.starstar_arg:
2722 code.put_error_if_neg(self.pos,
2723 "PyDict_Update(%s, %s)" % (
2724 self.keyword_args.py_result(),
2725 self.starstar_arg.py_result()))
2726 keyword_code = self.keyword_args.py_result()
2727 elif self.keyword_args:
2728 keyword_code = self.keyword_args.py_result()
2729 elif self.starstar_arg:
2730 keyword_code = self.starstar_arg.py_result()
2731 else:
2732 keyword_code = None
2733 if not keyword_code:
2734 call_code = "PyObject_Call(%s, %s, NULL)" % (
2735 self.function.py_result(),
2736 self.positional_args.py_result())
2737 else:
2738 call_code = "PyEval_CallObjectWithKeywords(%s, %s, %s)" % (
2739 self.function.py_result(),
2740 self.positional_args.py_result(),
2741 keyword_code)
2742 code.putln(
2743 "%s = %s; %s" % (
2744 self.result(),
2745 call_code,
2746 code.error_goto_if_null(self.result(), self.pos)))
2747 code.put_gotref(self.py_result())
2750 class AsTupleNode(ExprNode):
2751 # Convert argument to tuple. Used for normalising
2752 # the * argument of a function call.
2754 # arg ExprNode
2756 subexprs = ['arg']
2758 def calculate_constant_result(self):
2759 self.constant_result = tuple(self.base.constant_result)
2761 def compile_time_value(self, denv):
2762 arg = self.arg.compile_time_value(denv)
2763 try:
2764 return tuple(arg)
2765 except Exception, e:
2766 self.compile_time_value_error(e)
2768 def analyse_types(self, env):
2769 self.arg.analyse_types(env)
2770 self.arg = self.arg.coerce_to_pyobject(env)
2771 self.type = tuple_type
2772 self.is_temp = 1
2774 nogil_check = Node.gil_error
2775 gil_message = "Constructing Python tuple"
2777 def generate_result_code(self, code):
2778 code.putln(
2779 "%s = PySequence_Tuple(%s); %s" % (
2780 self.result(),
2781 self.arg.py_result(),
2782 code.error_goto_if_null(self.result(), self.pos)))
2783 code.put_gotref(self.py_result())
2786 class AttributeNode(ExprNode):
2787 # obj.attribute
2789 # obj ExprNode
2790 # attribute string
2791 # needs_none_check boolean Used if obj is an extension type.
2792 # If set to True, it is known that the type is not None.
2794 # Used internally:
2796 # is_py_attr boolean Is a Python getattr operation
2797 # member string C name of struct member
2798 # is_called boolean Function call is being done on result
2799 # entry Entry Symbol table entry of attribute
2801 is_attribute = 1
2802 subexprs = ['obj']
2804 type = PyrexTypes.error_type
2805 entry = None
2806 is_called = 0
2807 needs_none_check = True
2809 def as_cython_attribute(self):
2810 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
2811 return self.attribute
2813 def coerce_to(self, dst_type, env):
2814 # If coercing to a generic pyobject and this is a cpdef function
2815 # we can create the corresponding attribute
2816 if dst_type is py_object_type:
2817 entry = self.entry
2818 if entry and entry.is_cfunction and entry.as_variable:
2819 # must be a cpdef function
2820 self.is_temp = 1
2821 self.entry = entry.as_variable
2822 self.analyse_as_python_attribute(env)
2823 return self
2824 return ExprNode.coerce_to(self, dst_type, env)
2826 def calculate_constant_result(self):
2827 attr = self.attribute
2828 if attr.startswith("__") and attr.endswith("__"):
2829 return
2830 self.constant_result = getattr(self.obj.constant_result, attr)
2832 def compile_time_value(self, denv):
2833 attr = self.attribute
2834 if attr.startswith("__") and attr.endswith("__"):
2835 error(self.pos,
2836 "Invalid attribute name '%s' in compile-time expression" % attr)
2837 return None
2838 obj = self.obj.compile_time_value(denv)
2839 try:
2840 return getattr(obj, attr)
2841 except Exception, e:
2842 self.compile_time_value_error(e)
2844 def type_dependencies(self, env):
2845 return self.obj.type_dependencies(env)
2847 def infer_type(self, env):
2848 if self.analyse_as_cimported_attribute(env, 0):
2849 return self.entry.type
2850 elif self.analyse_as_unbound_cmethod(env):
2851 return self.entry.type
2852 else:
2853 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
2854 return self.type
2856 def analyse_target_declaration(self, env):
2857 pass
2859 def analyse_target_types(self, env):
2860 self.analyse_types(env, target = 1)
2862 def analyse_types(self, env, target = 0):
2863 if self.analyse_as_cimported_attribute(env, target):
2864 return
2865 if not target and self.analyse_as_unbound_cmethod(env):
2866 return
2867 self.analyse_as_ordinary_attribute(env, target)
2869 def analyse_as_cimported_attribute(self, env, target):
2870 # Try to interpret this as a reference to an imported
2871 # C const, type, var or function. If successful, mutates
2872 # this node into a NameNode and returns 1, otherwise
2873 # returns 0.
2874 module_scope = self.obj.analyse_as_module(env)
2875 if module_scope:
2876 entry = module_scope.lookup_here(self.attribute)
2877 if entry and (
2878 entry.is_cglobal or entry.is_cfunction
2879 or entry.is_type or entry.is_const):
2880 self.mutate_into_name_node(env, entry, target)
2881 return 1
2882 return 0
2884 def analyse_as_unbound_cmethod(self, env):
2885 # Try to interpret this as a reference to an unbound
2886 # C method of an extension type. If successful, mutates
2887 # this node into a NameNode and returns 1, otherwise
2888 # returns 0.
2889 type = self.obj.analyse_as_extension_type(env)
2890 if type:
2891 entry = type.scope.lookup_here(self.attribute)
2892 if entry and entry.is_cmethod:
2893 # Create a temporary entry describing the C method
2894 # as an ordinary function.
2895 ubcm_entry = Symtab.Entry(entry.name,
2896 "%s->%s" % (type.vtabptr_cname, entry.cname),
2897 entry.type)
2898 ubcm_entry.is_cfunction = 1
2899 ubcm_entry.func_cname = entry.func_cname
2900 ubcm_entry.is_unbound_cmethod = 1
2901 self.mutate_into_name_node(env, ubcm_entry, None)
2902 return 1
2903 return 0
2905 def analyse_as_type(self, env):
2906 module_scope = self.obj.analyse_as_module(env)
2907 if module_scope:
2908 return module_scope.lookup_type(self.attribute)
2909 return None
2911 def analyse_as_extension_type(self, env):
2912 # Try to interpret this as a reference to an extension type
2913 # in a cimported module. Returns the extension type, or None.
2914 module_scope = self.obj.analyse_as_module(env)
2915 if module_scope:
2916 entry = module_scope.lookup_here(self.attribute)
2917 if entry and entry.is_type and entry.type.is_extension_type:
2918 return entry.type
2919 return None
2921 def analyse_as_module(self, env):
2922 # Try to interpret this as a reference to a cimported module
2923 # in another cimported module. Returns the module scope, or None.
2924 module_scope = self.obj.analyse_as_module(env)
2925 if module_scope:
2926 entry = module_scope.lookup_here(self.attribute)
2927 if entry and entry.as_module:
2928 return entry.as_module
2929 return None
2931 def mutate_into_name_node(self, env, entry, target):
2932 # Mutate this node into a NameNode and complete the
2933 # analyse_types phase.
2934 self.__class__ = NameNode
2935 self.name = self.attribute
2936 self.entry = entry
2937 del self.obj
2938 del self.attribute
2939 if target:
2940 NameNode.analyse_target_types(self, env)
2941 else:
2942 NameNode.analyse_rvalue_entry(self, env)
2944 def analyse_as_ordinary_attribute(self, env, target):
2945 self.obj.analyse_types(env)
2946 self.analyse_attribute(env)
2947 if self.entry and self.entry.is_cmethod and not self.is_called:
2948 # error(self.pos, "C method can only be called")
2949 pass
2950 ## Reference to C array turns into pointer to first element.
2951 #while self.type.is_array:
2952 # self.type = self.type.element_ptr_type()
2953 if self.is_py_attr:
2954 if not target:
2955 self.is_temp = 1
2956 self.result_ctype = py_object_type
2958 def analyse_attribute(self, env, obj_type = None):
2959 # Look up attribute and set self.type and self.member.
2960 self.is_py_attr = 0
2961 self.member = self.attribute
2962 if obj_type is None:
2963 if self.obj.type.is_string:
2964 self.obj = self.obj.coerce_to_pyobject(env)
2965 obj_type = self.obj.type
2966 else:
2967 if obj_type.is_string:
2968 obj_type = py_object_type
2969 if obj_type.is_ptr or obj_type.is_array:
2970 obj_type = obj_type.base_type
2971 self.op = "->"
2972 elif obj_type.is_extension_type:
2973 self.op = "->"
2974 else:
2975 self.op = "."
2976 if obj_type.has_attributes:
2977 entry = None
2978 if obj_type.attributes_known():
2979 entry = obj_type.scope.lookup_here(self.attribute)
2980 if entry and entry.is_member:
2981 entry = None
2982 else:
2983 error(self.pos,
2984 "Cannot select attribute of incomplete type '%s'"
2985 % obj_type)
2986 self.type = PyrexTypes.error_type
2987 return
2988 self.entry = entry
2989 if entry:
2990 if obj_type.is_extension_type and entry.name == "__weakref__":
2991 error(self.pos, "Illegal use of special attribute __weakref__")
2992 # methods need the normal attribute lookup
2993 # because they do not have struct entries
2994 if entry.is_variable or entry.is_cmethod:
2995 self.type = entry.type
2996 self.member = entry.cname
2997 return
2998 else:
2999 # If it's not a variable or C method, it must be a Python
3000 # method of an extension type, so we treat it like a Python
3001 # attribute.
3002 pass
3003 # If we get here, the base object is not a struct/union/extension
3004 # type, or it is an extension type and the attribute is either not
3005 # declared or is declared as a Python method. Treat it as a Python
3006 # attribute reference.
3007 self.analyse_as_python_attribute(env, obj_type)
3009 def analyse_as_python_attribute(self, env, obj_type = None):
3010 if obj_type is None:
3011 obj_type = self.obj.type
3012 self.member = self.attribute
3013 if obj_type.is_pyobject:
3014 self.type = py_object_type
3015 self.is_py_attr = 1
3016 else:
3017 if not obj_type.is_error:
3018 error(self.pos,
3019 "Object of type '%s' has no attribute '%s'" %
3020 (obj_type, self.attribute))
3022 def nogil_check(self, env):
3023 if self.is_py_attr:
3024 self.gil_error()
3026 gil_message = "Accessing Python attribute"
3028 def is_simple(self):
3029 if self.obj:
3030 return self.result_in_temp() or self.obj.is_simple()
3031 else:
3032 return NameNode.is_simple(self)
3034 def is_lvalue(self):
3035 if self.obj:
3036 return 1
3037 else:
3038 return NameNode.is_lvalue(self)
3040 def is_ephemeral(self):
3041 if self.obj:
3042 return self.obj.is_ephemeral()
3043 else:
3044 return NameNode.is_ephemeral(self)
3046 def calculate_result_code(self):
3047 #print "AttributeNode.calculate_result_code:", self.member ###
3048 #print "...obj node =", self.obj, "code", self.obj.result() ###
3049 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3050 obj = self.obj
3051 obj_code = obj.result_as(obj.type)
3052 #print "...obj_code =", obj_code ###
3053 if self.entry and self.entry.is_cmethod:
3054 if obj.type.is_extension_type:
3055 return "((struct %s *)%s%s%s)->%s" % (
3056 obj.type.vtabstruct_cname, obj_code, self.op,
3057 obj.type.vtabslot_cname, self.member)
3058 else:
3059 return self.member
3060 elif obj.type.is_complex:
3061 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3062 else:
3063 return "%s%s%s" % (obj_code, self.op, self.member)
3065 def generate_result_code(self, code):
3066 interned_attr_cname = code.intern_identifier(self.attribute)
3067 if self.is_py_attr:
3068 code.putln(
3069 '%s = PyObject_GetAttr(%s, %s); %s' % (
3070 self.result(),
3071 self.obj.py_result(),
3072 interned_attr_cname,
3073 code.error_goto_if_null(self.result(), self.pos)))
3074 code.put_gotref(self.py_result())
3075 else:
3076 # result_code contains what is needed, but we may need to insert
3077 # a check and raise an exception
3078 if (self.obj.type.is_extension_type
3079 and self.needs_none_check
3080 and code.globalstate.directives['nonecheck']):
3081 self.put_nonecheck(code)
3083 def generate_assignment_code(self, rhs, code):
3084 interned_attr_cname = code.intern_identifier(self.attribute)
3085 self.obj.generate_evaluation_code(code)
3086 if self.is_py_attr:
3087 code.put_error_if_neg(self.pos,
3088 'PyObject_SetAttr(%s, %s, %s)' % (
3089 self.obj.py_result(),
3090 interned_attr_cname,
3091 rhs.py_result()))
3092 rhs.generate_disposal_code(code)
3093 rhs.free_temps(code)
3094 else:
3095 if (self.obj.type.is_extension_type
3096 and self.needs_none_check
3097 and code.globalstate.directives['nonecheck']):
3098 self.put_nonecheck(code)
3100 select_code = self.result()
3101 if self.type.is_pyobject and self.use_managed_ref:
3102 rhs.make_owned_reference(code)
3103 code.put_giveref(rhs.py_result())
3104 code.put_gotref(select_code)
3105 code.put_decref(select_code, self.ctype())
3106 code.putln(
3107 "%s = %s;" % (
3108 select_code,
3109 rhs.result_as(self.ctype())))
3110 #rhs.result()))
3111 rhs.generate_post_assignment_code(code)
3112 rhs.free_temps(code)
3113 self.obj.generate_disposal_code(code)
3114 self.obj.free_temps(code)
3116 def generate_deletion_code(self, code):
3117 interned_attr_cname = code.intern_identifier(self.attribute)
3118 self.obj.generate_evaluation_code(code)
3119 if self.is_py_attr:
3120 code.put_error_if_neg(self.pos,
3121 'PyObject_DelAttr(%s, %s)' % (
3122 self.obj.py_result(),
3123 interned_attr_cname))
3124 else:
3125 error(self.pos, "Cannot delete C attribute of extension type")
3126 self.obj.generate_disposal_code(code)
3127 self.obj.free_temps(code)
3129 def annotate(self, code):
3130 if self.is_py_attr:
3131 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3132 else:
3133 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3135 def put_nonecheck(self, code):
3136 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3137 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3138 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3139 code.putln(code.error_goto(self.pos))
3140 code.putln("}")
3143 #-------------------------------------------------------------------
3145 # Constructor nodes
3147 #-------------------------------------------------------------------
3149 class StarredTargetNode(ExprNode):
3150 # A starred expression like "*a"
3152 # This is only allowed in sequence assignment targets such as
3154 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3156 # and will be removed during type analysis (or generate an error
3157 # if it's found at unexpected places).
3159 # target ExprNode
3161 subexprs = ['target']
3162 is_starred = 1
3163 type = py_object_type
3164 is_temp = 1
3166 def __init__(self, pos, target):
3167 self.pos = pos
3168 self.target = target
3170 def analyse_declarations(self, env):
3171 error(self.pos, "can use starred expression only as assignment target")
3172 self.target.analyse_declarations(env)
3174 def analyse_types(self, env):
3175 error(self.pos, "can use starred expression only as assignment target")
3176 self.target.analyse_types(env)
3177 self.type = self.target.type
3179 def analyse_target_declaration(self, env):
3180 self.target.analyse_target_declaration(env)
3182 def analyse_target_types(self, env):
3183 self.target.analyse_target_types(env)
3184 self.type = self.target.type
3186 def calculate_result_code(self):
3187 return ""
3189 def generate_result_code(self, code):
3190 pass
3193 class SequenceNode(ExprNode):
3194 # Base class for list and tuple constructor nodes.
3195 # Contains common code for performing sequence unpacking.
3197 # args [ExprNode]
3198 # iterator ExprNode
3199 # unpacked_items [ExprNode] or None
3200 # coerced_unpacked_items [ExprNode] or None
3202 subexprs = ['args']
3204 is_sequence_constructor = 1
3205 unpacked_items = None
3207 def compile_time_value_list(self, denv):
3208 return [arg.compile_time_value(denv) for arg in self.args]
3210 def replace_starred_target_node(self):
3211 # replace a starred node in the targets by the contained expression
3212 self.starred_assignment = False
3213 args = []
3214 for arg in self.args:
3215 if arg.is_starred:
3216 if self.starred_assignment:
3217 error(arg.pos, "more than 1 starred expression in assignment")
3218 self.starred_assignment = True
3219 arg = arg.target
3220 arg.is_starred = True
3221 args.append(arg)
3222 self.args = args
3224 def analyse_target_declaration(self, env):
3225 self.replace_starred_target_node()
3226 for arg in self.args:
3227 arg.analyse_target_declaration(env)
3229 def analyse_types(self, env, skip_children=False):
3230 for i in range(len(self.args)):
3231 arg = self.args[i]
3232 if not skip_children: arg.analyse_types(env)
3233 self.args[i] = arg.coerce_to_pyobject(env)
3234 self.type = py_object_type
3235 self.is_temp = 1
3237 def analyse_target_types(self, env):
3238 self.iterator = PyTempNode(self.pos, env)
3239 self.unpacked_items = []
3240 self.coerced_unpacked_items = []
3241 for arg in self.args:
3242 arg.analyse_target_types(env)
3243 if arg.is_starred:
3244 if not arg.type.assignable_from(Builtin.list_type):
3245 error(arg.pos,
3246 "starred target must have Python object (list) type")
3247 if arg.type is py_object_type:
3248 arg.type = Builtin.list_type
3249 unpacked_item = PyTempNode(self.pos, env)
3250 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3251 self.unpacked_items.append(unpacked_item)
3252 self.coerced_unpacked_items.append(coerced_unpacked_item)
3253 self.type = py_object_type
3255 def generate_result_code(self, code):
3256 self.generate_operation_code(code)
3258 def generate_assignment_code(self, rhs, code):
3259 if self.starred_assignment:
3260 self.generate_starred_assignment_code(rhs, code)
3261 else:
3262 self.generate_parallel_assignment_code(rhs, code)
3264 for item in self.unpacked_items:
3265 item.release(code)
3266 rhs.free_temps(code)
3268 def generate_parallel_assignment_code(self, rhs, code):
3269 # Need to work around the fact that generate_evaluation_code
3270 # allocates the temps in a rather hacky way -- the assignment
3271 # is evaluated twice, within each if-block.
3273 code.globalstate.use_utility_code(unpacking_utility_code)
3275 if rhs.type is tuple_type:
3276 tuple_check = "likely(%s != Py_None)"
3277 else:
3278 tuple_check = "PyTuple_CheckExact(%s)"
3279 code.putln(
3280 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3281 tuple_check % rhs.py_result(),
3282 rhs.py_result(),
3283 len(self.args)))
3284 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3285 for item in self.unpacked_items:
3286 item.allocate(code)
3287 for i in range(len(self.args)):
3288 item = self.unpacked_items[i]
3289 code.put(
3290 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3291 item.result(),
3292 i))
3293 code.put_incref(item.result(), item.ctype())
3294 value_node = self.coerced_unpacked_items[i]
3295 value_node.generate_evaluation_code(code)
3296 rhs.generate_disposal_code(code)
3298 for i in range(len(self.args)):
3299 self.args[i].generate_assignment_code(
3300 self.coerced_unpacked_items[i], code)
3302 code.putln("} else {")
3304 if rhs.type is tuple_type:
3305 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3306 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3307 rhs.py_result(), len(self.args)))
3308 code.putln(code.error_goto(self.pos))
3309 else:
3310 self.iterator.allocate(code)
3311 code.putln(
3312 "%s = PyObject_GetIter(%s); %s" % (
3313 self.iterator.result(),
3314 rhs.py_result(),
3315 code.error_goto_if_null(self.iterator.result(), self.pos)))
3316 code.put_gotref(self.iterator.py_result())
3317 rhs.generate_disposal_code(code)
3318 for i in range(len(self.args)):
3319 item = self.unpacked_items[i]
3320 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3321 self.iterator.py_result(), i)
3322 code.putln(
3323 "%s = %s; %s" % (
3324 item.result(),
3325 typecast(item.ctype(), py_object_type, unpack_code),
3326 code.error_goto_if_null(item.result(), self.pos)))
3327 code.put_gotref(item.py_result())
3328 value_node = self.coerced_unpacked_items[i]
3329 value_node.generate_evaluation_code(code)
3330 code.put_error_if_neg(self.pos,
3331 "__Pyx_EndUnpack(%s)" % (
3332 self.iterator.py_result()))
3333 if debug_disposal_code:
3334 print("UnpackNode.generate_assignment_code:")
3335 print("...generating disposal code for %s" % self.iterator)
3336 self.iterator.generate_disposal_code(code)
3337 self.iterator.free_temps(code)
3338 self.iterator.release(code)
3340 for i in range(len(self.args)):
3341 self.args[i].generate_assignment_code(
3342 self.coerced_unpacked_items[i], code)
3344 code.putln("}")
3346 def generate_starred_assignment_code(self, rhs, code):
3347 code.globalstate.use_utility_code(unpacking_utility_code)
3349 for i, arg in enumerate(self.args):
3350 if arg.is_starred:
3351 starred_target = self.unpacked_items[i]
3352 fixed_args_left = self.args[:i]
3353 fixed_args_right = self.args[i+1:]
3354 break
3356 self.iterator.allocate(code)
3357 code.putln(
3358 "%s = PyObject_GetIter(%s); %s" % (
3359 self.iterator.result(),
3360 rhs.py_result(),
3361 code.error_goto_if_null(self.iterator.result(), self.pos)))
3362 code.put_gotref(self.iterator.py_result())
3363 rhs.generate_disposal_code(code)
3365 for item in self.unpacked_items:
3366 item.allocate(code)
3367 for i in range(len(fixed_args_left)):
3368 item = self.unpacked_items[i]
3369 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3370 self.iterator.py_result(), i)
3371 code.putln(
3372 "%s = %s; %s" % (
3373 item.result(),
3374 typecast(item.ctype(), py_object_type, unpack_code),
3375 code.error_goto_if_null(item.result(), self.pos)))
3376 code.put_gotref(item.py_result())
3377 value_node = self.coerced_unpacked_items[i]
3378 value_node.generate_evaluation_code(code)
3380 target_list = starred_target.result()
3381 code.putln("%s = PySequence_List(%s); %s" % (
3382 target_list, self.iterator.py_result(),
3383 code.error_goto_if_null(target_list, self.pos)))
3384 code.put_gotref(target_list)
3385 if fixed_args_right:
3386 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3387 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3388 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3389 (target_list, len(unpacked_right_args))))
3390 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3391 len(fixed_args_left), target_list,
3392 code.error_goto(self.pos)))
3393 code.putln('}')
3394 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3395 self.coerced_unpacked_items[::-1])):
3396 code.putln(
3397 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3398 arg.py_result(),
3399 target_list, target_list))
3400 # resize the list the hard way
3401 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3402 code.put_gotref(arg.py_result())
3403 coerced_arg.generate_evaluation_code(code)
3405 self.iterator.generate_disposal_code(code)
3406 self.iterator.free_temps(code)
3407 self.iterator.release(code)
3409 for i in range(len(self.args)):
3410 self.args[i].generate_assignment_code(
3411 self.coerced_unpacked_items[i], code)
3413 def annotate(self, code):
3414 for arg in self.args:
3415 arg.annotate(code)
3416 if self.unpacked_items:
3417 for arg in self.unpacked_items:
3418 arg.annotate(code)
3419 for arg in self.coerced_unpacked_items:
3420 arg.annotate(code)
3423 class TupleNode(SequenceNode):
3424 # Tuple constructor.
3426 type = tuple_type
3428 gil_message = "Constructing Python tuple"
3430 def analyse_types(self, env, skip_children=False):
3431 if len(self.args) == 0:
3432 self.is_temp = 0
3433 self.is_literal = 1
3434 else:
3435 SequenceNode.analyse_types(self, env, skip_children)
3437 def calculate_result_code(self):
3438 if len(self.args) > 0:
3439 error(self.pos, "Positive length tuples must be constructed.")
3440 else:
3441 return Naming.empty_tuple
3443 def calculate_constant_result(self):
3444 self.constant_result = tuple([
3445 arg.constant_result for arg in self.args])
3447 def compile_time_value(self, denv):
3448 values = self.compile_time_value_list(denv)
3449 try:
3450 return tuple(values)
3451 except Exception, e:
3452 self.compile_time_value_error(e)
3454 def generate_operation_code(self, code):
3455 if len(self.args) == 0:
3456 # result_code is Naming.empty_tuple
3457 return
3458 code.putln(
3459 "%s = PyTuple_New(%s); %s" % (
3460 self.result(),
3461 len(self.args),
3462 code.error_goto_if_null(self.result(), self.pos)))
3463 code.put_gotref(self.py_result())
3464 for i in range(len(self.args)):
3465 arg = self.args[i]
3466 if not arg.result_in_temp():
3467 code.put_incref(arg.result(), arg.ctype())
3468 code.putln(
3469 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3470 self.result(),
3471 i,
3472 arg.py_result()))
3473 code.put_giveref(arg.py_result())
3475 def generate_subexpr_disposal_code(self, code):
3476 # We call generate_post_assignment_code here instead
3477 # of generate_disposal_code, because values were stored
3478 # in the tuple using a reference-stealing operation.
3479 for arg in self.args:
3480 arg.generate_post_assignment_code(code)
3481 # Should NOT call free_temps -- this is invoked by the default
3482 # generate_evaluation_code which will do that.
3485 class ListNode(SequenceNode):
3486 # List constructor.
3488 # obj_conversion_errors [PyrexError] used internally
3489 # orignial_args [ExprNode] used internally
3491 obj_conversion_errors = []
3493 gil_message = "Constructing Python list"
3495 def type_dependencies(self, env):
3496 return ()
3498 def infer_type(self, env):
3499 # TOOD: Infer non-object list arrays.
3500 return list_type
3502 def analyse_expressions(self, env):
3503 SequenceNode.analyse_expressions(self, env)
3504 self.coerce_to_pyobject(env)
3506 def analyse_types(self, env):
3507 hold_errors()
3508 self.original_args = list(self.args)
3509 SequenceNode.analyse_types(self, env)
3510 self.type = list_type
3511 self.obj_conversion_errors = held_errors()
3512 release_errors(ignore=True)
3514 def coerce_to(self, dst_type, env):
3515 if dst_type.is_pyobject:
3516 for err in self.obj_conversion_errors:
3517 report_error(err)
3518 self.obj_conversion_errors = []
3519 if not self.type.subtype_of(dst_type):
3520 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3521 elif dst_type.is_ptr:
3522 base_type = dst_type.base_type
3523 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3524 for i in range(len(self.original_args)):
3525 arg = self.args[i]
3526 if isinstance(arg, CoerceToPyTypeNode):
3527 arg = arg.arg
3528 self.args[i] = arg.coerce_to(base_type, env)
3529 elif dst_type.is_struct:
3530 if len(self.args) > len(dst_type.scope.var_entries):
3531 error(self.pos, "Too may members for '%s'" % dst_type)
3532 else:
3533 if len(self.args) < len(dst_type.scope.var_entries):
3534 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3535 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3536 if isinstance(arg, CoerceToPyTypeNode):
3537 arg = arg.arg
3538 self.args[i] = arg.coerce_to(member.type, env)
3539 self.type = dst_type
3540 else:
3541 self.type = error_type
3542 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3543 return self
3545 def release_temp(self, env):
3546 if self.type.is_array:
3547 # To be valid C++, we must allocate the memory on the stack
3548 # manually and be sure not to reuse it for something else.
3549 pass
3550 else:
3551 SequenceNode.release_temp(self, env)
3553 def calculate_constant_result(self):
3554 self.constant_result = [
3555 arg.constant_result for arg in self.args]
3557 def compile_time_value(self, denv):
3558 return self.compile_time_value_list(denv)
3560 def generate_operation_code(self, code):
3561 if self.type.is_pyobject:
3562 for err in self.obj_conversion_errors:
3563 report_error(err)
3564 code.putln("%s = PyList_New(%s); %s" %
3565 (self.result(),
3566 len(self.args),
3567 code.error_goto_if_null(self.result(), self.pos)))
3568 code.put_gotref(self.py_result())
3569 for i in range(len(self.args)):
3570 arg = self.args[i]
3571 #if not arg.is_temp:
3572 if not arg.result_in_temp():
3573 code.put_incref(arg.result(), arg.ctype())
3574 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
3575 (self.result(),
3576 i,
3577 arg.py_result()))
3578 code.put_giveref(arg.py_result())
3579 elif self.type.is_array:
3580 for i, arg in enumerate(self.args):
3581 code.putln("%s[%s] = %s;" % (
3582 self.result(),
3583 i,
3584 arg.result()))
3585 elif self.type.is_struct:
3586 for arg, member in zip(self.args, self.type.scope.var_entries):
3587 code.putln("%s.%s = %s;" % (
3588 self.result(),
3589 member.cname,
3590 arg.result()))
3591 else:
3592 raise InternalError("List type never specified")
3594 def generate_subexpr_disposal_code(self, code):
3595 # We call generate_post_assignment_code here instead
3596 # of generate_disposal_code, because values were stored
3597 # in the list using a reference-stealing operation.
3598 for arg in self.args:
3599 arg.generate_post_assignment_code(code)
3600 # Should NOT call free_temps -- this is invoked by the default
3601 # generate_evaluation_code which will do that.
3604 class ComprehensionNode(ExprNode):
3605 subexprs = ["target"]
3606 child_attrs = ["loop", "append"]
3608 def infer_type(self, env):
3609 return self.target.infer_type(env)
3611 def analyse_types(self, env):
3612 self.target.analyse_expressions(env)
3613 self.type = self.target.type
3614 self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop
3615 # We are analysing declarations to late.
3616 self.loop.target.analyse_target_declaration(env)
3617 env.infer_types()
3618 self.loop.analyse_declarations(env)
3619 self.loop.analyse_expressions(env)
3621 def calculate_result_code(self):
3622 return self.target.result()
3624 def generate_result_code(self, code):
3625 self.generate_operation_code(code)
3627 def generate_operation_code(self, code):
3628 self.loop.generate_execution_code(code)
3630 def annotate(self, code):
3631 self.loop.annotate(code)
3634 class ComprehensionAppendNode(ExprNode):
3635 # Need to be careful to avoid infinite recursion:
3636 # target must not be in child_attrs/subexprs
3637 subexprs = ['expr']
3639 type = PyrexTypes.c_int_type
3641 def analyse_types(self, env):
3642 self.expr.analyse_types(env)
3643 if not self.expr.type.is_pyobject:
3644 self.expr = self.expr.coerce_to_pyobject(env)
3645 self.is_temp = 1
3647 def generate_result_code(self, code):
3648 if self.target.type is list_type:
3649 function = "PyList_Append"
3650 elif self.target.type is set_type:
3651 function = "PySet_Add"
3652 else:
3653 raise InternalError(
3654 "Invalid type for comprehension node: %s" % self.target.type)
3656 code.putln("%s = %s(%s, (PyObject*)%s); %s" %
3657 (self.result(),
3658 function,
3659 self.target.result(),
3660 self.expr.result(),
3661 code.error_goto_if(self.result(), self.pos)))
3663 class DictComprehensionAppendNode(ComprehensionAppendNode):
3664 subexprs = ['key_expr', 'value_expr']
3666 def analyse_types(self, env):
3667 self.key_expr.analyse_types(env)
3668 if not self.key_expr.type.is_pyobject:
3669 self.key_expr = self.key_expr.coerce_to_pyobject(env)
3670 self.value_expr.analyse_types(env)
3671 if not self.value_expr.type.is_pyobject:
3672 self.value_expr = self.value_expr.coerce_to_pyobject(env)
3673 self.is_temp = 1
3675 def generate_result_code(self, code):
3676 code.putln("%s = PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s); %s" %
3677 (self.result(),
3678 self.target.result(),
3679 self.key_expr.result(),
3680 self.value_expr.result(),
3681 code.error_goto_if(self.result(), self.pos)))
3684 class SetNode(ExprNode):
3685 # Set constructor.
3687 type = set_type
3689 subexprs = ['args']
3691 gil_message = "Constructing Python set"
3693 def analyse_types(self, env):
3694 for i in range(len(self.args)):
3695 arg = self.args[i]
3696 arg.analyse_types(env)
3697 self.args[i] = arg.coerce_to_pyobject(env)
3698 self.type = set_type
3699 self.is_temp = 1
3701 def calculate_constant_result(self):
3702 self.constant_result = set([
3703 arg.constant_result for arg in self.args])
3705 def compile_time_value(self, denv):
3706 values = [arg.compile_time_value(denv) for arg in self.args]
3707 try:
3708 return set(values)
3709 except Exception, e:
3710 self.compile_time_value_error(e)
3712 def generate_evaluation_code(self, code):
3713 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
3714 self.allocate_temp_result(code)
3715 code.putln(
3716 "%s = PySet_New(0); %s" % (
3717 self.result(),
3718 code.error_goto_if_null(self.result(), self.pos)))
3719 code.put_gotref(self.py_result())
3720 for arg in self.args:
3721 arg.generate_evaluation_code(code)
3722 code.putln(
3723 code.error_goto_if_neg(
3724 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
3725 self.pos))
3726 arg.generate_disposal_code(code)
3727 arg.free_temps(code)
3730 class DictNode(ExprNode):
3731 # Dictionary constructor.
3733 # key_value_pairs [DictItemNode]
3735 # obj_conversion_errors [PyrexError] used internally
3737 subexprs = ['key_value_pairs']
3738 is_temp = 1
3739 type = dict_type
3741 obj_conversion_errors = []
3743 def calculate_constant_result(self):
3744 self.constant_result = dict([
3745 item.constant_result for item in self.key_value_pairs])
3747 def compile_time_value(self, denv):
3748 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
3749 for item in self.key_value_pairs]
3750 try:
3751 return dict(pairs)
3752 except Exception, e:
3753 self.compile_time_value_error(e)
3755 def type_dependencies(self, env):
3756 return ()
3758 def infer_type(self, env):
3759 # TOOD: Infer struct constructors.
3760 return dict_type
3762 def analyse_types(self, env):
3763 hold_errors()
3764 for item in self.key_value_pairs:
3765 item.analyse_types(env)
3766 self.obj_conversion_errors = held_errors()
3767 release_errors(ignore=True)
3769 def coerce_to(self, dst_type, env):
3770 if dst_type.is_pyobject:
3771 self.release_errors()
3772 if not self.type.subtype_of(dst_type):
3773 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3774 elif dst_type.is_struct_or_union:
3775 self.type = dst_type
3776 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
3777 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
3778 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
3779 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
3780 for item in self.key_value_pairs:
3781 if isinstance(item.key, CoerceToPyTypeNode):
3782 item.key = item.key.arg
3783 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
3784 error(item.key.pos, "Invalid struct field identifier")
3785 item.key = StringNode(item.key.pos, value="<error>")
3786 else:
3787 key = str(item.key.value) # converts string literals to unicode in Py3
3788 member = dst_type.scope.lookup_here(key)
3789 if not member:
3790 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
3791 else:
3792 value = item.value
3793 if isinstance(value, CoerceToPyTypeNode):
3794 value = value.arg
3795 item.value = value.coerce_to(member.type, env)
3796 else:
3797 self.type = error_type
3798 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3799 return self
3801 def release_errors(self):
3802 for err in self.obj_conversion_errors:
3803 report_error(err)
3804 self.obj_conversion_errors = []
3806 gil_message = "Constructing Python dict"
3808 def generate_evaluation_code(self, code):
3809 # Custom method used here because key-value
3810 # pairs are evaluated and used one at a time.
3811 code.mark_pos(self.pos)
3812 self.allocate_temp_result(code)
3813 if self.type.is_pyobject:
3814 self.release_errors()
3815 code.putln(
3816 "%s = PyDict_New(); %s" % (
3817 self.result(),
3818 code.error_goto_if_null(self.result(), self.pos)))
3819 code.put_gotref(self.py_result())
3820 for item in self.key_value_pairs:
3821 item.generate_evaluation_code(code)
3822 if self.type.is_pyobject:
3823 code.put_error_if_neg(self.pos,
3824 "PyDict_SetItem(%s, %s, %s)" % (
3825 self.result(),
3826 item.key.py_result(),
3827 item.value.py_result()))
3828 else:
3829 code.putln("%s.%s = %s;" % (
3830 self.result(),
3831 item.key.value,
3832 item.value.result()))
3833 item.generate_disposal_code(code)
3834 item.free_temps(code)
3836 def annotate(self, code):
3837 for item in self.key_value_pairs:
3838 item.annotate(code)
3840 class DictItemNode(ExprNode):
3841 # Represents a single item in a DictNode
3843 # key ExprNode
3844 # value ExprNode
3845 subexprs = ['key', 'value']
3847 nogil_check = None # Parent DictNode takes care of it
3849 def calculate_constant_result(self):
3850 self.constant_result = (
3851 self.key.constant_result, self.value.constant_result)
3853 def analyse_types(self, env):
3854 self.key.analyse_types(env)
3855 self.value.analyse_types(env)
3856 self.key = self.key.coerce_to_pyobject(env)
3857 self.value = self.value.coerce_to_pyobject(env)
3859 def generate_evaluation_code(self, code):
3860 self.key.generate_evaluation_code(code)
3861 self.value.generate_evaluation_code(code)
3863 def generate_disposal_code(self, code):
3864 self.key.generate_disposal_code(code)
3865 self.value.generate_disposal_code(code)
3867 def free_temps(self, code):
3868 self.key.free_temps(code)
3869 self.value.free_temps(code)
3871 def __iter__(self):
3872 return iter([self.key, self.value])
3875 class ClassNode(ExprNode):
3876 # Helper class used in the implementation of Python
3877 # class definitions. Constructs a class object given
3878 # a name, tuple of bases and class dictionary.
3880 # name EncodedString Name of the class
3881 # bases ExprNode Base class tuple
3882 # dict ExprNode Class dict (not owned by this node)
3883 # doc ExprNode or None Doc string
3884 # module_name string Name of defining module
3886 subexprs = ['bases', 'doc']
3888 def analyse_types(self, env):
3889 self.bases.analyse_types(env)
3890 if self.doc:
3891 self.doc.analyse_types(env)
3892 self.doc = self.doc.coerce_to_pyobject(env)
3893 self.module_name = env.global_scope().qualified_name
3894 self.type = py_object_type
3895 self.is_temp = 1
3896 env.use_utility_code(create_class_utility_code);
3898 gil_message = "Constructing Python class"
3900 def generate_result_code(self, code):
3901 cname = code.intern_identifier(self.name)
3902 if self.doc:
3903 code.put_error_if_neg(self.pos,
3904 'PyDict_SetItemString(%s, "__doc__", %s)' % (
3905 self.dict.py_result(),
3906 self.doc.py_result()))
3907 code.putln(
3908 '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % (
3909 self.result(),
3910 self.bases.py_result(),
3911 self.dict.py_result(),
3912 cname,
3913 self.module_name,
3914 code.error_goto_if_null(self.result(), self.pos)))
3915 code.put_gotref(self.py_result())
3918 class UnboundMethodNode(ExprNode):
3919 # Helper class used in the implementation of Python
3920 # class definitions. Constructs an unbound method
3921 # object from a class and a function.
3923 # function ExprNode Function object
3925 type = py_object_type
3926 is_temp = 1
3928 subexprs = ['function']
3930 def analyse_types(self, env):
3931 self.function.analyse_types(env)
3933 gil_message = "Constructing an unbound method"
3935 def generate_result_code(self, code):
3936 class_cname = code.pyclass_stack[-1].classobj.result()
3937 code.putln(
3938 "%s = PyMethod_New(%s, 0, %s); %s" % (
3939 self.result(),
3940 self.function.py_result(),
3941 class_cname,
3942 code.error_goto_if_null(self.result(), self.pos)))
3943 code.put_gotref(self.py_result())
3945 class PyCFunctionNode(AtomicExprNode):
3946 # Helper class used in the implementation of Python
3947 # class definitions. Constructs a PyCFunction object
3948 # from a PyMethodDef struct.
3950 # pymethdef_cname string PyMethodDef structure
3952 type = py_object_type
3953 is_temp = 1
3955 def analyse_types(self, env):
3956 pass
3958 gil_message = "Constructing Python function"
3960 def generate_result_code(self, code):
3961 code.putln(
3962 "%s = PyCFunction_New(&%s, 0); %s" % (
3963 self.result(),
3964 self.pymethdef_cname,
3965 code.error_goto_if_null(self.result(), self.pos)))
3966 code.put_gotref(self.py_result())
3968 #-------------------------------------------------------------------
3970 # Unary operator nodes
3972 #-------------------------------------------------------------------
3974 compile_time_unary_operators = {
3975 'not': operator.not_,
3976 '~': operator.inv,
3977 '-': operator.neg,
3978 '+': operator.pos,
3981 class UnopNode(ExprNode):
3982 # operator string
3983 # operand ExprNode
3985 # Processing during analyse_expressions phase:
3987 # analyse_c_operation
3988 # Called when the operand is not a pyobject.
3989 # - Check operand type and coerce if needed.
3990 # - Determine result type and result code fragment.
3991 # - Allocate temporary for result if needed.
3993 subexprs = ['operand']
3994 infix = True
3996 def calculate_constant_result(self):
3997 func = compile_time_unary_operators[self.operator]
3998 self.constant_result = func(self.operand.constant_result)
4000 def compile_time_value(self, denv):
4001 func = compile_time_unary_operators.get(self.operator)
4002 if not func:
4003 error(self.pos,
4004 "Unary '%s' not supported in compile-time expression"
4005 % self.operator)
4006 operand = self.operand.compile_time_value(denv)
4007 try:
4008 return func(operand)
4009 except Exception, e:
4010 self.compile_time_value_error(e)
4012 def infer_type(self, env):
4013 return self.operand.infer_type(env)
4015 def analyse_types(self, env):
4016 self.operand.analyse_types(env)
4017 if self.is_py_operation():
4018 self.coerce_operand_to_pyobject(env)
4019 self.type = py_object_type
4020 self.is_temp = 1
4021 else:
4022 self.analyse_c_operation(env)
4024 def check_const(self):
4025 return self.operand.check_const()
4027 def is_py_operation(self):
4028 return self.operand.type.is_pyobject
4030 def nogil_check(self, env):
4031 if self.is_py_operation():
4032 self.gil_error()
4034 def coerce_operand_to_pyobject(self, env):
4035 self.operand = self.operand.coerce_to_pyobject(env)
4037 def generate_result_code(self, code):
4038 if self.operand.type.is_pyobject:
4039 self.generate_py_operation_code(code)
4041 def generate_py_operation_code(self, code):
4042 function = self.py_operation_function()
4043 code.putln(
4044 "%s = %s(%s); %s" % (
4045 self.result(),
4046 function,
4047 self.operand.py_result(),
4048 code.error_goto_if_null(self.result(), self.pos)))
4049 code.put_gotref(self.py_result())
4051 def type_error(self):
4052 if not self.operand.type.is_error:
4053 error(self.pos, "Invalid operand type for '%s' (%s)" %
4054 (self.operator, self.operand.type))
4055 self.type = PyrexTypes.error_type
4058 class NotNode(ExprNode):
4059 # 'not' operator
4061 # operand ExprNode
4063 type = PyrexTypes.c_bint_type
4065 subexprs = ['operand']
4067 def calculate_constant_result(self):
4068 self.constant_result = not self.operand.constant_result
4070 def compile_time_value(self, denv):
4071 operand = self.operand.compile_time_value(denv)
4072 try:
4073 return not operand
4074 except Exception, e:
4075 self.compile_time_value_error(e)
4077 def infer_type(self, env):
4078 return PyrexTypes.c_bint_type
4080 def analyse_types(self, env):
4081 self.operand.analyse_types(env)
4082 self.operand = self.operand.coerce_to_boolean(env)
4084 def calculate_result_code(self):
4085 return "(!%s)" % self.operand.result()
4087 def generate_result_code(self, code):
4088 pass
4091 class UnaryPlusNode(UnopNode):
4092 # unary '+' operator
4094 operator = '+'
4096 def analyse_c_operation(self, env):
4097 self.type = self.operand.type
4099 def py_operation_function(self):
4100 return "PyNumber_Positive"
4102 def calculate_result_code(self):
4103 return self.operand.result()
4106 class UnaryMinusNode(UnopNode):
4107 # unary '-' operator
4109 operator = '-'
4111 def analyse_c_operation(self, env):
4112 if self.operand.type.is_numeric:
4113 self.type = self.operand.type
4114 else:
4115 self.type_error()
4116 if self.type.is_complex:
4117 self.infix = False
4119 def py_operation_function(self):
4120 return "PyNumber_Negative"
4122 def calculate_result_code(self):
4123 if self.infix:
4124 return "(-%s)" % self.operand.result()
4125 else:
4126 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
4128 def get_constant_c_result_code(self):
4129 value = self.operand.get_constant_c_result_code()
4130 if value:
4131 return "(-%s)" % (value)
4133 class TildeNode(UnopNode):
4134 # unary '~' operator
4136 def analyse_c_operation(self, env):
4137 if self.operand.type.is_int:
4138 self.type = self.operand.type
4139 else:
4140 self.type_error()
4142 def py_operation_function(self):
4143 return "PyNumber_Invert"
4145 def calculate_result_code(self):
4146 return "(~%s)" % self.operand.result()
4149 class AmpersandNode(ExprNode):
4150 # The C address-of operator.
4152 # operand ExprNode
4154 subexprs = ['operand']
4156 def infer_type(self, env):
4157 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
4159 def analyse_types(self, env):
4160 self.operand.analyse_types(env)
4161 argtype = self.operand.type
4162 if not (argtype.is_cfunction or self.operand.is_lvalue()):
4163 self.error("Taking address of non-lvalue")
4164 return
4165 if argtype.is_pyobject:
4166 self.error("Cannot take address of Python variable")
4167 return
4168 self.type = PyrexTypes.c_ptr_type(argtype)
4170 def check_const(self):
4171 return self.operand.check_const_addr()
4173 def error(self, mess):
4174 error(self.pos, mess)
4175 self.type = PyrexTypes.error_type
4176 self.result_code = "<error>"
4178 def calculate_result_code(self):
4179 return "(&%s)" % self.operand.result()
4181 def generate_result_code(self, code):
4182 pass
4185 unop_node_classes = {
4186 "+": UnaryPlusNode,
4187 "-": UnaryMinusNode,
4188 "~": TildeNode,
4191 def unop_node(pos, operator, operand):
4192 # Construct unnop node of appropriate class for
4193 # given operator.
4194 if isinstance(operand, IntNode) and operator == '-':
4195 return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
4196 elif isinstance(operand, UnopNode) and operand.operator == operator:
4197 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
4198 return unop_node_classes[operator](pos,
4199 operator = operator,
4200 operand = operand)
4203 class TypecastNode(ExprNode):
4204 # C type cast
4206 # operand ExprNode
4207 # base_type CBaseTypeNode
4208 # declarator CDeclaratorNode
4210 # If used from a transform, one can if wanted specify the attribute
4211 # "type" directly and leave base_type and declarator to None
4213 subexprs = ['operand']
4214 base_type = declarator = type = None
4216 def type_dependencies(self, env):
4217 return ()
4219 def infer_type(self, env):
4220 if self.type is None:
4221 base_type = self.base_type.analyse(env)
4222 _, self.type = self.declarator.analyse(base_type, env)
4223 return self.type
4225 def analyse_types(self, env):
4226 if self.type is None:
4227 base_type = self.base_type.analyse(env)
4228 _, self.type = self.declarator.analyse(base_type, env)
4229 if self.type.is_cfunction:
4230 error(self.pos,
4231 "Cannot cast to a function type")
4232 self.type = PyrexTypes.error_type
4233 self.operand.analyse_types(env)
4234 to_py = self.type.is_pyobject
4235 from_py = self.operand.type.is_pyobject
4236 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
4237 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
4238 if to_py and not from_py:
4239 if self.operand.type.create_to_py_utility_code(env):
4240 self.result_ctype = py_object_type
4241 self.operand = self.operand.coerce_to_pyobject(env)
4242 else:
4243 if self.operand.type.is_ptr:
4244 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
4245 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
4246 else:
4247 # Should this be an error?
4248 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
4249 self.operand = self.operand.coerce_to_simple(env)
4250 elif from_py and not to_py:
4251 if self.type.create_from_py_utility_code(env):
4252 self.operand = self.operand.coerce_to(self.type, env)
4253 elif self.type.is_ptr:
4254 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
4255 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
4256 else:
4257 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
4258 elif from_py and to_py:
4259 if self.typecheck and self.type.is_extension_type:
4260 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
4262 def nogil_check(self, env):
4263 if self.type and self.type.is_pyobject and self.is_temp:
4264 self.gil_error()
4266 def check_const(self):
4267 return self.operand.check_const()
4269 def calculate_constant_result(self):
4270 # we usually do not know the result of a type cast at code
4271 # generation time
4272 pass
4274 def calculate_result_code(self):
4275 opnd = self.operand
4276 return self.type.cast_code(opnd.result())
4278 def get_constant_c_result_code(self):
4279 operand_result = self.operand.get_constant_c_result_code()
4280 if operand_result:
4281 return self.type.cast_code(operand_result)
4283 def result_as(self, type):
4284 if self.type.is_pyobject and not self.is_temp:
4285 # Optimise away some unnecessary casting
4286 return self.operand.result_as(type)
4287 else:
4288 return ExprNode.result_as(self, type)
4290 def generate_result_code(self, code):
4291 if self.is_temp:
4292 code.putln(
4293 "%s = (PyObject *)%s;" % (
4294 self.result(),
4295 self.operand.result()))
4296 code.put_incref(self.result(), self.ctype())
4299 class SizeofNode(ExprNode):
4300 # Abstract base class for sizeof(x) expression nodes.
4302 type = PyrexTypes.c_size_t_type
4304 def check_const(self):
4305 return True
4307 def generate_result_code(self, code):
4308 pass
4311 class SizeofTypeNode(SizeofNode):
4312 # C sizeof function applied to a type
4314 # base_type CBaseTypeNode
4315 # declarator CDeclaratorNode
4317 subexprs = []
4318 arg_type = None
4320 def analyse_types(self, env):
4321 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
4322 # this could be better handled by more uniformly treating types as runtime-available objects
4323 if 0 and self.base_type.module_path:
4324 path = self.base_type.module_path
4325 obj = env.lookup(path[0])
4326 if obj.as_module is None:
4327 operand = NameNode(pos=self.pos, name=path[0])
4328 for attr in path[1:]:
4329 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
4330 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
4331 self.operand = operand
4332 self.__class__ = SizeofVarNode
4333 self.analyse_types(env)
4334 return
4335 if self.arg_type is None:
4336 base_type = self.base_type.analyse(env)
4337 _, arg_type = self.declarator.analyse(base_type, env)
4338 self.arg_type = arg_type
4339 self.check_type()
4341 def check_type(self):
4342 arg_type = self.arg_type
4343 if arg_type.is_pyobject and not arg_type.is_extension_type:
4344 error(self.pos, "Cannot take sizeof Python object")
4345 elif arg_type.is_void:
4346 error(self.pos, "Cannot take sizeof void")
4347 elif not arg_type.is_complete():
4348 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
4350 def calculate_result_code(self):
4351 if self.arg_type.is_extension_type:
4352 # the size of the pointer is boring
4353 # we want the size of the actual struct
4354 arg_code = self.arg_type.declaration_code("", deref=1)
4355 else:
4356 arg_code = self.arg_type.declaration_code("")
4357 return "(sizeof(%s))" % arg_code
4360 class SizeofVarNode(SizeofNode):
4361 # C sizeof function applied to a variable
4363 # operand ExprNode
4365 subexprs = ['operand']
4367 def analyse_types(self, env):
4368 # We may actually be looking at a type rather than a variable...
4369 # If we are, traditional analysis would fail...
4370 operand_as_type = self.operand.analyse_as_type(env)
4371 if operand_as_type:
4372 self.arg_type = operand_as_type
4373 self.__class__ = SizeofTypeNode
4374 self.check_type()
4375 else:
4376 self.operand.analyse_types(env)
4378 def calculate_result_code(self):
4379 return "(sizeof(%s))" % self.operand.result()
4381 def generate_result_code(self, code):
4382 pass
4384 class TypeofNode(ExprNode):
4385 # Compile-time type of an expression, as a string.
4387 # operand ExprNode
4388 # literal StringNode # internal
4390 literal = None
4391 type = py_object_type
4393 subexprs = ['operand', 'literal']
4395 def analyse_types(self, env):
4396 self.operand.analyse_types(env)
4397 self.literal = StringNode(
4398 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
4399 self.literal.analyse_types(env)
4400 self.literal = self.literal.coerce_to_pyobject(env)
4402 def generate_evaluation_code(self, code):
4403 self.literal.generate_evaluation_code(code)
4405 def calculate_result_code(self):
4406 return self.literal.calculate_result_code()
4408 #-------------------------------------------------------------------
4410 # Binary operator nodes
4412 #-------------------------------------------------------------------
4414 def _not_in(x, seq):
4415 return x not in seq
4417 compile_time_binary_operators = {
4418 '<': operator.lt,
4419 '<=': operator.le,
4420 '==': operator.eq,
4421 '!=': operator.ne,
4422 '>=': operator.ge,
4423 '>': operator.gt,
4424 'is': operator.is_,
4425 'is_not': operator.is_not,
4426 '+': operator.add,
4427 '&': operator.and_,
4428 '/': operator.truediv,
4429 '//': operator.floordiv,
4430 '<<': operator.lshift,
4431 '%': operator.mod,
4432 '*': operator.mul,
4433 '|': operator.or_,
4434 '**': operator.pow,
4435 '>>': operator.rshift,
4436 '-': operator.sub,
4437 '^': operator.xor,
4438 'in': operator.contains,
4439 'not_in': _not_in,
4442 def get_compile_time_binop(node):
4443 func = compile_time_binary_operators.get(node.operator)
4444 if not func:
4445 error(node.pos,
4446 "Binary '%s' not supported in compile-time expression"
4447 % node.operator)
4448 return func
4450 class BinopNode(ExprNode):
4451 # operator string
4452 # operand1 ExprNode
4453 # operand2 ExprNode
4455 # Processing during analyse_expressions phase:
4457 # analyse_c_operation
4458 # Called when neither operand is a pyobject.
4459 # - Check operand types and coerce if needed.
4460 # - Determine result type and result code fragment.
4461 # - Allocate temporary for result if needed.
4463 subexprs = ['operand1', 'operand2']
4465 def calculate_constant_result(self):
4466 func = compile_time_binary_operators[self.operator]
4467 self.constant_result = func(
4468 self.operand1.constant_result,
4469 self.operand2.constant_result)
4471 def compile_time_value(self, denv):
4472 func = get_compile_time_binop(self)
4473 operand1 = self.operand1.compile_time_value(denv)
4474 operand2 = self.operand2.compile_time_value(denv)
4475 try:
4476 return func(operand1, operand2)
4477 except Exception, e:
4478 self.compile_time_value_error(e)
4480 def infer_type(self, env):
4481 return self.result_type(self.operand1.infer_type(env),
4482 self.operand2.infer_type(env))
4484 def analyse_types(self, env):
4485 self.operand1.analyse_types(env)
4486 self.operand2.analyse_types(env)
4487 if self.is_py_operation():
4488 self.coerce_operands_to_pyobjects(env)
4489 self.type = py_object_type
4490 self.is_temp = 1
4491 else:
4492 self.analyse_c_operation(env)
4494 def is_py_operation(self):
4495 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
4497 def is_py_operation_types(self, type1, type2):
4498 return type1.is_pyobject or type2.is_pyobject
4500 def result_type(self, type1, type2):
4501 if self.is_py_operation_types(type1, type2):
4502 return py_object_type
4503 else:
4504 return self.compute_c_result_type(type1, type2)
4506 def nogil_check(self, env):
4507 if self.is_py_operation():
4508 self.gil_error()
4510 def coerce_operands_to_pyobjects(self, env):
4511 self.operand1 = self.operand1.coerce_to_pyobject(env)
4512 self.operand2 = self.operand2.coerce_to_pyobject(env)
4514 def check_const(self):
4515 return self.operand1.check_const() and self.operand2.check_const()
4517 def generate_result_code(self, code):
4518 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
4519 if self.operand1.type.is_pyobject:
4520 function = self.py_operation_function()
4521 if function == "PyNumber_Power":
4522 extra_args = ", Py_None"
4523 else:
4524 extra_args = ""
4525 code.putln(
4526 "%s = %s(%s, %s%s); %s" % (
4527 self.result(),
4528 function,
4529 self.operand1.py_result(),
4530 self.operand2.py_result(),
4531 extra_args,
4532 code.error_goto_if_null(self.result(), self.pos)))
4533 code.put_gotref(self.py_result())
4535 def type_error(self):
4536 if not (self.operand1.type.is_error
4537 or self.operand2.type.is_error):
4538 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
4539 (self.operator, self.operand1.type,
4540 self.operand2.type))
4541 self.type = PyrexTypes.error_type
4544 class NumBinopNode(BinopNode):
4545 # Binary operation taking numeric arguments.
4547 infix = True
4549 def analyse_c_operation(self, env):
4550 type1 = self.operand1.type
4551 type2 = self.operand2.type
4552 self.type = self.compute_c_result_type(type1, type2)
4553 if not self.type:
4554 self.type_error()
4555 return
4556 if self.type.is_complex:
4557 self.infix = False
4558 if not self.infix:
4559 self.operand1 = self.operand1.coerce_to(self.type, env)
4560 self.operand2 = self.operand2.coerce_to(self.type, env)
4562 def compute_c_result_type(self, type1, type2):
4563 if self.c_types_okay(type1, type2):
4564 return PyrexTypes.widest_numeric_type(type1, type2)
4565 else:
4566 return None
4568 def get_constant_c_result_code(self):
4569 value1 = self.operand1.get_constant_c_result_code()
4570 value2 = self.operand2.get_constant_c_result_code()
4571 if value1 and value2:
4572 return "(%s %s %s)" % (value1, self.operator, value2)
4573 else:
4574 return None
4576 def c_types_okay(self, type1, type2):
4577 #print "NumBinopNode.c_types_okay:", type1, type2 ###
4578 return (type1.is_numeric or type1.is_enum) \
4579 and (type2.is_numeric or type2.is_enum)
4581 def calculate_result_code(self):
4582 if self.infix:
4583 return "(%s %s %s)" % (
4584 self.operand1.result(),
4585 self.operator,
4586 self.operand2.result())
4587 else:
4588 func = self.type.binary_op(self.operator)
4589 if func is None:
4590 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
4591 return "%s(%s, %s)" % (
4592 func,
4593 self.operand1.result(),
4594 self.operand2.result())
4596 def py_operation_function(self):
4597 return self.py_functions[self.operator]
4599 py_functions = {
4600 "|": "PyNumber_Or",
4601 "^": "PyNumber_Xor",
4602 "&": "PyNumber_And",
4603 "<<": "PyNumber_Lshift",
4604 ">>": "PyNumber_Rshift",
4605 "+": "PyNumber_Add",
4606 "-": "PyNumber_Subtract",
4607 "*": "PyNumber_Multiply",
4608 "/": "__Pyx_PyNumber_Divide",
4609 "//": "PyNumber_FloorDivide",
4610 "%": "PyNumber_Remainder",
4611 "**": "PyNumber_Power"
4615 class IntBinopNode(NumBinopNode):
4616 # Binary operation taking integer arguments.
4618 def c_types_okay(self, type1, type2):
4619 #print "IntBinopNode.c_types_okay:", type1, type2 ###
4620 return (type1.is_int or type1.is_enum) \
4621 and (type2.is_int or type2.is_enum)
4624 class AddNode(NumBinopNode):
4625 # '+' operator.
4627 def is_py_operation_types(self, type1, type2):
4628 if type1.is_string and type2.is_string:
4629 return 1
4630 else:
4631 return NumBinopNode.is_py_operation_types(self, type1, type2)
4633 def compute_c_result_type(self, type1, type2):
4634 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
4635 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4636 return type1
4637 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
4638 return type2
4639 else:
4640 return NumBinopNode.compute_c_result_type(
4641 self, type1, type2)
4644 class SubNode(NumBinopNode):
4645 # '-' operator.
4647 def compute_c_result_type(self, type1, type2):
4648 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4649 return type1
4650 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
4651 return PyrexTypes.c_int_type
4652 else:
4653 return NumBinopNode.compute_c_result_type(
4654 self, type1, type2)
4657 class MulNode(NumBinopNode):
4658 # '*' operator.
4660 def is_py_operation_types(self, type1, type2):
4661 if (type1.is_string and type2.is_int) \
4662 or (type2.is_string and type1.is_int):
4663 return 1
4664 else:
4665 return NumBinopNode.is_py_operation_types(self, type1, type2)
4668 class DivNode(NumBinopNode):
4669 # '/' or '//' operator.
4671 cdivision = None
4672 truedivision = None # == "unknown" if operator == '/'
4673 ctruedivision = False
4674 cdivision_warnings = False
4675 zerodivision_check = None
4677 def find_compile_time_binary_operator(self, op1, op2):
4678 func = compile_time_binary_operators[self.operator]
4679 if self.operator == '/' and self.truedivision is None:
4680 # => true div for floats, floor div for integers
4681 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
4682 func = compile_time_binary_operators['//']
4683 return func
4685 def calculate_constant_result(self):
4686 op1 = self.operand1.constant_result
4687 op2 = self.operand2.constant_result
4688 func = self.find_compile_time_binary_operator(op1, op2)
4689 self.constant_result = func(
4690 self.operand1.constant_result,
4691 self.operand2.constant_result)
4693 def compile_time_value(self, denv):
4694 operand1 = self.operand1.compile_time_value(denv)
4695 operand2 = self.operand2.compile_time_value(denv)
4696 try:
4697 func = self.find_compile_time_binary_operator(
4698 self, operand1, operand2)
4699 return func(operand1, operand2)
4700 except Exception, e:
4701 self.compile_time_value_error(e)
4703 def analyse_types(self, env):
4704 if self.cdivision or env.directives['cdivision']:
4705 self.ctruedivision = False
4706 else:
4707 self.ctruedivision = self.truedivision
4708 NumBinopNode.analyse_types(self, env)
4709 if not self.type.is_pyobject:
4710 self.zerodivision_check = (
4711 self.cdivision is None and not env.directives['cdivision']
4712 and (self.operand2.constant_result is not_a_constant or
4713 self.operand2.constant_result == 0))
4714 if self.zerodivision_check or env.directives['cdivision_warnings']:
4715 # Need to check ahead of time to warn or raise zero division error
4716 self.operand1 = self.operand1.coerce_to_simple(env)
4717 self.operand2 = self.operand2.coerce_to_simple(env)
4718 if env.nogil:
4719 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
4721 def compute_c_result_type(self, type1, type2):
4722 if self.operator == '/' and self.ctruedivision:
4723 if not type1.is_float and not type2.is_float:
4724 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
4725 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
4726 return widest_type
4727 return NumBinopNode.compute_c_result_type(self, type1, type2)
4729 def zero_division_message(self):
4730 if self.type.is_int:
4731 return "integer division or modulo by zero"
4732 else:
4733 return "float division"
4735 def generate_evaluation_code(self, code):
4736 if not self.type.is_pyobject and not self.type.is_complex:
4737 if self.cdivision is None:
4738 self.cdivision = (code.globalstate.directives['cdivision']
4739 or not self.type.signed
4740 or self.type.is_float)
4741 if not self.cdivision:
4742 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
4743 NumBinopNode.generate_evaluation_code(self, code)
4744 self.generate_div_warning_code(code)
4746 def generate_div_warning_code(self, code):
4747 if not self.type.is_pyobject:
4748 if self.zerodivision_check:
4749 if not self.infix:
4750 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
4751 else:
4752 zero_test = "%s == 0" % self.operand2.result()
4753 code.putln("if (unlikely(%s)) {" % zero_test)
4754 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
4755 code.putln(code.error_goto(self.pos))
4756 code.putln("}")
4757 if self.type.is_int and self.type.signed and self.operator != '%':
4758 code.globalstate.use_utility_code(division_overflow_test_code)
4759 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
4760 self.type.declaration_code(''),
4761 self.operand2.result(),
4762 self.operand1.result()))
4763 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
4764 code.putln(code.error_goto(self.pos))
4765 code.putln("}")
4766 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
4767 code.globalstate.use_utility_code(cdivision_warning_utility_code)
4768 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
4769 self.operand1.result(),
4770 self.operand2.result()))
4771 code.putln(code.set_error_info(self.pos));
4772 code.put("if (__Pyx_cdivision_warning()) ")
4773 code.put_goto(code.error_label)
4774 code.putln("}")
4776 def calculate_result_code(self):
4777 if self.type.is_complex:
4778 return NumBinopNode.calculate_result_code(self)
4779 elif self.type.is_float and self.operator == '//':
4780 return "floor(%s / %s)" % (
4781 self.operand1.result(),
4782 self.operand2.result())
4783 elif self.truedivision or self.cdivision:
4784 op1 = self.operand1.result()
4785 op2 = self.operand2.result()
4786 if self.truedivision:
4787 if self.type != self.operand1.type:
4788 op1 = self.type.cast_code(op1)
4789 if self.type != self.operand2.type:
4790 op2 = self.type.cast_code(op2)
4791 return "(%s / %s)" % (op1, op2)
4792 else:
4793 return "__Pyx_div_%s(%s, %s)" % (
4794 self.type.specalization_name(),
4795 self.operand1.result(),
4796 self.operand2.result())
4799 class ModNode(DivNode):
4800 # '%' operator.
4802 def is_py_operation_types(self, type1, type2):
4803 return (type1.is_string
4804 or type2.is_string
4805 or NumBinopNode.is_py_operation_types(self, type1, type2))
4807 def zero_division_message(self):
4808 if self.type.is_int:
4809 return "integer division or modulo by zero"
4810 else:
4811 return "float divmod()"
4813 def generate_evaluation_code(self, code):
4814 if not self.type.is_pyobject:
4815 if self.cdivision is None:
4816 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
4817 if not self.cdivision:
4818 if self.type.is_int:
4819 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
4820 else:
4821 code.globalstate.use_utility_code(
4822 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
4823 NumBinopNode.generate_evaluation_code(self, code)
4824 self.generate_div_warning_code(code)
4826 def calculate_result_code(self):
4827 if self.cdivision:
4828 if self.type.is_float:
4829 return "fmod%s(%s, %s)" % (
4830 self.type.math_h_modifier,
4831 self.operand1.result(),
4832 self.operand2.result())
4833 else:
4834 return "(%s %% %s)" % (
4835 self.operand1.result(),
4836 self.operand2.result())
4837 else:
4838 return "__Pyx_mod_%s(%s, %s)" % (
4839 self.type.specalization_name(),
4840 self.operand1.result(),
4841 self.operand2.result())
4843 class PowNode(NumBinopNode):
4844 # '**' operator.
4846 def analyse_c_operation(self, env):
4847 NumBinopNode.analyse_c_operation(self, env)
4848 if self.type.is_complex:
4849 error(self.pos, "complex powers not yet supported")
4850 self.pow_func = "<error>"
4851 elif self.type.is_float:
4852 self.pow_func = "pow"
4853 else:
4854 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
4855 env.use_utility_code(
4856 int_pow_utility_code.specialize(func_name=self.pow_func,
4857 type=self.type.declaration_code('')))
4859 def calculate_result_code(self):
4860 return "%s(%s, %s)" % (
4861 self.pow_func,
4862 self.operand1.result(),
4863 self.operand2.result())
4866 # Note: This class is temporary "shut down" into an ineffective mode temp
4867 # allocation mode.
4869 # More sophisticated temp reuse was going on before,
4870 # one could have a look at adding this again after /all/ classes
4871 # are converted to the new temp scheme. (The temp juggling cannot work
4872 # otherwise).
4873 class BoolBinopNode(ExprNode):
4874 # Short-circuiting boolean operation.
4876 # operator string
4877 # operand1 ExprNode
4878 # operand2 ExprNode
4880 subexprs = ['operand1', 'operand2']
4882 def infer_type(self, env):
4883 type1 = self.operand1.infer_type(env)
4884 type2 = self.operand2.infer_type(env)
4885 return PyrexTypes.spanning_type(type1, type2)
4887 def calculate_constant_result(self):
4888 if self.operator == 'and':
4889 self.constant_result = \
4890 self.operand1.constant_result and \
4891 self.operand2.constant_result
4892 else:
4893 self.constant_result = \
4894 self.operand1.constant_result or \
4895 self.operand2.constant_result
4897 def compile_time_value(self, denv):
4898 if self.operator == 'and':
4899 return self.operand1.compile_time_value(denv) \
4900 and self.operand2.compile_time_value(denv)
4901 else:
4902 return self.operand1.compile_time_value(denv) \
4903 or self.operand2.compile_time_value(denv)
4905 def coerce_to_boolean(self, env):
4906 self.operand1 = self.operand1.coerce_to_boolean(env)
4907 self.operand2 = self.operand2.coerce_to_boolean(env)
4908 self.type = PyrexTypes.c_bint_type
4909 return self
4911 def analyse_types(self, env):
4912 self.operand1.analyse_types(env)
4913 self.operand2.analyse_types(env)
4914 self.type = PyrexTypes.spanning_type(self.operand1.type, self.operand2.type)
4915 self.operand1 = self.operand1.coerce_to(self.type, env)
4916 self.operand2 = self.operand2.coerce_to(self.type, env)
4918 # For what we're about to do, it's vital that
4919 # both operands be temp nodes.
4920 self.operand1 = self.operand1.coerce_to_simple(env)
4921 self.operand2 = self.operand2.coerce_to_simple(env)
4922 self.is_temp = 1
4924 gil_message = "Truth-testing Python object"
4926 def check_const(self):
4927 return self.operand1.check_const() and self.operand2.check_const()
4929 def generate_evaluation_code(self, code):
4930 code.mark_pos(self.pos)
4931 self.operand1.generate_evaluation_code(code)
4932 test_result, uses_temp = self.generate_operand1_test(code)
4933 if self.operator == 'and':
4934 sense = ""
4935 else:
4936 sense = "!"
4937 code.putln(
4938 "if (%s%s) {" % (
4939 sense,
4940 test_result))
4941 if uses_temp:
4942 code.funcstate.release_temp(test_result)
4943 self.operand1.generate_disposal_code(code)
4944 self.operand2.generate_evaluation_code(code)
4945 self.allocate_temp_result(code)
4946 self.operand2.make_owned_reference(code)
4947 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
4948 self.operand2.generate_post_assignment_code(code)
4949 self.operand2.free_temps(code)
4950 code.putln("} else {")
4951 self.operand1.make_owned_reference(code)
4952 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
4953 self.operand1.generate_post_assignment_code(code)
4954 self.operand1.free_temps(code)
4955 code.putln("}")
4957 def generate_operand1_test(self, code):
4958 # Generate code to test the truth of the first operand.
4959 if self.type.is_pyobject:
4960 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
4961 manage_ref=False)
4962 code.putln(
4963 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
4964 test_result,
4965 self.operand1.py_result(),
4966 code.error_goto_if_neg(test_result, self.pos)))
4967 else:
4968 test_result = self.operand1.result()
4969 return (test_result, self.type.is_pyobject)
4972 class CondExprNode(ExprNode):
4973 # Short-circuiting conditional expression.
4975 # test ExprNode
4976 # true_val ExprNode
4977 # false_val ExprNode
4979 true_val = None
4980 false_val = None
4982 subexprs = ['test', 'true_val', 'false_val']
4984 def type_dependencies(self, env):
4985 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
4987 def infer_type(self, env):
4988 return self.compute_result_type(self.true_val.infer_type(env),
4989 self.false_val.infer_type(env))
4991 def calculate_constant_result(self):
4992 if self.test.constant_result:
4993 self.constant_result = self.true_val.constant_result
4994 else:
4995 self.constant_result = self.false_val.constant_result
4997 def analyse_types(self, env):
4998 self.test.analyse_types(env)
4999 self.test = self.test.coerce_to_boolean(env)
5000 self.true_val.analyse_types(env)
5001 self.false_val.analyse_types(env)
5002 self.type = self.compute_result_type(self.true_val.type, self.false_val.type)
5003 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
5004 self.true_val = self.true_val.coerce_to(self.type, env)
5005 self.false_val = self.false_val.coerce_to(self.type, env)
5006 self.is_temp = 1
5007 if self.type == PyrexTypes.error_type:
5008 self.type_error()
5010 def compute_result_type(self, type1, type2):
5011 if type1 == type2:
5012 return type1
5013 elif type1.is_numeric and type2.is_numeric:
5014 return PyrexTypes.widest_numeric_type(type1, type2)
5015 elif type1.is_extension_type and type1.subtype_of_resolved_type(type2):
5016 return type2
5017 elif type2.is_extension_type and type2.subtype_of_resolved_type(type1):
5018 return type1
5019 elif type1.is_pyobject or type2.is_pyobject:
5020 return py_object_type
5021 elif type1.assignable_from(type2):
5022 return type1
5023 elif type2.assignable_from(type1):
5024 return type2
5025 else:
5026 return PyrexTypes.error_type
5028 def type_error(self):
5029 if not (self.true_val.type.is_error or self.false_val.type.is_error):
5030 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
5031 (self.true_val.type, self.false_val.type))
5032 self.type = PyrexTypes.error_type
5034 def check_const(self):
5035 return (self.test.check_const()
5036 and self.true_val.check_const()
5037 and self.false_val.check_const())
5039 def generate_evaluation_code(self, code):
5040 # Because subexprs may not be evaluated we can use a more optimal
5041 # subexpr allocation strategy than the default, so override evaluation_code.
5043 code.mark_pos(self.pos)
5044 self.allocate_temp_result(code)
5045 self.test.generate_evaluation_code(code)
5046 code.putln("if (%s) {" % self.test.result() )
5047 self.eval_and_get(code, self.true_val)
5048 code.putln("} else {")
5049 self.eval_and_get(code, self.false_val)
5050 code.putln("}")
5051 self.test.generate_disposal_code(code)
5052 self.test.free_temps(code)
5054 def eval_and_get(self, code, expr):
5055 expr.generate_evaluation_code(code)
5056 expr.make_owned_reference(code)
5057 code.putln("%s = %s;" % (self.result(), expr.result()))
5058 expr.generate_post_assignment_code(code)
5059 expr.free_temps(code)
5061 richcmp_constants = {
5062 "<" : "Py_LT",
5063 "<=": "Py_LE",
5064 "==": "Py_EQ",
5065 "!=": "Py_NE",
5066 "<>": "Py_NE",
5067 ">" : "Py_GT",
5068 ">=": "Py_GE",
5071 class CmpNode(object):
5072 # Mixin class containing code common to PrimaryCmpNodes
5073 # and CascadedCmpNodes.
5075 def infer_types(self, env):
5076 # TODO: Actually implement this (after merging with -unstable).
5077 return py_object_type
5079 def calculate_cascaded_constant_result(self, operand1_result):
5080 func = compile_time_binary_operators[self.operator]
5081 operand2_result = self.operand2.constant_result
5082 result = func(operand1_result, operand2_result)
5083 if result and self.cascade:
5084 result = result and \
5085 self.cascade.cascaded_compile_time_value(operand2_result)
5086 self.constant_result = result
5088 def cascaded_compile_time_value(self, operand1, denv):
5089 func = get_compile_time_binop(self)
5090 operand2 = self.operand2.compile_time_value(denv)
5091 try:
5092 result = func(operand1, operand2)
5093 except Exception, e:
5094 self.compile_time_value_error(e)
5095 result = None
5096 if result:
5097 cascade = self.cascade
5098 if cascade:
5099 # FIXME: I bet this must call cascaded_compile_time_value()
5100 result = result and cascade.compile_time_value(operand2, denv)
5101 return result
5103 def find_common_int_type(self, env, op, operand1, operand2):
5104 # type1 != type2 and at least one of the types is not a C int
5105 type1 = operand1.type
5106 type2 = operand2.type
5107 type1_can_be_int = False
5108 type2_can_be_int = False
5110 if isinstance(operand1, (StringNode, BytesNode)) \
5111 and operand1.can_coerce_to_char_literal():
5112 type1_can_be_int = True
5113 if isinstance(operand2, (StringNode, BytesNode)) \
5114 and operand2.can_coerce_to_char_literal():
5115 type2_can_be_int = True
5117 if type1.is_int:
5118 if type2_can_be_int:
5119 return type1
5120 elif type2.is_int:
5121 if type1_can_be_int:
5122 return type2
5123 elif type1_can_be_int:
5124 if type2_can_be_int:
5125 return PyrexTypes.c_uchar_type
5127 return None
5129 def find_common_type(self, env, op, operand1, common_type=None):
5130 operand2 = self.operand2
5131 type1 = operand1.type
5132 type2 = operand2.type
5134 new_common_type = None
5136 # catch general errors
5137 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
5138 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
5139 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
5140 new_common_type = error_type
5142 # try to use numeric comparisons where possible
5143 elif type1.is_complex or type2.is_complex:
5144 if op not in ('==', '!='):
5145 error(self.pos, "complex types are unordered")
5146 new_common_type = error_type
5147 if type1.is_pyobject:
5148 new_common_type = type1
5149 elif type2.is_pyobject:
5150 new_common_type = type2
5151 else:
5152 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5153 elif type1.is_numeric and type2.is_numeric:
5154 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5155 elif common_type is None or not common_type.is_pyobject:
5156 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
5158 if new_common_type is None:
5159 # fall back to generic type compatibility tests
5160 if type1 == type2:
5161 new_common_type = type1
5162 elif type1.is_pyobject or type2.is_pyobject:
5163 if type2.is_numeric or type2.is_string:
5164 if operand2.check_for_coercion_error(type1):
5165 new_common_type = error_type
5166 else:
5167 new_common_type = py_object_type
5168 elif type1.is_numeric or type1.is_string:
5169 if operand1.check_for_coercion_error(type2):
5170 new_common_type = error_type
5171 else:
5172 new_common_type = py_object_type
5173 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
5174 new_common_type = py_object_type
5175 else:
5176 # one Python type and one non-Python type, not assignable
5177 self.invalid_types_error(operand1, op, operand2)
5178 new_common_type = error_type
5179 elif type1.assignable_from(type2):
5180 new_common_type = type1
5181 elif type2.assignable_from(type1):
5182 new_common_type = type2
5183 else:
5184 # C types that we couldn't handle up to here are an error
5185 self.invalid_types_error(operand1, op, operand2)
5186 new_common_type = error_type
5188 # recursively merge types
5189 if common_type is None or new_common_type.is_error:
5190 common_type = new_common_type
5191 else:
5192 # we could do a lot better by splitting the comparison
5193 # into a non-Python part and a Python part, but this is
5194 # safer for now
5195 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
5197 if self.cascade:
5198 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
5200 return common_type
5202 def invalid_types_error(self, operand1, op, operand2):
5203 error(self.pos, "Invalid types for '%s' (%s, %s)" %
5204 (op, operand1.type, operand2.type))
5206 def is_python_comparison(self):
5207 return (self.has_python_operands()
5208 or (self.cascade and self.cascade.is_python_comparison())
5209 or self.operator in ('in', 'not_in'))
5211 def coerce_operands_to(self, dst_type, env):
5212 operand2 = self.operand2
5213 if operand2.type != dst_type:
5214 self.operand2 = operand2.coerce_to(dst_type, env)
5215 if self.cascade:
5216 self.cascade.coerce_operands_to(dst_type, env)
5218 def is_python_result(self):
5219 return ((self.has_python_operands() and
5220 self.operator not in ('is', 'is_not', 'in', 'not_in'))
5221 or (self.cascade and self.cascade.is_python_result()))
5223 def generate_operation_code(self, code, result_code,
5224 operand1, op , operand2):
5225 if self.type is PyrexTypes.py_object_type:
5226 coerce_result = "__Pyx_PyBool_FromLong"
5227 else:
5228 coerce_result = ""
5229 if 'not' in op: negation = "!"
5230 else: negation = ""
5231 if op == 'in' or op == 'not_in':
5232 if operand2.type is dict_type:
5233 code.globalstate.use_utility_code(
5234 raise_none_iter_error_utility_code)
5235 code.putln("if (unlikely(%s == Py_None)) {" % operand2.py_result())
5236 code.putln("__Pyx_RaiseNoneNotIterableError(); %s" %
5237 code.error_goto(self.pos))
5238 code.putln("} else {")
5239 code.putln(
5240 "%s = %s(%sPyDict_Contains(%s, %s)); %s" % (
5241 result_code,
5242 coerce_result,
5243 negation,
5244 operand2.py_result(),
5245 operand1.py_result(),
5246 code.error_goto_if_neg(result_code, self.pos)))
5247 code.putln("}")
5248 else:
5249 code.putln(
5250 "%s = %s(%sPySequence_Contains(%s, %s)); %s" % (
5251 result_code,
5252 coerce_result,
5253 negation,
5254 operand2.py_result(),
5255 operand1.py_result(),
5256 code.error_goto_if_neg(result_code, self.pos)))
5257 elif (operand1.type.is_pyobject
5258 and op not in ('is', 'is_not')):
5259 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
5260 result_code,
5261 operand1.py_result(),
5262 operand2.py_result(),
5263 richcmp_constants[op],
5264 code.error_goto_if_null(result_code, self.pos)))
5265 code.put_gotref(result_code)
5266 elif operand1.type.is_complex:
5267 if op == "!=":
5268 negation = "!"
5269 else:
5270 negation = ""
5271 code.putln("%s = %s(%s%s(%s, %s));" % (
5272 result_code,
5273 coerce_result,
5274 negation,
5275 operand1.type.unary_op('eq'),
5276 operand1.result(),
5277 operand2.result()))
5278 else:
5279 type1 = operand1.type
5280 type2 = operand2.type
5281 if (type1.is_extension_type or type2.is_extension_type) \
5282 and not type1.same_as(type2):
5283 common_type = py_object_type
5284 elif type1.is_numeric:
5285 common_type = PyrexTypes.widest_numeric_type(type1, type2)
5286 else:
5287 common_type = type1
5288 code1 = operand1.result_as(common_type)
5289 code2 = operand2.result_as(common_type)
5290 code.putln("%s = %s(%s %s %s);" % (
5291 result_code,
5292 coerce_result,
5293 code1,
5294 self.c_operator(op),
5295 code2))
5297 def c_operator(self, op):
5298 if op == 'is':
5299 return "=="
5300 elif op == 'is_not':
5301 return "!="
5302 else:
5303 return op
5306 class PrimaryCmpNode(ExprNode, CmpNode):
5307 # Non-cascaded comparison or first comparison of
5308 # a cascaded sequence.
5310 # operator string
5311 # operand1 ExprNode
5312 # operand2 ExprNode
5313 # cascade CascadedCmpNode
5315 # We don't use the subexprs mechanism, because
5316 # things here are too complicated for it to handle.
5317 # Instead, we override all the framework methods
5318 # which use it.
5320 child_attrs = ['operand1', 'operand2', 'cascade']
5322 cascade = None
5324 def infer_type(self, env):
5325 # TODO: Actually implement this (after merging with -unstable).
5326 return py_object_type
5328 def type_dependencies(self, env):
5329 return ()
5331 def calculate_constant_result(self):
5332 self.constant_result = self.calculate_cascaded_constant_result(
5333 self.operand1.constant_result)
5335 def compile_time_value(self, denv):
5336 operand1 = self.operand1.compile_time_value(denv)
5337 return self.cascaded_compile_time_value(operand1, denv)
5339 def analyse_types(self, env):
5340 self.operand1.analyse_types(env)
5341 self.operand2.analyse_types(env)
5342 if self.cascade:
5343 self.cascade.analyse_types(env)
5345 if self.operator in ('in', 'not_in'):
5346 common_type = py_object_type
5347 self.is_pycmp = True
5348 else:
5349 common_type = self.find_common_type(env, self.operator, self.operand1)
5350 self.is_pycmp = common_type.is_pyobject
5352 if not common_type.is_error:
5353 if self.operand1.type != common_type:
5354 self.operand1 = self.operand1.coerce_to(common_type, env)
5355 self.coerce_operands_to(common_type, env)
5357 if self.cascade:
5358 self.operand2 = self.operand2.coerce_to_simple(env)
5359 self.cascade.coerce_cascaded_operands_to_temp(env)
5360 if self.is_python_result():
5361 self.type = PyrexTypes.py_object_type
5362 else:
5363 self.type = PyrexTypes.c_bint_type
5364 cdr = self.cascade
5365 while cdr:
5366 cdr.type = self.type
5367 cdr = cdr.cascade
5368 if self.is_pycmp or self.cascade:
5369 self.is_temp = 1
5371 def has_python_operands(self):
5372 return (self.operand1.type.is_pyobject
5373 or self.operand2.type.is_pyobject)
5375 def check_const(self):
5376 if self.cascade:
5377 self.not_const()
5378 return False
5379 else:
5380 return self.operand1.check_const() and self.operand2.check_const()
5382 def calculate_result_code(self):
5383 if self.operand1.type.is_complex:
5384 if self.operator == "!=":
5385 negation = "!"
5386 else:
5387 negation = ""
5388 return "(%s%s(%s, %s))" % (
5389 negation,
5390 self.operand1.type.binary_op('=='),
5391 self.operand1.result(),
5392 self.operand2.result())
5393 else:
5394 return "(%s %s %s)" % (
5395 self.operand1.result(),
5396 self.c_operator(self.operator),
5397 self.operand2.result())
5399 def generate_evaluation_code(self, code):
5400 self.operand1.generate_evaluation_code(code)
5401 self.operand2.generate_evaluation_code(code)
5402 if self.is_temp:
5403 self.allocate_temp_result(code)
5404 self.generate_operation_code(code, self.result(),
5405 self.operand1, self.operator, self.operand2)
5406 if self.cascade:
5407 self.cascade.generate_evaluation_code(code,
5408 self.result(), self.operand2)
5409 self.operand1.generate_disposal_code(code)
5410 self.operand1.free_temps(code)
5411 self.operand2.generate_disposal_code(code)
5412 self.operand2.free_temps(code)
5414 def generate_subexpr_disposal_code(self, code):
5415 # If this is called, it is a non-cascaded cmp,
5416 # so only need to dispose of the two main operands.
5417 self.operand1.generate_disposal_code(code)
5418 self.operand2.generate_disposal_code(code)
5420 def free_subexpr_temps(self, code):
5421 # If this is called, it is a non-cascaded cmp,
5422 # so only need to dispose of the two main operands.
5423 self.operand1.free_temps(code)
5424 self.operand2.free_temps(code)
5426 def annotate(self, code):
5427 self.operand1.annotate(code)
5428 self.operand2.annotate(code)
5429 if self.cascade:
5430 self.cascade.annotate(code)
5433 class CascadedCmpNode(Node, CmpNode):
5434 # A CascadedCmpNode is not a complete expression node. It
5435 # hangs off the side of another comparison node, shares
5436 # its left operand with that node, and shares its result
5437 # with the PrimaryCmpNode at the head of the chain.
5439 # operator string
5440 # operand2 ExprNode
5441 # cascade CascadedCmpNode
5443 child_attrs = ['operand2', 'cascade']
5445 cascade = None
5446 constant_result = constant_value_not_set # FIXME: where to calculate this?
5448 def infer_type(self, env):
5449 # TODO: Actually implement this (after merging with -unstable).
5450 return py_object_type
5452 def type_dependencies(self, env):
5453 return ()
5455 def analyse_types(self, env):
5456 self.operand2.analyse_types(env)
5457 if self.cascade:
5458 self.cascade.analyse_types(env)
5460 def has_python_operands(self):
5461 return self.operand2.type.is_pyobject
5463 def coerce_operands_to_pyobjects(self, env):
5464 self.operand2 = self.operand2.coerce_to_pyobject(env)
5465 if self.cascade:
5466 self.cascade.coerce_operands_to_pyobjects(env)
5468 def coerce_cascaded_operands_to_temp(self, env):
5469 if self.cascade:
5470 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
5471 self.operand2 = self.operand2.coerce_to_simple(env)
5472 self.cascade.coerce_cascaded_operands_to_temp(env)
5474 def generate_evaluation_code(self, code, result, operand1):
5475 if self.type.is_pyobject:
5476 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
5477 code.put_decref(result, self.type)
5478 else:
5479 code.putln("if (%s) {" % result)
5480 self.operand2.generate_evaluation_code(code)
5481 self.generate_operation_code(code, result,
5482 operand1, self.operator, self.operand2)
5483 if self.cascade:
5484 self.cascade.generate_evaluation_code(
5485 code, result, self.operand2)
5486 # Cascaded cmp result is always temp
5487 self.operand2.generate_disposal_code(code)
5488 self.operand2.free_temps(code)
5489 code.putln("}")
5491 def annotate(self, code):
5492 self.operand2.annotate(code)
5493 if self.cascade:
5494 self.cascade.annotate(code)
5497 binop_node_classes = {
5498 "or": BoolBinopNode,
5499 "and": BoolBinopNode,
5500 "|": IntBinopNode,
5501 "^": IntBinopNode,
5502 "&": IntBinopNode,
5503 "<<": IntBinopNode,
5504 ">>": IntBinopNode,
5505 "+": AddNode,
5506 "-": SubNode,
5507 "*": MulNode,
5508 "/": DivNode,
5509 "//": DivNode,
5510 "%": ModNode,
5511 "**": PowNode
5514 def binop_node(pos, operator, operand1, operand2):
5515 # Construct binop node of appropriate class for
5516 # given operator.
5517 return binop_node_classes[operator](pos,
5518 operator = operator,
5519 operand1 = operand1,
5520 operand2 = operand2)
5522 #-------------------------------------------------------------------
5524 # Coercion nodes
5526 # Coercion nodes are special in that they are created during
5527 # the analyse_types phase of parse tree processing.
5528 # Their __init__ methods consequently incorporate some aspects
5529 # of that phase.
5531 #-------------------------------------------------------------------
5533 class CoercionNode(ExprNode):
5534 # Abstract base class for coercion nodes.
5536 # arg ExprNode node being coerced
5538 subexprs = ['arg']
5539 constant_result = not_a_constant
5541 def __init__(self, arg):
5542 self.pos = arg.pos
5543 self.arg = arg
5544 if debug_coercion:
5545 print("%s Coercing %s" % (self, self.arg))
5547 def calculate_constant_result(self):
5548 # constant folding can break type coercion, so this is disabled
5549 pass
5551 def annotate(self, code):
5552 self.arg.annotate(code)
5553 if self.arg.type != self.type:
5554 file, line, col = self.pos
5555 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
5558 class CastNode(CoercionNode):
5559 # Wrap a node in a C type cast.
5561 def __init__(self, arg, new_type):
5562 CoercionNode.__init__(self, arg)
5563 self.type = new_type
5565 def calculate_result_code(self):
5566 return self.arg.result_as(self.type)
5568 def generate_result_code(self, code):
5569 self.arg.generate_result_code(code)
5572 class PyTypeTestNode(CoercionNode):
5573 # This node is used to check that a generic Python
5574 # object is an instance of a particular extension type.
5575 # This node borrows the result of its argument node.
5577 def __init__(self, arg, dst_type, env, notnone=False):
5578 # The arg is know to be a Python object, and
5579 # the dst_type is known to be an extension type.
5580 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
5581 CoercionNode.__init__(self, arg)
5582 self.type = dst_type
5583 self.result_ctype = arg.ctype()
5584 self.notnone = notnone
5586 nogil_check = Node.gil_error
5587 gil_message = "Python type test"
5589 def analyse_types(self, env):
5590 pass
5592 def result_in_temp(self):
5593 return self.arg.result_in_temp()
5595 def is_ephemeral(self):
5596 return self.arg.is_ephemeral()
5598 def calculate_constant_result(self):
5599 # FIXME
5600 pass
5602 def calculate_result_code(self):
5603 return self.arg.result()
5605 def generate_result_code(self, code):
5606 if self.type.typeobj_is_available():
5607 if not self.type.is_builtin_type:
5608 code.globalstate.use_utility_code(type_test_utility_code)
5609 code.putln(
5610 "if (!(%s)) %s" % (
5611 self.type.type_test_code(self.arg.py_result(), self.notnone),
5612 code.error_goto(self.pos)))
5613 else:
5614 error(self.pos, "Cannot test type of extern C class "
5615 "without type object name specification")
5617 def generate_post_assignment_code(self, code):
5618 self.arg.generate_post_assignment_code(code)
5620 def free_temps(self, code):
5621 self.arg.free_temps(code)
5624 class NoneCheckNode(CoercionNode):
5625 # This node is used to check that a Python object is not None and
5626 # raises an appropriate exception (as specified by the creating
5627 # transform).
5629 def __init__(self, arg, exception_type_cname, exception_message):
5630 CoercionNode.__init__(self, arg)
5631 self.type = arg.type
5632 self.result_ctype = arg.ctype()
5633 self.exception_type_cname = exception_type_cname
5634 self.exception_message = exception_message
5636 def analyse_types(self, env):
5637 pass
5639 def result_in_temp(self):
5640 return self.arg.result_in_temp()
5642 def calculate_result_code(self):
5643 return self.arg.result()
5645 def generate_result_code(self, code):
5646 code.putln(
5647 "if (unlikely(%s == Py_None)) {" % self.arg.result())
5648 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
5649 self.exception_type_cname,
5650 StringEncoding.escape_byte_string(
5651 self.exception_message.encode('UTF-8')),
5652 code.error_goto(self.pos)))
5653 code.putln("}")
5655 def generate_post_assignment_code(self, code):
5656 self.arg.generate_post_assignment_code(code)
5658 def free_temps(self, code):
5659 self.arg.free_temps(code)
5662 class CoerceToPyTypeNode(CoercionNode):
5663 # This node is used to convert a C data type
5664 # to a Python object.
5666 type = py_object_type
5667 is_temp = 1
5669 def __init__(self, arg, env):
5670 CoercionNode.__init__(self, arg)
5671 if not arg.type.create_to_py_utility_code(env):
5672 error(arg.pos,
5673 "Cannot convert '%s' to Python object" % arg.type)
5675 gil_message = "Converting to Python object"
5677 def coerce_to_boolean(self, env):
5678 return self.arg.coerce_to_boolean(env).coerce_to_temp(env)
5680 def coerce_to_integer(self, env):
5681 # If not already some C integer type, coerce to longint.
5682 if self.arg.type.is_int:
5683 return self.arg
5684 else:
5685 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
5687 def analyse_types(self, env):
5688 # The arg is always already analysed
5689 pass
5691 def generate_result_code(self, code):
5692 function = self.arg.type.to_py_function
5693 code.putln('%s = %s(%s); %s' % (
5694 self.result(),
5695 function,
5696 self.arg.result(),
5697 code.error_goto_if_null(self.result(), self.pos)))
5698 code.put_gotref(self.py_result())
5701 class CoerceFromPyTypeNode(CoercionNode):
5702 # This node is used to convert a Python object
5703 # to a C data type.
5705 def __init__(self, result_type, arg, env):
5706 CoercionNode.__init__(self, arg)
5707 self.type = result_type
5708 self.is_temp = 1
5709 if not result_type.create_from_py_utility_code(env):
5710 error(arg.pos,
5711 "Cannot convert Python object to '%s'" % result_type)
5712 if self.type.is_string and self.arg.is_ephemeral():
5713 error(arg.pos,
5714 "Obtaining char * from temporary Python value")
5716 def analyse_types(self, env):
5717 # The arg is always already analysed
5718 pass
5720 def generate_result_code(self, code):
5721 function = self.type.from_py_function
5722 operand = self.arg.py_result()
5723 rhs = "%s(%s)" % (function, operand)
5724 if self.type.is_enum:
5725 rhs = typecast(self.type, c_long_type, rhs)
5726 code.putln('%s = %s; %s' % (
5727 self.result(),
5728 rhs,
5729 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
5730 if self.type.is_pyobject:
5731 code.put_gotref(self.py_result())
5734 class CoerceToBooleanNode(CoercionNode):
5735 # This node is used when a result needs to be used
5736 # in a boolean context.
5738 type = PyrexTypes.c_bint_type
5740 def __init__(self, arg, env):
5741 CoercionNode.__init__(self, arg)
5742 if arg.type.is_pyobject:
5743 self.is_temp = 1
5745 def nogil_check(self, env):
5746 if self.arg.type.is_pyobject:
5747 self.gil_error()
5749 gil_message = "Truth-testing Python object"
5751 def check_const(self):
5752 if self.is_temp:
5753 self.not_const()
5754 return False
5755 return self.arg.check_const()
5757 def calculate_result_code(self):
5758 return "(%s != 0)" % self.arg.result()
5760 def generate_result_code(self, code):
5761 if self.arg.type.is_pyobject:
5762 code.putln(
5763 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5764 self.result(),
5765 self.arg.py_result(),
5766 code.error_goto_if_neg(self.result(), self.pos)))
5768 class CoerceToComplexNode(CoercionNode):
5770 def __init__(self, arg, dst_type, env):
5771 if arg.type.is_complex:
5772 arg = arg.coerce_to_simple(env)
5773 self.type = dst_type
5774 CoercionNode.__init__(self, arg)
5775 dst_type.create_declaration_utility_code(env)
5777 def calculate_result_code(self):
5778 if self.arg.type.is_complex:
5779 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
5780 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
5781 else:
5782 real_part = self.arg.result()
5783 imag_part = "0"
5784 return "%s(%s, %s)" % (
5785 self.type.from_parts,
5786 real_part,
5787 imag_part)
5789 def generate_result_code(self, code):
5790 pass
5792 class CoerceToTempNode(CoercionNode):
5793 # This node is used to force the result of another node
5794 # to be stored in a temporary. It is only used if the
5795 # argument node's result is not already in a temporary.
5797 def __init__(self, arg, env):
5798 CoercionNode.__init__(self, arg)
5799 self.type = self.arg.type
5800 self.is_temp = 1
5801 if self.type.is_pyobject:
5802 self.result_ctype = py_object_type
5804 gil_message = "Creating temporary Python reference"
5806 def analyse_types(self, env):
5807 # The arg is always already analysed
5808 pass
5810 def coerce_to_boolean(self, env):
5811 self.arg = self.arg.coerce_to_boolean(env)
5812 self.type = self.arg.type
5813 self.result_ctype = self.type
5814 return self
5816 def generate_result_code(self, code):
5817 #self.arg.generate_evaluation_code(code) # Already done
5818 # by generic generate_subexpr_evaluation_code!
5819 code.putln("%s = %s;" % (
5820 self.result(), self.arg.result_as(self.ctype())))
5821 if self.type.is_pyobject and self.use_managed_ref:
5822 code.put_incref(self.result(), self.ctype())
5825 class CloneNode(CoercionNode):
5826 # This node is employed when the result of another node needs
5827 # to be used multiple times. The argument node's result must
5828 # be in a temporary. This node "borrows" the result from the
5829 # argument node, and does not generate any evaluation or
5830 # disposal code for it. The original owner of the argument
5831 # node is responsible for doing those things.
5833 subexprs = [] # Arg is not considered a subexpr
5834 nogil_check = None
5836 def __init__(self, arg):
5837 CoercionNode.__init__(self, arg)
5838 if hasattr(arg, 'type'):
5839 self.type = arg.type
5840 self.result_ctype = arg.result_ctype
5841 if hasattr(arg, 'entry'):
5842 self.entry = arg.entry
5844 def result(self):
5845 return self.arg.result()
5847 def type_dependencies(self, env):
5848 return self.arg.type_dependencies(env)
5850 def infer_type(self, env):
5851 return self.arg.infer_type(env)
5853 def analyse_types(self, env):
5854 self.type = self.arg.type
5855 self.result_ctype = self.arg.result_ctype
5856 self.is_temp = 1
5857 if hasattr(self.arg, 'entry'):
5858 self.entry = self.arg.entry
5860 def generate_evaluation_code(self, code):
5861 pass
5863 def generate_result_code(self, code):
5864 pass
5866 def generate_disposal_code(self, code):
5867 pass
5869 def free_temps(self, code):
5870 pass
5873 class ModuleRefNode(ExprNode):
5874 # Simple returns the module object
5876 type = py_object_type
5877 is_temp = False
5878 subexprs = []
5880 def analyse_types(self, env):
5881 pass
5883 def calculate_result_code(self):
5884 return Naming.module_cname
5886 def generate_result_code(self, code):
5887 pass
5889 class DocstringRefNode(ExprNode):
5890 # Extracts the docstring of the body element
5892 subexprs = ['body']
5893 type = py_object_type
5894 is_temp = True
5896 def __init__(self, pos, body):
5897 ExprNode.__init__(self, pos)
5898 assert body.type.is_pyobject
5899 self.body = body
5901 def analyse_types(self, env):
5902 pass
5904 def generate_result_code(self, code):
5905 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__");' %
5906 (self.result(), self.body.result()))
5907 code.put_gotref(self.result())
5911 #------------------------------------------------------------------------------------
5913 # Runtime support code
5915 #------------------------------------------------------------------------------------
5917 get_name_interned_utility_code = UtilityCode(
5918 proto = """
5919 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
5920 """,
5921 impl = """
5922 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
5923 PyObject *result;
5924 result = PyObject_GetAttr(dict, name);
5925 if (!result)
5926 PyErr_SetObject(PyExc_NameError, name);
5927 return result;
5929 """)
5931 #------------------------------------------------------------------------------------
5933 import_utility_code = UtilityCode(
5934 proto = """
5935 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
5936 """,
5937 impl = """
5938 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
5939 PyObject *__import__ = 0;
5940 PyObject *empty_list = 0;
5941 PyObject *module = 0;
5942 PyObject *global_dict = 0;
5943 PyObject *empty_dict = 0;
5944 PyObject *list;
5945 __import__ = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
5946 if (!__import__)
5947 goto bad;
5948 if (from_list)
5949 list = from_list;
5950 else {
5951 empty_list = PyList_New(0);
5952 if (!empty_list)
5953 goto bad;
5954 list = empty_list;
5956 global_dict = PyModule_GetDict(%(GLOBALS)s);
5957 if (!global_dict)
5958 goto bad;
5959 empty_dict = PyDict_New();
5960 if (!empty_dict)
5961 goto bad;
5962 module = PyObject_CallFunctionObjArgs(__import__,
5963 name, global_dict, empty_dict, list, NULL);
5964 bad:
5965 Py_XDECREF(empty_list);
5966 Py_XDECREF(__import__);
5967 Py_XDECREF(empty_dict);
5968 return module;
5970 """ % {
5971 "BUILTINS": Naming.builtins_cname,
5972 "GLOBALS": Naming.module_cname,
5973 })
5975 #------------------------------------------------------------------------------------
5977 get_exception_utility_code = UtilityCode(
5978 proto = """
5979 static PyObject *__Pyx_GetExcValue(void); /*proto*/
5980 """,
5981 impl = """
5982 static PyObject *__Pyx_GetExcValue(void) {
5983 PyObject *type = 0, *value = 0, *tb = 0;
5984 PyObject *tmp_type, *tmp_value, *tmp_tb;
5985 PyObject *result = 0;
5986 PyThreadState *tstate = PyThreadState_Get();
5987 PyErr_Fetch(&type, &value, &tb);
5988 PyErr_NormalizeException(&type, &value, &tb);
5989 if (PyErr_Occurred())
5990 goto bad;
5991 if (!value) {
5992 value = Py_None;
5993 Py_INCREF(value);
5995 tmp_type = tstate->exc_type;
5996 tmp_value = tstate->exc_value;
5997 tmp_tb = tstate->exc_traceback;
5998 tstate->exc_type = type;
5999 tstate->exc_value = value;
6000 tstate->exc_traceback = tb;
6001 /* Make sure tstate is in a consistent state when we XDECREF
6002 these objects (XDECREF may run arbitrary code). */
6003 Py_XDECREF(tmp_type);
6004 Py_XDECREF(tmp_value);
6005 Py_XDECREF(tmp_tb);
6006 result = value;
6007 Py_XINCREF(result);
6008 type = 0;
6009 value = 0;
6010 tb = 0;
6011 bad:
6012 Py_XDECREF(type);
6013 Py_XDECREF(value);
6014 Py_XDECREF(tb);
6015 return result;
6017 """)
6019 #------------------------------------------------------------------------------------
6021 type_test_utility_code = UtilityCode(
6022 proto = """
6023 static INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
6024 """,
6025 impl = """
6026 static INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
6027 if (unlikely(!type)) {
6028 PyErr_Format(PyExc_SystemError, "Missing type object");
6029 return 0;
6031 if (likely(PyObject_TypeCheck(obj, type)))
6032 return 1;
6033 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
6034 Py_TYPE(obj)->tp_name, type->tp_name);
6035 return 0;
6037 """)
6039 #------------------------------------------------------------------------------------
6041 create_class_utility_code = UtilityCode(
6042 proto = """
6043 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/
6044 """,
6045 impl = """
6046 static PyObject *__Pyx_CreateClass(
6047 PyObject *bases, PyObject *dict, PyObject *name, const char *modname)
6049 PyObject *py_modname;
6050 PyObject *result = 0;
6052 #if PY_MAJOR_VERSION < 3
6053 py_modname = PyString_FromString(modname);
6054 #else
6055 py_modname = PyUnicode_FromString(modname);
6056 #endif
6057 if (!py_modname)
6058 goto bad;
6059 if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
6060 goto bad;
6061 #if PY_MAJOR_VERSION < 3
6062 result = PyClass_New(bases, dict, name);
6063 #else
6064 result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
6065 #endif
6066 bad:
6067 Py_XDECREF(py_modname);
6068 return result;
6070 """)
6072 #------------------------------------------------------------------------------------
6074 cpp_exception_utility_code = UtilityCode(
6075 proto = """
6076 #ifndef __Pyx_CppExn2PyErr
6077 static void __Pyx_CppExn2PyErr() {
6078 try {
6079 if (PyErr_Occurred())
6080 ; // let the latest Python exn pass through and ignore the current one
6081 else
6082 throw;
6083 } catch (const std::out_of_range& exn) {
6084 // catch out_of_range explicitly so the proper Python exn may be raised
6085 PyErr_SetString(PyExc_IndexError, exn.what());
6086 } catch (const std::exception& exn) {
6087 PyErr_SetString(PyExc_RuntimeError, exn.what());
6089 catch (...)
6091 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
6094 #endif
6095 """,
6096 impl = ""
6099 #------------------------------------------------------------------------------------
6101 # If the is_unsigned flag is set, we need to do some extra work to make
6102 # sure the index doesn't become negative.
6104 getitem_int_utility_code = UtilityCode(
6105 proto = """
6107 static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
6108 PyObject *r;
6109 if (!j) return NULL;
6110 r = PyObject_GetItem(o, j);
6111 Py_DECREF(j);
6112 return r;
6115 """ + ''.join([
6116 """
6117 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6118 __Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\
6119 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
6121 static INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6122 if (likely(o != Py_None)) {
6123 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
6124 PyObject *r = Py%(type)s_GET_ITEM(o, i);
6125 Py_INCREF(r);
6126 return r;
6128 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
6129 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
6130 Py_INCREF(r);
6131 return r;
6134 return __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
6136 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
6137 ]) + """
6139 #define __Pyx_GetItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6140 __Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\
6141 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
6143 static INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6144 PyObject *r;
6145 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
6146 r = PyList_GET_ITEM(o, i);
6147 Py_INCREF(r);
6149 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
6150 r = PyTuple_GET_ITEM(o, i);
6151 Py_INCREF(r);
6153 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
6154 r = PySequence_GetItem(o, i);
6156 else {
6157 r = __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
6159 return r;
6161 """,
6162 impl = """
6163 """)
6167 #------------------------------------------------------------------------------------
6169 setitem_int_utility_code = UtilityCode(
6170 proto = """
6171 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6172 __Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\
6173 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
6175 static INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
6176 int r;
6177 if (!j) return -1;
6178 r = PyObject_SetItem(o, j, v);
6179 Py_DECREF(j);
6180 return r;
6183 static INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
6184 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
6185 Py_INCREF(v);
6186 Py_DECREF(PyList_GET_ITEM(o, i));
6187 PyList_SET_ITEM(o, i, v);
6188 return 1;
6190 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
6191 return PySequence_SetItem(o, i, v);
6192 else {
6193 PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
6194 return __Pyx_SetItemInt_Generic(o, j, v);
6197 """,
6198 impl = """
6199 """)
6201 #------------------------------------------------------------------------------------
6203 delitem_int_utility_code = UtilityCode(
6204 proto = """
6205 #define __Pyx_DelItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6206 __Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\
6207 __Pyx_DelItem_Generic(o, to_py_func(i)))
6209 static INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
6210 int r;
6211 if (!j) return -1;
6212 r = PyObject_DelItem(o, j);
6213 Py_DECREF(j);
6214 return r;
6217 static INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6218 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
6219 return PySequence_DelItem(o, i);
6220 else {
6221 PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
6222 return __Pyx_DelItem_Generic(o, j);
6225 """,
6226 impl = """
6227 """)
6229 #------------------------------------------------------------------------------------
6231 raise_noneattr_error_utility_code = UtilityCode(
6232 proto = """
6233 static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
6234 """,
6235 impl = '''
6236 static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
6237 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
6239 ''')
6241 raise_noneindex_error_utility_code = UtilityCode(
6242 proto = """
6243 static INLINE void __Pyx_RaiseNoneIndexingError(void);
6244 """,
6245 impl = '''
6246 static INLINE void __Pyx_RaiseNoneIndexingError(void) {
6247 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
6249 ''')
6251 raise_none_iter_error_utility_code = UtilityCode(
6252 proto = """
6253 static INLINE void __Pyx_RaiseNoneNotIterableError(void);
6254 """,
6255 impl = '''
6256 static INLINE void __Pyx_RaiseNoneNotIterableError(void) {
6257 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
6259 ''')
6261 raise_too_many_values_to_unpack = UtilityCode(
6262 proto = """
6263 static INLINE void __Pyx_RaiseTooManyValuesError(void);
6264 """,
6265 impl = '''
6266 static INLINE void __Pyx_RaiseTooManyValuesError(void) {
6267 PyErr_SetString(PyExc_ValueError, "too many values to unpack");
6269 ''')
6271 raise_need_more_values_to_unpack = UtilityCode(
6272 proto = """
6273 static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
6274 """,
6275 impl = '''
6276 static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
6277 PyErr_Format(PyExc_ValueError,
6278 #if PY_VERSION_HEX < 0x02050000
6279 "need more than %d value%s to unpack", (int)index,
6280 #else
6281 "need more than %zd value%s to unpack", index,
6282 #endif
6283 (index == 1) ? "" : "s");
6285 ''')
6287 #------------------------------------------------------------------------------------
6289 tuple_unpacking_error_code = UtilityCode(
6290 proto = """
6291 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
6292 """,
6293 impl = """
6294 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
6295 if (t == Py_None) {
6296 __Pyx_RaiseNoneNotIterableError();
6297 } else if (PyTuple_GET_SIZE(t) < index) {
6298 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
6299 } else {
6300 __Pyx_RaiseTooManyValuesError();
6303 """,
6304 requires = [raise_none_iter_error_utility_code,
6305 raise_need_more_values_to_unpack,
6306 raise_too_many_values_to_unpack]
6309 unpacking_utility_code = UtilityCode(
6310 proto = """
6311 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
6312 static int __Pyx_EndUnpack(PyObject *); /*proto*/
6313 """,
6314 impl = """
6315 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
6316 PyObject *item;
6317 if (!(item = PyIter_Next(iter))) {
6318 if (!PyErr_Occurred()) {
6319 __Pyx_RaiseNeedMoreValuesError(index);
6322 return item;
6325 static int __Pyx_EndUnpack(PyObject *iter) {
6326 PyObject *item;
6327 if ((item = PyIter_Next(iter))) {
6328 Py_DECREF(item);
6329 __Pyx_RaiseTooManyValuesError();
6330 return -1;
6332 else if (!PyErr_Occurred())
6333 return 0;
6334 else
6335 return -1;
6337 """,
6338 requires = [raise_need_more_values_to_unpack,
6339 raise_too_many_values_to_unpack]
6343 #------------------------------------------------------------------------------------
6345 int_pow_utility_code = UtilityCode(
6346 proto="""
6347 static INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
6348 """,
6349 impl="""
6350 static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
6351 %(type)s t = b;
6352 switch (e) {
6353 case 3:
6354 t *= b;
6355 case 2:
6356 t *= b;
6357 case 1:
6358 return t;
6359 case 0:
6360 return 1;
6362 if (unlikely(e<0)) return 0;
6363 t = 1;
6364 while (likely(e)) {
6365 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
6366 b *= b;
6367 e >>= 1;
6369 return t;
6371 """)
6373 # ------------------------------ Division ------------------------------------
6375 div_int_utility_code = UtilityCode(
6376 proto="""
6377 static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
6378 """,
6379 impl="""
6380 static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
6381 %(type)s q = a / b;
6382 %(type)s r = a - q*b;
6383 q -= ((r != 0) & ((r ^ b) < 0));
6384 return q;
6386 """)
6388 mod_int_utility_code = UtilityCode(
6389 proto="""
6390 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6391 """,
6392 impl="""
6393 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6394 %(type)s r = a %% b;
6395 r += ((r != 0) & ((r ^ b) < 0)) * b;
6396 return r;
6398 """)
6400 mod_float_utility_code = UtilityCode(
6401 proto="""
6402 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6403 """,
6404 impl="""
6405 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6406 %(type)s r = fmod%(math_h_modifier)s(a, b);
6407 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
6408 return r;
6410 """)
6412 cdivision_warning_utility_code = UtilityCode(
6413 proto="""
6414 static int __Pyx_cdivision_warning(void); /* proto */
6415 """,
6416 impl="""
6417 static int __Pyx_cdivision_warning(void) {
6418 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
6419 "division with oppositely signed operands, C and Python semantics differ",
6420 %(FILENAME)s,
6421 %(LINENO)s,
6422 __Pyx_MODULE_NAME,
6423 NULL);
6425 """ % {
6426 'FILENAME': Naming.filename_cname,
6427 'LINENO': Naming.lineno_cname,
6428 })
6430 # from intobject.c
6431 division_overflow_test_code = UtilityCode(
6432 proto="""
6433 #define UNARY_NEG_WOULD_OVERFLOW(x) \
6434 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
6435 """)