2 # Pyrex - Parse tree nodes for expressions
7 cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
8 CompileError=object, UtilityCode=object, StringEncoding=object, operator=object,
9 Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
10 list_type=object, tuple_type=object, set_type=object, dict_type=object, \
11 unicode_type=object, str_type=object, bytes_type=object, type_type=object,
12 Builtin=object, Symtab=object, Utils=object, find_coercion_error=object,
13 debug_disposal_code=object, debug_temp_alloc=object, debug_coercion=object)
17 from Errors import error, warning, warn_once, InternalError, CompileError
18 from Errors import hold_errors, release_errors, held_errors, report_error
19 from Code import UtilityCode
23 from Nodes import Node
25 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
27 from Builtin import list_type, tuple_type, set_type, dict_type, \
28 unicode_type, str_type, bytes_type, type_type
32 from Cython import Utils
33 from Annotate import AnnotationItem
35 from Cython.Debugging import print_call_chain
36 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
40 from __builtin__ import basestring
42 basestring = str # Python 3
44 class NotConstant(object):
46 return "<NOT CONSTANT>"
48 not_a_constant = NotConstant()
49 constant_value_not_set = object()
51 # error messages when coercing from key[0] to key[1]
52 find_coercion_error = {
53 # string related errors
54 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
55 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
56 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
57 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
58 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
59 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
60 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
61 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
62 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
63 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
68 # subexprs [string] Class var holding names of subexpr node attrs
69 # type PyrexType Type of the result
70 # result_code string Code fragment
71 # result_ctype string C type of result_code if different from type
72 # is_temp boolean Result is in a temporary variable
73 # is_sequence_constructor
74 # boolean Is a list or tuple constructor expression
75 # is_starred boolean Is a starred expression (e.g. '*a')
77 # [ExprNode or [ExprNode or None] or None]
78 # Cached result of subexpr_nodes()
79 # use_managed_ref boolean use ref-counted temps/assignments/etc.
84 old_temp = None # error checker for multiple frees etc.
85 use_managed_ref = True # can be set by optimisation transforms
87 # The Analyse Expressions phase for expressions is split
88 # into two sub-phases:
91 # Determines the result type of the expression based
92 # on the types of its sub-expressions, and inserts
93 # coercion nodes into the expression tree where needed.
94 # Marks nodes which will need to have temporary variables
98 # Allocates temporary variables where needed, and fills
99 # in the result_code field of each node.
101 # ExprNode provides some convenience routines which
102 # perform both of the above phases. These should only
103 # be called from statement nodes, and only when no
104 # coercion nodes need to be added around the expression
105 # being analysed. In that case, the above two phases
106 # should be invoked separately.
108 # Framework code in ExprNode provides much of the common
109 # processing for the various phases. It makes use of the
110 # 'subexprs' class attribute of ExprNodes, which should
111 # contain a list of the names of attributes which can
112 # hold sub-nodes or sequences of sub-nodes.
114 # The framework makes use of a number of abstract methods.
115 # Their responsibilities are as follows.
117 # Declaration Analysis phase
119 # analyse_target_declaration
120 # Called during the Analyse Declarations phase to analyse
121 # the LHS of an assignment or argument of a del statement.
122 # Nodes which cannot be the LHS of an assignment need not
125 # Expression Analysis phase
128 # - Call analyse_types on all sub-expressions.
129 # - Check operand types, and wrap coercion nodes around
130 # sub-expressions where needed.
131 # - Set the type of this node.
132 # - If a temporary variable will be required for the
133 # result, set the is_temp flag of this node.
135 # analyse_target_types
136 # Called during the Analyse Types phase to analyse
137 # the LHS of an assignment or argument of a del
138 # statement. Similar responsibilities to analyse_types.
141 # Called by the default implementation of allocate_target_temps.
142 # Should return a C lvalue for assigning to the node. The default
143 # implementation calls calculate_result_code.
146 # - Check that this node and its subnodes form a
147 # legal constant expression. If so, do nothing,
148 # otherwise call not_const.
150 # The default implementation of check_const
151 # assumes that the expression is not constant.
154 # - Same as check_const, except check that the
155 # expression is a C lvalue whose address is
156 # constant. Otherwise, call addr_not_const.
158 # The default implementation of calc_const_addr
159 # assumes that the expression is not a constant
162 # Code Generation phase
164 # generate_evaluation_code
165 # - Call generate_evaluation_code for sub-expressions.
166 # - Perform the functions of generate_result_code
168 # - If result is temporary, call generate_disposal_code
169 # on all sub-expressions.
171 # A default implementation of generate_evaluation_code
172 # is provided which uses the following abstract methods:
174 # generate_result_code
175 # - Generate any C statements necessary to calculate
176 # the result of this node from the results of its
179 # calculate_result_code
180 # - Should return a C code fragment evaluating to the
181 # result. This is only called when the result is not
184 # generate_assignment_code
185 # Called on the LHS of an assignment.
186 # - Call generate_evaluation_code for sub-expressions.
187 # - Generate code to perform the assignment.
188 # - If the assignment absorbed a reference, call
189 # generate_post_assignment_code on the RHS,
190 # otherwise call generate_disposal_code on it.
192 # generate_deletion_code
193 # Called on an argument of a del statement.
194 # - Call generate_evaluation_code for sub-expressions.
195 # - Generate code to perform the deletion.
196 # - Call generate_disposal_code on all sub-expressions.
200 is_sequence_constructor = 0
203 saved_subexpr_nodes = None
208 constant_result = constant_value_not_set
211 _get_child_attrs = operator.attrgetter('subexprs')
212 except AttributeError:
214 def __get_child_attrs(self):
216 _get_child_attrs = __get_child_attrs
217 child_attrs = property(fget=_get_child_attrs)
219 def not_implemented(self, method_name):
220 print_call_chain(method_name, "not implemented") ###
222 "%s.%s not implemented" %
223 (self.__class__.__name__, method_name))
228 def is_ephemeral(self):
229 # An ephemeral node is one whose result is in
230 # a Python temporary and we suspect there are no
231 # other references to it. Certain operations are
232 # disallowed on such values, since they are
233 # likely to result in a dangling pointer.
234 return self.type.is_pyobject and self.is_temp
236 def subexpr_nodes(self):
237 # Extract a list of subexpression nodes based
238 # on the contents of the subexprs class attribute.
240 for name in self.subexprs:
241 item = getattr(self, name)
243 if type(item) is list:
251 return self.temp_code
253 return self.calculate_result_code()
255 def result_as(self, type = None):
256 # Return the result code cast to the specified C type.
257 return typecast(type, self.ctype(), self.result())
260 # Return the result code cast to PyObject *.
261 return self.result_as(py_object_type)
264 # Return the native C type of the result (i.e. the
265 # C type of the result_code expression).
266 return self.result_ctype or self.type
268 def get_constant_c_result_code(self):
269 # Return the constant value of this node as a result code
270 # string, or None if the node is not constant. This method
271 # can be called when the constant result code is required
272 # before the code generation phase.
274 # The return value is a string that can represent a simple C
275 # value, a constant C name or a constant C expression. If the
276 # node type depends on Python code, this must return None.
279 def calculate_constant_result(self):
280 # Calculate the constant compile time result value of this
281 # expression and store it in ``self.constant_result``. Does
282 # nothing by default, thus leaving ``self.constant_result``
283 # unknown. If valid, the result can be an arbitrary Python
286 # This must only be called when it is assured that all
287 # sub-expressions have a valid constant_result value. The
288 # ConstantFolding transform will do this.
291 def has_constant_result(self):
292 return self.constant_result is not constant_value_not_set and \
293 self.constant_result is not not_a_constant
295 def compile_time_value(self, denv):
296 # Return value of compile-time expression, or report error.
297 error(self.pos, "Invalid compile-time expression")
299 def compile_time_value_error(self, e):
300 error(self.pos, "Error in compile-time expression: %s: %s" % (
301 e.__class__.__name__, e))
303 # ------------- Declaration Analysis ----------------
305 def analyse_target_declaration(self, env):
306 error(self.pos, "Cannot assign to or delete this")
308 # ------------- Expression Analysis ----------------
310 def analyse_const_expression(self, env):
311 # Called during the analyse_declarations phase of a
312 # constant expression. Analyses the expression's type,
313 # checks whether it is a legal const expression,
314 # and determines its value.
315 self.analyse_types(env)
316 return self.check_const()
318 def analyse_expressions(self, env):
319 # Convenience routine performing both the Type
320 # Analysis and Temp Allocation phases for a whole
322 self.analyse_types(env)
324 def analyse_target_expression(self, env, rhs):
325 # Convenience routine performing both the Type
326 # Analysis and Temp Allocation phases for the LHS of
328 self.analyse_target_types(env)
330 def analyse_boolean_expression(self, env):
331 # Analyse expression and coerce to a boolean.
332 self.analyse_types(env)
333 bool = self.coerce_to_boolean(env)
336 def analyse_temp_boolean_expression(self, env):
337 # Analyse boolean expression and coerce result into
338 # a temporary. This is used when a branch is to be
339 # performed on the result and we won't have an
340 # opportunity to ensure disposal code is executed
341 # afterwards. By forcing the result into a temporary,
342 # we ensure that all disposal has been done by the
343 # time we get the result.
344 self.analyse_types(env)
345 return self.coerce_to_boolean(env).coerce_to_simple(env)
347 # --------------- Type Inference -----------------
349 def type_dependencies(self, env):
350 # Returns the list of entries whose types must be determined
351 # before the type of self can be infered.
352 if hasattr(self, 'type') and self.type is not None:
354 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
356 def infer_type(self, env):
357 # Attempt to deduce the type of self.
358 # Differs from analyse_types as it avoids unnecessary
359 # analysis of subexpressions, but can assume everything
360 # in self.type_dependencies() has been resolved.
361 if hasattr(self, 'type') and self.type is not None:
363 elif hasattr(self, 'entry') and self.entry is not None:
364 return self.entry.type
366 self.not_implemented("infer_type")
368 # --------------- Type Analysis ------------------
370 def analyse_as_module(self, env):
371 # If this node can be interpreted as a reference to a
372 # cimported module, return its scope, else None.
375 def analyse_as_type(self, env):
376 # If this node can be interpreted as a reference to a
377 # type, return that type, else None.
380 def analyse_as_extension_type(self, env):
381 # If this node can be interpreted as a reference to an
382 # extension type, return its type, else None.
385 def analyse_types(self, env):
386 self.not_implemented("analyse_types")
388 def analyse_target_types(self, env):
389 self.analyse_types(env)
391 def nogil_check(self, env):
392 # By default, any expression based on Python objects is
393 # prevented in nogil environments. Subtypes must override
394 # this if they can work without the GIL.
395 if self.type.is_pyobject:
398 def gil_assignment_check(self, env):
399 if env.nogil and self.type.is_pyobject:
400 error(self.pos, "Assignment of Python object not allowed without gil")
402 def check_const(self):
407 error(self.pos, "Not allowed in a constant expression")
409 def check_const_addr(self):
410 self.addr_not_const()
413 def addr_not_const(self):
414 error(self.pos, "Address is not constant")
416 # ----------------- Result Allocation -----------------
418 def result_in_temp(self):
419 # Return true if result is in a temporary owned by
420 # this node or one of its subexpressions. Overridden
421 # by certain nodes which can share the result of
425 def target_code(self):
426 # Return code fragment for use as LHS of a C assignment.
427 return self.calculate_result_code()
429 def calculate_result_code(self):
430 self.not_implemented("calculate_result_code")
432 # def release_target_temp(self, env):
433 # # Release temporaries used by LHS of an assignment.
434 # self.release_subexpr_temps(env)
436 def allocate_temp_result(self, code):
438 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
442 type = PyrexTypes.py_object_type
443 self.temp_code = code.funcstate.allocate_temp(
444 type, manage_ref=self.use_managed_ref)
446 self.temp_code = None
448 def release_temp_result(self, code):
449 if not self.temp_code:
451 raise RuntimeError("temp %s released multiple times in %s" % (
452 self.old_temp, self.__class__.__name__))
454 raise RuntimeError("no temp, but release requested in %s" % (
455 self.__class__.__name__))
456 code.funcstate.release_temp(self.temp_code)
457 self.old_temp = self.temp_code
458 self.temp_code = None
460 # ---------------- Code Generation -----------------
462 def make_owned_reference(self, code):
463 # If result is a pyobject, make sure we own
465 if self.type.is_pyobject and not self.result_in_temp():
466 code.put_incref(self.result(), self.ctype())
468 def generate_evaluation_code(self, code):
469 code.mark_pos(self.pos)
471 # Generate code to evaluate this node and
472 # its sub-expressions, and dispose of any
473 # temporary results of its sub-expressions.
474 self.generate_subexpr_evaluation_code(code)
477 self.allocate_temp_result(code)
479 self.generate_result_code(code)
481 # If we are temp we do not need to wait until this node is disposed
482 # before disposing children.
483 self.generate_subexpr_disposal_code(code)
484 self.free_subexpr_temps(code)
486 def generate_subexpr_evaluation_code(self, code):
487 for node in self.subexpr_nodes():
488 node.generate_evaluation_code(code)
490 def generate_result_code(self, code):
491 self.not_implemented("generate_result_code")
493 def generate_disposal_code(self, code):
495 if self.type.is_pyobject:
496 code.put_decref_clear(self.result(), self.ctype())
498 # Already done if self.is_temp
499 self.generate_subexpr_disposal_code(code)
501 def generate_subexpr_disposal_code(self, code):
502 # Generate code to dispose of temporary results
503 # of all sub-expressions.
504 for node in self.subexpr_nodes():
505 node.generate_disposal_code(code)
507 def generate_post_assignment_code(self, code):
509 if self.type.is_pyobject:
510 code.putln("%s = 0;" % self.result())
512 self.generate_subexpr_disposal_code(code)
514 def generate_assignment_code(self, rhs, code):
515 # Stub method for nodes which are not legal as
516 # the LHS of an assignment. An error will have
517 # been reported earlier.
520 def generate_deletion_code(self, code):
521 # Stub method for nodes that are not legal as
522 # the argument of a del statement. An error
523 # will have been reported earlier.
526 def free_temps(self, code):
528 if not self.type.is_void:
529 self.release_temp_result(code)
531 self.free_subexpr_temps(code)
533 def free_subexpr_temps(self, code):
534 for sub in self.subexpr_nodes():
537 def generate_function_definitions(self, env, code):
540 # ---------------- Annotation ---------------------
542 def annotate(self, code):
543 for node in self.subexpr_nodes():
546 # ----------------- Coercion ----------------------
548 def coerce_to(self, dst_type, env):
549 # Coerce the result so that it can be assigned to
550 # something of type dst_type. If processing is necessary,
551 # wraps this node in a coercion node and returns that.
552 # Otherwise, returns this node unchanged.
554 # This method is called during the analyse_expressions
555 # phase of the src_node's processing.
557 # Note that subclasses that override this (especially
558 # ConstNodes) must not (re-)set their own .type attribute
559 # here. Since expression nodes may turn up in different
560 # places in the tree (e.g. inside of CloneNodes in cascaded
561 # assignments), this method must return a new node instance
562 # if it changes the type.
566 src_is_py_type = src_type.is_pyobject
567 dst_is_py_type = dst_type.is_pyobject
569 if self.check_for_coercion_error(dst_type):
572 if dst_type.is_reference:
573 dst_type = dst_type.ref_base_type
575 if dst_type.is_pyobject:
576 if not src.type.is_pyobject:
577 if dst_type is bytes_type and src.type.is_int:
578 src = CoerceIntToBytesNode(src, env)
580 src = CoerceToPyTypeNode(src, env)
581 if not src.type.subtype_of(dst_type):
582 if not isinstance(src, NoneNode):
583 src = PyTypeTestNode(src, dst_type, env)
584 elif src.type.is_pyobject:
585 src = CoerceFromPyTypeNode(dst_type, src, env)
586 elif (dst_type.is_complex
587 and src_type != dst_type
588 and dst_type.assignable_from(src_type)):
589 src = CoerceToComplexNode(src, dst_type, env)
590 else: # neither src nor dst are py types
591 # Added the string comparison, since for c types that
592 # is enough, but Cython gets confused when the types are
593 # in different pxi files.
594 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
595 self.fail_assignment(dst_type)
598 def fail_assignment(self, dst_type):
599 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
601 def check_for_coercion_error(self, dst_type, fail=False, default=None):
602 if fail and not default:
603 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
604 message = find_coercion_error((self.type, dst_type), default)
605 if message is not None:
606 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
609 self.fail_assignment(dst_type)
613 def coerce_to_pyobject(self, env):
614 return self.coerce_to(PyrexTypes.py_object_type, env)
616 def coerce_to_boolean(self, env):
617 # Coerce result to something acceptable as
620 # if it's constant, calculate the result now
621 if self.has_constant_result():
622 bool_value = bool(self.constant_result)
623 return BoolNode(self.pos, value=bool_value,
624 constant_result=bool_value)
627 if type.is_pyobject or type.is_ptr or type.is_float:
628 return CoerceToBooleanNode(self, env)
630 if not (type.is_int or type.is_enum or type.is_error):
632 "Type '%s' not acceptable as a boolean" % type)
635 def coerce_to_integer(self, env):
636 # If not already some C integer type, coerce to longint.
640 return self.coerce_to(PyrexTypes.c_long_type, env)
642 def coerce_to_temp(self, env):
643 # Ensure that the result is in a temporary.
644 if self.result_in_temp():
647 return CoerceToTempNode(self, env)
649 def coerce_to_simple(self, env):
650 # Ensure that the result is simple (see is_simple).
654 return self.coerce_to_temp(env)
657 # A node is simple if its result is something that can
658 # be referred to without performing any operations, e.g.
659 # a constant, local var, C global var, struct member
660 # reference, or temporary.
661 return self.result_in_temp()
663 def may_be_none(self):
664 if not self.type.is_pyobject:
666 if self.constant_result not in (not_a_constant, constant_value_not_set):
667 return self.constant_result is not None
670 def as_cython_attribute(self):
673 def as_none_safe_node(self, message, error="PyExc_TypeError"):
674 # Wraps the node in a NoneCheckNode if it is not known to be
675 # not-None (e.g. because it is a Python literal).
676 if self.may_be_none():
677 return NoneCheckNode(self, error, message)
682 class AtomicExprNode(ExprNode):
683 # Abstract base class for expression nodes which have
684 # no sub-expressions.
688 # Override to optimize -- we know we have no children
689 def generate_subexpr_evaluation_code(self, code):
691 def generate_subexpr_disposal_code(self, code):
694 class PyConstNode(AtomicExprNode):
695 # Abstract base class for constant Python values.
698 type = py_object_type
703 def may_be_none(self):
706 def analyse_types(self, env):
709 def calculate_result_code(self):
712 def generate_result_code(self, code):
716 class NoneNode(PyConstNode):
717 # The constant value None
721 constant_result = None
725 def compile_time_value(self, denv):
728 def may_be_none(self):
732 class EllipsisNode(PyConstNode):
733 # '...' in a subscript list.
735 value = "Py_Ellipsis"
737 constant_result = Ellipsis
739 def compile_time_value(self, denv):
743 class ConstNode(AtomicExprNode):
744 # Abstract base type for literal constant nodes.
746 # value string C code fragment
754 def may_be_none(self):
757 def analyse_types(self, env):
758 pass # Types are held in class variables
760 def check_const(self):
763 def get_constant_c_result_code(self):
764 return self.calculate_result_code()
766 def calculate_result_code(self):
767 return str(self.value)
769 def generate_result_code(self, code):
773 class BoolNode(ConstNode):
774 type = PyrexTypes.c_bint_type
775 # The constant value True or False
777 def calculate_constant_result(self):
778 self.constant_result = self.value
780 def compile_time_value(self, denv):
783 def calculate_result_code(self):
784 return str(int(self.value))
787 class NullNode(ConstNode):
788 type = PyrexTypes.c_null_ptr_type
792 def get_constant_c_result_code(self):
796 class CharNode(ConstNode):
797 type = PyrexTypes.c_char_type
799 def calculate_constant_result(self):
800 self.constant_result = ord(self.value)
802 def compile_time_value(self, denv):
803 return ord(self.value)
805 def calculate_result_code(self):
806 return "'%s'" % StringEncoding.escape_char(self.value)
809 class IntNode(ConstNode):
812 # longness "" or "L" or "LL"
813 # is_c_literal True/False/None creator considers this a C integer literal
817 is_c_literal = None # unknown
819 def __init__(self, pos, **kwds):
820 ExprNode.__init__(self, pos, **kwds)
821 if 'type' not in kwds:
822 self.type = self.find_suitable_type_for_value()
824 def find_suitable_type_for_value(self):
825 if self.constant_result is constant_value_not_set:
827 self.calculate_constant_result()
830 # we ignore 'is_c_literal = True' and instead map signed 32bit
831 # integers as C long values
832 if self.is_c_literal or \
833 self.constant_result in (constant_value_not_set, not_a_constant) or \
834 self.unsigned or self.longness == 'LL':
835 # clearly a C literal
836 rank = (self.longness == 'LL') and 2 or 1
837 suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
839 suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
841 # C literal or Python literal - split at 32bit boundary
842 if self.constant_result >= -2**31 and self.constant_result < 2**31:
843 if self.type and self.type.is_int:
844 suitable_type = self.type
846 suitable_type = PyrexTypes.c_long_type
848 suitable_type = PyrexTypes.py_object_type
851 def coerce_to(self, dst_type, env):
852 if self.type is dst_type:
854 elif dst_type.is_float:
855 if self.constant_result is not not_a_constant:
856 float_value = float(self.constant_result)
857 return FloatNode(self.pos, value=repr(float_value), type=dst_type,
858 constant_result=float_value)
860 return FloatNode(self.pos, value=self.value, type=dst_type,
861 constant_result=not_a_constant)
862 if dst_type.is_numeric and not dst_type.is_complex:
863 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
864 type = dst_type, is_c_literal = True,
865 unsigned=self.unsigned, longness=self.longness)
867 elif dst_type.is_pyobject:
868 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
869 type = PyrexTypes.py_object_type, is_c_literal = False,
870 unsigned=self.unsigned, longness=self.longness)
872 # FIXME: not setting the type here to keep it working with
873 # complex numbers. Should they be special cased?
874 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
875 unsigned=self.unsigned, longness=self.longness)
876 # We still need to perform normal coerce_to processing on the
877 # result, because we might be coercing to an extension type,
878 # in which case a type test node will be needed.
879 return ConstNode.coerce_to(node, dst_type, env)
881 def coerce_to_boolean(self, env):
883 self.pos, value=self.value,
884 type = PyrexTypes.c_bint_type,
885 unsigned=self.unsigned, longness=self.longness)
887 def generate_evaluation_code(self, code):
888 if self.type.is_pyobject:
889 # pre-allocate a Python version of the number
890 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
891 self.result_code = code.get_py_num(plain_integer_string, self.longness)
893 self.result_code = self.get_constant_c_result_code()
895 def get_constant_c_result_code(self):
896 return self.value_as_c_integer_string() + self.unsigned + self.longness
898 def value_as_c_integer_string(self, plain_digits=False):
900 if isinstance(value, basestring) and len(value) > 2:
901 # must convert C-incompatible Py3 oct/bin notations
904 value = int(value[2:], 8)
906 value = value[0] + value[2:] # '0o123' => '0123'
907 elif value[1] in 'bB':
908 value = int(value[2:], 2)
909 elif plain_digits and value[1] in 'xX':
910 value = int(value[2:], 16)
913 def calculate_result_code(self):
914 return self.result_code
916 def calculate_constant_result(self):
917 self.constant_result = Utils.str_to_number(self.value)
919 def compile_time_value(self, denv):
920 return Utils.str_to_number(self.value)
923 class FloatNode(ConstNode):
924 type = PyrexTypes.c_double_type
926 def calculate_constant_result(self):
927 self.constant_result = float(self.value)
929 def compile_time_value(self, denv):
930 return float(self.value)
932 def calculate_result_code(self):
934 assert isinstance(strval, (str, unicode))
935 cmpval = repr(float(strval))
937 return "(Py_HUGE_VAL * 0)"
938 elif cmpval == 'inf':
940 elif cmpval == '-inf':
941 return "(-Py_HUGE_VAL)"
946 class BytesNode(ConstNode):
947 # A char* or bytes literal
951 type = PyrexTypes.c_char_ptr_type
953 def compile_time_value(self, denv):
956 def analyse_as_type(self, env):
957 type = PyrexTypes.parse_basic_type(self.value)
960 from TreeFragment import TreeFragment
961 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
962 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
963 sizeof_node = declaration.root.stats[0].expr
964 sizeof_node.analyse_types(env)
965 if isinstance(sizeof_node, SizeofTypeNode):
966 return sizeof_node.arg_type
968 def can_coerce_to_char_literal(self):
969 return len(self.value) == 1
971 def coerce_to_boolean(self, env):
972 # This is special because we start off as a C char*. Testing
973 # that for truth directly would yield the wrong result.
974 return BoolNode(self.pos, value=bool(self.value))
976 def coerce_to(self, dst_type, env):
978 if not self.can_coerce_to_char_literal():
979 error(self.pos, "Only single-character string literals can be coerced into ints.")
981 if dst_type is PyrexTypes.c_py_unicode_type:
982 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.")
984 return CharNode(self.pos, value=self.value)
986 node = BytesNode(self.pos, value=self.value)
987 if dst_type == PyrexTypes.c_char_ptr_type:
988 node.type = PyrexTypes.c_char_ptr_type
990 elif dst_type == PyrexTypes.c_uchar_ptr_type:
991 node.type = PyrexTypes.c_char_ptr_type
992 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
994 if not self.type.is_pyobject:
995 if dst_type in (py_object_type, Builtin.bytes_type):
996 node.type = Builtin.bytes_type
997 elif dst_type.is_pyobject:
998 self.fail_assignment(dst_type)
1000 elif dst_type.is_pyobject and dst_type is not py_object_type:
1001 self.check_for_coercion_error(dst_type, fail=True)
1004 # We still need to perform normal coerce_to processing on the
1005 # result, because we might be coercing to an extension type,
1006 # in which case a type test node will be needed.
1007 return ConstNode.coerce_to(node, dst_type, env)
1009 def as_py_string_node(self, env):
1010 # Return a new BytesNode with the same value as this node
1011 # but whose type is a Python type instead of a C type.
1012 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
1014 def generate_evaluation_code(self, code):
1015 if self.type.is_pyobject:
1016 self.result_code = code.get_py_string_const(self.value)
1018 self.result_code = code.get_string_const(self.value)
1020 def get_constant_c_result_code(self):
1023 def calculate_result_code(self):
1024 return self.result_code
1027 class UnicodeNode(PyConstNode):
1028 # A Python unicode object
1030 # value EncodedString
1031 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
1036 def coerce_to(self, dst_type, env):
1037 if dst_type is self.type:
1039 elif dst_type is PyrexTypes.c_py_unicode_type:
1040 if not self.can_coerce_to_char_literal():
1041 error(self.pos, "Only single-character Unicode string literals can be coerced into Py_UNICODE.")
1043 int_value = ord(self.value)
1044 return IntNode(self.pos, value=int_value, constant_result=int_value)
1045 elif not dst_type.is_pyobject:
1046 if dst_type.is_string and self.bytes_value is not None:
1047 # special case: '-3' enforced unicode literal used in a C char* context
1048 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
1049 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE.")
1050 elif dst_type is not py_object_type:
1051 if not self.check_for_coercion_error(dst_type):
1052 self.fail_assignment(dst_type)
1055 def can_coerce_to_char_literal(self):
1056 return len(self.value) == 1
1058 def contains_surrogates(self):
1059 # Check if the unicode string contains surrogate code points
1060 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1061 # Unicode, i.e. characters that would be spelled as two
1062 # separate code units on a narrow platform.
1063 for c in map(ord, self.value):
1064 if c > 65535: # can only happen on wide platforms
1066 # We only look for the first code unit (D800-DBFF) of a
1067 # surrogate pair - if we find one, the other one
1068 # (DC00-DFFF) is likely there, too. If we don't find it,
1069 # any second code unit cannot make for a surrogate pair by
1071 if c >= 0xD800 and c <= 0xDBFF:
1075 def generate_evaluation_code(self, code):
1076 self.result_code = code.get_py_string_const(self.value)
1078 def calculate_result_code(self):
1079 return self.result_code
1081 def compile_time_value(self, env):
1085 class StringNode(PyConstNode):
1086 # A Python str object, i.e. a byte string in Python 2.x and a
1087 # unicode string in Python 3.x
1089 # value BytesLiteral (or EncodedString with ASCII content)
1090 # unicode_value EncodedString or None
1091 # is_identifier boolean
1094 is_identifier = None
1095 unicode_value = None
1097 def coerce_to(self, dst_type, env):
1098 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1099 # if dst_type is Builtin.bytes_type:
1100 # # special case: bytes = 'str literal'
1101 # return BytesNode(self.pos, value=self.value)
1102 if not dst_type.is_pyobject:
1103 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1104 self.check_for_coercion_error(dst_type, fail=True)
1106 # this will be a unicode string in Py3, so make sure we can decode it
1107 if self.value.encoding and isinstance(self.value, StringEncoding.BytesLiteral):
1109 self.value.decode(self.value.encoding)
1110 except UnicodeDecodeError:
1111 error(self.pos, ("Decoding unprefixed string literal from '%s' failed. Consider using"
1112 "a byte string or unicode string explicitly, "
1113 "or adjust the source code encoding.") % self.value.encoding)
1117 def can_coerce_to_char_literal(self):
1118 return not self.is_identifier and len(self.value) == 1
1120 def generate_evaluation_code(self, code):
1121 self.result_code = code.get_py_string_const(
1122 self.value, identifier=self.is_identifier, is_str=True)
1124 def get_constant_c_result_code(self):
1127 def calculate_result_code(self):
1128 return self.result_code
1130 def compile_time_value(self, env):
1134 class IdentifierStringNode(StringNode):
1135 # A special str value that represents an identifier (bytes in Py2,
1137 is_identifier = True
1140 class LongNode(AtomicExprNode):
1141 # Python long integer literal
1145 type = py_object_type
1147 def calculate_constant_result(self):
1148 self.constant_result = Utils.str_to_number(self.value)
1150 def compile_time_value(self, denv):
1151 return Utils.str_to_number(self.value)
1153 def analyse_types(self, env):
1156 def may_be_none(self):
1159 gil_message = "Constructing Python long int"
1161 def generate_result_code(self, code):
1163 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1166 code.error_goto_if_null(self.result(), self.pos)))
1167 code.put_gotref(self.py_result())
1170 class ImagNode(AtomicExprNode):
1171 # Imaginary number literal
1173 # value float imaginary part
1175 type = PyrexTypes.c_double_complex_type
1177 def calculate_constant_result(self):
1178 self.constant_result = complex(0.0, self.value)
1180 def compile_time_value(self, denv):
1181 return complex(0.0, self.value)
1183 def analyse_types(self, env):
1184 self.type.create_declaration_utility_code(env)
1186 def may_be_none(self):
1189 def coerce_to(self, dst_type, env):
1190 if self.type is dst_type:
1192 node = ImagNode(self.pos, value=self.value)
1193 if dst_type.is_pyobject:
1195 node.type = PyrexTypes.py_object_type
1196 # We still need to perform normal coerce_to processing on the
1197 # result, because we might be coercing to an extension type,
1198 # in which case a type test node will be needed.
1199 return AtomicExprNode.coerce_to(node, dst_type, env)
1201 gil_message = "Constructing complex number"
1203 def calculate_result_code(self):
1204 if self.type.is_pyobject:
1205 return self.result()
1207 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1209 def generate_result_code(self, code):
1210 if self.type.is_pyobject:
1212 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1215 code.error_goto_if_null(self.result(), self.pos)))
1216 code.put_gotref(self.py_result())
1219 class NewExprNode(AtomicExprNode):
1223 # cppclass node c++ class to create
1227 def infer_type(self, env):
1228 type = self.cppclass.analyse_as_type(env)
1229 if type is None or not type.is_cpp_class:
1230 error(self.pos, "new operator can only be applied to a C++ class")
1231 self.type = error_type
1234 constructor = type.scope.lookup(u'<init>')
1235 if constructor is None:
1236 return_type = PyrexTypes.CFuncType(type, [])
1237 return_type = PyrexTypes.CPtrType(return_type)
1238 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1239 constructor = type.scope.lookup(u'<init>')
1240 self.class_type = type
1241 self.entry = constructor
1242 self.type = constructor.type
1245 def analyse_types(self, env):
1246 if self.type is None:
1247 self.infer_type(env)
1249 def may_be_none(self):
1252 def generate_result_code(self, code):
1255 def calculate_result_code(self):
1256 return "new " + self.class_type.declaration_code("")
1259 class NameNode(AtomicExprNode):
1260 # Reference to a local or global variable name.
1262 # name string Python name of the variable
1263 # entry Entry Symbol table entry
1264 # type_entry Entry For extension type names, the original type entry
1267 is_cython_module = False
1268 cython_attribute = None
1269 lhs_of_first_assignment = False
1270 is_used_as_rvalue = 0
1274 def create_analysed_rvalue(pos, env, entry):
1275 node = NameNode(pos)
1276 node.analyse_types(env, entry=entry)
1279 def as_cython_attribute(self):
1280 return self.cython_attribute
1282 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1284 def type_dependencies(self, env):
1285 if self.entry is None:
1286 self.entry = env.lookup(self.name)
1287 if self.entry is not None and self.entry.type.is_unspecified:
1288 return (self.entry,)
1292 def infer_type(self, env):
1293 if self.entry is None:
1294 self.entry = env.lookup(self.name)
1295 if self.entry is None:
1296 return py_object_type
1297 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1298 self.name == self.entry.type.name:
1299 # Unfortunately the type attribute of type objects
1300 # is used for the pointer to the type they represent.
1303 return self.entry.type
1305 def compile_time_value(self, denv):
1307 return denv.lookup(self.name)
1309 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1311 def get_constant_c_result_code(self):
1312 if not self.entry or self.entry.type.is_pyobject:
1314 return self.entry.cname
1316 def coerce_to(self, dst_type, env):
1317 # If coercing to a generic pyobject and this is a builtin
1318 # C function with a Python equivalent, manufacture a NameNode
1319 # referring to the Python builtin.
1320 #print "NameNode.coerce_to:", self.name, dst_type ###
1321 if dst_type is py_object_type:
1323 if entry and entry.is_cfunction:
1324 var_entry = entry.as_variable
1326 if var_entry.is_builtin and Options.cache_builtins:
1327 var_entry = env.declare_builtin(var_entry.name, self.pos)
1328 node = NameNode(self.pos, name = self.name)
1329 node.entry = var_entry
1330 node.analyse_rvalue_entry(env)
1332 return super(NameNode, self).coerce_to(dst_type, env)
1334 def analyse_as_module(self, env):
1335 # Try to interpret this as a reference to a cimported module.
1336 # Returns the module scope, or None.
1339 entry = env.lookup(self.name)
1340 if entry and entry.as_module:
1341 return entry.as_module
1344 def analyse_as_type(self, env):
1345 if self.cython_attribute:
1346 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1348 type = PyrexTypes.parse_basic_type(self.name)
1353 entry = env.lookup(self.name)
1354 if entry and entry.is_type:
1359 def analyse_as_extension_type(self, env):
1360 # Try to interpret this as a reference to an extension type.
1361 # Returns the extension type, or None.
1364 entry = env.lookup(self.name)
1365 if entry and entry.is_type and entry.type.is_extension_type:
1370 def analyse_target_declaration(self, env):
1372 self.entry = env.lookup_here(self.name)
1374 if env.directives['warn.undeclared']:
1375 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1376 if env.directives['infer_types'] != False:
1377 type = unspecified_type
1379 type = py_object_type
1380 self.entry = env.declare_var(self.name, type, self.pos)
1381 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1382 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1383 if self.entry.is_declared_generic:
1384 self.result_ctype = py_object_type
1386 def analyse_types(self, env):
1387 if self.entry is None:
1388 self.entry = env.lookup(self.name)
1390 self.entry = env.declare_builtin(self.name, self.pos)
1392 self.type = PyrexTypes.error_type
1397 if entry.type.is_buffer:
1399 Buffer.used_buffer_aux_vars(entry)
1400 if entry.utility_code:
1401 env.use_utility_code(entry.utility_code)
1402 self.analyse_rvalue_entry(env)
1404 def analyse_target_types(self, env):
1405 self.analyse_entry(env)
1406 if not self.is_lvalue():
1407 error(self.pos, "Assignment to non-lvalue '%s'"
1409 self.type = PyrexTypes.error_type
1411 if self.entry.type.is_buffer:
1413 Buffer.used_buffer_aux_vars(self.entry)
1415 def analyse_rvalue_entry(self, env):
1416 #print "NameNode.analyse_rvalue_entry:", self.name ###
1417 #print "Entry:", self.entry.__dict__ ###
1418 self.analyse_entry(env)
1420 if entry.is_declared_generic:
1421 self.result_ctype = py_object_type
1422 if entry.is_pyglobal or entry.is_builtin:
1423 if Options.cache_builtins and entry.is_builtin:
1427 env.use_utility_code(get_name_interned_utility_code)
1428 self.is_used_as_rvalue = 1
1430 def nogil_check(self, env):
1431 if self.is_used_as_rvalue:
1433 if entry.is_builtin:
1434 # if not Options.cache_builtins: # cached builtins are ok
1436 elif entry.is_pyglobal:
1439 gil_message = "Accessing Python global or builtin"
1441 def analyse_entry(self, env):
1442 #print "NameNode.analyse_entry:", self.name ###
1443 self.check_identifier_kind()
1448 def check_identifier_kind(self):
1449 # Check that this is an appropriate kind of name for use in an
1450 # expression. Also finds the variable entry associated with
1451 # an extension type.
1453 if entry.is_type and entry.type.is_extension_type:
1454 self.type_entry = entry
1455 if not (entry.is_const or entry.is_variable
1456 or entry.is_builtin or entry.is_cfunction
1457 or entry.is_cpp_class):
1458 if self.entry.as_variable:
1459 self.entry = self.entry.as_variable
1462 "'%s' is not a constant, variable or function identifier" % self.name)
1464 def is_simple(self):
1465 # If it's not a C variable, it'll be in a temp.
1468 def calculate_target_results(self, env):
1471 def check_const(self):
1473 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1478 def check_const_addr(self):
1480 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1481 self.addr_not_const()
1485 def is_lvalue(self):
1486 return self.entry.is_variable and \
1487 not self.entry.type.is_array and \
1488 not self.entry.is_readonly
1490 def is_ephemeral(self):
1491 # Name nodes are never ephemeral, even if the
1492 # result is in a temporary.
1495 def calculate_result_code(self):
1498 return "<error>" # There was an error earlier
1501 def generate_result_code(self, code):
1502 assert hasattr(self, 'entry')
1505 return # There was an error earlier
1506 if entry.is_builtin and Options.cache_builtins:
1507 return # Lookup already cached
1508 elif entry.is_pyclass_attr:
1509 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1510 interned_cname = code.intern_identifier(self.entry.name)
1511 if entry.is_builtin:
1512 namespace = Naming.builtins_cname
1513 else: # entry.is_pyglobal
1514 namespace = entry.scope.namespace_cname
1516 '%s = PyObject_GetItem(%s, %s); %s' % (
1520 code.error_goto_if_null(self.result(), self.pos)))
1521 code.put_gotref(self.py_result())
1523 elif entry.is_pyglobal or entry.is_builtin:
1524 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1525 interned_cname = code.intern_identifier(self.entry.name)
1526 if entry.is_builtin:
1527 namespace = Naming.builtins_cname
1528 else: # entry.is_pyglobal
1529 namespace = entry.scope.namespace_cname
1530 code.globalstate.use_utility_code(get_name_interned_utility_code)
1532 '%s = __Pyx_GetName(%s, %s); %s' % (
1536 code.error_goto_if_null(self.result(), self.pos)))
1537 code.put_gotref(self.py_result())
1539 elif entry.is_local and False:
1540 # control flow not good enough yet
1541 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1542 if assigned is False:
1543 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1544 elif not Options.init_local_none and assigned is None:
1545 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1546 (entry.cname, entry.name, code.error_goto(self.pos)))
1547 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1549 def generate_assignment_code(self, rhs, code):
1550 #print "NameNode.generate_assignment_code:", self.name ###
1553 return # There was an error earlier
1555 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1556 and not self.lhs_of_first_assignment):
1557 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1559 # is_pyglobal seems to be True for module level-globals only.
1560 # We use this to access class->tp_dict if necessary.
1561 if entry.is_pyglobal:
1562 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1563 interned_cname = code.intern_identifier(self.entry.name)
1564 namespace = self.entry.scope.namespace_cname
1566 # if the entry is a member we have to cheat: SetAttr does not work
1567 # on types, so we create a descriptor which is then added to tp_dict
1568 code.put_error_if_neg(self.pos,
1569 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1573 rhs.generate_disposal_code(code)
1574 rhs.free_temps(code)
1575 # in Py2.6+, we need to invalidate the method cache
1576 code.putln("PyType_Modified(%s);" %
1577 entry.scope.parent_type.typeptr_cname)
1578 elif entry.is_pyclass_attr:
1579 code.put_error_if_neg(self.pos,
1580 'PyObject_SetItem(%s, %s, %s)' % (
1584 rhs.generate_disposal_code(code)
1585 rhs.free_temps(code)
1587 code.put_error_if_neg(self.pos,
1588 'PyObject_SetAttr(%s, %s, %s)' % (
1592 if debug_disposal_code:
1593 print("NameNode.generate_assignment_code:")
1594 print("...generating disposal code for %s" % rhs)
1595 rhs.generate_disposal_code(code)
1596 rhs.free_temps(code)
1598 if self.type.is_buffer:
1599 # Generate code for doing the buffer release/acquisition.
1600 # This might raise an exception in which case the assignment (done
1601 # below) will not happen.
1603 # The reason this is not in a typetest-like node is because the
1604 # variables that the acquired buffer info is stored to is allocated
1605 # per entry and coupled with it.
1606 self.generate_acquire_buffer(rhs, code)
1608 if self.type.is_pyobject:
1609 #print "NameNode.generate_assignment_code: to", self.name ###
1610 #print "...from", rhs ###
1611 #print "...LHS type", self.type, "ctype", self.ctype() ###
1612 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1613 if self.use_managed_ref:
1614 rhs.make_owned_reference(code)
1615 if entry.is_cglobal:
1616 code.put_gotref(self.py_result())
1617 if not self.lhs_of_first_assignment:
1618 if entry.is_local and not Options.init_local_none:
1619 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1620 if initialized is True:
1621 code.put_decref(self.result(), self.ctype())
1622 elif initialized is None:
1623 code.put_xdecref(self.result(), self.ctype())
1625 code.put_decref(self.result(), self.ctype())
1626 if entry.is_cglobal:
1627 code.put_giveref(rhs.py_result())
1629 code.putln('%s = %s;' % (self.result(),
1630 rhs.result_as(self.ctype())))
1631 if debug_disposal_code:
1632 print("NameNode.generate_assignment_code:")
1633 print("...generating post-assignment code for %s" % rhs)
1634 rhs.generate_post_assignment_code(code)
1635 rhs.free_temps(code)
1637 def generate_acquire_buffer(self, rhs, code):
1638 # rhstmp is only used in case the rhs is a complicated expression leading to
1639 # the object, to avoid repeating the same C expression for every reference
1640 # to the rhs. It does NOT hold a reference.
1641 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1643 rhstmp = rhs.result_as(self.ctype())
1645 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1646 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1648 buffer_aux = self.entry.buffer_aux
1649 bufstruct = buffer_aux.buffer_info_var.cname
1651 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1652 is_initialized=not self.lhs_of_first_assignment,
1653 pos=self.pos, code=code)
1656 code.putln("%s = 0;" % rhstmp)
1657 code.funcstate.release_temp(rhstmp)
1659 def generate_deletion_code(self, code):
1660 if self.entry is None:
1661 return # There was an error earlier
1662 if not self.entry.is_pyglobal:
1663 error(self.pos, "Deletion of local or C global name not supported")
1665 if self.entry.is_pyclass_attr:
1666 namespace = self.entry.scope.namespace_cname
1667 code.put_error_if_neg(self.pos,
1668 'PyMapping_DelItemString(%s, "%s")' % (
1672 code.put_error_if_neg(self.pos,
1673 '__Pyx_DelAttrString(%s, "%s")' % (
1674 Naming.module_cname,
1677 def annotate(self, code):
1678 if hasattr(self, 'is_called') and self.is_called:
1679 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1680 if self.type.is_pyobject:
1681 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1683 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1685 class BackquoteNode(ExprNode):
1690 type = py_object_type
1694 def analyse_types(self, env):
1695 self.arg.analyse_types(env)
1696 self.arg = self.arg.coerce_to_pyobject(env)
1699 gil_message = "Backquote expression"
1701 def calculate_constant_result(self):
1702 self.constant_result = repr(self.arg.constant_result)
1704 def generate_result_code(self, code):
1706 "%s = PyObject_Repr(%s); %s" % (
1708 self.arg.py_result(),
1709 code.error_goto_if_null(self.result(), self.pos)))
1710 code.put_gotref(self.py_result())
1714 class ImportNode(ExprNode):
1715 # Used as part of import statement implementation.
1716 # Implements result =
1717 # __import__(module_name, globals(), None, name_list)
1719 # module_name StringNode dotted name of module
1720 # name_list ListNode or None list of names to be imported
1722 type = py_object_type
1724 subexprs = ['module_name', 'name_list']
1726 def analyse_types(self, env):
1727 self.module_name.analyse_types(env)
1728 self.module_name = self.module_name.coerce_to_pyobject(env)
1730 self.name_list.analyse_types(env)
1731 self.name_list.coerce_to_pyobject(env)
1733 env.use_utility_code(import_utility_code)
1735 gil_message = "Python import"
1737 def generate_result_code(self, code):
1739 name_list_code = self.name_list.py_result()
1741 name_list_code = "0"
1743 "%s = __Pyx_Import(%s, %s); %s" % (
1745 self.module_name.py_result(),
1747 code.error_goto_if_null(self.result(), self.pos)))
1748 code.put_gotref(self.py_result())
1751 class IteratorNode(ExprNode):
1752 # Used as part of for statement implementation.
1754 # allocate_counter_temp/release_counter_temp needs to be called
1755 # by parent (ForInStatNode)
1757 # Implements result = iter(sequence)
1761 type = py_object_type
1763 subexprs = ['sequence']
1765 def analyse_types(self, env):
1766 self.sequence.analyse_types(env)
1767 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1768 not self.sequence.type.is_string:
1769 # C array iteration will be transformed later on
1770 self.type = self.sequence.type
1772 self.sequence = self.sequence.coerce_to_pyobject(env)
1773 if self.sequence.type is list_type or \
1774 self.sequence.type is tuple_type:
1775 self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
1778 gil_message = "Iterating over Python object"
1780 def allocate_counter_temp(self, code):
1781 self.counter_cname = code.funcstate.allocate_temp(
1782 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1784 def release_counter_temp(self, code):
1785 code.funcstate.release_temp(self.counter_cname)
1787 def generate_result_code(self, code):
1788 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1789 raise InternalError("for in carray slice not transformed")
1790 is_builtin_sequence = self.sequence.type is list_type or \
1791 self.sequence.type is tuple_type
1792 may_be_a_sequence = not self.sequence.type.is_builtin_type
1793 if may_be_a_sequence:
1795 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1796 self.sequence.py_result(),
1797 self.sequence.py_result()))
1798 if is_builtin_sequence or may_be_a_sequence:
1800 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1803 self.sequence.py_result(),
1805 if not is_builtin_sequence:
1806 if may_be_a_sequence:
1807 code.putln("} else {")
1808 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1811 self.sequence.py_result(),
1812 code.error_goto_if_null(self.result(), self.pos)))
1813 code.put_gotref(self.py_result())
1814 if may_be_a_sequence:
1818 class NextNode(AtomicExprNode):
1819 # Used as part of for statement implementation.
1820 # Implements result = iterator.next()
1821 # Created during analyse_types phase.
1822 # The iterator is not owned by this node.
1826 type = py_object_type
1828 def __init__(self, iterator, env):
1829 self.pos = iterator.pos
1830 self.iterator = iterator
1831 if iterator.type.is_ptr or iterator.type.is_array:
1832 self.type = iterator.type.base_type
1835 def generate_result_code(self, code):
1836 sequence_type = self.iterator.sequence.type
1837 if sequence_type is list_type:
1838 type_checks = [(list_type, "List")]
1839 elif sequence_type is tuple_type:
1840 type_checks = [(tuple_type, "Tuple")]
1841 elif not sequence_type.is_builtin_type:
1842 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1846 for py_type, prefix in type_checks:
1847 if len(type_checks) > 1:
1849 "if (likely(Py%s_CheckExact(%s))) {" % (
1850 prefix, self.iterator.py_result()))
1852 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1853 self.iterator.counter_cname,
1855 self.iterator.py_result()))
1857 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1860 self.iterator.py_result(),
1861 self.iterator.counter_cname,
1863 self.iterator.counter_cname))
1864 if len(type_checks) > 1:
1866 if len(type_checks) == 1:
1870 "%s = PyIter_Next(%s);" % (
1872 self.iterator.py_result()))
1876 code.putln(code.error_goto_if_PyErr(self.pos))
1877 code.putln("break;")
1879 code.put_gotref(self.py_result())
1883 class ExcValueNode(AtomicExprNode):
1884 # Node created during analyse_types phase
1885 # of an ExceptClauseNode to fetch the current
1888 type = py_object_type
1890 def __init__(self, pos, env):
1891 ExprNode.__init__(self, pos)
1893 def set_var(self, var):
1896 def calculate_result_code(self):
1899 def generate_result_code(self, code):
1902 def analyse_types(self, env):
1906 class TempNode(ExprNode):
1907 # Node created during analyse_types phase
1908 # of some nodes to hold a temporary value.
1910 # Note: One must call "allocate" and "release" on
1911 # the node during code generation to get/release the temp.
1912 # This is because the temp result is often used outside of
1913 # the regular cycle.
1917 def __init__(self, pos, type, env):
1918 ExprNode.__init__(self, pos)
1920 if type.is_pyobject:
1921 self.result_ctype = py_object_type
1924 def analyse_types(self, env):
1927 def generate_result_code(self, code):
1930 def allocate(self, code):
1931 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1933 def release(self, code):
1934 code.funcstate.release_temp(self.temp_cname)
1935 self.temp_cname = None
1939 return self.temp_cname
1941 assert False, "Remember to call allocate/release on TempNode"
1944 # Do not participate in normal temp alloc/dealloc:
1945 def allocate_temp_result(self, code):
1948 def release_temp_result(self, code):
1951 class PyTempNode(TempNode):
1952 # TempNode holding a Python value.
1954 def __init__(self, pos, env):
1955 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1957 class RawCNameExprNode(ExprNode):
1960 def __init__(self, pos, type=None):
1964 def analyse_types(self, env):
1967 def set_cname(self, cname):
1973 def generate_result_code(self, code):
1977 #-------------------------------------------------------------------
1981 #-------------------------------------------------------------------
1983 class IndexNode(ExprNode):
1984 # Sequence indexing.
1988 # indices [ExprNode]
1989 # is_buffer_access boolean Whether this is a buffer access.
1991 # indices is used on buffer access, index on non-buffer access.
1992 # The former contains a clean list of index parameters, the
1993 # latter whatever Python object is needed for index access.
1995 subexprs = ['base', 'index', 'indices']
1998 def __init__(self, pos, index, *args, **kw):
1999 ExprNode.__init__(self, pos, index=index, *args, **kw)
2002 def calculate_constant_result(self):
2003 self.constant_result = \
2004 self.base.constant_result[self.index.constant_result]
2006 def compile_time_value(self, denv):
2007 base = self.base.compile_time_value(denv)
2008 index = self.index.compile_time_value(denv)
2011 except Exception, e:
2012 self.compile_time_value_error(e)
2014 def is_ephemeral(self):
2015 return self.base.is_ephemeral()
2017 def analyse_target_declaration(self, env):
2020 def analyse_as_type(self, env):
2021 base_type = self.base.analyse_as_type(env)
2022 if base_type and not base_type.is_pyobject:
2023 if base_type.is_cpp_class:
2024 if isinstance(self.index, TupleNode):
2025 template_values = self.index.args
2027 template_values = [self.index]
2029 type_node = Nodes.TemplatedTypeNode(
2031 positional_args = template_values,
2032 keyword_args = None)
2033 return type_node.analyse(env, base_type = base_type)
2035 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2038 def type_dependencies(self, env):
2039 return self.base.type_dependencies(env)
2041 def infer_type(self, env):
2042 base_type = self.base.infer_type(env)
2043 if isinstance(self.index, SliceNode):
2045 if base_type.is_string:
2046 # sliced C strings must coerce to Python
2048 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2049 # slicing these returns the same type
2052 # TODO: Handle buffers (hopefully without too much redundancy).
2053 return py_object_type
2055 index_type = self.index.infer_type(env)
2056 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2058 if base_type is unicode_type:
2059 # Py_UNICODE will automatically coerce to a unicode string
2060 # if required, so this is safe. We only infer Py_UNICODE
2061 # when the index is a C integer type. Otherwise, we may
2062 # need to use normal Python item access, in which case
2063 # it's faster to return the one-char unicode string than
2064 # to receive it, throw it away, and potentially rebuild it
2065 # on a subsequent PyObject coercion.
2066 return PyrexTypes.c_py_unicode_type
2067 elif isinstance(self.base, BytesNode):
2068 #if env.global_scope().context.language_level >= 3:
2069 # # infering 'char' can be made to work in Python 3 mode
2070 # return PyrexTypes.c_char_type
2071 # Py2/3 return different types on indexing bytes objects
2072 return py_object_type
2073 elif base_type.is_ptr or base_type.is_array:
2074 return base_type.base_type
2076 # may be slicing or indexing, we don't know
2077 if base_type is unicode_type:
2078 # this type always returns its own type on Python indexing/slicing
2081 # TODO: Handle buffers (hopefully without too much redundancy).
2082 return py_object_type
2084 def analyse_types(self, env):
2085 self.analyse_base_and_index_types(env, getting = 1)
2087 def analyse_target_types(self, env):
2088 self.analyse_base_and_index_types(env, setting = 1)
2090 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2091 # Note: This might be cleaned up by having IndexNode
2092 # parsed in a saner way and only construct the tuple if
2095 # Note that this function must leave IndexNode in a cloneable state.
2096 # For buffers, self.index is packed out on the initial analysis, and
2097 # when cloning self.indices is copied.
2098 self.is_buffer_access = False
2100 self.base.analyse_types(env)
2101 if self.base.type.is_error:
2102 # Do not visit child tree if base is undeclared to avoid confusing
2104 self.type = PyrexTypes.error_type
2107 is_slice = isinstance(self.index, SliceNode)
2108 # Potentially overflowing index value.
2109 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2110 self.index = self.index.coerce_to_pyobject(env)
2112 # Handle the case where base is a literal char* (and we expect a string, not an int)
2113 if isinstance(self.base, BytesNode) or is_slice:
2114 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2115 self.base = self.base.coerce_to_pyobject(env)
2117 skip_child_analysis = False
2118 buffer_access = False
2119 if self.base.type.is_buffer:
2121 indices = self.indices
2123 if isinstance(self.index, TupleNode):
2124 indices = self.index.args
2126 indices = [self.index]
2127 if len(indices) == self.base.type.ndim:
2128 buffer_access = True
2129 skip_child_analysis = True
2131 x.analyse_types(env)
2132 if not x.type.is_int:
2133 buffer_access = False
2135 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2137 # On cloning, indices is cloned. Otherwise, unpack index into indices
2138 assert not (buffer_access and isinstance(self.index, CloneNode))
2141 self.indices = indices
2143 self.type = self.base.type.dtype
2144 self.is_buffer_access = True
2145 self.buffer_type = self.base.entry.type
2147 if getting and self.type.is_pyobject:
2150 if not self.base.entry.type.writable:
2151 error(self.pos, "Writing to readonly buffer")
2153 self.base.entry.buffer_aux.writable_needed = True
2155 base_type = self.base.type
2156 if isinstance(self.index, TupleNode):
2157 self.index.analyse_types(env, skip_children=skip_child_analysis)
2158 elif not skip_child_analysis:
2159 self.index.analyse_types(env)
2160 self.original_index_type = self.index.type
2161 if base_type is PyrexTypes.c_py_unicode_type:
2162 # we infer Py_UNICODE for unicode strings in some
2163 # cases, but indexing must still work for them
2164 if self.index.constant_result in (0, -1):
2165 # FIXME: we know that this node is redundant -
2166 # currently, this needs to get handled in Optimize.py
2168 self.base = self.base.coerce_to_pyobject(env)
2169 base_type = self.base.type
2170 if base_type.is_pyobject:
2171 if self.index.type.is_int:
2173 and (base_type in (list_type, tuple_type, unicode_type))
2174 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2175 and not env.directives['boundscheck']):
2179 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2181 self.index = self.index.coerce_to_pyobject(env)
2183 if self.index.type.is_int and base_type is unicode_type:
2184 # Py_UNICODE will automatically coerce to a unicode string
2185 # if required, so this is fast and safe
2186 self.type = PyrexTypes.c_py_unicode_type
2187 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2188 self.type = base_type
2190 self.type = py_object_type
2192 if base_type.is_ptr or base_type.is_array:
2193 self.type = base_type.base_type
2195 self.type = base_type
2196 elif self.index.type.is_pyobject:
2197 self.index = self.index.coerce_to(
2198 PyrexTypes.c_py_ssize_t_type, env)
2199 elif not self.index.type.is_int:
2201 "Invalid index type '%s'" %
2203 elif base_type.is_cpp_class:
2204 function = env.lookup_operator("[]", [self.base, self.index])
2205 if function is None:
2206 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2207 self.type = PyrexTypes.error_type
2208 self.result_code = "<error>"
2210 func_type = function.type
2211 if func_type.is_ptr:
2212 func_type = func_type.base_type
2213 self.index = self.index.coerce_to(func_type.args[0].type, env)
2214 self.type = func_type.return_type
2215 if setting and not func_type.return_type.is_reference:
2216 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2219 "Attempting to index non-array type '%s'" %
2221 self.type = PyrexTypes.error_type
2223 gil_message = "Indexing Python object"
2225 def nogil_check(self, env):
2226 if self.is_buffer_access:
2227 if env.directives['boundscheck']:
2228 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2230 elif self.type.is_pyobject:
2231 error(self.pos, "Cannot access buffer with object dtype without gil")
2233 super(IndexNode, self).nogil_check(env)
2236 def check_const_addr(self):
2237 return self.base.check_const_addr() and self.index.check_const()
2239 def is_lvalue(self):
2242 def calculate_result_code(self):
2243 if self.is_buffer_access:
2244 return "(*%s)" % self.buffer_ptr_code
2245 elif self.base.type is list_type:
2246 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2247 elif self.base.type is tuple_type:
2248 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2249 elif self.base.type is unicode_type and self.type is PyrexTypes.c_py_unicode_type:
2250 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2251 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2252 error(self.pos, "Invalid use of pointer slice")
2254 return "(%s[%s])" % (
2255 self.base.result(), self.index.result())
2257 def extra_index_params(self):
2258 if self.index.type.is_int:
2259 if self.original_index_type.signed:
2260 size_adjustment = ""
2262 size_adjustment = "+1"
2263 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2267 def generate_subexpr_evaluation_code(self, code):
2268 self.base.generate_evaluation_code(code)
2269 if not self.indices:
2270 self.index.generate_evaluation_code(code)
2272 for i in self.indices:
2273 i.generate_evaluation_code(code)
2275 def generate_subexpr_disposal_code(self, code):
2276 self.base.generate_disposal_code(code)
2277 if not self.indices:
2278 self.index.generate_disposal_code(code)
2280 for i in self.indices:
2281 i.generate_disposal_code(code)
2283 def free_subexpr_temps(self, code):
2284 self.base.free_temps(code)
2285 if not self.indices:
2286 self.index.free_temps(code)
2288 for i in self.indices:
2291 def generate_result_code(self, code):
2292 if self.is_buffer_access:
2293 if code.globalstate.directives['nonecheck']:
2294 self.put_nonecheck(code)
2295 self.buffer_ptr_code = self.buffer_lookup_code(code)
2296 if self.type.is_pyobject:
2297 # is_temp is True, so must pull out value and incref it.
2298 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2299 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2301 if self.type.is_pyobject:
2302 if self.index.type.is_int:
2303 index_code = self.index.result()
2304 if self.base.type is list_type:
2305 function = "__Pyx_GetItemInt_List"
2306 elif self.base.type is tuple_type:
2307 function = "__Pyx_GetItemInt_Tuple"
2309 function = "__Pyx_GetItemInt"
2310 code.globalstate.use_utility_code(getitem_int_utility_code)
2312 index_code = self.index.py_result()
2313 if self.base.type is dict_type:
2314 function = "__Pyx_PyDict_GetItem"
2315 code.globalstate.use_utility_code(getitem_dict_utility_code)
2317 function = "PyObject_GetItem"
2319 "%s = %s(%s, %s%s); if (!%s) %s" % (
2322 self.base.py_result(),
2324 self.extra_index_params(),
2326 code.error_goto(self.pos)))
2327 code.put_gotref(self.py_result())
2328 elif self.type is PyrexTypes.c_py_unicode_type and self.base.type is unicode_type:
2329 assert self.index.type.is_int
2330 index_code = self.index.result()
2331 function = "__Pyx_GetItemInt_Unicode"
2332 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2334 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2337 self.base.py_result(),
2339 self.extra_index_params(),
2341 code.error_goto(self.pos)))
2343 def generate_setitem_code(self, value_code, code):
2344 if self.index.type.is_int:
2345 function = "__Pyx_SetItemInt"
2346 index_code = self.index.result()
2347 code.globalstate.use_utility_code(setitem_int_utility_code)
2349 index_code = self.index.py_result()
2350 if self.base.type is dict_type:
2351 function = "PyDict_SetItem"
2352 # It would seem that we could specialized lists/tuples, but that
2353 # shouldn't happen here.
2354 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2355 # not a PyObject*, and bad conversion here would give the wrong
2356 # exception. Also, tuples are supposed to be immutable, and raise
2357 # TypeErrors when trying to set their entries (PyTuple_SetItem
2358 # is for creating new tuples from).
2360 function = "PyObject_SetItem"
2362 "if (%s(%s, %s, %s%s) < 0) %s" % (
2364 self.base.py_result(),
2367 self.extra_index_params(),
2368 code.error_goto(self.pos)))
2370 def generate_buffer_setitem_code(self, rhs, code, op=""):
2371 # Used from generate_assignment_code and InPlaceAssignmentNode
2372 if code.globalstate.directives['nonecheck']:
2373 self.put_nonecheck(code)
2374 ptrexpr = self.buffer_lookup_code(code)
2375 if self.buffer_type.dtype.is_pyobject:
2376 # Must manage refcounts. Decref what is already there
2377 # and incref what we put in.
2378 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2379 rhs_code = rhs.result()
2380 code.putln("%s = %s;" % (ptr, ptrexpr))
2381 code.put_gotref("*%s" % ptr)
2382 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2385 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2386 code.put_giveref("*%s" % ptr)
2387 code.funcstate.release_temp(ptr)
2390 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2392 def generate_assignment_code(self, rhs, code):
2393 self.generate_subexpr_evaluation_code(code)
2394 if self.is_buffer_access:
2395 self.generate_buffer_setitem_code(rhs, code)
2396 elif self.type.is_pyobject:
2397 self.generate_setitem_code(rhs.py_result(), code)
2401 self.result(), rhs.result()))
2402 self.generate_subexpr_disposal_code(code)
2403 self.free_subexpr_temps(code)
2404 rhs.generate_disposal_code(code)
2405 rhs.free_temps(code)
2407 def generate_deletion_code(self, code):
2408 self.generate_subexpr_evaluation_code(code)
2409 #if self.type.is_pyobject:
2410 if self.index.type.is_int:
2411 function = "__Pyx_DelItemInt"
2412 index_code = self.index.result()
2413 code.globalstate.use_utility_code(delitem_int_utility_code)
2415 index_code = self.index.py_result()
2416 if self.base.type is dict_type:
2417 function = "PyDict_DelItem"
2419 function = "PyObject_DelItem"
2421 "if (%s(%s, %s%s) < 0) %s" % (
2423 self.base.py_result(),
2425 self.extra_index_params(),
2426 code.error_goto(self.pos)))
2427 self.generate_subexpr_disposal_code(code)
2428 self.free_subexpr_temps(code)
2430 def buffer_lookup_code(self, code):
2431 # Assign indices to temps
2432 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2433 for temp, index in zip(index_temps, self.indices):
2434 code.putln("%s = %s;" % (temp, index.result()))
2435 # Generate buffer access code using these temps
2437 # The above could happen because child_attrs is wrong somewhere so that
2438 # options are not propagated.
2439 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2440 index_signeds=[i.type.signed for i in self.indices],
2441 index_cnames=index_temps,
2442 directives=code.globalstate.directives,
2443 pos=self.pos, code=code)
2445 def put_nonecheck(self, code):
2446 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2447 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2448 code.putln("__Pyx_RaiseNoneIndexingError();")
2449 code.putln(code.error_goto(self.pos))
2452 class SliceIndexNode(ExprNode):
2453 # 2-element slice indexing
2456 # start ExprNode or None
2457 # stop ExprNode or None
2459 subexprs = ['base', 'start', 'stop']
2461 def infer_type(self, env):
2462 base_type = self.base.infer_type(env)
2463 if base_type.is_string:
2465 elif base_type in (bytes_type, str_type, unicode_type,
2466 list_type, tuple_type):
2468 return py_object_type
2470 def calculate_constant_result(self):
2471 self.constant_result = self.base.constant_result[
2472 self.start.constant_result : self.stop.constant_result]
2474 def compile_time_value(self, denv):
2475 base = self.base.compile_time_value(denv)
2476 if self.start is None:
2479 start = self.start.compile_time_value(denv)
2480 if self.stop is None:
2483 stop = self.stop.compile_time_value(denv)
2485 return base[start:stop]
2486 except Exception, e:
2487 self.compile_time_value_error(e)
2489 def analyse_target_declaration(self, env):
2492 def analyse_target_types(self, env):
2493 self.analyse_types(env)
2494 # when assigning, we must accept any Python type
2495 if self.type.is_pyobject:
2496 self.type = py_object_type
2498 def analyse_types(self, env):
2499 self.base.analyse_types(env)
2501 self.start.analyse_types(env)
2503 self.stop.analyse_types(env)
2504 base_type = self.base.type
2505 if base_type.is_string:
2506 self.type = bytes_type
2507 elif base_type.is_ptr:
2508 self.type = base_type
2509 elif base_type.is_array:
2510 # we need a ptr type here instead of an array type, as
2511 # array types can result in invalid type casts in the C
2513 self.type = PyrexTypes.CPtrType(base_type.base_type)
2515 self.base = self.base.coerce_to_pyobject(env)
2516 self.type = py_object_type
2517 if base_type.is_builtin_type:
2518 # slicing builtin types returns something of the same type
2519 self.type = base_type
2520 c_int = PyrexTypes.c_py_ssize_t_type
2522 self.start = self.start.coerce_to(c_int, env)
2524 self.stop = self.stop.coerce_to(c_int, env)
2527 nogil_check = Node.gil_error
2528 gil_message = "Slicing Python object"
2530 def generate_result_code(self, code):
2531 if not self.type.is_pyobject:
2533 "Slicing is not currently supported for '%s'." % self.type)
2535 if self.base.type.is_string:
2536 if self.stop is None:
2538 "%s = PyBytes_FromString(%s + %s); %s" % (
2542 code.error_goto_if_null(self.result(), self.pos)))
2545 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2551 code.error_goto_if_null(self.result(), self.pos)))
2554 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2556 self.base.py_result(),
2559 code.error_goto_if_null(self.result(), self.pos)))
2560 code.put_gotref(self.py_result())
2562 def generate_assignment_code(self, rhs, code):
2563 self.generate_subexpr_evaluation_code(code)
2564 if self.type.is_pyobject:
2565 code.put_error_if_neg(self.pos,
2566 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2567 self.base.py_result(),
2574 start_offset = self.start_code()
2575 if start_offset == '0':
2579 if rhs.type.is_array:
2580 array_length = rhs.type.size
2581 self.generate_slice_guard_code(code, array_length)
2584 "Slice assignments from pointers are not yet supported.")
2585 # FIXME: fix the array size according to start/stop
2586 array_length = self.base.type.size
2587 for i in range(array_length):
2588 code.putln("%s[%s%s] = %s[%d];" % (
2589 self.base.result(), start_offset, i,
2591 self.generate_subexpr_disposal_code(code)
2592 self.free_subexpr_temps(code)
2593 rhs.generate_disposal_code(code)
2594 rhs.free_temps(code)
2596 def generate_deletion_code(self, code):
2597 if not self.base.type.is_pyobject:
2599 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2601 self.generate_subexpr_evaluation_code(code)
2602 code.put_error_if_neg(self.pos,
2603 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2604 self.base.py_result(),
2607 self.generate_subexpr_disposal_code(code)
2609 def generate_slice_guard_code(self, code, target_size):
2610 if not self.base.type.is_array:
2612 slice_size = self.base.type.size
2615 stop = self.stop.result()
2619 slice_size = self.base.type.size + stop
2626 start = self.start.result()
2630 start = self.base.type.size + start
2638 error(self.pos, "Assignment to empty slice.")
2639 elif start is None and stop is None:
2640 # we know the exact slice length
2641 if target_size != slice_size:
2642 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2643 slice_size, target_size))
2644 elif start is not None:
2647 check = "(%s)-(%s)" % (stop, start)
2648 else: # stop is not None:
2651 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2652 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));' % (
2653 target_size, check))
2654 code.putln(code.error_goto(self.pos))
2657 def start_code(self):
2659 return self.start.result()
2663 def stop_code(self):
2665 return self.stop.result()
2666 elif self.base.type.is_array:
2667 return self.base.type.size
2669 return "PY_SSIZE_T_MAX"
2671 def calculate_result_code(self):
2672 # self.result() is not used, but this method must exist
2676 class SliceNode(ExprNode):
2677 # start:stop:step in subscript list
2683 type = py_object_type
2686 def calculate_constant_result(self):
2687 self.constant_result = self.base.constant_result[
2688 self.start.constant_result : \
2689 self.stop.constant_result : \
2690 self.step.constant_result]
2692 def compile_time_value(self, denv):
2693 start = self.start.compile_time_value(denv)
2694 if self.stop is None:
2697 stop = self.stop.compile_time_value(denv)
2698 if self.step is None:
2701 step = self.step.compile_time_value(denv)
2703 return slice(start, stop, step)
2704 except Exception, e:
2705 self.compile_time_value_error(e)
2707 subexprs = ['start', 'stop', 'step']
2709 def analyse_types(self, env):
2710 self.start.analyse_types(env)
2711 self.stop.analyse_types(env)
2712 self.step.analyse_types(env)
2713 self.start = self.start.coerce_to_pyobject(env)
2714 self.stop = self.stop.coerce_to_pyobject(env)
2715 self.step = self.step.coerce_to_pyobject(env)
2717 gil_message = "Constructing Python slice object"
2719 def generate_result_code(self, code):
2721 "%s = PySlice_New(%s, %s, %s); %s" % (
2723 self.start.py_result(),
2724 self.stop.py_result(),
2725 self.step.py_result(),
2726 code.error_goto_if_null(self.result(), self.pos)))
2727 code.put_gotref(self.py_result())
2730 class CallNode(ExprNode):
2732 # allow overriding the default 'may_be_none' behaviour
2733 may_return_none = None
2735 def may_be_none(self):
2736 if self.may_return_none is not None:
2737 return self.may_return_none
2738 return ExprNode.may_be_none(self)
2740 def analyse_as_type_constructor(self, env):
2741 type = self.function.analyse_as_type(env)
2742 if type and type.is_struct_or_union:
2743 args, kwds = self.explicit_args_kwds()
2745 for arg, member in zip(args, type.scope.var_entries):
2746 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2748 items += kwds.key_value_pairs
2749 self.key_value_pairs = items
2750 self.__class__ = DictNode
2751 self.analyse_types(env)
2752 self.coerce_to(type, env)
2754 elif type and type.is_cpp_class:
2755 for arg in self.args:
2756 arg.analyse_types(env)
2757 constructor = type.scope.lookup("<init>")
2758 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2759 self.function.entry = constructor
2760 self.function.set_cname(type.declaration_code(""))
2761 self.analyse_c_function_call(env)
2764 def is_lvalue(self):
2765 return self.type.is_reference
2767 def nogil_check(self, env):
2768 func_type = self.function_type()
2769 if func_type.is_pyobject:
2771 elif not getattr(func_type, 'nogil', False):
2774 gil_message = "Calling gil-requiring function"
2777 class SimpleCallNode(CallNode):
2778 # Function call without keyword, * or ** args.
2782 # arg_tuple ExprNode or None used internally
2783 # self ExprNode or None used internally
2784 # coerced_self ExprNode or None used internally
2785 # wrapper_call bool used internally
2786 # has_optional_args bool used internally
2787 # nogil bool used internally
2789 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2794 wrapper_call = False
2795 has_optional_args = False
2799 def compile_time_value(self, denv):
2800 function = self.function.compile_time_value(denv)
2801 args = [arg.compile_time_value(denv) for arg in self.args]
2803 return function(*args)
2804 except Exception, e:
2805 self.compile_time_value_error(e)
2807 def type_dependencies(self, env):
2808 # TODO: Update when Danilo's C++ code merged in to handle the
2809 # the case of function overloading.
2810 return self.function.type_dependencies(env)
2812 def infer_type(self, env):
2813 function = self.function
2814 func_type = function.infer_type(env)
2815 if isinstance(self.function, NewExprNode):
2816 return PyrexTypes.CPtrType(self.function.class_type)
2817 if func_type.is_ptr:
2818 func_type = func_type.base_type
2819 if func_type.is_cfunction:
2820 return func_type.return_type
2821 elif func_type is type_type:
2822 if function.is_name and function.entry and function.entry.type:
2823 result_type = function.entry.type
2824 if result_type.is_extension_type:
2826 elif result_type.is_builtin_type:
2827 if function.entry.name == 'float':
2828 return PyrexTypes.c_double_type
2829 elif function.entry.name in Builtin.types_that_construct_their_instance:
2831 return py_object_type
2833 def analyse_as_type(self, env):
2834 attr = self.function.as_cython_attribute()
2835 if attr == 'pointer':
2836 if len(self.args) != 1:
2837 error(self.args.pos, "only one type allowed.")
2839 type = self.args[0].analyse_as_type(env)
2841 error(self.args[0].pos, "Unknown type")
2843 return PyrexTypes.CPtrType(type)
2845 def explicit_args_kwds(self):
2846 return self.args, None
2848 def analyse_types(self, env):
2849 if self.analyse_as_type_constructor(env):
2853 self.analysed = True
2854 function = self.function
2855 function.is_called = 1
2856 self.function.analyse_types(env)
2857 if function.is_attribute and function.entry and function.entry.is_cmethod:
2858 # Take ownership of the object from which the attribute
2859 # was obtained, because we need to pass it as 'self'.
2860 self.self = function.obj
2861 function.obj = CloneNode(self.self)
2862 func_type = self.function_type()
2863 if func_type.is_pyobject:
2864 self.arg_tuple = TupleNode(self.pos, args = self.args)
2865 self.arg_tuple.analyse_types(env)
2867 if func_type is Builtin.type_type and function.is_name and \
2868 function.entry and \
2869 function.entry.is_builtin and \
2870 function.entry.name in Builtin.types_that_construct_their_instance:
2871 # calling a builtin type that returns a specific object type
2872 if function.entry.name == 'float':
2873 # the following will come true later on in a transform
2874 self.type = PyrexTypes.c_double_type
2875 self.result_ctype = PyrexTypes.c_double_type
2877 self.type = Builtin.builtin_types[function.entry.name]
2878 self.result_ctype = py_object_type
2879 self.may_return_none = False
2880 elif function.is_name and function.type_entry:
2881 # We are calling an extension type constructor. As
2882 # long as we do not support __new__(), the result type
2884 self.type = function.type_entry.type
2885 self.result_ctype = py_object_type
2886 self.may_return_none = False
2888 self.type = py_object_type
2891 for arg in self.args:
2892 arg.analyse_types(env)
2893 if self.self and func_type.args:
2894 # Coerce 'self' to the type expected by the method.
2895 self_arg = func_type.args[0]
2896 if self_arg.not_none: # C methods must do the None test for self at *call* time
2897 self.self = self.self.as_none_safe_node(
2898 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2899 'PyExc_AttributeError')
2900 expected_type = self_arg.type
2901 self.coerced_self = CloneNode(self.self).coerce_to(
2903 # Insert coerced 'self' argument into argument list.
2904 self.args.insert(0, self.coerced_self)
2905 self.analyse_c_function_call(env)
2907 def function_type(self):
2908 # Return the type of the function being called, coercing a function
2909 # pointer to a function if necessary.
2910 func_type = self.function.type
2911 if func_type.is_ptr:
2912 func_type = func_type.base_type
2915 def analyse_c_function_call(self, env):
2916 if self.function.type is error_type:
2917 self.type = error_type
2919 if self.function.type.is_cpp_class:
2920 overloaded_entry = self.function.type.scope.lookup("operator()")
2921 if overloaded_entry is None:
2922 self.type = PyrexTypes.error_type
2923 self.result_code = "<error>"
2925 elif hasattr(self.function, 'entry'):
2926 overloaded_entry = self.function.entry
2928 overloaded_entry = None
2929 if overloaded_entry:
2930 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2932 self.type = PyrexTypes.error_type
2933 self.result_code = "<error>"
2935 self.function.entry = entry
2936 self.function.type = entry.type
2937 func_type = self.function_type()
2939 func_type = self.function_type()
2940 if not func_type.is_cfunction:
2941 error(self.pos, "Calling non-function type '%s'" % func_type)
2942 self.type = PyrexTypes.error_type
2943 self.result_code = "<error>"
2946 max_nargs = len(func_type.args)
2947 expected_nargs = max_nargs - func_type.optional_arg_count
2948 actual_nargs = len(self.args)
2949 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2950 self.has_optional_args = 1
2953 for i in range(min(max_nargs, actual_nargs)):
2954 formal_type = func_type.args[i].type
2955 self.args[i] = self.args[i].coerce_to(formal_type, env)
2956 for i in range(max_nargs, actual_nargs):
2957 if self.args[i].type.is_pyobject:
2958 error(self.args[i].pos,
2959 "Python object cannot be passed as a varargs parameter")
2960 # Calc result type and code fragment
2961 if isinstance(self.function, NewExprNode):
2962 self.type = PyrexTypes.CPtrType(self.function.class_type)
2964 self.type = func_type.return_type
2965 if self.type.is_pyobject:
2966 self.result_ctype = py_object_type
2968 elif func_type.exception_value is not None \
2969 or func_type.exception_check:
2971 # Called in 'nogil' context?
2972 self.nogil = env.nogil
2974 func_type.exception_check and
2975 func_type.exception_check != '+'):
2976 env.use_utility_code(pyerr_occurred_withgil_utility_code)
2977 # C++ exception handler
2978 if func_type.exception_check == '+':
2979 if func_type.exception_value is None:
2980 env.use_utility_code(cpp_exception_utility_code)
2982 def calculate_result_code(self):
2983 return self.c_call_code()
2985 def c_call_code(self):
2986 func_type = self.function_type()
2987 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2989 formal_args = func_type.args
2991 args = list(zip(formal_args, self.args))
2992 max_nargs = len(func_type.args)
2993 expected_nargs = max_nargs - func_type.optional_arg_count
2994 actual_nargs = len(self.args)
2995 for formal_arg, actual_arg in args[:expected_nargs]:
2996 arg_code = actual_arg.result_as(formal_arg.type)
2997 arg_list_code.append(arg_code)
2999 if func_type.is_overridable:
3000 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3002 if func_type.optional_arg_count:
3003 if expected_nargs == actual_nargs:
3004 optional_args = 'NULL'
3006 optional_args = "&%s" % self.opt_arg_struct
3007 arg_list_code.append(optional_args)
3009 for actual_arg in self.args[len(formal_args):]:
3010 arg_list_code.append(actual_arg.result())
3011 result = "%s(%s)" % (self.function.result(),
3012 ', '.join(arg_list_code))
3015 def generate_result_code(self, code):
3016 func_type = self.function_type()
3017 if func_type.is_pyobject:
3018 arg_code = self.arg_tuple.py_result()
3020 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3022 self.function.py_result(),
3024 code.error_goto_if_null(self.result(), self.pos)))
3025 code.put_gotref(self.py_result())
3026 elif func_type.is_cfunction:
3027 if self.has_optional_args:
3028 actual_nargs = len(self.args)
3029 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3030 self.opt_arg_struct = code.funcstate.allocate_temp(
3031 func_type.op_arg_struct.base_type, manage_ref=True)
3032 code.putln("%s.%s = %s;" % (
3033 self.opt_arg_struct,
3034 Naming.pyrex_prefix + "n",
3035 len(self.args) - expected_nargs))
3036 args = list(zip(func_type.args, self.args))
3037 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3038 code.putln("%s.%s = %s;" % (
3039 self.opt_arg_struct,
3040 func_type.opt_arg_cname(formal_arg.name),
3041 actual_arg.result_as(formal_arg.type)))
3043 if self.type.is_pyobject and self.is_temp:
3044 exc_checks.append("!%s" % self.result())
3046 exc_val = func_type.exception_value
3047 exc_check = func_type.exception_check
3048 if exc_val is not None:
3049 exc_checks.append("%s == %s" % (self.result(), exc_val))
3052 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3054 exc_checks.append("PyErr_Occurred()")
3055 if self.is_temp or exc_checks:
3056 rhs = self.c_call_code()
3058 lhs = "%s = " % self.result()
3059 if self.is_temp and self.type.is_pyobject:
3060 #return_type = self.type # func_type.return_type
3061 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3062 # "from", return_type, "to pyobject" ###
3063 rhs = typecast(py_object_type, self.type, rhs)
3066 if func_type.exception_check == '+':
3067 if func_type.exception_value is None:
3068 raise_py_exception = "__Pyx_CppExn2PyErr()"
3069 elif func_type.exception_value.type.is_pyobject:
3070 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3071 func_type.exception_value.entry.cname,
3072 func_type.exception_value.entry.cname)
3074 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3076 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3078 "try {%s%s;} catch(...) {%s; %s}" % (
3082 code.error_goto(self.pos)))
3085 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3088 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3089 if self.type.is_pyobject and self.result():
3090 code.put_gotref(self.py_result())
3091 if self.has_optional_args:
3092 code.funcstate.release_temp(self.opt_arg_struct)
3095 class PythonCapiFunctionNode(ExprNode):
3097 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3101 self.type = func_type
3102 self.utility_code = utility_code
3104 def analyse_types(self, env):
3107 def generate_result_code(self, code):
3108 if self.utility_code:
3109 code.globalstate.use_utility_code(self.utility_code)
3111 def calculate_result_code(self):
3114 class PythonCapiCallNode(SimpleCallNode):
3115 # Python C-API Function call (only created in transforms)
3117 # By default, we assume that the call never returns None, as this
3118 # is true for most C-API functions in CPython. If this does not
3119 # apply to a call, set the following to True (or None to inherit
3120 # the default behaviour).
3121 may_return_none = False
3123 def __init__(self, pos, function_name, func_type,
3124 utility_code = None, py_name=None, **kwargs):
3125 self.type = func_type.return_type
3126 self.result_ctype = self.type
3127 self.function = PythonCapiFunctionNode(
3128 pos, py_name, function_name, func_type,
3129 utility_code = utility_code)
3130 # call this last so that we can override the constructed
3131 # attributes above with explicit keyword arguments if required
3132 SimpleCallNode.__init__(self, pos, **kwargs)
3135 class GeneralCallNode(CallNode):
3136 # General Python function call, including keyword,
3137 # * and ** arguments.
3140 # positional_args ExprNode Tuple of positional arguments
3141 # keyword_args ExprNode or None Dict of keyword arguments
3142 # starstar_arg ExprNode or None Dict of extra keyword args
3144 type = py_object_type
3146 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3148 nogil_check = Node.gil_error
3150 def compile_time_value(self, denv):
3151 function = self.function.compile_time_value(denv)
3152 positional_args = self.positional_args.compile_time_value(denv)
3153 keyword_args = self.keyword_args.compile_time_value(denv)
3154 starstar_arg = self.starstar_arg.compile_time_value(denv)
3156 keyword_args.update(starstar_arg)
3157 return function(*positional_args, **keyword_args)
3158 except Exception, e:
3159 self.compile_time_value_error(e)
3161 def explicit_args_kwds(self):
3162 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3163 raise CompileError(self.pos,
3164 'Compile-time keyword arguments must be explicit.')
3165 return self.positional_args.args, self.keyword_args
3167 def analyse_types(self, env):
3168 if self.analyse_as_type_constructor(env):
3170 self.function.analyse_types(env)
3171 self.positional_args.analyse_types(env)
3172 if self.keyword_args:
3173 self.keyword_args.analyse_types(env)
3174 if self.starstar_arg:
3175 self.starstar_arg.analyse_types(env)
3176 if not self.function.type.is_pyobject:
3177 if self.function.type.is_error:
3178 self.type = error_type
3180 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3181 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3183 self.function = self.function.coerce_to_pyobject(env)
3184 self.positional_args = \
3185 self.positional_args.coerce_to_pyobject(env)
3186 if self.starstar_arg:
3187 self.starstar_arg = \
3188 self.starstar_arg.coerce_to_pyobject(env)
3189 function = self.function
3190 if function.is_name and function.type_entry:
3191 # We are calling an extension type constructor. As long
3192 # as we do not support __new__(), the result type is clear
3193 self.type = function.type_entry.type
3194 self.result_ctype = py_object_type
3195 self.may_return_none = False
3197 self.type = py_object_type
3200 def generate_result_code(self, code):
3201 if self.type.is_error: return
3202 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3203 if self.keyword_args and self.starstar_arg:
3204 code.put_error_if_neg(self.pos,
3205 "PyDict_Update(%s, %s)" % (
3206 self.keyword_args.py_result(),
3207 self.starstar_arg.py_result()))
3208 keyword_code = self.keyword_args.py_result()
3209 elif self.keyword_args:
3210 keyword_code = self.keyword_args.py_result()
3211 elif self.starstar_arg:
3212 keyword_code = self.starstar_arg.py_result()
3213 if self.starstar_arg.type is not Builtin.dict_type:
3214 # CPython supports calling functions with non-dicts, so do we
3215 code.globalstate.use_utility_code(kwargs_call_utility_code)
3216 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3219 if not keyword_code:
3220 call_code = "PyObject_Call(%s, %s, NULL)" % (
3221 self.function.py_result(),
3222 self.positional_args.py_result())
3224 call_code = "%s(%s, %s, %s)" % (
3225 kwargs_call_function,
3226 self.function.py_result(),
3227 self.positional_args.py_result(),
3233 code.error_goto_if_null(self.result(), self.pos)))
3234 code.put_gotref(self.py_result())
3237 class AsTupleNode(ExprNode):
3238 # Convert argument to tuple. Used for normalising
3239 # the * argument of a function call.
3245 def calculate_constant_result(self):
3246 self.constant_result = tuple(self.base.constant_result)
3248 def compile_time_value(self, denv):
3249 arg = self.arg.compile_time_value(denv)
3252 except Exception, e:
3253 self.compile_time_value_error(e)
3255 def analyse_types(self, env):
3256 self.arg.analyse_types(env)
3257 self.arg = self.arg.coerce_to_pyobject(env)
3258 self.type = tuple_type
3261 def may_be_none(self):
3264 nogil_check = Node.gil_error
3265 gil_message = "Constructing Python tuple"
3267 def generate_result_code(self, code):
3269 "%s = PySequence_Tuple(%s); %s" % (
3271 self.arg.py_result(),
3272 code.error_goto_if_null(self.result(), self.pos)))
3273 code.put_gotref(self.py_result())
3276 class AttributeNode(ExprNode):
3281 # needs_none_check boolean Used if obj is an extension type.
3282 # If set to True, it is known that the type is not None.
3286 # is_py_attr boolean Is a Python getattr operation
3287 # member string C name of struct member
3288 # is_called boolean Function call is being done on result
3289 # entry Entry Symbol table entry of attribute
3294 type = PyrexTypes.error_type
3297 needs_none_check = True
3299 def as_cython_attribute(self):
3300 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3301 return self.attribute
3302 cy = self.obj.as_cython_attribute()
3304 return "%s.%s" % (cy, self.attribute)
3306 def coerce_to(self, dst_type, env):
3307 # If coercing to a generic pyobject and this is a cpdef function
3308 # we can create the corresponding attribute
3309 if dst_type is py_object_type:
3311 if entry and entry.is_cfunction and entry.as_variable:
3312 # must be a cpdef function
3314 self.entry = entry.as_variable
3315 self.analyse_as_python_attribute(env)
3317 return ExprNode.coerce_to(self, dst_type, env)
3319 def calculate_constant_result(self):
3320 attr = self.attribute
3321 if attr.startswith("__") and attr.endswith("__"):
3323 self.constant_result = getattr(self.obj.constant_result, attr)
3325 def compile_time_value(self, denv):
3326 attr = self.attribute
3327 if attr.startswith("__") and attr.endswith("__"):
3329 "Invalid attribute name '%s' in compile-time expression" % attr)
3331 obj = self.obj.compile_time_value(denv)
3333 return getattr(obj, attr)
3334 except Exception, e:
3335 self.compile_time_value_error(e)
3337 def type_dependencies(self, env):
3338 return self.obj.type_dependencies(env)
3340 def infer_type(self, env):
3341 if self.analyse_as_cimported_attribute(env, 0):
3342 return self.entry.type
3343 elif self.analyse_as_unbound_cmethod(env):
3344 return self.entry.type
3346 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3349 def analyse_target_declaration(self, env):
3352 def analyse_target_types(self, env):
3353 self.analyse_types(env, target = 1)
3355 def analyse_types(self, env, target = 0):
3356 if self.analyse_as_cimported_attribute(env, target):
3358 if not target and self.analyse_as_unbound_cmethod(env):
3360 self.analyse_as_ordinary_attribute(env, target)
3362 def analyse_as_cimported_attribute(self, env, target):
3363 # Try to interpret this as a reference to an imported
3364 # C const, type, var or function. If successful, mutates
3365 # this node into a NameNode and returns 1, otherwise
3367 module_scope = self.obj.analyse_as_module(env)
3369 entry = module_scope.lookup_here(self.attribute)
3371 entry.is_cglobal or entry.is_cfunction
3372 or entry.is_type or entry.is_const):
3373 self.mutate_into_name_node(env, entry, target)
3377 def analyse_as_unbound_cmethod(self, env):
3378 # Try to interpret this as a reference to an unbound
3379 # C method of an extension type. If successful, mutates
3380 # this node into a NameNode and returns 1, otherwise
3382 type = self.obj.analyse_as_extension_type(env)
3384 entry = type.scope.lookup_here(self.attribute)
3385 if entry and entry.is_cmethod:
3386 # Create a temporary entry describing the C method
3387 # as an ordinary function.
3388 ubcm_entry = Symtab.Entry(entry.name,
3389 "%s->%s" % (type.vtabptr_cname, entry.cname),
3391 ubcm_entry.is_cfunction = 1
3392 ubcm_entry.func_cname = entry.func_cname
3393 ubcm_entry.is_unbound_cmethod = 1
3394 self.mutate_into_name_node(env, ubcm_entry, None)
3398 def analyse_as_type(self, env):
3399 module_scope = self.obj.analyse_as_module(env)
3401 return module_scope.lookup_type(self.attribute)
3402 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3403 base_type = self.obj.analyse_as_type(env)
3404 if base_type and hasattr(base_type, 'scope'):
3405 return base_type.scope.lookup_type(self.attribute)
3408 def analyse_as_extension_type(self, env):
3409 # Try to interpret this as a reference to an extension type
3410 # in a cimported module. Returns the extension type, or None.
3411 module_scope = self.obj.analyse_as_module(env)
3413 entry = module_scope.lookup_here(self.attribute)
3414 if entry and entry.is_type and entry.type.is_extension_type:
3418 def analyse_as_module(self, env):
3419 # Try to interpret this as a reference to a cimported module
3420 # in another cimported module. Returns the module scope, or None.
3421 module_scope = self.obj.analyse_as_module(env)
3423 entry = module_scope.lookup_here(self.attribute)
3424 if entry and entry.as_module:
3425 return entry.as_module
3428 def mutate_into_name_node(self, env, entry, target):
3429 # Mutate this node into a NameNode and complete the
3430 # analyse_types phase.
3431 self.__class__ = NameNode
3432 self.name = self.attribute
3437 NameNode.analyse_target_types(self, env)
3439 NameNode.analyse_rvalue_entry(self, env)
3441 def analyse_as_ordinary_attribute(self, env, target):
3442 self.obj.analyse_types(env)
3443 self.analyse_attribute(env)
3444 if self.entry and self.entry.is_cmethod and not self.is_called:
3445 # error(self.pos, "C method can only be called")
3447 ## Reference to C array turns into pointer to first element.
3448 #while self.type.is_array:
3449 # self.type = self.type.element_ptr_type()
3453 self.result_ctype = py_object_type
3454 elif target and self.obj.type.is_builtin_type:
3455 error(self.pos, "Assignment to an immutable object field")
3457 def analyse_attribute(self, env, obj_type = None):
3458 # Look up attribute and set self.type and self.member.
3460 self.member = self.attribute
3461 if obj_type is None:
3462 if self.obj.type.is_string:
3463 self.obj = self.obj.coerce_to_pyobject(env)
3464 obj_type = self.obj.type
3466 if obj_type.is_string:
3467 obj_type = py_object_type
3468 if obj_type.is_ptr or obj_type.is_array:
3469 obj_type = obj_type.base_type
3471 elif obj_type.is_extension_type or obj_type.is_builtin_type:
3475 if obj_type.has_attributes:
3477 if obj_type.attributes_known():
3478 entry = obj_type.scope.lookup_here(self.attribute)
3479 if entry and entry.is_member:
3483 "Cannot select attribute of incomplete type '%s'"
3485 self.type = PyrexTypes.error_type
3489 if obj_type.is_extension_type and entry.name == "__weakref__":
3490 error(self.pos, "Illegal use of special attribute __weakref__")
3491 # methods need the normal attribute lookup
3492 # because they do not have struct entries
3493 if entry.is_variable or entry.is_cmethod:
3494 self.type = entry.type
3495 self.member = entry.cname
3498 # If it's not a variable or C method, it must be a Python
3499 # method of an extension type, so we treat it like a Python
3502 # If we get here, the base object is not a struct/union/extension
3503 # type, or it is an extension type and the attribute is either not
3504 # declared or is declared as a Python method. Treat it as a Python
3505 # attribute reference.
3506 self.analyse_as_python_attribute(env, obj_type)
3508 def analyse_as_python_attribute(self, env, obj_type = None):
3509 if obj_type is None:
3510 obj_type = self.obj.type
3511 self.member = self.attribute
3512 self.type = py_object_type
3514 if not obj_type.is_pyobject and not obj_type.is_error:
3515 if obj_type.can_coerce_to_pyobject(env):
3516 self.obj = self.obj.coerce_to_pyobject(env)
3519 "Object of type '%s' has no attribute '%s'" %
3520 (obj_type, self.attribute))
3522 def nogil_check(self, env):
3526 gil_message = "Accessing Python attribute"
3528 def is_simple(self):
3530 return self.result_in_temp() or self.obj.is_simple()
3532 return NameNode.is_simple(self)
3534 def is_lvalue(self):
3538 return NameNode.is_lvalue(self)
3540 def is_ephemeral(self):
3542 return self.obj.is_ephemeral()
3544 return NameNode.is_ephemeral(self)
3546 def calculate_result_code(self):
3547 #print "AttributeNode.calculate_result_code:", self.member ###
3548 #print "...obj node =", self.obj, "code", self.obj.result() ###
3549 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3551 obj_code = obj.result_as(obj.type)
3552 #print "...obj_code =", obj_code ###
3553 if self.entry and self.entry.is_cmethod:
3554 if obj.type.is_extension_type:
3555 return "((struct %s *)%s%s%s)->%s" % (
3556 obj.type.vtabstruct_cname, obj_code, self.op,
3557 obj.type.vtabslot_cname, self.member)
3560 elif obj.type.is_complex:
3561 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3563 if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
3564 # accessing a field of a builtin type, need to cast better than result_as() does
3565 obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
3566 return "%s%s%s" % (obj_code, self.op, self.member)
3568 def generate_result_code(self, code):
3569 interned_attr_cname = code.intern_identifier(self.attribute)
3572 '%s = PyObject_GetAttr(%s, %s); %s' % (
3574 self.obj.py_result(),
3575 interned_attr_cname,
3576 code.error_goto_if_null(self.result(), self.pos)))
3577 code.put_gotref(self.py_result())
3579 # result_code contains what is needed, but we may need to insert
3580 # a check and raise an exception
3581 if (self.obj.type.is_extension_type
3582 and self.needs_none_check
3583 and code.globalstate.directives['nonecheck']):
3584 self.put_nonecheck(code)
3586 def generate_assignment_code(self, rhs, code):
3587 interned_attr_cname = code.intern_identifier(self.attribute)
3588 self.obj.generate_evaluation_code(code)
3590 code.put_error_if_neg(self.pos,
3591 'PyObject_SetAttr(%s, %s, %s)' % (
3592 self.obj.py_result(),
3593 interned_attr_cname,
3595 rhs.generate_disposal_code(code)
3596 rhs.free_temps(code)
3597 elif self.obj.type.is_complex:
3598 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3599 self.member.upper(),
3600 self.obj.result_as(self.obj.type),
3601 rhs.result_as(self.ctype())))
3603 if (self.obj.type.is_extension_type
3604 and self.needs_none_check
3605 and code.globalstate.directives['nonecheck']):
3606 self.put_nonecheck(code)
3608 select_code = self.result()
3609 if self.type.is_pyobject and self.use_managed_ref:
3610 rhs.make_owned_reference(code)
3611 code.put_giveref(rhs.py_result())
3612 code.put_gotref(select_code)
3613 code.put_decref(select_code, self.ctype())
3617 rhs.result_as(self.ctype())))
3619 rhs.generate_post_assignment_code(code)
3620 rhs.free_temps(code)
3621 self.obj.generate_disposal_code(code)
3622 self.obj.free_temps(code)
3624 def generate_deletion_code(self, code):
3625 interned_attr_cname = code.intern_identifier(self.attribute)
3626 self.obj.generate_evaluation_code(code)
3627 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3628 and u'__del__' in self.entry.scope.entries):
3629 code.put_error_if_neg(self.pos,
3630 'PyObject_DelAttr(%s, %s)' % (
3631 self.obj.py_result(),
3632 interned_attr_cname))
3634 error(self.pos, "Cannot delete C attribute of extension type")
3635 self.obj.generate_disposal_code(code)
3636 self.obj.free_temps(code)
3638 def annotate(self, code):
3640 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3642 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3644 def put_nonecheck(self, code):
3645 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3646 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3647 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3648 code.putln(code.error_goto(self.pos))
3652 #-------------------------------------------------------------------
3656 #-------------------------------------------------------------------
3658 class StarredTargetNode(ExprNode):
3659 # A starred expression like "*a"
3661 # This is only allowed in sequence assignment targets such as
3663 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3665 # and will be removed during type analysis (or generate an error
3666 # if it's found at unexpected places).
3670 subexprs = ['target']
3672 type = py_object_type
3675 def __init__(self, pos, target):
3677 self.target = target
3679 def analyse_declarations(self, env):
3680 error(self.pos, "can use starred expression only as assignment target")
3681 self.target.analyse_declarations(env)
3683 def analyse_types(self, env):
3684 error(self.pos, "can use starred expression only as assignment target")
3685 self.target.analyse_types(env)
3686 self.type = self.target.type
3688 def analyse_target_declaration(self, env):
3689 self.target.analyse_target_declaration(env)
3691 def analyse_target_types(self, env):
3692 self.target.analyse_target_types(env)
3693 self.type = self.target.type
3695 def calculate_result_code(self):
3698 def generate_result_code(self, code):
3702 class SequenceNode(ExprNode):
3703 # Base class for list and tuple constructor nodes.
3704 # Contains common code for performing sequence unpacking.
3708 # unpacked_items [ExprNode] or None
3709 # coerced_unpacked_items [ExprNode] or None
3713 is_sequence_constructor = 1
3714 unpacked_items = None
3716 def compile_time_value_list(self, denv):
3717 return [arg.compile_time_value(denv) for arg in self.args]
3719 def replace_starred_target_node(self):
3720 # replace a starred node in the targets by the contained expression
3721 self.starred_assignment = False
3723 for arg in self.args:
3725 if self.starred_assignment:
3726 error(arg.pos, "more than 1 starred expression in assignment")
3727 self.starred_assignment = True
3729 arg.is_starred = True
3733 def analyse_target_declaration(self, env):
3734 self.replace_starred_target_node()
3735 for arg in self.args:
3736 arg.analyse_target_declaration(env)
3738 def analyse_types(self, env, skip_children=False):
3739 for i in range(len(self.args)):
3741 if not skip_children: arg.analyse_types(env)
3742 self.args[i] = arg.coerce_to_pyobject(env)
3744 # not setting self.type here, subtypes do this
3746 def may_be_none(self):
3749 def analyse_target_types(self, env):
3750 self.iterator = PyTempNode(self.pos, env)
3751 self.unpacked_items = []
3752 self.coerced_unpacked_items = []
3753 for arg in self.args:
3754 arg.analyse_target_types(env)
3756 if not arg.type.assignable_from(Builtin.list_type):
3758 "starred target must have Python object (list) type")
3759 if arg.type is py_object_type:
3760 arg.type = Builtin.list_type
3761 unpacked_item = PyTempNode(self.pos, env)
3762 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3763 self.unpacked_items.append(unpacked_item)
3764 self.coerced_unpacked_items.append(coerced_unpacked_item)
3765 self.type = py_object_type
3767 def generate_result_code(self, code):
3768 self.generate_operation_code(code)
3770 def generate_assignment_code(self, rhs, code):
3771 if self.starred_assignment:
3772 self.generate_starred_assignment_code(rhs, code)
3774 self.generate_parallel_assignment_code(rhs, code)
3776 for item in self.unpacked_items:
3778 rhs.free_temps(code)
3780 def generate_parallel_assignment_code(self, rhs, code):
3781 # Need to work around the fact that generate_evaluation_code
3782 # allocates the temps in a rather hacky way -- the assignment
3783 # is evaluated twice, within each if-block.
3785 if rhs.type is tuple_type:
3786 tuple_check = "likely(%s != Py_None)"
3788 tuple_check = "PyTuple_CheckExact(%s)"
3790 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3791 tuple_check % rhs.py_result(),
3794 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3795 for item in self.unpacked_items:
3797 for i in range(len(self.args)):
3798 item = self.unpacked_items[i]
3800 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3803 code.put_incref(item.result(), item.ctype())
3804 value_node = self.coerced_unpacked_items[i]
3805 value_node.generate_evaluation_code(code)
3806 rhs.generate_disposal_code(code)
3808 for i in range(len(self.args)):
3809 self.args[i].generate_assignment_code(
3810 self.coerced_unpacked_items[i], code)
3812 code.putln("} else {")
3814 if rhs.type is tuple_type:
3815 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3816 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3817 rhs.py_result(), len(self.args)))
3818 code.putln(code.error_goto(self.pos))
3820 code.globalstate.use_utility_code(unpacking_utility_code)
3822 self.iterator.allocate(code)
3824 "%s = PyObject_GetIter(%s); %s" % (
3825 self.iterator.result(),
3827 code.error_goto_if_null(self.iterator.result(), self.pos)))
3828 code.put_gotref(self.iterator.py_result())
3829 rhs.generate_disposal_code(code)
3830 for i in range(len(self.args)):
3831 item = self.unpacked_items[i]
3832 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3833 self.iterator.py_result(), i)
3837 typecast(item.ctype(), py_object_type, unpack_code),
3838 code.error_goto_if_null(item.result(), self.pos)))
3839 code.put_gotref(item.py_result())
3840 value_node = self.coerced_unpacked_items[i]
3841 value_node.generate_evaluation_code(code)
3842 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3843 self.iterator.py_result(),
3845 if debug_disposal_code:
3846 print("UnpackNode.generate_assignment_code:")
3847 print("...generating disposal code for %s" % self.iterator)
3848 self.iterator.generate_disposal_code(code)
3849 self.iterator.free_temps(code)
3850 self.iterator.release(code)
3852 for i in range(len(self.args)):
3853 self.args[i].generate_assignment_code(
3854 self.coerced_unpacked_items[i], code)
3858 def generate_starred_assignment_code(self, rhs, code):
3859 code.globalstate.use_utility_code(unpacking_utility_code)
3861 for i, arg in enumerate(self.args):
3863 starred_target = self.unpacked_items[i]
3864 fixed_args_left = self.args[:i]
3865 fixed_args_right = self.args[i+1:]
3868 self.iterator.allocate(code)
3870 "%s = PyObject_GetIter(%s); %s" % (
3871 self.iterator.result(),
3873 code.error_goto_if_null(self.iterator.result(), self.pos)))
3874 code.put_gotref(self.iterator.py_result())
3875 rhs.generate_disposal_code(code)
3877 for item in self.unpacked_items:
3879 for i in range(len(fixed_args_left)):
3880 item = self.unpacked_items[i]
3881 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3882 self.iterator.py_result(), i)
3886 typecast(item.ctype(), py_object_type, unpack_code),
3887 code.error_goto_if_null(item.result(), self.pos)))
3888 code.put_gotref(item.py_result())
3889 value_node = self.coerced_unpacked_items[i]
3890 value_node.generate_evaluation_code(code)
3892 target_list = starred_target.result()
3893 code.putln("%s = PySequence_List(%s); %s" % (
3894 target_list, self.iterator.py_result(),
3895 code.error_goto_if_null(target_list, self.pos)))
3896 code.put_gotref(target_list)
3897 if fixed_args_right:
3898 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3899 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3900 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3901 (target_list, len(unpacked_right_args))))
3902 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3903 len(fixed_args_left), target_list,
3904 code.error_goto(self.pos)))
3906 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3907 self.coerced_unpacked_items[::-1])):
3909 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3911 target_list, target_list))
3912 # resize the list the hard way
3913 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3914 code.put_gotref(arg.py_result())
3915 coerced_arg.generate_evaluation_code(code)
3917 self.iterator.generate_disposal_code(code)
3918 self.iterator.free_temps(code)
3919 self.iterator.release(code)
3921 for i in range(len(self.args)):
3922 self.args[i].generate_assignment_code(
3923 self.coerced_unpacked_items[i], code)
3925 def annotate(self, code):
3926 for arg in self.args:
3928 if self.unpacked_items:
3929 for arg in self.unpacked_items:
3931 for arg in self.coerced_unpacked_items:
3935 class TupleNode(SequenceNode):
3936 # Tuple constructor.
3940 gil_message = "Constructing Python tuple"
3942 def analyse_types(self, env, skip_children=False):
3943 if len(self.args) == 0:
3947 SequenceNode.analyse_types(self, env, skip_children)
3948 for child in self.args:
3949 if not child.is_literal:
3955 def calculate_result_code(self):
3956 if len(self.args) > 0:
3957 return self.result_code
3959 return Naming.empty_tuple
3961 def calculate_constant_result(self):
3962 self.constant_result = tuple([
3963 arg.constant_result for arg in self.args])
3965 def compile_time_value(self, denv):
3966 values = self.compile_time_value_list(denv)
3968 return tuple(values)
3969 except Exception, e:
3970 self.compile_time_value_error(e)
3972 def generate_operation_code(self, code):
3973 if len(self.args) == 0:
3974 # result_code is Naming.empty_tuple
3977 # non-empty cached tuple => result is global constant,
3978 # creation code goes into separate code writer
3979 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
3980 code = code.get_cached_constants_writer()
3981 code.mark_pos(self.pos)
3984 "%s = PyTuple_New(%s); %s" % (
3987 code.error_goto_if_null(self.result(), self.pos)))
3988 code.put_gotref(self.py_result())
3989 for i in range(len(self.args)):
3991 if not arg.result_in_temp():
3992 code.put_incref(arg.result(), arg.ctype())
3994 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3998 code.put_giveref(arg.py_result())
4000 code.put_giveref(self.py_result())
4002 def generate_subexpr_disposal_code(self, code):
4003 # We call generate_post_assignment_code here instead
4004 # of generate_disposal_code, because values were stored
4005 # in the tuple using a reference-stealing operation.
4006 for arg in self.args:
4007 arg.generate_post_assignment_code(code)
4008 # Should NOT call free_temps -- this is invoked by the default
4009 # generate_evaluation_code which will do that.
4012 class ListNode(SequenceNode):
4015 # obj_conversion_errors [PyrexError] used internally
4016 # orignial_args [ExprNode] used internally
4018 obj_conversion_errors = []
4021 gil_message = "Constructing Python list"
4023 def type_dependencies(self, env):
4026 def infer_type(self, env):
4027 # TOOD: Infer non-object list arrays.
4030 def analyse_expressions(self, env):
4031 SequenceNode.analyse_expressions(self, env)
4032 self.coerce_to_pyobject(env)
4034 def analyse_types(self, env):
4036 self.original_args = list(self.args)
4037 SequenceNode.analyse_types(self, env)
4038 self.obj_conversion_errors = held_errors()
4039 release_errors(ignore=True)
4041 def coerce_to(self, dst_type, env):
4042 if dst_type.is_pyobject:
4043 for err in self.obj_conversion_errors:
4045 self.obj_conversion_errors = []
4046 if not self.type.subtype_of(dst_type):
4047 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4048 elif dst_type.is_ptr:
4049 base_type = dst_type.base_type
4050 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4051 for i in range(len(self.original_args)):
4053 if isinstance(arg, CoerceToPyTypeNode):
4055 self.args[i] = arg.coerce_to(base_type, env)
4056 elif dst_type.is_struct:
4057 if len(self.args) > len(dst_type.scope.var_entries):
4058 error(self.pos, "Too may members for '%s'" % dst_type)
4060 if len(self.args) < len(dst_type.scope.var_entries):
4061 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4062 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4063 if isinstance(arg, CoerceToPyTypeNode):
4065 self.args[i] = arg.coerce_to(member.type, env)
4066 self.type = dst_type
4068 self.type = error_type
4069 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4072 def release_temp(self, env):
4073 if self.type.is_array:
4074 # To be valid C++, we must allocate the memory on the stack
4075 # manually and be sure not to reuse it for something else.
4078 SequenceNode.release_temp(self, env)
4080 def calculate_constant_result(self):
4081 self.constant_result = [
4082 arg.constant_result for arg in self.args]
4084 def compile_time_value(self, denv):
4085 return self.compile_time_value_list(denv)
4087 def generate_operation_code(self, code):
4088 if self.type.is_pyobject:
4089 for err in self.obj_conversion_errors:
4091 code.putln("%s = PyList_New(%s); %s" %
4094 code.error_goto_if_null(self.result(), self.pos)))
4095 code.put_gotref(self.py_result())
4096 for i in range(len(self.args)):
4098 #if not arg.is_temp:
4099 if not arg.result_in_temp():
4100 code.put_incref(arg.result(), arg.ctype())
4101 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4105 code.put_giveref(arg.py_result())
4106 elif self.type.is_array:
4107 for i, arg in enumerate(self.args):
4108 code.putln("%s[%s] = %s;" % (
4112 elif self.type.is_struct:
4113 for arg, member in zip(self.args, self.type.scope.var_entries):
4114 code.putln("%s.%s = %s;" % (
4119 raise InternalError("List type never specified")
4121 def generate_subexpr_disposal_code(self, code):
4122 # We call generate_post_assignment_code here instead
4123 # of generate_disposal_code, because values were stored
4124 # in the list using a reference-stealing operation.
4125 for arg in self.args:
4126 arg.generate_post_assignment_code(code)
4127 # Should NOT call free_temps -- this is invoked by the default
4128 # generate_evaluation_code which will do that.
4131 class ScopedExprNode(ExprNode):
4132 # Abstract base class for ExprNodes that have their own local
4133 # scope, such as generator expressions.
4135 # expr_scope Scope the inner scope of the expression
4140 # does this node really have a local scope, e.g. does it leak loop
4141 # variables or not? non-leaking Py3 behaviour is default, except
4142 # for list comprehensions where the behaviour differs in Py2 and
4143 # Py3 (set in Parsing.py based on parser context)
4144 has_local_scope = True
4146 def init_scope(self, outer_scope, expr_scope=None):
4147 if expr_scope is not None:
4148 self.expr_scope = expr_scope
4149 elif self.has_local_scope:
4150 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4152 self.expr_scope = None
4154 def analyse_declarations(self, env):
4155 self.init_scope(env)
4157 def analyse_scoped_declarations(self, env):
4158 # this is called with the expr_scope as env
4161 def analyse_types(self, env):
4162 # no recursion here, the children will be analysed separately below
4165 def analyse_scoped_expressions(self, env):
4166 # this is called with the expr_scope as env
4169 def generate_evaluation_code(self, code):
4170 # set up local variables and free their references on exit
4171 generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
4172 if not self.has_local_scope or not self.expr_scope.var_entries:
4173 # no local variables => delegate, done
4174 generate_inner_evaluation_code(code)
4177 code.putln('{ /* enter inner scope */')
4179 for entry in self.expr_scope.var_entries:
4180 if not entry.in_closure:
4181 code.put_var_declaration(entry)
4182 if entry.type.is_pyobject and entry.used:
4183 py_entries.append(entry)
4184 code.put_init_var_to_py_none(entry)
4186 # no local Python references => no cleanup required
4187 generate_inner_evaluation_code(code)
4188 code.putln('} /* exit inner scope */')
4191 # must free all local Python references at each exit point
4192 old_loop_labels = tuple(code.new_loop_labels())
4193 old_error_label = code.new_error_label()
4195 generate_inner_evaluation_code(code)
4197 # normal (non-error) exit
4198 for entry in py_entries:
4199 code.put_var_decref(entry)
4201 # error/loop body exit points
4202 exit_scope = code.new_label('exit_scope')
4203 code.put_goto(exit_scope)
4204 for label, old_label in ([(code.error_label, old_error_label)] +
4205 list(zip(code.get_loop_labels(), old_loop_labels))):
4206 if code.label_used(label):
4207 code.put_label(label)
4208 for entry in py_entries:
4209 code.put_var_decref(entry)
4210 code.put_goto(old_label)
4211 code.put_label(exit_scope)
4212 code.putln('} /* exit inner scope */')
4214 code.set_loop_labels(old_loop_labels)
4215 code.error_label = old_error_label
4218 class ComprehensionNode(ScopedExprNode):
4219 subexprs = ["target"]
4220 child_attrs = ["loop", "append"]
4222 def infer_type(self, env):
4223 return self.target.infer_type(env)
4225 def analyse_declarations(self, env):
4226 self.append.target = self # this is used in the PyList_Append of the inner loop
4227 self.init_scope(env)
4229 def analyse_scoped_declarations(self, env):
4230 self.loop.analyse_declarations(env)
4232 def analyse_types(self, env):
4233 self.target.analyse_expressions(env)
4234 self.type = self.target.type
4235 if not self.has_local_scope:
4236 self.loop.analyse_expressions(env)
4238 def analyse_scoped_expressions(self, env):
4239 if self.has_local_scope:
4240 self.loop.analyse_expressions(env)
4242 def may_be_none(self):
4245 def calculate_result_code(self):
4246 return self.target.result()
4248 def generate_result_code(self, code):
4249 self.generate_operation_code(code)
4251 def generate_operation_code(self, code):
4252 self.loop.generate_execution_code(code)
4254 def annotate(self, code):
4255 self.loop.annotate(code)
4258 class ComprehensionAppendNode(Node):
4259 # Need to be careful to avoid infinite recursion:
4260 # target must not be in child_attrs/subexprs
4262 child_attrs = ['expr']
4264 type = PyrexTypes.c_int_type
4266 def analyse_expressions(self, env):
4267 self.expr.analyse_expressions(env)
4268 if not self.expr.type.is_pyobject:
4269 self.expr = self.expr.coerce_to_pyobject(env)
4271 def generate_execution_code(self, code):
4272 if self.target.type is list_type:
4273 function = "PyList_Append"
4274 elif self.target.type is set_type:
4275 function = "PySet_Add"
4277 raise InternalError(
4278 "Invalid type for comprehension node: %s" % self.target.type)
4280 self.expr.generate_evaluation_code(code)
4281 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4283 self.target.result(),
4286 self.expr.generate_disposal_code(code)
4287 self.expr.free_temps(code)
4289 def generate_function_definitions(self, env, code):
4290 self.expr.generate_function_definitions(env, code)
4292 def annotate(self, code):
4293 self.expr.annotate(code)
4295 class DictComprehensionAppendNode(ComprehensionAppendNode):
4296 child_attrs = ['key_expr', 'value_expr']
4298 def analyse_expressions(self, env):
4299 self.key_expr.analyse_expressions(env)
4300 if not self.key_expr.type.is_pyobject:
4301 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4302 self.value_expr.analyse_expressions(env)
4303 if not self.value_expr.type.is_pyobject:
4304 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4306 def generate_execution_code(self, code):
4307 self.key_expr.generate_evaluation_code(code)
4308 self.value_expr.generate_evaluation_code(code)
4309 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4310 self.target.result(),
4311 self.key_expr.result(),
4312 self.value_expr.result()
4314 self.key_expr.generate_disposal_code(code)
4315 self.key_expr.free_temps(code)
4316 self.value_expr.generate_disposal_code(code)
4317 self.value_expr.free_temps(code)
4319 def generate_function_definitions(self, env, code):
4320 self.key_expr.generate_function_definitions(env, code)
4321 self.value_expr.generate_function_definitions(env, code)
4323 def annotate(self, code):
4324 self.key_expr.annotate(code)
4325 self.value_expr.annotate(code)
4328 class GeneratorExpressionNode(ScopedExprNode):
4329 # A generator expression, e.g. (i for i in range(10))
4331 # Result is a generator.
4333 # loop ForStatNode the for-loop, containing a YieldExprNode
4335 child_attrs = ["loop"]
4337 type = py_object_type
4339 def analyse_scoped_declarations(self, env):
4340 self.loop.analyse_declarations(env)
4342 def analyse_types(self, env):
4343 if not self.has_local_scope:
4344 self.loop.analyse_expressions(env)
4347 def analyse_scoped_expressions(self, env):
4348 if self.has_local_scope:
4349 self.loop.analyse_expressions(env)
4351 def may_be_none(self):
4354 def annotate(self, code):
4355 self.loop.annotate(code)
4358 class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
4359 # An inlined generator expression for which the result is
4360 # calculated inside of the loop. This will only be created by
4361 # transforms when replacing builtin calls on generator
4364 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4365 # result_node ResultRefNode the reference to the result value temp
4366 # orig_func String the name of the builtin function this node replaces
4368 child_attrs = ["loop"]
4369 loop_analysed = False
4371 def infer_type(self, env):
4372 return self.result_node.infer_type(env)
4374 def analyse_types(self, env):
4375 if not self.has_local_scope:
4376 self.loop_analysed = True
4377 self.loop.analyse_expressions(env)
4378 self.type = self.result_node.type
4381 def analyse_scoped_expressions(self, env):
4382 self.loop_analysed = True
4383 GeneratorExpressionNode.analyse_scoped_expressions(self, env)
4385 def coerce_to(self, dst_type, env):
4386 if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
4387 # We can optimise by dropping the aggregation variable and
4388 # the add operations into C. This can only be done safely
4389 # before analysing the loop body, after that, the result
4390 # reference type will have infected expressions and
4392 self.result_node.type = self.type = dst_type
4394 return GeneratorExpressionNode.coerce_to(self, dst_type, env)
4396 def generate_result_code(self, code):
4397 self.result_node.result_code = self.result()
4398 self.loop.generate_execution_code(code)
4401 class SetNode(ExprNode):
4408 gil_message = "Constructing Python set"
4410 def analyse_types(self, env):
4411 for i in range(len(self.args)):
4413 arg.analyse_types(env)
4414 self.args[i] = arg.coerce_to_pyobject(env)
4415 self.type = set_type
4418 def may_be_none(self):
4421 def calculate_constant_result(self):
4422 self.constant_result = set([
4423 arg.constant_result for arg in self.args])
4425 def compile_time_value(self, denv):
4426 values = [arg.compile_time_value(denv) for arg in self.args]
4429 except Exception, e:
4430 self.compile_time_value_error(e)
4432 def generate_evaluation_code(self, code):
4433 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4434 self.allocate_temp_result(code)
4436 "%s = PySet_New(0); %s" % (
4438 code.error_goto_if_null(self.result(), self.pos)))
4439 code.put_gotref(self.py_result())
4440 for arg in self.args:
4441 arg.generate_evaluation_code(code)
4443 code.error_goto_if_neg(
4444 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4446 arg.generate_disposal_code(code)
4447 arg.free_temps(code)
4450 class DictNode(ExprNode):
4451 # Dictionary constructor.
4453 # key_value_pairs [DictItemNode]
4455 # obj_conversion_errors [PyrexError] used internally
4457 subexprs = ['key_value_pairs']
4461 obj_conversion_errors = []
4463 def calculate_constant_result(self):
4464 self.constant_result = dict([
4465 item.constant_result for item in self.key_value_pairs])
4467 def compile_time_value(self, denv):
4468 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4469 for item in self.key_value_pairs]
4472 except Exception, e:
4473 self.compile_time_value_error(e)
4475 def type_dependencies(self, env):
4478 def infer_type(self, env):
4479 # TOOD: Infer struct constructors.
4482 def analyse_types(self, env):
4484 for item in self.key_value_pairs:
4485 item.analyse_types(env)
4486 self.obj_conversion_errors = held_errors()
4487 release_errors(ignore=True)
4489 def may_be_none(self):
4492 def coerce_to(self, dst_type, env):
4493 if dst_type.is_pyobject:
4494 self.release_errors()
4495 if not self.type.subtype_of(dst_type):
4496 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4497 elif dst_type.is_struct_or_union:
4498 self.type = dst_type
4499 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4500 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4501 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4502 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4503 for item in self.key_value_pairs:
4504 if isinstance(item.key, CoerceToPyTypeNode):
4505 item.key = item.key.arg
4506 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4507 error(item.key.pos, "Invalid struct field identifier")
4508 item.key = StringNode(item.key.pos, value="<error>")
4510 key = str(item.key.value) # converts string literals to unicode in Py3
4511 member = dst_type.scope.lookup_here(key)
4513 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4516 if isinstance(value, CoerceToPyTypeNode):
4518 item.value = value.coerce_to(member.type, env)
4520 self.type = error_type
4521 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4524 def release_errors(self):
4525 for err in self.obj_conversion_errors:
4527 self.obj_conversion_errors = []
4529 gil_message = "Constructing Python dict"
4531 def generate_evaluation_code(self, code):
4532 # Custom method used here because key-value
4533 # pairs are evaluated and used one at a time.
4534 code.mark_pos(self.pos)
4535 self.allocate_temp_result(code)
4536 if self.type.is_pyobject:
4537 self.release_errors()
4539 "%s = PyDict_New(); %s" % (
4541 code.error_goto_if_null(self.result(), self.pos)))
4542 code.put_gotref(self.py_result())
4543 for item in self.key_value_pairs:
4544 item.generate_evaluation_code(code)
4545 if self.type.is_pyobject:
4546 code.put_error_if_neg(self.pos,
4547 "PyDict_SetItem(%s, %s, %s)" % (
4549 item.key.py_result(),
4550 item.value.py_result()))
4552 code.putln("%s.%s = %s;" % (
4555 item.value.result()))
4556 item.generate_disposal_code(code)
4557 item.free_temps(code)
4559 def annotate(self, code):
4560 for item in self.key_value_pairs:
4563 class DictItemNode(ExprNode):
4564 # Represents a single item in a DictNode
4568 subexprs = ['key', 'value']
4570 nogil_check = None # Parent DictNode takes care of it
4572 def calculate_constant_result(self):
4573 self.constant_result = (
4574 self.key.constant_result, self.value.constant_result)
4576 def analyse_types(self, env):
4577 self.key.analyse_types(env)
4578 self.value.analyse_types(env)
4579 self.key = self.key.coerce_to_pyobject(env)
4580 self.value = self.value.coerce_to_pyobject(env)
4582 def generate_evaluation_code(self, code):
4583 self.key.generate_evaluation_code(code)
4584 self.value.generate_evaluation_code(code)
4586 def generate_disposal_code(self, code):
4587 self.key.generate_disposal_code(code)
4588 self.value.generate_disposal_code(code)
4590 def free_temps(self, code):
4591 self.key.free_temps(code)
4592 self.value.free_temps(code)
4595 return iter([self.key, self.value])
4597 class ModuleNameMixin(object):
4598 def set_mod_name(self, env):
4599 self.module_name = env.global_scope().qualified_name
4601 def get_py_mod_name(self, code):
4602 return code.get_py_string_const(
4603 self.module_name, identifier=True)
4605 class ClassNode(ExprNode, ModuleNameMixin):
4606 # Helper class used in the implementation of Python
4607 # class definitions. Constructs a class object given
4608 # a name, tuple of bases and class dictionary.
4610 # name EncodedString Name of the class
4611 # bases ExprNode Base class tuple
4612 # dict ExprNode Class dict (not owned by this node)
4613 # doc ExprNode or None Doc string
4614 # module_name EncodedString Name of defining module
4616 subexprs = ['bases', 'doc']
4618 def analyse_types(self, env):
4619 self.bases.analyse_types(env)
4621 self.doc.analyse_types(env)
4622 self.doc = self.doc.coerce_to_pyobject(env)
4623 self.type = py_object_type
4625 env.use_utility_code(create_class_utility_code);
4626 #TODO(craig,haoyu) This should be moved to a better place
4627 self.set_mod_name(env)
4629 def may_be_none(self):
4632 gil_message = "Constructing Python class"
4634 def generate_result_code(self, code):
4635 cname = code.intern_identifier(self.name)
4638 code.put_error_if_neg(self.pos,
4639 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4640 self.dict.py_result(),
4641 self.doc.py_result()))
4642 py_mod_name = self.get_py_mod_name(code)
4644 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4646 self.bases.py_result(),
4647 self.dict.py_result(),
4650 code.error_goto_if_null(self.result(), self.pos)))
4651 code.put_gotref(self.py_result())
4654 class Py3ClassNode(ExprNode):
4655 # Helper class used in the implementation of Python3+
4656 # class definitions. Constructs a class object given
4657 # a name, tuple of bases and class dictionary.
4659 # name EncodedString Name of the class
4660 # dict ExprNode Class dict (not owned by this node)
4661 # module_name EncodedString Name of defining module
4665 def analyse_types(self, env):
4666 self.type = py_object_type
4669 def may_be_none(self):
4672 gil_message = "Constructing Python class"
4674 def generate_result_code(self, code):
4675 code.globalstate.use_utility_code(create_py3class_utility_code)
4676 cname = code.intern_identifier(self.name)
4678 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4680 self.metaclass.result(),
4682 self.bases.py_result(),
4683 self.dict.py_result(),
4684 self.mkw.py_result(),
4685 code.error_goto_if_null(self.result(), self.pos)))
4686 code.put_gotref(self.py_result())
4688 class KeywordArgsNode(ExprNode):
4689 # Helper class for keyword arguments
4691 # keyword_args ExprNode or None Keyword arguments
4692 # starstar_arg ExprNode or None Extra arguments
4694 subexprs = ['keyword_args', 'starstar_arg']
4696 def analyse_types(self, env):
4697 if self.keyword_args:
4698 self.keyword_args.analyse_types(env)
4699 if self.starstar_arg:
4700 self.starstar_arg.analyse_types(env)
4701 # make sure we have a Python object as **kwargs mapping
4702 self.starstar_arg = \
4703 self.starstar_arg.coerce_to_pyobject(env)
4704 self.type = py_object_type
4707 gil_message = "Constructing Keyword Args"
4709 def generate_result_code(self, code):
4710 if self.keyword_args and self.starstar_arg:
4711 code.put_error_if_neg(self.pos,
4712 "PyDict_Update(%s, %s)" % (
4713 self.keyword_args.py_result(),
4714 self.starstar_arg.py_result()))
4715 if self.keyword_args:
4716 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4717 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4718 elif self.starstar_arg:
4720 "%s = PyDict_Copy(%s); %s" % (
4722 self.starstar_arg.py_result(),
4723 code.error_goto_if_null(self.result(), self.pos)))
4724 code.put_gotref(self.py_result())
4727 "%s = PyDict_New(); %s" % (
4729 code.error_goto_if_null(self.result(), self.pos)))
4730 code.put_gotref(self.py_result())
4732 class PyClassMetaclassNode(ExprNode):
4733 # Helper class holds Python3 metaclass object
4735 # bases ExprNode Base class tuple (not owned by this node)
4736 # mkw ExprNode Class keyword arguments (not owned by this node)
4740 def analyse_types(self, env):
4741 self.type = py_object_type
4744 def may_be_none(self):
4747 def generate_result_code(self, code):
4749 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4751 self.bases.result(),
4753 code.error_goto_if_null(self.result(), self.pos)))
4754 code.put_gotref(self.py_result())
4756 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4757 # Helper class holds Python3 namespace object
4759 # All this are not owned by this node
4760 # metaclass ExprNode Metaclass object
4761 # bases ExprNode Base class tuple
4762 # mkw ExprNode Class keyword arguments
4763 # doc ExprNode or None Doc string (owned)
4767 def analyse_types(self, env):
4768 self.bases.analyse_types(env)
4770 self.doc.analyse_types(env)
4771 self.doc = self.doc.coerce_to_pyobject(env)
4772 self.type = py_object_type
4774 #TODO(craig,haoyu) This should be moved to a better place
4775 self.set_mod_name(env)
4777 def may_be_none(self):
4780 def generate_result_code(self, code):
4781 cname = code.intern_identifier(self.name)
4782 py_mod_name = self.get_py_mod_name(code)
4784 doc_code = self.doc.result()
4786 doc_code = '(PyObject *) NULL'
4788 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4790 self.metaclass.result(),
4791 self.bases.result(),
4796 code.error_goto_if_null(self.result(), self.pos)))
4797 code.put_gotref(self.py_result())
4799 class BoundMethodNode(ExprNode):
4800 # Helper class used in the implementation of Python
4801 # class definitions. Constructs an bound method
4802 # object from a class and a function.
4804 # function ExprNode Function object
4805 # self_object ExprNode self object
4807 subexprs = ['function']
4809 def analyse_types(self, env):
4810 self.function.analyse_types(env)
4811 self.type = py_object_type
4814 gil_message = "Constructing an bound method"
4816 def generate_result_code(self, code):
4818 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4820 self.function.py_result(),
4821 self.self_object.py_result(),
4822 self.self_object.py_result(),
4823 code.error_goto_if_null(self.result(), self.pos)))
4824 code.put_gotref(self.py_result())
4826 class UnboundMethodNode(ExprNode):
4827 # Helper class used in the implementation of Python
4828 # class definitions. Constructs an unbound method
4829 # object from a class and a function.
4831 # function ExprNode Function object
4833 type = py_object_type
4836 subexprs = ['function']
4838 def analyse_types(self, env):
4839 self.function.analyse_types(env)
4841 def may_be_none(self):
4844 gil_message = "Constructing an unbound method"
4846 def generate_result_code(self, code):
4847 class_cname = code.pyclass_stack[-1].classobj.result()
4849 "%s = PyMethod_New(%s, 0, %s); %s" % (
4851 self.function.py_result(),
4853 code.error_goto_if_null(self.result(), self.pos)))
4854 code.put_gotref(self.py_result())
4857 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4858 # Helper class used in the implementation of Python
4859 # class definitions. Constructs a PyCFunction object
4860 # from a PyMethodDef struct.
4862 # pymethdef_cname string PyMethodDef structure
4863 # self_object ExprNode or None
4865 # module_name EncodedString Name of defining module
4871 type = py_object_type
4874 def analyse_types(self, env):
4876 env.use_utility_code(binding_cfunc_utility_code)
4878 #TODO(craig,haoyu) This should be moved to a better place
4879 self.set_mod_name(env)
4881 def may_be_none(self):
4884 gil_message = "Constructing Python function"
4886 def self_result_code(self):
4887 if self.self_object is None:
4888 self_result = "NULL"
4890 self_result = self.self_object.py_result()
4893 def generate_result_code(self, code):
4895 constructor = "%s_NewEx" % Naming.binding_cfunc
4897 constructor = "PyCFunction_NewEx"
4898 py_mod_name = self.get_py_mod_name(code)
4900 '%s = %s(&%s, %s, %s); %s' % (
4903 self.pymethdef_cname,
4904 self.self_result_code(),
4906 code.error_goto_if_null(self.result(), self.pos)))
4907 code.put_gotref(self.py_result())
4909 class InnerFunctionNode(PyCFunctionNode):
4910 # Special PyCFunctionNode that depends on a closure class
4914 needs_self_code = True
4916 def self_result_code(self):
4917 if self.needs_self_code:
4918 return "((PyObject*)%s)" % (Naming.cur_scope_cname)
4921 class LambdaNode(InnerFunctionNode):
4922 # Lambda expression node (only used as a function reference)
4924 # args [CArgDeclNode] formal arguments
4925 # star_arg PyArgDeclNode or None * argument
4926 # starstar_arg PyArgDeclNode or None ** argument
4927 # lambda_name string a module-globally unique lambda name
4928 # result_expr ExprNode
4929 # def_node DefNode the underlying function 'def' node
4931 child_attrs = ['def_node']
4934 name = StringEncoding.EncodedString('<lambda>')
4936 def analyse_declarations(self, env):
4937 self.def_node.analyse_declarations(env)
4938 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
4939 env.add_lambda_def(self.def_node)
4942 class OldYieldExprNode(ExprNode):
4943 # XXX: remove me someday
4945 # arg ExprNode the value to return from the generator
4946 # label_name string name of the C label used for this yield
4949 type = py_object_type
4951 def analyse_types(self, env):
4953 if self.arg is not None:
4954 self.arg.analyse_types(env)
4955 if not self.arg.type.is_pyobject:
4956 self.arg = self.arg.coerce_to_pyobject(env)
4957 error(self.pos, "Generators are not supported")
4959 def generate_result_code(self, code):
4960 self.label_name = code.new_label('resume_from_yield')
4961 code.use_label(self.label_name)
4962 code.putln("/* FIXME: save temporary variables */")
4963 code.putln("/* FIXME: return from function, yielding value */")
4964 code.put_label(self.label_name)
4965 code.putln("/* FIXME: restore temporary variables and */")
4966 code.putln("/* FIXME: extract sent value from closure */")
4968 class YieldExprNode(ExprNode):
4969 # Yield expression node
4971 # arg ExprNode the value to return from the generator
4972 # label_name string name of the C label used for this yield
4975 type = py_object_type
4977 def analyse_types(self, env):
4979 if self.arg is not None:
4980 self.arg.analyse_types(env)
4981 if not self.arg.type.is_pyobject:
4982 self.arg = self.arg.coerce_to_pyobject(env)
4983 env.use_utility_code(generator_utility_code)
4985 def generate_evaluation_code(self, code):
4987 self.temp_allocator.reset()
4988 code.putln('/* Save temporary variables */')
4989 for cname, type, manage_ref in code.funcstate.temps_in_use():
4990 save_cname = self.temp_allocator.allocate_temp(type)
4991 saved.append((cname, save_cname, type))
4992 code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
4993 if type.is_pyobject:
4994 code.put_giveref(cname)
4995 self.label_name = code.new_label('resume_from_yield')
4996 code.use_label(self.label_name)
4997 self.allocate_temp_result(code)
4999 self.arg.generate_evaluation_code(code)
5000 self.arg.make_owned_reference(code)
5003 Naming.retval_cname,
5004 self.arg.result_as(py_object_type)))
5005 self.arg.generate_post_assignment_code(code)
5006 #self.arg.generate_disposal_code(code)
5007 self.arg.free_temps(code)
5009 code.put_init_to_py_none(Naming.retval_cname, py_object_type)
5011 code.put_finish_refcount_context()
5012 code.putln("/* return from function, yielding value */")
5013 code.putln("%s->%s.resume_label = %d;" % (Naming.cur_scope_cname, Naming.obj_base_cname, self.label_num))
5014 code.putln("return %s;" % Naming.retval_cname);
5015 code.put_label(self.label_name)
5016 code.putln('/* Restore temporary variables */')
5017 for cname, save_cname, type in saved:
5018 code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
5019 if type.is_pyobject:
5020 code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
5021 code.put_gotref(cname)
5022 code.putln('%s = __pyx_send_value;' % self.result())
5023 code.put_incref(self.result(), py_object_type)
5025 class StopIterationNode(YieldExprNode):
5028 def generate_evaluation_code(self, code):
5029 self.allocate_temp_result(code)
5030 self.label_name = code.new_label('resume_from_yield')
5031 code.use_label(self.label_name)
5032 code.put_label(self.label_name)
5033 code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
5035 #-------------------------------------------------------------------
5037 # Unary operator nodes
5039 #-------------------------------------------------------------------
5041 compile_time_unary_operators = {
5042 'not': operator.not_,
5048 class UnopNode(ExprNode):
5052 # Processing during analyse_expressions phase:
5054 # analyse_c_operation
5055 # Called when the operand is not a pyobject.
5056 # - Check operand type and coerce if needed.
5057 # - Determine result type and result code fragment.
5058 # - Allocate temporary for result if needed.
5060 subexprs = ['operand']
5063 def calculate_constant_result(self):
5064 func = compile_time_unary_operators[self.operator]
5065 self.constant_result = func(self.operand.constant_result)
5067 def compile_time_value(self, denv):
5068 func = compile_time_unary_operators.get(self.operator)
5071 "Unary '%s' not supported in compile-time expression"
5073 operand = self.operand.compile_time_value(denv)
5075 return func(operand)
5076 except Exception, e:
5077 self.compile_time_value_error(e)
5079 def infer_type(self, env):
5080 operand_type = self.operand.infer_type(env)
5081 if operand_type.is_pyobject:
5082 return py_object_type
5086 def analyse_types(self, env):
5087 self.operand.analyse_types(env)
5088 if self.is_py_operation():
5089 self.coerce_operand_to_pyobject(env)
5090 self.type = py_object_type
5092 elif self.is_cpp_operation():
5093 self.analyse_cpp_operation(env)
5095 self.analyse_c_operation(env)
5097 def check_const(self):
5098 return self.operand.check_const()
5100 def is_py_operation(self):
5101 return self.operand.type.is_pyobject
5103 def nogil_check(self, env):
5104 if self.is_py_operation():
5107 def is_cpp_operation(self):
5108 type = self.operand.type
5109 return type.is_cpp_class
5111 def coerce_operand_to_pyobject(self, env):
5112 self.operand = self.operand.coerce_to_pyobject(env)
5114 def generate_result_code(self, code):
5115 if self.operand.type.is_pyobject:
5116 self.generate_py_operation_code(code)
5118 def generate_py_operation_code(self, code):
5119 function = self.py_operation_function()
5121 "%s = %s(%s); %s" % (
5124 self.operand.py_result(),
5125 code.error_goto_if_null(self.result(), self.pos)))
5126 code.put_gotref(self.py_result())
5128 def type_error(self):
5129 if not self.operand.type.is_error:
5130 error(self.pos, "Invalid operand type for '%s' (%s)" %
5131 (self.operator, self.operand.type))
5132 self.type = PyrexTypes.error_type
5134 def analyse_cpp_operation(self, env):
5135 type = self.operand.type
5137 type = type.base_type
5138 function = type.scope.lookup("operator%s" % self.operator)
5140 error(self.pos, "'%s' operator not defined for %s"
5141 % (self.operator, type))
5144 func_type = function.type
5145 if func_type.is_ptr:
5146 func_type = func_type.base_type
5147 self.type = func_type.return_type
5150 class NotNode(ExprNode):
5155 type = PyrexTypes.c_bint_type
5157 subexprs = ['operand']
5159 def calculate_constant_result(self):
5160 self.constant_result = not self.operand.constant_result
5162 def compile_time_value(self, denv):
5163 operand = self.operand.compile_time_value(denv)
5166 except Exception, e:
5167 self.compile_time_value_error(e)
5169 def infer_type(self, env):
5170 return PyrexTypes.c_bint_type
5172 def analyse_types(self, env):
5173 self.operand.analyse_types(env)
5174 self.operand = self.operand.coerce_to_boolean(env)
5176 def calculate_result_code(self):
5177 return "(!%s)" % self.operand.result()
5179 def generate_result_code(self, code):
5183 class UnaryPlusNode(UnopNode):
5184 # unary '+' operator
5188 def analyse_c_operation(self, env):
5189 self.type = self.operand.type
5191 def py_operation_function(self):
5192 return "PyNumber_Positive"
5194 def calculate_result_code(self):
5195 if self.is_cpp_operation():
5196 return "(+%s)" % self.operand.result()
5198 return self.operand.result()
5201 class UnaryMinusNode(UnopNode):
5202 # unary '-' operator
5206 def analyse_c_operation(self, env):
5207 if self.operand.type.is_numeric:
5208 self.type = self.operand.type
5211 if self.type.is_complex:
5214 def py_operation_function(self):
5215 return "PyNumber_Negative"
5217 def calculate_result_code(self):
5219 return "(-%s)" % self.operand.result()
5221 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5223 def get_constant_c_result_code(self):
5224 value = self.operand.get_constant_c_result_code()
5226 return "(-%s)" % (value)
5228 class TildeNode(UnopNode):
5229 # unary '~' operator
5231 def analyse_c_operation(self, env):
5232 if self.operand.type.is_int:
5233 self.type = self.operand.type
5237 def py_operation_function(self):
5238 return "PyNumber_Invert"
5240 def calculate_result_code(self):
5241 return "(~%s)" % self.operand.result()
5244 class CUnopNode(UnopNode):
5246 def is_py_operation(self):
5249 class DereferenceNode(CUnopNode):
5254 def analyse_c_operation(self, env):
5255 if self.operand.type.is_ptr:
5256 self.type = self.operand.type.base_type
5260 def calculate_result_code(self):
5261 return "(*%s)" % self.operand.result()
5264 class DecrementIncrementNode(CUnopNode):
5265 # unary ++/-- operator
5267 def analyse_c_operation(self, env):
5268 if self.operand.type.is_ptr or self.operand.type.is_numeric:
5269 self.type = self.operand.type
5273 def calculate_result_code(self):
5275 return "(%s%s)" % (self.operator, self.operand.result())
5277 return "(%s%s)" % (self.operand.result(), self.operator)
5279 def inc_dec_constructor(is_prefix, operator):
5280 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5283 class AmpersandNode(ExprNode):
5284 # The C address-of operator.
5288 subexprs = ['operand']
5290 def infer_type(self, env):
5291 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5293 def analyse_types(self, env):
5294 self.operand.analyse_types(env)
5295 argtype = self.operand.type
5296 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5297 self.error("Taking address of non-lvalue")
5299 if argtype.is_pyobject:
5300 self.error("Cannot take address of Python variable")
5302 self.type = PyrexTypes.c_ptr_type(argtype)
5304 def check_const(self):
5305 return self.operand.check_const_addr()
5307 def error(self, mess):
5308 error(self.pos, mess)
5309 self.type = PyrexTypes.error_type
5310 self.result_code = "<error>"
5312 def calculate_result_code(self):
5313 return "(&%s)" % self.operand.result()
5315 def generate_result_code(self, code):
5319 unop_node_classes = {
5321 "-": UnaryMinusNode,
5325 def unop_node(pos, operator, operand):
5326 # Construct unnop node of appropriate class for
5328 if isinstance(operand, IntNode) and operator == '-':
5329 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5330 elif isinstance(operand, UnopNode) and operand.operator == operator:
5331 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5332 return unop_node_classes[operator](pos,
5333 operator = operator,
5337 class TypecastNode(ExprNode):
5341 # base_type CBaseTypeNode
5342 # declarator CDeclaratorNode
5344 # If used from a transform, one can if wanted specify the attribute
5345 # "type" directly and leave base_type and declarator to None
5347 subexprs = ['operand']
5348 base_type = declarator = type = None
5350 def type_dependencies(self, env):
5353 def infer_type(self, env):
5354 if self.type is None:
5355 base_type = self.base_type.analyse(env)
5356 _, self.type = self.declarator.analyse(base_type, env)
5359 def analyse_types(self, env):
5360 if self.type is None:
5361 base_type = self.base_type.analyse(env)
5362 _, self.type = self.declarator.analyse(base_type, env)
5363 if self.type.is_cfunction:
5365 "Cannot cast to a function type")
5366 self.type = PyrexTypes.error_type
5367 self.operand.analyse_types(env)
5368 to_py = self.type.is_pyobject
5369 from_py = self.operand.type.is_pyobject
5370 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5371 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5372 if to_py and not from_py:
5373 if self.type is bytes_type and self.operand.type.is_int:
5374 # FIXME: the type cast node isn't needed in this case
5375 # and can be dropped once analyse_types() can return a
5377 self.operand = CoerceIntToBytesNode(self.operand, env)
5378 elif self.operand.type.can_coerce_to_pyobject(env):
5379 self.result_ctype = py_object_type
5380 self.operand = self.operand.coerce_to_pyobject(env)
5382 if self.operand.type.is_ptr:
5383 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5384 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5386 # Should this be an error?
5387 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5388 self.operand = self.operand.coerce_to_simple(env)
5389 elif from_py and not to_py:
5390 if self.type.create_from_py_utility_code(env):
5391 self.operand = self.operand.coerce_to(self.type, env)
5392 elif self.type.is_ptr:
5393 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5394 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5396 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5397 elif from_py and to_py:
5398 if self.typecheck and self.type.is_extension_type:
5399 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5400 elif self.type.is_complex and self.operand.type.is_complex:
5401 self.operand = self.operand.coerce_to_simple(env)
5403 def nogil_check(self, env):
5404 if self.type and self.type.is_pyobject and self.is_temp:
5407 def check_const(self):
5408 return self.operand.check_const()
5410 def calculate_constant_result(self):
5411 # we usually do not know the result of a type cast at code
5415 def calculate_result_code(self):
5416 if self.type.is_complex:
5417 operand_result = self.operand.result()
5418 if self.operand.type.is_complex:
5419 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5420 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5422 real_part = self.type.real_type.cast_code(operand_result)
5424 return "%s(%s, %s)" % (
5425 self.type.from_parts,
5429 return self.type.cast_code(self.operand.result())
5431 def get_constant_c_result_code(self):
5432 operand_result = self.operand.get_constant_c_result_code()
5434 return self.type.cast_code(operand_result)
5436 def result_as(self, type):
5437 if self.type.is_pyobject and not self.is_temp:
5438 # Optimise away some unnecessary casting
5439 return self.operand.result_as(type)
5441 return ExprNode.result_as(self, type)
5443 def generate_result_code(self, code):
5446 "%s = (PyObject *)%s;" % (
5448 self.operand.result()))
5449 code.put_incref(self.result(), self.ctype())
5452 class SizeofNode(ExprNode):
5453 # Abstract base class for sizeof(x) expression nodes.
5455 type = PyrexTypes.c_size_t_type
5457 def check_const(self):
5460 def generate_result_code(self, code):
5464 class SizeofTypeNode(SizeofNode):
5465 # C sizeof function applied to a type
5467 # base_type CBaseTypeNode
5468 # declarator CDeclaratorNode
5473 def analyse_types(self, env):
5474 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5475 # this could be better handled by more uniformly treating types as runtime-available objects
5476 if 0 and self.base_type.module_path:
5477 path = self.base_type.module_path
5478 obj = env.lookup(path[0])
5479 if obj.as_module is None:
5480 operand = NameNode(pos=self.pos, name=path[0])
5481 for attr in path[1:]:
5482 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5483 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5484 self.operand = operand
5485 self.__class__ = SizeofVarNode
5486 self.analyse_types(env)
5488 if self.arg_type is None:
5489 base_type = self.base_type.analyse(env)
5490 _, arg_type = self.declarator.analyse(base_type, env)
5491 self.arg_type = arg_type
5494 def check_type(self):
5495 arg_type = self.arg_type
5496 if arg_type.is_pyobject and not arg_type.is_extension_type:
5497 error(self.pos, "Cannot take sizeof Python object")
5498 elif arg_type.is_void:
5499 error(self.pos, "Cannot take sizeof void")
5500 elif not arg_type.is_complete():
5501 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5503 def calculate_result_code(self):
5504 if self.arg_type.is_extension_type:
5505 # the size of the pointer is boring
5506 # we want the size of the actual struct
5507 arg_code = self.arg_type.declaration_code("", deref=1)
5509 arg_code = self.arg_type.declaration_code("")
5510 return "(sizeof(%s))" % arg_code
5513 class SizeofVarNode(SizeofNode):
5514 # C sizeof function applied to a variable
5518 subexprs = ['operand']
5520 def analyse_types(self, env):
5521 # We may actually be looking at a type rather than a variable...
5522 # If we are, traditional analysis would fail...
5523 operand_as_type = self.operand.analyse_as_type(env)
5525 self.arg_type = operand_as_type
5526 self.__class__ = SizeofTypeNode
5529 self.operand.analyse_types(env)
5531 def calculate_result_code(self):
5532 return "(sizeof(%s))" % self.operand.result()
5534 def generate_result_code(self, code):
5537 class TypeofNode(ExprNode):
5538 # Compile-time type of an expression, as a string.
5541 # literal StringNode # internal
5544 type = py_object_type
5546 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5548 def analyse_types(self, env):
5549 self.operand.analyse_types(env)
5550 self.literal = StringNode(
5551 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5552 self.literal.analyse_types(env)
5553 self.literal = self.literal.coerce_to_pyobject(env)
5555 def may_be_none(self):
5558 def generate_evaluation_code(self, code):
5559 self.literal.generate_evaluation_code(code)
5561 def calculate_result_code(self):
5562 return self.literal.calculate_result_code()
5564 #-------------------------------------------------------------------
5566 # Binary operator nodes
5568 #-------------------------------------------------------------------
5570 def _not_in(x, seq):
5573 compile_time_binary_operators = {
5581 'is_not': operator.is_not,
5584 '/': operator.truediv,
5585 '//': operator.floordiv,
5586 '<<': operator.lshift,
5591 '>>': operator.rshift,
5594 'in': operator.contains,
5598 def get_compile_time_binop(node):
5599 func = compile_time_binary_operators.get(node.operator)
5602 "Binary '%s' not supported in compile-time expression"
5606 class BinopNode(ExprNode):
5611 # Processing during analyse_expressions phase:
5613 # analyse_c_operation
5614 # Called when neither operand is a pyobject.
5615 # - Check operand types and coerce if needed.
5616 # - Determine result type and result code fragment.
5617 # - Allocate temporary for result if needed.
5619 subexprs = ['operand1', 'operand2']
5622 def calculate_constant_result(self):
5623 func = compile_time_binary_operators[self.operator]
5624 self.constant_result = func(
5625 self.operand1.constant_result,
5626 self.operand2.constant_result)
5628 def compile_time_value(self, denv):
5629 func = get_compile_time_binop(self)
5630 operand1 = self.operand1.compile_time_value(denv)
5631 operand2 = self.operand2.compile_time_value(denv)
5633 return func(operand1, operand2)
5634 except Exception, e:
5635 self.compile_time_value_error(e)
5637 def infer_type(self, env):
5638 return self.result_type(self.operand1.infer_type(env),
5639 self.operand2.infer_type(env))
5641 def analyse_types(self, env):
5642 self.operand1.analyse_types(env)
5643 self.operand2.analyse_types(env)
5644 self.analyse_operation(env)
5646 def analyse_operation(self, env):
5647 if self.is_py_operation():
5648 self.coerce_operands_to_pyobjects(env)
5649 self.type = self.result_type(self.operand1.type,
5651 assert self.type.is_pyobject
5653 elif self.is_cpp_operation():
5654 self.analyse_cpp_operation(env)
5656 self.analyse_c_operation(env)
5658 def is_py_operation(self):
5659 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5661 def is_py_operation_types(self, type1, type2):
5662 return type1.is_pyobject or type2.is_pyobject
5664 def is_cpp_operation(self):
5665 return (self.operand1.type.is_cpp_class
5666 or self.operand2.type.is_cpp_class)
5668 def analyse_cpp_operation(self, env):
5669 type1 = self.operand1.type
5670 type2 = self.operand2.type
5671 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5675 func_type = entry.type
5676 if func_type.is_ptr:
5677 func_type = func_type.base_type
5678 if len(func_type.args) == 1:
5679 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5681 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5682 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5683 self.type = func_type.return_type
5685 def result_type(self, type1, type2):
5686 if self.is_py_operation_types(type1, type2):
5688 type2 = Builtin.bytes_type
5690 type1 = Builtin.bytes_type
5691 elif self.operator == '%' \
5692 and type1 in (Builtin.str_type, Builtin.unicode_type):
5693 # note that b'%s' % b'abc' doesn't work in Py3
5695 if type1.is_builtin_type:
5697 if self.operator in '**%+|&^':
5698 # FIXME: at least these operators should be safe - others?
5700 elif self.operator == '*':
5701 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5703 # multiplication of containers/numbers with an
5704 # integer value always (?) returns the same type
5707 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5708 # multiplication of containers/numbers with an
5709 # integer value always (?) returns the same type
5711 return py_object_type
5713 return self.compute_c_result_type(type1, type2)
5715 def nogil_check(self, env):
5716 if self.is_py_operation():
5719 def coerce_operands_to_pyobjects(self, env):
5720 self.operand1 = self.operand1.coerce_to_pyobject(env)
5721 self.operand2 = self.operand2.coerce_to_pyobject(env)
5723 def check_const(self):
5724 return self.operand1.check_const() and self.operand2.check_const()
5726 def generate_result_code(self, code):
5727 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5728 if self.operand1.type.is_pyobject:
5729 function = self.py_operation_function()
5730 if self.operator == '**':
5731 extra_args = ", Py_None"
5735 "%s = %s(%s, %s%s); %s" % (
5738 self.operand1.py_result(),
5739 self.operand2.py_result(),
5741 code.error_goto_if_null(self.result(), self.pos)))
5742 code.put_gotref(self.py_result())
5744 def type_error(self):
5745 if not (self.operand1.type.is_error
5746 or self.operand2.type.is_error):
5747 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5748 (self.operator, self.operand1.type,
5749 self.operand2.type))
5750 self.type = PyrexTypes.error_type
5753 class CBinopNode(BinopNode):
5755 def analyse_types(self, env):
5756 BinopNode.analyse_types(self, env)
5757 if self.is_py_operation():
5758 self.type = PyrexTypes.error_type
5760 def py_operation_function():
5763 def calculate_result_code(self):
5764 return "(%s %s %s)" % (
5765 self.operand1.result(),
5767 self.operand2.result())
5770 def c_binop_constructor(operator):
5771 def make_binop_node(pos, **operands):
5772 return CBinopNode(pos, operator=operator, **operands)
5773 return make_binop_node
5775 class NumBinopNode(BinopNode):
5776 # Binary operation taking numeric arguments.
5780 def analyse_c_operation(self, env):
5781 type1 = self.operand1.type
5782 type2 = self.operand2.type
5783 self.type = self.compute_c_result_type(type1, type2)
5787 if self.type.is_complex:
5789 if not self.infix or (type1.is_numeric and type2.is_numeric):
5790 self.operand1 = self.operand1.coerce_to(self.type, env)
5791 self.operand2 = self.operand2.coerce_to(self.type, env)
5793 def compute_c_result_type(self, type1, type2):
5794 if self.c_types_okay(type1, type2):
5795 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5796 if widest_type is PyrexTypes.c_bint_type:
5797 if self.operator not in '|^&':
5798 # False + False == 0 # not False!
5799 widest_type = PyrexTypes.c_int_type
5804 def get_constant_c_result_code(self):
5805 value1 = self.operand1.get_constant_c_result_code()
5806 value2 = self.operand2.get_constant_c_result_code()
5807 if value1 and value2:
5808 return "(%s %s %s)" % (value1, self.operator, value2)
5812 def c_types_okay(self, type1, type2):
5813 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5814 return (type1.is_numeric or type1.is_enum) \
5815 and (type2.is_numeric or type2.is_enum)
5817 def calculate_result_code(self):
5819 return "(%s %s %s)" % (
5820 self.operand1.result(),
5822 self.operand2.result())
5824 func = self.type.binary_op(self.operator)
5826 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5827 return "%s(%s, %s)" % (
5829 self.operand1.result(),
5830 self.operand2.result())
5832 def is_py_operation_types(self, type1, type2):
5833 return (type1 is PyrexTypes.c_py_unicode_type or
5834 type2 is PyrexTypes.c_py_unicode_type or
5835 BinopNode.is_py_operation_types(self, type1, type2))
5837 def py_operation_function(self):
5838 fuction = self.py_functions[self.operator]
5840 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
5845 "^": "PyNumber_Xor",
5846 "&": "PyNumber_And",
5847 "<<": "PyNumber_Lshift",
5848 ">>": "PyNumber_Rshift",
5849 "+": "PyNumber_Add",
5850 "-": "PyNumber_Subtract",
5851 "*": "PyNumber_Multiply",
5852 "/": "__Pyx_PyNumber_Divide",
5853 "//": "PyNumber_FloorDivide",
5854 "%": "PyNumber_Remainder",
5855 "**": "PyNumber_Power"
5858 class IntBinopNode(NumBinopNode):
5859 # Binary operation taking integer arguments.
5861 def c_types_okay(self, type1, type2):
5862 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5863 return (type1.is_int or type1.is_enum) \
5864 and (type2.is_int or type2.is_enum)
5867 class AddNode(NumBinopNode):
5870 def is_py_operation_types(self, type1, type2):
5871 if type1.is_string and type2.is_string:
5874 return NumBinopNode.is_py_operation_types(self, type1, type2)
5876 def compute_c_result_type(self, type1, type2):
5877 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5878 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5880 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5883 return NumBinopNode.compute_c_result_type(
5887 class SubNode(NumBinopNode):
5890 def compute_c_result_type(self, type1, type2):
5891 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5893 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5894 return PyrexTypes.c_int_type
5896 return NumBinopNode.compute_c_result_type(
5900 class MulNode(NumBinopNode):
5903 def is_py_operation_types(self, type1, type2):
5904 if (type1.is_string and type2.is_int) \
5905 or (type2.is_string and type1.is_int):
5908 return NumBinopNode.is_py_operation_types(self, type1, type2)
5911 class DivNode(NumBinopNode):
5912 # '/' or '//' operator.
5915 truedivision = None # == "unknown" if operator == '/'
5916 ctruedivision = False
5917 cdivision_warnings = False
5918 zerodivision_check = None
5920 def find_compile_time_binary_operator(self, op1, op2):
5921 func = compile_time_binary_operators[self.operator]
5922 if self.operator == '/' and self.truedivision is None:
5923 # => true div for floats, floor div for integers
5924 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5925 func = compile_time_binary_operators['//']
5928 def calculate_constant_result(self):
5929 op1 = self.operand1.constant_result
5930 op2 = self.operand2.constant_result
5931 func = self.find_compile_time_binary_operator(op1, op2)
5932 self.constant_result = func(
5933 self.operand1.constant_result,
5934 self.operand2.constant_result)
5936 def compile_time_value(self, denv):
5937 operand1 = self.operand1.compile_time_value(denv)
5938 operand2 = self.operand2.compile_time_value(denv)
5940 func = self.find_compile_time_binary_operator(
5941 self, operand1, operand2)
5942 return func(operand1, operand2)
5943 except Exception, e:
5944 self.compile_time_value_error(e)
5946 def analyse_operation(self, env):
5947 if self.cdivision or env.directives['cdivision']:
5948 self.ctruedivision = False
5950 self.ctruedivision = self.truedivision
5951 NumBinopNode.analyse_operation(self, env)
5952 if self.is_cpp_operation():
5953 self.cdivision = True
5954 if not self.type.is_pyobject:
5955 self.zerodivision_check = (
5956 self.cdivision is None and not env.directives['cdivision']
5957 and (not self.operand2.has_constant_result() or
5958 self.operand2.constant_result == 0))
5959 if self.zerodivision_check or env.directives['cdivision_warnings']:
5960 # Need to check ahead of time to warn or raise zero division error
5961 self.operand1 = self.operand1.coerce_to_simple(env)
5962 self.operand2 = self.operand2.coerce_to_simple(env)
5964 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5966 def compute_c_result_type(self, type1, type2):
5967 if self.operator == '/' and self.ctruedivision:
5968 if not type1.is_float and not type2.is_float:
5969 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5970 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5972 return NumBinopNode.compute_c_result_type(self, type1, type2)
5974 def zero_division_message(self):
5975 if self.type.is_int:
5976 return "integer division or modulo by zero"
5978 return "float division"
5980 def generate_evaluation_code(self, code):
5981 if not self.type.is_pyobject and not self.type.is_complex:
5982 if self.cdivision is None:
5983 self.cdivision = (code.globalstate.directives['cdivision']
5984 or not self.type.signed
5985 or self.type.is_float)
5986 if not self.cdivision:
5987 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5988 NumBinopNode.generate_evaluation_code(self, code)
5989 self.generate_div_warning_code(code)
5991 def generate_div_warning_code(self, code):
5992 if not self.type.is_pyobject:
5993 if self.zerodivision_check:
5995 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5997 zero_test = "%s == 0" % self.operand2.result()
5998 code.putln("if (unlikely(%s)) {" % zero_test)
5999 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
6000 code.putln(code.error_goto(self.pos))
6002 if self.type.is_int and self.type.signed and self.operator != '%':
6003 code.globalstate.use_utility_code(division_overflow_test_code)
6004 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6005 self.type.declaration_code(''),
6006 self.operand2.result(),
6007 self.operand1.result()))
6008 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
6009 code.putln(code.error_goto(self.pos))
6011 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6012 code.globalstate.use_utility_code(cdivision_warning_utility_code)
6013 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
6014 self.operand1.result(),
6015 self.operand2.result()))
6016 code.putln(code.set_error_info(self.pos));
6017 code.put("if (__Pyx_cdivision_warning()) ")
6018 code.put_goto(code.error_label)
6021 def calculate_result_code(self):
6022 if self.type.is_complex:
6023 return NumBinopNode.calculate_result_code(self)
6024 elif self.type.is_float and self.operator == '//':
6025 return "floor(%s / %s)" % (
6026 self.operand1.result(),
6027 self.operand2.result())
6028 elif self.truedivision or self.cdivision:
6029 op1 = self.operand1.result()
6030 op2 = self.operand2.result()
6031 if self.truedivision:
6032 if self.type != self.operand1.type:
6033 op1 = self.type.cast_code(op1)
6034 if self.type != self.operand2.type:
6035 op2 = self.type.cast_code(op2)
6036 return "(%s / %s)" % (op1, op2)
6038 return "__Pyx_div_%s(%s, %s)" % (
6039 self.type.specialization_name(),
6040 self.operand1.result(),
6041 self.operand2.result())
6044 class ModNode(DivNode):
6047 def is_py_operation_types(self, type1, type2):
6048 return (type1.is_string
6050 or NumBinopNode.is_py_operation_types(self, type1, type2))
6052 def zero_division_message(self):
6053 if self.type.is_int:
6054 return "integer division or modulo by zero"
6056 return "float divmod()"
6058 def generate_evaluation_code(self, code):
6059 if not self.type.is_pyobject:
6060 if self.cdivision is None:
6061 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
6062 if not self.cdivision:
6063 if self.type.is_int:
6064 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6066 code.globalstate.use_utility_code(
6067 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6068 NumBinopNode.generate_evaluation_code(self, code)
6069 self.generate_div_warning_code(code)
6071 def calculate_result_code(self):
6073 if self.type.is_float:
6074 return "fmod%s(%s, %s)" % (
6075 self.type.math_h_modifier,
6076 self.operand1.result(),
6077 self.operand2.result())
6079 return "(%s %% %s)" % (
6080 self.operand1.result(),
6081 self.operand2.result())
6083 return "__Pyx_mod_%s(%s, %s)" % (
6084 self.type.specialization_name(),
6085 self.operand1.result(),
6086 self.operand2.result())
6088 class PowNode(NumBinopNode):
6091 def analyse_c_operation(self, env):
6092 NumBinopNode.analyse_c_operation(self, env)
6093 if self.type.is_complex:
6094 if self.type.real_type.is_float:
6095 self.operand1 = self.operand1.coerce_to(self.type, env)
6096 self.operand2 = self.operand2.coerce_to(self.type, env)
6097 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
6099 error(self.pos, "complex int powers not supported")
6100 self.pow_func = "<error>"
6101 elif self.type.is_float:
6102 self.pow_func = "pow" + self.type.math_h_modifier
6104 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
6105 env.use_utility_code(
6106 int_pow_utility_code.specialize(func_name=self.pow_func,
6107 type=self.type.declaration_code('')))
6109 def calculate_result_code(self):
6110 # Work around MSVC overloading ambiguity.
6111 def typecast(operand):
6112 if self.type == operand.type:
6113 return operand.result()
6115 return self.type.cast_code(operand.result())
6116 return "%s(%s, %s)" % (
6118 typecast(self.operand1),
6119 typecast(self.operand2))
6122 # Note: This class is temporarily "shut down" into an ineffective temp
6125 # More sophisticated temp reuse was going on before, one could have a
6126 # look at adding this again after /all/ classes are converted to the
6127 # new temp scheme. (The temp juggling cannot work otherwise).
6128 class BoolBinopNode(ExprNode):
6129 # Short-circuiting boolean operation.
6135 subexprs = ['operand1', 'operand2']
6137 def infer_type(self, env):
6138 type1 = self.operand1.infer_type(env)
6139 type2 = self.operand2.infer_type(env)
6140 return PyrexTypes.independent_spanning_type(type1, type2)
6142 def may_be_none(self):
6143 if self.operator == 'or':
6144 return self.operand2.may_be_none()
6146 return self.operand1.may_be_none() or self.operand2.may_be_none()
6148 def calculate_constant_result(self):
6149 if self.operator == 'and':
6150 self.constant_result = \
6151 self.operand1.constant_result and \
6152 self.operand2.constant_result
6154 self.constant_result = \
6155 self.operand1.constant_result or \
6156 self.operand2.constant_result
6158 def compile_time_value(self, denv):
6159 if self.operator == 'and':
6160 return self.operand1.compile_time_value(denv) \
6161 and self.operand2.compile_time_value(denv)
6163 return self.operand1.compile_time_value(denv) \
6164 or self.operand2.compile_time_value(denv)
6166 def coerce_to_boolean(self, env):
6167 return BoolBinopNode(
6169 operator = self.operator,
6170 operand1 = self.operand1.coerce_to_boolean(env),
6171 operand2 = self.operand2.coerce_to_boolean(env),
6172 type = PyrexTypes.c_bint_type,
6173 is_temp = self.is_temp)
6175 def analyse_types(self, env):
6176 self.operand1.analyse_types(env)
6177 self.operand2.analyse_types(env)
6178 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6179 self.operand1 = self.operand1.coerce_to(self.type, env)
6180 self.operand2 = self.operand2.coerce_to(self.type, env)
6182 # For what we're about to do, it's vital that
6183 # both operands be temp nodes.
6184 self.operand1 = self.operand1.coerce_to_simple(env)
6185 self.operand2 = self.operand2.coerce_to_simple(env)
6188 gil_message = "Truth-testing Python object"
6190 def check_const(self):
6191 return self.operand1.check_const() and self.operand2.check_const()
6193 def generate_evaluation_code(self, code):
6194 code.mark_pos(self.pos)
6195 self.operand1.generate_evaluation_code(code)
6196 test_result, uses_temp = self.generate_operand1_test(code)
6197 if self.operator == 'and':
6206 code.funcstate.release_temp(test_result)
6207 self.operand1.generate_disposal_code(code)
6208 self.operand2.generate_evaluation_code(code)
6209 self.allocate_temp_result(code)
6210 self.operand2.make_owned_reference(code)
6211 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6212 self.operand2.generate_post_assignment_code(code)
6213 self.operand2.free_temps(code)
6214 code.putln("} else {")
6215 self.operand1.make_owned_reference(code)
6216 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6217 self.operand1.generate_post_assignment_code(code)
6218 self.operand1.free_temps(code)
6221 def generate_operand1_test(self, code):
6222 # Generate code to test the truth of the first operand.
6223 if self.type.is_pyobject:
6224 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6227 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6229 self.operand1.py_result(),
6230 code.error_goto_if_neg(test_result, self.pos)))
6232 test_result = self.operand1.result()
6233 return (test_result, self.type.is_pyobject)
6236 class CondExprNode(ExprNode):
6237 # Short-circuiting conditional expression.
6241 # false_val ExprNode
6246 subexprs = ['test', 'true_val', 'false_val']
6248 def type_dependencies(self, env):
6249 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6251 def infer_type(self, env):
6252 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6253 self.false_val.infer_type(env))
6255 def calculate_constant_result(self):
6256 if self.test.constant_result:
6257 self.constant_result = self.true_val.constant_result
6259 self.constant_result = self.false_val.constant_result
6261 def analyse_types(self, env):
6262 self.test.analyse_types(env)
6263 self.test = self.test.coerce_to_boolean(env)
6264 self.true_val.analyse_types(env)
6265 self.false_val.analyse_types(env)
6266 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6267 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6268 self.true_val = self.true_val.coerce_to(self.type, env)
6269 self.false_val = self.false_val.coerce_to(self.type, env)
6271 if self.type == PyrexTypes.error_type:
6274 def type_error(self):
6275 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6276 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6277 (self.true_val.type, self.false_val.type))
6278 self.type = PyrexTypes.error_type
6280 def check_const(self):
6281 return (self.test.check_const()
6282 and self.true_val.check_const()
6283 and self.false_val.check_const())
6285 def generate_evaluation_code(self, code):
6286 # Because subexprs may not be evaluated we can use a more optimal
6287 # subexpr allocation strategy than the default, so override evaluation_code.
6289 code.mark_pos(self.pos)
6290 self.allocate_temp_result(code)
6291 self.test.generate_evaluation_code(code)
6292 code.putln("if (%s) {" % self.test.result() )
6293 self.eval_and_get(code, self.true_val)
6294 code.putln("} else {")
6295 self.eval_and_get(code, self.false_val)
6297 self.test.generate_disposal_code(code)
6298 self.test.free_temps(code)
6300 def eval_and_get(self, code, expr):
6301 expr.generate_evaluation_code(code)
6302 expr.make_owned_reference(code)
6303 code.putln("%s = %s;" % (self.result(), expr.result()))
6304 expr.generate_post_assignment_code(code)
6305 expr.free_temps(code)
6307 richcmp_constants = {
6317 class CmpNode(object):
6318 # Mixin class containing code common to PrimaryCmpNodes
6319 # and CascadedCmpNodes.
6321 special_bool_cmp_function = None
6323 def infer_type(self, env):
6324 # TODO: Actually implement this (after merging with -unstable).
6325 return py_object_type
6327 def calculate_cascaded_constant_result(self, operand1_result):
6328 func = compile_time_binary_operators[self.operator]
6329 operand2_result = self.operand2.constant_result
6330 result = func(operand1_result, operand2_result)
6332 self.cascade.calculate_cascaded_constant_result(operand2_result)
6333 if self.cascade.constant_result:
6334 self.constant_result = result and self.cascade.constant_result
6336 self.constant_result = result
6338 def cascaded_compile_time_value(self, operand1, denv):
6339 func = get_compile_time_binop(self)
6340 operand2 = self.operand2.compile_time_value(denv)
6342 result = func(operand1, operand2)
6343 except Exception, e:
6344 self.compile_time_value_error(e)
6347 cascade = self.cascade
6349 # FIXME: I bet this must call cascaded_compile_time_value()
6350 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6353 def is_cpp_comparison(self):
6354 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6356 def find_common_int_type(self, env, op, operand1, operand2):
6357 # type1 != type2 and at least one of the types is not a C int
6358 type1 = operand1.type
6359 type2 = operand2.type
6360 type1_can_be_int = False
6361 type2_can_be_int = False
6363 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6364 and operand1.can_coerce_to_char_literal():
6365 type1_can_be_int = True
6366 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6367 and operand2.can_coerce_to_char_literal():
6368 type2_can_be_int = True
6371 if type2_can_be_int:
6374 if type1_can_be_int:
6376 elif type1_can_be_int:
6377 if type2_can_be_int:
6378 return PyrexTypes.c_uchar_type
6382 def find_common_type(self, env, op, operand1, common_type=None):
6383 operand2 = self.operand2
6384 type1 = operand1.type
6385 type2 = operand2.type
6387 new_common_type = None
6389 # catch general errors
6390 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6391 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6392 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6393 new_common_type = error_type
6395 # try to use numeric comparisons where possible
6396 elif type1.is_complex or type2.is_complex:
6397 if op not in ('==', '!='):
6398 error(self.pos, "complex types are unordered")
6399 new_common_type = error_type
6400 if type1.is_pyobject:
6401 new_common_type = type1
6402 elif type2.is_pyobject:
6403 new_common_type = type2
6405 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6406 elif type1.is_numeric and type2.is_numeric:
6407 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6408 elif common_type is None or not common_type.is_pyobject:
6409 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6411 if new_common_type is None:
6412 # fall back to generic type compatibility tests
6414 new_common_type = type1
6415 elif type1.is_pyobject or type2.is_pyobject:
6416 if type2.is_numeric or type2.is_string:
6417 if operand2.check_for_coercion_error(type1):
6418 new_common_type = error_type
6420 new_common_type = py_object_type
6421 elif type1.is_numeric or type1.is_string:
6422 if operand1.check_for_coercion_error(type2):
6423 new_common_type = error_type
6425 new_common_type = py_object_type
6426 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6427 new_common_type = py_object_type
6429 # one Python type and one non-Python type, not assignable
6430 self.invalid_types_error(operand1, op, operand2)
6431 new_common_type = error_type
6432 elif type1.assignable_from(type2):
6433 new_common_type = type1
6434 elif type2.assignable_from(type1):
6435 new_common_type = type2
6437 # C types that we couldn't handle up to here are an error
6438 self.invalid_types_error(operand1, op, operand2)
6439 new_common_type = error_type
6441 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6442 isinstance(operand2, BytesNode)):
6443 # special case when comparing char* to bytes literal: must
6444 # compare string values!
6445 new_common_type = bytes_type
6447 # recursively merge types
6448 if common_type is None or new_common_type.is_error:
6449 common_type = new_common_type
6451 # we could do a lot better by splitting the comparison
6452 # into a non-Python part and a Python part, but this is
6454 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6457 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6461 def invalid_types_error(self, operand1, op, operand2):
6462 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6463 (op, operand1.type, operand2.type))
6465 def is_python_comparison(self):
6466 return (not self.is_ptr_contains()
6467 and not self.is_c_string_contains()
6468 and (self.has_python_operands()
6469 or (self.cascade and self.cascade.is_python_comparison())
6470 or self.operator in ('in', 'not_in')))
6472 def coerce_operands_to(self, dst_type, env):
6473 operand2 = self.operand2
6474 if operand2.type != dst_type:
6475 self.operand2 = operand2.coerce_to(dst_type, env)
6477 self.cascade.coerce_operands_to(dst_type, env)
6479 def is_python_result(self):
6480 return ((self.has_python_operands() and
6481 self.special_bool_cmp_function is None and
6482 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6483 not self.is_c_string_contains() and
6484 not self.is_ptr_contains())
6485 or (self.cascade and self.cascade.is_python_result()))
6487 def is_c_string_contains(self):
6488 return self.operator in ('in', 'not_in') and \
6489 ((self.operand1.type.is_int
6490 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6491 (self.operand1.type is PyrexTypes.c_py_unicode_type
6492 and self.operand2.type is unicode_type))
6494 def is_ptr_contains(self):
6495 if self.operator in ('in', 'not_in'):
6496 container_type = self.operand2.type
6497 return (container_type.is_ptr or container_type.is_array) \
6498 and not container_type.is_string
6500 def find_special_bool_compare_function(self, env):
6501 if self.operator in ('==', '!='):
6502 type1, type2 = self.operand1.type, self.operand2.type
6503 if type1.is_pyobject and type2.is_pyobject:
6504 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6505 env.use_utility_code(pyunicode_equals_utility_code)
6506 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6510 def generate_operation_code(self, code, result_code,
6511 operand1, op , operand2):
6512 if self.type.is_pyobject:
6513 coerce_result = "__Pyx_PyBool_FromLong"
6520 if self.special_bool_cmp_function:
6521 if operand1.type.is_pyobject:
6522 result1 = operand1.py_result()
6524 result1 = operand1.result()
6525 if operand2.type.is_pyobject:
6526 result2 = operand2.py_result()
6528 result2 = operand2.result()
6529 code.putln("%s = %s(%s, %s, %s); %s" % (
6531 self.special_bool_cmp_function,
6534 richcmp_constants[op],
6535 code.error_goto_if_neg(result_code, self.pos)))
6536 elif op == 'in' or op == 'not_in':
6537 code.globalstate.use_utility_code(contains_utility_code)
6538 if self.type.is_pyobject:
6539 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6541 negation = "__Pyx_NegateNonNeg"
6542 if operand2.type is dict_type:
6543 method = "PyDict_Contains"
6545 method = "PySequence_Contains"
6546 if self.type.is_pyobject:
6547 error_clause = code.error_goto_if_null
6548 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6550 error_clause = code.error_goto_if_neg
6553 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6558 operand2.py_result(),
6559 operand1.py_result(),
6561 error_clause(result_code, self.pos)))
6562 elif (operand1.type.is_pyobject
6563 and op not in ('is', 'is_not')):
6564 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6566 operand1.py_result(),
6567 operand2.py_result(),
6568 richcmp_constants[op],
6569 code.error_goto_if_null(result_code, self.pos)))
6570 code.put_gotref(result_code)
6571 elif operand1.type.is_complex:
6576 code.putln("%s = %s(%s%s(%s, %s));" % (
6580 operand1.type.unary_op('eq'),
6584 type1 = operand1.type
6585 type2 = operand2.type
6586 if (type1.is_extension_type or type2.is_extension_type) \
6587 and not type1.same_as(type2):
6588 common_type = py_object_type
6589 elif type1.is_numeric:
6590 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6593 code1 = operand1.result_as(common_type)
6594 code2 = operand2.result_as(common_type)
6595 code.putln("%s = %s(%s %s %s);" % (
6599 self.c_operator(op),
6602 def c_operator(self, op):
6605 elif op == 'is_not':
6610 contains_utility_code = UtilityCode(
6612 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6613 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6614 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6618 char_in_bytes_utility_code = UtilityCode(
6620 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6623 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6624 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6625 char* char_start = PyBytes_AS_STRING(bytes);
6627 for (pos=char_start; pos < char_start+length; pos++) {
6628 if (character == pos[0]) return 1;
6634 pyunicode_in_unicode_utility_code = UtilityCode(
6636 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6639 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6640 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6641 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6643 for (pos=char_start; pos < char_start+length; pos++) {
6644 if (character == pos[0]) return 1;
6650 pyunicode_equals_utility_code = UtilityCode(
6652 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6655 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6656 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6657 return (equals == Py_EQ);
6658 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6659 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6660 return (equals == Py_NE);
6661 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6662 if (equals == Py_EQ)
6663 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6665 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6667 int result = PyUnicode_Compare(s1, s2);
6668 if ((result == -1) && unlikely(PyErr_Occurred()))
6670 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6672 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6673 return (equals == Py_EQ);
6674 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6675 return (equals == Py_NE);
6676 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6677 return (equals == Py_NE);
6680 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6683 result = __Pyx_PyObject_IsTrue(py_result);
6684 Py_DECREF(py_result);
6691 class PrimaryCmpNode(ExprNode, CmpNode):
6692 # Non-cascaded comparison or first comparison of
6693 # a cascaded sequence.
6698 # cascade CascadedCmpNode
6700 # We don't use the subexprs mechanism, because
6701 # things here are too complicated for it to handle.
6702 # Instead, we override all the framework methods
6705 child_attrs = ['operand1', 'operand2', 'cascade']
6709 def infer_type(self, env):
6710 # TODO: Actually implement this (after merging with -unstable).
6711 return py_object_type
6713 def type_dependencies(self, env):
6716 def calculate_constant_result(self):
6717 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6719 def compile_time_value(self, denv):
6720 operand1 = self.operand1.compile_time_value(denv)
6721 return self.cascaded_compile_time_value(operand1, denv)
6723 def analyse_types(self, env):
6724 self.operand1.analyse_types(env)
6725 self.operand2.analyse_types(env)
6726 if self.is_cpp_comparison():
6727 self.analyse_cpp_comparison(env)
6729 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6732 self.cascade.analyse_types(env)
6734 if self.operator in ('in', 'not_in'):
6735 if self.is_c_string_contains():
6736 self.is_pycmp = False
6739 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6741 if self.operand2.type is unicode_type:
6742 env.use_utility_code(pyunicode_in_unicode_utility_code)
6744 if self.operand1.type is PyrexTypes.c_uchar_type:
6745 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6746 if self.operand2.type is not bytes_type:
6747 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6748 env.use_utility_code(char_in_bytes_utility_code)
6749 self.operand2 = self.operand2.as_none_safe_node(
6750 "argument of type 'NoneType' is not iterable")
6751 elif self.is_ptr_contains():
6753 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6754 self.type = PyrexTypes.c_bint_type
6755 # Will be transformed by IterationTransform
6758 if self.operand2.type is dict_type:
6759 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6760 common_type = py_object_type
6761 self.is_pycmp = True
6762 elif self.find_special_bool_compare_function(env):
6763 common_type = None # if coercion needed, the method call above has already done it
6764 self.is_pycmp = False # result is bint
6765 self.is_temp = True # must check for error return
6767 common_type = self.find_common_type(env, self.operator, self.operand1)
6768 self.is_pycmp = common_type.is_pyobject
6770 if common_type is not None and not common_type.is_error:
6771 if self.operand1.type != common_type:
6772 self.operand1 = self.operand1.coerce_to(common_type, env)
6773 self.coerce_operands_to(common_type, env)
6776 self.operand2 = self.operand2.coerce_to_simple(env)
6777 self.cascade.coerce_cascaded_operands_to_temp(env)
6778 if self.is_python_result():
6779 self.type = PyrexTypes.py_object_type
6781 self.type = PyrexTypes.c_bint_type
6784 cdr.type = self.type
6786 if self.is_pycmp or self.cascade:
6789 def analyse_cpp_comparison(self, env):
6790 type1 = self.operand1.type
6791 type2 = self.operand2.type
6792 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6794 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6795 (self.operator, type1, type2))
6796 self.type = PyrexTypes.error_type
6797 self.result_code = "<error>"
6799 func_type = entry.type
6800 if func_type.is_ptr:
6801 func_type = func_type.base_type
6802 if len(func_type.args) == 1:
6803 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6805 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6806 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6807 self.type = func_type.return_type
6809 def has_python_operands(self):
6810 return (self.operand1.type.is_pyobject
6811 or self.operand2.type.is_pyobject)
6813 def check_const(self):
6818 return self.operand1.check_const() and self.operand2.check_const()
6820 def calculate_result_code(self):
6821 if self.operand1.type.is_complex:
6822 if self.operator == "!=":
6826 return "(%s%s(%s, %s))" % (
6828 self.operand1.type.binary_op('=='),
6829 self.operand1.result(),
6830 self.operand2.result())
6831 elif self.is_c_string_contains():
6832 if self.operand2.type is bytes_type:
6833 method = "__Pyx_BytesContains"
6835 method = "__Pyx_UnicodeContains"
6836 if self.operator == "not_in":
6840 return "(%s%s(%s, %s))" % (
6843 self.operand2.result(),
6844 self.operand1.result())
6846 return "(%s %s %s)" % (
6847 self.operand1.result(),
6848 self.c_operator(self.operator),
6849 self.operand2.result())
6851 def generate_evaluation_code(self, code):
6852 self.operand1.generate_evaluation_code(code)
6853 self.operand2.generate_evaluation_code(code)
6855 self.allocate_temp_result(code)
6856 self.generate_operation_code(code, self.result(),
6857 self.operand1, self.operator, self.operand2)
6859 self.cascade.generate_evaluation_code(code,
6860 self.result(), self.operand2)
6861 self.operand1.generate_disposal_code(code)
6862 self.operand1.free_temps(code)
6863 self.operand2.generate_disposal_code(code)
6864 self.operand2.free_temps(code)
6866 def generate_subexpr_disposal_code(self, code):
6867 # If this is called, it is a non-cascaded cmp,
6868 # so only need to dispose of the two main operands.
6869 self.operand1.generate_disposal_code(code)
6870 self.operand2.generate_disposal_code(code)
6872 def free_subexpr_temps(self, code):
6873 # If this is called, it is a non-cascaded cmp,
6874 # so only need to dispose of the two main operands.
6875 self.operand1.free_temps(code)
6876 self.operand2.free_temps(code)
6878 def annotate(self, code):
6879 self.operand1.annotate(code)
6880 self.operand2.annotate(code)
6882 self.cascade.annotate(code)
6885 class CascadedCmpNode(Node, CmpNode):
6886 # A CascadedCmpNode is not a complete expression node. It
6887 # hangs off the side of another comparison node, shares
6888 # its left operand with that node, and shares its result
6889 # with the PrimaryCmpNode at the head of the chain.
6893 # cascade CascadedCmpNode
6895 child_attrs = ['operand2', 'cascade']
6898 constant_result = constant_value_not_set # FIXME: where to calculate this?
6900 def infer_type(self, env):
6901 # TODO: Actually implement this (after merging with -unstable).
6902 return py_object_type
6904 def type_dependencies(self, env):
6907 def has_constant_result(self):
6908 return self.constant_result is not constant_value_not_set and \
6909 self.constant_result is not not_a_constant
6911 def analyse_types(self, env):
6912 self.operand2.analyse_types(env)
6914 self.cascade.analyse_types(env)
6916 def has_python_operands(self):
6917 return self.operand2.type.is_pyobject
6919 def coerce_operands_to_pyobjects(self, env):
6920 self.operand2 = self.operand2.coerce_to_pyobject(env)
6921 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
6922 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6924 self.cascade.coerce_operands_to_pyobjects(env)
6926 def coerce_cascaded_operands_to_temp(self, env):
6928 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6929 self.operand2 = self.operand2.coerce_to_simple(env)
6930 self.cascade.coerce_cascaded_operands_to_temp(env)
6932 def generate_evaluation_code(self, code, result, operand1):
6933 if self.type.is_pyobject:
6934 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
6935 code.put_decref(result, self.type)
6937 code.putln("if (%s) {" % result)
6938 self.operand2.generate_evaluation_code(code)
6939 self.generate_operation_code(code, result,
6940 operand1, self.operator, self.operand2)
6942 self.cascade.generate_evaluation_code(
6943 code, result, self.operand2)
6944 # Cascaded cmp result is always temp
6945 self.operand2.generate_disposal_code(code)
6946 self.operand2.free_temps(code)
6949 def annotate(self, code):
6950 self.operand2.annotate(code)
6952 self.cascade.annotate(code)
6955 binop_node_classes = {
6956 "or": BoolBinopNode,
6957 "and": BoolBinopNode,
6972 def binop_node(pos, operator, operand1, operand2, inplace=False):
6973 # Construct binop node of appropriate class for
6975 return binop_node_classes[operator](pos,
6976 operator = operator,
6977 operand1 = operand1,
6978 operand2 = operand2,
6981 #-------------------------------------------------------------------
6985 # Coercion nodes are special in that they are created during
6986 # the analyse_types phase of parse tree processing.
6987 # Their __init__ methods consequently incorporate some aspects
6990 #-------------------------------------------------------------------
6992 class CoercionNode(ExprNode):
6993 # Abstract base class for coercion nodes.
6995 # arg ExprNode node being coerced
6998 constant_result = not_a_constant
7000 def __init__(self, arg):
7004 print("%s Coercing %s" % (self, self.arg))
7006 def calculate_constant_result(self):
7007 # constant folding can break type coercion, so this is disabled
7010 def annotate(self, code):
7011 self.arg.annotate(code)
7012 if self.arg.type != self.type:
7013 file, line, col = self.pos
7014 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
7017 class CastNode(CoercionNode):
7018 # Wrap a node in a C type cast.
7020 def __init__(self, arg, new_type):
7021 CoercionNode.__init__(self, arg)
7022 self.type = new_type
7024 def may_be_none(self):
7025 return self.arg.may_be_none()
7027 def calculate_result_code(self):
7028 return self.arg.result_as(self.type)
7030 def generate_result_code(self, code):
7031 self.arg.generate_result_code(code)
7034 class PyTypeTestNode(CoercionNode):
7035 # This node is used to check that a generic Python
7036 # object is an instance of a particular extension type.
7037 # This node borrows the result of its argument node.
7039 def __init__(self, arg, dst_type, env, notnone=False):
7040 # The arg is know to be a Python object, and
7041 # the dst_type is known to be an extension type.
7042 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
7043 CoercionNode.__init__(self, arg)
7044 self.type = dst_type
7045 self.result_ctype = arg.ctype()
7046 self.notnone = notnone
7048 nogil_check = Node.gil_error
7049 gil_message = "Python type test"
7051 def analyse_types(self, env):
7054 def may_be_none(self):
7057 return self.arg.may_be_none()
7059 def result_in_temp(self):
7060 return self.arg.result_in_temp()
7062 def is_ephemeral(self):
7063 return self.arg.is_ephemeral()
7065 def calculate_constant_result(self):
7069 def calculate_result_code(self):
7070 return self.arg.result()
7072 def generate_result_code(self, code):
7073 if self.type.typeobj_is_available():
7074 if not self.type.is_builtin_type:
7075 code.globalstate.use_utility_code(type_test_utility_code)
7078 self.type.type_test_code(self.arg.py_result(), self.notnone),
7079 code.error_goto(self.pos)))
7081 error(self.pos, "Cannot test type of extern C class "
7082 "without type object name specification")
7084 def generate_post_assignment_code(self, code):
7085 self.arg.generate_post_assignment_code(code)
7087 def free_temps(self, code):
7088 self.arg.free_temps(code)
7091 class NoneCheckNode(CoercionNode):
7092 # This node is used to check that a Python object is not None and
7093 # raises an appropriate exception (as specified by the creating
7096 def __init__(self, arg, exception_type_cname, exception_message):
7097 CoercionNode.__init__(self, arg)
7098 self.type = arg.type
7099 self.result_ctype = arg.ctype()
7100 self.exception_type_cname = exception_type_cname
7101 self.exception_message = exception_message
7103 def analyse_types(self, env):
7106 def may_be_none(self):
7109 def result_in_temp(self):
7110 return self.arg.result_in_temp()
7112 def calculate_result_code(self):
7113 return self.arg.result()
7115 def generate_result_code(self, code):
7117 "if (unlikely(%s == Py_None)) {" % self.arg.result())
7118 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
7119 self.exception_type_cname,
7120 StringEncoding.escape_byte_string(
7121 self.exception_message.encode('UTF-8')),
7122 code.error_goto(self.pos)))
7125 def generate_post_assignment_code(self, code):
7126 self.arg.generate_post_assignment_code(code)
7128 def free_temps(self, code):
7129 self.arg.free_temps(code)
7132 class CoerceToPyTypeNode(CoercionNode):
7133 # This node is used to convert a C data type
7134 # to a Python object.
7136 type = py_object_type
7139 def __init__(self, arg, env, type=py_object_type):
7140 CoercionNode.__init__(self, arg)
7141 if not arg.type.create_to_py_utility_code(env):
7143 "Cannot convert '%s' to Python object" % arg.type)
7144 if type is py_object_type:
7145 # be specific about some known types
7146 if arg.type.is_string:
7147 self.type = bytes_type
7148 elif arg.type is PyrexTypes.c_py_unicode_type:
7149 self.type = unicode_type
7150 elif arg.type.is_complex:
7151 self.type = Builtin.complex_type
7153 # FIXME: check that the target type and the resulting type are compatible
7156 gil_message = "Converting to Python object"
7158 def may_be_none(self):
7159 # FIXME: is this always safe?
7162 def coerce_to_boolean(self, env):
7163 arg_type = self.arg.type
7164 if (arg_type == PyrexTypes.c_bint_type or
7165 (arg_type.is_pyobject and arg_type.name == 'bool')):
7166 return self.arg.coerce_to_temp(env)
7168 return CoerceToBooleanNode(self, env)
7170 def coerce_to_integer(self, env):
7171 # If not already some C integer type, coerce to longint.
7172 if self.arg.type.is_int:
7175 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7177 def analyse_types(self, env):
7178 # The arg is always already analysed
7181 def generate_result_code(self, code):
7182 function = self.arg.type.to_py_function
7183 code.putln('%s = %s(%s); %s' % (
7187 code.error_goto_if_null(self.result(), self.pos)))
7188 code.put_gotref(self.py_result())
7191 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7192 # This node is used to convert a C int type to a Python bytes
7197 def __init__(self, arg, env):
7198 arg = arg.coerce_to_simple(env)
7199 CoercionNode.__init__(self, arg)
7200 self.type = Builtin.bytes_type
7202 def generate_result_code(self, code):
7204 arg_result = arg.result()
7205 if arg.type not in (PyrexTypes.c_char_type,
7206 PyrexTypes.c_uchar_type,
7207 PyrexTypes.c_schar_type):
7209 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7210 arg_result, arg_result))
7212 code.putln("if (%s > 255) {" % arg_result)
7213 code.putln('PyErr_Format(PyExc_OverflowError, '
7214 '"value too large to pack into a byte"); %s' % (
7215 code.error_goto(self.pos)))
7218 if arg.type is not PyrexTypes.c_char_type:
7219 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7220 code.putln("%s = (char)%s;" % (temp, arg_result))
7222 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7225 code.error_goto_if_null(self.result(), self.pos)))
7226 if temp is not None:
7227 code.funcstate.release_temp(temp)
7228 code.put_gotref(self.py_result())
7231 class CoerceFromPyTypeNode(CoercionNode):
7232 # This node is used to convert a Python object
7235 def __init__(self, result_type, arg, env):
7236 CoercionNode.__init__(self, arg)
7237 self.type = result_type
7239 if not result_type.create_from_py_utility_code(env):
7241 "Cannot convert Python object to '%s'" % result_type)
7242 if self.type.is_string and self.arg.is_ephemeral():
7244 "Obtaining char * from temporary Python value")
7246 def analyse_types(self, env):
7247 # The arg is always already analysed
7250 def generate_result_code(self, code):
7251 function = self.type.from_py_function
7252 operand = self.arg.py_result()
7253 rhs = "%s(%s)" % (function, operand)
7254 if self.type.is_enum:
7255 rhs = typecast(self.type, c_long_type, rhs)
7256 code.putln('%s = %s; %s' % (
7259 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7260 if self.type.is_pyobject:
7261 code.put_gotref(self.py_result())
7264 class CoerceToBooleanNode(CoercionNode):
7265 # This node is used when a result needs to be used
7266 # in a boolean context.
7268 type = PyrexTypes.c_bint_type
7270 _special_builtins = {
7271 Builtin.list_type : 'PyList_GET_SIZE',
7272 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7273 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7274 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7277 def __init__(self, arg, env):
7278 CoercionNode.__init__(self, arg)
7279 if arg.type.is_pyobject:
7282 def nogil_check(self, env):
7283 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7286 gil_message = "Truth-testing Python object"
7288 def check_const(self):
7292 return self.arg.check_const()
7294 def calculate_result_code(self):
7295 return "(%s != 0)" % self.arg.result()
7297 def generate_result_code(self, code):
7298 if not self.is_temp:
7300 test_func = self._special_builtins.get(self.arg.type)
7301 if test_func is not None:
7302 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7304 self.arg.py_result(),
7306 self.arg.py_result()))
7309 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7311 self.arg.py_result(),
7312 code.error_goto_if_neg(self.result(), self.pos)))
7314 class CoerceToComplexNode(CoercionNode):
7316 def __init__(self, arg, dst_type, env):
7317 if arg.type.is_complex:
7318 arg = arg.coerce_to_simple(env)
7319 self.type = dst_type
7320 CoercionNode.__init__(self, arg)
7321 dst_type.create_declaration_utility_code(env)
7323 def calculate_result_code(self):
7324 if self.arg.type.is_complex:
7325 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7326 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7328 real_part = self.arg.result()
7330 return "%s(%s, %s)" % (
7331 self.type.from_parts,
7335 def generate_result_code(self, code):
7338 class CoerceToTempNode(CoercionNode):
7339 # This node is used to force the result of another node
7340 # to be stored in a temporary. It is only used if the
7341 # argument node's result is not already in a temporary.
7343 def __init__(self, arg, env):
7344 CoercionNode.__init__(self, arg)
7345 self.type = self.arg.type
7346 self.constant_result = self.arg.constant_result
7348 if self.type.is_pyobject:
7349 self.result_ctype = py_object_type
7351 gil_message = "Creating temporary Python reference"
7353 def analyse_types(self, env):
7354 # The arg is always already analysed
7357 def coerce_to_boolean(self, env):
7358 self.arg = self.arg.coerce_to_boolean(env)
7359 if self.arg.is_simple():
7361 self.type = self.arg.type
7362 self.result_ctype = self.type
7365 def generate_result_code(self, code):
7366 #self.arg.generate_evaluation_code(code) # Already done
7367 # by generic generate_subexpr_evaluation_code!
7368 code.putln("%s = %s;" % (
7369 self.result(), self.arg.result_as(self.ctype())))
7370 if self.type.is_pyobject and self.use_managed_ref:
7371 code.put_incref(self.result(), self.ctype())
7374 class CloneNode(CoercionNode):
7375 # This node is employed when the result of another node needs
7376 # to be used multiple times. The argument node's result must
7377 # be in a temporary. This node "borrows" the result from the
7378 # argument node, and does not generate any evaluation or
7379 # disposal code for it. The original owner of the argument
7380 # node is responsible for doing those things.
7382 subexprs = [] # Arg is not considered a subexpr
7385 def __init__(self, arg):
7386 CoercionNode.__init__(self, arg)
7387 if hasattr(arg, 'type'):
7388 self.type = arg.type
7389 self.result_ctype = arg.result_ctype
7390 if hasattr(arg, 'entry'):
7391 self.entry = arg.entry
7394 return self.arg.result()
7396 def type_dependencies(self, env):
7397 return self.arg.type_dependencies(env)
7399 def infer_type(self, env):
7400 return self.arg.infer_type(env)
7402 def analyse_types(self, env):
7403 self.type = self.arg.type
7404 self.result_ctype = self.arg.result_ctype
7406 if hasattr(self.arg, 'entry'):
7407 self.entry = self.arg.entry
7409 def generate_evaluation_code(self, code):
7412 def generate_result_code(self, code):
7415 def generate_disposal_code(self, code):
7418 def free_temps(self, code):
7422 class ModuleRefNode(ExprNode):
7423 # Simple returns the module object
7425 type = py_object_type
7429 def analyse_types(self, env):
7432 def may_be_none(self):
7435 def calculate_result_code(self):
7436 return Naming.module_cname
7438 def generate_result_code(self, code):
7441 class DocstringRefNode(ExprNode):
7442 # Extracts the docstring of the body element
7445 type = py_object_type
7448 def __init__(self, pos, body):
7449 ExprNode.__init__(self, pos)
7450 assert body.type.is_pyobject
7453 def analyse_types(self, env):
7456 def generate_result_code(self, code):
7457 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7458 self.result(), self.body.result(),
7459 code.error_goto_if_null(self.result(), self.pos)))
7460 code.put_gotref(self.result())
7464 #------------------------------------------------------------------------------------
7466 # Runtime support code
7468 #------------------------------------------------------------------------------------
7470 get_name_interned_utility_code = UtilityCode(
7472 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7475 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7477 result = PyObject_GetAttr(dict, name);
7479 PyErr_SetObject(PyExc_NameError, name);
7484 #------------------------------------------------------------------------------------
7486 import_utility_code = UtilityCode(
7488 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7491 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7492 PyObject *py_import = 0;
7493 PyObject *empty_list = 0;
7494 PyObject *module = 0;
7495 PyObject *global_dict = 0;
7496 PyObject *empty_dict = 0;
7498 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7504 empty_list = PyList_New(0);
7509 global_dict = PyModule_GetDict(%(GLOBALS)s);
7512 empty_dict = PyDict_New();
7515 module = PyObject_CallFunctionObjArgs(py_import,
7516 name, global_dict, empty_dict, list, NULL);
7518 Py_XDECREF(empty_list);
7519 Py_XDECREF(py_import);
7520 Py_XDECREF(empty_dict);
7524 "BUILTINS": Naming.builtins_cname,
7525 "GLOBALS": Naming.module_cname,
7528 #------------------------------------------------------------------------------------
7530 get_exception_utility_code = UtilityCode(
7532 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7535 static PyObject *__Pyx_GetExcValue(void) {
7536 PyObject *type = 0, *value = 0, *tb = 0;
7537 PyObject *tmp_type, *tmp_value, *tmp_tb;
7538 PyObject *result = 0;
7539 PyThreadState *tstate = PyThreadState_Get();
7540 PyErr_Fetch(&type, &value, &tb);
7541 PyErr_NormalizeException(&type, &value, &tb);
7542 if (PyErr_Occurred())
7548 tmp_type = tstate->exc_type;
7549 tmp_value = tstate->exc_value;
7550 tmp_tb = tstate->exc_traceback;
7551 tstate->exc_type = type;
7552 tstate->exc_value = value;
7553 tstate->exc_traceback = tb;
7554 /* Make sure tstate is in a consistent state when we XDECREF
7555 these objects (XDECREF may run arbitrary code). */
7556 Py_XDECREF(tmp_type);
7557 Py_XDECREF(tmp_value);
7572 #------------------------------------------------------------------------------------
7574 type_test_utility_code = UtilityCode(
7576 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7579 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7580 if (unlikely(!type)) {
7581 PyErr_Format(PyExc_SystemError, "Missing type object");
7584 if (likely(PyObject_TypeCheck(obj, type)))
7586 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7587 Py_TYPE(obj)->tp_name, type->tp_name);
7592 #------------------------------------------------------------------------------------
7594 find_py2_metaclass_utility_code = UtilityCode(
7596 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7599 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7600 PyObject *metaclass;
7601 /* Default metaclass */
7602 #if PY_MAJOR_VERSION < 3
7603 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7604 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7605 metaclass = PyObject_GetAttrString(base, "__class__");
7608 metaclass = (PyObject*) Py_TYPE(base);
7611 metaclass = (PyObject *) &PyClass_Type;
7614 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7615 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7616 metaclass = (PyObject*) Py_TYPE(base);
7618 metaclass = (PyObject *) &PyType_Type;
7621 Py_INCREF(metaclass);
7626 create_class_utility_code = UtilityCode(
7628 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7629 PyObject *modname); /*proto*/
7632 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7633 PyObject *modname) {
7635 PyObject *metaclass;
7637 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7640 /* Python2 __metaclass__ */
7641 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7643 Py_INCREF(metaclass);
7645 metaclass = __Pyx_FindPy2Metaclass(bases);
7647 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7648 Py_DECREF(metaclass);
7652 requires = [find_py2_metaclass_utility_code])
7654 #------------------------------------------------------------------------------------
7656 create_py3class_utility_code = UtilityCode(
7658 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7659 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7660 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7663 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7664 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7666 Py_INCREF(metaclass);
7667 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7668 Py_DECREF(metaclass);
7673 return __Pyx_FindPy2Metaclass(bases);
7676 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7677 PyObject *modname, PyObject *doc) {
7683 prep = PyObject_GetAttrString(metaclass, "__prepare__");
7685 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7688 return PyDict_New();
7690 pargs = PyTuple_New(2);
7698 PyTuple_SET_ITEM(pargs, 0, name);
7699 PyTuple_SET_ITEM(pargs, 1, bases);
7701 ns = PyObject_Call(prep, pargs, mkw);
7709 /* Required here to emulate assignment order */
7710 /* XXX: use consts here */
7711 #if PY_MAJOR_VERSION >= 3
7712 str = PyUnicode_FromString("__module__");
7714 str = PyString_FromString("__module__");
7721 if (PyObject_SetItem(ns, str, modname) < 0) {
7728 #if PY_MAJOR_VERSION >= 3
7729 str = PyUnicode_FromString("__doc__");
7731 str = PyString_FromString("__doc__");
7737 if (PyObject_SetItem(ns, str, doc) < 0) {
7747 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7749 PyObject *margs = PyTuple_New(3);
7755 PyTuple_SET_ITEM(margs, 0, name);
7756 PyTuple_SET_ITEM(margs, 1, bases);
7757 PyTuple_SET_ITEM(margs, 2, dict);
7758 result = PyObject_Call(metaclass, margs, mkw);
7763 requires = [find_py2_metaclass_utility_code])
7765 #------------------------------------------------------------------------------------
7767 cpp_exception_utility_code = UtilityCode(
7769 #ifndef __Pyx_CppExn2PyErr
7770 static void __Pyx_CppExn2PyErr() {
7772 if (PyErr_Occurred())
7773 ; // let the latest Python exn pass through and ignore the current one
7776 } catch (const std::invalid_argument& exn) {
7777 // Catch a handful of different errors here and turn them into the
7778 // equivalent Python errors.
7779 // Change invalid_argument to ValueError
7780 PyErr_SetString(PyExc_ValueError, exn.what());
7781 } catch (const std::out_of_range& exn) {
7782 // Change out_of_range to IndexError
7783 PyErr_SetString(PyExc_IndexError, exn.what());
7784 } catch (const std::exception& exn) {
7785 PyErr_SetString(PyExc_RuntimeError, exn.what());
7789 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7797 pyerr_occurred_withgil_utility_code= UtilityCode(
7799 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7802 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7805 PyGILState_STATE _save = PyGILState_Ensure();
7807 err = !!PyErr_Occurred();
7809 PyGILState_Release(_save);
7816 #------------------------------------------------------------------------------------
7818 raise_noneattr_error_utility_code = UtilityCode(
7820 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7823 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7824 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7828 raise_noneindex_error_utility_code = UtilityCode(
7830 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7833 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7834 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7838 raise_none_iter_error_utility_code = UtilityCode(
7840 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7843 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7844 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7848 #------------------------------------------------------------------------------------
7850 getitem_dict_utility_code = UtilityCode(
7852 #if PY_MAJOR_VERSION >= 3
7853 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7855 if (unlikely(d == Py_None)) {
7856 __Pyx_RaiseNoneIndexingError();
7859 value = PyDict_GetItemWithError(d, key);
7860 if (unlikely(!value)) {
7861 if (!PyErr_Occurred())
7862 PyErr_SetObject(PyExc_KeyError, key);
7869 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7872 requires = [raise_noneindex_error_utility_code])
7874 #------------------------------------------------------------------------------------
7876 getitem_int_pyunicode_utility_code = UtilityCode(
7878 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7879 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7880 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7882 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7883 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7884 return PyUnicode_AS_UNICODE(ustring)[i];
7885 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7886 i += PyUnicode_GET_SIZE(ustring);
7887 return PyUnicode_AS_UNICODE(ustring)[i];
7889 PyErr_SetString(PyExc_IndexError, "string index out of range");
7890 return (Py_UNICODE)-1;
7894 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7896 PyObject *uchar_string;
7897 if (!j) return (Py_UNICODE)-1;
7898 uchar_string = PyObject_GetItem(ustring, j);
7900 if (!uchar_string) return (Py_UNICODE)-1;
7901 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7902 Py_DECREF(uchar_string);
7907 getitem_int_utility_code = UtilityCode(
7910 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7912 if (!j) return NULL;
7913 r = PyObject_GetItem(o, j);
7920 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7921 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7922 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7924 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
7925 if (likely(o != Py_None)) {
7926 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
7927 PyObject *r = Py%(type)s_GET_ITEM(o, i);
7931 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
7932 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
7937 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7939 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
7942 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7943 __Pyx_GetItemInt_Fast(o, i) : \\
7944 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7946 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
7948 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7949 r = PyList_GET_ITEM(o, i);
7952 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
7953 r = PyTuple_GET_ITEM(o, i);
7956 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
7957 r = PySequence_GetItem(o, i);
7960 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7970 #------------------------------------------------------------------------------------
7972 setitem_int_utility_code = UtilityCode(
7974 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7975 __Pyx_SetItemInt_Fast(o, i, v) : \\
7976 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
7978 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
7981 r = PyObject_SetItem(o, j, v);
7986 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
7987 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7989 Py_DECREF(PyList_GET_ITEM(o, i));
7990 PyList_SET_ITEM(o, i, v);
7993 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
7994 return PySequence_SetItem(o, i, v);
7996 PyObject *j = PyInt_FromSsize_t(i);
7997 return __Pyx_SetItemInt_Generic(o, j, v);
8004 #------------------------------------------------------------------------------------
8006 delitem_int_utility_code = UtilityCode(
8008 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8009 __Pyx_DelItemInt_Fast(o, i) : \\
8010 __Pyx_DelItem_Generic(o, to_py_func(i)))
8012 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8015 r = PyObject_DelItem(o, j);
8020 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8021 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
8022 return PySequence_DelItem(o, i);
8024 PyObject *j = PyInt_FromSsize_t(i);
8025 return __Pyx_DelItem_Generic(o, j);
8032 #------------------------------------------------------------------------------------
8034 raise_too_many_values_to_unpack = UtilityCode(
8036 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8039 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
8040 PyErr_Format(PyExc_ValueError,
8041 #if PY_VERSION_HEX < 0x02050000
8042 "too many values to unpack (expected %d)", (int)expected);
8044 "too many values to unpack (expected %zd)", expected);
8049 raise_need_more_values_to_unpack = UtilityCode(
8051 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8054 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8055 PyErr_Format(PyExc_ValueError,
8056 #if PY_VERSION_HEX < 0x02050000
8057 "need more than %d value%s to unpack", (int)index,
8059 "need more than %zd value%s to unpack", index,
8061 (index == 1) ? "" : "s");
8065 #------------------------------------------------------------------------------------
8067 tuple_unpacking_error_code = UtilityCode(
8069 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8072 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
8074 __Pyx_RaiseNoneNotIterableError();
8075 } else if (PyTuple_GET_SIZE(t) < index) {
8076 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
8078 __Pyx_RaiseTooManyValuesError(index);
8082 requires = [raise_none_iter_error_utility_code,
8083 raise_need_more_values_to_unpack,
8084 raise_too_many_values_to_unpack]
8087 unpacking_utility_code = UtilityCode(
8089 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8090 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8093 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
8095 if (!(item = PyIter_Next(iter))) {
8096 if (!PyErr_Occurred()) {
8097 __Pyx_RaiseNeedMoreValuesError(index);
8103 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8105 if ((item = PyIter_Next(iter))) {
8107 __Pyx_RaiseTooManyValuesError(expected);
8110 else if (!PyErr_Occurred())
8116 requires = [raise_need_more_values_to_unpack,
8117 raise_too_many_values_to_unpack]
8120 #------------------------------------------------------------------------------------
8122 # CPython supports calling functions with non-dict kwargs by
8123 # converting them to a dict first
8125 kwargs_call_utility_code = UtilityCode(
8127 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
8130 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
8132 if (likely(PyDict_Check(kwargs))) {
8133 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
8135 PyObject* real_dict;
8136 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
8137 if (unlikely(!real_dict))
8139 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
8140 Py_DECREF(real_dict);
8141 return result; /* may be NULL */
8148 #------------------------------------------------------------------------------------
8150 int_pow_utility_code = UtilityCode(
8152 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8155 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8167 if (unlikely(e<0)) return 0;
8170 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8178 # ------------------------------ Division ------------------------------------
8180 div_int_utility_code = UtilityCode(
8182 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8185 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8187 %(type)s r = a - q*b;
8188 q -= ((r != 0) & ((r ^ b) < 0));
8193 mod_int_utility_code = UtilityCode(
8195 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8198 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8199 %(type)s r = a %% b;
8200 r += ((r != 0) & ((r ^ b) < 0)) * b;
8205 mod_float_utility_code = UtilityCode(
8207 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8210 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8211 %(type)s r = fmod%(math_h_modifier)s(a, b);
8212 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8217 cdivision_warning_utility_code = UtilityCode(
8219 static int __Pyx_cdivision_warning(void); /* proto */
8222 static int __Pyx_cdivision_warning(void) {
8223 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8224 "division with oppositely signed operands, C and Python semantics differ",
8231 'FILENAME': Naming.filename_cname,
8232 'LINENO': Naming.lineno_cname,
8236 division_overflow_test_code = UtilityCode(
8238 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8239 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8243 binding_cfunc_utility_code = UtilityCode(
8245 #define %(binding_cfunc)s_USED 1
8248 PyCFunctionObject func;
8249 } %(binding_cfunc)s_object;
8251 PyTypeObject %(binding_cfunc)s_type;
8252 PyTypeObject *%(binding_cfunc)s = NULL;
8254 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8255 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8257 int %(binding_cfunc)s_init(void); /* proto */
8258 """ % Naming.__dict__,
8261 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8262 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8267 op->func.m_self = self;
8269 op->func.m_module = module;
8270 PyObject_GC_Track(op);
8271 return (PyObject *)op;
8274 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8275 PyObject_GC_UnTrack(m);
8276 Py_XDECREF(m->func.m_self);
8277 Py_XDECREF(m->func.m_module);
8281 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8284 return PyMethod_New(func, obj, type);
8287 int %(binding_cfunc)s_init(void) {
8288 %(binding_cfunc)s_type = PyCFunction_Type;
8289 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8290 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8291 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8292 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8295 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8299 """ % Naming.__dict__)
8301 generator_utility_code = UtilityCode(
8303 static PyObject *__CyGenerator_Next(PyObject *self);
8304 static PyObject *__CyGenerator_Send(PyObject *self, PyObject *value);
8305 typedef PyObject *(*__cygenerator_body_t)(PyObject *, PyObject *, int);
8308 static CYTHON_INLINE PyObject *__CyGenerator_SendEx(struct __CyGenerator *self, PyObject *value, int is_exc)
8312 if (self->is_running) {
8313 PyErr_SetString(PyExc_ValueError,
8314 "generator already executing");
8318 if (self->resume_label == 0) {
8319 if (value && value != Py_None) {
8320 PyErr_SetString(PyExc_TypeError,
8321 "can't send non-None value to a "
8322 "just-started generator");
8327 self->is_running = 1;
8328 retval = self->body((PyObject *) self, value, is_exc);
8329 self->is_running = 0;
8334 static PyObject *__CyGenerator_Next(PyObject *self)
8336 struct __CyGenerator *generator = (struct __CyGenerator *) self;
8340 retval = __CyGenerator_SendEx(generator, Py_None, 0);
8345 static PyObject *__CyGenerator_Send(PyObject *self, PyObject *value)
8347 return __CyGenerator_SendEx((struct __CyGenerator *) self, value, 0);
8349 """, proto_block='utility_code_proto_before_types')