2 # Pyrex - Parse tree nodes for expressions
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
13 from Nodes import Node
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
21 from Annotate import AnnotationItem
23 from Cython.Debugging import print_call_chain
24 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
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",
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')
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.
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:
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
83 # Allocates temporary variables where needed, and fills
84 # in the result_code field of each node.
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.
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.
99 # The framework makes use of a number of abstract methods.
100 # Their responsibilities are as follows.
102 # Declaration Analysis phase
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
110 # Expression Analysis phase
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.
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.
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.
131 # - Check that this node and its subnodes form a
132 # legal constant expression. If so, do nothing,
133 # otherwise call not_const.
135 # The default implementation of check_const
136 # assumes that the expression is not constant.
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.
143 # The default implementation of calc_const_addr
144 # assumes that the expression is not a constant
147 # Code Generation phase
149 # generate_evaluation_code
150 # - Call generate_evaluation_code for sub-expressions.
151 # - Perform the functions of generate_result_code
153 # - If result is temporary, call generate_disposal_code
154 # on all sub-expressions.
156 # A default implementation of generate_evaluation_code
157 # is provided which uses the following abstract methods:
159 # generate_result_code
160 # - Generate any C statements necessary to calculate
161 # the result of this node from the results of its
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
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.
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.
185 is_sequence_constructor = 0
188 saved_subexpr_nodes = None
193 constant_result = constant_value_not_set
196 _get_child_attrs = operator.attrgetter('subexprs')
197 except AttributeError:
199 def _get_child_attrs(self):
201 child_attrs = property(fget=_get_child_attrs)
203 def not_implemented(self, method_name):
204 print_call_chain(method_name, "not implemented") ###
206 "%s.%s not implemented" %
207 (self.__class__.__name__, method_name))
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.
224 for name in self.subexprs:
225 item = getattr(self, name)
227 if type(item) is list:
235 return self.temp_code
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())
244 # Return the result code cast to PyObject *.
245 return self.result_as(py_object_type)
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.
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.
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
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.
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
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
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)
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)
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:
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:
345 elif hasattr(self, 'entry') and self.entry is not None:
346 return self.entry.type
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.
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.
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.
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:
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):
389 error(self.pos, "Not allowed in a constant expression")
391 def check_const_addr(self):
392 self.addr_not_const()
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
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):
420 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
424 type = PyrexTypes.py_object_type
425 self.temp_code = code.funcstate.allocate_temp(
426 type, manage_ref=self.use_managed_ref)
428 self.temp_code = None
430 def release_temp_result(self, code):
431 if not self.temp_code:
433 raise RuntimeError("temp %s released multiple times in %s" % (
434 self.old_temp, self.__class__.__name__))
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
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)
459 self.allocate_temp_result(code)
461 self.generate_result_code(code)
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):
477 if self.type.is_pyobject:
478 code.put_decref_clear(self.result(), self.ctype())
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):
491 if self.type.is_pyobject:
492 code.putln("%s = 0;" % self.result())
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.
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.
508 def free_temps(self, code):
510 if not self.type.is_void:
511 self.release_temp_result(code)
513 self.free_subexpr_temps(code)
515 def free_subexpr_temps(self, code):
516 for sub in self.subexpr_nodes():
519 # ---------------- Annotation ---------------------
521 def annotate(self, code):
522 for node in self.subexpr_nodes():
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.
533 # This method is called during the analyse_expressions
534 # phase of the src_node's processing.
536 # Note that subclasses that override this (especially
537 # ConstNodes) must not (re-)set their own .type attribute
538 # here. Since expression nodes may turn up in different
539 # places in the tree (e.g. inside of CloneNodes in cascaded
540 # assignments), this method must return a new node instance
541 # if it changes the type.
545 src_is_py_type = src_type.is_pyobject
546 dst_is_py_type = dst_type.is_pyobject
548 if self.check_for_coercion_error(dst_type):
551 if dst_type.is_pyobject:
552 if not src.type.is_pyobject:
553 src = CoerceToPyTypeNode(src, env)
554 if not src.type.subtype_of(dst_type):
555 if not isinstance(src, NoneNode):
556 src = PyTypeTestNode(src, dst_type, env)
557 elif src.type.is_pyobject:
558 src = CoerceFromPyTypeNode(dst_type, src, env)
559 elif (dst_type.is_complex
560 and src_type != dst_type
561 and dst_type.assignable_from(src_type)):
562 src = CoerceToComplexNode(src, dst_type, env)
563 else: # neither src nor dst are py types
564 # Added the string comparison, since for c types that
565 # is enough, but Cython gets confused when the types are
566 # in different pxi files.
567 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
568 self.fail_assignment(dst_type)
571 def fail_assignment(self, dst_type):
572 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
574 def check_for_coercion_error(self, dst_type, fail=False, default=None):
575 if fail and not default:
576 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
577 message = find_coercion_error((self.type, dst_type), default)
578 if message is not None:
579 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
582 self.fail_assignment(dst_type)
586 def coerce_to_pyobject(self, env):
587 return self.coerce_to(PyrexTypes.py_object_type, env)
589 def coerce_to_boolean(self, env):
590 # Coerce result to something acceptable as
593 if type.is_pyobject or type.is_ptr or type.is_float:
594 return CoerceToBooleanNode(self, env)
596 if not type.is_int and not type.is_error:
598 "Type '%s' not acceptable as a boolean" % type)
601 def coerce_to_integer(self, env):
602 # If not already some C integer type, coerce to longint.
606 return self.coerce_to(PyrexTypes.c_long_type, env)
608 def coerce_to_temp(self, env):
609 # Ensure that the result is in a temporary.
610 if self.result_in_temp():
613 return CoerceToTempNode(self, env)
615 def coerce_to_simple(self, env):
616 # Ensure that the result is simple (see is_simple).
620 return self.coerce_to_temp(env)
623 # A node is simple if its result is something that can
624 # be referred to without performing any operations, e.g.
625 # a constant, local var, C global var, struct member
626 # reference, or temporary.
627 return self.result_in_temp()
629 def as_cython_attribute(self):
632 class AtomicExprNode(ExprNode):
633 # Abstract base class for expression nodes which have
634 # no sub-expressions.
638 # Override to optimize -- we know we have no children
639 def generate_subexpr_evaluation_code(self, code):
641 def generate_subexpr_disposal_code(self, code):
644 class PyConstNode(AtomicExprNode):
645 # Abstract base class for constant Python values.
648 type = py_object_type
653 def analyse_types(self, env):
656 def calculate_result_code(self):
659 def generate_result_code(self, code):
663 class NoneNode(PyConstNode):
664 # The constant value None
668 constant_result = None
672 def compile_time_value(self, denv):
675 class EllipsisNode(PyConstNode):
676 # '...' in a subscript list.
678 value = "Py_Ellipsis"
680 constant_result = Ellipsis
682 def compile_time_value(self, denv):
686 class ConstNode(AtomicExprNode):
687 # Abstract base type for literal constant nodes.
689 # value string C code fragment
697 def analyse_types(self, env):
698 pass # Types are held in class variables
700 def check_const(self):
703 def get_constant_c_result_code(self):
704 return self.calculate_result_code()
706 def calculate_result_code(self):
707 return str(self.value)
709 def generate_result_code(self, code):
713 class BoolNode(ConstNode):
714 type = PyrexTypes.c_bint_type
715 # The constant value True or False
717 def calculate_constant_result(self):
718 self.constant_result = self.value
720 def compile_time_value(self, denv):
723 def calculate_result_code(self):
724 return str(int(self.value))
727 class NullNode(ConstNode):
728 type = PyrexTypes.c_null_ptr_type
732 def get_constant_c_result_code(self):
736 class CharNode(ConstNode):
737 type = PyrexTypes.c_char_type
739 def calculate_constant_result(self):
740 self.constant_result = ord(self.value)
742 def compile_time_value(self, denv):
743 return ord(self.value)
745 def calculate_result_code(self):
746 return "'%s'" % StringEncoding.escape_char(self.value)
749 class IntNode(ConstNode):
752 # longness "" or "L" or "LL"
756 type = PyrexTypes.c_long_type
758 def coerce_to(self, dst_type, env):
759 if self.type is dst_type:
761 node = IntNode(self.pos, value=self.value,
762 unsigned=self.unsigned, longness=self.longness)
763 if dst_type.is_numeric and not dst_type.is_complex:
765 if dst_type.is_pyobject:
766 node.type = PyrexTypes.py_object_type
767 # We still need to perform normal coerce_to processing on the
768 # result, because we might be coercing to an extension type,
769 # in which case a type test node will be needed.
770 return ConstNode.coerce_to(node, dst_type, env)
772 def coerce_to_boolean(self, env):
774 self.pos, value=self.value,
775 type = PyrexTypes.c_bint_type,
776 unsigned=self.unsigned, longness=self.longness)
778 def generate_evaluation_code(self, code):
779 if self.type.is_pyobject:
780 # pre-allocate a Python version of the number
781 self.result_code = code.get_py_num(self.value, self.longness)
783 self.result_code = self.get_constant_c_result_code()
785 def get_constant_c_result_code(self):
786 return str(self.value) + self.unsigned + self.longness
788 def calculate_result_code(self):
789 return self.result_code
791 def calculate_constant_result(self):
792 self.constant_result = int(self.value, 0)
794 def compile_time_value(self, denv):
795 return int(self.value, 0)
798 class FloatNode(ConstNode):
799 type = PyrexTypes.c_double_type
801 def calculate_constant_result(self):
802 self.constant_result = float(self.value)
804 def compile_time_value(self, denv):
805 return float(self.value)
807 def calculate_result_code(self):
808 strval = repr(float(self.value))
810 return "(Py_HUGE_VAL * 0)"
811 elif strval == 'inf':
813 elif strval == '-inf':
814 return "(-Py_HUGE_VAL)"
819 class BytesNode(ConstNode):
820 # A char* or bytes literal
824 type = PyrexTypes.c_char_ptr_type
826 def compile_time_value(self, denv):
829 def analyse_as_type(self, env):
830 type = PyrexTypes.parse_basic_type(self.value)
833 from TreeFragment import TreeFragment
834 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
835 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
836 sizeof_node = declaration.root.stats[0].expr
837 sizeof_node.analyse_types(env)
838 if isinstance(sizeof_node, SizeofTypeNode):
839 return sizeof_node.arg_type
841 def can_coerce_to_char_literal(self):
842 return len(self.value) == 1
844 def coerce_to(self, dst_type, env):
846 if not self.can_coerce_to_char_literal():
847 error(self.pos, "Only single-character strings can be coerced into ints.")
849 return CharNode(self.pos, value=self.value)
851 node = BytesNode(self.pos, value=self.value)
852 if dst_type == PyrexTypes.c_char_ptr_type:
853 node.type = PyrexTypes.c_char_ptr_type
855 elif dst_type == PyrexTypes.c_uchar_ptr_type:
856 node.type = PyrexTypes.c_char_ptr_type
857 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
859 if not self.type.is_pyobject:
860 if dst_type in (py_object_type, Builtin.bytes_type):
861 node.type = Builtin.bytes_type
862 elif dst_type.is_pyobject:
863 self.fail_assignment(dst_type)
865 elif dst_type.is_pyobject and dst_type is not py_object_type:
866 self.check_for_coercion_error(dst_type, fail=True)
869 # We still need to perform normal coerce_to processing on the
870 # result, because we might be coercing to an extension type,
871 # in which case a type test node will be needed.
872 return ConstNode.coerce_to(node, dst_type, env)
874 def as_py_string_node(self, env):
875 # Return a new BytesNode with the same value as this node
876 # but whose type is a Python type instead of a C type.
877 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
879 def generate_evaluation_code(self, code):
880 if self.type.is_pyobject:
881 self.result_code = code.get_py_string_const(self.value)
883 self.result_code = code.get_string_const(self.value)
885 def get_constant_c_result_code(self):
888 def calculate_result_code(self):
889 return self.result_code
892 class UnicodeNode(PyConstNode):
893 # A Python unicode object
895 # value EncodedString
899 def coerce_to(self, dst_type, env):
900 if dst_type is self.type:
902 elif not dst_type.is_pyobject:
903 error(self.pos, "Unicode objects do not support coercion to C types.")
904 elif dst_type is not py_object_type:
905 if not self.check_for_coercion_error(dst_type):
906 self.fail_assignment(dst_type)
909 def generate_evaluation_code(self, code):
910 self.result_code = code.get_py_string_const(self.value)
912 def calculate_result_code(self):
913 return self.result_code
915 def compile_time_value(self, env):
919 class StringNode(PyConstNode):
920 # A Python str object, i.e. a byte string in Python 2.x and a
921 # unicode string in Python 3.x
923 # value BytesLiteral or EncodedString
924 # is_identifier boolean
929 def coerce_to(self, dst_type, env):
930 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
931 # if dst_type is Builtin.bytes_type:
932 # # special case: bytes = 'str literal'
933 # return BytesNode(self.pos, value=self.value)
934 if not dst_type.is_pyobject:
935 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
936 self.check_for_coercion_error(dst_type, fail=True)
938 # this will be a unicode string in Py3, so make sure we can decode it
939 if self.value.encoding:
940 encoding = self.value.encoding
942 self.value.decode(encoding)
943 except UnicodeDecodeError:
944 error(self.pos, "String decoding as '%s' failed. Consider using a byte string or unicode string explicitly, or adjust the source code encoding." % encoding)
948 def can_coerce_to_char_literal(self):
949 return not self.is_identifier and len(self.value) == 1
951 def generate_evaluation_code(self, code):
952 self.result_code = code.get_py_string_const(
953 self.value, identifier=self.is_identifier, is_str=True)
955 def get_constant_c_result_code(self):
958 def calculate_result_code(self):
959 return self.result_code
961 def compile_time_value(self, env):
965 class IdentifierStringNode(StringNode):
966 # A special str value that represents an identifier (bytes in Py2,
971 class LongNode(AtomicExprNode):
972 # Python long integer literal
976 type = py_object_type
978 def calculate_constant_result(self):
979 self.constant_result = long(self.value)
981 def compile_time_value(self, denv):
982 return long(self.value)
984 def analyse_types(self, env):
987 gil_message = "Constructing Python long int"
989 def generate_result_code(self, code):
991 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
994 code.error_goto_if_null(self.result(), self.pos)))
995 code.put_gotref(self.py_result())
998 class ImagNode(AtomicExprNode):
999 # Imaginary number literal
1001 # value float imaginary part
1003 type = PyrexTypes.c_double_complex_type
1005 def calculate_constant_result(self):
1006 self.constant_result = complex(0.0, self.value)
1008 def compile_time_value(self, denv):
1009 return complex(0.0, self.value)
1011 def analyse_types(self, env):
1012 self.type.create_declaration_utility_code(env)
1014 def coerce_to(self, dst_type, env):
1015 if self.type is dst_type:
1017 node = ImagNode(self.pos, value=self.value)
1018 if dst_type.is_pyobject:
1020 node.type = PyrexTypes.py_object_type
1021 # We still need to perform normal coerce_to processing on the
1022 # result, because we might be coercing to an extension type,
1023 # in which case a type test node will be needed.
1024 return AtomicExprNode.coerce_to(node, dst_type, env)
1026 gil_message = "Constructing complex number"
1028 def calculate_result_code(self):
1029 if self.type.is_pyobject:
1030 return self.result()
1032 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1034 def generate_result_code(self, code):
1035 if self.type.is_pyobject:
1037 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1040 code.error_goto_if_null(self.result(), self.pos)))
1041 code.put_gotref(self.py_result())
1044 class NewExprNode(AtomicExprNode):
1048 # cppclass node c++ class to create
1052 def infer_type(self, env):
1053 type = self.cppclass.analyse_as_type(env)
1054 if type is None or not type.is_cpp_class:
1055 error(self.pos, "new operator can only be applied to a C++ class")
1056 self.type = error_type
1059 constructor = type.scope.lookup(u'<init>')
1060 if constructor is None:
1061 return_type = PyrexTypes.CFuncType(type, [])
1062 return_type = PyrexTypes.CPtrType(return_type)
1063 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1064 constructor = type.scope.lookup(u'<init>')
1065 self.class_type = type
1066 self.entry = constructor
1067 self.type = constructor.type
1070 def analyse_types(self, env):
1071 if self.type is None:
1072 self.infer_type(env)
1074 def generate_result_code(self, code):
1077 def calculate_result_code(self):
1078 return "new " + self.class_type.declaration_code("")
1081 class NameNode(AtomicExprNode):
1082 # Reference to a local or global variable name.
1084 # name string Python name of the variable
1085 # entry Entry Symbol table entry
1086 # type_entry Entry For extension type names, the original type entry
1089 is_cython_module = False
1090 cython_attribute = None
1091 lhs_of_first_assignment = False
1092 is_used_as_rvalue = 0
1096 def create_analysed_rvalue(pos, env, entry):
1097 node = NameNode(pos)
1098 node.analyse_types(env, entry=entry)
1101 def as_cython_attribute(self):
1102 return self.cython_attribute
1104 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1106 def type_dependencies(self, env):
1107 if self.entry is None:
1108 self.entry = env.lookup(self.name)
1109 if self.entry is not None and self.entry.type.is_unspecified:
1110 return (self.entry,)
1114 def infer_type(self, env):
1115 if self.entry is None:
1116 self.entry = env.lookup(self.name)
1117 if self.entry is None:
1118 return py_object_type
1119 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1120 self.name == self.entry.type.name:
1121 # Unfortunately the type attribute of type objects
1122 # is used for the pointer to the type they represent.
1125 return self.entry.type
1127 def compile_time_value(self, denv):
1129 return denv.lookup(self.name)
1131 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1133 def get_constant_c_result_code(self):
1134 if not self.entry or self.entry.type.is_pyobject:
1136 return self.entry.cname
1138 def coerce_to(self, dst_type, env):
1139 # If coercing to a generic pyobject and this is a builtin
1140 # C function with a Python equivalent, manufacture a NameNode
1141 # referring to the Python builtin.
1142 #print "NameNode.coerce_to:", self.name, dst_type ###
1143 if dst_type is py_object_type:
1145 if entry and entry.is_cfunction:
1146 var_entry = entry.as_variable
1148 if var_entry.is_builtin and Options.cache_builtins:
1149 var_entry = env.declare_builtin(var_entry.name, self.pos)
1150 node = NameNode(self.pos, name = self.name)
1151 node.entry = var_entry
1152 node.analyse_rvalue_entry(env)
1154 return super(NameNode, self).coerce_to(dst_type, env)
1156 def analyse_as_module(self, env):
1157 # Try to interpret this as a reference to a cimported module.
1158 # Returns the module scope, or None.
1161 entry = env.lookup(self.name)
1162 if entry and entry.as_module:
1163 return entry.as_module
1166 def analyse_as_type(self, env):
1167 if self.cython_attribute:
1168 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1170 type = PyrexTypes.parse_basic_type(self.name)
1175 entry = env.lookup(self.name)
1176 if entry and entry.is_type:
1181 def analyse_as_extension_type(self, env):
1182 # Try to interpret this as a reference to an extension type.
1183 # Returns the extension type, or None.
1186 entry = env.lookup(self.name)
1187 if entry and entry.is_type and entry.type.is_extension_type:
1192 def analyse_target_declaration(self, env):
1194 self.entry = env.lookup_here(self.name)
1196 if env.directives['warn.undeclared']:
1197 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1198 if env.directives['infer_types'] != False:
1199 type = unspecified_type
1201 type = py_object_type
1202 self.entry = env.declare_var(self.name, type, self.pos)
1203 env.control_flow.set_state(self.pos, (self.name, 'initalized'), True)
1204 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1205 if self.entry.is_declared_generic:
1206 self.result_ctype = py_object_type
1208 def analyse_types(self, env):
1209 if self.entry is None:
1210 self.entry = env.lookup(self.name)
1212 self.entry = env.declare_builtin(self.name, self.pos)
1214 self.type = PyrexTypes.error_type
1219 if entry.type.is_buffer:
1221 Buffer.used_buffer_aux_vars(entry)
1222 if entry.utility_code:
1223 env.use_utility_code(entry.utility_code)
1224 self.analyse_rvalue_entry(env)
1226 def analyse_target_types(self, env):
1227 self.analyse_entry(env)
1228 if not self.is_lvalue():
1229 error(self.pos, "Assignment to non-lvalue '%s'"
1231 self.type = PyrexTypes.error_type
1233 if self.entry.type.is_buffer:
1235 Buffer.used_buffer_aux_vars(self.entry)
1237 def analyse_rvalue_entry(self, env):
1238 #print "NameNode.analyse_rvalue_entry:", self.name ###
1239 #print "Entry:", self.entry.__dict__ ###
1240 self.analyse_entry(env)
1242 if entry.is_declared_generic:
1243 self.result_ctype = py_object_type
1244 if entry.is_pyglobal or entry.is_builtin:
1245 if Options.cache_builtins and entry.is_builtin:
1249 env.use_utility_code(get_name_interned_utility_code)
1250 self.is_used_as_rvalue = 1
1252 def nogil_check(self, env):
1253 if self.is_used_as_rvalue:
1255 if entry.is_builtin:
1256 # if not Options.cache_builtins: # cached builtins are ok
1258 elif entry.is_pyglobal:
1261 gil_message = "Accessing Python global or builtin"
1263 def analyse_entry(self, env):
1264 #print "NameNode.analyse_entry:", self.name ###
1265 self.check_identifier_kind()
1270 def check_identifier_kind(self):
1271 # Check that this is an appropriate kind of name for use in an
1272 # expression. Also finds the variable entry associated with
1273 # an extension type.
1275 if entry.is_type and entry.type.is_extension_type:
1276 self.type_entry = entry
1277 if not (entry.is_const or entry.is_variable
1278 or entry.is_builtin or entry.is_cfunction
1279 or entry.is_cpp_class):
1280 if self.entry.as_variable:
1281 self.entry = self.entry.as_variable
1284 "'%s' is not a constant, variable or function identifier" % self.name)
1286 def is_simple(self):
1287 # If it's not a C variable, it'll be in a temp.
1290 def calculate_target_results(self, env):
1293 def check_const(self):
1295 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1300 def check_const_addr(self):
1302 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1303 self.addr_not_const()
1307 def is_lvalue(self):
1308 return self.entry.is_variable and \
1309 not self.entry.type.is_array and \
1310 not self.entry.is_readonly
1312 def is_ephemeral(self):
1313 # Name nodes are never ephemeral, even if the
1314 # result is in a temporary.
1317 def calculate_result_code(self):
1320 return "<error>" # There was an error earlier
1323 def generate_result_code(self, code):
1324 assert hasattr(self, 'entry')
1327 return # There was an error earlier
1328 if entry.is_builtin and Options.cache_builtins:
1329 return # Lookup already cached
1330 elif entry.is_pyglobal or entry.is_builtin:
1331 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1332 interned_cname = code.intern_identifier(self.entry.name)
1333 if entry.is_builtin:
1334 namespace = Naming.builtins_cname
1335 else: # entry.is_pyglobal
1336 namespace = entry.scope.namespace_cname
1337 code.globalstate.use_utility_code(get_name_interned_utility_code)
1339 '%s = __Pyx_GetName(%s, %s); %s' % (
1343 code.error_goto_if_null(self.result(), self.pos)))
1344 code.put_gotref(self.py_result())
1346 elif entry.is_local and False:
1347 # control flow not good enough yet
1348 assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1349 if assigned is False:
1350 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1351 elif not Options.init_local_none and assigned is None:
1352 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1353 (entry.cname, entry.name, code.error_goto(self.pos)))
1354 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True)
1356 def generate_assignment_code(self, rhs, code):
1357 #print "NameNode.generate_assignment_code:", self.name ###
1360 return # There was an error earlier
1362 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1363 and not self.lhs_of_first_assignment):
1364 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1366 # is_pyglobal seems to be True for module level-globals only.
1367 # We use this to access class->tp_dict if necessary.
1368 if entry.is_pyglobal:
1369 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1370 interned_cname = code.intern_identifier(self.entry.name)
1371 namespace = self.entry.scope.namespace_cname
1373 # if the entry is a member we have to cheat: SetAttr does not work
1374 # on types, so we create a descriptor which is then added to tp_dict
1375 code.put_error_if_neg(self.pos,
1376 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1380 rhs.generate_disposal_code(code)
1381 rhs.free_temps(code)
1382 # in Py2.6+, we need to invalidate the method cache
1383 code.putln("PyType_Modified(%s);" %
1384 entry.scope.parent_type.typeptr_cname)
1386 code.put_error_if_neg(self.pos,
1387 'PyObject_SetAttr(%s, %s, %s)' % (
1391 if debug_disposal_code:
1392 print("NameNode.generate_assignment_code:")
1393 print("...generating disposal code for %s" % rhs)
1394 rhs.generate_disposal_code(code)
1395 rhs.free_temps(code)
1397 if self.type.is_buffer:
1398 # Generate code for doing the buffer release/acquisition.
1399 # This might raise an exception in which case the assignment (done
1400 # below) will not happen.
1402 # The reason this is not in a typetest-like node is because the
1403 # variables that the acquired buffer info is stored to is allocated
1404 # per entry and coupled with it.
1405 self.generate_acquire_buffer(rhs, code)
1407 if self.type.is_pyobject:
1408 #print "NameNode.generate_assignment_code: to", self.name ###
1409 #print "...from", rhs ###
1410 #print "...LHS type", self.type, "ctype", self.ctype() ###
1411 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1412 if self.use_managed_ref:
1413 rhs.make_owned_reference(code)
1414 if entry.is_cglobal:
1415 code.put_gotref(self.py_result())
1416 if self.use_managed_ref and not self.lhs_of_first_assignment:
1417 if entry.is_local and not Options.init_local_none:
1418 initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1419 if initalized is True:
1420 code.put_decref(self.result(), self.ctype())
1421 elif initalized is None:
1422 code.put_xdecref(self.result(), self.ctype())
1424 code.put_decref(self.result(), self.ctype())
1425 if self.use_managed_ref:
1426 if entry.is_cglobal:
1427 code.put_giveref(rhs.py_result())
1428 code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
1429 if debug_disposal_code:
1430 print("NameNode.generate_assignment_code:")
1431 print("...generating post-assignment code for %s" % rhs)
1432 rhs.generate_post_assignment_code(code)
1433 rhs.free_temps(code)
1435 def generate_acquire_buffer(self, rhs, code):
1436 # rhstmp is only used in case the rhs is a complicated expression leading to
1437 # the object, to avoid repeating the same C expression for every reference
1438 # to the rhs. It does NOT hold a reference.
1439 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1441 rhstmp = rhs.result_as(self.ctype())
1443 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1444 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1446 buffer_aux = self.entry.buffer_aux
1447 bufstruct = buffer_aux.buffer_info_var.cname
1449 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1450 is_initialized=not self.lhs_of_first_assignment,
1451 pos=self.pos, code=code)
1454 code.putln("%s = 0;" % rhstmp)
1455 code.funcstate.release_temp(rhstmp)
1457 def generate_deletion_code(self, code):
1458 if self.entry is None:
1459 return # There was an error earlier
1460 if not self.entry.is_pyglobal:
1461 error(self.pos, "Deletion of local or C global name not supported")
1463 code.put_error_if_neg(self.pos,
1464 '__Pyx_DelAttrString(%s, "%s")' % (
1465 Naming.module_cname,
1468 def annotate(self, code):
1469 if hasattr(self, 'is_called') and self.is_called:
1470 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1471 if self.type.is_pyobject:
1472 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1474 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1476 class BackquoteNode(ExprNode):
1481 type = py_object_type
1485 def analyse_types(self, env):
1486 self.arg.analyse_types(env)
1487 self.arg = self.arg.coerce_to_pyobject(env)
1490 gil_message = "Backquote expression"
1492 def calculate_constant_result(self):
1493 self.constant_result = repr(self.arg.constant_result)
1495 def generate_result_code(self, code):
1497 "%s = PyObject_Repr(%s); %s" % (
1499 self.arg.py_result(),
1500 code.error_goto_if_null(self.result(), self.pos)))
1501 code.put_gotref(self.py_result())
1505 class ImportNode(ExprNode):
1506 # Used as part of import statement implementation.
1507 # Implements result =
1508 # __import__(module_name, globals(), None, name_list)
1510 # module_name StringNode dotted name of module
1511 # name_list ListNode or None list of names to be imported
1513 type = py_object_type
1515 subexprs = ['module_name', 'name_list']
1517 def analyse_types(self, env):
1518 self.module_name.analyse_types(env)
1519 self.module_name = self.module_name.coerce_to_pyobject(env)
1521 self.name_list.analyse_types(env)
1522 self.name_list.coerce_to_pyobject(env)
1524 env.use_utility_code(import_utility_code)
1526 gil_message = "Python import"
1528 def generate_result_code(self, code):
1530 name_list_code = self.name_list.py_result()
1532 name_list_code = "0"
1534 "%s = __Pyx_Import(%s, %s); %s" % (
1536 self.module_name.py_result(),
1538 code.error_goto_if_null(self.result(), self.pos)))
1539 code.put_gotref(self.py_result())
1542 class IteratorNode(ExprNode):
1543 # Used as part of for statement implementation.
1545 # allocate_counter_temp/release_counter_temp needs to be called
1546 # by parent (ForInStatNode)
1548 # Implements result = iter(sequence)
1552 type = py_object_type
1554 subexprs = ['sequence']
1556 def analyse_types(self, env):
1557 self.sequence.analyse_types(env)
1558 if isinstance(self.sequence, SliceIndexNode) and \
1559 (self.sequence.base.type.is_array or self.sequence.base.type.is_ptr) \
1560 or self.sequence.type.is_array and self.sequence.type.size is not None:
1561 # C array iteration will be transformed later on
1564 self.sequence = self.sequence.coerce_to_pyobject(env)
1567 gil_message = "Iterating over Python object"
1569 def allocate_counter_temp(self, code):
1570 self.counter_cname = code.funcstate.allocate_temp(
1571 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1573 def release_counter_temp(self, code):
1574 code.funcstate.release_temp(self.counter_cname)
1576 def generate_result_code(self, code):
1577 is_builtin_sequence = self.sequence.type is list_type or \
1578 self.sequence.type is tuple_type
1579 may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1580 if is_builtin_sequence:
1582 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1583 elif may_be_a_sequence:
1585 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1586 self.sequence.py_result(),
1587 self.sequence.py_result()))
1588 if may_be_a_sequence:
1590 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1593 self.sequence.py_result(),
1595 code.putln("} else {")
1596 if is_builtin_sequence:
1598 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1599 code.error_goto(self.pos))
1601 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1604 self.sequence.py_result(),
1605 code.error_goto_if_null(self.result(), self.pos)))
1606 code.put_gotref(self.py_result())
1607 if may_be_a_sequence:
1611 class NextNode(AtomicExprNode):
1612 # Used as part of for statement implementation.
1613 # Implements result = iterator.next()
1614 # Created during analyse_types phase.
1615 # The iterator is not owned by this node.
1619 type = py_object_type
1621 def __init__(self, iterator, env):
1622 self.pos = iterator.pos
1623 self.iterator = iterator
1626 def generate_result_code(self, code):
1627 sequence_type = self.iterator.sequence.type
1628 if sequence_type is list_type:
1629 type_checks = [(list_type, "List")]
1630 elif sequence_type is tuple_type:
1631 type_checks = [(tuple_type, "Tuple")]
1632 elif not sequence_type.is_builtin_type:
1633 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1637 for py_type, prefix in type_checks:
1638 if len(type_checks) > 1:
1640 "if (likely(Py%s_CheckExact(%s))) {" % (
1641 prefix, self.iterator.py_result()))
1643 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1644 self.iterator.counter_cname,
1646 self.iterator.py_result()))
1648 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1651 self.iterator.py_result(),
1652 self.iterator.counter_cname,
1654 self.iterator.counter_cname))
1655 if len(type_checks) > 1:
1657 if len(type_checks) == 1:
1661 "%s = PyIter_Next(%s);" % (
1663 self.iterator.py_result()))
1667 code.putln(code.error_goto_if_PyErr(self.pos))
1668 code.putln("break;")
1670 code.put_gotref(self.py_result())
1674 class ExcValueNode(AtomicExprNode):
1675 # Node created during analyse_types phase
1676 # of an ExceptClauseNode to fetch the current
1679 type = py_object_type
1681 def __init__(self, pos, env):
1682 ExprNode.__init__(self, pos)
1684 def set_var(self, var):
1687 def calculate_result_code(self):
1690 def generate_result_code(self, code):
1693 def analyse_types(self, env):
1697 class TempNode(ExprNode):
1698 # Node created during analyse_types phase
1699 # of some nodes to hold a temporary value.
1701 # Note: One must call "allocate" and "release" on
1702 # the node during code generation to get/release the temp.
1703 # This is because the temp result is often used outside of
1704 # the regular cycle.
1708 def __init__(self, pos, type, env):
1709 ExprNode.__init__(self, pos)
1711 if type.is_pyobject:
1712 self.result_ctype = py_object_type
1715 def analyse_types(self, env):
1718 def generate_result_code(self, code):
1721 def allocate(self, code):
1722 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1724 def release(self, code):
1725 code.funcstate.release_temp(self.temp_cname)
1726 self.temp_cname = None
1730 return self.temp_cname
1732 assert False, "Remember to call allocate/release on TempNode"
1735 # Do not participate in normal temp alloc/dealloc:
1736 def allocate_temp_result(self, code):
1739 def release_temp_result(self, code):
1742 class PyTempNode(TempNode):
1743 # TempNode holding a Python value.
1745 def __init__(self, pos, env):
1746 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1748 class RawCNameExprNode(ExprNode):
1751 def __init__(self, pos, type=None):
1755 def analyse_types(self, env):
1758 def set_cname(self, cname):
1764 def generate_result_code(self, code):
1768 #-------------------------------------------------------------------
1772 #-------------------------------------------------------------------
1774 class IndexNode(ExprNode):
1775 # Sequence indexing.
1779 # indices [ExprNode]
1780 # is_buffer_access boolean Whether this is a buffer access.
1782 # indices is used on buffer access, index on non-buffer access.
1783 # The former contains a clean list of index parameters, the
1784 # latter whatever Python object is needed for index access.
1786 subexprs = ['base', 'index', 'indices']
1789 def __init__(self, pos, index, *args, **kw):
1790 ExprNode.__init__(self, pos, index=index, *args, **kw)
1793 def calculate_constant_result(self):
1794 self.constant_result = \
1795 self.base.constant_result[self.index.constant_result]
1797 def compile_time_value(self, denv):
1798 base = self.base.compile_time_value(denv)
1799 index = self.index.compile_time_value(denv)
1802 except Exception, e:
1803 self.compile_time_value_error(e)
1805 def is_ephemeral(self):
1806 return self.base.is_ephemeral()
1808 def analyse_target_declaration(self, env):
1811 def analyse_as_type(self, env):
1812 base_type = self.base.analyse_as_type(env)
1813 if base_type and not base_type.is_pyobject:
1814 if base_type.is_cpp_class:
1815 if isinstance(self.index, TupleNode):
1816 template_values = self.index.args
1818 template_values = [self.index]
1820 type_node = Nodes.TemplatedTypeNode(
1822 positional_args = template_values,
1823 keyword_args = None)
1824 return type_node.analyse(env, base_type = base_type)
1826 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1829 def type_dependencies(self, env):
1830 return self.base.type_dependencies(env)
1832 def infer_type(self, env):
1833 if isinstance(self.base, (StringNode, UnicodeNode)): # FIXME: BytesNode?
1834 return py_object_type
1835 base_type = self.base.infer_type(env)
1836 if base_type.is_ptr or base_type.is_array:
1837 return base_type.base_type
1839 # TODO: Handle buffers (hopefully without too much redundancy).
1840 return py_object_type
1842 def analyse_types(self, env):
1843 self.analyse_base_and_index_types(env, getting = 1)
1845 def analyse_target_types(self, env):
1846 self.analyse_base_and_index_types(env, setting = 1)
1848 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
1849 # Note: This might be cleaned up by having IndexNode
1850 # parsed in a saner way and only construct the tuple if
1853 # Note that this function must leave IndexNode in a cloneable state.
1854 # For buffers, self.index is packed out on the initial analysis, and
1855 # when cloning self.indices is copied.
1856 self.is_buffer_access = False
1858 self.base.analyse_types(env)
1859 if self.base.type.is_error:
1860 # Do not visit child tree if base is undeclared to avoid confusing
1862 self.type = PyrexTypes.error_type
1865 # Handle the case where base is a literal char* (and we expect a string, not an int)
1866 if isinstance(self.base, BytesNode):
1867 self.base = self.base.coerce_to_pyobject(env)
1869 skip_child_analysis = False
1870 buffer_access = False
1871 if self.base.type.is_buffer:
1872 assert hasattr(self.base, "entry") # Must be a NameNode-like node
1874 indices = self.indices
1876 if isinstance(self.index, TupleNode):
1877 indices = self.index.args
1879 indices = [self.index]
1880 if len(indices) == self.base.type.ndim:
1881 buffer_access = True
1882 skip_child_analysis = True
1884 x.analyse_types(env)
1885 if not x.type.is_int:
1886 buffer_access = False
1888 # On cloning, indices is cloned. Otherwise, unpack index into indices
1889 assert not (buffer_access and isinstance(self.index, CloneNode))
1892 self.indices = indices
1894 self.type = self.base.type.dtype
1895 self.is_buffer_access = True
1896 self.buffer_type = self.base.entry.type
1898 if getting and self.type.is_pyobject:
1901 if not self.base.entry.type.writable:
1902 error(self.pos, "Writing to readonly buffer")
1904 self.base.entry.buffer_aux.writable_needed = True
1906 if isinstance(self.index, TupleNode):
1907 self.index.analyse_types(env, skip_children=skip_child_analysis)
1908 elif not skip_child_analysis:
1909 self.index.analyse_types(env)
1910 self.original_index_type = self.index.type
1911 if self.base.type.is_pyobject:
1912 if self.index.type.is_int:
1914 and (self.base.type is list_type or self.base.type is tuple_type)
1915 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
1916 and not env.directives['boundscheck']):
1920 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
1922 self.index = self.index.coerce_to_pyobject(env)
1924 self.type = py_object_type
1926 if self.base.type.is_ptr or self.base.type.is_array:
1927 self.type = self.base.type.base_type
1928 if self.index.type.is_pyobject:
1929 self.index = self.index.coerce_to(
1930 PyrexTypes.c_py_ssize_t_type, env)
1931 if not self.index.type.is_int:
1933 "Invalid index type '%s'" %
1935 elif self.base.type.is_cpp_class:
1936 function = env.lookup_operator("[]", [self.base, self.index])
1937 if function is None:
1938 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (self.base.type, self.index.type))
1939 self.type = PyrexTypes.error_type
1940 self.result_code = "<error>"
1942 func_type = function.type
1943 if func_type.is_ptr:
1944 func_type = func_type.base_type
1945 self.index = self.index.coerce_to(func_type.args[0].type, env)
1946 self.type = func_type.return_type
1947 if setting and not func_type.return_type.is_reference:
1948 error(self.pos, "Can't set non-reference result '%s'" % self.type)
1951 "Attempting to index non-array type '%s'" %
1953 self.type = PyrexTypes.error_type
1954 gil_message = "Indexing Python object"
1956 def nogil_check(self, env):
1957 if self.is_buffer_access:
1958 if env.directives['boundscheck']:
1959 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
1961 elif self.type.is_pyobject:
1962 error(self.pos, "Cannot access buffer with object dtype without gil")
1964 super(IndexNode, self).nogil_check(env)
1967 def check_const_addr(self):
1968 return self.base.check_const_addr() and self.index.check_const()
1970 def is_lvalue(self):
1973 def calculate_result_code(self):
1974 if self.is_buffer_access:
1975 return "(*%s)" % self.buffer_ptr_code
1976 elif self.base.type is list_type:
1977 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
1978 elif self.base.type is tuple_type:
1979 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
1981 return "(%s[%s])" % (
1982 self.base.result(), self.index.result())
1984 def extra_index_params(self):
1985 if self.index.type.is_int:
1986 if self.original_index_type.signed:
1987 size_adjustment = ""
1989 size_adjustment = "+1"
1990 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
1994 def generate_subexpr_evaluation_code(self, code):
1995 self.base.generate_evaluation_code(code)
1996 if not self.indices:
1997 self.index.generate_evaluation_code(code)
1999 for i in self.indices:
2000 i.generate_evaluation_code(code)
2002 def generate_subexpr_disposal_code(self, code):
2003 self.base.generate_disposal_code(code)
2004 if not self.indices:
2005 self.index.generate_disposal_code(code)
2007 for i in self.indices:
2008 i.generate_disposal_code(code)
2010 def free_subexpr_temps(self, code):
2011 self.base.free_temps(code)
2012 if not self.indices:
2013 self.index.free_temps(code)
2015 for i in self.indices:
2018 def generate_result_code(self, code):
2019 if self.is_buffer_access:
2020 if code.globalstate.directives['nonecheck']:
2021 self.put_nonecheck(code)
2022 self.buffer_ptr_code = self.buffer_lookup_code(code)
2023 if self.type.is_pyobject:
2024 # is_temp is True, so must pull out value and incref it.
2025 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2026 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2027 elif self.type.is_pyobject and self.is_temp:
2028 if self.index.type.is_int:
2029 index_code = self.index.result()
2030 if self.base.type is list_type:
2031 function = "__Pyx_GetItemInt_List"
2032 elif self.base.type is tuple_type:
2033 function = "__Pyx_GetItemInt_Tuple"
2035 function = "__Pyx_GetItemInt"
2036 code.globalstate.use_utility_code(getitem_int_utility_code)
2038 function = "PyObject_GetItem"
2039 index_code = self.index.py_result()
2042 "%s = %s(%s, %s%s); if (!%s) %s" % (
2045 self.base.py_result(),
2047 self.extra_index_params(),
2049 code.error_goto(self.pos)))
2050 code.put_gotref(self.py_result())
2052 def generate_setitem_code(self, value_code, code):
2053 if self.index.type.is_int:
2054 function = "__Pyx_SetItemInt"
2055 index_code = self.index.result()
2056 code.globalstate.use_utility_code(setitem_int_utility_code)
2058 index_code = self.index.py_result()
2059 if self.base.type is dict_type:
2060 function = "PyDict_SetItem"
2061 # It would seem that we could specalized lists/tuples, but that
2062 # shouldn't happen here.
2063 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2064 # not a PyObject*, and bad conversion here would give the wrong
2065 # exception. Also, tuples are supposed to be immutable, and raise
2066 # TypeErrors when trying to set their entries (PyTuple_SetItem
2067 # is for creating new tuples from).
2069 function = "PyObject_SetItem"
2071 "if (%s(%s, %s, %s%s) < 0) %s" % (
2073 self.base.py_result(),
2076 self.extra_index_params(),
2077 code.error_goto(self.pos)))
2079 def generate_buffer_setitem_code(self, rhs, code, op=""):
2080 # Used from generate_assignment_code and InPlaceAssignmentNode
2081 if code.globalstate.directives['nonecheck']:
2082 self.put_nonecheck(code)
2083 ptrexpr = self.buffer_lookup_code(code)
2084 if self.buffer_type.dtype.is_pyobject:
2085 # Must manage refcounts. Decref what is already there
2086 # and incref what we put in.
2087 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2088 rhs_code = rhs.result()
2089 code.putln("%s = %s;" % (ptr, ptrexpr))
2090 code.put_gotref("*%s" % ptr)
2091 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2094 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2095 code.put_giveref("*%s" % ptr)
2096 code.funcstate.release_temp(ptr)
2099 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2101 def generate_assignment_code(self, rhs, code):
2102 self.generate_subexpr_evaluation_code(code)
2103 if self.is_buffer_access:
2104 self.generate_buffer_setitem_code(rhs, code)
2105 elif self.type.is_pyobject:
2106 self.generate_setitem_code(rhs.py_result(), code)
2110 self.result(), rhs.result()))
2111 self.generate_subexpr_disposal_code(code)
2112 self.free_subexpr_temps(code)
2113 rhs.generate_disposal_code(code)
2114 rhs.free_temps(code)
2116 def generate_deletion_code(self, code):
2117 self.generate_subexpr_evaluation_code(code)
2118 #if self.type.is_pyobject:
2119 if self.index.type.is_int:
2120 function = "__Pyx_DelItemInt"
2121 index_code = self.index.result()
2122 code.globalstate.use_utility_code(delitem_int_utility_code)
2124 index_code = self.index.py_result()
2125 if self.base.type is dict_type:
2126 function = "PyDict_DelItem"
2128 function = "PyObject_DelItem"
2130 "if (%s(%s, %s%s) < 0) %s" % (
2132 self.base.py_result(),
2134 self.extra_index_params(),
2135 code.error_goto(self.pos)))
2136 self.generate_subexpr_disposal_code(code)
2137 self.free_subexpr_temps(code)
2139 def buffer_lookup_code(self, code):
2140 # Assign indices to temps
2141 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2142 for temp, index in zip(index_temps, self.indices):
2143 code.putln("%s = %s;" % (temp, index.result()))
2144 # Generate buffer access code using these temps
2146 # The above could happen because child_attrs is wrong somewhere so that
2147 # options are not propagated.
2148 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2149 index_signeds=[i.type.signed for i in self.indices],
2150 index_cnames=index_temps,
2151 directives=code.globalstate.directives,
2152 pos=self.pos, code=code)
2154 def put_nonecheck(self, code):
2155 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2156 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2157 code.putln("__Pyx_RaiseNoneIndexingError();")
2158 code.putln(code.error_goto(self.pos))
2161 class SliceIndexNode(ExprNode):
2162 # 2-element slice indexing
2165 # start ExprNode or None
2166 # stop ExprNode or None
2168 subexprs = ['base', 'start', 'stop']
2170 def infer_type(self, env):
2171 base_type = self.base.infer_type(env)
2172 if base_type.is_string:
2174 elif base_type in (bytes_type, str_type, unicode_type,
2175 list_type, tuple_type):
2177 return py_object_type
2179 def calculate_constant_result(self):
2180 self.constant_result = self.base.constant_result[
2181 self.start.constant_result : self.stop.constant_result]
2183 def compile_time_value(self, denv):
2184 base = self.base.compile_time_value(denv)
2185 if self.start is None:
2188 start = self.start.compile_time_value(denv)
2189 if self.stop is None:
2192 stop = self.stop.compile_time_value(denv)
2194 return base[start:stop]
2195 except Exception, e:
2196 self.compile_time_value_error(e)
2198 def analyse_target_declaration(self, env):
2201 def analyse_target_types(self, env):
2202 self.analyse_types(env)
2203 # when assigning, we must accept any Python type
2204 if self.type.is_pyobject:
2205 self.type = py_object_type
2207 def analyse_types(self, env):
2208 self.base.analyse_types(env)
2210 self.start.analyse_types(env)
2212 self.stop.analyse_types(env)
2213 base_type = self.base.type
2214 if base_type.is_string:
2215 self.type = bytes_type
2216 elif base_type.is_array or base_type.is_ptr:
2217 # we need a ptr type here instead of an array type, as
2218 # array types can result in invalid type casts in the C
2220 self.type = PyrexTypes.CPtrType(base_type.base_type)
2222 self.base = self.base.coerce_to_pyobject(env)
2223 self.type = py_object_type
2224 if base_type.is_builtin_type:
2225 # slicing builtin types returns something of the same type
2226 self.type = base_type
2227 c_int = PyrexTypes.c_py_ssize_t_type
2229 self.start = self.start.coerce_to(c_int, env)
2231 self.stop = self.stop.coerce_to(c_int, env)
2234 nogil_check = Node.gil_error
2235 gil_message = "Slicing Python object"
2237 def generate_result_code(self, code):
2238 if not self.type.is_pyobject:
2240 "Slicing is not currently supported for '%s'." % self.type)
2242 if self.base.type.is_string:
2243 if self.stop is None:
2245 "%s = __Pyx_PyBytes_FromString(%s + %s); %s" % (
2249 code.error_goto_if_null(self.result(), self.pos)))
2252 "%s = __Pyx_PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2258 code.error_goto_if_null(self.result(), self.pos)))
2261 "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
2263 self.base.py_result(),
2266 code.error_goto_if_null(self.result(), self.pos)))
2267 code.put_gotref(self.py_result())
2269 def generate_assignment_code(self, rhs, code):
2270 self.generate_subexpr_evaluation_code(code)
2271 if self.type.is_pyobject:
2272 code.put_error_if_neg(self.pos,
2273 "PySequence_SetSlice(%s, %s, %s, %s)" % (
2274 self.base.py_result(),
2281 start_offset = self.start_code()
2282 if start_offset == '0':
2286 if rhs.type.is_array:
2287 array_length = rhs.type.size
2288 self.generate_slice_guard_code(code, array_length)
2291 "Slice assignments from pointers are not yet supported.")
2292 # FIXME: fix the array size according to start/stop
2293 array_length = self.base.type.size
2294 for i in range(array_length):
2295 code.putln("%s[%s%s] = %s[%d];" % (
2296 self.base.result(), start_offset, i,
2298 self.generate_subexpr_disposal_code(code)
2299 self.free_subexpr_temps(code)
2300 rhs.generate_disposal_code(code)
2301 rhs.free_temps(code)
2303 def generate_deletion_code(self, code):
2304 if not self.base.type.is_pyobject:
2306 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2308 self.generate_subexpr_evaluation_code(code)
2309 code.put_error_if_neg(self.pos,
2310 "PySequence_DelSlice(%s, %s, %s)" % (
2311 self.base.py_result(),
2314 self.generate_subexpr_disposal_code(code)
2316 def generate_slice_guard_code(self, code, target_size):
2317 if not self.base.type.is_array:
2319 slice_size = self.base.type.size
2322 stop = self.stop.result()
2326 slice_size = self.base.type.size + stop
2333 start = self.start.result()
2337 start = self.base.type.size + start
2345 error(self.pos, "Assignment to empty slice.")
2346 elif start is None and stop is None:
2347 # we know the exact slice length
2348 if target_size != slice_size:
2349 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2350 slice_size, target_size))
2351 elif start is not None:
2354 check = "(%s)-(%s)" % (stop, start)
2355 else: # stop is not None:
2358 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2359 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));' % (
2360 target_size, check))
2361 code.putln(code.error_goto(self.pos))
2364 def start_code(self):
2366 return self.start.result()
2370 def stop_code(self):
2372 return self.stop.result()
2373 elif self.base.type.is_array:
2374 return self.base.type.size
2376 return "PY_SSIZE_T_MAX"
2378 def calculate_result_code(self):
2379 # self.result() is not used, but this method must exist
2383 class SliceNode(ExprNode):
2384 # start:stop:step in subscript list
2390 type = py_object_type
2393 def calculate_constant_result(self):
2394 self.constant_result = self.base.constant_result[
2395 self.start.constant_result : \
2396 self.stop.constant_result : \
2397 self.step.constant_result]
2399 def compile_time_value(self, denv):
2400 start = self.start.compile_time_value(denv)
2401 if self.stop is None:
2404 stop = self.stop.compile_time_value(denv)
2405 if self.step is None:
2408 step = self.step.compile_time_value(denv)
2410 return slice(start, stop, step)
2411 except Exception, e:
2412 self.compile_time_value_error(e)
2414 subexprs = ['start', 'stop', 'step']
2416 def analyse_types(self, env):
2417 self.start.analyse_types(env)
2418 self.stop.analyse_types(env)
2419 self.step.analyse_types(env)
2420 self.start = self.start.coerce_to_pyobject(env)
2421 self.stop = self.stop.coerce_to_pyobject(env)
2422 self.step = self.step.coerce_to_pyobject(env)
2424 gil_message = "Constructing Python slice object"
2426 def generate_result_code(self, code):
2428 "%s = PySlice_New(%s, %s, %s); %s" % (
2430 self.start.py_result(),
2431 self.stop.py_result(),
2432 self.step.py_result(),
2433 code.error_goto_if_null(self.result(), self.pos)))
2434 code.put_gotref(self.py_result())
2437 class CallNode(ExprNode):
2439 def analyse_as_type_constructor(self, env):
2440 type = self.function.analyse_as_type(env)
2441 if type and type.is_struct_or_union:
2442 args, kwds = self.explicit_args_kwds()
2444 for arg, member in zip(args, type.scope.var_entries):
2445 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2447 items += kwds.key_value_pairs
2448 self.key_value_pairs = items
2449 self.__class__ = DictNode
2450 self.analyse_types(env)
2451 self.coerce_to(type, env)
2453 elif type and type.is_cpp_class:
2454 for arg in self.args:
2455 arg.analyse_types(env)
2456 constructor = type.scope.lookup("<init>")
2457 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2458 self.function.entry = constructor
2459 self.function.set_cname(type.declaration_code(""))
2460 self.analyse_c_function_call(env)
2463 def is_lvalue(self):
2464 return self.type.is_reference
2466 def nogil_check(self, env):
2467 func_type = self.function_type()
2468 if func_type.is_pyobject:
2470 elif not getattr(func_type, 'nogil', False):
2473 gil_message = "Calling gil-requiring function"
2476 class SimpleCallNode(CallNode):
2477 # Function call without keyword, * or ** args.
2481 # arg_tuple ExprNode or None used internally
2482 # self ExprNode or None used internally
2483 # coerced_self ExprNode or None used internally
2484 # wrapper_call bool used internally
2485 # has_optional_args bool used internally
2487 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2492 wrapper_call = False
2493 has_optional_args = False
2495 def compile_time_value(self, denv):
2496 function = self.function.compile_time_value(denv)
2497 args = [arg.compile_time_value(denv) for arg in self.args]
2499 return function(*args)
2500 except Exception, e:
2501 self.compile_time_value_error(e)
2503 def type_dependencies(self, env):
2504 # TODO: Update when Danilo's C++ code merged in to handle the
2505 # the case of function overloading.
2506 return self.function.type_dependencies(env)
2508 def infer_type(self, env):
2509 function = self.function
2510 func_type = function.infer_type(env)
2511 if isinstance(self.function, NewExprNode):
2512 return PyrexTypes.CPtrType(self.function.class_type)
2513 if func_type.is_ptr:
2514 func_type = func_type.base_type
2515 if func_type.is_cfunction:
2516 return func_type.return_type
2517 elif func_type is type_type:
2518 if function.is_name and function.entry and function.entry.type:
2519 result_type = function.entry.type
2520 if result_type.is_extension_type:
2522 elif result_type.is_builtin_type:
2523 if function.entry.name == 'float':
2524 return PyrexTypes.c_double_type
2525 elif function.entry.name in Builtin.types_that_construct_their_instance:
2527 return py_object_type
2529 def analyse_as_type(self, env):
2530 attr = self.function.as_cython_attribute()
2531 if attr == 'pointer':
2532 if len(self.args) != 1:
2533 error(self.args.pos, "only one type allowed.")
2535 type = self.args[0].analyse_as_type(env)
2537 error(self.args[0].pos, "Unknown type")
2539 return PyrexTypes.CPtrType(type)
2541 def explicit_args_kwds(self):
2542 return self.args, None
2544 def analyse_types(self, env):
2545 if self.analyse_as_type_constructor(env):
2547 function = self.function
2548 function.is_called = 1
2549 self.function.analyse_types(env)
2550 if function.is_attribute and function.entry and function.entry.is_cmethod:
2551 # Take ownership of the object from which the attribute
2552 # was obtained, because we need to pass it as 'self'.
2553 self.self = function.obj
2554 function.obj = CloneNode(self.self)
2555 func_type = self.function_type()
2556 if func_type.is_pyobject:
2557 self.arg_tuple = TupleNode(self.pos, args = self.args)
2558 self.arg_tuple.analyse_types(env)
2560 if func_type is Builtin.type_type and function.is_name and \
2561 function.entry and \
2562 function.entry.is_builtin and \
2563 function.entry.name in Builtin.types_that_construct_their_instance:
2564 # calling a builtin type that returns a specific object type
2565 if function.entry.name == 'float':
2566 # the following will come true later on in a transform
2567 self.type = PyrexTypes.c_double_type
2568 self.result_ctype = PyrexTypes.c_double_type
2570 self.type = Builtin.builtin_types[function.entry.name]
2571 self.result_ctype = py_object_type
2572 elif function.is_name and function.type_entry:
2573 # We are calling an extension type constructor. As
2574 # long as we do not support __new__(), the result type
2576 self.type = function.type_entry.type
2577 self.result_ctype = py_object_type
2579 self.type = py_object_type
2582 for arg in self.args:
2583 arg.analyse_types(env)
2584 if self.self and func_type.args:
2585 # Coerce 'self' to the type expected by the method.
2586 expected_type = func_type.args[0].type
2587 self.coerced_self = CloneNode(self.self).coerce_to(
2589 # Insert coerced 'self' argument into argument list.
2590 self.args.insert(0, self.coerced_self)
2591 self.analyse_c_function_call(env)
2593 def function_type(self):
2594 # Return the type of the function being called, coercing a function
2595 # pointer to a function if necessary.
2596 func_type = self.function.type
2597 if func_type.is_ptr:
2598 func_type = func_type.base_type
2601 def analyse_c_function_call(self, env):
2602 if self.function.type is error_type:
2603 self.type = error_type
2605 if self.function.type.is_cpp_class:
2606 overloaded_entry = self.function.type.scope.lookup("operator()")
2607 if overloaded_entry is None:
2608 self.type = PyrexTypes.error_type
2609 self.result_code = "<error>"
2611 elif hasattr(self.function, 'entry'):
2612 overloaded_entry = self.function.entry
2614 overloaded_entry = None
2615 if overloaded_entry:
2616 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2618 self.type = PyrexTypes.error_type
2619 self.result_code = "<error>"
2621 self.function.entry = entry
2622 self.function.type = entry.type
2623 func_type = self.function_type()
2625 func_type = self.function_type()
2626 if not func_type.is_cfunction:
2627 error(self.pos, "Calling non-function type '%s'" % func_type)
2628 self.type = PyrexTypes.error_type
2629 self.result_code = "<error>"
2632 max_nargs = len(func_type.args)
2633 expected_nargs = max_nargs - func_type.optional_arg_count
2634 actual_nargs = len(self.args)
2635 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2636 self.has_optional_args = 1
2639 for i in range(min(max_nargs, actual_nargs)):
2640 formal_type = func_type.args[i].type
2641 self.args[i] = self.args[i].coerce_to(formal_type, env)
2642 for i in range(max_nargs, actual_nargs):
2643 if self.args[i].type.is_pyobject:
2644 error(self.args[i].pos,
2645 "Python object cannot be passed as a varargs parameter")
2646 # Calc result type and code fragment
2647 if isinstance(self.function, NewExprNode):
2648 self.type = PyrexTypes.CPtrType(self.function.class_type)
2650 self.type = func_type.return_type
2651 if self.type.is_pyobject:
2652 self.result_ctype = py_object_type
2654 elif func_type.exception_value is not None \
2655 or func_type.exception_check:
2657 # C++ exception handler
2658 if func_type.exception_check == '+':
2659 if func_type.exception_value is None:
2660 env.use_utility_code(cpp_exception_utility_code)
2662 def calculate_result_code(self):
2663 return self.c_call_code()
2665 def c_call_code(self):
2666 func_type = self.function_type()
2667 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2669 formal_args = func_type.args
2671 args = zip(formal_args, self.args)
2672 max_nargs = len(func_type.args)
2673 expected_nargs = max_nargs - func_type.optional_arg_count
2674 actual_nargs = len(self.args)
2675 for formal_arg, actual_arg in args[:expected_nargs]:
2676 arg_code = actual_arg.result_as(formal_arg.type)
2677 arg_list_code.append(arg_code)
2679 if func_type.is_overridable:
2680 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2682 if func_type.optional_arg_count:
2683 if expected_nargs == actual_nargs:
2684 optional_args = 'NULL'
2686 optional_args = "&%s" % self.opt_arg_struct
2687 arg_list_code.append(optional_args)
2689 for actual_arg in self.args[len(formal_args):]:
2690 arg_list_code.append(actual_arg.result())
2691 result = "%s(%s)" % (self.function.result(),
2692 ', '.join(arg_list_code))
2695 def generate_result_code(self, code):
2696 func_type = self.function_type()
2697 if func_type.is_pyobject:
2698 arg_code = self.arg_tuple.py_result()
2700 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2702 self.function.py_result(),
2704 code.error_goto_if_null(self.result(), self.pos)))
2705 code.put_gotref(self.py_result())
2706 elif func_type.is_cfunction:
2707 if self.has_optional_args:
2708 actual_nargs = len(self.args)
2709 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2710 self.opt_arg_struct = code.funcstate.allocate_temp(
2711 func_type.op_arg_struct.base_type, manage_ref=True)
2712 code.putln("%s.%s = %s;" % (
2713 self.opt_arg_struct,
2714 Naming.pyrex_prefix + "n",
2715 len(self.args) - expected_nargs))
2716 args = zip(func_type.args, self.args)
2717 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2718 code.putln("%s.%s = %s;" % (
2719 self.opt_arg_struct,
2720 func_type.opt_arg_cname(formal_arg.name),
2721 actual_arg.result_as(formal_arg.type)))
2723 if self.type.is_pyobject and self.is_temp:
2724 exc_checks.append("!%s" % self.result())
2726 exc_val = func_type.exception_value
2727 exc_check = func_type.exception_check
2728 if exc_val is not None:
2729 exc_checks.append("%s == %s" % (self.result(), exc_val))
2731 exc_checks.append("PyErr_Occurred()")
2732 if self.is_temp or exc_checks:
2733 rhs = self.c_call_code()
2735 lhs = "%s = " % self.result()
2736 if self.is_temp and self.type.is_pyobject:
2737 #return_type = self.type # func_type.return_type
2738 #print "SimpleCallNode.generate_result_code: casting", rhs, \
2739 # "from", return_type, "to pyobject" ###
2740 rhs = typecast(py_object_type, self.type, rhs)
2743 if func_type.exception_check == '+':
2744 if func_type.exception_value is None:
2745 raise_py_exception = "__Pyx_CppExn2PyErr()"
2746 elif func_type.exception_value.type.is_pyobject:
2747 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
2748 func_type.exception_value.entry.cname,
2749 func_type.exception_value.entry.cname)
2751 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
2753 "try {%s%s;} catch(...) {%s; %s}" % (
2757 code.error_goto(self.pos)))
2760 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
2763 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
2764 if self.type.is_pyobject and self.result():
2765 code.put_gotref(self.py_result())
2766 if self.has_optional_args:
2767 code.funcstate.release_temp(self.opt_arg_struct)
2770 class PythonCapiFunctionNode(ExprNode):
2772 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
2776 self.type = func_type
2777 self.utility_code = utility_code
2779 def analyse_types(self, env):
2782 def generate_result_code(self, code):
2783 if self.utility_code:
2784 code.globalstate.use_utility_code(self.utility_code)
2786 def calculate_result_code(self):
2789 class PythonCapiCallNode(SimpleCallNode):
2790 # Python C-API Function call (only created in transforms)
2792 def __init__(self, pos, function_name, func_type,
2793 utility_code = None, py_name=None, **kwargs):
2794 self.type = func_type.return_type
2795 self.result_ctype = self.type
2796 self.function = PythonCapiFunctionNode(
2797 pos, py_name, function_name, func_type,
2798 utility_code = utility_code)
2799 # call this last so that we can override the constructed
2800 # attributes above with explicit keyword arguments if required
2801 SimpleCallNode.__init__(self, pos, **kwargs)
2804 class GeneralCallNode(CallNode):
2805 # General Python function call, including keyword,
2806 # * and ** arguments.
2809 # positional_args ExprNode Tuple of positional arguments
2810 # keyword_args ExprNode or None Dict of keyword arguments
2811 # starstar_arg ExprNode or None Dict of extra keyword args
2813 type = py_object_type
2815 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
2817 nogil_check = Node.gil_error
2819 def compile_time_value(self, denv):
2820 function = self.function.compile_time_value(denv)
2821 positional_args = self.positional_args.compile_time_value(denv)
2822 keyword_args = self.keyword_args.compile_time_value(denv)
2823 starstar_arg = self.starstar_arg.compile_time_value(denv)
2825 keyword_args.update(starstar_arg)
2826 return function(*positional_args, **keyword_args)
2827 except Exception, e:
2828 self.compile_time_value_error(e)
2830 def explicit_args_kwds(self):
2831 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
2832 raise PostParseError(self.pos,
2833 'Compile-time keyword arguments must be explicit.')
2834 return self.positional_args.args, self.keyword_args
2836 def analyse_types(self, env):
2837 if self.analyse_as_type_constructor(env):
2839 self.function.analyse_types(env)
2840 self.positional_args.analyse_types(env)
2841 if self.keyword_args:
2842 self.keyword_args.analyse_types(env)
2843 if self.starstar_arg:
2844 self.starstar_arg.analyse_types(env)
2845 if not self.function.type.is_pyobject:
2846 if self.function.type.is_error:
2847 self.type = error_type
2849 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
2850 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
2852 self.function = self.function.coerce_to_pyobject(env)
2853 self.positional_args = \
2854 self.positional_args.coerce_to_pyobject(env)
2855 if self.starstar_arg:
2856 self.starstar_arg = \
2857 self.starstar_arg.coerce_to_pyobject(env)
2858 function = self.function
2859 if function.is_name and function.type_entry:
2860 # We are calling an extension type constructor. As long
2861 # as we do not support __new__(), the result type is clear
2862 self.type = function.type_entry.type
2863 self.result_ctype = py_object_type
2865 self.type = py_object_type
2868 def generate_result_code(self, code):
2869 if self.type.is_error: return
2870 kwargs_call_function = "PyEval_CallObjectWithKeywords"
2871 if self.keyword_args and self.starstar_arg:
2872 code.put_error_if_neg(self.pos,
2873 "PyDict_Update(%s, %s)" % (
2874 self.keyword_args.py_result(),
2875 self.starstar_arg.py_result()))
2876 keyword_code = self.keyword_args.py_result()
2877 elif self.keyword_args:
2878 keyword_code = self.keyword_args.py_result()
2879 elif self.starstar_arg:
2880 keyword_code = self.starstar_arg.py_result()
2881 if self.starstar_arg.type is not Builtin.dict_type:
2882 # CPython supports calling functions with non-dicts, so do we
2883 code.globalstate.use_utility_code(kwargs_call_utility_code)
2884 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
2887 if not keyword_code:
2888 call_code = "PyObject_Call(%s, %s, NULL)" % (
2889 self.function.py_result(),
2890 self.positional_args.py_result())
2892 call_code = "%s(%s, %s, %s)" % (
2893 kwargs_call_function,
2894 self.function.py_result(),
2895 self.positional_args.py_result(),
2901 code.error_goto_if_null(self.result(), self.pos)))
2902 code.put_gotref(self.py_result())
2905 class AsTupleNode(ExprNode):
2906 # Convert argument to tuple. Used for normalising
2907 # the * argument of a function call.
2913 def calculate_constant_result(self):
2914 self.constant_result = tuple(self.base.constant_result)
2916 def compile_time_value(self, denv):
2917 arg = self.arg.compile_time_value(denv)
2920 except Exception, e:
2921 self.compile_time_value_error(e)
2923 def analyse_types(self, env):
2924 self.arg.analyse_types(env)
2925 self.arg = self.arg.coerce_to_pyobject(env)
2926 self.type = tuple_type
2929 nogil_check = Node.gil_error
2930 gil_message = "Constructing Python tuple"
2932 def generate_result_code(self, code):
2934 "%s = PySequence_Tuple(%s); %s" % (
2936 self.arg.py_result(),
2937 code.error_goto_if_null(self.result(), self.pos)))
2938 code.put_gotref(self.py_result())
2941 class AttributeNode(ExprNode):
2946 # needs_none_check boolean Used if obj is an extension type.
2947 # If set to True, it is known that the type is not None.
2951 # is_py_attr boolean Is a Python getattr operation
2952 # member string C name of struct member
2953 # is_called boolean Function call is being done on result
2954 # entry Entry Symbol table entry of attribute
2959 type = PyrexTypes.error_type
2962 needs_none_check = True
2964 def as_cython_attribute(self):
2965 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
2966 return self.attribute
2967 cy = self.obj.as_cython_attribute()
2969 return "%s.%s" % (cy, self.attribute)
2971 def coerce_to(self, dst_type, env):
2972 # If coercing to a generic pyobject and this is a cpdef function
2973 # we can create the corresponding attribute
2974 if dst_type is py_object_type:
2976 if entry and entry.is_cfunction and entry.as_variable:
2977 # must be a cpdef function
2979 self.entry = entry.as_variable
2980 self.analyse_as_python_attribute(env)
2982 return ExprNode.coerce_to(self, dst_type, env)
2984 def calculate_constant_result(self):
2985 attr = self.attribute
2986 if attr.startswith("__") and attr.endswith("__"):
2988 self.constant_result = getattr(self.obj.constant_result, attr)
2990 def compile_time_value(self, denv):
2991 attr = self.attribute
2992 if attr.startswith("__") and attr.endswith("__"):
2994 "Invalid attribute name '%s' in compile-time expression" % attr)
2996 obj = self.obj.compile_time_value(denv)
2998 return getattr(obj, attr)
2999 except Exception, e:
3000 self.compile_time_value_error(e)
3002 def type_dependencies(self, env):
3003 return self.obj.type_dependencies(env)
3005 def infer_type(self, env):
3006 if self.analyse_as_cimported_attribute(env, 0):
3007 return self.entry.type
3008 elif self.analyse_as_unbound_cmethod(env):
3009 return self.entry.type
3011 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3014 def analyse_target_declaration(self, env):
3017 def analyse_target_types(self, env):
3018 self.analyse_types(env, target = 1)
3020 def analyse_types(self, env, target = 0):
3021 if self.analyse_as_cimported_attribute(env, target):
3023 if not target and self.analyse_as_unbound_cmethod(env):
3025 self.analyse_as_ordinary_attribute(env, target)
3027 def analyse_as_cimported_attribute(self, env, target):
3028 # Try to interpret this as a reference to an imported
3029 # C const, type, var or function. If successful, mutates
3030 # this node into a NameNode and returns 1, otherwise
3032 module_scope = self.obj.analyse_as_module(env)
3034 entry = module_scope.lookup_here(self.attribute)
3036 entry.is_cglobal or entry.is_cfunction
3037 or entry.is_type or entry.is_const):
3038 self.mutate_into_name_node(env, entry, target)
3042 def analyse_as_unbound_cmethod(self, env):
3043 # Try to interpret this as a reference to an unbound
3044 # C method of an extension type. If successful, mutates
3045 # this node into a NameNode and returns 1, otherwise
3047 type = self.obj.analyse_as_extension_type(env)
3049 entry = type.scope.lookup_here(self.attribute)
3050 if entry and entry.is_cmethod:
3051 # Create a temporary entry describing the C method
3052 # as an ordinary function.
3053 ubcm_entry = Symtab.Entry(entry.name,
3054 "%s->%s" % (type.vtabptr_cname, entry.cname),
3056 ubcm_entry.is_cfunction = 1
3057 ubcm_entry.func_cname = entry.func_cname
3058 ubcm_entry.is_unbound_cmethod = 1
3059 self.mutate_into_name_node(env, ubcm_entry, None)
3063 def analyse_as_type(self, env):
3064 module_scope = self.obj.analyse_as_module(env)
3066 return module_scope.lookup_type(self.attribute)
3067 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3068 base_type = self.obj.analyse_as_type(env)
3069 if base_type and hasattr(base_type, 'scope'):
3070 return base_type.scope.lookup_type(self.attribute)
3073 def analyse_as_extension_type(self, env):
3074 # Try to interpret this as a reference to an extension type
3075 # in a cimported module. Returns the extension type, or None.
3076 module_scope = self.obj.analyse_as_module(env)
3078 entry = module_scope.lookup_here(self.attribute)
3079 if entry and entry.is_type and entry.type.is_extension_type:
3083 def analyse_as_module(self, env):
3084 # Try to interpret this as a reference to a cimported module
3085 # in another cimported module. Returns the module scope, or None.
3086 module_scope = self.obj.analyse_as_module(env)
3088 entry = module_scope.lookup_here(self.attribute)
3089 if entry and entry.as_module:
3090 return entry.as_module
3093 def mutate_into_name_node(self, env, entry, target):
3094 # Mutate this node into a NameNode and complete the
3095 # analyse_types phase.
3096 self.__class__ = NameNode
3097 self.name = self.attribute
3102 NameNode.analyse_target_types(self, env)
3104 NameNode.analyse_rvalue_entry(self, env)
3106 def analyse_as_ordinary_attribute(self, env, target):
3107 self.obj.analyse_types(env)
3108 self.analyse_attribute(env)
3109 if self.entry and self.entry.is_cmethod and not self.is_called:
3110 # error(self.pos, "C method can only be called")
3112 ## Reference to C array turns into pointer to first element.
3113 #while self.type.is_array:
3114 # self.type = self.type.element_ptr_type()
3118 self.result_ctype = py_object_type
3120 def analyse_attribute(self, env, obj_type = None):
3121 # Look up attribute and set self.type and self.member.
3123 self.member = self.attribute
3124 if obj_type is None:
3125 if self.obj.type.is_string:
3126 self.obj = self.obj.coerce_to_pyobject(env)
3127 obj_type = self.obj.type
3129 if obj_type.is_string:
3130 obj_type = py_object_type
3131 if obj_type.is_ptr or obj_type.is_array:
3132 obj_type = obj_type.base_type
3134 elif obj_type.is_extension_type:
3138 if obj_type.has_attributes:
3140 if obj_type.attributes_known():
3141 entry = obj_type.scope.lookup_here(self.attribute)
3142 if entry and entry.is_member:
3146 "Cannot select attribute of incomplete type '%s'"
3148 self.type = PyrexTypes.error_type
3152 if obj_type.is_extension_type and entry.name == "__weakref__":
3153 error(self.pos, "Illegal use of special attribute __weakref__")
3154 # methods need the normal attribute lookup
3155 # because they do not have struct entries
3156 if entry.is_variable or entry.is_cmethod:
3157 self.type = entry.type
3158 self.member = entry.cname
3161 # If it's not a variable or C method, it must be a Python
3162 # method of an extension type, so we treat it like a Python
3165 # If we get here, the base object is not a struct/union/extension
3166 # type, or it is an extension type and the attribute is either not
3167 # declared or is declared as a Python method. Treat it as a Python
3168 # attribute reference.
3169 self.analyse_as_python_attribute(env, obj_type)
3171 def analyse_as_python_attribute(self, env, obj_type = None):
3172 if obj_type is None:
3173 obj_type = self.obj.type
3174 self.member = self.attribute
3175 self.type = py_object_type
3177 if not obj_type.is_pyobject and not obj_type.is_error:
3178 if obj_type.can_coerce_to_pyobject(env):
3179 self.obj = self.obj.coerce_to_pyobject(env)
3182 "Object of type '%s' has no attribute '%s'" %
3183 (obj_type, self.attribute))
3185 def nogil_check(self, env):
3189 gil_message = "Accessing Python attribute"
3191 def is_simple(self):
3193 return self.result_in_temp() or self.obj.is_simple()
3195 return NameNode.is_simple(self)
3197 def is_lvalue(self):
3201 return NameNode.is_lvalue(self)
3203 def is_ephemeral(self):
3205 return self.obj.is_ephemeral()
3207 return NameNode.is_ephemeral(self)
3209 def calculate_result_code(self):
3210 #print "AttributeNode.calculate_result_code:", self.member ###
3211 #print "...obj node =", self.obj, "code", self.obj.result() ###
3212 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3214 obj_code = obj.result_as(obj.type)
3215 #print "...obj_code =", obj_code ###
3216 if self.entry and self.entry.is_cmethod:
3217 if obj.type.is_extension_type:
3218 return "((struct %s *)%s%s%s)->%s" % (
3219 obj.type.vtabstruct_cname, obj_code, self.op,
3220 obj.type.vtabslot_cname, self.member)
3223 elif obj.type.is_complex:
3224 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3226 return "%s%s%s" % (obj_code, self.op, self.member)
3228 def generate_result_code(self, code):
3229 interned_attr_cname = code.intern_identifier(self.attribute)
3232 '%s = PyObject_GetAttr(%s, %s); %s' % (
3234 self.obj.py_result(),
3235 interned_attr_cname,
3236 code.error_goto_if_null(self.result(), self.pos)))
3237 code.put_gotref(self.py_result())
3239 # result_code contains what is needed, but we may need to insert
3240 # a check and raise an exception
3241 if (self.obj.type.is_extension_type
3242 and self.needs_none_check
3243 and code.globalstate.directives['nonecheck']):
3244 self.put_nonecheck(code)
3246 def generate_assignment_code(self, rhs, code):
3247 interned_attr_cname = code.intern_identifier(self.attribute)
3248 self.obj.generate_evaluation_code(code)
3250 code.put_error_if_neg(self.pos,
3251 'PyObject_SetAttr(%s, %s, %s)' % (
3252 self.obj.py_result(),
3253 interned_attr_cname,
3255 rhs.generate_disposal_code(code)
3256 rhs.free_temps(code)
3257 elif self.obj.type.is_complex:
3258 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3259 self.member.upper(),
3260 self.obj.result_as(self.obj.type),
3261 rhs.result_as(self.ctype())))
3263 if (self.obj.type.is_extension_type
3264 and self.needs_none_check
3265 and code.globalstate.directives['nonecheck']):
3266 self.put_nonecheck(code)
3268 select_code = self.result()
3269 if self.type.is_pyobject and self.use_managed_ref:
3270 rhs.make_owned_reference(code)
3271 code.put_giveref(rhs.py_result())
3272 code.put_gotref(select_code)
3273 code.put_decref(select_code, self.ctype())
3277 rhs.result_as(self.ctype())))
3279 rhs.generate_post_assignment_code(code)
3280 rhs.free_temps(code)
3281 self.obj.generate_disposal_code(code)
3282 self.obj.free_temps(code)
3284 def generate_deletion_code(self, code):
3285 interned_attr_cname = code.intern_identifier(self.attribute)
3286 self.obj.generate_evaluation_code(code)
3288 code.put_error_if_neg(self.pos,
3289 'PyObject_DelAttr(%s, %s)' % (
3290 self.obj.py_result(),
3291 interned_attr_cname))
3293 error(self.pos, "Cannot delete C attribute of extension type")
3294 self.obj.generate_disposal_code(code)
3295 self.obj.free_temps(code)
3297 def annotate(self, code):
3299 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3301 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3303 def put_nonecheck(self, code):
3304 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3305 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3306 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3307 code.putln(code.error_goto(self.pos))
3311 #-------------------------------------------------------------------
3315 #-------------------------------------------------------------------
3317 class StarredTargetNode(ExprNode):
3318 # A starred expression like "*a"
3320 # This is only allowed in sequence assignment targets such as
3322 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3324 # and will be removed during type analysis (or generate an error
3325 # if it's found at unexpected places).
3329 subexprs = ['target']
3331 type = py_object_type
3334 def __init__(self, pos, target):
3336 self.target = target
3338 def analyse_declarations(self, env):
3339 error(self.pos, "can use starred expression only as assignment target")
3340 self.target.analyse_declarations(env)
3342 def analyse_types(self, env):
3343 error(self.pos, "can use starred expression only as assignment target")
3344 self.target.analyse_types(env)
3345 self.type = self.target.type
3347 def analyse_target_declaration(self, env):
3348 self.target.analyse_target_declaration(env)
3350 def analyse_target_types(self, env):
3351 self.target.analyse_target_types(env)
3352 self.type = self.target.type
3354 def calculate_result_code(self):
3357 def generate_result_code(self, code):
3361 class SequenceNode(ExprNode):
3362 # Base class for list and tuple constructor nodes.
3363 # Contains common code for performing sequence unpacking.
3367 # unpacked_items [ExprNode] or None
3368 # coerced_unpacked_items [ExprNode] or None
3372 is_sequence_constructor = 1
3373 unpacked_items = None
3375 def compile_time_value_list(self, denv):
3376 return [arg.compile_time_value(denv) for arg in self.args]
3378 def replace_starred_target_node(self):
3379 # replace a starred node in the targets by the contained expression
3380 self.starred_assignment = False
3382 for arg in self.args:
3384 if self.starred_assignment:
3385 error(arg.pos, "more than 1 starred expression in assignment")
3386 self.starred_assignment = True
3388 arg.is_starred = True
3392 def analyse_target_declaration(self, env):
3393 self.replace_starred_target_node()
3394 for arg in self.args:
3395 arg.analyse_target_declaration(env)
3397 def analyse_types(self, env, skip_children=False):
3398 for i in range(len(self.args)):
3400 if not skip_children: arg.analyse_types(env)
3401 self.args[i] = arg.coerce_to_pyobject(env)
3402 self.type = py_object_type
3405 def analyse_target_types(self, env):
3406 self.iterator = PyTempNode(self.pos, env)
3407 self.unpacked_items = []
3408 self.coerced_unpacked_items = []
3409 for arg in self.args:
3410 arg.analyse_target_types(env)
3412 if not arg.type.assignable_from(Builtin.list_type):
3414 "starred target must have Python object (list) type")
3415 if arg.type is py_object_type:
3416 arg.type = Builtin.list_type
3417 unpacked_item = PyTempNode(self.pos, env)
3418 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3419 self.unpacked_items.append(unpacked_item)
3420 self.coerced_unpacked_items.append(coerced_unpacked_item)
3421 self.type = py_object_type
3423 def generate_result_code(self, code):
3424 self.generate_operation_code(code)
3426 def generate_assignment_code(self, rhs, code):
3427 if self.starred_assignment:
3428 self.generate_starred_assignment_code(rhs, code)
3430 self.generate_parallel_assignment_code(rhs, code)
3432 for item in self.unpacked_items:
3434 rhs.free_temps(code)
3436 def generate_parallel_assignment_code(self, rhs, code):
3437 # Need to work around the fact that generate_evaluation_code
3438 # allocates the temps in a rather hacky way -- the assignment
3439 # is evaluated twice, within each if-block.
3441 code.globalstate.use_utility_code(unpacking_utility_code)
3443 if rhs.type is tuple_type:
3444 tuple_check = "likely(%s != Py_None)"
3446 tuple_check = "PyTuple_CheckExact(%s)"
3448 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3449 tuple_check % rhs.py_result(),
3452 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3453 for item in self.unpacked_items:
3455 for i in range(len(self.args)):
3456 item = self.unpacked_items[i]
3458 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3461 code.put_incref(item.result(), item.ctype())
3462 value_node = self.coerced_unpacked_items[i]
3463 value_node.generate_evaluation_code(code)
3464 rhs.generate_disposal_code(code)
3466 for i in range(len(self.args)):
3467 self.args[i].generate_assignment_code(
3468 self.coerced_unpacked_items[i], code)
3470 code.putln("} else {")
3472 if rhs.type is tuple_type:
3473 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3474 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3475 rhs.py_result(), len(self.args)))
3476 code.putln(code.error_goto(self.pos))
3478 self.iterator.allocate(code)
3480 "%s = PyObject_GetIter(%s); %s" % (
3481 self.iterator.result(),
3483 code.error_goto_if_null(self.iterator.result(), self.pos)))
3484 code.put_gotref(self.iterator.py_result())
3485 rhs.generate_disposal_code(code)
3486 for i in range(len(self.args)):
3487 item = self.unpacked_items[i]
3488 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3489 self.iterator.py_result(), i)
3493 typecast(item.ctype(), py_object_type, unpack_code),
3494 code.error_goto_if_null(item.result(), self.pos)))
3495 code.put_gotref(item.py_result())
3496 value_node = self.coerced_unpacked_items[i]
3497 value_node.generate_evaluation_code(code)
3498 code.put_error_if_neg(self.pos,
3499 "__Pyx_EndUnpack(%s)" % (
3500 self.iterator.py_result()))
3501 if debug_disposal_code:
3502 print("UnpackNode.generate_assignment_code:")
3503 print("...generating disposal code for %s" % self.iterator)
3504 self.iterator.generate_disposal_code(code)
3505 self.iterator.free_temps(code)
3506 self.iterator.release(code)
3508 for i in range(len(self.args)):
3509 self.args[i].generate_assignment_code(
3510 self.coerced_unpacked_items[i], code)
3514 def generate_starred_assignment_code(self, rhs, code):
3515 code.globalstate.use_utility_code(unpacking_utility_code)
3517 for i, arg in enumerate(self.args):
3519 starred_target = self.unpacked_items[i]
3520 fixed_args_left = self.args[:i]
3521 fixed_args_right = self.args[i+1:]
3524 self.iterator.allocate(code)
3526 "%s = PyObject_GetIter(%s); %s" % (
3527 self.iterator.result(),
3529 code.error_goto_if_null(self.iterator.result(), self.pos)))
3530 code.put_gotref(self.iterator.py_result())
3531 rhs.generate_disposal_code(code)
3533 for item in self.unpacked_items:
3535 for i in range(len(fixed_args_left)):
3536 item = self.unpacked_items[i]
3537 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3538 self.iterator.py_result(), i)
3542 typecast(item.ctype(), py_object_type, unpack_code),
3543 code.error_goto_if_null(item.result(), self.pos)))
3544 code.put_gotref(item.py_result())
3545 value_node = self.coerced_unpacked_items[i]
3546 value_node.generate_evaluation_code(code)
3548 target_list = starred_target.result()
3549 code.putln("%s = PySequence_List(%s); %s" % (
3550 target_list, self.iterator.py_result(),
3551 code.error_goto_if_null(target_list, self.pos)))
3552 code.put_gotref(target_list)
3553 if fixed_args_right:
3554 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3555 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3556 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3557 (target_list, len(unpacked_right_args))))
3558 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3559 len(fixed_args_left), target_list,
3560 code.error_goto(self.pos)))
3562 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3563 self.coerced_unpacked_items[::-1])):
3565 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3567 target_list, target_list))
3568 # resize the list the hard way
3569 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3570 code.put_gotref(arg.py_result())
3571 coerced_arg.generate_evaluation_code(code)
3573 self.iterator.generate_disposal_code(code)
3574 self.iterator.free_temps(code)
3575 self.iterator.release(code)
3577 for i in range(len(self.args)):
3578 self.args[i].generate_assignment_code(
3579 self.coerced_unpacked_items[i], code)
3581 def annotate(self, code):
3582 for arg in self.args:
3584 if self.unpacked_items:
3585 for arg in self.unpacked_items:
3587 for arg in self.coerced_unpacked_items:
3591 class TupleNode(SequenceNode):
3592 # Tuple constructor.
3596 gil_message = "Constructing Python tuple"
3598 def analyse_types(self, env, skip_children=False):
3599 if len(self.args) == 0:
3603 SequenceNode.analyse_types(self, env, skip_children)
3605 def calculate_result_code(self):
3606 if len(self.args) > 0:
3607 error(self.pos, "Positive length tuples must be constructed.")
3609 return Naming.empty_tuple
3611 def calculate_constant_result(self):
3612 self.constant_result = tuple([
3613 arg.constant_result for arg in self.args])
3615 def compile_time_value(self, denv):
3616 values = self.compile_time_value_list(denv)
3618 return tuple(values)
3619 except Exception, e:
3620 self.compile_time_value_error(e)
3622 def generate_operation_code(self, code):
3623 if len(self.args) == 0:
3624 # result_code is Naming.empty_tuple
3627 "%s = PyTuple_New(%s); %s" % (
3630 code.error_goto_if_null(self.result(), self.pos)))
3631 code.put_gotref(self.py_result())
3632 for i in range(len(self.args)):
3634 if not arg.result_in_temp():
3635 code.put_incref(arg.result(), arg.ctype())
3637 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3641 code.put_giveref(arg.py_result())
3643 def generate_subexpr_disposal_code(self, code):
3644 # We call generate_post_assignment_code here instead
3645 # of generate_disposal_code, because values were stored
3646 # in the tuple using a reference-stealing operation.
3647 for arg in self.args:
3648 arg.generate_post_assignment_code(code)
3649 # Should NOT call free_temps -- this is invoked by the default
3650 # generate_evaluation_code which will do that.
3653 class ListNode(SequenceNode):
3656 # obj_conversion_errors [PyrexError] used internally
3657 # orignial_args [ExprNode] used internally
3659 obj_conversion_errors = []
3661 gil_message = "Constructing Python list"
3663 def type_dependencies(self, env):
3666 def infer_type(self, env):
3667 # TOOD: Infer non-object list arrays.
3670 def analyse_expressions(self, env):
3671 SequenceNode.analyse_expressions(self, env)
3672 self.coerce_to_pyobject(env)
3674 def analyse_types(self, env):
3676 self.original_args = list(self.args)
3677 SequenceNode.analyse_types(self, env)
3678 self.type = list_type
3679 self.obj_conversion_errors = held_errors()
3680 release_errors(ignore=True)
3682 def coerce_to(self, dst_type, env):
3683 if dst_type.is_pyobject:
3684 for err in self.obj_conversion_errors:
3686 self.obj_conversion_errors = []
3687 if not self.type.subtype_of(dst_type):
3688 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3689 elif dst_type.is_ptr:
3690 base_type = dst_type.base_type
3691 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3692 for i in range(len(self.original_args)):
3694 if isinstance(arg, CoerceToPyTypeNode):
3696 self.args[i] = arg.coerce_to(base_type, env)
3697 elif dst_type.is_struct:
3698 if len(self.args) > len(dst_type.scope.var_entries):
3699 error(self.pos, "Too may members for '%s'" % dst_type)
3701 if len(self.args) < len(dst_type.scope.var_entries):
3702 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3703 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3704 if isinstance(arg, CoerceToPyTypeNode):
3706 self.args[i] = arg.coerce_to(member.type, env)
3707 self.type = dst_type
3709 self.type = error_type
3710 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3713 def release_temp(self, env):
3714 if self.type.is_array:
3715 # To be valid C++, we must allocate the memory on the stack
3716 # manually and be sure not to reuse it for something else.
3719 SequenceNode.release_temp(self, env)
3721 def calculate_constant_result(self):
3722 self.constant_result = [
3723 arg.constant_result for arg in self.args]
3725 def compile_time_value(self, denv):
3726 return self.compile_time_value_list(denv)
3728 def generate_operation_code(self, code):
3729 if self.type.is_pyobject:
3730 for err in self.obj_conversion_errors:
3732 code.putln("%s = PyList_New(%s); %s" %
3735 code.error_goto_if_null(self.result(), self.pos)))
3736 code.put_gotref(self.py_result())
3737 for i in range(len(self.args)):
3739 #if not arg.is_temp:
3740 if not arg.result_in_temp():
3741 code.put_incref(arg.result(), arg.ctype())
3742 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
3746 code.put_giveref(arg.py_result())
3747 elif self.type.is_array:
3748 for i, arg in enumerate(self.args):
3749 code.putln("%s[%s] = %s;" % (
3753 elif self.type.is_struct:
3754 for arg, member in zip(self.args, self.type.scope.var_entries):
3755 code.putln("%s.%s = %s;" % (
3760 raise InternalError("List type never specified")
3762 def generate_subexpr_disposal_code(self, code):
3763 # We call generate_post_assignment_code here instead
3764 # of generate_disposal_code, because values were stored
3765 # in the list using a reference-stealing operation.
3766 for arg in self.args:
3767 arg.generate_post_assignment_code(code)
3768 # Should NOT call free_temps -- this is invoked by the default
3769 # generate_evaluation_code which will do that.
3772 class ComprehensionNode(ExprNode):
3773 subexprs = ["target"]
3774 child_attrs = ["loop", "append"]
3776 def infer_type(self, env):
3777 return self.target.infer_type(env)
3779 def analyse_declarations(self, env):
3780 self.append.target = self # this is used in the PyList_Append of the inner loop
3781 self.loop.analyse_declarations(env)
3783 def analyse_types(self, env):
3784 self.target.analyse_expressions(env)
3785 self.type = self.target.type
3786 self.loop.analyse_expressions(env)
3788 def calculate_result_code(self):
3789 return self.target.result()
3791 def generate_result_code(self, code):
3792 self.generate_operation_code(code)
3794 def generate_operation_code(self, code):
3795 self.loop.generate_execution_code(code)
3797 def annotate(self, code):
3798 self.loop.annotate(code)
3801 class ComprehensionAppendNode(ExprNode):
3802 # Need to be careful to avoid infinite recursion:
3803 # target must not be in child_attrs/subexprs
3806 type = PyrexTypes.c_int_type
3808 def analyse_types(self, env):
3809 self.expr.analyse_types(env)
3810 if not self.expr.type.is_pyobject:
3811 self.expr = self.expr.coerce_to_pyobject(env)
3814 def generate_result_code(self, code):
3815 if self.target.type is list_type:
3816 function = "PyList_Append"
3817 elif self.target.type is set_type:
3818 function = "PySet_Add"
3820 raise InternalError(
3821 "Invalid type for comprehension node: %s" % self.target.type)
3823 code.putln("%s = %s(%s, (PyObject*)%s); %s" %
3826 self.target.result(),
3828 code.error_goto_if(self.result(), self.pos)))
3830 class DictComprehensionAppendNode(ComprehensionAppendNode):
3831 subexprs = ['key_expr', 'value_expr']
3833 def analyse_types(self, env):
3834 self.key_expr.analyse_types(env)
3835 if not self.key_expr.type.is_pyobject:
3836 self.key_expr = self.key_expr.coerce_to_pyobject(env)
3837 self.value_expr.analyse_types(env)
3838 if not self.value_expr.type.is_pyobject:
3839 self.value_expr = self.value_expr.coerce_to_pyobject(env)
3842 def generate_result_code(self, code):
3843 code.putln("%s = PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s); %s" %
3845 self.target.result(),
3846 self.key_expr.result(),
3847 self.value_expr.result(),
3848 code.error_goto_if(self.result(), self.pos)))
3851 class SetNode(ExprNode):
3858 gil_message = "Constructing Python set"
3860 def analyse_types(self, env):
3861 for i in range(len(self.args)):
3863 arg.analyse_types(env)
3864 self.args[i] = arg.coerce_to_pyobject(env)
3865 self.type = set_type
3868 def calculate_constant_result(self):
3869 self.constant_result = set([
3870 arg.constant_result for arg in self.args])
3872 def compile_time_value(self, denv):
3873 values = [arg.compile_time_value(denv) for arg in self.args]
3876 except Exception, e:
3877 self.compile_time_value_error(e)
3879 def generate_evaluation_code(self, code):
3880 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
3881 self.allocate_temp_result(code)
3883 "%s = PySet_New(0); %s" % (
3885 code.error_goto_if_null(self.result(), self.pos)))
3886 code.put_gotref(self.py_result())
3887 for arg in self.args:
3888 arg.generate_evaluation_code(code)
3890 code.error_goto_if_neg(
3891 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
3893 arg.generate_disposal_code(code)
3894 arg.free_temps(code)
3897 class DictNode(ExprNode):
3898 # Dictionary constructor.
3900 # key_value_pairs [DictItemNode]
3902 # obj_conversion_errors [PyrexError] used internally
3904 subexprs = ['key_value_pairs']
3908 obj_conversion_errors = []
3910 def calculate_constant_result(self):
3911 self.constant_result = dict([
3912 item.constant_result for item in self.key_value_pairs])
3914 def compile_time_value(self, denv):
3915 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
3916 for item in self.key_value_pairs]
3919 except Exception, e:
3920 self.compile_time_value_error(e)
3922 def type_dependencies(self, env):
3925 def infer_type(self, env):
3926 # TOOD: Infer struct constructors.
3929 def analyse_types(self, env):
3931 for item in self.key_value_pairs:
3932 item.analyse_types(env)
3933 self.obj_conversion_errors = held_errors()
3934 release_errors(ignore=True)
3936 def coerce_to(self, dst_type, env):
3937 if dst_type.is_pyobject:
3938 self.release_errors()
3939 if not self.type.subtype_of(dst_type):
3940 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3941 elif dst_type.is_struct_or_union:
3942 self.type = dst_type
3943 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
3944 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
3945 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
3946 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
3947 for item in self.key_value_pairs:
3948 if isinstance(item.key, CoerceToPyTypeNode):
3949 item.key = item.key.arg
3950 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
3951 error(item.key.pos, "Invalid struct field identifier")
3952 item.key = StringNode(item.key.pos, value="<error>")
3954 key = str(item.key.value) # converts string literals to unicode in Py3
3955 member = dst_type.scope.lookup_here(key)
3957 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
3960 if isinstance(value, CoerceToPyTypeNode):
3962 item.value = value.coerce_to(member.type, env)
3964 self.type = error_type
3965 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3968 def release_errors(self):
3969 for err in self.obj_conversion_errors:
3971 self.obj_conversion_errors = []
3973 gil_message = "Constructing Python dict"
3975 def generate_evaluation_code(self, code):
3976 # Custom method used here because key-value
3977 # pairs are evaluated and used one at a time.
3978 code.mark_pos(self.pos)
3979 self.allocate_temp_result(code)
3980 if self.type.is_pyobject:
3981 self.release_errors()
3983 "%s = PyDict_New(); %s" % (
3985 code.error_goto_if_null(self.result(), self.pos)))
3986 code.put_gotref(self.py_result())
3987 for item in self.key_value_pairs:
3988 item.generate_evaluation_code(code)
3989 if self.type.is_pyobject:
3990 code.put_error_if_neg(self.pos,
3991 "PyDict_SetItem(%s, %s, %s)" % (
3993 item.key.py_result(),
3994 item.value.py_result()))
3996 code.putln("%s.%s = %s;" % (
3999 item.value.result()))
4000 item.generate_disposal_code(code)
4001 item.free_temps(code)
4003 def annotate(self, code):
4004 for item in self.key_value_pairs:
4007 class DictItemNode(ExprNode):
4008 # Represents a single item in a DictNode
4012 subexprs = ['key', 'value']
4014 nogil_check = None # Parent DictNode takes care of it
4016 def calculate_constant_result(self):
4017 self.constant_result = (
4018 self.key.constant_result, self.value.constant_result)
4020 def analyse_types(self, env):
4021 self.key.analyse_types(env)
4022 self.value.analyse_types(env)
4023 self.key = self.key.coerce_to_pyobject(env)
4024 self.value = self.value.coerce_to_pyobject(env)
4026 def generate_evaluation_code(self, code):
4027 self.key.generate_evaluation_code(code)
4028 self.value.generate_evaluation_code(code)
4030 def generate_disposal_code(self, code):
4031 self.key.generate_disposal_code(code)
4032 self.value.generate_disposal_code(code)
4034 def free_temps(self, code):
4035 self.key.free_temps(code)
4036 self.value.free_temps(code)
4039 return iter([self.key, self.value])
4042 class ClassNode(ExprNode):
4043 # Helper class used in the implementation of Python
4044 # class definitions. Constructs a class object given
4045 # a name, tuple of bases and class dictionary.
4047 # name EncodedString Name of the class
4048 # bases ExprNode Base class tuple
4049 # dict ExprNode Class dict (not owned by this node)
4050 # doc ExprNode or None Doc string
4051 # module_name string Name of defining module
4053 subexprs = ['bases', 'doc']
4055 def analyse_types(self, env):
4056 self.bases.analyse_types(env)
4058 self.doc.analyse_types(env)
4059 self.doc = self.doc.coerce_to_pyobject(env)
4060 self.module_name = env.global_scope().qualified_name
4061 self.type = py_object_type
4063 env.use_utility_code(create_class_utility_code);
4065 gil_message = "Constructing Python class"
4067 def generate_result_code(self, code):
4068 cname = code.intern_identifier(self.name)
4070 code.put_error_if_neg(self.pos,
4071 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4072 self.dict.py_result(),
4073 self.doc.py_result()))
4075 '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % (
4077 self.bases.py_result(),
4078 self.dict.py_result(),
4081 code.error_goto_if_null(self.result(), self.pos)))
4082 code.put_gotref(self.py_result())
4085 class UnboundMethodNode(ExprNode):
4086 # Helper class used in the implementation of Python
4087 # class definitions. Constructs an unbound method
4088 # object from a class and a function.
4090 # function ExprNode Function object
4092 type = py_object_type
4095 subexprs = ['function']
4097 def analyse_types(self, env):
4098 self.function.analyse_types(env)
4100 gil_message = "Constructing an unbound method"
4102 def generate_result_code(self, code):
4103 class_cname = code.pyclass_stack[-1].classobj.result()
4105 "%s = PyMethod_New(%s, 0, %s); %s" % (
4107 self.function.py_result(),
4109 code.error_goto_if_null(self.result(), self.pos)))
4110 code.put_gotref(self.py_result())
4113 class PyCFunctionNode(AtomicExprNode):
4114 # Helper class used in the implementation of Python
4115 # class definitions. Constructs a PyCFunction object
4116 # from a PyMethodDef struct.
4118 # pymethdef_cname string PyMethodDef structure
4120 type = py_object_type
4123 def analyse_types(self, env):
4126 gil_message = "Constructing Python function"
4128 def generate_result_code(self, code):
4130 "%s = PyCFunction_New(&%s, 0); %s" % (
4132 self.pymethdef_cname,
4133 code.error_goto_if_null(self.result(), self.pos)))
4134 code.put_gotref(self.py_result())
4136 #-------------------------------------------------------------------
4138 # Unary operator nodes
4140 #-------------------------------------------------------------------
4142 compile_time_unary_operators = {
4143 'not': operator.not_,
4149 class UnopNode(ExprNode):
4153 # Processing during analyse_expressions phase:
4155 # analyse_c_operation
4156 # Called when the operand is not a pyobject.
4157 # - Check operand type and coerce if needed.
4158 # - Determine result type and result code fragment.
4159 # - Allocate temporary for result if needed.
4161 subexprs = ['operand']
4164 def calculate_constant_result(self):
4165 func = compile_time_unary_operators[self.operator]
4166 self.constant_result = func(self.operand.constant_result)
4168 def compile_time_value(self, denv):
4169 func = compile_time_unary_operators.get(self.operator)
4172 "Unary '%s' not supported in compile-time expression"
4174 operand = self.operand.compile_time_value(denv)
4176 return func(operand)
4177 except Exception, e:
4178 self.compile_time_value_error(e)
4180 def infer_type(self, env):
4181 return self.operand.infer_type(env)
4183 def analyse_types(self, env):
4184 self.operand.analyse_types(env)
4185 if self.is_py_operation():
4186 self.coerce_operand_to_pyobject(env)
4187 self.type = py_object_type
4189 elif self.is_cpp_operation():
4190 self.analyse_cpp_operation(env)
4192 self.analyse_c_operation(env)
4194 def check_const(self):
4195 return self.operand.check_const()
4197 def is_py_operation(self):
4198 return self.operand.type.is_pyobject
4200 def nogil_check(self, env):
4201 if self.is_py_operation():
4204 def is_cpp_operation(self):
4205 type = self.operand.type
4206 return type.is_cpp_class
4208 def coerce_operand_to_pyobject(self, env):
4209 self.operand = self.operand.coerce_to_pyobject(env)
4211 def generate_result_code(self, code):
4212 if self.operand.type.is_pyobject:
4213 self.generate_py_operation_code(code)
4215 def generate_py_operation_code(self, code):
4216 function = self.py_operation_function()
4218 "%s = %s(%s); %s" % (
4221 self.operand.py_result(),
4222 code.error_goto_if_null(self.result(), self.pos)))
4223 code.put_gotref(self.py_result())
4225 def type_error(self):
4226 if not self.operand.type.is_error:
4227 error(self.pos, "Invalid operand type for '%s' (%s)" %
4228 (self.operator, self.operand.type))
4229 self.type = PyrexTypes.error_type
4231 def analyse_cpp_operation(self, env):
4232 type = self.operand.type
4234 type = type.base_type
4235 function = type.scope.lookup("operator%s" % self.operator)
4237 error(self.pos, "'%s' operator not defined for %s"
4238 % (self.operator, type))
4241 func_type = function.type
4242 if func_type.is_ptr:
4243 func_type = func_type.base_type
4244 self.type = func_type.return_type
4247 class NotNode(ExprNode):
4252 type = PyrexTypes.c_bint_type
4254 subexprs = ['operand']
4256 def calculate_constant_result(self):
4257 self.constant_result = not self.operand.constant_result
4259 def compile_time_value(self, denv):
4260 operand = self.operand.compile_time_value(denv)
4263 except Exception, e:
4264 self.compile_time_value_error(e)
4266 def infer_type(self, env):
4267 return PyrexTypes.c_bint_type
4269 def analyse_types(self, env):
4270 self.operand.analyse_types(env)
4271 self.operand = self.operand.coerce_to_boolean(env)
4273 def calculate_result_code(self):
4274 return "(!%s)" % self.operand.result()
4276 def generate_result_code(self, code):
4280 class UnaryPlusNode(UnopNode):
4281 # unary '+' operator
4285 def analyse_c_operation(self, env):
4286 self.type = self.operand.type
4288 def py_operation_function(self):
4289 return "PyNumber_Positive"
4291 def calculate_result_code(self):
4292 if self.is_cpp_operation():
4293 return "(+%s)" % self.operand.result()
4295 return self.operand.result()
4298 class UnaryMinusNode(UnopNode):
4299 # unary '-' operator
4303 def analyse_c_operation(self, env):
4304 if self.operand.type.is_numeric:
4305 self.type = self.operand.type
4308 if self.type.is_complex:
4311 def py_operation_function(self):
4312 return "PyNumber_Negative"
4314 def calculate_result_code(self):
4316 return "(-%s)" % self.operand.result()
4318 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
4320 def get_constant_c_result_code(self):
4321 value = self.operand.get_constant_c_result_code()
4323 return "(-%s)" % (value)
4325 class TildeNode(UnopNode):
4326 # unary '~' operator
4328 def analyse_c_operation(self, env):
4329 if self.operand.type.is_int:
4330 self.type = self.operand.type
4334 def py_operation_function(self):
4335 return "PyNumber_Invert"
4337 def calculate_result_code(self):
4338 return "(~%s)" % self.operand.result()
4341 class CUnopNode(UnopNode):
4343 def is_py_operation(self):
4346 class DereferenceNode(CUnopNode):
4351 def analyse_c_operation(self, env):
4352 if self.operand.type.is_ptr:
4353 self.type = self.operand.type.base_type
4357 def calculate_result_code(self):
4358 return "(*%s)" % self.operand.result()
4361 class DecrementIncrementNode(CUnopNode):
4362 # unary ++/-- operator
4364 def analyse_c_operation(self, env):
4365 if self.operand.type.is_ptr or self.operand.type.is_numeric:
4366 self.type = self.operand.type
4370 def calculate_result_code(self):
4372 return "(%s%s)" % (self.operator, self.operand.result())
4374 return "(%s%s)" % (self.operand.result(), self.operator)
4376 def inc_dec_constructor(is_prefix, operator):
4377 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
4380 class AmpersandNode(ExprNode):
4381 # The C address-of operator.
4385 subexprs = ['operand']
4387 def infer_type(self, env):
4388 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
4390 def analyse_types(self, env):
4391 self.operand.analyse_types(env)
4392 argtype = self.operand.type
4393 if not (argtype.is_cfunction or self.operand.is_lvalue()):
4394 self.error("Taking address of non-lvalue")
4396 if argtype.is_pyobject:
4397 self.error("Cannot take address of Python variable")
4399 self.type = PyrexTypes.c_ptr_type(argtype)
4401 def check_const(self):
4402 return self.operand.check_const_addr()
4404 def error(self, mess):
4405 error(self.pos, mess)
4406 self.type = PyrexTypes.error_type
4407 self.result_code = "<error>"
4409 def calculate_result_code(self):
4410 return "(&%s)" % self.operand.result()
4412 def generate_result_code(self, code):
4416 unop_node_classes = {
4418 "-": UnaryMinusNode,
4422 def unop_node(pos, operator, operand):
4423 # Construct unnop node of appropriate class for
4425 if isinstance(operand, IntNode) and operator == '-':
4426 return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
4427 elif isinstance(operand, UnopNode) and operand.operator == operator:
4428 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
4429 return unop_node_classes[operator](pos,
4430 operator = operator,
4434 class TypecastNode(ExprNode):
4438 # base_type CBaseTypeNode
4439 # declarator CDeclaratorNode
4441 # If used from a transform, one can if wanted specify the attribute
4442 # "type" directly and leave base_type and declarator to None
4444 subexprs = ['operand']
4445 base_type = declarator = type = None
4447 def type_dependencies(self, env):
4450 def infer_type(self, env):
4451 if self.type is None:
4452 base_type = self.base_type.analyse(env)
4453 _, self.type = self.declarator.analyse(base_type, env)
4456 def analyse_types(self, env):
4457 if self.type is None:
4458 base_type = self.base_type.analyse(env)
4459 _, self.type = self.declarator.analyse(base_type, env)
4460 if self.type.is_cfunction:
4462 "Cannot cast to a function type")
4463 self.type = PyrexTypes.error_type
4464 self.operand.analyse_types(env)
4465 to_py = self.type.is_pyobject
4466 from_py = self.operand.type.is_pyobject
4467 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
4468 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
4469 if to_py and not from_py:
4470 if self.operand.type.can_coerce_to_pyobject(env):
4471 self.result_ctype = py_object_type
4472 self.operand = self.operand.coerce_to_pyobject(env)
4474 if self.operand.type.is_ptr:
4475 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
4476 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
4478 # Should this be an error?
4479 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
4480 self.operand = self.operand.coerce_to_simple(env)
4481 elif from_py and not to_py:
4482 if self.type.create_from_py_utility_code(env):
4483 self.operand = self.operand.coerce_to(self.type, env)
4484 elif self.type.is_ptr:
4485 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
4486 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
4488 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
4489 elif from_py and to_py:
4490 if self.typecheck and self.type.is_extension_type:
4491 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
4492 elif self.type.is_complex and self.operand.type.is_complex:
4493 self.operand = self.operand.coerce_to_simple(env)
4495 def nogil_check(self, env):
4496 if self.type and self.type.is_pyobject and self.is_temp:
4499 def check_const(self):
4500 return self.operand.check_const()
4502 def calculate_constant_result(self):
4503 # we usually do not know the result of a type cast at code
4507 def calculate_result_code(self):
4508 if self.type.is_complex:
4509 operand_result = self.operand.result()
4510 if self.operand.type.is_complex:
4511 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
4512 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
4514 real_part = self.type.real_type.cast_code(operand_result)
4516 return "%s(%s, %s)" % (
4517 self.type.from_parts,
4521 return self.type.cast_code(self.operand.result())
4523 def get_constant_c_result_code(self):
4524 operand_result = self.operand.get_constant_c_result_code()
4526 return self.type.cast_code(operand_result)
4528 def result_as(self, type):
4529 if self.type.is_pyobject and not self.is_temp:
4530 # Optimise away some unnecessary casting
4531 return self.operand.result_as(type)
4533 return ExprNode.result_as(self, type)
4535 def generate_result_code(self, code):
4538 "%s = (PyObject *)%s;" % (
4540 self.operand.result()))
4541 code.put_incref(self.result(), self.ctype())
4544 class SizeofNode(ExprNode):
4545 # Abstract base class for sizeof(x) expression nodes.
4547 type = PyrexTypes.c_size_t_type
4549 def check_const(self):
4552 def generate_result_code(self, code):
4556 class SizeofTypeNode(SizeofNode):
4557 # C sizeof function applied to a type
4559 # base_type CBaseTypeNode
4560 # declarator CDeclaratorNode
4565 def analyse_types(self, env):
4566 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
4567 # this could be better handled by more uniformly treating types as runtime-available objects
4568 if 0 and self.base_type.module_path:
4569 path = self.base_type.module_path
4570 obj = env.lookup(path[0])
4571 if obj.as_module is None:
4572 operand = NameNode(pos=self.pos, name=path[0])
4573 for attr in path[1:]:
4574 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
4575 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
4576 self.operand = operand
4577 self.__class__ = SizeofVarNode
4578 self.analyse_types(env)
4580 if self.arg_type is None:
4581 base_type = self.base_type.analyse(env)
4582 _, arg_type = self.declarator.analyse(base_type, env)
4583 self.arg_type = arg_type
4586 def check_type(self):
4587 arg_type = self.arg_type
4588 if arg_type.is_pyobject and not arg_type.is_extension_type:
4589 error(self.pos, "Cannot take sizeof Python object")
4590 elif arg_type.is_void:
4591 error(self.pos, "Cannot take sizeof void")
4592 elif not arg_type.is_complete():
4593 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
4595 def calculate_result_code(self):
4596 if self.arg_type.is_extension_type:
4597 # the size of the pointer is boring
4598 # we want the size of the actual struct
4599 arg_code = self.arg_type.declaration_code("", deref=1)
4601 arg_code = self.arg_type.declaration_code("")
4602 return "(sizeof(%s))" % arg_code
4605 class SizeofVarNode(SizeofNode):
4606 # C sizeof function applied to a variable
4610 subexprs = ['operand']
4612 def analyse_types(self, env):
4613 # We may actually be looking at a type rather than a variable...
4614 # If we are, traditional analysis would fail...
4615 operand_as_type = self.operand.analyse_as_type(env)
4617 self.arg_type = operand_as_type
4618 self.__class__ = SizeofTypeNode
4621 self.operand.analyse_types(env)
4623 def calculate_result_code(self):
4624 return "(sizeof(%s))" % self.operand.result()
4626 def generate_result_code(self, code):
4629 class TypeofNode(ExprNode):
4630 # Compile-time type of an expression, as a string.
4633 # literal StringNode # internal
4636 type = py_object_type
4638 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
4640 def analyse_types(self, env):
4641 self.operand.analyse_types(env)
4642 self.literal = StringNode(
4643 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
4644 self.literal.analyse_types(env)
4645 self.literal = self.literal.coerce_to_pyobject(env)
4647 def generate_evaluation_code(self, code):
4648 self.literal.generate_evaluation_code(code)
4650 def calculate_result_code(self):
4651 return self.literal.calculate_result_code()
4653 #-------------------------------------------------------------------
4655 # Binary operator nodes
4657 #-------------------------------------------------------------------
4659 def _not_in(x, seq):
4662 compile_time_binary_operators = {
4670 'is_not': operator.is_not,
4673 '/': operator.truediv,
4674 '//': operator.floordiv,
4675 '<<': operator.lshift,
4680 '>>': operator.rshift,
4683 'in': operator.contains,
4687 def get_compile_time_binop(node):
4688 func = compile_time_binary_operators.get(node.operator)
4691 "Binary '%s' not supported in compile-time expression"
4695 class BinopNode(ExprNode):
4700 # Processing during analyse_expressions phase:
4702 # analyse_c_operation
4703 # Called when neither operand is a pyobject.
4704 # - Check operand types and coerce if needed.
4705 # - Determine result type and result code fragment.
4706 # - Allocate temporary for result if needed.
4708 subexprs = ['operand1', 'operand2']
4710 def calculate_constant_result(self):
4711 func = compile_time_binary_operators[self.operator]
4712 self.constant_result = func(
4713 self.operand1.constant_result,
4714 self.operand2.constant_result)
4716 def compile_time_value(self, denv):
4717 func = get_compile_time_binop(self)
4718 operand1 = self.operand1.compile_time_value(denv)
4719 operand2 = self.operand2.compile_time_value(denv)
4721 return func(operand1, operand2)
4722 except Exception, e:
4723 self.compile_time_value_error(e)
4725 def infer_type(self, env):
4726 return self.result_type(self.operand1.infer_type(env),
4727 self.operand2.infer_type(env))
4729 def analyse_types(self, env):
4730 self.operand1.analyse_types(env)
4731 self.operand2.analyse_types(env)
4732 if self.is_py_operation():
4733 self.coerce_operands_to_pyobjects(env)
4734 self.type = self.result_type(self.operand1.type,
4736 assert self.type.is_pyobject
4738 elif self.is_cpp_operation():
4739 self.analyse_cpp_operation(env)
4741 self.analyse_c_operation(env)
4743 def is_py_operation(self):
4744 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
4746 def is_py_operation_types(self, type1, type2):
4747 return type1.is_pyobject or type2.is_pyobject
4749 def is_cpp_operation(self):
4750 return (self.operand1.type.is_cpp_class
4751 or self.operand2.type.is_cpp_class)
4753 def analyse_cpp_operation(self, env):
4754 type1 = self.operand1.type
4755 type2 = self.operand2.type
4756 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
4760 func_type = entry.type
4761 if func_type.is_ptr:
4762 func_type = func_type.base_type
4763 if len(func_type.args) == 1:
4764 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
4766 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
4767 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
4768 self.type = func_type.return_type
4770 def result_type(self, type1, type2):
4771 if self.is_py_operation_types(type1, type2):
4773 type2 = Builtin.bytes_type
4775 type1 = Builtin.bytes_type
4776 elif self.operator == '%' \
4777 and type1 in (Builtin.str_type, Builtin.unicode_type):
4778 # note that b'%s' % b'abc' doesn't work in Py3
4780 if type1.is_builtin_type:
4782 if self.operator in '**%+|&^':
4783 # FIXME: at least these operators should be safe - others?
4785 elif self.operator == '*':
4786 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
4788 # multiplication of containers/numbers with an
4789 # integer value always (?) returns the same type
4792 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
4793 # multiplication of containers/numbers with an
4794 # integer value always (?) returns the same type
4796 return py_object_type
4798 return self.compute_c_result_type(type1, type2)
4800 def nogil_check(self, env):
4801 if self.is_py_operation():
4804 def coerce_operands_to_pyobjects(self, env):
4805 self.operand1 = self.operand1.coerce_to_pyobject(env)
4806 self.operand2 = self.operand2.coerce_to_pyobject(env)
4808 def check_const(self):
4809 return self.operand1.check_const() and self.operand2.check_const()
4811 def generate_result_code(self, code):
4812 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
4813 if self.operand1.type.is_pyobject:
4814 function = self.py_operation_function()
4815 if function == "PyNumber_Power":
4816 extra_args = ", Py_None"
4820 "%s = %s(%s, %s%s); %s" % (
4823 self.operand1.py_result(),
4824 self.operand2.py_result(),
4826 code.error_goto_if_null(self.result(), self.pos)))
4827 code.put_gotref(self.py_result())
4829 def type_error(self):
4830 if not (self.operand1.type.is_error
4831 or self.operand2.type.is_error):
4832 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
4833 (self.operator, self.operand1.type,
4834 self.operand2.type))
4835 self.type = PyrexTypes.error_type
4838 class NumBinopNode(BinopNode):
4839 # Binary operation taking numeric arguments.
4843 def analyse_c_operation(self, env):
4844 type1 = self.operand1.type
4845 type2 = self.operand2.type
4846 self.type = self.compute_c_result_type(type1, type2)
4850 if self.type.is_complex:
4853 self.operand1 = self.operand1.coerce_to(self.type, env)
4854 self.operand2 = self.operand2.coerce_to(self.type, env)
4856 def compute_c_result_type(self, type1, type2):
4857 if self.c_types_okay(type1, type2):
4858 return PyrexTypes.widest_numeric_type(type1, type2)
4862 def get_constant_c_result_code(self):
4863 value1 = self.operand1.get_constant_c_result_code()
4864 value2 = self.operand2.get_constant_c_result_code()
4865 if value1 and value2:
4866 return "(%s %s %s)" % (value1, self.operator, value2)
4870 def c_types_okay(self, type1, type2):
4871 #print "NumBinopNode.c_types_okay:", type1, type2 ###
4872 return (type1.is_numeric or type1.is_enum) \
4873 and (type2.is_numeric or type2.is_enum)
4875 def calculate_result_code(self):
4877 return "(%s %s %s)" % (
4878 self.operand1.result(),
4880 self.operand2.result())
4882 func = self.type.binary_op(self.operator)
4884 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
4885 return "%s(%s, %s)" % (
4887 self.operand1.result(),
4888 self.operand2.result())
4890 def py_operation_function(self):
4891 return self.py_functions[self.operator]
4895 "^": "PyNumber_Xor",
4896 "&": "PyNumber_And",
4897 "<<": "PyNumber_Lshift",
4898 ">>": "PyNumber_Rshift",
4899 "+": "PyNumber_Add",
4900 "-": "PyNumber_Subtract",
4901 "*": "PyNumber_Multiply",
4902 "/": "__Pyx_PyNumber_Divide",
4903 "//": "PyNumber_FloorDivide",
4904 "%": "PyNumber_Remainder",
4905 "**": "PyNumber_Power"
4909 class IntBinopNode(NumBinopNode):
4910 # Binary operation taking integer arguments.
4912 def c_types_okay(self, type1, type2):
4913 #print "IntBinopNode.c_types_okay:", type1, type2 ###
4914 return (type1.is_int or type1.is_enum) \
4915 and (type2.is_int or type2.is_enum)
4918 class AddNode(NumBinopNode):
4921 def is_py_operation_types(self, type1, type2):
4922 if type1.is_string and type2.is_string:
4925 return NumBinopNode.is_py_operation_types(self, type1, type2)
4927 def compute_c_result_type(self, type1, type2):
4928 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
4929 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4931 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
4934 return NumBinopNode.compute_c_result_type(
4938 class SubNode(NumBinopNode):
4941 def compute_c_result_type(self, type1, type2):
4942 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4944 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
4945 return PyrexTypes.c_int_type
4947 return NumBinopNode.compute_c_result_type(
4951 class MulNode(NumBinopNode):
4954 def is_py_operation_types(self, type1, type2):
4955 if (type1.is_string and type2.is_int) \
4956 or (type2.is_string and type1.is_int):
4959 return NumBinopNode.is_py_operation_types(self, type1, type2)
4962 class DivNode(NumBinopNode):
4963 # '/' or '//' operator.
4966 truedivision = None # == "unknown" if operator == '/'
4967 ctruedivision = False
4968 cdivision_warnings = False
4969 zerodivision_check = None
4971 def find_compile_time_binary_operator(self, op1, op2):
4972 func = compile_time_binary_operators[self.operator]
4973 if self.operator == '/' and self.truedivision is None:
4974 # => true div for floats, floor div for integers
4975 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
4976 func = compile_time_binary_operators['//']
4979 def calculate_constant_result(self):
4980 op1 = self.operand1.constant_result
4981 op2 = self.operand2.constant_result
4982 func = self.find_compile_time_binary_operator(op1, op2)
4983 self.constant_result = func(
4984 self.operand1.constant_result,
4985 self.operand2.constant_result)
4987 def compile_time_value(self, denv):
4988 operand1 = self.operand1.compile_time_value(denv)
4989 operand2 = self.operand2.compile_time_value(denv)
4991 func = self.find_compile_time_binary_operator(
4992 self, operand1, operand2)
4993 return func(operand1, operand2)
4994 except Exception, e:
4995 self.compile_time_value_error(e)
4997 def analyse_types(self, env):
4998 if self.cdivision or env.directives['cdivision']:
4999 self.ctruedivision = False
5001 self.ctruedivision = self.truedivision
5002 NumBinopNode.analyse_types(self, env)
5003 if self.is_cpp_operation():
5004 self.cdivision = True
5005 if not self.type.is_pyobject:
5006 self.zerodivision_check = (
5007 self.cdivision is None and not env.directives['cdivision']
5008 and (self.operand2.constant_result is not_a_constant or
5009 self.operand2.constant_result == 0))
5010 if self.zerodivision_check or env.directives['cdivision_warnings']:
5011 # Need to check ahead of time to warn or raise zero division error
5012 self.operand1 = self.operand1.coerce_to_simple(env)
5013 self.operand2 = self.operand2.coerce_to_simple(env)
5015 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5017 def compute_c_result_type(self, type1, type2):
5018 if self.operator == '/' and self.ctruedivision:
5019 if not type1.is_float and not type2.is_float:
5020 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5021 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5023 return NumBinopNode.compute_c_result_type(self, type1, type2)
5025 def zero_division_message(self):
5026 if self.type.is_int:
5027 return "integer division or modulo by zero"
5029 return "float division"
5031 def generate_evaluation_code(self, code):
5032 if not self.type.is_pyobject and not self.type.is_complex:
5033 if self.cdivision is None:
5034 self.cdivision = (code.globalstate.directives['cdivision']
5035 or not self.type.signed
5036 or self.type.is_float)
5037 if not self.cdivision:
5038 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5039 NumBinopNode.generate_evaluation_code(self, code)
5040 self.generate_div_warning_code(code)
5042 def generate_div_warning_code(self, code):
5043 if not self.type.is_pyobject:
5044 if self.zerodivision_check:
5046 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5048 zero_test = "%s == 0" % self.operand2.result()
5049 code.putln("if (unlikely(%s)) {" % zero_test)
5050 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
5051 code.putln(code.error_goto(self.pos))
5053 if self.type.is_int and self.type.signed and self.operator != '%':
5054 code.globalstate.use_utility_code(division_overflow_test_code)
5055 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
5056 self.type.declaration_code(''),
5057 self.operand2.result(),
5058 self.operand1.result()))
5059 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
5060 code.putln(code.error_goto(self.pos))
5062 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
5063 code.globalstate.use_utility_code(cdivision_warning_utility_code)
5064 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
5065 self.operand1.result(),
5066 self.operand2.result()))
5067 code.putln(code.set_error_info(self.pos));
5068 code.put("if (__Pyx_cdivision_warning()) ")
5069 code.put_goto(code.error_label)
5072 def calculate_result_code(self):
5073 if self.type.is_complex:
5074 return NumBinopNode.calculate_result_code(self)
5075 elif self.type.is_float and self.operator == '//':
5076 return "floor(%s / %s)" % (
5077 self.operand1.result(),
5078 self.operand2.result())
5079 elif self.truedivision or self.cdivision:
5080 op1 = self.operand1.result()
5081 op2 = self.operand2.result()
5082 if self.truedivision:
5083 if self.type != self.operand1.type:
5084 op1 = self.type.cast_code(op1)
5085 if self.type != self.operand2.type:
5086 op2 = self.type.cast_code(op2)
5087 return "(%s / %s)" % (op1, op2)
5089 return "__Pyx_div_%s(%s, %s)" % (
5090 self.type.specalization_name(),
5091 self.operand1.result(),
5092 self.operand2.result())
5095 class ModNode(DivNode):
5098 def is_py_operation_types(self, type1, type2):
5099 return (type1.is_string
5101 or NumBinopNode.is_py_operation_types(self, type1, type2))
5103 def zero_division_message(self):
5104 if self.type.is_int:
5105 return "integer division or modulo by zero"
5107 return "float divmod()"
5109 def generate_evaluation_code(self, code):
5110 if not self.type.is_pyobject:
5111 if self.cdivision is None:
5112 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
5113 if not self.cdivision:
5114 if self.type.is_int:
5115 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
5117 code.globalstate.use_utility_code(
5118 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
5119 NumBinopNode.generate_evaluation_code(self, code)
5120 self.generate_div_warning_code(code)
5122 def calculate_result_code(self):
5124 if self.type.is_float:
5125 return "fmod%s(%s, %s)" % (
5126 self.type.math_h_modifier,
5127 self.operand1.result(),
5128 self.operand2.result())
5130 return "(%s %% %s)" % (
5131 self.operand1.result(),
5132 self.operand2.result())
5134 return "__Pyx_mod_%s(%s, %s)" % (
5135 self.type.specalization_name(),
5136 self.operand1.result(),
5137 self.operand2.result())
5139 class PowNode(NumBinopNode):
5142 def analyse_c_operation(self, env):
5143 NumBinopNode.analyse_c_operation(self, env)
5144 if self.type.is_complex:
5145 error(self.pos, "complex powers not yet supported")
5146 self.pow_func = "<error>"
5147 elif self.type.is_float:
5148 self.pow_func = "pow"
5150 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
5151 env.use_utility_code(
5152 int_pow_utility_code.specialize(func_name=self.pow_func,
5153 type=self.type.declaration_code('')))
5155 def calculate_result_code(self):
5156 return "%s(%s, %s)" % (
5158 self.operand1.result(),
5159 self.operand2.result())
5162 # Note: This class is temporary "shut down" into an ineffective mode temp
5165 # More sophisticated temp reuse was going on before,
5166 # one could have a look at adding this again after /all/ classes
5167 # are converted to the new temp scheme. (The temp juggling cannot work
5169 class BoolBinopNode(ExprNode):
5170 # Short-circuiting boolean operation.
5176 subexprs = ['operand1', 'operand2']
5178 def infer_type(self, env):
5179 type1 = self.operand1.infer_type(env)
5180 type2 = self.operand2.infer_type(env)
5181 return PyrexTypes.spanning_type(type1, type2)
5183 def calculate_constant_result(self):
5184 if self.operator == 'and':
5185 self.constant_result = \
5186 self.operand1.constant_result and \
5187 self.operand2.constant_result
5189 self.constant_result = \
5190 self.operand1.constant_result or \
5191 self.operand2.constant_result
5193 def compile_time_value(self, denv):
5194 if self.operator == 'and':
5195 return self.operand1.compile_time_value(denv) \
5196 and self.operand2.compile_time_value(denv)
5198 return self.operand1.compile_time_value(denv) \
5199 or self.operand2.compile_time_value(denv)
5201 def coerce_to_boolean(self, env):
5202 self.operand1 = self.operand1.coerce_to_boolean(env)
5203 self.operand2 = self.operand2.coerce_to_boolean(env)
5204 self.type = PyrexTypes.c_bint_type
5207 def analyse_types(self, env):
5208 self.operand1.analyse_types(env)
5209 self.operand2.analyse_types(env)
5210 self.type = PyrexTypes.spanning_type(self.operand1.type, self.operand2.type)
5211 self.operand1 = self.operand1.coerce_to(self.type, env)
5212 self.operand2 = self.operand2.coerce_to(self.type, env)
5214 # For what we're about to do, it's vital that
5215 # both operands be temp nodes.
5216 self.operand1 = self.operand1.coerce_to_simple(env)
5217 self.operand2 = self.operand2.coerce_to_simple(env)
5220 gil_message = "Truth-testing Python object"
5222 def check_const(self):
5223 return self.operand1.check_const() and self.operand2.check_const()
5225 def generate_evaluation_code(self, code):
5226 code.mark_pos(self.pos)
5227 self.operand1.generate_evaluation_code(code)
5228 test_result, uses_temp = self.generate_operand1_test(code)
5229 if self.operator == 'and':
5238 code.funcstate.release_temp(test_result)
5239 self.operand1.generate_disposal_code(code)
5240 self.operand2.generate_evaluation_code(code)
5241 self.allocate_temp_result(code)
5242 self.operand2.make_owned_reference(code)
5243 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
5244 self.operand2.generate_post_assignment_code(code)
5245 self.operand2.free_temps(code)
5246 code.putln("} else {")
5247 self.operand1.make_owned_reference(code)
5248 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
5249 self.operand1.generate_post_assignment_code(code)
5250 self.operand1.free_temps(code)
5253 def generate_operand1_test(self, code):
5254 # Generate code to test the truth of the first operand.
5255 if self.type.is_pyobject:
5256 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
5259 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5261 self.operand1.py_result(),
5262 code.error_goto_if_neg(test_result, self.pos)))
5264 test_result = self.operand1.result()
5265 return (test_result, self.type.is_pyobject)
5268 class CondExprNode(ExprNode):
5269 # Short-circuiting conditional expression.
5273 # false_val ExprNode
5278 subexprs = ['test', 'true_val', 'false_val']
5280 def type_dependencies(self, env):
5281 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
5283 def infer_type(self, env):
5284 return self.compute_result_type(self.true_val.infer_type(env),
5285 self.false_val.infer_type(env))
5287 def calculate_constant_result(self):
5288 if self.test.constant_result:
5289 self.constant_result = self.true_val.constant_result
5291 self.constant_result = self.false_val.constant_result
5293 def analyse_types(self, env):
5294 self.test.analyse_types(env)
5295 self.test = self.test.coerce_to_boolean(env)
5296 self.true_val.analyse_types(env)
5297 self.false_val.analyse_types(env)
5298 self.type = self.compute_result_type(self.true_val.type, self.false_val.type)
5299 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
5300 self.true_val = self.true_val.coerce_to(self.type, env)
5301 self.false_val = self.false_val.coerce_to(self.type, env)
5303 if self.type == PyrexTypes.error_type:
5306 def compute_result_type(self, type1, type2):
5309 elif type1.is_numeric and type2.is_numeric:
5310 return PyrexTypes.widest_numeric_type(type1, type2)
5311 elif type1.is_extension_type and type1.subtype_of_resolved_type(type2):
5313 elif type2.is_extension_type and type2.subtype_of_resolved_type(type1):
5315 elif type1.is_pyobject or type2.is_pyobject:
5316 return py_object_type
5317 elif type1.assignable_from(type2):
5319 elif type2.assignable_from(type1):
5322 return PyrexTypes.error_type
5324 def type_error(self):
5325 if not (self.true_val.type.is_error or self.false_val.type.is_error):
5326 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
5327 (self.true_val.type, self.false_val.type))
5328 self.type = PyrexTypes.error_type
5330 def check_const(self):
5331 return (self.test.check_const()
5332 and self.true_val.check_const()
5333 and self.false_val.check_const())
5335 def generate_evaluation_code(self, code):
5336 # Because subexprs may not be evaluated we can use a more optimal
5337 # subexpr allocation strategy than the default, so override evaluation_code.
5339 code.mark_pos(self.pos)
5340 self.allocate_temp_result(code)
5341 self.test.generate_evaluation_code(code)
5342 code.putln("if (%s) {" % self.test.result() )
5343 self.eval_and_get(code, self.true_val)
5344 code.putln("} else {")
5345 self.eval_and_get(code, self.false_val)
5347 self.test.generate_disposal_code(code)
5348 self.test.free_temps(code)
5350 def eval_and_get(self, code, expr):
5351 expr.generate_evaluation_code(code)
5352 expr.make_owned_reference(code)
5353 code.putln("%s = %s;" % (self.result(), expr.result()))
5354 expr.generate_post_assignment_code(code)
5355 expr.free_temps(code)
5357 richcmp_constants = {
5367 class CmpNode(object):
5368 # Mixin class containing code common to PrimaryCmpNodes
5369 # and CascadedCmpNodes.
5371 def infer_types(self, env):
5372 # TODO: Actually implement this (after merging with -unstable).
5373 return py_object_type
5375 def calculate_cascaded_constant_result(self, operand1_result):
5376 func = compile_time_binary_operators[self.operator]
5377 operand2_result = self.operand2.constant_result
5378 result = func(operand1_result, operand2_result)
5379 if result and self.cascade:
5380 result = result and \
5381 self.cascade.cascaded_compile_time_value(operand2_result)
5382 self.constant_result = result
5384 def cascaded_compile_time_value(self, operand1, denv):
5385 func = get_compile_time_binop(self)
5386 operand2 = self.operand2.compile_time_value(denv)
5388 result = func(operand1, operand2)
5389 except Exception, e:
5390 self.compile_time_value_error(e)
5393 cascade = self.cascade
5395 # FIXME: I bet this must call cascaded_compile_time_value()
5396 result = result and cascade.compile_time_value(operand2, denv)
5399 def is_cpp_comparison(self):
5400 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
5402 def find_common_int_type(self, env, op, operand1, operand2):
5403 # type1 != type2 and at least one of the types is not a C int
5404 type1 = operand1.type
5405 type2 = operand2.type
5406 type1_can_be_int = False
5407 type2_can_be_int = False
5409 if isinstance(operand1, (StringNode, BytesNode)) \
5410 and operand1.can_coerce_to_char_literal():
5411 type1_can_be_int = True
5412 if isinstance(operand2, (StringNode, BytesNode)) \
5413 and operand2.can_coerce_to_char_literal():
5414 type2_can_be_int = True
5417 if type2_can_be_int:
5420 if type1_can_be_int:
5422 elif type1_can_be_int:
5423 if type2_can_be_int:
5424 return PyrexTypes.c_uchar_type
5428 def find_common_type(self, env, op, operand1, common_type=None):
5429 operand2 = self.operand2
5430 type1 = operand1.type
5431 type2 = operand2.type
5433 new_common_type = None
5435 # catch general errors
5436 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
5437 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
5438 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
5439 new_common_type = error_type
5441 # try to use numeric comparisons where possible
5442 elif type1.is_complex or type2.is_complex:
5443 if op not in ('==', '!='):
5444 error(self.pos, "complex types are unordered")
5445 new_common_type = error_type
5446 if type1.is_pyobject:
5447 new_common_type = type1
5448 elif type2.is_pyobject:
5449 new_common_type = type2
5451 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5452 elif type1.is_numeric and type2.is_numeric:
5453 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5454 elif common_type is None or not common_type.is_pyobject:
5455 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
5457 if new_common_type is None:
5458 # fall back to generic type compatibility tests
5460 new_common_type = type1
5461 elif type1.is_pyobject or type2.is_pyobject:
5462 if type2.is_numeric or type2.is_string:
5463 if operand2.check_for_coercion_error(type1):
5464 new_common_type = error_type
5466 new_common_type = py_object_type
5467 elif type1.is_numeric or type1.is_string:
5468 if operand1.check_for_coercion_error(type2):
5469 new_common_type = error_type
5471 new_common_type = py_object_type
5472 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
5473 new_common_type = py_object_type
5475 # one Python type and one non-Python type, not assignable
5476 self.invalid_types_error(operand1, op, operand2)
5477 new_common_type = error_type
5478 elif type1.assignable_from(type2):
5479 new_common_type = type1
5480 elif type2.assignable_from(type1):
5481 new_common_type = type2
5483 # C types that we couldn't handle up to here are an error
5484 self.invalid_types_error(operand1, op, operand2)
5485 new_common_type = error_type
5487 # recursively merge types
5488 if common_type is None or new_common_type.is_error:
5489 common_type = new_common_type
5491 # we could do a lot better by splitting the comparison
5492 # into a non-Python part and a Python part, but this is
5494 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
5497 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
5501 def invalid_types_error(self, operand1, op, operand2):
5502 error(self.pos, "Invalid types for '%s' (%s, %s)" %
5503 (op, operand1.type, operand2.type))
5505 def is_python_comparison(self):
5506 return (self.has_python_operands()
5507 or (self.cascade and self.cascade.is_python_comparison())
5508 or self.operator in ('in', 'not_in'))
5510 def coerce_operands_to(self, dst_type, env):
5511 operand2 = self.operand2
5512 if operand2.type != dst_type:
5513 self.operand2 = operand2.coerce_to(dst_type, env)
5515 self.cascade.coerce_operands_to(dst_type, env)
5517 def is_python_result(self):
5518 return ((self.has_python_operands() and
5519 self.operator not in ('is', 'is_not', 'in', 'not_in'))
5520 or (self.cascade and self.cascade.is_python_result()))
5522 def generate_operation_code(self, code, result_code,
5523 operand1, op , operand2):
5524 if self.type is PyrexTypes.py_object_type:
5525 coerce_result = "__Pyx_PyBool_FromLong"
5532 if op == 'in' or op == 'not_in':
5533 code.globalstate.use_utility_code(contians_utility_code)
5534 if self.type is PyrexTypes.py_object_type:
5535 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
5537 negation = "__Pyx_NegateNonNeg"
5538 if operand2.type is dict_type:
5539 code.globalstate.use_utility_code(
5540 raise_none_iter_error_utility_code)
5541 code.putln("if (unlikely(%s == Py_None)) {" % operand2.py_result())
5542 code.putln("__Pyx_RaiseNoneNotIterableError(); %s" %
5543 code.error_goto(self.pos))
5544 code.putln("} else {")
5545 method = "PyDict_Contains"
5547 method = "PySequence_Contains"
5548 if self.type is PyrexTypes.py_object_type:
5549 error_clause = code.error_goto_if_null
5550 got_ref = "__Pyx_XGOTREF(%s); " % result_code
5552 error_clause = code.error_goto_if_neg
5555 "%s = %s(%s(%s(%s, %s))); %s%s" % (
5560 operand2.py_result(),
5561 operand1.py_result(),
5563 error_clause(result_code, self.pos)))
5564 if operand2.type is dict_type:
5567 elif (operand1.type.is_pyobject
5568 and op not in ('is', 'is_not')):
5569 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
5571 operand1.py_result(),
5572 operand2.py_result(),
5573 richcmp_constants[op],
5574 code.error_goto_if_null(result_code, self.pos)))
5575 code.put_gotref(result_code)
5576 elif operand1.type.is_complex:
5581 code.putln("%s = %s(%s%s(%s, %s));" % (
5585 operand1.type.unary_op('eq'),
5589 type1 = operand1.type
5590 type2 = operand2.type
5591 if (type1.is_extension_type or type2.is_extension_type) \
5592 and not type1.same_as(type2):
5593 common_type = py_object_type
5594 elif type1.is_numeric:
5595 common_type = PyrexTypes.widest_numeric_type(type1, type2)
5598 code1 = operand1.result_as(common_type)
5599 code2 = operand2.result_as(common_type)
5600 code.putln("%s = %s(%s %s %s);" % (
5604 self.c_operator(op),
5607 def c_operator(self, op):
5610 elif op == 'is_not':
5615 contians_utility_code = UtilityCode(
5617 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
5618 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
5619 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
5624 class PrimaryCmpNode(ExprNode, CmpNode):
5625 # Non-cascaded comparison or first comparison of
5626 # a cascaded sequence.
5631 # cascade CascadedCmpNode
5633 # We don't use the subexprs mechanism, because
5634 # things here are too complicated for it to handle.
5635 # Instead, we override all the framework methods
5638 child_attrs = ['operand1', 'operand2', 'cascade']
5642 def infer_type(self, env):
5643 # TODO: Actually implement this (after merging with -unstable).
5644 return py_object_type
5646 def type_dependencies(self, env):
5649 def calculate_constant_result(self):
5650 self.constant_result = self.calculate_cascaded_constant_result(
5651 self.operand1.constant_result)
5653 def compile_time_value(self, denv):
5654 operand1 = self.operand1.compile_time_value(denv)
5655 return self.cascaded_compile_time_value(operand1, denv)
5657 def analyse_types(self, env):
5658 self.operand1.analyse_types(env)
5659 self.operand2.analyse_types(env)
5660 if self.is_cpp_comparison():
5661 self.analyse_cpp_comparison(env)
5663 error(self.pos, "Cascading comparison not yet supported for cpp types.")
5666 self.cascade.analyse_types(env)
5668 if self.operator in ('in', 'not_in'):
5669 common_type = py_object_type
5670 self.is_pycmp = True
5672 common_type = self.find_common_type(env, self.operator, self.operand1)
5673 self.is_pycmp = common_type.is_pyobject
5675 if not common_type.is_error:
5676 if self.operand1.type != common_type:
5677 self.operand1 = self.operand1.coerce_to(common_type, env)
5678 self.coerce_operands_to(common_type, env)
5681 self.operand2 = self.operand2.coerce_to_simple(env)
5682 self.cascade.coerce_cascaded_operands_to_temp(env)
5683 if self.is_python_result():
5684 self.type = PyrexTypes.py_object_type
5686 self.type = PyrexTypes.c_bint_type
5689 cdr.type = self.type
5691 if self.is_pycmp or self.cascade:
5694 def analyse_cpp_comparison(self, env):
5695 type1 = self.operand1.type
5696 type2 = self.operand2.type
5697 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5699 error(self.pos, "Invalid types for '%s' (%s, %s)" %
5700 (self.operator, type1, type2))
5701 self.type = PyrexTypes.error_type
5702 self.result_code = "<error>"
5704 func_type = entry.type
5705 if func_type.is_ptr:
5706 func_type = func_type.base_type
5707 if len(func_type.args) == 1:
5708 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5710 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5711 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5712 self.type = func_type.return_type
5714 def has_python_operands(self):
5715 return (self.operand1.type.is_pyobject
5716 or self.operand2.type.is_pyobject)
5718 def check_const(self):
5723 return self.operand1.check_const() and self.operand2.check_const()
5725 def calculate_result_code(self):
5726 if self.operand1.type.is_complex:
5727 if self.operator == "!=":
5731 return "(%s%s(%s, %s))" % (
5733 self.operand1.type.binary_op('=='),
5734 self.operand1.result(),
5735 self.operand2.result())
5737 return "(%s %s %s)" % (
5738 self.operand1.result(),
5739 self.c_operator(self.operator),
5740 self.operand2.result())
5742 def generate_evaluation_code(self, code):
5743 self.operand1.generate_evaluation_code(code)
5744 self.operand2.generate_evaluation_code(code)
5746 self.allocate_temp_result(code)
5747 self.generate_operation_code(code, self.result(),
5748 self.operand1, self.operator, self.operand2)
5750 self.cascade.generate_evaluation_code(code,
5751 self.result(), self.operand2)
5752 self.operand1.generate_disposal_code(code)
5753 self.operand1.free_temps(code)
5754 self.operand2.generate_disposal_code(code)
5755 self.operand2.free_temps(code)
5757 def generate_subexpr_disposal_code(self, code):
5758 # If this is called, it is a non-cascaded cmp,
5759 # so only need to dispose of the two main operands.
5760 self.operand1.generate_disposal_code(code)
5761 self.operand2.generate_disposal_code(code)
5763 def free_subexpr_temps(self, code):
5764 # If this is called, it is a non-cascaded cmp,
5765 # so only need to dispose of the two main operands.
5766 self.operand1.free_temps(code)
5767 self.operand2.free_temps(code)
5769 def annotate(self, code):
5770 self.operand1.annotate(code)
5771 self.operand2.annotate(code)
5773 self.cascade.annotate(code)
5776 class CascadedCmpNode(Node, CmpNode):
5777 # A CascadedCmpNode is not a complete expression node. It
5778 # hangs off the side of another comparison node, shares
5779 # its left operand with that node, and shares its result
5780 # with the PrimaryCmpNode at the head of the chain.
5784 # cascade CascadedCmpNode
5786 child_attrs = ['operand2', 'cascade']
5789 constant_result = constant_value_not_set # FIXME: where to calculate this?
5791 def infer_type(self, env):
5792 # TODO: Actually implement this (after merging with -unstable).
5793 return py_object_type
5795 def type_dependencies(self, env):
5798 def analyse_types(self, env):
5799 self.operand2.analyse_types(env)
5801 self.cascade.analyse_types(env)
5803 def has_python_operands(self):
5804 return self.operand2.type.is_pyobject
5806 def coerce_operands_to_pyobjects(self, env):
5807 self.operand2 = self.operand2.coerce_to_pyobject(env)
5809 self.cascade.coerce_operands_to_pyobjects(env)
5811 def coerce_cascaded_operands_to_temp(self, env):
5813 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
5814 self.operand2 = self.operand2.coerce_to_simple(env)
5815 self.cascade.coerce_cascaded_operands_to_temp(env)
5817 def generate_evaluation_code(self, code, result, operand1):
5818 if self.type.is_pyobject:
5819 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
5820 code.put_decref(result, self.type)
5822 code.putln("if (%s) {" % result)
5823 self.operand2.generate_evaluation_code(code)
5824 self.generate_operation_code(code, result,
5825 operand1, self.operator, self.operand2)
5827 self.cascade.generate_evaluation_code(
5828 code, result, self.operand2)
5829 # Cascaded cmp result is always temp
5830 self.operand2.generate_disposal_code(code)
5831 self.operand2.free_temps(code)
5834 def annotate(self, code):
5835 self.operand2.annotate(code)
5837 self.cascade.annotate(code)
5840 binop_node_classes = {
5841 "or": BoolBinopNode,
5842 "and": BoolBinopNode,
5857 def binop_node(pos, operator, operand1, operand2):
5858 # Construct binop node of appropriate class for
5860 return binop_node_classes[operator](pos,
5861 operator = operator,
5862 operand1 = operand1,
5863 operand2 = operand2)
5865 #-------------------------------------------------------------------
5869 # Coercion nodes are special in that they are created during
5870 # the analyse_types phase of parse tree processing.
5871 # Their __init__ methods consequently incorporate some aspects
5874 #-------------------------------------------------------------------
5876 class CoercionNode(ExprNode):
5877 # Abstract base class for coercion nodes.
5879 # arg ExprNode node being coerced
5882 constant_result = not_a_constant
5884 def __init__(self, arg):
5888 print("%s Coercing %s" % (self, self.arg))
5890 def calculate_constant_result(self):
5891 # constant folding can break type coercion, so this is disabled
5894 def annotate(self, code):
5895 self.arg.annotate(code)
5896 if self.arg.type != self.type:
5897 file, line, col = self.pos
5898 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
5901 class CastNode(CoercionNode):
5902 # Wrap a node in a C type cast.
5904 def __init__(self, arg, new_type):
5905 CoercionNode.__init__(self, arg)
5906 self.type = new_type
5908 def calculate_result_code(self):
5909 return self.arg.result_as(self.type)
5911 def generate_result_code(self, code):
5912 self.arg.generate_result_code(code)
5915 class PyTypeTestNode(CoercionNode):
5916 # This node is used to check that a generic Python
5917 # object is an instance of a particular extension type.
5918 # This node borrows the result of its argument node.
5920 def __init__(self, arg, dst_type, env, notnone=False):
5921 # The arg is know to be a Python object, and
5922 # the dst_type is known to be an extension type.
5923 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
5924 CoercionNode.__init__(self, arg)
5925 self.type = dst_type
5926 self.result_ctype = arg.ctype()
5927 self.notnone = notnone
5929 nogil_check = Node.gil_error
5930 gil_message = "Python type test"
5932 def analyse_types(self, env):
5935 def result_in_temp(self):
5936 return self.arg.result_in_temp()
5938 def is_ephemeral(self):
5939 return self.arg.is_ephemeral()
5941 def calculate_constant_result(self):
5945 def calculate_result_code(self):
5946 return self.arg.result()
5948 def generate_result_code(self, code):
5949 if self.type.typeobj_is_available():
5950 if not self.type.is_builtin_type:
5951 code.globalstate.use_utility_code(type_test_utility_code)
5954 self.type.type_test_code(self.arg.py_result(), self.notnone),
5955 code.error_goto(self.pos)))
5957 error(self.pos, "Cannot test type of extern C class "
5958 "without type object name specification")
5960 def generate_post_assignment_code(self, code):
5961 self.arg.generate_post_assignment_code(code)
5963 def free_temps(self, code):
5964 self.arg.free_temps(code)
5967 class NoneCheckNode(CoercionNode):
5968 # This node is used to check that a Python object is not None and
5969 # raises an appropriate exception (as specified by the creating
5972 def __init__(self, arg, exception_type_cname, exception_message):
5973 CoercionNode.__init__(self, arg)
5974 self.type = arg.type
5975 self.result_ctype = arg.ctype()
5976 self.exception_type_cname = exception_type_cname
5977 self.exception_message = exception_message
5979 def analyse_types(self, env):
5982 def result_in_temp(self):
5983 return self.arg.result_in_temp()
5985 def calculate_result_code(self):
5986 return self.arg.result()
5988 def generate_result_code(self, code):
5990 "if (unlikely(%s == Py_None)) {" % self.arg.result())
5991 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
5992 self.exception_type_cname,
5993 StringEncoding.escape_byte_string(
5994 self.exception_message.encode('UTF-8')),
5995 code.error_goto(self.pos)))
5998 def generate_post_assignment_code(self, code):
5999 self.arg.generate_post_assignment_code(code)
6001 def free_temps(self, code):
6002 self.arg.free_temps(code)
6005 class CoerceToPyTypeNode(CoercionNode):
6006 # This node is used to convert a C data type
6007 # to a Python object.
6009 type = py_object_type
6012 def __init__(self, arg, env, type=py_object_type):
6013 CoercionNode.__init__(self, arg)
6014 if not arg.type.create_to_py_utility_code(env):
6016 "Cannot convert '%s' to Python object" % arg.type)
6017 if type is not py_object_type:
6018 self.type = py_object_type
6019 elif arg.type.is_string:
6020 self.type = Builtin.bytes_type
6022 gil_message = "Converting to Python object"
6024 def coerce_to_boolean(self, env):
6025 return self.arg.coerce_to_boolean(env).coerce_to_temp(env)
6027 def coerce_to_integer(self, env):
6028 # If not already some C integer type, coerce to longint.
6029 if self.arg.type.is_int:
6032 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
6034 def analyse_types(self, env):
6035 # The arg is always already analysed
6038 def generate_result_code(self, code):
6039 function = self.arg.type.to_py_function
6040 code.putln('%s = %s(%s); %s' % (
6044 code.error_goto_if_null(self.result(), self.pos)))
6045 code.put_gotref(self.py_result())
6048 class CoerceFromPyTypeNode(CoercionNode):
6049 # This node is used to convert a Python object
6052 def __init__(self, result_type, arg, env):
6053 CoercionNode.__init__(self, arg)
6054 self.type = result_type
6056 if not result_type.create_from_py_utility_code(env):
6058 "Cannot convert Python object to '%s'" % result_type)
6059 if self.type.is_string and self.arg.is_ephemeral():
6061 "Obtaining char * from temporary Python value")
6063 def analyse_types(self, env):
6064 # The arg is always already analysed
6067 def generate_result_code(self, code):
6068 function = self.type.from_py_function
6069 operand = self.arg.py_result()
6070 rhs = "%s(%s)" % (function, operand)
6071 if self.type.is_enum:
6072 rhs = typecast(self.type, c_long_type, rhs)
6073 code.putln('%s = %s; %s' % (
6076 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
6077 if self.type.is_pyobject:
6078 code.put_gotref(self.py_result())
6081 class CoerceToBooleanNode(CoercionNode):
6082 # This node is used when a result needs to be used
6083 # in a boolean context.
6085 type = PyrexTypes.c_bint_type
6087 def __init__(self, arg, env):
6088 CoercionNode.__init__(self, arg)
6089 if arg.type.is_pyobject:
6092 def nogil_check(self, env):
6093 if self.arg.type.is_pyobject:
6096 gil_message = "Truth-testing Python object"
6098 def check_const(self):
6102 return self.arg.check_const()
6104 def calculate_result_code(self):
6105 return "(%s != 0)" % self.arg.result()
6107 def generate_result_code(self, code):
6108 if self.arg.type.is_pyobject:
6110 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6112 self.arg.py_result(),
6113 code.error_goto_if_neg(self.result(), self.pos)))
6115 class CoerceToComplexNode(CoercionNode):
6117 def __init__(self, arg, dst_type, env):
6118 if arg.type.is_complex:
6119 arg = arg.coerce_to_simple(env)
6120 self.type = dst_type
6121 CoercionNode.__init__(self, arg)
6122 dst_type.create_declaration_utility_code(env)
6124 def calculate_result_code(self):
6125 if self.arg.type.is_complex:
6126 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
6127 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
6129 real_part = self.arg.result()
6131 return "%s(%s, %s)" % (
6132 self.type.from_parts,
6136 def generate_result_code(self, code):
6139 class CoerceToTempNode(CoercionNode):
6140 # This node is used to force the result of another node
6141 # to be stored in a temporary. It is only used if the
6142 # argument node's result is not already in a temporary.
6144 def __init__(self, arg, env):
6145 CoercionNode.__init__(self, arg)
6146 self.type = self.arg.type
6148 if self.type.is_pyobject:
6149 self.result_ctype = py_object_type
6151 gil_message = "Creating temporary Python reference"
6153 def analyse_types(self, env):
6154 # The arg is always already analysed
6157 def coerce_to_boolean(self, env):
6158 self.arg = self.arg.coerce_to_boolean(env)
6159 self.type = self.arg.type
6160 self.result_ctype = self.type
6163 def generate_result_code(self, code):
6164 #self.arg.generate_evaluation_code(code) # Already done
6165 # by generic generate_subexpr_evaluation_code!
6166 code.putln("%s = %s;" % (
6167 self.result(), self.arg.result_as(self.ctype())))
6168 if self.type.is_pyobject and self.use_managed_ref:
6169 code.put_incref(self.result(), self.ctype())
6172 class CloneNode(CoercionNode):
6173 # This node is employed when the result of another node needs
6174 # to be used multiple times. The argument node's result must
6175 # be in a temporary. This node "borrows" the result from the
6176 # argument node, and does not generate any evaluation or
6177 # disposal code for it. The original owner of the argument
6178 # node is responsible for doing those things.
6180 subexprs = [] # Arg is not considered a subexpr
6183 def __init__(self, arg):
6184 CoercionNode.__init__(self, arg)
6185 if hasattr(arg, 'type'):
6186 self.type = arg.type
6187 self.result_ctype = arg.result_ctype
6188 if hasattr(arg, 'entry'):
6189 self.entry = arg.entry
6192 return self.arg.result()
6194 def type_dependencies(self, env):
6195 return self.arg.type_dependencies(env)
6197 def infer_type(self, env):
6198 return self.arg.infer_type(env)
6200 def analyse_types(self, env):
6201 self.type = self.arg.type
6202 self.result_ctype = self.arg.result_ctype
6204 if hasattr(self.arg, 'entry'):
6205 self.entry = self.arg.entry
6207 def generate_evaluation_code(self, code):
6210 def generate_result_code(self, code):
6213 def generate_disposal_code(self, code):
6216 def free_temps(self, code):
6220 class ModuleRefNode(ExprNode):
6221 # Simple returns the module object
6223 type = py_object_type
6227 def analyse_types(self, env):
6230 def calculate_result_code(self):
6231 return Naming.module_cname
6233 def generate_result_code(self, code):
6236 class DocstringRefNode(ExprNode):
6237 # Extracts the docstring of the body element
6240 type = py_object_type
6243 def __init__(self, pos, body):
6244 ExprNode.__init__(self, pos)
6245 assert body.type.is_pyobject
6248 def analyse_types(self, env):
6251 def generate_result_code(self, code):
6252 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__");' %
6253 (self.result(), self.body.result()))
6254 code.put_gotref(self.result())
6258 #------------------------------------------------------------------------------------
6260 # Runtime support code
6262 #------------------------------------------------------------------------------------
6264 get_name_interned_utility_code = UtilityCode(
6266 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
6269 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
6271 result = PyObject_GetAttr(dict, name);
6273 PyErr_SetObject(PyExc_NameError, name);
6278 #------------------------------------------------------------------------------------
6280 import_utility_code = UtilityCode(
6282 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
6285 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
6286 PyObject *__import__ = 0;
6287 PyObject *empty_list = 0;
6288 PyObject *module = 0;
6289 PyObject *global_dict = 0;
6290 PyObject *empty_dict = 0;
6292 __import__ = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
6298 empty_list = PyList_New(0);
6303 global_dict = PyModule_GetDict(%(GLOBALS)s);
6306 empty_dict = PyDict_New();
6309 module = PyObject_CallFunctionObjArgs(__import__,
6310 name, global_dict, empty_dict, list, NULL);
6312 Py_XDECREF(empty_list);
6313 Py_XDECREF(__import__);
6314 Py_XDECREF(empty_dict);
6318 "BUILTINS": Naming.builtins_cname,
6319 "GLOBALS": Naming.module_cname,
6322 #------------------------------------------------------------------------------------
6324 get_exception_utility_code = UtilityCode(
6326 static PyObject *__Pyx_GetExcValue(void); /*proto*/
6329 static PyObject *__Pyx_GetExcValue(void) {
6330 PyObject *type = 0, *value = 0, *tb = 0;
6331 PyObject *tmp_type, *tmp_value, *tmp_tb;
6332 PyObject *result = 0;
6333 PyThreadState *tstate = PyThreadState_Get();
6334 PyErr_Fetch(&type, &value, &tb);
6335 PyErr_NormalizeException(&type, &value, &tb);
6336 if (PyErr_Occurred())
6342 tmp_type = tstate->exc_type;
6343 tmp_value = tstate->exc_value;
6344 tmp_tb = tstate->exc_traceback;
6345 tstate->exc_type = type;
6346 tstate->exc_value = value;
6347 tstate->exc_traceback = tb;
6348 /* Make sure tstate is in a consistent state when we XDECREF
6349 these objects (XDECREF may run arbitrary code). */
6350 Py_XDECREF(tmp_type);
6351 Py_XDECREF(tmp_value);
6366 #------------------------------------------------------------------------------------
6368 type_test_utility_code = UtilityCode(
6370 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
6373 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
6374 if (unlikely(!type)) {
6375 PyErr_Format(PyExc_SystemError, "Missing type object");
6378 if (likely(PyObject_TypeCheck(obj, type)))
6380 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
6381 Py_TYPE(obj)->tp_name, type->tp_name);
6386 #------------------------------------------------------------------------------------
6388 create_class_utility_code = UtilityCode(
6390 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/
6393 static PyObject *__Pyx_CreateClass(
6394 PyObject *bases, PyObject *dict, PyObject *name, const char *modname)
6396 PyObject *py_modname;
6397 PyObject *result = 0;
6399 #if PY_MAJOR_VERSION < 3
6400 py_modname = PyString_FromString(modname);
6402 py_modname = PyUnicode_FromString(modname);
6406 if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
6408 #if PY_MAJOR_VERSION < 3
6409 result = PyClass_New(bases, dict, name);
6411 result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
6414 Py_XDECREF(py_modname);
6419 #------------------------------------------------------------------------------------
6421 cpp_exception_utility_code = UtilityCode(
6423 #ifndef __Pyx_CppExn2PyErr
6424 static void __Pyx_CppExn2PyErr() {
6426 if (PyErr_Occurred())
6427 ; // let the latest Python exn pass through and ignore the current one
6430 } catch (const std::out_of_range& exn) {
6431 // catch out_of_range explicitly so the proper Python exn may be raised
6432 PyErr_SetString(PyExc_IndexError, exn.what());
6433 } catch (const std::exception& exn) {
6434 PyErr_SetString(PyExc_RuntimeError, exn.what());
6438 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
6446 #------------------------------------------------------------------------------------
6448 # If the is_unsigned flag is set, we need to do some extra work to make
6449 # sure the index doesn't become negative.
6451 getitem_int_utility_code = UtilityCode(
6454 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
6456 if (!j) return NULL;
6457 r = PyObject_GetItem(o, j);
6464 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6465 __Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\
6466 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
6468 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6469 if (likely(o != Py_None)) {
6470 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
6471 PyObject *r = Py%(type)s_GET_ITEM(o, i);
6475 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
6476 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
6481 return __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
6483 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
6486 #define __Pyx_GetItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6487 __Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\
6488 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
6490 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6492 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
6493 r = PyList_GET_ITEM(o, i);
6496 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
6497 r = PyTuple_GET_ITEM(o, i);
6500 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
6501 r = PySequence_GetItem(o, i);
6504 r = __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
6514 #------------------------------------------------------------------------------------
6516 setitem_int_utility_code = UtilityCode(
6518 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6519 __Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\
6520 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
6522 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
6525 r = PyObject_SetItem(o, j, v);
6530 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
6531 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
6533 Py_DECREF(PyList_GET_ITEM(o, i));
6534 PyList_SET_ITEM(o, i, v);
6537 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
6538 return PySequence_SetItem(o, i, v);
6540 PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
6541 return __Pyx_SetItemInt_Generic(o, j, v);
6548 #------------------------------------------------------------------------------------
6550 delitem_int_utility_code = UtilityCode(
6552 #define __Pyx_DelItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
6553 __Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\
6554 __Pyx_DelItem_Generic(o, to_py_func(i)))
6556 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
6559 r = PyObject_DelItem(o, j);
6564 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
6565 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
6566 return PySequence_DelItem(o, i);
6568 PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
6569 return __Pyx_DelItem_Generic(o, j);
6576 #------------------------------------------------------------------------------------
6578 raise_noneattr_error_utility_code = UtilityCode(
6580 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
6583 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
6584 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
6588 raise_noneindex_error_utility_code = UtilityCode(
6590 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
6593 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
6594 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
6598 raise_none_iter_error_utility_code = UtilityCode(
6600 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
6603 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
6604 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
6608 raise_too_many_values_to_unpack = UtilityCode(
6610 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(void);
6613 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(void) {
6614 PyErr_SetString(PyExc_ValueError, "too many values to unpack");
6618 raise_need_more_values_to_unpack = UtilityCode(
6620 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
6623 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
6624 PyErr_Format(PyExc_ValueError,
6625 #if PY_VERSION_HEX < 0x02050000
6626 "need more than %d value%s to unpack", (int)index,
6628 "need more than %zd value%s to unpack", index,
6630 (index == 1) ? "" : "s");
6634 #------------------------------------------------------------------------------------
6636 tuple_unpacking_error_code = UtilityCode(
6638 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
6641 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
6643 __Pyx_RaiseNoneNotIterableError();
6644 } else if (PyTuple_GET_SIZE(t) < index) {
6645 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
6647 __Pyx_RaiseTooManyValuesError();
6651 requires = [raise_none_iter_error_utility_code,
6652 raise_need_more_values_to_unpack,
6653 raise_too_many_values_to_unpack]
6656 unpacking_utility_code = UtilityCode(
6658 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
6659 static int __Pyx_EndUnpack(PyObject *); /*proto*/
6662 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
6664 if (!(item = PyIter_Next(iter))) {
6665 if (!PyErr_Occurred()) {
6666 __Pyx_RaiseNeedMoreValuesError(index);
6672 static int __Pyx_EndUnpack(PyObject *iter) {
6674 if ((item = PyIter_Next(iter))) {
6676 __Pyx_RaiseTooManyValuesError();
6679 else if (!PyErr_Occurred())
6685 requires = [raise_need_more_values_to_unpack,
6686 raise_too_many_values_to_unpack]
6689 #------------------------------------------------------------------------------------
6691 # CPython supports calling functions with non-dict kwargs by
6692 # converting them to a dict first
6694 kwargs_call_utility_code = UtilityCode(
6696 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
6699 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
6701 if (likely(PyDict_Check(kwargs))) {
6702 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
6704 PyObject* real_dict;
6705 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
6706 if (unlikely(!real_dict))
6708 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
6709 Py_DECREF(real_dict);
6710 return result; /* may be NULL */
6717 #------------------------------------------------------------------------------------
6719 int_pow_utility_code = UtilityCode(
6721 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
6724 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
6736 if (unlikely(e<0)) return 0;
6739 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
6747 # ------------------------------ Division ------------------------------------
6749 div_int_utility_code = UtilityCode(
6751 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
6754 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
6756 %(type)s r = a - q*b;
6757 q -= ((r != 0) & ((r ^ b) < 0));
6762 mod_int_utility_code = UtilityCode(
6764 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6767 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6768 %(type)s r = a %% b;
6769 r += ((r != 0) & ((r ^ b) < 0)) * b;
6774 mod_float_utility_code = UtilityCode(
6776 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6779 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6780 %(type)s r = fmod%(math_h_modifier)s(a, b);
6781 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
6786 cdivision_warning_utility_code = UtilityCode(
6788 static int __Pyx_cdivision_warning(void); /* proto */
6791 static int __Pyx_cdivision_warning(void) {
6792 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
6793 "division with oppositely signed operands, C and Python semantics differ",
6800 'FILENAME': Naming.filename_cname,
6801 'LINENO': Naming.lineno_cname,
6805 division_overflow_test_code = UtilityCode(
6807 #define UNARY_NEG_WOULD_OVERFLOW(x) \
6808 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))