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.
80 # result_is_used boolean indicates that the result will be dropped and the
81 # result_code/temp_result can safely be set to None
86 old_temp = None # error checker for multiple frees etc.
87 use_managed_ref = True # can be set by optimisation transforms
90 # The Analyse Expressions phase for expressions is split
91 # into two sub-phases:
94 # Determines the result type of the expression based
95 # on the types of its sub-expressions, and inserts
96 # coercion nodes into the expression tree where needed.
97 # Marks nodes which will need to have temporary variables
101 # Allocates temporary variables where needed, and fills
102 # in the result_code field of each node.
104 # ExprNode provides some convenience routines which
105 # perform both of the above phases. These should only
106 # be called from statement nodes, and only when no
107 # coercion nodes need to be added around the expression
108 # being analysed. In that case, the above two phases
109 # should be invoked separately.
111 # Framework code in ExprNode provides much of the common
112 # processing for the various phases. It makes use of the
113 # 'subexprs' class attribute of ExprNodes, which should
114 # contain a list of the names of attributes which can
115 # hold sub-nodes or sequences of sub-nodes.
117 # The framework makes use of a number of abstract methods.
118 # Their responsibilities are as follows.
120 # Declaration Analysis phase
122 # analyse_target_declaration
123 # Called during the Analyse Declarations phase to analyse
124 # the LHS of an assignment or argument of a del statement.
125 # Nodes which cannot be the LHS of an assignment need not
128 # Expression Analysis phase
131 # - Call analyse_types on all sub-expressions.
132 # - Check operand types, and wrap coercion nodes around
133 # sub-expressions where needed.
134 # - Set the type of this node.
135 # - If a temporary variable will be required for the
136 # result, set the is_temp flag of this node.
138 # analyse_target_types
139 # Called during the Analyse Types phase to analyse
140 # the LHS of an assignment or argument of a del
141 # statement. Similar responsibilities to analyse_types.
144 # Called by the default implementation of allocate_target_temps.
145 # Should return a C lvalue for assigning to the node. The default
146 # implementation calls calculate_result_code.
149 # - Check that this node and its subnodes form a
150 # legal constant expression. If so, do nothing,
151 # otherwise call not_const.
153 # The default implementation of check_const
154 # assumes that the expression is not constant.
157 # - Same as check_const, except check that the
158 # expression is a C lvalue whose address is
159 # constant. Otherwise, call addr_not_const.
161 # The default implementation of calc_const_addr
162 # assumes that the expression is not a constant
165 # Code Generation phase
167 # generate_evaluation_code
168 # - Call generate_evaluation_code for sub-expressions.
169 # - Perform the functions of generate_result_code
171 # - If result is temporary, call generate_disposal_code
172 # on all sub-expressions.
174 # A default implementation of generate_evaluation_code
175 # is provided which uses the following abstract methods:
177 # generate_result_code
178 # - Generate any C statements necessary to calculate
179 # the result of this node from the results of its
182 # calculate_result_code
183 # - Should return a C code fragment evaluating to the
184 # result. This is only called when the result is not
187 # generate_assignment_code
188 # Called on the LHS of an assignment.
189 # - Call generate_evaluation_code for sub-expressions.
190 # - Generate code to perform the assignment.
191 # - If the assignment absorbed a reference, call
192 # generate_post_assignment_code on the RHS,
193 # otherwise call generate_disposal_code on it.
195 # generate_deletion_code
196 # Called on an argument of a del statement.
197 # - Call generate_evaluation_code for sub-expressions.
198 # - Generate code to perform the deletion.
199 # - Call generate_disposal_code on all sub-expressions.
203 is_sequence_constructor = 0
206 saved_subexpr_nodes = None
211 constant_result = constant_value_not_set
214 _get_child_attrs = operator.attrgetter('subexprs')
215 except AttributeError:
217 def __get_child_attrs(self):
219 _get_child_attrs = __get_child_attrs
220 child_attrs = property(fget=_get_child_attrs)
222 def not_implemented(self, method_name):
223 print_call_chain(method_name, "not implemented") ###
225 "%s.%s not implemented" %
226 (self.__class__.__name__, method_name))
231 def is_ephemeral(self):
232 # An ephemeral node is one whose result is in
233 # a Python temporary and we suspect there are no
234 # other references to it. Certain operations are
235 # disallowed on such values, since they are
236 # likely to result in a dangling pointer.
237 return self.type.is_pyobject and self.is_temp
239 def subexpr_nodes(self):
240 # Extract a list of subexpression nodes based
241 # on the contents of the subexprs class attribute.
243 for name in self.subexprs:
244 item = getattr(self, name)
246 if type(item) is list:
254 return self.temp_code
256 return self.calculate_result_code()
258 def result_as(self, type = None):
259 # Return the result code cast to the specified C type.
260 return typecast(type, self.ctype(), self.result())
263 # Return the result code cast to PyObject *.
264 return self.result_as(py_object_type)
267 # Return the native C type of the result (i.e. the
268 # C type of the result_code expression).
269 return self.result_ctype or self.type
271 def get_constant_c_result_code(self):
272 # Return the constant value of this node as a result code
273 # string, or None if the node is not constant. This method
274 # can be called when the constant result code is required
275 # before the code generation phase.
277 # The return value is a string that can represent a simple C
278 # value, a constant C name or a constant C expression. If the
279 # node type depends on Python code, this must return None.
282 def calculate_constant_result(self):
283 # Calculate the constant compile time result value of this
284 # expression and store it in ``self.constant_result``. Does
285 # nothing by default, thus leaving ``self.constant_result``
286 # unknown. If valid, the result can be an arbitrary Python
289 # This must only be called when it is assured that all
290 # sub-expressions have a valid constant_result value. The
291 # ConstantFolding transform will do this.
294 def has_constant_result(self):
295 return self.constant_result is not constant_value_not_set and \
296 self.constant_result is not not_a_constant
298 def compile_time_value(self, denv):
299 # Return value of compile-time expression, or report error.
300 error(self.pos, "Invalid compile-time expression")
302 def compile_time_value_error(self, e):
303 error(self.pos, "Error in compile-time expression: %s: %s" % (
304 e.__class__.__name__, e))
306 # ------------- Declaration Analysis ----------------
308 def analyse_target_declaration(self, env):
309 error(self.pos, "Cannot assign to or delete this")
311 # ------------- Expression Analysis ----------------
313 def analyse_const_expression(self, env):
314 # Called during the analyse_declarations phase of a
315 # constant expression. Analyses the expression's type,
316 # checks whether it is a legal const expression,
317 # and determines its value.
318 self.analyse_types(env)
319 return self.check_const()
321 def analyse_expressions(self, env):
322 # Convenience routine performing both the Type
323 # Analysis and Temp Allocation phases for a whole
325 self.analyse_types(env)
327 def analyse_target_expression(self, env, rhs):
328 # Convenience routine performing both the Type
329 # Analysis and Temp Allocation phases for the LHS of
331 self.analyse_target_types(env)
333 def analyse_boolean_expression(self, env):
334 # Analyse expression and coerce to a boolean.
335 self.analyse_types(env)
336 bool = self.coerce_to_boolean(env)
339 def analyse_temp_boolean_expression(self, env):
340 # Analyse boolean expression and coerce result into
341 # a temporary. This is used when a branch is to be
342 # performed on the result and we won't have an
343 # opportunity to ensure disposal code is executed
344 # afterwards. By forcing the result into a temporary,
345 # we ensure that all disposal has been done by the
346 # time we get the result.
347 self.analyse_types(env)
348 return self.coerce_to_boolean(env).coerce_to_simple(env)
350 # --------------- Type Inference -----------------
352 def type_dependencies(self, env):
353 # Returns the list of entries whose types must be determined
354 # before the type of self can be infered.
355 if hasattr(self, 'type') and self.type is not None:
357 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
359 def infer_type(self, env):
360 # Attempt to deduce the type of self.
361 # Differs from analyse_types as it avoids unnecessary
362 # analysis of subexpressions, but can assume everything
363 # in self.type_dependencies() has been resolved.
364 if hasattr(self, 'type') and self.type is not None:
366 elif hasattr(self, 'entry') and self.entry is not None:
367 return self.entry.type
369 self.not_implemented("infer_type")
371 def nonlocally_immutable(self):
372 # Returns whether this variable is a safe reference, i.e.
373 # can't be modified as part of globals or closures.
374 return self.is_temp or self.type.is_array or self.type.is_cfunction
376 # --------------- Type Analysis ------------------
378 def analyse_as_module(self, env):
379 # If this node can be interpreted as a reference to a
380 # cimported module, return its scope, else None.
383 def analyse_as_type(self, env):
384 # If this node can be interpreted as a reference to a
385 # type, return that type, else None.
388 def analyse_as_extension_type(self, env):
389 # If this node can be interpreted as a reference to an
390 # extension type, return its type, else None.
393 def analyse_types(self, env):
394 self.not_implemented("analyse_types")
396 def analyse_target_types(self, env):
397 self.analyse_types(env)
399 def nogil_check(self, env):
400 # By default, any expression based on Python objects is
401 # prevented in nogil environments. Subtypes must override
402 # this if they can work without the GIL.
403 if self.type.is_pyobject:
406 def gil_assignment_check(self, env):
407 if env.nogil and self.type.is_pyobject:
408 error(self.pos, "Assignment of Python object not allowed without gil")
410 def check_const(self):
415 error(self.pos, "Not allowed in a constant expression")
417 def check_const_addr(self):
418 self.addr_not_const()
421 def addr_not_const(self):
422 error(self.pos, "Address is not constant")
424 # ----------------- Result Allocation -----------------
426 def result_in_temp(self):
427 # Return true if result is in a temporary owned by
428 # this node or one of its subexpressions. Overridden
429 # by certain nodes which can share the result of
433 def target_code(self):
434 # Return code fragment for use as LHS of a C assignment.
435 return self.calculate_result_code()
437 def calculate_result_code(self):
438 self.not_implemented("calculate_result_code")
440 # def release_target_temp(self, env):
441 # # Release temporaries used by LHS of an assignment.
442 # self.release_subexpr_temps(env)
444 def allocate_temp_result(self, code):
446 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
450 type = PyrexTypes.py_object_type
451 self.temp_code = code.funcstate.allocate_temp(
452 type, manage_ref=self.use_managed_ref)
454 self.temp_code = None
456 def release_temp_result(self, code):
457 if not self.temp_code:
458 if not self.result_is_used:
459 # not used anyway, so ignore if not set up
462 raise RuntimeError("temp %s released multiple times in %s" % (
463 self.old_temp, self.__class__.__name__))
465 raise RuntimeError("no temp, but release requested in %s" % (
466 self.__class__.__name__))
467 code.funcstate.release_temp(self.temp_code)
468 self.old_temp = self.temp_code
469 self.temp_code = None
471 # ---------------- Code Generation -----------------
473 def make_owned_reference(self, code):
474 # If result is a pyobject, make sure we own
476 if self.type.is_pyobject and not self.result_in_temp():
477 code.put_incref(self.result(), self.ctype())
479 def generate_evaluation_code(self, code):
480 code.mark_pos(self.pos)
482 # Generate code to evaluate this node and
483 # its sub-expressions, and dispose of any
484 # temporary results of its sub-expressions.
485 self.generate_subexpr_evaluation_code(code)
488 self.allocate_temp_result(code)
490 self.generate_result_code(code)
492 # If we are temp we do not need to wait until this node is disposed
493 # before disposing children.
494 self.generate_subexpr_disposal_code(code)
495 self.free_subexpr_temps(code)
497 def generate_subexpr_evaluation_code(self, code):
498 for node in self.subexpr_nodes():
499 node.generate_evaluation_code(code)
501 def generate_result_code(self, code):
502 self.not_implemented("generate_result_code")
504 def generate_disposal_code(self, code):
506 if self.type.is_pyobject and self.result():
507 code.put_decref_clear(self.result(), self.ctype())
509 # Already done if self.is_temp
510 self.generate_subexpr_disposal_code(code)
512 def generate_subexpr_disposal_code(self, code):
513 # Generate code to dispose of temporary results
514 # of all sub-expressions.
515 for node in self.subexpr_nodes():
516 node.generate_disposal_code(code)
518 def generate_post_assignment_code(self, code):
520 if self.type.is_pyobject:
521 code.putln("%s = 0;" % self.result())
523 self.generate_subexpr_disposal_code(code)
525 def generate_assignment_code(self, rhs, code):
526 # Stub method for nodes which are not legal as
527 # the LHS of an assignment. An error will have
528 # been reported earlier.
531 def generate_deletion_code(self, code):
532 # Stub method for nodes that are not legal as
533 # the argument of a del statement. An error
534 # will have been reported earlier.
537 def free_temps(self, code):
539 if not self.type.is_void:
540 self.release_temp_result(code)
542 self.free_subexpr_temps(code)
544 def free_subexpr_temps(self, code):
545 for sub in self.subexpr_nodes():
548 def generate_function_definitions(self, env, code):
551 # ---------------- Annotation ---------------------
553 def annotate(self, code):
554 for node in self.subexpr_nodes():
557 # ----------------- Coercion ----------------------
559 def coerce_to(self, dst_type, env):
560 # Coerce the result so that it can be assigned to
561 # something of type dst_type. If processing is necessary,
562 # wraps this node in a coercion node and returns that.
563 # Otherwise, returns this node unchanged.
565 # This method is called during the analyse_expressions
566 # phase of the src_node's processing.
568 # Note that subclasses that override this (especially
569 # ConstNodes) must not (re-)set their own .type attribute
570 # here. Since expression nodes may turn up in different
571 # places in the tree (e.g. inside of CloneNodes in cascaded
572 # assignments), this method must return a new node instance
573 # if it changes the type.
577 src_is_py_type = src_type.is_pyobject
578 dst_is_py_type = dst_type.is_pyobject
580 if self.check_for_coercion_error(dst_type):
583 if dst_type.is_reference:
584 dst_type = dst_type.ref_base_type
586 if dst_type.is_pyobject:
587 if not src.type.is_pyobject:
588 if dst_type is bytes_type and src.type.is_int:
589 src = CoerceIntToBytesNode(src, env)
591 src = CoerceToPyTypeNode(src, env)
592 if not src.type.subtype_of(dst_type):
593 if not isinstance(src, NoneNode):
594 src = PyTypeTestNode(src, dst_type, env)
595 elif src.type.is_pyobject:
596 src = CoerceFromPyTypeNode(dst_type, src, env)
597 elif (dst_type.is_complex
598 and src_type != dst_type
599 and dst_type.assignable_from(src_type)):
600 src = CoerceToComplexNode(src, dst_type, env)
601 else: # neither src nor dst are py types
602 # Added the string comparison, since for c types that
603 # is enough, but Cython gets confused when the types are
604 # in different pxi files.
605 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
606 self.fail_assignment(dst_type)
609 def fail_assignment(self, dst_type):
610 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
612 def check_for_coercion_error(self, dst_type, fail=False, default=None):
613 if fail and not default:
614 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
615 message = find_coercion_error((self.type, dst_type), default)
616 if message is not None:
617 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
620 self.fail_assignment(dst_type)
624 def coerce_to_pyobject(self, env):
625 return self.coerce_to(PyrexTypes.py_object_type, env)
627 def coerce_to_boolean(self, env):
628 # Coerce result to something acceptable as
631 # if it's constant, calculate the result now
632 if self.has_constant_result():
633 bool_value = bool(self.constant_result)
634 return BoolNode(self.pos, value=bool_value,
635 constant_result=bool_value)
638 if type.is_pyobject or type.is_ptr or type.is_float:
639 return CoerceToBooleanNode(self, env)
641 if not (type.is_int or type.is_enum or type.is_error):
643 "Type '%s' not acceptable as a boolean" % type)
646 def coerce_to_integer(self, env):
647 # If not already some C integer type, coerce to longint.
651 return self.coerce_to(PyrexTypes.c_long_type, env)
653 def coerce_to_temp(self, env):
654 # Ensure that the result is in a temporary.
655 if self.result_in_temp():
658 return CoerceToTempNode(self, env)
660 def coerce_to_simple(self, env):
661 # Ensure that the result is simple (see is_simple).
665 return self.coerce_to_temp(env)
668 # A node is simple if its result is something that can
669 # be referred to without performing any operations, e.g.
670 # a constant, local var, C global var, struct member
671 # reference, or temporary.
672 return self.result_in_temp()
674 def may_be_none(self):
675 if not self.type.is_pyobject:
677 if self.constant_result not in (not_a_constant, constant_value_not_set):
678 return self.constant_result is not None
681 def as_cython_attribute(self):
684 def as_none_safe_node(self, message, error="PyExc_TypeError"):
685 # Wraps the node in a NoneCheckNode if it is not known to be
686 # not-None (e.g. because it is a Python literal).
687 if self.may_be_none():
688 return NoneCheckNode(self, error, message)
693 class AtomicExprNode(ExprNode):
694 # Abstract base class for expression nodes which have
695 # no sub-expressions.
699 # Override to optimize -- we know we have no children
700 def generate_subexpr_evaluation_code(self, code):
702 def generate_subexpr_disposal_code(self, code):
705 class PyConstNode(AtomicExprNode):
706 # Abstract base class for constant Python values.
709 type = py_object_type
714 def may_be_none(self):
717 def analyse_types(self, env):
720 def calculate_result_code(self):
723 def generate_result_code(self, code):
727 class NoneNode(PyConstNode):
728 # The constant value None
732 constant_result = None
736 def compile_time_value(self, denv):
739 def may_be_none(self):
743 class EllipsisNode(PyConstNode):
744 # '...' in a subscript list.
746 value = "Py_Ellipsis"
748 constant_result = Ellipsis
750 def compile_time_value(self, denv):
754 class ConstNode(AtomicExprNode):
755 # Abstract base type for literal constant nodes.
757 # value string C code fragment
765 def nonlocally_immutable(self):
768 def may_be_none(self):
771 def analyse_types(self, env):
772 pass # Types are held in class variables
774 def check_const(self):
777 def get_constant_c_result_code(self):
778 return self.calculate_result_code()
780 def calculate_result_code(self):
781 return str(self.value)
783 def generate_result_code(self, code):
787 class BoolNode(ConstNode):
788 type = PyrexTypes.c_bint_type
789 # The constant value True or False
791 def calculate_constant_result(self):
792 self.constant_result = self.value
794 def compile_time_value(self, denv):
797 def calculate_result_code(self):
798 return str(int(self.value))
801 class NullNode(ConstNode):
802 type = PyrexTypes.c_null_ptr_type
806 def get_constant_c_result_code(self):
810 class CharNode(ConstNode):
811 type = PyrexTypes.c_char_type
813 def calculate_constant_result(self):
814 self.constant_result = ord(self.value)
816 def compile_time_value(self, denv):
817 return ord(self.value)
819 def calculate_result_code(self):
820 return "'%s'" % StringEncoding.escape_char(self.value)
823 class IntNode(ConstNode):
826 # longness "" or "L" or "LL"
827 # is_c_literal True/False/None creator considers this a C integer literal
831 is_c_literal = None # unknown
833 def __init__(self, pos, **kwds):
834 ExprNode.__init__(self, pos, **kwds)
835 if 'type' not in kwds:
836 self.type = self.find_suitable_type_for_value()
838 def find_suitable_type_for_value(self):
839 if self.constant_result is constant_value_not_set:
841 self.calculate_constant_result()
844 # we ignore 'is_c_literal = True' and instead map signed 32bit
845 # integers as C long values
846 if self.is_c_literal or \
847 self.constant_result in (constant_value_not_set, not_a_constant) or \
848 self.unsigned or self.longness == 'LL':
849 # clearly a C literal
850 rank = (self.longness == 'LL') and 2 or 1
851 suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
853 suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
855 # C literal or Python literal - split at 32bit boundary
856 if self.constant_result >= -2**31 and self.constant_result < 2**31:
857 if self.type and self.type.is_int:
858 suitable_type = self.type
860 suitable_type = PyrexTypes.c_long_type
862 suitable_type = PyrexTypes.py_object_type
865 def coerce_to(self, dst_type, env):
866 if self.type is dst_type:
868 elif dst_type.is_float:
869 if self.constant_result is not not_a_constant:
870 return FloatNode(self.pos, value='%d.0' % int(self.constant_result), type=dst_type,
871 constant_result=float(self.constant_result))
873 return FloatNode(self.pos, value=self.value, type=dst_type,
874 constant_result=not_a_constant)
875 if dst_type.is_numeric and not dst_type.is_complex:
876 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
877 type = dst_type, is_c_literal = True,
878 unsigned=self.unsigned, longness=self.longness)
880 elif dst_type.is_pyobject:
881 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
882 type = PyrexTypes.py_object_type, is_c_literal = False,
883 unsigned=self.unsigned, longness=self.longness)
885 # FIXME: not setting the type here to keep it working with
886 # complex numbers. Should they be special cased?
887 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
888 unsigned=self.unsigned, longness=self.longness)
889 # We still need to perform normal coerce_to processing on the
890 # result, because we might be coercing to an extension type,
891 # in which case a type test node will be needed.
892 return ConstNode.coerce_to(node, dst_type, env)
894 def coerce_to_boolean(self, env):
896 self.pos, value=self.value,
897 type = PyrexTypes.c_bint_type,
898 unsigned=self.unsigned, longness=self.longness)
900 def generate_evaluation_code(self, code):
901 if self.type.is_pyobject:
902 # pre-allocate a Python version of the number
903 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
904 self.result_code = code.get_py_num(plain_integer_string, self.longness)
906 self.result_code = self.get_constant_c_result_code()
908 def get_constant_c_result_code(self):
909 return self.value_as_c_integer_string() + self.unsigned + self.longness
911 def value_as_c_integer_string(self, plain_digits=False):
913 if isinstance(value, basestring) and len(value) > 2:
914 # must convert C-incompatible Py3 oct/bin notations
917 value = int(value[2:], 8)
919 value = value[0] + value[2:] # '0o123' => '0123'
920 elif value[1] in 'bB':
921 value = int(value[2:], 2)
922 elif plain_digits and value[1] in 'xX':
923 value = int(value[2:], 16)
926 def calculate_result_code(self):
927 return self.result_code
929 def calculate_constant_result(self):
930 self.constant_result = Utils.str_to_number(self.value)
932 def compile_time_value(self, denv):
933 return Utils.str_to_number(self.value)
936 class FloatNode(ConstNode):
937 type = PyrexTypes.c_double_type
939 def calculate_constant_result(self):
940 self.constant_result = float(self.value)
942 def compile_time_value(self, denv):
943 return float(self.value)
945 def calculate_result_code(self):
947 assert isinstance(strval, (str, unicode))
948 cmpval = repr(float(strval))
950 return "(Py_HUGE_VAL * 0)"
951 elif cmpval == 'inf':
953 elif cmpval == '-inf':
954 return "(-Py_HUGE_VAL)"
959 class BytesNode(ConstNode):
960 # A char* or bytes literal
964 # start off as Python 'bytes' to support len() in O(1)
967 def compile_time_value(self, denv):
970 def analyse_as_type(self, env):
971 type = PyrexTypes.parse_basic_type(self.value)
974 from TreeFragment import TreeFragment
975 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
976 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
977 sizeof_node = declaration.root.stats[0].expr
978 sizeof_node.analyse_types(env)
979 if isinstance(sizeof_node, SizeofTypeNode):
980 return sizeof_node.arg_type
982 def can_coerce_to_char_literal(self):
983 return len(self.value) == 1
985 def coerce_to_boolean(self, env):
986 # This is special because testing a C char* for truth directly
987 # would yield the wrong result.
988 return BoolNode(self.pos, value=bool(self.value))
990 def coerce_to(self, dst_type, env):
991 if self.type == dst_type:
994 if not self.can_coerce_to_char_literal():
995 error(self.pos, "Only single-character string literals can be coerced into ints.")
997 if dst_type.is_unicode_char:
998 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
1000 return CharNode(self.pos, value=self.value)
1002 node = BytesNode(self.pos, value=self.value)
1003 if dst_type.is_pyobject:
1004 if dst_type in (py_object_type, Builtin.bytes_type):
1005 node.type = Builtin.bytes_type
1007 self.check_for_coercion_error(dst_type, fail=True)
1009 elif dst_type == PyrexTypes.c_char_ptr_type:
1010 node.type = dst_type
1012 elif dst_type == PyrexTypes.c_uchar_ptr_type:
1013 node.type = PyrexTypes.c_char_ptr_type
1014 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
1015 elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
1016 node.type = dst_type
1019 # We still need to perform normal coerce_to processing on the
1020 # result, because we might be coercing to an extension type,
1021 # in which case a type test node will be needed.
1022 return ConstNode.coerce_to(node, dst_type, env)
1024 def generate_evaluation_code(self, code):
1025 if self.type.is_pyobject:
1026 self.result_code = code.get_py_string_const(self.value)
1028 self.result_code = code.get_string_const(self.value)
1030 def get_constant_c_result_code(self):
1033 def calculate_result_code(self):
1034 return self.result_code
1037 class UnicodeNode(PyConstNode):
1038 # A Python unicode object
1040 # value EncodedString
1041 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
1046 def coerce_to(self, dst_type, env):
1047 if dst_type is self.type:
1049 elif dst_type.is_unicode_char:
1050 if not self.can_coerce_to_char_literal():
1051 error(self.pos, "Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
1053 int_value = ord(self.value)
1054 return IntNode(self.pos, type=dst_type, value=str(int_value), constant_result=int_value)
1055 elif not dst_type.is_pyobject:
1056 if dst_type.is_string and self.bytes_value is not None:
1057 # special case: '-3' enforced unicode literal used in a C char* context
1058 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
1059 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE or Py_UCS4.")
1060 elif dst_type is not py_object_type:
1061 if not self.check_for_coercion_error(dst_type):
1062 self.fail_assignment(dst_type)
1065 def can_coerce_to_char_literal(self):
1066 return len(self.value) == 1
1067 ## or (len(self.value) == 2
1068 ## and (0xD800 <= self.value[0] <= 0xDBFF)
1069 ## and (0xDC00 <= self.value[1] <= 0xDFFF))
1071 def contains_surrogates(self):
1072 # Check if the unicode string contains surrogate code points
1073 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1074 # Unicode, i.e. characters that would be spelled as two
1075 # separate code units on a narrow platform.
1076 for c in map(ord, self.value):
1077 if c > 65535: # can only happen on wide platforms
1079 # We only look for the first code unit (D800-DBFF) of a
1080 # surrogate pair - if we find one, the other one
1081 # (DC00-DFFF) is likely there, too. If we don't find it,
1082 # any second code unit cannot make for a surrogate pair by
1084 if c >= 0xD800 and c <= 0xDBFF:
1088 def generate_evaluation_code(self, code):
1089 self.result_code = code.get_py_string_const(self.value)
1091 def calculate_result_code(self):
1092 return self.result_code
1094 def compile_time_value(self, env):
1098 class StringNode(PyConstNode):
1099 # A Python str object, i.e. a byte string in Python 2.x and a
1100 # unicode string in Python 3.x
1102 # value BytesLiteral (or EncodedString with ASCII content)
1103 # unicode_value EncodedString or None
1104 # is_identifier boolean
1107 is_identifier = None
1108 unicode_value = None
1110 def coerce_to(self, dst_type, env):
1111 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1112 # if dst_type is Builtin.bytes_type:
1113 # # special case: bytes = 'str literal'
1114 # return BytesNode(self.pos, value=self.value)
1115 if not dst_type.is_pyobject:
1116 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1117 self.check_for_coercion_error(dst_type, fail=True)
1120 def can_coerce_to_char_literal(self):
1121 return not self.is_identifier and len(self.value) == 1
1123 def generate_evaluation_code(self, code):
1124 self.result_code = code.get_py_string_const(
1125 self.value, identifier=self.is_identifier, is_str=True,
1126 unicode_value=self.unicode_value)
1128 def get_constant_c_result_code(self):
1131 def calculate_result_code(self):
1132 return self.result_code
1134 def compile_time_value(self, env):
1138 class IdentifierStringNode(StringNode):
1139 # A special str value that represents an identifier (bytes in Py2,
1141 is_identifier = True
1144 class LongNode(AtomicExprNode):
1145 # Python long integer literal
1149 type = py_object_type
1151 def calculate_constant_result(self):
1152 self.constant_result = Utils.str_to_number(self.value)
1154 def compile_time_value(self, denv):
1155 return Utils.str_to_number(self.value)
1157 def analyse_types(self, env):
1160 def may_be_none(self):
1163 gil_message = "Constructing Python long int"
1165 def generate_result_code(self, code):
1167 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1170 code.error_goto_if_null(self.result(), self.pos)))
1171 code.put_gotref(self.py_result())
1174 class ImagNode(AtomicExprNode):
1175 # Imaginary number literal
1177 # value float imaginary part
1179 type = PyrexTypes.c_double_complex_type
1181 def calculate_constant_result(self):
1182 self.constant_result = complex(0.0, self.value)
1184 def compile_time_value(self, denv):
1185 return complex(0.0, self.value)
1187 def analyse_types(self, env):
1188 self.type.create_declaration_utility_code(env)
1190 def may_be_none(self):
1193 def coerce_to(self, dst_type, env):
1194 if self.type is dst_type:
1196 node = ImagNode(self.pos, value=self.value)
1197 if dst_type.is_pyobject:
1199 node.type = PyrexTypes.py_object_type
1200 # We still need to perform normal coerce_to processing on the
1201 # result, because we might be coercing to an extension type,
1202 # in which case a type test node will be needed.
1203 return AtomicExprNode.coerce_to(node, dst_type, env)
1205 gil_message = "Constructing complex number"
1207 def calculate_result_code(self):
1208 if self.type.is_pyobject:
1209 return self.result()
1211 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1213 def generate_result_code(self, code):
1214 if self.type.is_pyobject:
1216 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1219 code.error_goto_if_null(self.result(), self.pos)))
1220 code.put_gotref(self.py_result())
1223 class NewExprNode(AtomicExprNode):
1227 # cppclass node c++ class to create
1231 def infer_type(self, env):
1232 type = self.cppclass.analyse_as_type(env)
1233 if type is None or not type.is_cpp_class:
1234 error(self.pos, "new operator can only be applied to a C++ class")
1235 self.type = error_type
1238 constructor = type.scope.lookup(u'<init>')
1239 if constructor is None:
1240 return_type = PyrexTypes.CFuncType(type, [])
1241 return_type = PyrexTypes.CPtrType(return_type)
1242 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1243 constructor = type.scope.lookup(u'<init>')
1244 self.class_type = type
1245 self.entry = constructor
1246 self.type = constructor.type
1249 def analyse_types(self, env):
1250 if self.type is None:
1251 self.infer_type(env)
1253 def may_be_none(self):
1256 def generate_result_code(self, code):
1259 def calculate_result_code(self):
1260 return "new " + self.class_type.declaration_code("")
1263 class NameNode(AtomicExprNode):
1264 # Reference to a local or global variable name.
1266 # name string Python name of the variable
1267 # entry Entry Symbol table entry
1268 # type_entry Entry For extension type names, the original type entry
1271 is_cython_module = False
1272 cython_attribute = None
1273 lhs_of_first_assignment = False
1274 is_used_as_rvalue = 0
1278 def create_analysed_rvalue(pos, env, entry):
1279 node = NameNode(pos)
1280 node.analyse_types(env, entry=entry)
1283 def as_cython_attribute(self):
1284 return self.cython_attribute
1286 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1288 def type_dependencies(self, env):
1289 if self.entry is None:
1290 self.entry = env.lookup(self.name)
1291 if self.entry is not None and self.entry.type.is_unspecified:
1292 return (self.entry,)
1296 def infer_type(self, env):
1297 if self.entry is None:
1298 self.entry = env.lookup(self.name)
1299 if self.entry is None:
1300 return py_object_type
1301 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1302 self.name == self.entry.type.name:
1303 # Unfortunately the type attribute of type objects
1304 # is used for the pointer to the type they represent.
1306 elif self.entry.type.is_cfunction:
1307 # special case: referring to a C function must return its pointer
1308 return PyrexTypes.CPtrType(self.entry.type)
1310 return self.entry.type
1312 def compile_time_value(self, denv):
1314 return denv.lookup(self.name)
1316 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1318 def get_constant_c_result_code(self):
1319 if not self.entry or self.entry.type.is_pyobject:
1321 return self.entry.cname
1323 def coerce_to(self, dst_type, env):
1324 # If coercing to a generic pyobject and this is a builtin
1325 # C function with a Python equivalent, manufacture a NameNode
1326 # referring to the Python builtin.
1327 #print "NameNode.coerce_to:", self.name, dst_type ###
1328 if dst_type is py_object_type:
1330 if entry and entry.is_cfunction:
1331 var_entry = entry.as_variable
1333 if var_entry.is_builtin and var_entry.is_const:
1334 var_entry = env.declare_builtin(var_entry.name, self.pos)
1335 node = NameNode(self.pos, name = self.name)
1336 node.entry = var_entry
1337 node.analyse_rvalue_entry(env)
1339 return super(NameNode, self).coerce_to(dst_type, env)
1341 def analyse_as_module(self, env):
1342 # Try to interpret this as a reference to a cimported module.
1343 # Returns the module scope, or None.
1346 entry = env.lookup(self.name)
1347 if entry and entry.as_module:
1348 return entry.as_module
1351 def analyse_as_type(self, env):
1352 if self.cython_attribute:
1353 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1355 type = PyrexTypes.parse_basic_type(self.name)
1360 entry = env.lookup(self.name)
1361 if entry and entry.is_type:
1366 def analyse_as_extension_type(self, env):
1367 # Try to interpret this as a reference to an extension type.
1368 # Returns the extension type, or None.
1371 entry = env.lookup(self.name)
1372 if entry and entry.is_type and entry.type.is_extension_type:
1377 def analyse_target_declaration(self, env):
1379 self.entry = env.lookup_here(self.name)
1381 if env.directives['warn.undeclared']:
1382 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1383 if env.directives['infer_types'] != False:
1384 type = unspecified_type
1386 type = py_object_type
1387 self.entry = env.declare_var(self.name, type, self.pos)
1388 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1389 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1390 if self.entry.is_declared_generic:
1391 self.result_ctype = py_object_type
1393 def analyse_types(self, env):
1394 if self.entry is None:
1395 self.entry = env.lookup(self.name)
1397 self.entry = env.declare_builtin(self.name, self.pos)
1399 self.type = PyrexTypes.error_type
1404 if entry.type.is_buffer:
1406 Buffer.used_buffer_aux_vars(entry)
1407 if entry.utility_code:
1408 env.use_utility_code(entry.utility_code)
1409 self.analyse_rvalue_entry(env)
1411 def analyse_target_types(self, env):
1412 self.analyse_entry(env)
1413 if not self.is_lvalue():
1414 error(self.pos, "Assignment to non-lvalue '%s'"
1416 self.type = PyrexTypes.error_type
1418 if self.entry.type.is_buffer:
1420 Buffer.used_buffer_aux_vars(self.entry)
1422 def analyse_rvalue_entry(self, env):
1423 #print "NameNode.analyse_rvalue_entry:", self.name ###
1424 #print "Entry:", self.entry.__dict__ ###
1425 self.analyse_entry(env)
1427 if entry.is_declared_generic:
1428 self.result_ctype = py_object_type
1429 if entry.is_pyglobal or entry.is_builtin:
1430 if entry.is_builtin and entry.is_const:
1434 env.use_utility_code(get_name_interned_utility_code)
1435 self.is_used_as_rvalue = 1
1437 def nogil_check(self, env):
1438 if self.is_used_as_rvalue:
1440 if entry.is_builtin:
1441 if not entry.is_const: # cached builtins are ok
1443 elif entry.is_pyglobal:
1446 gil_message = "Accessing Python global or builtin"
1448 def analyse_entry(self, env):
1449 #print "NameNode.analyse_entry:", self.name ###
1450 self.check_identifier_kind()
1455 def check_identifier_kind(self):
1456 # Check that this is an appropriate kind of name for use in an
1457 # expression. Also finds the variable entry associated with
1458 # an extension type.
1460 if entry.is_type and entry.type.is_extension_type:
1461 self.type_entry = entry
1462 if not (entry.is_const or entry.is_variable
1463 or entry.is_builtin or entry.is_cfunction
1464 or entry.is_cpp_class):
1465 if self.entry.as_variable:
1466 self.entry = self.entry.as_variable
1469 "'%s' is not a constant, variable or function identifier" % self.name)
1471 def is_simple(self):
1472 # If it's not a C variable, it'll be in a temp.
1475 def nonlocally_immutable(self):
1476 if ExprNode.nonlocally_immutable(self):
1479 return entry and (entry.is_local or entry.is_arg) and not entry.in_closure
1481 def calculate_target_results(self, env):
1484 def check_const(self):
1486 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1491 def check_const_addr(self):
1493 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1494 self.addr_not_const()
1498 def is_lvalue(self):
1499 return self.entry.is_variable and \
1500 not self.entry.type.is_array and \
1501 not self.entry.is_readonly
1503 def is_ephemeral(self):
1504 # Name nodes are never ephemeral, even if the
1505 # result is in a temporary.
1508 def calculate_result_code(self):
1511 return "<error>" # There was an error earlier
1514 def generate_result_code(self, code):
1515 assert hasattr(self, 'entry')
1518 return # There was an error earlier
1519 if entry.is_builtin and entry.is_const:
1520 return # Lookup already cached
1521 elif entry.is_pyclass_attr:
1522 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1523 interned_cname = code.intern_identifier(self.entry.name)
1524 if entry.is_builtin:
1525 namespace = Naming.builtins_cname
1526 else: # entry.is_pyglobal
1527 namespace = entry.scope.namespace_cname
1529 '%s = PyObject_GetItem(%s, %s); %s' % (
1533 code.error_goto_if_null(self.result(), self.pos)))
1534 code.put_gotref(self.py_result())
1536 elif entry.is_pyglobal or entry.is_builtin:
1537 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1538 interned_cname = code.intern_identifier(self.entry.name)
1539 if entry.is_builtin:
1540 namespace = Naming.builtins_cname
1541 else: # entry.is_pyglobal
1542 namespace = entry.scope.namespace_cname
1543 code.globalstate.use_utility_code(get_name_interned_utility_code)
1545 '%s = __Pyx_GetName(%s, %s); %s' % (
1549 code.error_goto_if_null(self.result(), self.pos)))
1550 code.put_gotref(self.py_result())
1552 elif entry.is_local and False:
1553 # control flow not good enough yet
1554 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1555 if assigned is False:
1556 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1557 elif not Options.init_local_none and assigned is None:
1558 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1559 (entry.cname, entry.name, code.error_goto(self.pos)))
1560 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1562 def generate_assignment_code(self, rhs, code):
1563 #print "NameNode.generate_assignment_code:", self.name ###
1566 return # There was an error earlier
1568 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1569 and not self.lhs_of_first_assignment):
1570 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1572 # is_pyglobal seems to be True for module level-globals only.
1573 # We use this to access class->tp_dict if necessary.
1574 if entry.is_pyglobal:
1575 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1576 interned_cname = code.intern_identifier(self.entry.name)
1577 namespace = self.entry.scope.namespace_cname
1579 # if the entry is a member we have to cheat: SetAttr does not work
1580 # on types, so we create a descriptor which is then added to tp_dict
1581 code.put_error_if_neg(self.pos,
1582 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1586 rhs.generate_disposal_code(code)
1587 rhs.free_temps(code)
1588 # in Py2.6+, we need to invalidate the method cache
1589 code.putln("PyType_Modified(%s);" %
1590 entry.scope.parent_type.typeptr_cname)
1591 elif entry.is_pyclass_attr:
1592 code.put_error_if_neg(self.pos,
1593 'PyObject_SetItem(%s, %s, %s)' % (
1597 rhs.generate_disposal_code(code)
1598 rhs.free_temps(code)
1600 code.put_error_if_neg(self.pos,
1601 'PyObject_SetAttr(%s, %s, %s)' % (
1605 if debug_disposal_code:
1606 print("NameNode.generate_assignment_code:")
1607 print("...generating disposal code for %s" % rhs)
1608 rhs.generate_disposal_code(code)
1609 rhs.free_temps(code)
1611 if self.type.is_buffer:
1612 # Generate code for doing the buffer release/acquisition.
1613 # This might raise an exception in which case the assignment (done
1614 # below) will not happen.
1616 # The reason this is not in a typetest-like node is because the
1617 # variables that the acquired buffer info is stored to is allocated
1618 # per entry and coupled with it.
1619 self.generate_acquire_buffer(rhs, code)
1621 if self.type.is_pyobject:
1622 #print "NameNode.generate_assignment_code: to", self.name ###
1623 #print "...from", rhs ###
1624 #print "...LHS type", self.type, "ctype", self.ctype() ###
1625 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1626 if self.use_managed_ref:
1627 rhs.make_owned_reference(code)
1628 is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
1629 if not self.lhs_of_first_assignment:
1631 code.put_gotref(self.py_result())
1632 if entry.is_local and not Options.init_local_none:
1633 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1634 if initialized is True:
1635 code.put_decref(self.result(), self.ctype())
1636 elif initialized is None:
1637 code.put_xdecref(self.result(), self.ctype())
1639 code.put_decref(self.result(), self.ctype())
1641 code.put_giveref(rhs.py_result())
1643 code.putln('%s = %s;' % (self.result(),
1644 rhs.result_as(self.ctype())))
1645 if debug_disposal_code:
1646 print("NameNode.generate_assignment_code:")
1647 print("...generating post-assignment code for %s" % rhs)
1648 rhs.generate_post_assignment_code(code)
1649 rhs.free_temps(code)
1651 def generate_acquire_buffer(self, rhs, code):
1652 # rhstmp is only used in case the rhs is a complicated expression leading to
1653 # the object, to avoid repeating the same C expression for every reference
1654 # to the rhs. It does NOT hold a reference.
1655 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1657 rhstmp = rhs.result_as(self.ctype())
1659 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1660 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1662 buffer_aux = self.entry.buffer_aux
1663 bufstruct = buffer_aux.buffer_info_var.cname
1665 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1666 is_initialized=not self.lhs_of_first_assignment,
1667 pos=self.pos, code=code)
1670 code.putln("%s = 0;" % rhstmp)
1671 code.funcstate.release_temp(rhstmp)
1673 def generate_deletion_code(self, code):
1674 if self.entry is None:
1675 return # There was an error earlier
1676 elif self.entry.is_pyclass_attr:
1677 namespace = self.entry.scope.namespace_cname
1678 code.put_error_if_neg(self.pos,
1679 'PyMapping_DelItemString(%s, "%s")' % (
1682 elif self.entry.is_pyglobal:
1683 code.put_error_if_neg(self.pos,
1684 '__Pyx_DelAttrString(%s, "%s")' % (
1685 Naming.module_cname,
1687 elif self.entry.type.is_pyobject:
1688 # Fake it until we can do it for real...
1689 self.generate_assignment_code(NoneNode(self.pos), code)
1691 error(self.pos, "Deletion of C names not supported")
1693 def annotate(self, code):
1694 if hasattr(self, 'is_called') and self.is_called:
1695 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1696 if self.type.is_pyobject:
1697 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1699 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1701 class BackquoteNode(ExprNode):
1706 type = py_object_type
1710 def analyse_types(self, env):
1711 self.arg.analyse_types(env)
1712 self.arg = self.arg.coerce_to_pyobject(env)
1715 gil_message = "Backquote expression"
1717 def calculate_constant_result(self):
1718 self.constant_result = repr(self.arg.constant_result)
1720 def generate_result_code(self, code):
1722 "%s = PyObject_Repr(%s); %s" % (
1724 self.arg.py_result(),
1725 code.error_goto_if_null(self.result(), self.pos)))
1726 code.put_gotref(self.py_result())
1729 class ImportNode(ExprNode):
1730 # Used as part of import statement implementation.
1731 # Implements result =
1732 # __import__(module_name, globals(), None, name_list, level)
1734 # module_name StringNode dotted name of module. Empty module
1735 # name means importing the parent package accourding
1737 # name_list ListNode or None list of names to be imported
1738 # level int relative import level:
1739 # -1: attempt both relative import and absolute import;
1740 # 0: absolute import;
1741 # >0: the number of parent directories to search
1742 # relative to the current module.
1743 # None: decide the level according to language level and
1746 type = py_object_type
1748 subexprs = ['module_name', 'name_list']
1750 def analyse_types(self, env):
1751 if self.level is None:
1752 if env.directives['language_level'] < 3 or env.directives['py2_import']:
1756 self.module_name.analyse_types(env)
1757 self.module_name = self.module_name.coerce_to_pyobject(env)
1759 self.name_list.analyse_types(env)
1760 self.name_list.coerce_to_pyobject(env)
1762 env.use_utility_code(import_utility_code)
1764 gil_message = "Python import"
1766 def generate_result_code(self, code):
1768 name_list_code = self.name_list.py_result()
1770 name_list_code = "0"
1772 "%s = __Pyx_Import(%s, %s, %d); %s" % (
1774 self.module_name.py_result(),
1777 code.error_goto_if_null(self.result(), self.pos)))
1778 code.put_gotref(self.py_result())
1781 class IteratorNode(ExprNode):
1782 # Used as part of for statement implementation.
1784 # allocate_counter_temp/release_counter_temp needs to be called
1785 # by parent (ForInStatNode)
1787 # Implements result = iter(sequence)
1791 type = py_object_type
1793 subexprs = ['sequence']
1795 def analyse_types(self, env):
1796 self.sequence.analyse_types(env)
1797 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1798 not self.sequence.type.is_string:
1799 # C array iteration will be transformed later on
1800 self.type = self.sequence.type
1802 self.sequence = self.sequence.coerce_to_pyobject(env)
1803 if self.sequence.type is list_type or \
1804 self.sequence.type is tuple_type:
1805 self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
1808 gil_message = "Iterating over Python object"
1810 def allocate_counter_temp(self, code):
1811 self.counter_cname = code.funcstate.allocate_temp(
1812 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1814 def release_counter_temp(self, code):
1815 code.funcstate.release_temp(self.counter_cname)
1817 def generate_result_code(self, code):
1818 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1819 raise InternalError("for in carray slice not transformed")
1820 is_builtin_sequence = self.sequence.type is list_type or \
1821 self.sequence.type is tuple_type
1822 may_be_a_sequence = not self.sequence.type.is_builtin_type
1823 if may_be_a_sequence:
1825 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1826 self.sequence.py_result(),
1827 self.sequence.py_result()))
1828 if is_builtin_sequence or may_be_a_sequence:
1830 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1833 self.sequence.py_result(),
1835 if not is_builtin_sequence:
1836 if may_be_a_sequence:
1837 code.putln("} else {")
1838 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1841 self.sequence.py_result(),
1842 code.error_goto_if_null(self.result(), self.pos)))
1843 code.put_gotref(self.py_result())
1844 if may_be_a_sequence:
1848 class NextNode(AtomicExprNode):
1849 # Used as part of for statement implementation.
1850 # Implements result = iterator.next()
1851 # Created during analyse_types phase.
1852 # The iterator is not owned by this node.
1856 type = py_object_type
1858 def __init__(self, iterator, env):
1859 self.pos = iterator.pos
1860 self.iterator = iterator
1861 if iterator.type.is_ptr or iterator.type.is_array:
1862 self.type = iterator.type.base_type
1865 def generate_result_code(self, code):
1866 sequence_type = self.iterator.sequence.type
1867 if sequence_type is list_type:
1868 type_checks = [(list_type, "List")]
1869 elif sequence_type is tuple_type:
1870 type_checks = [(tuple_type, "Tuple")]
1871 elif not sequence_type.is_builtin_type:
1872 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1876 for py_type, prefix in type_checks:
1877 if len(type_checks) > 1:
1879 "if (likely(Py%s_CheckExact(%s))) {" % (
1880 prefix, self.iterator.py_result()))
1882 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1883 self.iterator.counter_cname,
1885 self.iterator.py_result()))
1887 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1890 self.iterator.py_result(),
1891 self.iterator.counter_cname,
1893 self.iterator.counter_cname))
1894 if len(type_checks) > 1:
1896 if len(type_checks) == 1:
1900 "%s = PyIter_Next(%s);" % (
1902 self.iterator.py_result()))
1906 code.putln(code.error_goto_if_PyErr(self.pos))
1907 code.putln("break;")
1909 code.put_gotref(self.py_result())
1913 class ExcValueNode(AtomicExprNode):
1914 # Node created during analyse_types phase
1915 # of an ExceptClauseNode to fetch the current
1918 type = py_object_type
1920 def __init__(self, pos, env):
1921 ExprNode.__init__(self, pos)
1923 def set_var(self, var):
1926 def calculate_result_code(self):
1929 def generate_result_code(self, code):
1932 def analyse_types(self, env):
1936 class TempNode(ExprNode):
1937 # Node created during analyse_types phase
1938 # of some nodes to hold a temporary value.
1940 # Note: One must call "allocate" and "release" on
1941 # the node during code generation to get/release the temp.
1942 # This is because the temp result is often used outside of
1943 # the regular cycle.
1947 def __init__(self, pos, type, env):
1948 ExprNode.__init__(self, pos)
1950 if type.is_pyobject:
1951 self.result_ctype = py_object_type
1954 def analyse_types(self, env):
1957 def generate_result_code(self, code):
1960 def allocate(self, code):
1961 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1963 def release(self, code):
1964 code.funcstate.release_temp(self.temp_cname)
1965 self.temp_cname = None
1969 return self.temp_cname
1971 assert False, "Remember to call allocate/release on TempNode"
1974 # Do not participate in normal temp alloc/dealloc:
1975 def allocate_temp_result(self, code):
1978 def release_temp_result(self, code):
1981 class PyTempNode(TempNode):
1982 # TempNode holding a Python value.
1984 def __init__(self, pos, env):
1985 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1987 class RawCNameExprNode(ExprNode):
1990 def __init__(self, pos, type=None):
1994 def analyse_types(self, env):
1997 def set_cname(self, cname):
2003 def generate_result_code(self, code):
2007 #-------------------------------------------------------------------
2011 #-------------------------------------------------------------------
2013 class IndexNode(ExprNode):
2014 # Sequence indexing.
2018 # indices [ExprNode]
2019 # is_buffer_access boolean Whether this is a buffer access.
2021 # indices is used on buffer access, index on non-buffer access.
2022 # The former contains a clean list of index parameters, the
2023 # latter whatever Python object is needed for index access.
2025 subexprs = ['base', 'index', 'indices']
2028 def __init__(self, pos, index, *args, **kw):
2029 ExprNode.__init__(self, pos, index=index, *args, **kw)
2032 def calculate_constant_result(self):
2033 self.constant_result = \
2034 self.base.constant_result[self.index.constant_result]
2036 def compile_time_value(self, denv):
2037 base = self.base.compile_time_value(denv)
2038 index = self.index.compile_time_value(denv)
2041 except Exception, e:
2042 self.compile_time_value_error(e)
2044 def is_ephemeral(self):
2045 return self.base.is_ephemeral()
2047 def is_simple(self):
2048 if self.is_buffer_access:
2051 return (base.is_simple() and self.index.is_simple()
2052 and base.type and (base.type.is_ptr or base.type.is_array))
2054 def analyse_target_declaration(self, env):
2057 def analyse_as_type(self, env):
2058 base_type = self.base.analyse_as_type(env)
2059 if base_type and not base_type.is_pyobject:
2060 if base_type.is_cpp_class:
2061 if isinstance(self.index, TupleNode):
2062 template_values = self.index.args
2064 template_values = [self.index]
2066 type_node = Nodes.TemplatedTypeNode(
2068 positional_args = template_values,
2069 keyword_args = None)
2070 return type_node.analyse(env, base_type = base_type)
2072 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2075 def type_dependencies(self, env):
2076 return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2078 def infer_type(self, env):
2079 base_type = self.base.infer_type(env)
2080 if isinstance(self.index, SliceNode):
2082 if base_type.is_string:
2083 # sliced C strings must coerce to Python
2085 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2086 # slicing these returns the same type
2089 # TODO: Handle buffers (hopefully without too much redundancy).
2090 return py_object_type
2092 index_type = self.index.infer_type(env)
2093 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2095 if base_type is unicode_type:
2096 # Py_UCS4 will automatically coerce to a unicode string
2097 # if required, so this is safe. We only infer Py_UCS4
2098 # when the index is a C integer type. Otherwise, we may
2099 # need to use normal Python item access, in which case
2100 # it's faster to return the one-char unicode string than
2101 # to receive it, throw it away, and potentially rebuild it
2102 # on a subsequent PyObject coercion.
2103 return PyrexTypes.c_py_ucs4_type
2104 elif base_type is str_type:
2105 # always returns str - Py2: bytes, Py3: unicode
2107 elif isinstance(self.base, BytesNode):
2108 #if env.global_scope().context.language_level >= 3:
2109 # # infering 'char' can be made to work in Python 3 mode
2110 # return PyrexTypes.c_char_type
2111 # Py2/3 return different types on indexing bytes objects
2112 return py_object_type
2113 elif base_type.is_ptr or base_type.is_array:
2114 return base_type.base_type
2116 # may be slicing or indexing, we don't know
2117 if base_type in (unicode_type, str_type):
2118 # these types always returns their own type on Python indexing/slicing
2121 # TODO: Handle buffers (hopefully without too much redundancy).
2122 return py_object_type
2124 def analyse_types(self, env):
2125 self.analyse_base_and_index_types(env, getting = 1)
2127 def analyse_target_types(self, env):
2128 self.analyse_base_and_index_types(env, setting = 1)
2130 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2131 # Note: This might be cleaned up by having IndexNode
2132 # parsed in a saner way and only construct the tuple if
2135 # Note that this function must leave IndexNode in a cloneable state.
2136 # For buffers, self.index is packed out on the initial analysis, and
2137 # when cloning self.indices is copied.
2138 self.is_buffer_access = False
2140 self.base.analyse_types(env)
2141 if self.base.type.is_error:
2142 # Do not visit child tree if base is undeclared to avoid confusing
2144 self.type = PyrexTypes.error_type
2147 is_slice = isinstance(self.index, SliceNode)
2148 # Potentially overflowing index value.
2149 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2150 self.index = self.index.coerce_to_pyobject(env)
2152 # Handle the case where base is a literal char* (and we expect a string, not an int)
2153 if isinstance(self.base, BytesNode) or is_slice:
2154 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2155 self.base = self.base.coerce_to_pyobject(env)
2157 skip_child_analysis = False
2158 buffer_access = False
2159 if self.base.type.is_buffer:
2161 indices = self.indices
2163 if isinstance(self.index, TupleNode):
2164 indices = self.index.args
2166 indices = [self.index]
2167 if len(indices) == self.base.type.ndim:
2168 buffer_access = True
2169 skip_child_analysis = True
2171 x.analyse_types(env)
2172 if not x.type.is_int:
2173 buffer_access = False
2175 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2177 # On cloning, indices is cloned. Otherwise, unpack index into indices
2178 assert not (buffer_access and isinstance(self.index, CloneNode))
2181 self.indices = indices
2183 self.type = self.base.type.dtype
2184 self.is_buffer_access = True
2185 self.buffer_type = self.base.entry.type
2187 if getting and self.type.is_pyobject:
2190 if not self.base.entry.type.writable:
2191 error(self.pos, "Writing to readonly buffer")
2193 self.base.entry.buffer_aux.writable_needed = True
2195 base_type = self.base.type
2196 if isinstance(self.index, TupleNode):
2197 self.index.analyse_types(env, skip_children=skip_child_analysis)
2198 elif not skip_child_analysis:
2199 self.index.analyse_types(env)
2200 self.original_index_type = self.index.type
2201 if base_type.is_unicode_char:
2202 # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
2203 # cases, but indexing must still work for them
2204 if self.index.constant_result in (0, -1):
2205 # FIXME: we know that this node is redundant -
2206 # currently, this needs to get handled in Optimize.py
2208 self.base = self.base.coerce_to_pyobject(env)
2209 base_type = self.base.type
2210 if base_type.is_pyobject:
2211 if self.index.type.is_int:
2213 and (base_type in (list_type, tuple_type, unicode_type))
2214 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2215 and not env.directives['boundscheck']):
2219 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2221 self.index = self.index.coerce_to_pyobject(env)
2223 if self.index.type.is_int and base_type is unicode_type:
2224 # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
2225 # if required, so this is fast and safe
2226 self.type = PyrexTypes.c_py_ucs4_type
2227 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2228 self.type = base_type
2230 self.type = py_object_type
2232 if base_type.is_ptr or base_type.is_array:
2233 self.type = base_type.base_type
2235 self.type = base_type
2236 elif self.index.type.is_pyobject:
2237 self.index = self.index.coerce_to(
2238 PyrexTypes.c_py_ssize_t_type, env)
2239 elif not self.index.type.is_int:
2241 "Invalid index type '%s'" %
2243 elif base_type.is_cpp_class:
2244 function = env.lookup_operator("[]", [self.base, self.index])
2245 if function is None:
2246 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2247 self.type = PyrexTypes.error_type
2248 self.result_code = "<error>"
2250 func_type = function.type
2251 if func_type.is_ptr:
2252 func_type = func_type.base_type
2253 self.index = self.index.coerce_to(func_type.args[0].type, env)
2254 self.type = func_type.return_type
2255 if setting and not func_type.return_type.is_reference:
2256 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2259 "Attempting to index non-array type '%s'" %
2261 self.type = PyrexTypes.error_type
2263 gil_message = "Indexing Python object"
2265 def nogil_check(self, env):
2266 if self.is_buffer_access:
2267 if env.directives['boundscheck']:
2268 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2270 elif self.type.is_pyobject:
2271 error(self.pos, "Cannot access buffer with object dtype without gil")
2273 super(IndexNode, self).nogil_check(env)
2276 def check_const_addr(self):
2277 return self.base.check_const_addr() and self.index.check_const()
2279 def is_lvalue(self):
2282 def calculate_result_code(self):
2283 if self.is_buffer_access:
2284 return "(*%s)" % self.buffer_ptr_code
2285 elif self.base.type is list_type:
2286 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2287 elif self.base.type is tuple_type:
2288 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2289 elif self.base.type is unicode_type and self.type.is_unicode_char:
2290 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2291 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2292 error(self.pos, "Invalid use of pointer slice")
2294 return "(%s[%s])" % (
2295 self.base.result(), self.index.result())
2297 def extra_index_params(self):
2298 if self.index.type.is_int:
2299 if self.original_index_type.signed:
2300 size_adjustment = ""
2302 size_adjustment = "+1"
2303 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2307 def generate_subexpr_evaluation_code(self, code):
2308 self.base.generate_evaluation_code(code)
2309 if not self.indices:
2310 self.index.generate_evaluation_code(code)
2312 for i in self.indices:
2313 i.generate_evaluation_code(code)
2315 def generate_subexpr_disposal_code(self, code):
2316 self.base.generate_disposal_code(code)
2317 if not self.indices:
2318 self.index.generate_disposal_code(code)
2320 for i in self.indices:
2321 i.generate_disposal_code(code)
2323 def free_subexpr_temps(self, code):
2324 self.base.free_temps(code)
2325 if not self.indices:
2326 self.index.free_temps(code)
2328 for i in self.indices:
2331 def generate_result_code(self, code):
2332 if self.is_buffer_access:
2333 if code.globalstate.directives['nonecheck']:
2334 self.put_nonecheck(code)
2335 self.buffer_ptr_code = self.buffer_lookup_code(code)
2336 if self.type.is_pyobject:
2337 # is_temp is True, so must pull out value and incref it.
2338 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2339 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2341 if self.type.is_pyobject:
2342 if self.index.type.is_int:
2343 index_code = self.index.result()
2344 if self.base.type is list_type:
2345 function = "__Pyx_GetItemInt_List"
2346 elif self.base.type is tuple_type:
2347 function = "__Pyx_GetItemInt_Tuple"
2349 function = "__Pyx_GetItemInt"
2350 code.globalstate.use_utility_code(getitem_int_utility_code)
2352 index_code = self.index.py_result()
2353 if self.base.type is dict_type:
2354 function = "__Pyx_PyDict_GetItem"
2355 code.globalstate.use_utility_code(getitem_dict_utility_code)
2357 function = "PyObject_GetItem"
2359 "%s = %s(%s, %s%s); if (!%s) %s" % (
2362 self.base.py_result(),
2364 self.extra_index_params(),
2366 code.error_goto(self.pos)))
2367 code.put_gotref(self.py_result())
2368 elif self.type.is_unicode_char and self.base.type is unicode_type:
2369 assert self.index.type.is_int
2370 index_code = self.index.result()
2371 function = "__Pyx_GetItemInt_Unicode"
2372 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2374 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2377 self.base.py_result(),
2379 self.extra_index_params(),
2381 code.error_goto(self.pos)))
2383 def generate_setitem_code(self, value_code, code):
2384 if self.index.type.is_int:
2385 function = "__Pyx_SetItemInt"
2386 index_code = self.index.result()
2387 code.globalstate.use_utility_code(setitem_int_utility_code)
2389 index_code = self.index.py_result()
2390 if self.base.type is dict_type:
2391 function = "PyDict_SetItem"
2392 # It would seem that we could specialized lists/tuples, but that
2393 # shouldn't happen here.
2394 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2395 # not a PyObject*, and bad conversion here would give the wrong
2396 # exception. Also, tuples are supposed to be immutable, and raise
2397 # TypeErrors when trying to set their entries (PyTuple_SetItem
2398 # is for creating new tuples from).
2400 function = "PyObject_SetItem"
2402 "if (%s(%s, %s, %s%s) < 0) %s" % (
2404 self.base.py_result(),
2407 self.extra_index_params(),
2408 code.error_goto(self.pos)))
2410 def generate_buffer_setitem_code(self, rhs, code, op=""):
2411 # Used from generate_assignment_code and InPlaceAssignmentNode
2412 if code.globalstate.directives['nonecheck']:
2413 self.put_nonecheck(code)
2414 ptrexpr = self.buffer_lookup_code(code)
2415 if self.buffer_type.dtype.is_pyobject:
2416 # Must manage refcounts. Decref what is already there
2417 # and incref what we put in.
2418 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2419 rhs_code = rhs.result()
2420 code.putln("%s = %s;" % (ptr, ptrexpr))
2421 code.put_gotref("*%s" % ptr)
2422 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2425 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2426 code.put_giveref("*%s" % ptr)
2427 code.funcstate.release_temp(ptr)
2430 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2432 def generate_assignment_code(self, rhs, code):
2433 self.generate_subexpr_evaluation_code(code)
2434 if self.is_buffer_access:
2435 self.generate_buffer_setitem_code(rhs, code)
2436 elif self.type.is_pyobject:
2437 self.generate_setitem_code(rhs.py_result(), code)
2441 self.result(), rhs.result()))
2442 self.generate_subexpr_disposal_code(code)
2443 self.free_subexpr_temps(code)
2444 rhs.generate_disposal_code(code)
2445 rhs.free_temps(code)
2447 def generate_deletion_code(self, code):
2448 self.generate_subexpr_evaluation_code(code)
2449 #if self.type.is_pyobject:
2450 if self.index.type.is_int:
2451 function = "__Pyx_DelItemInt"
2452 index_code = self.index.result()
2453 code.globalstate.use_utility_code(delitem_int_utility_code)
2455 index_code = self.index.py_result()
2456 if self.base.type is dict_type:
2457 function = "PyDict_DelItem"
2459 function = "PyObject_DelItem"
2461 "if (%s(%s, %s%s) < 0) %s" % (
2463 self.base.py_result(),
2465 self.extra_index_params(),
2466 code.error_goto(self.pos)))
2467 self.generate_subexpr_disposal_code(code)
2468 self.free_subexpr_temps(code)
2470 def buffer_lookup_code(self, code):
2471 # Assign indices to temps
2472 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2473 for temp, index in zip(index_temps, self.indices):
2474 code.putln("%s = %s;" % (temp, index.result()))
2475 # Generate buffer access code using these temps
2477 # The above could happen because child_attrs is wrong somewhere so that
2478 # options are not propagated.
2479 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2480 index_signeds=[i.type.signed for i in self.indices],
2481 index_cnames=index_temps,
2482 directives=code.globalstate.directives,
2483 pos=self.pos, code=code)
2485 def put_nonecheck(self, code):
2486 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2487 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2488 code.putln("__Pyx_RaiseNoneIndexingError();")
2489 code.putln(code.error_goto(self.pos))
2492 class SliceIndexNode(ExprNode):
2493 # 2-element slice indexing
2496 # start ExprNode or None
2497 # stop ExprNode or None
2499 subexprs = ['base', 'start', 'stop']
2501 def infer_type(self, env):
2502 base_type = self.base.infer_type(env)
2503 if base_type.is_string:
2505 elif base_type in (bytes_type, str_type, unicode_type,
2506 list_type, tuple_type):
2508 elif base_type.is_ptr or base_type.is_array:
2509 return PyrexTypes.c_array_type(base_type.base_type, None)
2510 return py_object_type
2512 def calculate_constant_result(self):
2513 self.constant_result = self.base.constant_result[
2514 self.start.constant_result : self.stop.constant_result]
2516 def compile_time_value(self, denv):
2517 base = self.base.compile_time_value(denv)
2518 if self.start is None:
2521 start = self.start.compile_time_value(denv)
2522 if self.stop is None:
2525 stop = self.stop.compile_time_value(denv)
2527 return base[start:stop]
2528 except Exception, e:
2529 self.compile_time_value_error(e)
2531 def analyse_target_declaration(self, env):
2534 def analyse_target_types(self, env):
2535 self.analyse_types(env)
2536 # when assigning, we must accept any Python type
2537 if self.type.is_pyobject:
2538 self.type = py_object_type
2540 def analyse_types(self, env):
2541 self.base.analyse_types(env)
2543 self.start.analyse_types(env)
2545 self.stop.analyse_types(env)
2546 base_type = self.base.type
2547 if base_type.is_string:
2548 self.type = bytes_type
2549 elif base_type.is_ptr:
2550 self.type = base_type
2551 elif base_type.is_array:
2552 # we need a ptr type here instead of an array type, as
2553 # array types can result in invalid type casts in the C
2555 self.type = PyrexTypes.CPtrType(base_type.base_type)
2557 self.base = self.base.coerce_to_pyobject(env)
2558 self.type = py_object_type
2559 if base_type.is_builtin_type:
2560 # slicing builtin types returns something of the same type
2561 self.type = base_type
2562 c_int = PyrexTypes.c_py_ssize_t_type
2564 self.start = self.start.coerce_to(c_int, env)
2566 self.stop = self.stop.coerce_to(c_int, env)
2569 nogil_check = Node.gil_error
2570 gil_message = "Slicing Python object"
2572 def generate_result_code(self, code):
2573 if not self.type.is_pyobject:
2575 "Slicing is not currently supported for '%s'." % self.type)
2577 if self.base.type.is_string:
2578 if self.stop is None:
2580 "%s = PyBytes_FromString(%s + %s); %s" % (
2584 code.error_goto_if_null(self.result(), self.pos)))
2587 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2593 code.error_goto_if_null(self.result(), self.pos)))
2596 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2598 self.base.py_result(),
2601 code.error_goto_if_null(self.result(), self.pos)))
2602 code.put_gotref(self.py_result())
2604 def generate_assignment_code(self, rhs, code):
2605 self.generate_subexpr_evaluation_code(code)
2606 if self.type.is_pyobject:
2607 code.put_error_if_neg(self.pos,
2608 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2609 self.base.py_result(),
2616 start_offset = self.start_code()
2617 if start_offset == '0':
2621 if rhs.type.is_array:
2622 array_length = rhs.type.size
2623 self.generate_slice_guard_code(code, array_length)
2626 "Slice assignments from pointers are not yet supported.")
2627 # FIXME: fix the array size according to start/stop
2628 array_length = self.base.type.size
2629 for i in range(array_length):
2630 code.putln("%s[%s%s] = %s[%d];" % (
2631 self.base.result(), start_offset, i,
2633 self.generate_subexpr_disposal_code(code)
2634 self.free_subexpr_temps(code)
2635 rhs.generate_disposal_code(code)
2636 rhs.free_temps(code)
2638 def generate_deletion_code(self, code):
2639 if not self.base.type.is_pyobject:
2641 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2643 self.generate_subexpr_evaluation_code(code)
2644 code.put_error_if_neg(self.pos,
2645 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2646 self.base.py_result(),
2649 self.generate_subexpr_disposal_code(code)
2650 self.free_subexpr_temps(code)
2652 def generate_slice_guard_code(self, code, target_size):
2653 if not self.base.type.is_array:
2655 slice_size = self.base.type.size
2658 stop = self.stop.result()
2662 slice_size = self.base.type.size + stop
2669 start = self.start.result()
2673 start = self.base.type.size + start
2681 error(self.pos, "Assignment to empty slice.")
2682 elif start is None and stop is None:
2683 # we know the exact slice length
2684 if target_size != slice_size:
2685 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2686 slice_size, target_size))
2687 elif start is not None:
2690 check = "(%s)-(%s)" % (stop, start)
2691 else: # stop is not None:
2694 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2695 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));' % (
2696 target_size, check))
2697 code.putln(code.error_goto(self.pos))
2700 def start_code(self):
2702 return self.start.result()
2706 def stop_code(self):
2708 return self.stop.result()
2709 elif self.base.type.is_array:
2710 return self.base.type.size
2712 return "PY_SSIZE_T_MAX"
2714 def calculate_result_code(self):
2715 # self.result() is not used, but this method must exist
2719 class SliceNode(ExprNode):
2720 # start:stop:step in subscript list
2726 subexprs = ['start', 'stop', 'step']
2728 type = py_object_type
2731 def calculate_constant_result(self):
2732 self.constant_result = slice(
2733 self.start.constant_result,
2734 self.stop.constant_result,
2735 self.step.constant_result)
2737 def compile_time_value(self, denv):
2738 start = self.start.compile_time_value(denv)
2739 stop = self.stop.compile_time_value(denv)
2740 step = self.step.compile_time_value(denv)
2742 return slice(start, stop, step)
2743 except Exception, e:
2744 self.compile_time_value_error(e)
2746 def analyse_types(self, env):
2747 self.start.analyse_types(env)
2748 self.stop.analyse_types(env)
2749 self.step.analyse_types(env)
2750 self.start = self.start.coerce_to_pyobject(env)
2751 self.stop = self.stop.coerce_to_pyobject(env)
2752 self.step = self.step.coerce_to_pyobject(env)
2753 if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
2754 self.is_literal = True
2755 self.is_temp = False
2757 gil_message = "Constructing Python slice object"
2759 def calculate_result_code(self):
2760 return self.result_code
2762 def generate_result_code(self, code):
2764 self.result_code = code.get_py_const(py_object_type, 'slice_', cleanup_level=2)
2765 code = code.get_cached_constants_writer()
2766 code.mark_pos(self.pos)
2769 "%s = PySlice_New(%s, %s, %s); %s" % (
2771 self.start.py_result(),
2772 self.stop.py_result(),
2773 self.step.py_result(),
2774 code.error_goto_if_null(self.result(), self.pos)))
2775 code.put_gotref(self.py_result())
2777 code.put_giveref(self.py_result())
2780 class CallNode(ExprNode):
2782 # allow overriding the default 'may_be_none' behaviour
2783 may_return_none = None
2785 def may_be_none(self):
2786 if self.may_return_none is not None:
2787 return self.may_return_none
2788 return ExprNode.may_be_none(self)
2790 def analyse_as_type_constructor(self, env):
2791 type = self.function.analyse_as_type(env)
2792 if type and type.is_struct_or_union:
2793 args, kwds = self.explicit_args_kwds()
2795 for arg, member in zip(args, type.scope.var_entries):
2796 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2798 items += kwds.key_value_pairs
2799 self.key_value_pairs = items
2800 self.__class__ = DictNode
2801 self.analyse_types(env)
2802 self.coerce_to(type, env)
2804 elif type and type.is_cpp_class:
2805 for arg in self.args:
2806 arg.analyse_types(env)
2807 constructor = type.scope.lookup("<init>")
2808 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2809 self.function.entry = constructor
2810 self.function.set_cname(type.declaration_code(""))
2811 self.analyse_c_function_call(env)
2814 def is_lvalue(self):
2815 return self.type.is_reference
2817 def nogil_check(self, env):
2818 func_type = self.function_type()
2819 if func_type.is_pyobject:
2821 elif not getattr(func_type, 'nogil', False):
2824 gil_message = "Calling gil-requiring function"
2827 class SimpleCallNode(CallNode):
2828 # Function call without keyword, * or ** args.
2832 # arg_tuple ExprNode or None used internally
2833 # self ExprNode or None used internally
2834 # coerced_self ExprNode or None used internally
2835 # wrapper_call bool used internally
2836 # has_optional_args bool used internally
2837 # nogil bool used internally
2839 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2844 wrapper_call = False
2845 has_optional_args = False
2849 def compile_time_value(self, denv):
2850 function = self.function.compile_time_value(denv)
2851 args = [arg.compile_time_value(denv) for arg in self.args]
2853 return function(*args)
2854 except Exception, e:
2855 self.compile_time_value_error(e)
2857 def type_dependencies(self, env):
2858 # TODO: Update when Danilo's C++ code merged in to handle the
2859 # the case of function overloading.
2860 return self.function.type_dependencies(env)
2862 def infer_type(self, env):
2863 function = self.function
2864 func_type = function.infer_type(env)
2865 if isinstance(self.function, NewExprNode):
2866 return PyrexTypes.CPtrType(self.function.class_type)
2867 if func_type.is_ptr:
2868 func_type = func_type.base_type
2869 if func_type.is_cfunction:
2870 return func_type.return_type
2871 elif func_type is type_type:
2872 if function.is_name and function.entry and function.entry.type:
2873 result_type = function.entry.type
2874 if result_type.is_extension_type:
2876 elif result_type.is_builtin_type:
2877 if function.entry.name == 'float':
2878 return PyrexTypes.c_double_type
2879 elif function.entry.name in Builtin.types_that_construct_their_instance:
2881 return py_object_type
2883 def analyse_as_type(self, env):
2884 attr = self.function.as_cython_attribute()
2885 if attr == 'pointer':
2886 if len(self.args) != 1:
2887 error(self.args.pos, "only one type allowed.")
2889 type = self.args[0].analyse_as_type(env)
2891 error(self.args[0].pos, "Unknown type")
2893 return PyrexTypes.CPtrType(type)
2895 def explicit_args_kwds(self):
2896 return self.args, None
2898 def analyse_types(self, env):
2899 if self.analyse_as_type_constructor(env):
2903 self.analysed = True
2904 function = self.function
2905 function.is_called = 1
2906 self.function.analyse_types(env)
2907 if function.is_attribute and function.entry and function.entry.is_cmethod:
2908 # Take ownership of the object from which the attribute
2909 # was obtained, because we need to pass it as 'self'.
2910 self.self = function.obj
2911 function.obj = CloneNode(self.self)
2912 func_type = self.function_type()
2913 if func_type.is_pyobject:
2914 self.arg_tuple = TupleNode(self.pos, args = self.args)
2915 self.arg_tuple.analyse_types(env)
2917 if func_type is Builtin.type_type and function.is_name and \
2918 function.entry and \
2919 function.entry.is_builtin and \
2920 function.entry.name in Builtin.types_that_construct_their_instance:
2921 # calling a builtin type that returns a specific object type
2922 if function.entry.name == 'float':
2923 # the following will come true later on in a transform
2924 self.type = PyrexTypes.c_double_type
2925 self.result_ctype = PyrexTypes.c_double_type
2927 self.type = Builtin.builtin_types[function.entry.name]
2928 self.result_ctype = py_object_type
2929 self.may_return_none = False
2930 elif function.is_name and function.type_entry:
2931 # We are calling an extension type constructor. As
2932 # long as we do not support __new__(), the result type
2934 self.type = function.type_entry.type
2935 self.result_ctype = py_object_type
2936 self.may_return_none = False
2938 self.type = py_object_type
2941 for arg in self.args:
2942 arg.analyse_types(env)
2943 if self.self and func_type.args:
2944 # Coerce 'self' to the type expected by the method.
2945 self_arg = func_type.args[0]
2946 if self_arg.not_none: # C methods must do the None test for self at *call* time
2947 self.self = self.self.as_none_safe_node(
2948 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2949 'PyExc_AttributeError')
2950 expected_type = self_arg.type
2951 self.coerced_self = CloneNode(self.self).coerce_to(
2953 # Insert coerced 'self' argument into argument list.
2954 self.args.insert(0, self.coerced_self)
2955 self.analyse_c_function_call(env)
2957 def function_type(self):
2958 # Return the type of the function being called, coercing a function
2959 # pointer to a function if necessary.
2960 func_type = self.function.type
2961 if func_type.is_ptr:
2962 func_type = func_type.base_type
2965 def is_simple(self):
2966 # C function calls could be considered simple, but they may
2967 # have side-effects that may hit when multiple operations must
2968 # be effected in order, e.g. when constructing the argument
2969 # sequence for a function call or comparing values.
2972 def analyse_c_function_call(self, env):
2973 if self.function.type is error_type:
2974 self.type = error_type
2976 if self.function.type.is_cpp_class:
2977 overloaded_entry = self.function.type.scope.lookup("operator()")
2978 if overloaded_entry is None:
2979 self.type = PyrexTypes.error_type
2980 self.result_code = "<error>"
2982 elif hasattr(self.function, 'entry'):
2983 overloaded_entry = self.function.entry
2985 overloaded_entry = None
2986 if overloaded_entry:
2987 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2989 self.type = PyrexTypes.error_type
2990 self.result_code = "<error>"
2992 self.function.entry = entry
2993 self.function.type = entry.type
2994 func_type = self.function_type()
2996 func_type = self.function_type()
2997 if not func_type.is_cfunction:
2998 error(self.pos, "Calling non-function type '%s'" % func_type)
2999 self.type = PyrexTypes.error_type
3000 self.result_code = "<error>"
3003 max_nargs = len(func_type.args)
3004 expected_nargs = max_nargs - func_type.optional_arg_count
3005 actual_nargs = len(self.args)
3006 if func_type.optional_arg_count and expected_nargs != actual_nargs:
3007 self.has_optional_args = 1
3010 some_args_in_temps = False
3011 for i in xrange(min(max_nargs, actual_nargs)):
3012 formal_type = func_type.args[i].type
3013 arg = self.args[i].coerce_to(formal_type, env)
3016 # first argument in temp doesn't impact subsequent arguments
3017 some_args_in_temps = True
3018 elif arg.type.is_pyobject and not env.nogil:
3019 if i == 0 and self.self is not None:
3020 # a method's cloned "self" argument is ok
3022 elif arg.nonlocally_immutable():
3023 # plain local variables are ok
3026 # we do not safely own the argument's reference,
3027 # but we must make sure it cannot be collected
3028 # before we return from the function, so we create
3029 # an owned temp reference to it
3030 if i > 0: # first argument doesn't matter
3031 some_args_in_temps = True
3032 arg = arg.coerce_to_temp(env)
3034 # handle additional varargs parameters
3035 for i in xrange(max_nargs, actual_nargs):
3037 if arg.type.is_pyobject:
3038 arg_ctype = arg.type.default_coerced_ctype()
3039 if arg_ctype is None:
3040 error(self.args[i].pos,
3041 "Python object cannot be passed as a varargs parameter")
3043 self.args[i] = arg = arg.coerce_to(arg_ctype, env)
3044 if arg.is_temp and i > 0:
3045 some_args_in_temps = True
3046 if some_args_in_temps:
3047 # if some args are temps and others are not, they may get
3048 # constructed in the wrong order (temps first) => make
3049 # sure they are either all temps or all not temps (except
3050 # for the last argument, which is evaluated last in any
3052 for i in xrange(actual_nargs-1):
3053 if i == 0 and self.self is not None:
3054 continue # self is ok
3056 if arg.nonlocally_immutable():
3057 # locals, C functions, unassignable types are safe.
3059 elif arg.type.is_cpp_class:
3060 # Assignment has side effects, avoid.
3062 elif env.nogil and arg.type.is_pyobject:
3063 # can't copy a Python reference into a temp in nogil
3064 # env (this is safe: a construction would fail in
3068 #self.args[i] = arg.coerce_to_temp(env)
3069 # instead: issue a warning
3070 if i > 0 or i == 1 and self.self is not None: # skip first arg
3071 warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
3073 # Calc result type and code fragment
3074 if isinstance(self.function, NewExprNode):
3075 self.type = PyrexTypes.CPtrType(self.function.class_type)
3077 self.type = func_type.return_type
3078 if self.type.is_pyobject:
3079 self.result_ctype = py_object_type
3081 elif func_type.exception_value is not None \
3082 or func_type.exception_check:
3084 # Called in 'nogil' context?
3085 self.nogil = env.nogil
3087 func_type.exception_check and
3088 func_type.exception_check != '+'):
3089 env.use_utility_code(pyerr_occurred_withgil_utility_code)
3090 # C++ exception handler
3091 if func_type.exception_check == '+':
3092 if func_type.exception_value is None:
3093 env.use_utility_code(cpp_exception_utility_code)
3095 def calculate_result_code(self):
3096 return self.c_call_code()
3098 def c_call_code(self):
3099 func_type = self.function_type()
3100 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
3102 formal_args = func_type.args
3104 args = list(zip(formal_args, self.args))
3105 max_nargs = len(func_type.args)
3106 expected_nargs = max_nargs - func_type.optional_arg_count
3107 actual_nargs = len(self.args)
3108 for formal_arg, actual_arg in args[:expected_nargs]:
3109 arg_code = actual_arg.result_as(formal_arg.type)
3110 arg_list_code.append(arg_code)
3112 if func_type.is_overridable:
3113 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3115 if func_type.optional_arg_count:
3116 if expected_nargs == actual_nargs:
3117 optional_args = 'NULL'
3119 optional_args = "&%s" % self.opt_arg_struct
3120 arg_list_code.append(optional_args)
3122 for actual_arg in self.args[len(formal_args):]:
3123 arg_list_code.append(actual_arg.result())
3124 result = "%s(%s)" % (self.function.result(),
3125 ', '.join(arg_list_code))
3128 def generate_result_code(self, code):
3129 func_type = self.function_type()
3130 if func_type.is_pyobject:
3131 arg_code = self.arg_tuple.py_result()
3133 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3135 self.function.py_result(),
3137 code.error_goto_if_null(self.result(), self.pos)))
3138 code.put_gotref(self.py_result())
3139 elif func_type.is_cfunction:
3140 if self.has_optional_args:
3141 actual_nargs = len(self.args)
3142 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3143 self.opt_arg_struct = code.funcstate.allocate_temp(
3144 func_type.op_arg_struct.base_type, manage_ref=True)
3145 code.putln("%s.%s = %s;" % (
3146 self.opt_arg_struct,
3147 Naming.pyrex_prefix + "n",
3148 len(self.args) - expected_nargs))
3149 args = list(zip(func_type.args, self.args))
3150 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3151 code.putln("%s.%s = %s;" % (
3152 self.opt_arg_struct,
3153 func_type.opt_arg_cname(formal_arg.name),
3154 actual_arg.result_as(formal_arg.type)))
3156 if self.type.is_pyobject and self.is_temp:
3157 exc_checks.append("!%s" % self.result())
3159 exc_val = func_type.exception_value
3160 exc_check = func_type.exception_check
3161 if exc_val is not None:
3162 exc_checks.append("%s == %s" % (self.result(), exc_val))
3165 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3167 exc_checks.append("PyErr_Occurred()")
3168 if self.is_temp or exc_checks:
3169 rhs = self.c_call_code()
3171 lhs = "%s = " % self.result()
3172 if self.is_temp and self.type.is_pyobject:
3173 #return_type = self.type # func_type.return_type
3174 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3175 # "from", return_type, "to pyobject" ###
3176 rhs = typecast(py_object_type, self.type, rhs)
3179 if func_type.exception_check == '+':
3180 if func_type.exception_value is None:
3181 raise_py_exception = "__Pyx_CppExn2PyErr()"
3182 elif func_type.exception_value.type.is_pyobject:
3183 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3184 func_type.exception_value.entry.cname,
3185 func_type.exception_value.entry.cname)
3187 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3189 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3191 "try {%s%s;} catch(...) {%s; %s}" % (
3195 code.error_goto(self.pos)))
3198 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3201 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3202 if self.type.is_pyobject and self.result():
3203 code.put_gotref(self.py_result())
3204 if self.has_optional_args:
3205 code.funcstate.release_temp(self.opt_arg_struct)
3208 class PythonCapiFunctionNode(ExprNode):
3210 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3214 self.type = func_type
3215 self.utility_code = utility_code
3217 def analyse_types(self, env):
3220 def generate_result_code(self, code):
3221 if self.utility_code:
3222 code.globalstate.use_utility_code(self.utility_code)
3224 def calculate_result_code(self):
3227 class PythonCapiCallNode(SimpleCallNode):
3228 # Python C-API Function call (only created in transforms)
3230 # By default, we assume that the call never returns None, as this
3231 # is true for most C-API functions in CPython. If this does not
3232 # apply to a call, set the following to True (or None to inherit
3233 # the default behaviour).
3234 may_return_none = False
3236 def __init__(self, pos, function_name, func_type,
3237 utility_code = None, py_name=None, **kwargs):
3238 self.type = func_type.return_type
3239 self.result_ctype = self.type
3240 self.function = PythonCapiFunctionNode(
3241 pos, py_name, function_name, func_type,
3242 utility_code = utility_code)
3243 # call this last so that we can override the constructed
3244 # attributes above with explicit keyword arguments if required
3245 SimpleCallNode.__init__(self, pos, **kwargs)
3248 class GeneralCallNode(CallNode):
3249 # General Python function call, including keyword,
3250 # * and ** arguments.
3253 # positional_args ExprNode Tuple of positional arguments
3254 # keyword_args ExprNode or None Dict of keyword arguments
3255 # starstar_arg ExprNode or None Dict of extra keyword args
3257 type = py_object_type
3259 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3261 nogil_check = Node.gil_error
3263 def compile_time_value(self, denv):
3264 function = self.function.compile_time_value(denv)
3265 positional_args = self.positional_args.compile_time_value(denv)
3266 keyword_args = self.keyword_args.compile_time_value(denv)
3267 starstar_arg = self.starstar_arg.compile_time_value(denv)
3269 keyword_args.update(starstar_arg)
3270 return function(*positional_args, **keyword_args)
3271 except Exception, e:
3272 self.compile_time_value_error(e)
3274 def explicit_args_kwds(self):
3275 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3276 raise CompileError(self.pos,
3277 'Compile-time keyword arguments must be explicit.')
3278 return self.positional_args.args, self.keyword_args
3280 def analyse_types(self, env):
3281 if self.analyse_as_type_constructor(env):
3283 self.function.analyse_types(env)
3284 self.positional_args.analyse_types(env)
3285 if self.keyword_args:
3286 self.keyword_args.analyse_types(env)
3287 if self.starstar_arg:
3288 self.starstar_arg.analyse_types(env)
3289 if not self.function.type.is_pyobject:
3290 if self.function.type.is_error:
3291 self.type = error_type
3293 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3294 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3296 self.function = self.function.coerce_to_pyobject(env)
3297 self.positional_args = \
3298 self.positional_args.coerce_to_pyobject(env)
3299 if self.starstar_arg:
3300 self.starstar_arg = \
3301 self.starstar_arg.coerce_to_pyobject(env)
3302 function = self.function
3303 if function.is_name and function.type_entry:
3304 # We are calling an extension type constructor. As long
3305 # as we do not support __new__(), the result type is clear
3306 self.type = function.type_entry.type
3307 self.result_ctype = py_object_type
3308 self.may_return_none = False
3310 self.type = py_object_type
3313 def generate_result_code(self, code):
3314 if self.type.is_error: return
3315 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3316 if self.keyword_args and self.starstar_arg:
3317 code.put_error_if_neg(self.pos,
3318 "PyDict_Update(%s, %s)" % (
3319 self.keyword_args.py_result(),
3320 self.starstar_arg.py_result()))
3321 keyword_code = self.keyword_args.py_result()
3322 elif self.keyword_args:
3323 keyword_code = self.keyword_args.py_result()
3324 elif self.starstar_arg:
3325 keyword_code = self.starstar_arg.py_result()
3326 if self.starstar_arg.type is not Builtin.dict_type:
3327 # CPython supports calling functions with non-dicts, so do we
3328 code.globalstate.use_utility_code(kwargs_call_utility_code)
3329 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3332 if not keyword_code:
3333 call_code = "PyObject_Call(%s, %s, NULL)" % (
3334 self.function.py_result(),
3335 self.positional_args.py_result())
3337 call_code = "%s(%s, %s, %s)" % (
3338 kwargs_call_function,
3339 self.function.py_result(),
3340 self.positional_args.py_result(),
3346 code.error_goto_if_null(self.result(), self.pos)))
3347 code.put_gotref(self.py_result())
3350 class AsTupleNode(ExprNode):
3351 # Convert argument to tuple. Used for normalising
3352 # the * argument of a function call.
3358 def calculate_constant_result(self):
3359 self.constant_result = tuple(self.base.constant_result)
3361 def compile_time_value(self, denv):
3362 arg = self.arg.compile_time_value(denv)
3365 except Exception, e:
3366 self.compile_time_value_error(e)
3368 def analyse_types(self, env):
3369 self.arg.analyse_types(env)
3370 self.arg = self.arg.coerce_to_pyobject(env)
3371 self.type = tuple_type
3374 def may_be_none(self):
3377 nogil_check = Node.gil_error
3378 gil_message = "Constructing Python tuple"
3380 def generate_result_code(self, code):
3382 "%s = PySequence_Tuple(%s); %s" % (
3384 self.arg.py_result(),
3385 code.error_goto_if_null(self.result(), self.pos)))
3386 code.put_gotref(self.py_result())
3389 class AttributeNode(ExprNode):
3394 # needs_none_check boolean Used if obj is an extension type.
3395 # If set to True, it is known that the type is not None.
3399 # is_py_attr boolean Is a Python getattr operation
3400 # member string C name of struct member
3401 # is_called boolean Function call is being done on result
3402 # entry Entry Symbol table entry of attribute
3407 type = PyrexTypes.error_type
3410 needs_none_check = True
3412 def as_cython_attribute(self):
3413 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3414 return self.attribute
3415 cy = self.obj.as_cython_attribute()
3417 return "%s.%s" % (cy, self.attribute)
3419 def coerce_to(self, dst_type, env):
3420 # If coercing to a generic pyobject and this is a cpdef function
3421 # we can create the corresponding attribute
3422 if dst_type is py_object_type:
3424 if entry and entry.is_cfunction and entry.as_variable:
3425 # must be a cpdef function
3427 self.entry = entry.as_variable
3428 self.analyse_as_python_attribute(env)
3430 return ExprNode.coerce_to(self, dst_type, env)
3432 def calculate_constant_result(self):
3433 attr = self.attribute
3434 if attr.startswith("__") and attr.endswith("__"):
3436 self.constant_result = getattr(self.obj.constant_result, attr)
3438 def compile_time_value(self, denv):
3439 attr = self.attribute
3440 if attr.startswith("__") and attr.endswith("__"):
3442 "Invalid attribute name '%s' in compile-time expression" % attr)
3444 obj = self.obj.compile_time_value(denv)
3446 return getattr(obj, attr)
3447 except Exception, e:
3448 self.compile_time_value_error(e)
3450 def type_dependencies(self, env):
3451 return self.obj.type_dependencies(env)
3453 def infer_type(self, env):
3454 if self.analyse_as_cimported_attribute(env, 0):
3455 return self.entry.type
3456 elif self.analyse_as_unbound_cmethod(env):
3457 return self.entry.type
3459 obj_type = self.obj.infer_type(env)
3460 self.analyse_attribute(env, obj_type = obj_type)
3461 if obj_type.is_builtin_type and self.type.is_cfunction:
3462 # special case: C-API replacements for C methods of
3463 # builtin types cannot be inferred as C functions as
3464 # that would prevent their use as bound methods
3465 self.type = py_object_type
3466 return py_object_type
3469 def analyse_target_declaration(self, env):
3472 def analyse_target_types(self, env):
3473 self.analyse_types(env, target = 1)
3475 def analyse_types(self, env, target = 0):
3476 if self.analyse_as_cimported_attribute(env, target):
3478 if not target and self.analyse_as_unbound_cmethod(env):
3480 self.analyse_as_ordinary_attribute(env, target)
3482 def analyse_as_cimported_attribute(self, env, target):
3483 # Try to interpret this as a reference to an imported
3484 # C const, type, var or function. If successful, mutates
3485 # this node into a NameNode and returns 1, otherwise
3487 module_scope = self.obj.analyse_as_module(env)
3489 entry = module_scope.lookup_here(self.attribute)
3491 entry.is_cglobal or entry.is_cfunction
3492 or entry.is_type or entry.is_const):
3493 self.mutate_into_name_node(env, entry, target)
3497 def analyse_as_unbound_cmethod(self, env):
3498 # Try to interpret this as a reference to an unbound
3499 # C method of an extension type. If successful, mutates
3500 # this node into a NameNode and returns 1, otherwise
3502 type = self.obj.analyse_as_extension_type(env)
3504 entry = type.scope.lookup_here(self.attribute)
3505 if entry and entry.is_cmethod:
3506 # Create a temporary entry describing the C method
3507 # as an ordinary function.
3508 ubcm_entry = Symtab.Entry(entry.name,
3509 "%s->%s" % (type.vtabptr_cname, entry.cname),
3511 ubcm_entry.is_cfunction = 1
3512 ubcm_entry.func_cname = entry.func_cname
3513 ubcm_entry.is_unbound_cmethod = 1
3514 self.mutate_into_name_node(env, ubcm_entry, None)
3518 def analyse_as_type(self, env):
3519 module_scope = self.obj.analyse_as_module(env)
3521 return module_scope.lookup_type(self.attribute)
3522 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3523 base_type = self.obj.analyse_as_type(env)
3524 if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
3525 return base_type.scope.lookup_type(self.attribute)
3528 def analyse_as_extension_type(self, env):
3529 # Try to interpret this as a reference to an extension type
3530 # in a cimported module. Returns the extension type, or None.
3531 module_scope = self.obj.analyse_as_module(env)
3533 entry = module_scope.lookup_here(self.attribute)
3534 if entry and entry.is_type and entry.type.is_extension_type:
3538 def analyse_as_module(self, env):
3539 # Try to interpret this as a reference to a cimported module
3540 # in another cimported module. Returns the module scope, or None.
3541 module_scope = self.obj.analyse_as_module(env)
3543 entry = module_scope.lookup_here(self.attribute)
3544 if entry and entry.as_module:
3545 return entry.as_module
3548 def mutate_into_name_node(self, env, entry, target):
3549 # Mutate this node into a NameNode and complete the
3550 # analyse_types phase.
3551 self.__class__ = NameNode
3552 self.name = self.attribute
3557 NameNode.analyse_target_types(self, env)
3559 NameNode.analyse_rvalue_entry(self, env)
3561 def analyse_as_ordinary_attribute(self, env, target):
3562 self.obj.analyse_types(env)
3563 self.analyse_attribute(env)
3564 if self.entry and self.entry.is_cmethod and not self.is_called:
3565 # error(self.pos, "C method can only be called")
3567 ## Reference to C array turns into pointer to first element.
3568 #while self.type.is_array:
3569 # self.type = self.type.element_ptr_type()
3573 self.result_ctype = py_object_type
3574 elif target and self.obj.type.is_builtin_type:
3575 error(self.pos, "Assignment to an immutable object field")
3577 def analyse_attribute(self, env, obj_type = None):
3578 # Look up attribute and set self.type and self.member.
3580 self.member = self.attribute
3581 if obj_type is None:
3582 if self.obj.type.is_string:
3583 self.obj = self.obj.coerce_to_pyobject(env)
3584 obj_type = self.obj.type
3586 if obj_type.is_string:
3587 obj_type = py_object_type
3588 if obj_type.is_ptr or obj_type.is_array:
3589 obj_type = obj_type.base_type
3591 elif obj_type.is_extension_type or obj_type.is_builtin_type:
3595 if obj_type.has_attributes:
3597 if obj_type.attributes_known():
3598 entry = obj_type.scope.lookup_here(self.attribute)
3599 if entry and entry.is_member:
3603 "Cannot select attribute of incomplete type '%s'"
3605 self.type = PyrexTypes.error_type
3609 if obj_type.is_extension_type and entry.name == "__weakref__":
3610 error(self.pos, "Illegal use of special attribute __weakref__")
3611 # methods need the normal attribute lookup
3612 # because they do not have struct entries
3613 if entry.is_variable or entry.is_cmethod:
3614 self.type = entry.type
3615 self.member = entry.cname
3618 # If it's not a variable or C method, it must be a Python
3619 # method of an extension type, so we treat it like a Python
3622 # If we get here, the base object is not a struct/union/extension
3623 # type, or it is an extension type and the attribute is either not
3624 # declared or is declared as a Python method. Treat it as a Python
3625 # attribute reference.
3626 self.analyse_as_python_attribute(env, obj_type)
3628 def analyse_as_python_attribute(self, env, obj_type = None):
3629 if obj_type is None:
3630 obj_type = self.obj.type
3631 self.member = self.attribute
3632 self.type = py_object_type
3634 if not obj_type.is_pyobject and not obj_type.is_error:
3635 if obj_type.can_coerce_to_pyobject(env):
3636 self.obj = self.obj.coerce_to_pyobject(env)
3639 "Object of type '%s' has no attribute '%s'" %
3640 (obj_type, self.attribute))
3642 def nogil_check(self, env):
3646 gil_message = "Accessing Python attribute"
3648 def is_simple(self):
3650 return self.result_in_temp() or self.obj.is_simple()
3652 return NameNode.is_simple(self)
3654 def is_lvalue(self):
3658 return NameNode.is_lvalue(self)
3660 def is_ephemeral(self):
3662 return self.obj.is_ephemeral()
3664 return NameNode.is_ephemeral(self)
3666 def calculate_result_code(self):
3667 #print "AttributeNode.calculate_result_code:", self.member ###
3668 #print "...obj node =", self.obj, "code", self.obj.result() ###
3669 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3671 obj_code = obj.result_as(obj.type)
3672 #print "...obj_code =", obj_code ###
3673 if self.entry and self.entry.is_cmethod:
3674 if obj.type.is_extension_type:
3675 return "((struct %s *)%s%s%s)->%s" % (
3676 obj.type.vtabstruct_cname, obj_code, self.op,
3677 obj.type.vtabslot_cname, self.member)
3680 elif obj.type.is_complex:
3681 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3683 if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
3684 # accessing a field of a builtin type, need to cast better than result_as() does
3685 obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
3686 return "%s%s%s" % (obj_code, self.op, self.member)
3688 def generate_result_code(self, code):
3689 interned_attr_cname = code.intern_identifier(self.attribute)
3692 '%s = PyObject_GetAttr(%s, %s); %s' % (
3694 self.obj.py_result(),
3695 interned_attr_cname,
3696 code.error_goto_if_null(self.result(), self.pos)))
3697 code.put_gotref(self.py_result())
3699 # result_code contains what is needed, but we may need to insert
3700 # a check and raise an exception
3701 if (self.obj.type.is_extension_type
3702 and self.needs_none_check
3703 and code.globalstate.directives['nonecheck']):
3704 self.put_nonecheck(code)
3706 def generate_assignment_code(self, rhs, code):
3707 interned_attr_cname = code.intern_identifier(self.attribute)
3708 self.obj.generate_evaluation_code(code)
3710 code.put_error_if_neg(self.pos,
3711 'PyObject_SetAttr(%s, %s, %s)' % (
3712 self.obj.py_result(),
3713 interned_attr_cname,
3715 rhs.generate_disposal_code(code)
3716 rhs.free_temps(code)
3717 elif self.obj.type.is_complex:
3718 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3719 self.member.upper(),
3720 self.obj.result_as(self.obj.type),
3721 rhs.result_as(self.ctype())))
3723 if (self.obj.type.is_extension_type
3724 and self.needs_none_check
3725 and code.globalstate.directives['nonecheck']):
3726 self.put_nonecheck(code)
3728 select_code = self.result()
3729 if self.type.is_pyobject and self.use_managed_ref:
3730 rhs.make_owned_reference(code)
3731 code.put_giveref(rhs.py_result())
3732 code.put_gotref(select_code)
3733 code.put_decref(select_code, self.ctype())
3737 rhs.result_as(self.ctype())))
3739 rhs.generate_post_assignment_code(code)
3740 rhs.free_temps(code)
3741 self.obj.generate_disposal_code(code)
3742 self.obj.free_temps(code)
3744 def generate_deletion_code(self, code):
3745 interned_attr_cname = code.intern_identifier(self.attribute)
3746 self.obj.generate_evaluation_code(code)
3747 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3748 and u'__del__' in self.entry.scope.entries):
3749 code.put_error_if_neg(self.pos,
3750 'PyObject_DelAttr(%s, %s)' % (
3751 self.obj.py_result(),
3752 interned_attr_cname))
3754 error(self.pos, "Cannot delete C attribute of extension type")
3755 self.obj.generate_disposal_code(code)
3756 self.obj.free_temps(code)
3758 def annotate(self, code):
3760 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3762 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3764 def put_nonecheck(self, code):
3765 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3766 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3767 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3768 code.putln(code.error_goto(self.pos))
3772 #-------------------------------------------------------------------
3776 #-------------------------------------------------------------------
3778 class StarredTargetNode(ExprNode):
3779 # A starred expression like "*a"
3781 # This is only allowed in sequence assignment targets such as
3783 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3785 # and will be removed during type analysis (or generate an error
3786 # if it's found at unexpected places).
3790 subexprs = ['target']
3792 type = py_object_type
3795 def __init__(self, pos, target):
3797 self.target = target
3799 def analyse_declarations(self, env):
3800 error(self.pos, "can use starred expression only as assignment target")
3801 self.target.analyse_declarations(env)
3803 def analyse_types(self, env):
3804 error(self.pos, "can use starred expression only as assignment target")
3805 self.target.analyse_types(env)
3806 self.type = self.target.type
3808 def analyse_target_declaration(self, env):
3809 self.target.analyse_target_declaration(env)
3811 def analyse_target_types(self, env):
3812 self.target.analyse_target_types(env)
3813 self.type = self.target.type
3815 def calculate_result_code(self):
3818 def generate_result_code(self, code):
3822 class SequenceNode(ExprNode):
3823 # Base class for list and tuple constructor nodes.
3824 # Contains common code for performing sequence unpacking.
3828 # unpacked_items [ExprNode] or None
3829 # coerced_unpacked_items [ExprNode] or None
3833 is_sequence_constructor = 1
3834 unpacked_items = None
3836 def compile_time_value_list(self, denv):
3837 return [arg.compile_time_value(denv) for arg in self.args]
3839 def replace_starred_target_node(self):
3840 # replace a starred node in the targets by the contained expression
3841 self.starred_assignment = False
3843 for arg in self.args:
3845 if self.starred_assignment:
3846 error(arg.pos, "more than 1 starred expression in assignment")
3847 self.starred_assignment = True
3849 arg.is_starred = True
3853 def analyse_target_declaration(self, env):
3854 self.replace_starred_target_node()
3855 for arg in self.args:
3856 arg.analyse_target_declaration(env)
3858 def analyse_types(self, env, skip_children=False):
3859 for i in range(len(self.args)):
3861 if not skip_children: arg.analyse_types(env)
3862 self.args[i] = arg.coerce_to_pyobject(env)
3864 # not setting self.type here, subtypes do this
3866 def may_be_none(self):
3869 def analyse_target_types(self, env):
3870 self.iterator = PyTempNode(self.pos, env)
3871 self.unpacked_items = []
3872 self.coerced_unpacked_items = []
3873 for arg in self.args:
3874 arg.analyse_target_types(env)
3876 if not arg.type.assignable_from(Builtin.list_type):
3878 "starred target must have Python object (list) type")
3879 if arg.type is py_object_type:
3880 arg.type = Builtin.list_type
3881 unpacked_item = PyTempNode(self.pos, env)
3882 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3883 self.unpacked_items.append(unpacked_item)
3884 self.coerced_unpacked_items.append(coerced_unpacked_item)
3885 self.type = py_object_type
3887 def generate_result_code(self, code):
3888 self.generate_operation_code(code)
3890 def generate_assignment_code(self, rhs, code):
3891 if self.starred_assignment:
3892 self.generate_starred_assignment_code(rhs, code)
3894 self.generate_parallel_assignment_code(rhs, code)
3896 for item in self.unpacked_items:
3898 rhs.free_temps(code)
3900 def generate_parallel_assignment_code(self, rhs, code):
3901 # Need to work around the fact that generate_evaluation_code
3902 # allocates the temps in a rather hacky way -- the assignment
3903 # is evaluated twice, within each if-block.
3905 if rhs.type is tuple_type:
3906 tuple_check = "likely(%s != Py_None)"
3908 tuple_check = "PyTuple_CheckExact(%s)"
3910 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3911 tuple_check % rhs.py_result(),
3914 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3915 for item in self.unpacked_items:
3917 for i in range(len(self.args)):
3918 item = self.unpacked_items[i]
3920 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3923 code.put_incref(item.result(), item.ctype())
3924 value_node = self.coerced_unpacked_items[i]
3925 value_node.generate_evaluation_code(code)
3926 rhs.generate_disposal_code(code)
3928 for i in range(len(self.args)):
3929 self.args[i].generate_assignment_code(
3930 self.coerced_unpacked_items[i], code)
3932 code.putln("} else {")
3934 if rhs.type is tuple_type:
3935 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3936 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3937 rhs.py_result(), len(self.args)))
3938 code.putln(code.error_goto(self.pos))
3940 code.globalstate.use_utility_code(unpacking_utility_code)
3942 self.iterator.allocate(code)
3944 "%s = PyObject_GetIter(%s); %s" % (
3945 self.iterator.result(),
3947 code.error_goto_if_null(self.iterator.result(), self.pos)))
3948 code.put_gotref(self.iterator.py_result())
3949 rhs.generate_disposal_code(code)
3950 for i in range(len(self.args)):
3951 item = self.unpacked_items[i]
3952 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3953 self.iterator.py_result(), i)
3957 typecast(item.ctype(), py_object_type, unpack_code),
3958 code.error_goto_if_null(item.result(), self.pos)))
3959 code.put_gotref(item.py_result())
3960 value_node = self.coerced_unpacked_items[i]
3961 value_node.generate_evaluation_code(code)
3962 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3963 self.iterator.py_result(),
3965 if debug_disposal_code:
3966 print("UnpackNode.generate_assignment_code:")
3967 print("...generating disposal code for %s" % self.iterator)
3968 self.iterator.generate_disposal_code(code)
3969 self.iterator.free_temps(code)
3970 self.iterator.release(code)
3972 for i in range(len(self.args)):
3973 self.args[i].generate_assignment_code(
3974 self.coerced_unpacked_items[i], code)
3978 def generate_starred_assignment_code(self, rhs, code):
3979 code.globalstate.use_utility_code(unpacking_utility_code)
3981 for i, arg in enumerate(self.args):
3983 starred_target = self.unpacked_items[i]
3984 fixed_args_left = self.args[:i]
3985 fixed_args_right = self.args[i+1:]
3988 self.iterator.allocate(code)
3990 "%s = PyObject_GetIter(%s); %s" % (
3991 self.iterator.result(),
3993 code.error_goto_if_null(self.iterator.result(), self.pos)))
3994 code.put_gotref(self.iterator.py_result())
3995 rhs.generate_disposal_code(code)
3997 for item in self.unpacked_items:
3999 for i in range(len(fixed_args_left)):
4000 item = self.unpacked_items[i]
4001 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
4002 self.iterator.py_result(), i)
4006 typecast(item.ctype(), py_object_type, unpack_code),
4007 code.error_goto_if_null(item.result(), self.pos)))
4008 code.put_gotref(item.py_result())
4009 value_node = self.coerced_unpacked_items[i]
4010 value_node.generate_evaluation_code(code)
4012 target_list = starred_target.result()
4013 code.putln("%s = PySequence_List(%s); %s" % (
4014 target_list, self.iterator.py_result(),
4015 code.error_goto_if_null(target_list, self.pos)))
4016 code.put_gotref(target_list)
4017 if fixed_args_right:
4018 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
4019 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
4020 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
4021 (target_list, len(unpacked_right_args))))
4022 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
4023 len(fixed_args_left), target_list,
4024 code.error_goto(self.pos)))
4026 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
4027 self.coerced_unpacked_items[::-1])):
4029 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
4031 target_list, target_list))
4032 # resize the list the hard way
4033 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
4034 code.put_gotref(arg.py_result())
4035 coerced_arg.generate_evaluation_code(code)
4037 self.iterator.generate_disposal_code(code)
4038 self.iterator.free_temps(code)
4039 self.iterator.release(code)
4041 for i in range(len(self.args)):
4042 self.args[i].generate_assignment_code(
4043 self.coerced_unpacked_items[i], code)
4045 def annotate(self, code):
4046 for arg in self.args:
4048 if self.unpacked_items:
4049 for arg in self.unpacked_items:
4051 for arg in self.coerced_unpacked_items:
4055 class TupleNode(SequenceNode):
4056 # Tuple constructor.
4060 gil_message = "Constructing Python tuple"
4062 def analyse_types(self, env, skip_children=False):
4063 if len(self.args) == 0:
4067 SequenceNode.analyse_types(self, env, skip_children)
4068 for child in self.args:
4069 if not child.is_literal:
4075 def is_simple(self):
4076 # either temp or constant => always simple
4079 def nonlocally_immutable(self):
4080 # either temp or constant => always safe
4083 def calculate_result_code(self):
4084 if len(self.args) > 0:
4085 return self.result_code
4087 return Naming.empty_tuple
4089 def calculate_constant_result(self):
4090 self.constant_result = tuple([
4091 arg.constant_result for arg in self.args])
4093 def compile_time_value(self, denv):
4094 values = self.compile_time_value_list(denv)
4096 return tuple(values)
4097 except Exception, e:
4098 self.compile_time_value_error(e)
4100 def generate_operation_code(self, code):
4101 if len(self.args) == 0:
4102 # result_code is Naming.empty_tuple
4105 # non-empty cached tuple => result is global constant,
4106 # creation code goes into separate code writer
4107 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
4108 code = code.get_cached_constants_writer()
4109 code.mark_pos(self.pos)
4112 "%s = PyTuple_New(%s); %s" % (
4115 code.error_goto_if_null(self.result(), self.pos)))
4116 code.put_gotref(self.py_result())
4117 for i in range(len(self.args)):
4119 if not arg.result_in_temp():
4120 code.put_incref(arg.result(), arg.ctype())
4122 "PyTuple_SET_ITEM(%s, %s, %s);" % (
4126 code.put_giveref(arg.py_result())
4128 code.put_giveref(self.py_result())
4130 def generate_subexpr_disposal_code(self, code):
4131 # We call generate_post_assignment_code here instead
4132 # of generate_disposal_code, because values were stored
4133 # in the tuple using a reference-stealing operation.
4134 for arg in self.args:
4135 arg.generate_post_assignment_code(code)
4136 # Should NOT call free_temps -- this is invoked by the default
4137 # generate_evaluation_code which will do that.
4140 class ListNode(SequenceNode):
4143 # obj_conversion_errors [PyrexError] used internally
4144 # orignial_args [ExprNode] used internally
4146 obj_conversion_errors = []
4149 gil_message = "Constructing Python list"
4151 def type_dependencies(self, env):
4154 def infer_type(self, env):
4155 # TOOD: Infer non-object list arrays.
4158 def analyse_expressions(self, env):
4159 SequenceNode.analyse_expressions(self, env)
4160 self.coerce_to_pyobject(env)
4162 def analyse_types(self, env):
4164 self.original_args = list(self.args)
4165 SequenceNode.analyse_types(self, env)
4166 self.obj_conversion_errors = held_errors()
4167 release_errors(ignore=True)
4169 def coerce_to(self, dst_type, env):
4170 if dst_type.is_pyobject:
4171 for err in self.obj_conversion_errors:
4173 self.obj_conversion_errors = []
4174 if not self.type.subtype_of(dst_type):
4175 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4176 elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
4177 base_type = dst_type.base_type
4178 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4179 for i in range(len(self.original_args)):
4181 if isinstance(arg, CoerceToPyTypeNode):
4183 self.args[i] = arg.coerce_to(base_type, env)
4184 elif dst_type.is_struct:
4185 if len(self.args) > len(dst_type.scope.var_entries):
4186 error(self.pos, "Too may members for '%s'" % dst_type)
4188 if len(self.args) < len(dst_type.scope.var_entries):
4189 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4190 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4191 if isinstance(arg, CoerceToPyTypeNode):
4193 self.args[i] = arg.coerce_to(member.type, env)
4194 self.type = dst_type
4196 self.type = error_type
4197 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4200 def release_temp(self, env):
4201 if self.type.is_array:
4202 # To be valid C++, we must allocate the memory on the stack
4203 # manually and be sure not to reuse it for something else.
4206 SequenceNode.release_temp(self, env)
4208 def calculate_constant_result(self):
4209 self.constant_result = [
4210 arg.constant_result for arg in self.args]
4212 def compile_time_value(self, denv):
4213 return self.compile_time_value_list(denv)
4215 def generate_operation_code(self, code):
4216 if self.type.is_pyobject:
4217 for err in self.obj_conversion_errors:
4219 code.putln("%s = PyList_New(%s); %s" %
4222 code.error_goto_if_null(self.result(), self.pos)))
4223 code.put_gotref(self.py_result())
4224 for i in range(len(self.args)):
4226 #if not arg.is_temp:
4227 if not arg.result_in_temp():
4228 code.put_incref(arg.result(), arg.ctype())
4229 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4233 code.put_giveref(arg.py_result())
4234 elif self.type.is_array:
4235 for i, arg in enumerate(self.args):
4236 code.putln("%s[%s] = %s;" % (
4240 elif self.type.is_struct:
4241 for arg, member in zip(self.args, self.type.scope.var_entries):
4242 code.putln("%s.%s = %s;" % (
4247 raise InternalError("List type never specified")
4249 def generate_subexpr_disposal_code(self, code):
4250 # We call generate_post_assignment_code here instead
4251 # of generate_disposal_code, because values were stored
4252 # in the list using a reference-stealing operation.
4253 for arg in self.args:
4254 arg.generate_post_assignment_code(code)
4255 # Should NOT call free_temps -- this is invoked by the default
4256 # generate_evaluation_code which will do that.
4259 class ScopedExprNode(ExprNode):
4260 # Abstract base class for ExprNodes that have their own local
4261 # scope, such as generator expressions.
4263 # expr_scope Scope the inner scope of the expression
4268 # does this node really have a local scope, e.g. does it leak loop
4269 # variables or not? non-leaking Py3 behaviour is default, except
4270 # for list comprehensions where the behaviour differs in Py2 and
4271 # Py3 (set in Parsing.py based on parser context)
4272 has_local_scope = True
4274 def init_scope(self, outer_scope, expr_scope=None):
4275 if expr_scope is not None:
4276 self.expr_scope = expr_scope
4277 elif self.has_local_scope:
4278 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4280 self.expr_scope = None
4282 def analyse_declarations(self, env):
4283 self.init_scope(env)
4285 def analyse_scoped_declarations(self, env):
4286 # this is called with the expr_scope as env
4289 def analyse_types(self, env):
4290 # no recursion here, the children will be analysed separately below
4293 def analyse_scoped_expressions(self, env):
4294 # this is called with the expr_scope as env
4297 def generate_evaluation_code(self, code):
4298 # set up local variables and free their references on exit
4299 generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
4300 if not self.has_local_scope or not self.expr_scope.var_entries:
4301 # no local variables => delegate, done
4302 generate_inner_evaluation_code(code)
4305 code.putln('{ /* enter inner scope */')
4307 for entry in self.expr_scope.var_entries:
4308 if not entry.in_closure:
4309 code.put_var_declaration(entry)
4310 if entry.type.is_pyobject and entry.used:
4311 py_entries.append(entry)
4313 # no local Python references => no cleanup required
4314 generate_inner_evaluation_code(code)
4315 code.putln('} /* exit inner scope */')
4317 for entry in py_entries:
4318 code.put_init_var_to_py_none(entry)
4320 # must free all local Python references at each exit point
4321 old_loop_labels = tuple(code.new_loop_labels())
4322 old_error_label = code.new_error_label()
4324 generate_inner_evaluation_code(code)
4326 # normal (non-error) exit
4327 for entry in py_entries:
4328 code.put_var_decref(entry)
4330 # error/loop body exit points
4331 exit_scope = code.new_label('exit_scope')
4332 code.put_goto(exit_scope)
4333 for label, old_label in ([(code.error_label, old_error_label)] +
4334 list(zip(code.get_loop_labels(), old_loop_labels))):
4335 if code.label_used(label):
4336 code.put_label(label)
4337 for entry in py_entries:
4338 code.put_var_decref(entry)
4339 code.put_goto(old_label)
4340 code.put_label(exit_scope)
4341 code.putln('} /* exit inner scope */')
4343 code.set_loop_labels(old_loop_labels)
4344 code.error_label = old_error_label
4347 class ComprehensionNode(ScopedExprNode):
4348 subexprs = ["target"]
4349 child_attrs = ["loop", "append"]
4351 def infer_type(self, env):
4352 return self.target.infer_type(env)
4354 def analyse_declarations(self, env):
4355 self.append.target = self # this is used in the PyList_Append of the inner loop
4356 self.init_scope(env)
4358 def analyse_scoped_declarations(self, env):
4359 self.loop.analyse_declarations(env)
4361 def analyse_types(self, env):
4362 self.target.analyse_expressions(env)
4363 self.type = self.target.type
4364 if not self.has_local_scope:
4365 self.loop.analyse_expressions(env)
4367 def analyse_scoped_expressions(self, env):
4368 if self.has_local_scope:
4369 self.loop.analyse_expressions(env)
4371 def may_be_none(self):
4374 def calculate_result_code(self):
4375 return self.target.result()
4377 def generate_result_code(self, code):
4378 self.generate_operation_code(code)
4380 def generate_operation_code(self, code):
4381 self.loop.generate_execution_code(code)
4383 def annotate(self, code):
4384 self.loop.annotate(code)
4387 class ComprehensionAppendNode(Node):
4388 # Need to be careful to avoid infinite recursion:
4389 # target must not be in child_attrs/subexprs
4391 child_attrs = ['expr']
4393 type = PyrexTypes.c_int_type
4395 def analyse_expressions(self, env):
4396 self.expr.analyse_expressions(env)
4397 if not self.expr.type.is_pyobject:
4398 self.expr = self.expr.coerce_to_pyobject(env)
4400 def generate_execution_code(self, code):
4401 if self.target.type is list_type:
4402 function = "PyList_Append"
4403 elif self.target.type is set_type:
4404 function = "PySet_Add"
4406 raise InternalError(
4407 "Invalid type for comprehension node: %s" % self.target.type)
4409 self.expr.generate_evaluation_code(code)
4410 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4412 self.target.result(),
4415 self.expr.generate_disposal_code(code)
4416 self.expr.free_temps(code)
4418 def generate_function_definitions(self, env, code):
4419 self.expr.generate_function_definitions(env, code)
4421 def annotate(self, code):
4422 self.expr.annotate(code)
4424 class DictComprehensionAppendNode(ComprehensionAppendNode):
4425 child_attrs = ['key_expr', 'value_expr']
4427 def analyse_expressions(self, env):
4428 self.key_expr.analyse_expressions(env)
4429 if not self.key_expr.type.is_pyobject:
4430 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4431 self.value_expr.analyse_expressions(env)
4432 if not self.value_expr.type.is_pyobject:
4433 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4435 def generate_execution_code(self, code):
4436 self.key_expr.generate_evaluation_code(code)
4437 self.value_expr.generate_evaluation_code(code)
4438 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4439 self.target.result(),
4440 self.key_expr.result(),
4441 self.value_expr.result()
4443 self.key_expr.generate_disposal_code(code)
4444 self.key_expr.free_temps(code)
4445 self.value_expr.generate_disposal_code(code)
4446 self.value_expr.free_temps(code)
4448 def generate_function_definitions(self, env, code):
4449 self.key_expr.generate_function_definitions(env, code)
4450 self.value_expr.generate_function_definitions(env, code)
4452 def annotate(self, code):
4453 self.key_expr.annotate(code)
4454 self.value_expr.annotate(code)
4457 class InlinedGeneratorExpressionNode(ScopedExprNode):
4458 # An inlined generator expression for which the result is
4459 # calculated inside of the loop. This will only be created by
4460 # transforms when replacing builtin calls on generator
4463 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4464 # result_node ResultRefNode the reference to the result value temp
4465 # orig_func String the name of the builtin function this node replaces
4467 child_attrs = ["loop"]
4468 loop_analysed = False
4469 type = py_object_type
4471 def analyse_scoped_declarations(self, env):
4472 self.loop.analyse_declarations(env)
4474 def analyse_types(self, env):
4475 if not self.has_local_scope:
4476 self.loop.analyse_expressions(env)
4479 def may_be_none(self):
4482 def annotate(self, code):
4483 self.loop.annotate(code)
4485 def infer_type(self, env):
4486 return self.result_node.infer_type(env)
4488 def analyse_types(self, env):
4489 if not self.has_local_scope:
4490 self.loop_analysed = True
4491 self.loop.analyse_expressions(env)
4492 self.type = self.result_node.type
4495 def analyse_scoped_expressions(self, env):
4496 self.loop_analysed = True
4497 if self.has_local_scope:
4498 self.loop.analyse_expressions(env)
4500 def coerce_to(self, dst_type, env):
4501 if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
4502 # We can optimise by dropping the aggregation variable and
4503 # the add operations into C. This can only be done safely
4504 # before analysing the loop body, after that, the result
4505 # reference type will have infected expressions and
4507 self.result_node.type = self.type = dst_type
4509 return super(InlinedGeneratorExpressionNode, self).coerce_to(dst_type, env)
4511 def generate_result_code(self, code):
4512 self.result_node.result_code = self.result()
4513 self.loop.generate_execution_code(code)
4516 class SetNode(ExprNode):
4523 gil_message = "Constructing Python set"
4525 def analyse_types(self, env):
4526 for i in range(len(self.args)):
4528 arg.analyse_types(env)
4529 self.args[i] = arg.coerce_to_pyobject(env)
4530 self.type = set_type
4533 def may_be_none(self):
4536 def calculate_constant_result(self):
4537 self.constant_result = set([
4538 arg.constant_result for arg in self.args])
4540 def compile_time_value(self, denv):
4541 values = [arg.compile_time_value(denv) for arg in self.args]
4544 except Exception, e:
4545 self.compile_time_value_error(e)
4547 def generate_evaluation_code(self, code):
4548 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4549 self.allocate_temp_result(code)
4551 "%s = PySet_New(0); %s" % (
4553 code.error_goto_if_null(self.result(), self.pos)))
4554 code.put_gotref(self.py_result())
4555 for arg in self.args:
4556 arg.generate_evaluation_code(code)
4558 code.error_goto_if_neg(
4559 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4561 arg.generate_disposal_code(code)
4562 arg.free_temps(code)
4565 class DictNode(ExprNode):
4566 # Dictionary constructor.
4568 # key_value_pairs [DictItemNode]
4570 # obj_conversion_errors [PyrexError] used internally
4572 subexprs = ['key_value_pairs']
4576 obj_conversion_errors = []
4578 def calculate_constant_result(self):
4579 self.constant_result = dict([
4580 item.constant_result for item in self.key_value_pairs])
4582 def compile_time_value(self, denv):
4583 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4584 for item in self.key_value_pairs]
4587 except Exception, e:
4588 self.compile_time_value_error(e)
4590 def type_dependencies(self, env):
4593 def infer_type(self, env):
4594 # TOOD: Infer struct constructors.
4597 def analyse_types(self, env):
4599 for item in self.key_value_pairs:
4600 item.analyse_types(env)
4601 self.obj_conversion_errors = held_errors()
4602 release_errors(ignore=True)
4604 def may_be_none(self):
4607 def coerce_to(self, dst_type, env):
4608 if dst_type.is_pyobject:
4609 self.release_errors()
4610 if not self.type.subtype_of(dst_type):
4611 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4612 elif dst_type.is_struct_or_union:
4613 self.type = dst_type
4614 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4615 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4616 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4617 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4618 for item in self.key_value_pairs:
4619 if isinstance(item.key, CoerceToPyTypeNode):
4620 item.key = item.key.arg
4621 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4622 error(item.key.pos, "Invalid struct field identifier")
4623 item.key = StringNode(item.key.pos, value="<error>")
4625 key = str(item.key.value) # converts string literals to unicode in Py3
4626 member = dst_type.scope.lookup_here(key)
4628 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4631 if isinstance(value, CoerceToPyTypeNode):
4633 item.value = value.coerce_to(member.type, env)
4635 self.type = error_type
4636 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4639 def release_errors(self):
4640 for err in self.obj_conversion_errors:
4642 self.obj_conversion_errors = []
4644 gil_message = "Constructing Python dict"
4646 def generate_evaluation_code(self, code):
4647 # Custom method used here because key-value
4648 # pairs are evaluated and used one at a time.
4649 code.mark_pos(self.pos)
4650 self.allocate_temp_result(code)
4651 if self.type.is_pyobject:
4652 self.release_errors()
4654 "%s = PyDict_New(); %s" % (
4656 code.error_goto_if_null(self.result(), self.pos)))
4657 code.put_gotref(self.py_result())
4658 for item in self.key_value_pairs:
4659 item.generate_evaluation_code(code)
4660 if self.type.is_pyobject:
4661 code.put_error_if_neg(self.pos,
4662 "PyDict_SetItem(%s, %s, %s)" % (
4664 item.key.py_result(),
4665 item.value.py_result()))
4667 code.putln("%s.%s = %s;" % (
4670 item.value.result()))
4671 item.generate_disposal_code(code)
4672 item.free_temps(code)
4674 def annotate(self, code):
4675 for item in self.key_value_pairs:
4678 class DictItemNode(ExprNode):
4679 # Represents a single item in a DictNode
4683 subexprs = ['key', 'value']
4685 nogil_check = None # Parent DictNode takes care of it
4687 def calculate_constant_result(self):
4688 self.constant_result = (
4689 self.key.constant_result, self.value.constant_result)
4691 def analyse_types(self, env):
4692 self.key.analyse_types(env)
4693 self.value.analyse_types(env)
4694 self.key = self.key.coerce_to_pyobject(env)
4695 self.value = self.value.coerce_to_pyobject(env)
4697 def generate_evaluation_code(self, code):
4698 self.key.generate_evaluation_code(code)
4699 self.value.generate_evaluation_code(code)
4701 def generate_disposal_code(self, code):
4702 self.key.generate_disposal_code(code)
4703 self.value.generate_disposal_code(code)
4705 def free_temps(self, code):
4706 self.key.free_temps(code)
4707 self.value.free_temps(code)
4710 return iter([self.key, self.value])
4712 class ModuleNameMixin(object):
4713 def set_mod_name(self, env):
4714 self.module_name = env.global_scope().qualified_name
4716 def get_py_mod_name(self, code):
4717 return code.get_py_string_const(
4718 self.module_name, identifier=True)
4720 class ClassNode(ExprNode, ModuleNameMixin):
4721 # Helper class used in the implementation of Python
4722 # class definitions. Constructs a class object given
4723 # a name, tuple of bases and class dictionary.
4725 # name EncodedString Name of the class
4726 # bases ExprNode Base class tuple
4727 # dict ExprNode Class dict (not owned by this node)
4728 # doc ExprNode or None Doc string
4729 # module_name EncodedString Name of defining module
4731 subexprs = ['bases', 'doc']
4733 def analyse_types(self, env):
4734 self.bases.analyse_types(env)
4736 self.doc.analyse_types(env)
4737 self.doc = self.doc.coerce_to_pyobject(env)
4738 self.type = py_object_type
4740 env.use_utility_code(create_class_utility_code);
4741 #TODO(craig,haoyu) This should be moved to a better place
4742 self.set_mod_name(env)
4744 def may_be_none(self):
4747 gil_message = "Constructing Python class"
4749 def generate_result_code(self, code):
4750 cname = code.intern_identifier(self.name)
4753 code.put_error_if_neg(self.pos,
4754 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4755 self.dict.py_result(),
4756 self.doc.py_result()))
4757 py_mod_name = self.get_py_mod_name(code)
4759 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4761 self.bases.py_result(),
4762 self.dict.py_result(),
4765 code.error_goto_if_null(self.result(), self.pos)))
4766 code.put_gotref(self.py_result())
4769 class Py3ClassNode(ExprNode):
4770 # Helper class used in the implementation of Python3+
4771 # class definitions. Constructs a class object given
4772 # a name, tuple of bases and class dictionary.
4774 # name EncodedString Name of the class
4775 # dict ExprNode Class dict (not owned by this node)
4776 # module_name EncodedString Name of defining module
4780 def analyse_types(self, env):
4781 self.type = py_object_type
4784 def may_be_none(self):
4787 gil_message = "Constructing Python class"
4789 def generate_result_code(self, code):
4790 code.globalstate.use_utility_code(create_py3class_utility_code)
4791 cname = code.intern_identifier(self.name)
4793 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4795 self.metaclass.result(),
4797 self.bases.py_result(),
4798 self.dict.py_result(),
4799 self.mkw.py_result(),
4800 code.error_goto_if_null(self.result(), self.pos)))
4801 code.put_gotref(self.py_result())
4803 class KeywordArgsNode(ExprNode):
4804 # Helper class for keyword arguments
4806 # keyword_args ExprNode or None Keyword arguments
4807 # starstar_arg ExprNode or None Extra arguments
4809 subexprs = ['keyword_args', 'starstar_arg']
4811 def analyse_types(self, env):
4812 if self.keyword_args:
4813 self.keyword_args.analyse_types(env)
4814 if self.starstar_arg:
4815 self.starstar_arg.analyse_types(env)
4816 # make sure we have a Python object as **kwargs mapping
4817 self.starstar_arg = \
4818 self.starstar_arg.coerce_to_pyobject(env)
4819 self.type = py_object_type
4822 gil_message = "Constructing Keyword Args"
4824 def generate_result_code(self, code):
4825 if self.keyword_args and self.starstar_arg:
4826 code.put_error_if_neg(self.pos,
4827 "PyDict_Update(%s, %s)" % (
4828 self.keyword_args.py_result(),
4829 self.starstar_arg.py_result()))
4830 if self.keyword_args:
4831 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4832 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4833 elif self.starstar_arg:
4835 "%s = PyDict_Copy(%s); %s" % (
4837 self.starstar_arg.py_result(),
4838 code.error_goto_if_null(self.result(), self.pos)))
4839 code.put_gotref(self.py_result())
4842 "%s = PyDict_New(); %s" % (
4844 code.error_goto_if_null(self.result(), self.pos)))
4845 code.put_gotref(self.py_result())
4847 class PyClassMetaclassNode(ExprNode):
4848 # Helper class holds Python3 metaclass object
4850 # bases ExprNode Base class tuple (not owned by this node)
4851 # mkw ExprNode Class keyword arguments (not owned by this node)
4855 def analyse_types(self, env):
4856 self.type = py_object_type
4859 def may_be_none(self):
4862 def generate_result_code(self, code):
4864 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4866 self.bases.result(),
4868 code.error_goto_if_null(self.result(), self.pos)))
4869 code.put_gotref(self.py_result())
4871 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4872 # Helper class holds Python3 namespace object
4874 # All this are not owned by this node
4875 # metaclass ExprNode Metaclass object
4876 # bases ExprNode Base class tuple
4877 # mkw ExprNode Class keyword arguments
4878 # doc ExprNode or None Doc string (owned)
4882 def analyse_types(self, env):
4883 self.bases.analyse_types(env)
4885 self.doc.analyse_types(env)
4886 self.doc = self.doc.coerce_to_pyobject(env)
4887 self.type = py_object_type
4889 #TODO(craig,haoyu) This should be moved to a better place
4890 self.set_mod_name(env)
4892 def may_be_none(self):
4895 def generate_result_code(self, code):
4896 cname = code.intern_identifier(self.name)
4897 py_mod_name = self.get_py_mod_name(code)
4899 doc_code = self.doc.result()
4901 doc_code = '(PyObject *) NULL'
4903 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4905 self.metaclass.result(),
4906 self.bases.result(),
4911 code.error_goto_if_null(self.result(), self.pos)))
4912 code.put_gotref(self.py_result())
4914 class BoundMethodNode(ExprNode):
4915 # Helper class used in the implementation of Python
4916 # class definitions. Constructs an bound method
4917 # object from a class and a function.
4919 # function ExprNode Function object
4920 # self_object ExprNode self object
4922 subexprs = ['function']
4924 def analyse_types(self, env):
4925 self.function.analyse_types(env)
4926 self.type = py_object_type
4929 gil_message = "Constructing an bound method"
4931 def generate_result_code(self, code):
4933 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4935 self.function.py_result(),
4936 self.self_object.py_result(),
4937 self.self_object.py_result(),
4938 code.error_goto_if_null(self.result(), self.pos)))
4939 code.put_gotref(self.py_result())
4941 class UnboundMethodNode(ExprNode):
4942 # Helper class used in the implementation of Python
4943 # class definitions. Constructs an unbound method
4944 # object from a class and a function.
4946 # function ExprNode Function object
4948 type = py_object_type
4951 subexprs = ['function']
4953 def analyse_types(self, env):
4954 self.function.analyse_types(env)
4956 def may_be_none(self):
4959 gil_message = "Constructing an unbound method"
4961 def generate_result_code(self, code):
4962 class_cname = code.pyclass_stack[-1].classobj.result()
4964 "%s = PyMethod_New(%s, 0, %s); %s" % (
4966 self.function.py_result(),
4968 code.error_goto_if_null(self.result(), self.pos)))
4969 code.put_gotref(self.py_result())
4972 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4973 # Helper class used in the implementation of Python
4974 # class definitions. Constructs a PyCFunction object
4975 # from a PyMethodDef struct.
4977 # pymethdef_cname string PyMethodDef structure
4978 # self_object ExprNode or None
4980 # module_name EncodedString Name of defining module
4986 type = py_object_type
4989 def analyse_types(self, env):
4991 env.use_utility_code(binding_cfunc_utility_code)
4993 #TODO(craig,haoyu) This should be moved to a better place
4994 self.set_mod_name(env)
4996 def may_be_none(self):
4999 gil_message = "Constructing Python function"
5001 def self_result_code(self):
5002 if self.self_object is None:
5003 self_result = "NULL"
5005 self_result = self.self_object.py_result()
5008 def generate_result_code(self, code):
5010 constructor = "%s_NewEx" % Naming.binding_cfunc
5012 constructor = "PyCFunction_NewEx"
5013 py_mod_name = self.get_py_mod_name(code)
5015 '%s = %s(&%s, %s, %s); %s' % (
5018 self.pymethdef_cname,
5019 self.self_result_code(),
5021 code.error_goto_if_null(self.result(), self.pos)))
5022 code.put_gotref(self.py_result())
5024 class InnerFunctionNode(PyCFunctionNode):
5025 # Special PyCFunctionNode that depends on a closure class
5029 needs_self_code = True
5031 def self_result_code(self):
5032 if self.needs_self_code:
5033 return "((PyObject*)%s)" % (Naming.cur_scope_cname)
5036 class LambdaNode(InnerFunctionNode):
5037 # Lambda expression node (only used as a function reference)
5039 # args [CArgDeclNode] formal arguments
5040 # star_arg PyArgDeclNode or None * argument
5041 # starstar_arg PyArgDeclNode or None ** argument
5042 # lambda_name string a module-globally unique lambda name
5043 # result_expr ExprNode
5044 # def_node DefNode the underlying function 'def' node
5046 child_attrs = ['def_node']
5049 name = StringEncoding.EncodedString('<lambda>')
5051 def analyse_declarations(self, env):
5052 self.def_node.analyse_declarations(env)
5053 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
5054 env.add_lambda_def(self.def_node)
5057 class GeneratorExpressionNode(LambdaNode):
5058 # A generator expression, e.g. (i for i in range(10))
5060 # Result is a generator.
5062 # loop ForStatNode the for-loop, containing a YieldExprNode
5063 # def_node DefNode the underlying generator 'def' node
5065 name = StringEncoding.EncodedString('genexpr')
5068 def analyse_declarations(self, env):
5069 self.def_node.no_assignment_synthesis = True
5070 self.def_node.analyse_declarations(env)
5071 env.add_lambda_def(self.def_node)
5073 def generate_result_code(self, code):
5075 '%s = %s(%s, NULL); %s' % (
5077 self.def_node.entry.func_cname,
5078 self.self_result_code(),
5079 code.error_goto_if_null(self.result(), self.pos)))
5080 code.put_gotref(self.py_result())
5083 class YieldExprNode(ExprNode):
5084 # Yield expression node
5086 # arg ExprNode the value to return from the generator
5087 # label_name string name of the C label used for this yield
5088 # label_num integer yield label number
5091 type = py_object_type
5094 def analyse_types(self, env):
5095 if not self.label_num:
5096 error(self.pos, "'yield' not supported here")
5098 if self.arg is not None:
5099 self.arg.analyse_types(env)
5100 if not self.arg.type.is_pyobject:
5101 self.arg = self.arg.coerce_to_pyobject(env)
5102 env.use_utility_code(generator_utility_code)
5104 def generate_evaluation_code(self, code):
5105 self.label_name = code.new_label('resume_from_yield')
5106 code.use_label(self.label_name)
5108 self.arg.generate_evaluation_code(code)
5109 self.arg.make_owned_reference(code)
5112 Naming.retval_cname,
5113 self.arg.result_as(py_object_type)))
5114 self.arg.generate_post_assignment_code(code)
5115 #self.arg.generate_disposal_code(code)
5116 self.arg.free_temps(code)
5118 code.put_init_to_py_none(Naming.retval_cname, py_object_type)
5120 code.funcstate.closure_temps.reset()
5121 for cname, type, manage_ref in code.funcstate.temps_in_use():
5122 save_cname = code.funcstate.closure_temps.allocate_temp(type)
5123 saved.append((cname, save_cname, type))
5124 if type.is_pyobject:
5125 code.put_xgiveref(cname)
5126 code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
5128 code.put_xgiveref(Naming.retval_cname)
5129 code.put_finish_refcount_context()
5130 code.putln("/* return from generator, yielding value */")
5131 code.putln("%s->%s.resume_label = %d;" % (Naming.cur_scope_cname, Naming.obj_base_cname, self.label_num))
5132 code.putln("return %s;" % Naming.retval_cname);
5133 code.put_label(self.label_name)
5134 for cname, save_cname, type in saved:
5135 code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
5136 if type.is_pyobject:
5137 code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
5138 if type.is_pyobject:
5139 code.put_xgotref(cname)
5140 if self.result_is_used:
5141 self.allocate_temp_result(code)
5142 code.putln('%s = %s; %s' %
5143 (self.result(), Naming.sent_value_cname,
5144 code.error_goto_if_null(self.result(), self.pos)))
5145 code.put_incref(self.result(), py_object_type)
5147 code.putln(code.error_goto_if_null(Naming.sent_value_cname, self.pos))
5149 #-------------------------------------------------------------------
5151 # Unary operator nodes
5153 #-------------------------------------------------------------------
5155 compile_time_unary_operators = {
5156 'not': operator.not_,
5162 class UnopNode(ExprNode):
5166 # Processing during analyse_expressions phase:
5168 # analyse_c_operation
5169 # Called when the operand is not a pyobject.
5170 # - Check operand type and coerce if needed.
5171 # - Determine result type and result code fragment.
5172 # - Allocate temporary for result if needed.
5174 subexprs = ['operand']
5177 def calculate_constant_result(self):
5178 func = compile_time_unary_operators[self.operator]
5179 self.constant_result = func(self.operand.constant_result)
5181 def compile_time_value(self, denv):
5182 func = compile_time_unary_operators.get(self.operator)
5185 "Unary '%s' not supported in compile-time expression"
5187 operand = self.operand.compile_time_value(denv)
5189 return func(operand)
5190 except Exception, e:
5191 self.compile_time_value_error(e)
5193 def infer_type(self, env):
5194 operand_type = self.operand.infer_type(env)
5195 if operand_type.is_pyobject:
5196 return py_object_type
5200 def analyse_types(self, env):
5201 self.operand.analyse_types(env)
5202 if self.is_py_operation():
5203 self.coerce_operand_to_pyobject(env)
5204 self.type = py_object_type
5206 elif self.is_cpp_operation():
5207 self.analyse_cpp_operation(env)
5209 self.analyse_c_operation(env)
5211 def check_const(self):
5212 return self.operand.check_const()
5214 def is_py_operation(self):
5215 return self.operand.type.is_pyobject
5217 def nogil_check(self, env):
5218 if self.is_py_operation():
5221 def is_cpp_operation(self):
5222 type = self.operand.type
5223 return type.is_cpp_class
5225 def coerce_operand_to_pyobject(self, env):
5226 self.operand = self.operand.coerce_to_pyobject(env)
5228 def generate_result_code(self, code):
5229 if self.operand.type.is_pyobject:
5230 self.generate_py_operation_code(code)
5232 def generate_py_operation_code(self, code):
5233 function = self.py_operation_function()
5235 "%s = %s(%s); %s" % (
5238 self.operand.py_result(),
5239 code.error_goto_if_null(self.result(), self.pos)))
5240 code.put_gotref(self.py_result())
5242 def type_error(self):
5243 if not self.operand.type.is_error:
5244 error(self.pos, "Invalid operand type for '%s' (%s)" %
5245 (self.operator, self.operand.type))
5246 self.type = PyrexTypes.error_type
5248 def analyse_cpp_operation(self, env):
5249 type = self.operand.type
5251 type = type.base_type
5252 function = type.scope.lookup("operator%s" % self.operator)
5254 error(self.pos, "'%s' operator not defined for %s"
5255 % (self.operator, type))
5258 func_type = function.type
5259 if func_type.is_ptr:
5260 func_type = func_type.base_type
5261 self.type = func_type.return_type
5264 class NotNode(ExprNode):
5269 type = PyrexTypes.c_bint_type
5271 subexprs = ['operand']
5273 def calculate_constant_result(self):
5274 self.constant_result = not self.operand.constant_result
5276 def compile_time_value(self, denv):
5277 operand = self.operand.compile_time_value(denv)
5280 except Exception, e:
5281 self.compile_time_value_error(e)
5283 def infer_type(self, env):
5284 return PyrexTypes.c_bint_type
5286 def analyse_types(self, env):
5287 self.operand.analyse_types(env)
5288 self.operand = self.operand.coerce_to_boolean(env)
5290 def calculate_result_code(self):
5291 return "(!%s)" % self.operand.result()
5293 def generate_result_code(self, code):
5297 class UnaryPlusNode(UnopNode):
5298 # unary '+' operator
5302 def analyse_c_operation(self, env):
5303 self.type = PyrexTypes.widest_numeric_type(
5304 self.operand.type, PyrexTypes.c_int_type)
5306 def py_operation_function(self):
5307 return "PyNumber_Positive"
5309 def calculate_result_code(self):
5310 if self.is_cpp_operation():
5311 return "(+%s)" % self.operand.result()
5313 return self.operand.result()
5316 class UnaryMinusNode(UnopNode):
5317 # unary '-' operator
5321 def analyse_c_operation(self, env):
5322 if self.operand.type.is_numeric:
5323 self.type = PyrexTypes.widest_numeric_type(
5324 self.operand.type, PyrexTypes.c_int_type)
5327 if self.type.is_complex:
5330 def py_operation_function(self):
5331 return "PyNumber_Negative"
5333 def calculate_result_code(self):
5335 return "(-%s)" % self.operand.result()
5337 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5339 def get_constant_c_result_code(self):
5340 value = self.operand.get_constant_c_result_code()
5342 return "(-%s)" % (value)
5344 class TildeNode(UnopNode):
5345 # unary '~' operator
5347 def analyse_c_operation(self, env):
5348 if self.operand.type.is_int:
5349 self.type = PyrexTypes.widest_numeric_type(
5350 self.operand.type, PyrexTypes.c_int_type)
5354 def py_operation_function(self):
5355 return "PyNumber_Invert"
5357 def calculate_result_code(self):
5358 return "(~%s)" % self.operand.result()
5361 class CUnopNode(UnopNode):
5363 def is_py_operation(self):
5366 class DereferenceNode(CUnopNode):
5371 def analyse_c_operation(self, env):
5372 if self.operand.type.is_ptr:
5373 self.type = self.operand.type.base_type
5377 def calculate_result_code(self):
5378 return "(*%s)" % self.operand.result()
5381 class DecrementIncrementNode(CUnopNode):
5382 # unary ++/-- operator
5384 def analyse_c_operation(self, env):
5385 if self.operand.type.is_numeric:
5386 self.type = PyrexTypes.widest_numeric_type(
5387 self.operand.type, PyrexTypes.c_int_type)
5388 elif self.operand.type.is_ptr:
5389 self.type = self.operand.type
5393 def calculate_result_code(self):
5395 return "(%s%s)" % (self.operator, self.operand.result())
5397 return "(%s%s)" % (self.operand.result(), self.operator)
5399 def inc_dec_constructor(is_prefix, operator):
5400 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5403 class AmpersandNode(ExprNode):
5404 # The C address-of operator.
5408 subexprs = ['operand']
5410 def infer_type(self, env):
5411 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5413 def analyse_types(self, env):
5414 self.operand.analyse_types(env)
5415 argtype = self.operand.type
5416 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5417 self.error("Taking address of non-lvalue")
5419 if argtype.is_pyobject:
5420 self.error("Cannot take address of Python variable")
5422 self.type = PyrexTypes.c_ptr_type(argtype)
5424 def check_const(self):
5425 return self.operand.check_const_addr()
5427 def error(self, mess):
5428 error(self.pos, mess)
5429 self.type = PyrexTypes.error_type
5430 self.result_code = "<error>"
5432 def calculate_result_code(self):
5433 return "(&%s)" % self.operand.result()
5435 def generate_result_code(self, code):
5439 unop_node_classes = {
5441 "-": UnaryMinusNode,
5445 def unop_node(pos, operator, operand):
5446 # Construct unnop node of appropriate class for
5448 if isinstance(operand, IntNode) and operator == '-':
5449 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5450 elif isinstance(operand, UnopNode) and operand.operator == operator:
5451 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5452 return unop_node_classes[operator](pos,
5453 operator = operator,
5457 class TypecastNode(ExprNode):
5461 # base_type CBaseTypeNode
5462 # declarator CDeclaratorNode
5464 # If used from a transform, one can if wanted specify the attribute
5465 # "type" directly and leave base_type and declarator to None
5467 subexprs = ['operand']
5468 base_type = declarator = type = None
5470 def type_dependencies(self, env):
5473 def infer_type(self, env):
5474 if self.type is None:
5475 base_type = self.base_type.analyse(env)
5476 _, self.type = self.declarator.analyse(base_type, env)
5479 def analyse_types(self, env):
5480 if self.type is None:
5481 base_type = self.base_type.analyse(env)
5482 _, self.type = self.declarator.analyse(base_type, env)
5483 if self.type.is_cfunction:
5485 "Cannot cast to a function type")
5486 self.type = PyrexTypes.error_type
5487 self.operand.analyse_types(env)
5488 to_py = self.type.is_pyobject
5489 from_py = self.operand.type.is_pyobject
5490 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5491 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5492 if to_py and not from_py:
5493 if self.type is bytes_type and self.operand.type.is_int:
5494 # FIXME: the type cast node isn't needed in this case
5495 # and can be dropped once analyse_types() can return a
5497 self.operand = CoerceIntToBytesNode(self.operand, env)
5498 elif self.operand.type.can_coerce_to_pyobject(env):
5499 self.result_ctype = py_object_type
5500 self.operand = self.operand.coerce_to_pyobject(env)
5502 if self.operand.type.is_ptr:
5503 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5504 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5506 # Should this be an error?
5507 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5508 self.operand = self.operand.coerce_to_simple(env)
5509 elif from_py and not to_py:
5510 if self.type.create_from_py_utility_code(env):
5511 self.operand = self.operand.coerce_to(self.type, env)
5512 elif self.type.is_ptr:
5513 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5514 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5516 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5517 elif from_py and to_py:
5518 if self.typecheck and self.type.is_extension_type:
5519 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5520 elif self.type.is_complex and self.operand.type.is_complex:
5521 self.operand = self.operand.coerce_to_simple(env)
5523 def is_simple(self):
5524 # either temp or a C cast => no side effects
5527 def nonlocally_immutable(self):
5528 return self.operand.nonlocally_immutable()
5530 def nogil_check(self, env):
5531 if self.type and self.type.is_pyobject and self.is_temp:
5534 def check_const(self):
5535 return self.operand.check_const()
5537 def calculate_constant_result(self):
5538 # we usually do not know the result of a type cast at code
5542 def calculate_result_code(self):
5543 if self.type.is_complex:
5544 operand_result = self.operand.result()
5545 if self.operand.type.is_complex:
5546 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5547 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5549 real_part = self.type.real_type.cast_code(operand_result)
5551 return "%s(%s, %s)" % (
5552 self.type.from_parts,
5556 return self.type.cast_code(self.operand.result())
5558 def get_constant_c_result_code(self):
5559 operand_result = self.operand.get_constant_c_result_code()
5561 return self.type.cast_code(operand_result)
5563 def result_as(self, type):
5564 if self.type.is_pyobject and not self.is_temp:
5565 # Optimise away some unnecessary casting
5566 return self.operand.result_as(type)
5568 return ExprNode.result_as(self, type)
5570 def generate_result_code(self, code):
5573 "%s = (PyObject *)%s;" % (
5575 self.operand.result()))
5576 code.put_incref(self.result(), self.ctype())
5579 class SizeofNode(ExprNode):
5580 # Abstract base class for sizeof(x) expression nodes.
5582 type = PyrexTypes.c_size_t_type
5584 def check_const(self):
5587 def generate_result_code(self, code):
5591 class SizeofTypeNode(SizeofNode):
5592 # C sizeof function applied to a type
5594 # base_type CBaseTypeNode
5595 # declarator CDeclaratorNode
5600 def analyse_types(self, env):
5601 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5602 # this could be better handled by more uniformly treating types as runtime-available objects
5603 if 0 and self.base_type.module_path:
5604 path = self.base_type.module_path
5605 obj = env.lookup(path[0])
5606 if obj.as_module is None:
5607 operand = NameNode(pos=self.pos, name=path[0])
5608 for attr in path[1:]:
5609 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5610 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5611 self.operand = operand
5612 self.__class__ = SizeofVarNode
5613 self.analyse_types(env)
5615 if self.arg_type is None:
5616 base_type = self.base_type.analyse(env)
5617 _, arg_type = self.declarator.analyse(base_type, env)
5618 self.arg_type = arg_type
5621 def check_type(self):
5622 arg_type = self.arg_type
5623 if arg_type.is_pyobject and not arg_type.is_extension_type:
5624 error(self.pos, "Cannot take sizeof Python object")
5625 elif arg_type.is_void:
5626 error(self.pos, "Cannot take sizeof void")
5627 elif not arg_type.is_complete():
5628 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5630 def calculate_result_code(self):
5631 if self.arg_type.is_extension_type:
5632 # the size of the pointer is boring
5633 # we want the size of the actual struct
5634 arg_code = self.arg_type.declaration_code("", deref=1)
5636 arg_code = self.arg_type.declaration_code("")
5637 return "(sizeof(%s))" % arg_code
5640 class SizeofVarNode(SizeofNode):
5641 # C sizeof function applied to a variable
5645 subexprs = ['operand']
5647 def analyse_types(self, env):
5648 # We may actually be looking at a type rather than a variable...
5649 # If we are, traditional analysis would fail...
5650 operand_as_type = self.operand.analyse_as_type(env)
5652 self.arg_type = operand_as_type
5653 self.__class__ = SizeofTypeNode
5656 self.operand.analyse_types(env)
5658 def calculate_result_code(self):
5659 return "(sizeof(%s))" % self.operand.result()
5661 def generate_result_code(self, code):
5664 class TypeofNode(ExprNode):
5665 # Compile-time type of an expression, as a string.
5668 # literal StringNode # internal
5671 type = py_object_type
5673 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5675 def analyse_types(self, env):
5676 self.operand.analyse_types(env)
5677 self.literal = StringNode(
5678 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5679 self.literal.analyse_types(env)
5680 self.literal = self.literal.coerce_to_pyobject(env)
5682 def may_be_none(self):
5685 def generate_evaluation_code(self, code):
5686 self.literal.generate_evaluation_code(code)
5688 def calculate_result_code(self):
5689 return self.literal.calculate_result_code()
5691 #-------------------------------------------------------------------
5693 # Binary operator nodes
5695 #-------------------------------------------------------------------
5697 def _not_in(x, seq):
5700 compile_time_binary_operators = {
5708 'is_not': operator.is_not,
5711 '/': operator.truediv,
5712 '//': operator.floordiv,
5713 '<<': operator.lshift,
5718 '>>': operator.rshift,
5721 'in': operator.contains,
5725 def get_compile_time_binop(node):
5726 func = compile_time_binary_operators.get(node.operator)
5729 "Binary '%s' not supported in compile-time expression"
5733 class BinopNode(ExprNode):
5738 # Processing during analyse_expressions phase:
5740 # analyse_c_operation
5741 # Called when neither operand is a pyobject.
5742 # - Check operand types and coerce if needed.
5743 # - Determine result type and result code fragment.
5744 # - Allocate temporary for result if needed.
5746 subexprs = ['operand1', 'operand2']
5749 def calculate_constant_result(self):
5750 func = compile_time_binary_operators[self.operator]
5751 self.constant_result = func(
5752 self.operand1.constant_result,
5753 self.operand2.constant_result)
5755 def compile_time_value(self, denv):
5756 func = get_compile_time_binop(self)
5757 operand1 = self.operand1.compile_time_value(denv)
5758 operand2 = self.operand2.compile_time_value(denv)
5760 return func(operand1, operand2)
5761 except Exception, e:
5762 self.compile_time_value_error(e)
5764 def infer_type(self, env):
5765 return self.result_type(self.operand1.infer_type(env),
5766 self.operand2.infer_type(env))
5768 def analyse_types(self, env):
5769 self.operand1.analyse_types(env)
5770 self.operand2.analyse_types(env)
5771 self.analyse_operation(env)
5773 def analyse_operation(self, env):
5774 if self.is_py_operation():
5775 self.coerce_operands_to_pyobjects(env)
5776 self.type = self.result_type(self.operand1.type,
5778 assert self.type.is_pyobject
5780 elif self.is_cpp_operation():
5781 self.analyse_cpp_operation(env)
5783 self.analyse_c_operation(env)
5785 def is_py_operation(self):
5786 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5788 def is_py_operation_types(self, type1, type2):
5789 return type1.is_pyobject or type2.is_pyobject
5791 def is_cpp_operation(self):
5792 return (self.operand1.type.is_cpp_class
5793 or self.operand2.type.is_cpp_class)
5795 def analyse_cpp_operation(self, env):
5796 type1 = self.operand1.type
5797 type2 = self.operand2.type
5798 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5802 func_type = entry.type
5803 if func_type.is_ptr:
5804 func_type = func_type.base_type
5805 if len(func_type.args) == 1:
5806 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5808 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5809 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5810 self.type = func_type.return_type
5812 def result_type(self, type1, type2):
5813 if self.is_py_operation_types(type1, type2):
5815 type2 = Builtin.bytes_type
5817 type1 = Builtin.bytes_type
5818 elif self.operator == '%' \
5819 and type1 in (Builtin.str_type, Builtin.unicode_type):
5820 # note that b'%s' % b'abc' doesn't work in Py3
5822 if type1.is_builtin_type:
5824 if self.operator in '**%+|&^':
5825 # FIXME: at least these operators should be safe - others?
5827 elif self.operator == '*':
5828 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5830 # multiplication of containers/numbers with an
5831 # integer value always (?) returns the same type
5834 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5835 # multiplication of containers/numbers with an
5836 # integer value always (?) returns the same type
5838 return py_object_type
5840 return self.compute_c_result_type(type1, type2)
5842 def nogil_check(self, env):
5843 if self.is_py_operation():
5846 def coerce_operands_to_pyobjects(self, env):
5847 self.operand1 = self.operand1.coerce_to_pyobject(env)
5848 self.operand2 = self.operand2.coerce_to_pyobject(env)
5850 def check_const(self):
5851 return self.operand1.check_const() and self.operand2.check_const()
5853 def generate_result_code(self, code):
5854 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5855 if self.operand1.type.is_pyobject:
5856 function = self.py_operation_function()
5857 if self.operator == '**':
5858 extra_args = ", Py_None"
5862 "%s = %s(%s, %s%s); %s" % (
5865 self.operand1.py_result(),
5866 self.operand2.py_result(),
5868 code.error_goto_if_null(self.result(), self.pos)))
5869 code.put_gotref(self.py_result())
5871 def type_error(self):
5872 if not (self.operand1.type.is_error
5873 or self.operand2.type.is_error):
5874 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5875 (self.operator, self.operand1.type,
5876 self.operand2.type))
5877 self.type = PyrexTypes.error_type
5880 class CBinopNode(BinopNode):
5882 def analyse_types(self, env):
5883 BinopNode.analyse_types(self, env)
5884 if self.is_py_operation():
5885 self.type = PyrexTypes.error_type
5887 def py_operation_function():
5890 def calculate_result_code(self):
5891 return "(%s %s %s)" % (
5892 self.operand1.result(),
5894 self.operand2.result())
5897 def c_binop_constructor(operator):
5898 def make_binop_node(pos, **operands):
5899 return CBinopNode(pos, operator=operator, **operands)
5900 return make_binop_node
5902 class NumBinopNode(BinopNode):
5903 # Binary operation taking numeric arguments.
5907 def analyse_c_operation(self, env):
5908 type1 = self.operand1.type
5909 type2 = self.operand2.type
5910 self.type = self.compute_c_result_type(type1, type2)
5914 if self.type.is_complex:
5916 if not self.infix or (type1.is_numeric and type2.is_numeric):
5917 self.operand1 = self.operand1.coerce_to(self.type, env)
5918 self.operand2 = self.operand2.coerce_to(self.type, env)
5920 def compute_c_result_type(self, type1, type2):
5921 if self.c_types_okay(type1, type2):
5922 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5923 if widest_type is PyrexTypes.c_bint_type:
5924 if self.operator not in '|^&':
5925 # False + False == 0 # not False!
5926 widest_type = PyrexTypes.c_int_type
5928 widest_type = PyrexTypes.widest_numeric_type(
5929 widest_type, PyrexTypes.c_int_type)
5934 def get_constant_c_result_code(self):
5935 value1 = self.operand1.get_constant_c_result_code()
5936 value2 = self.operand2.get_constant_c_result_code()
5937 if value1 and value2:
5938 return "(%s %s %s)" % (value1, self.operator, value2)
5942 def c_types_okay(self, type1, type2):
5943 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5944 return (type1.is_numeric or type1.is_enum) \
5945 and (type2.is_numeric or type2.is_enum)
5947 def calculate_result_code(self):
5949 return "(%s %s %s)" % (
5950 self.operand1.result(),
5952 self.operand2.result())
5954 func = self.type.binary_op(self.operator)
5956 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5957 return "%s(%s, %s)" % (
5959 self.operand1.result(),
5960 self.operand2.result())
5962 def is_py_operation_types(self, type1, type2):
5963 return (type1.is_unicode_char or
5964 type2.is_unicode_char or
5965 BinopNode.is_py_operation_types(self, type1, type2))
5967 def py_operation_function(self):
5968 fuction = self.py_functions[self.operator]
5970 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
5975 "^": "PyNumber_Xor",
5976 "&": "PyNumber_And",
5977 "<<": "PyNumber_Lshift",
5978 ">>": "PyNumber_Rshift",
5979 "+": "PyNumber_Add",
5980 "-": "PyNumber_Subtract",
5981 "*": "PyNumber_Multiply",
5982 "/": "__Pyx_PyNumber_Divide",
5983 "//": "PyNumber_FloorDivide",
5984 "%": "PyNumber_Remainder",
5985 "**": "PyNumber_Power"
5988 class IntBinopNode(NumBinopNode):
5989 # Binary operation taking integer arguments.
5991 def c_types_okay(self, type1, type2):
5992 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5993 return (type1.is_int or type1.is_enum) \
5994 and (type2.is_int or type2.is_enum)
5997 class AddNode(NumBinopNode):
6000 def is_py_operation_types(self, type1, type2):
6001 if type1.is_string and type2.is_string:
6004 return NumBinopNode.is_py_operation_types(self, type1, type2)
6006 def compute_c_result_type(self, type1, type2):
6007 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
6008 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
6010 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
6013 return NumBinopNode.compute_c_result_type(
6017 class SubNode(NumBinopNode):
6020 def compute_c_result_type(self, type1, type2):
6021 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
6023 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
6024 return PyrexTypes.c_int_type
6026 return NumBinopNode.compute_c_result_type(
6030 class MulNode(NumBinopNode):
6033 def is_py_operation_types(self, type1, type2):
6034 if (type1.is_string and type2.is_int) \
6035 or (type2.is_string and type1.is_int):
6038 return NumBinopNode.is_py_operation_types(self, type1, type2)
6041 class DivNode(NumBinopNode):
6042 # '/' or '//' operator.
6045 truedivision = None # == "unknown" if operator == '/'
6046 ctruedivision = False
6047 cdivision_warnings = False
6048 zerodivision_check = None
6050 def find_compile_time_binary_operator(self, op1, op2):
6051 func = compile_time_binary_operators[self.operator]
6052 if self.operator == '/' and self.truedivision is None:
6053 # => true div for floats, floor div for integers
6054 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
6055 func = compile_time_binary_operators['//']
6058 def calculate_constant_result(self):
6059 op1 = self.operand1.constant_result
6060 op2 = self.operand2.constant_result
6061 func = self.find_compile_time_binary_operator(op1, op2)
6062 self.constant_result = func(
6063 self.operand1.constant_result,
6064 self.operand2.constant_result)
6066 def compile_time_value(self, denv):
6067 operand1 = self.operand1.compile_time_value(denv)
6068 operand2 = self.operand2.compile_time_value(denv)
6070 func = self.find_compile_time_binary_operator(
6072 return func(operand1, operand2)
6073 except Exception, e:
6074 self.compile_time_value_error(e)
6076 def analyse_operation(self, env):
6077 if self.cdivision or env.directives['cdivision']:
6078 self.ctruedivision = False
6080 self.ctruedivision = self.truedivision
6081 NumBinopNode.analyse_operation(self, env)
6082 if self.is_cpp_operation():
6083 self.cdivision = True
6084 if not self.type.is_pyobject:
6085 self.zerodivision_check = (
6086 self.cdivision is None and not env.directives['cdivision']
6087 and (not self.operand2.has_constant_result() or
6088 self.operand2.constant_result == 0))
6089 if self.zerodivision_check or env.directives['cdivision_warnings']:
6090 # Need to check ahead of time to warn or raise zero division error
6091 self.operand1 = self.operand1.coerce_to_simple(env)
6092 self.operand2 = self.operand2.coerce_to_simple(env)
6094 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
6096 def compute_c_result_type(self, type1, type2):
6097 if self.operator == '/' and self.ctruedivision:
6098 if not type1.is_float and not type2.is_float:
6099 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
6100 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
6102 return NumBinopNode.compute_c_result_type(self, type1, type2)
6104 def zero_division_message(self):
6105 if self.type.is_int:
6106 return "integer division or modulo by zero"
6108 return "float division"
6110 def generate_evaluation_code(self, code):
6111 if not self.type.is_pyobject and not self.type.is_complex:
6112 if self.cdivision is None:
6113 self.cdivision = (code.globalstate.directives['cdivision']
6114 or not self.type.signed
6115 or self.type.is_float)
6116 if not self.cdivision:
6117 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
6118 NumBinopNode.generate_evaluation_code(self, code)
6119 self.generate_div_warning_code(code)
6121 def generate_div_warning_code(self, code):
6122 if not self.type.is_pyobject:
6123 if self.zerodivision_check:
6125 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
6127 zero_test = "%s == 0" % self.operand2.result()
6128 code.putln("if (unlikely(%s)) {" % zero_test)
6129 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
6130 code.putln(code.error_goto(self.pos))
6132 if self.type.is_int and self.type.signed and self.operator != '%':
6133 code.globalstate.use_utility_code(division_overflow_test_code)
6134 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6135 self.type.declaration_code(''),
6136 self.operand2.result(),
6137 self.operand1.result()))
6138 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
6139 code.putln(code.error_goto(self.pos))
6141 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6142 code.globalstate.use_utility_code(cdivision_warning_utility_code)
6143 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
6144 self.operand1.result(),
6145 self.operand2.result()))
6146 code.putln(code.set_error_info(self.pos));
6147 code.put("if (__Pyx_cdivision_warning()) ")
6148 code.put_goto(code.error_label)
6151 def calculate_result_code(self):
6152 if self.type.is_complex:
6153 return NumBinopNode.calculate_result_code(self)
6154 elif self.type.is_float and self.operator == '//':
6155 return "floor(%s / %s)" % (
6156 self.operand1.result(),
6157 self.operand2.result())
6158 elif self.truedivision or self.cdivision:
6159 op1 = self.operand1.result()
6160 op2 = self.operand2.result()
6161 if self.truedivision:
6162 if self.type != self.operand1.type:
6163 op1 = self.type.cast_code(op1)
6164 if self.type != self.operand2.type:
6165 op2 = self.type.cast_code(op2)
6166 return "(%s / %s)" % (op1, op2)
6168 return "__Pyx_div_%s(%s, %s)" % (
6169 self.type.specialization_name(),
6170 self.operand1.result(),
6171 self.operand2.result())
6174 class ModNode(DivNode):
6177 def is_py_operation_types(self, type1, type2):
6178 return (type1.is_string
6180 or NumBinopNode.is_py_operation_types(self, type1, type2))
6182 def zero_division_message(self):
6183 if self.type.is_int:
6184 return "integer division or modulo by zero"
6186 return "float divmod()"
6188 def generate_evaluation_code(self, code):
6189 if not self.type.is_pyobject:
6190 if self.cdivision is None:
6191 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
6192 if not self.cdivision:
6193 if self.type.is_int:
6194 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6196 code.globalstate.use_utility_code(
6197 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6198 NumBinopNode.generate_evaluation_code(self, code)
6199 self.generate_div_warning_code(code)
6201 def calculate_result_code(self):
6203 if self.type.is_float:
6204 return "fmod%s(%s, %s)" % (
6205 self.type.math_h_modifier,
6206 self.operand1.result(),
6207 self.operand2.result())
6209 return "(%s %% %s)" % (
6210 self.operand1.result(),
6211 self.operand2.result())
6213 return "__Pyx_mod_%s(%s, %s)" % (
6214 self.type.specialization_name(),
6215 self.operand1.result(),
6216 self.operand2.result())
6218 class PowNode(NumBinopNode):
6221 def analyse_c_operation(self, env):
6222 NumBinopNode.analyse_c_operation(self, env)
6223 if self.type.is_complex:
6224 if self.type.real_type.is_float:
6225 self.operand1 = self.operand1.coerce_to(self.type, env)
6226 self.operand2 = self.operand2.coerce_to(self.type, env)
6227 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
6229 error(self.pos, "complex int powers not supported")
6230 self.pow_func = "<error>"
6231 elif self.type.is_float:
6232 self.pow_func = "pow" + self.type.math_h_modifier
6234 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
6235 env.use_utility_code(
6236 int_pow_utility_code.specialize(func_name=self.pow_func,
6237 type=self.type.declaration_code('')))
6239 def calculate_result_code(self):
6240 # Work around MSVC overloading ambiguity.
6241 def typecast(operand):
6242 if self.type == operand.type:
6243 return operand.result()
6245 return self.type.cast_code(operand.result())
6246 return "%s(%s, %s)" % (
6248 typecast(self.operand1),
6249 typecast(self.operand2))
6252 # Note: This class is temporarily "shut down" into an ineffective temp
6255 # More sophisticated temp reuse was going on before, one could have a
6256 # look at adding this again after /all/ classes are converted to the
6257 # new temp scheme. (The temp juggling cannot work otherwise).
6258 class BoolBinopNode(ExprNode):
6259 # Short-circuiting boolean operation.
6265 subexprs = ['operand1', 'operand2']
6267 def infer_type(self, env):
6268 type1 = self.operand1.infer_type(env)
6269 type2 = self.operand2.infer_type(env)
6270 return PyrexTypes.independent_spanning_type(type1, type2)
6272 def may_be_none(self):
6273 if self.operator == 'or':
6274 return self.operand2.may_be_none()
6276 return self.operand1.may_be_none() or self.operand2.may_be_none()
6278 def calculate_constant_result(self):
6279 if self.operator == 'and':
6280 self.constant_result = \
6281 self.operand1.constant_result and \
6282 self.operand2.constant_result
6284 self.constant_result = \
6285 self.operand1.constant_result or \
6286 self.operand2.constant_result
6288 def compile_time_value(self, denv):
6289 if self.operator == 'and':
6290 return self.operand1.compile_time_value(denv) \
6291 and self.operand2.compile_time_value(denv)
6293 return self.operand1.compile_time_value(denv) \
6294 or self.operand2.compile_time_value(denv)
6296 def coerce_to_boolean(self, env):
6297 return BoolBinopNode(
6299 operator = self.operator,
6300 operand1 = self.operand1.coerce_to_boolean(env),
6301 operand2 = self.operand2.coerce_to_boolean(env),
6302 type = PyrexTypes.c_bint_type,
6303 is_temp = self.is_temp)
6305 def analyse_types(self, env):
6306 self.operand1.analyse_types(env)
6307 self.operand2.analyse_types(env)
6308 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6309 self.operand1 = self.operand1.coerce_to(self.type, env)
6310 self.operand2 = self.operand2.coerce_to(self.type, env)
6312 # For what we're about to do, it's vital that
6313 # both operands be temp nodes.
6314 self.operand1 = self.operand1.coerce_to_simple(env)
6315 self.operand2 = self.operand2.coerce_to_simple(env)
6318 gil_message = "Truth-testing Python object"
6320 def check_const(self):
6321 return self.operand1.check_const() and self.operand2.check_const()
6323 def generate_evaluation_code(self, code):
6324 code.mark_pos(self.pos)
6325 self.operand1.generate_evaluation_code(code)
6326 test_result, uses_temp = self.generate_operand1_test(code)
6327 if self.operator == 'and':
6336 code.funcstate.release_temp(test_result)
6337 self.operand1.generate_disposal_code(code)
6338 self.operand2.generate_evaluation_code(code)
6339 self.allocate_temp_result(code)
6340 self.operand2.make_owned_reference(code)
6341 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6342 self.operand2.generate_post_assignment_code(code)
6343 self.operand2.free_temps(code)
6344 code.putln("} else {")
6345 self.operand1.make_owned_reference(code)
6346 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6347 self.operand1.generate_post_assignment_code(code)
6348 self.operand1.free_temps(code)
6351 def generate_operand1_test(self, code):
6352 # Generate code to test the truth of the first operand.
6353 if self.type.is_pyobject:
6354 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6357 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6359 self.operand1.py_result(),
6360 code.error_goto_if_neg(test_result, self.pos)))
6362 test_result = self.operand1.result()
6363 return (test_result, self.type.is_pyobject)
6366 class CondExprNode(ExprNode):
6367 # Short-circuiting conditional expression.
6371 # false_val ExprNode
6376 subexprs = ['test', 'true_val', 'false_val']
6378 def type_dependencies(self, env):
6379 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6381 def infer_type(self, env):
6382 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6383 self.false_val.infer_type(env))
6385 def calculate_constant_result(self):
6386 if self.test.constant_result:
6387 self.constant_result = self.true_val.constant_result
6389 self.constant_result = self.false_val.constant_result
6391 def analyse_types(self, env):
6392 self.test.analyse_types(env)
6393 self.test = self.test.coerce_to_boolean(env)
6394 self.true_val.analyse_types(env)
6395 self.false_val.analyse_types(env)
6396 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6397 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6398 self.true_val = self.true_val.coerce_to(self.type, env)
6399 self.false_val = self.false_val.coerce_to(self.type, env)
6401 if self.type == PyrexTypes.error_type:
6404 def type_error(self):
6405 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6406 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6407 (self.true_val.type, self.false_val.type))
6408 self.type = PyrexTypes.error_type
6410 def check_const(self):
6411 return (self.test.check_const()
6412 and self.true_val.check_const()
6413 and self.false_val.check_const())
6415 def generate_evaluation_code(self, code):
6416 # Because subexprs may not be evaluated we can use a more optimal
6417 # subexpr allocation strategy than the default, so override evaluation_code.
6419 code.mark_pos(self.pos)
6420 self.allocate_temp_result(code)
6421 self.test.generate_evaluation_code(code)
6422 code.putln("if (%s) {" % self.test.result() )
6423 self.eval_and_get(code, self.true_val)
6424 code.putln("} else {")
6425 self.eval_and_get(code, self.false_val)
6427 self.test.generate_disposal_code(code)
6428 self.test.free_temps(code)
6430 def eval_and_get(self, code, expr):
6431 expr.generate_evaluation_code(code)
6432 expr.make_owned_reference(code)
6433 code.putln("%s = %s;" % (self.result(), expr.result()))
6434 expr.generate_post_assignment_code(code)
6435 expr.free_temps(code)
6437 richcmp_constants = {
6447 class CmpNode(object):
6448 # Mixin class containing code common to PrimaryCmpNodes
6449 # and CascadedCmpNodes.
6451 special_bool_cmp_function = None
6453 def infer_type(self, env):
6454 # TODO: Actually implement this (after merging with -unstable).
6455 return py_object_type
6457 def calculate_cascaded_constant_result(self, operand1_result):
6458 func = compile_time_binary_operators[self.operator]
6459 operand2_result = self.operand2.constant_result
6460 result = func(operand1_result, operand2_result)
6462 self.cascade.calculate_cascaded_constant_result(operand2_result)
6463 if self.cascade.constant_result:
6464 self.constant_result = result and self.cascade.constant_result
6466 self.constant_result = result
6468 def cascaded_compile_time_value(self, operand1, denv):
6469 func = get_compile_time_binop(self)
6470 operand2 = self.operand2.compile_time_value(denv)
6472 result = func(operand1, operand2)
6473 except Exception, e:
6474 self.compile_time_value_error(e)
6477 cascade = self.cascade
6479 # FIXME: I bet this must call cascaded_compile_time_value()
6480 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6483 def is_cpp_comparison(self):
6484 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6486 def find_common_int_type(self, env, op, operand1, operand2):
6487 # type1 != type2 and at least one of the types is not a C int
6488 type1 = operand1.type
6489 type2 = operand2.type
6490 type1_can_be_int = False
6491 type2_can_be_int = False
6493 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6494 and operand1.can_coerce_to_char_literal():
6495 type1_can_be_int = True
6496 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6497 and operand2.can_coerce_to_char_literal():
6498 type2_can_be_int = True
6501 if type2_can_be_int:
6504 if type1_can_be_int:
6506 elif type1_can_be_int:
6507 if type2_can_be_int:
6508 return PyrexTypes.c_uchar_type
6512 def find_common_type(self, env, op, operand1, common_type=None):
6513 operand2 = self.operand2
6514 type1 = operand1.type
6515 type2 = operand2.type
6517 new_common_type = None
6519 # catch general errors
6520 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6521 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6522 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6523 new_common_type = error_type
6525 # try to use numeric comparisons where possible
6526 elif type1.is_complex or type2.is_complex:
6527 if op not in ('==', '!='):
6528 error(self.pos, "complex types are unordered")
6529 new_common_type = error_type
6530 if type1.is_pyobject:
6531 new_common_type = type1
6532 elif type2.is_pyobject:
6533 new_common_type = type2
6535 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6536 elif type1.is_numeric and type2.is_numeric:
6537 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6538 elif common_type is None or not common_type.is_pyobject:
6539 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6541 if new_common_type is None:
6542 # fall back to generic type compatibility tests
6544 new_common_type = type1
6545 elif type1.is_pyobject or type2.is_pyobject:
6546 if type2.is_numeric or type2.is_string:
6547 if operand2.check_for_coercion_error(type1):
6548 new_common_type = error_type
6550 new_common_type = py_object_type
6551 elif type1.is_numeric or type1.is_string:
6552 if operand1.check_for_coercion_error(type2):
6553 new_common_type = error_type
6555 new_common_type = py_object_type
6556 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6557 new_common_type = py_object_type
6559 # one Python type and one non-Python type, not assignable
6560 self.invalid_types_error(operand1, op, operand2)
6561 new_common_type = error_type
6562 elif type1.assignable_from(type2):
6563 new_common_type = type1
6564 elif type2.assignable_from(type1):
6565 new_common_type = type2
6567 # C types that we couldn't handle up to here are an error
6568 self.invalid_types_error(operand1, op, operand2)
6569 new_common_type = error_type
6571 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6572 isinstance(operand2, BytesNode)):
6573 # special case when comparing char* to bytes literal: must
6574 # compare string values!
6575 new_common_type = bytes_type
6577 # recursively merge types
6578 if common_type is None or new_common_type.is_error:
6579 common_type = new_common_type
6581 # we could do a lot better by splitting the comparison
6582 # into a non-Python part and a Python part, but this is
6584 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6587 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6591 def invalid_types_error(self, operand1, op, operand2):
6592 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6593 (op, operand1.type, operand2.type))
6595 def is_python_comparison(self):
6596 return (not self.is_ptr_contains()
6597 and not self.is_c_string_contains()
6598 and (self.has_python_operands()
6599 or (self.cascade and self.cascade.is_python_comparison())
6600 or self.operator in ('in', 'not_in')))
6602 def coerce_operands_to(self, dst_type, env):
6603 operand2 = self.operand2
6604 if operand2.type != dst_type:
6605 self.operand2 = operand2.coerce_to(dst_type, env)
6607 self.cascade.coerce_operands_to(dst_type, env)
6609 def is_python_result(self):
6610 return ((self.has_python_operands() and
6611 self.special_bool_cmp_function is None and
6612 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6613 not self.is_c_string_contains() and
6614 not self.is_ptr_contains())
6615 or (self.cascade and self.cascade.is_python_result()))
6617 def is_c_string_contains(self):
6618 return self.operator in ('in', 'not_in') and \
6619 ((self.operand1.type.is_int
6620 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6621 (self.operand1.type.is_unicode_char
6622 and self.operand2.type is unicode_type))
6624 def is_ptr_contains(self):
6625 if self.operator in ('in', 'not_in'):
6626 container_type = self.operand2.type
6627 return (container_type.is_ptr or container_type.is_array) \
6628 and not container_type.is_string
6630 def find_special_bool_compare_function(self, env):
6631 if self.operator in ('==', '!='):
6632 type1, type2 = self.operand1.type, self.operand2.type
6633 if type1.is_pyobject and type2.is_pyobject:
6634 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6635 env.use_utility_code(pyunicode_equals_utility_code)
6636 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6640 def generate_operation_code(self, code, result_code,
6641 operand1, op , operand2):
6642 if self.type.is_pyobject:
6643 coerce_result = "__Pyx_PyBool_FromLong"
6650 if self.special_bool_cmp_function:
6651 if operand1.type.is_pyobject:
6652 result1 = operand1.py_result()
6654 result1 = operand1.result()
6655 if operand2.type.is_pyobject:
6656 result2 = operand2.py_result()
6658 result2 = operand2.result()
6659 code.putln("%s = %s(%s, %s, %s); %s" % (
6661 self.special_bool_cmp_function,
6664 richcmp_constants[op],
6665 code.error_goto_if_neg(result_code, self.pos)))
6666 elif op == 'in' or op == 'not_in':
6667 code.globalstate.use_utility_code(contains_utility_code)
6668 if self.type.is_pyobject:
6669 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6671 negation = "__Pyx_NegateNonNeg"
6672 if operand2.type is dict_type:
6673 method = "PyDict_Contains"
6675 method = "PySequence_Contains"
6676 if self.type.is_pyobject:
6677 error_clause = code.error_goto_if_null
6678 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6680 error_clause = code.error_goto_if_neg
6683 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6688 operand2.py_result(),
6689 operand1.py_result(),
6691 error_clause(result_code, self.pos)))
6692 elif (operand1.type.is_pyobject
6693 and op not in ('is', 'is_not')):
6694 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6696 operand1.py_result(),
6697 operand2.py_result(),
6698 richcmp_constants[op],
6699 code.error_goto_if_null(result_code, self.pos)))
6700 code.put_gotref(result_code)
6701 elif operand1.type.is_complex:
6706 code.putln("%s = %s(%s%s(%s, %s));" % (
6710 operand1.type.unary_op('eq'),
6714 type1 = operand1.type
6715 type2 = operand2.type
6716 if (type1.is_extension_type or type2.is_extension_type) \
6717 and not type1.same_as(type2):
6718 common_type = py_object_type
6719 elif type1.is_numeric:
6720 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6723 code1 = operand1.result_as(common_type)
6724 code2 = operand2.result_as(common_type)
6725 code.putln("%s = %s(%s %s %s);" % (
6729 self.c_operator(op),
6732 def c_operator(self, op):
6735 elif op == 'is_not':
6740 contains_utility_code = UtilityCode(
6742 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6743 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6744 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6748 char_in_bytes_utility_code = UtilityCode(
6750 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6753 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6754 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6755 char* char_start = PyBytes_AS_STRING(bytes);
6757 for (pos=char_start; pos < char_start+length; pos++) {
6758 if (character == pos[0]) return 1;
6764 pyunicode_in_unicode_utility_code = UtilityCode(
6766 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6769 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6771 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6772 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6774 for (pos=char_start; pos < char_start+length; pos++) {
6775 if (unlikely(character == pos[0])) return 1;
6781 py_ucs4_in_unicode_utility_code = UtilityCode(
6783 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
6785 # additionally handles surrogate pairs in 16bit Unicode builds
6787 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
6790 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6791 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6793 #if Py_UNICODE_SIZE == 2
6794 if (unlikely(character > 65535)) {
6795 Py_UNICODE high_val, low_val;
6796 high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
6797 low_val = (Py_UNICODE) (0xDC00 | ( (character - 0x10000) & ((1<<10)-1)));
6798 for (pos=char_start; pos < char_start+length-1; pos++) {
6799 if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
6804 uchar = (Py_UNICODE) character;
6805 for (pos=char_start; pos < char_start+length; pos++) {
6806 if (unlikely(uchar == pos[0])) return 1;
6812 pyunicode_equals_utility_code = UtilityCode(
6814 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6817 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6818 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6819 return (equals == Py_EQ);
6820 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6821 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6822 return (equals == Py_NE);
6823 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6824 if (equals == Py_EQ)
6825 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6827 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6829 int result = PyUnicode_Compare(s1, s2);
6830 if ((result == -1) && unlikely(PyErr_Occurred()))
6832 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6834 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6835 return (equals == Py_EQ);
6836 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6837 return (equals == Py_NE);
6838 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6839 return (equals == Py_NE);
6842 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6845 result = __Pyx_PyObject_IsTrue(py_result);
6846 Py_DECREF(py_result);
6853 class PrimaryCmpNode(ExprNode, CmpNode):
6854 # Non-cascaded comparison or first comparison of
6855 # a cascaded sequence.
6860 # cascade CascadedCmpNode
6862 # We don't use the subexprs mechanism, because
6863 # things here are too complicated for it to handle.
6864 # Instead, we override all the framework methods
6867 child_attrs = ['operand1', 'operand2', 'cascade']
6871 def infer_type(self, env):
6872 # TODO: Actually implement this (after merging with -unstable).
6873 return py_object_type
6875 def type_dependencies(self, env):
6878 def calculate_constant_result(self):
6879 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6881 def compile_time_value(self, denv):
6882 operand1 = self.operand1.compile_time_value(denv)
6883 return self.cascaded_compile_time_value(operand1, denv)
6885 def analyse_types(self, env):
6886 self.operand1.analyse_types(env)
6887 self.operand2.analyse_types(env)
6888 if self.is_cpp_comparison():
6889 self.analyse_cpp_comparison(env)
6891 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6894 self.cascade.analyse_types(env)
6896 if self.operator in ('in', 'not_in'):
6897 if self.is_c_string_contains():
6898 self.is_pycmp = False
6901 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6903 if self.operand2.type is unicode_type:
6904 self.uchar_test_type = PyrexTypes.widest_numeric_type(
6905 self.operand1.type, PyrexTypes.c_py_unicode_type)
6906 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
6907 env.use_utility_code(pyunicode_in_unicode_utility_code)
6909 env.use_utility_code(py_ucs4_in_unicode_utility_code)
6911 if self.operand1.type is PyrexTypes.c_uchar_type:
6912 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6913 if self.operand2.type is not bytes_type:
6914 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6915 env.use_utility_code(char_in_bytes_utility_code)
6916 self.operand2 = self.operand2.as_none_safe_node(
6917 "argument of type 'NoneType' is not iterable")
6918 elif self.is_ptr_contains():
6920 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6921 self.type = PyrexTypes.c_bint_type
6922 # Will be transformed by IterationTransform
6925 if self.operand2.type is dict_type:
6926 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6927 common_type = py_object_type
6928 self.is_pycmp = True
6929 elif self.find_special_bool_compare_function(env):
6930 common_type = None # if coercion needed, the method call above has already done it
6931 self.is_pycmp = False # result is bint
6932 self.is_temp = True # must check for error return
6934 common_type = self.find_common_type(env, self.operator, self.operand1)
6935 self.is_pycmp = common_type.is_pyobject
6937 if common_type is not None and not common_type.is_error:
6938 if self.operand1.type != common_type:
6939 self.operand1 = self.operand1.coerce_to(common_type, env)
6940 self.coerce_operands_to(common_type, env)
6943 self.operand2 = self.operand2.coerce_to_simple(env)
6944 self.cascade.coerce_cascaded_operands_to_temp(env)
6945 if self.is_python_result():
6946 self.type = PyrexTypes.py_object_type
6948 self.type = PyrexTypes.c_bint_type
6951 cdr.type = self.type
6953 if self.is_pycmp or self.cascade:
6956 def analyse_cpp_comparison(self, env):
6957 type1 = self.operand1.type
6958 type2 = self.operand2.type
6959 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6961 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6962 (self.operator, type1, type2))
6963 self.type = PyrexTypes.error_type
6964 self.result_code = "<error>"
6966 func_type = entry.type
6967 if func_type.is_ptr:
6968 func_type = func_type.base_type
6969 if len(func_type.args) == 1:
6970 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6972 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6973 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6974 self.type = func_type.return_type
6976 def has_python_operands(self):
6977 return (self.operand1.type.is_pyobject
6978 or self.operand2.type.is_pyobject)
6980 def check_const(self):
6985 return self.operand1.check_const() and self.operand2.check_const()
6987 def calculate_result_code(self):
6988 if self.operand1.type.is_complex:
6989 if self.operator == "!=":
6993 return "(%s%s(%s, %s))" % (
6995 self.operand1.type.binary_op('=='),
6996 self.operand1.result(),
6997 self.operand2.result())
6998 elif self.is_c_string_contains():
6999 if self.operand2.type is unicode_type:
7000 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
7001 method = "__Pyx_UnicodeContains"
7003 method = "__Pyx_UnicodeContainsUCS4"
7005 method = "__Pyx_BytesContains"
7006 if self.operator == "not_in":
7010 return "(%s%s(%s, %s))" % (
7013 self.operand2.result(),
7014 self.operand1.result())
7016 return "(%s %s %s)" % (
7017 self.operand1.result(),
7018 self.c_operator(self.operator),
7019 self.operand2.result())
7021 def generate_evaluation_code(self, code):
7022 self.operand1.generate_evaluation_code(code)
7023 self.operand2.generate_evaluation_code(code)
7025 self.allocate_temp_result(code)
7026 self.generate_operation_code(code, self.result(),
7027 self.operand1, self.operator, self.operand2)
7029 self.cascade.generate_evaluation_code(code,
7030 self.result(), self.operand2)
7031 self.operand1.generate_disposal_code(code)
7032 self.operand1.free_temps(code)
7033 self.operand2.generate_disposal_code(code)
7034 self.operand2.free_temps(code)
7036 def generate_subexpr_disposal_code(self, code):
7037 # If this is called, it is a non-cascaded cmp,
7038 # so only need to dispose of the two main operands.
7039 self.operand1.generate_disposal_code(code)
7040 self.operand2.generate_disposal_code(code)
7042 def free_subexpr_temps(self, code):
7043 # If this is called, it is a non-cascaded cmp,
7044 # so only need to dispose of the two main operands.
7045 self.operand1.free_temps(code)
7046 self.operand2.free_temps(code)
7048 def annotate(self, code):
7049 self.operand1.annotate(code)
7050 self.operand2.annotate(code)
7052 self.cascade.annotate(code)
7055 class CascadedCmpNode(Node, CmpNode):
7056 # A CascadedCmpNode is not a complete expression node. It
7057 # hangs off the side of another comparison node, shares
7058 # its left operand with that node, and shares its result
7059 # with the PrimaryCmpNode at the head of the chain.
7063 # cascade CascadedCmpNode
7065 child_attrs = ['operand2', 'cascade']
7068 constant_result = constant_value_not_set # FIXME: where to calculate this?
7070 def infer_type(self, env):
7071 # TODO: Actually implement this (after merging with -unstable).
7072 return py_object_type
7074 def type_dependencies(self, env):
7077 def has_constant_result(self):
7078 return self.constant_result is not constant_value_not_set and \
7079 self.constant_result is not not_a_constant
7081 def analyse_types(self, env):
7082 self.operand2.analyse_types(env)
7084 self.cascade.analyse_types(env)
7086 def has_python_operands(self):
7087 return self.operand2.type.is_pyobject
7089 def coerce_operands_to_pyobjects(self, env):
7090 self.operand2 = self.operand2.coerce_to_pyobject(env)
7091 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
7092 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
7094 self.cascade.coerce_operands_to_pyobjects(env)
7096 def coerce_cascaded_operands_to_temp(self, env):
7098 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
7099 self.operand2 = self.operand2.coerce_to_simple(env)
7100 self.cascade.coerce_cascaded_operands_to_temp(env)
7102 def generate_evaluation_code(self, code, result, operand1):
7103 if self.type.is_pyobject:
7104 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
7105 code.put_decref(result, self.type)
7107 code.putln("if (%s) {" % result)
7108 self.operand2.generate_evaluation_code(code)
7109 self.generate_operation_code(code, result,
7110 operand1, self.operator, self.operand2)
7112 self.cascade.generate_evaluation_code(
7113 code, result, self.operand2)
7114 # Cascaded cmp result is always temp
7115 self.operand2.generate_disposal_code(code)
7116 self.operand2.free_temps(code)
7119 def annotate(self, code):
7120 self.operand2.annotate(code)
7122 self.cascade.annotate(code)
7125 binop_node_classes = {
7126 "or": BoolBinopNode,
7127 "and": BoolBinopNode,
7142 def binop_node(pos, operator, operand1, operand2, inplace=False):
7143 # Construct binop node of appropriate class for
7145 return binop_node_classes[operator](pos,
7146 operator = operator,
7147 operand1 = operand1,
7148 operand2 = operand2,
7151 #-------------------------------------------------------------------
7155 # Coercion nodes are special in that they are created during
7156 # the analyse_types phase of parse tree processing.
7157 # Their __init__ methods consequently incorporate some aspects
7160 #-------------------------------------------------------------------
7162 class CoercionNode(ExprNode):
7163 # Abstract base class for coercion nodes.
7165 # arg ExprNode node being coerced
7168 constant_result = not_a_constant
7170 def __init__(self, arg):
7174 print("%s Coercing %s" % (self, self.arg))
7176 def calculate_constant_result(self):
7177 # constant folding can break type coercion, so this is disabled
7180 def annotate(self, code):
7181 self.arg.annotate(code)
7182 if self.arg.type != self.type:
7183 file, line, col = self.pos
7184 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
7187 class CastNode(CoercionNode):
7188 # Wrap a node in a C type cast.
7190 def __init__(self, arg, new_type):
7191 CoercionNode.__init__(self, arg)
7192 self.type = new_type
7194 def may_be_none(self):
7195 return self.arg.may_be_none()
7197 def calculate_result_code(self):
7198 return self.arg.result_as(self.type)
7200 def generate_result_code(self, code):
7201 self.arg.generate_result_code(code)
7204 class PyTypeTestNode(CoercionNode):
7205 # This node is used to check that a generic Python
7206 # object is an instance of a particular extension type.
7207 # This node borrows the result of its argument node.
7209 def __init__(self, arg, dst_type, env, notnone=False):
7210 # The arg is know to be a Python object, and
7211 # the dst_type is known to be an extension type.
7212 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
7213 CoercionNode.__init__(self, arg)
7214 self.type = dst_type
7215 self.result_ctype = arg.ctype()
7216 self.notnone = notnone
7218 nogil_check = Node.gil_error
7219 gil_message = "Python type test"
7221 def analyse_types(self, env):
7224 def may_be_none(self):
7227 return self.arg.may_be_none()
7229 def is_simple(self):
7230 return self.arg.is_simple()
7232 def result_in_temp(self):
7233 return self.arg.result_in_temp()
7235 def is_ephemeral(self):
7236 return self.arg.is_ephemeral()
7238 def calculate_constant_result(self):
7242 def calculate_result_code(self):
7243 return self.arg.result()
7245 def generate_result_code(self, code):
7246 if self.type.typeobj_is_available():
7247 if not self.type.is_builtin_type:
7248 code.globalstate.use_utility_code(type_test_utility_code)
7251 self.type.type_test_code(self.arg.py_result(), self.notnone),
7252 code.error_goto(self.pos)))
7254 error(self.pos, "Cannot test type of extern C class "
7255 "without type object name specification")
7257 def generate_post_assignment_code(self, code):
7258 self.arg.generate_post_assignment_code(code)
7260 def free_temps(self, code):
7261 self.arg.free_temps(code)
7264 class NoneCheckNode(CoercionNode):
7265 # This node is used to check that a Python object is not None and
7266 # raises an appropriate exception (as specified by the creating
7269 def __init__(self, arg, exception_type_cname, exception_message):
7270 CoercionNode.__init__(self, arg)
7271 self.type = arg.type
7272 self.result_ctype = arg.ctype()
7273 self.exception_type_cname = exception_type_cname
7274 self.exception_message = exception_message
7276 def analyse_types(self, env):
7279 def may_be_none(self):
7282 def is_simple(self):
7283 return self.arg.is_simple()
7285 def result_in_temp(self):
7286 return self.arg.result_in_temp()
7288 def calculate_result_code(self):
7289 return self.arg.result()
7291 def generate_result_code(self, code):
7293 "if (unlikely(%s == Py_None)) {" % self.arg.result())
7294 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
7295 self.exception_type_cname,
7296 StringEncoding.escape_byte_string(
7297 self.exception_message.encode('UTF-8')),
7298 code.error_goto(self.pos)))
7301 def generate_post_assignment_code(self, code):
7302 self.arg.generate_post_assignment_code(code)
7304 def free_temps(self, code):
7305 self.arg.free_temps(code)
7308 class CoerceToPyTypeNode(CoercionNode):
7309 # This node is used to convert a C data type
7310 # to a Python object.
7312 type = py_object_type
7315 def __init__(self, arg, env, type=py_object_type):
7316 CoercionNode.__init__(self, arg)
7317 if not arg.type.create_to_py_utility_code(env):
7319 "Cannot convert '%s' to Python object" % arg.type)
7320 if type is py_object_type:
7321 # be specific about some known types
7322 if arg.type.is_string:
7323 self.type = bytes_type
7324 elif arg.type.is_unicode_char:
7325 self.type = unicode_type
7326 elif arg.type.is_complex:
7327 self.type = Builtin.complex_type
7329 # FIXME: check that the target type and the resulting type are compatible
7332 gil_message = "Converting to Python object"
7334 def may_be_none(self):
7335 # FIXME: is this always safe?
7338 def coerce_to_boolean(self, env):
7339 arg_type = self.arg.type
7340 if (arg_type == PyrexTypes.c_bint_type or
7341 (arg_type.is_pyobject and arg_type.name == 'bool')):
7342 return self.arg.coerce_to_temp(env)
7344 return CoerceToBooleanNode(self, env)
7346 def coerce_to_integer(self, env):
7347 # If not already some C integer type, coerce to longint.
7348 if self.arg.type.is_int:
7351 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7353 def analyse_types(self, env):
7354 # The arg is always already analysed
7357 def generate_result_code(self, code):
7358 function = self.arg.type.to_py_function
7359 code.putln('%s = %s(%s); %s' % (
7363 code.error_goto_if_null(self.result(), self.pos)))
7364 code.put_gotref(self.py_result())
7367 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7368 # This node is used to convert a C int type to a Python bytes
7373 def __init__(self, arg, env):
7374 arg = arg.coerce_to_simple(env)
7375 CoercionNode.__init__(self, arg)
7376 self.type = Builtin.bytes_type
7378 def generate_result_code(self, code):
7380 arg_result = arg.result()
7381 if arg.type not in (PyrexTypes.c_char_type,
7382 PyrexTypes.c_uchar_type,
7383 PyrexTypes.c_schar_type):
7385 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7386 arg_result, arg_result))
7388 code.putln("if (%s > 255) {" % arg_result)
7389 code.putln('PyErr_Format(PyExc_OverflowError, '
7390 '"value too large to pack into a byte"); %s' % (
7391 code.error_goto(self.pos)))
7394 if arg.type is not PyrexTypes.c_char_type:
7395 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7396 code.putln("%s = (char)%s;" % (temp, arg_result))
7398 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7401 code.error_goto_if_null(self.result(), self.pos)))
7402 if temp is not None:
7403 code.funcstate.release_temp(temp)
7404 code.put_gotref(self.py_result())
7407 class CoerceFromPyTypeNode(CoercionNode):
7408 # This node is used to convert a Python object
7411 def __init__(self, result_type, arg, env):
7412 CoercionNode.__init__(self, arg)
7413 self.type = result_type
7415 if not result_type.create_from_py_utility_code(env):
7417 "Cannot convert Python object to '%s'" % result_type)
7418 if self.type.is_string and self.arg.is_ephemeral():
7420 "Obtaining char * from temporary Python value")
7422 def analyse_types(self, env):
7423 # The arg is always already analysed
7426 def generate_result_code(self, code):
7427 function = self.type.from_py_function
7428 operand = self.arg.py_result()
7429 rhs = "%s(%s)" % (function, operand)
7430 if self.type.is_enum:
7431 rhs = typecast(self.type, c_long_type, rhs)
7432 code.putln('%s = %s; %s' % (
7435 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7436 if self.type.is_pyobject:
7437 code.put_gotref(self.py_result())
7440 class CoerceToBooleanNode(CoercionNode):
7441 # This node is used when a result needs to be used
7442 # in a boolean context.
7444 type = PyrexTypes.c_bint_type
7446 _special_builtins = {
7447 Builtin.list_type : 'PyList_GET_SIZE',
7448 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7449 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7450 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7453 def __init__(self, arg, env):
7454 CoercionNode.__init__(self, arg)
7455 if arg.type.is_pyobject:
7458 def nogil_check(self, env):
7459 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7462 gil_message = "Truth-testing Python object"
7464 def check_const(self):
7468 return self.arg.check_const()
7470 def calculate_result_code(self):
7471 return "(%s != 0)" % self.arg.result()
7473 def generate_result_code(self, code):
7474 if not self.is_temp:
7476 test_func = self._special_builtins.get(self.arg.type)
7477 if test_func is not None:
7478 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7480 self.arg.py_result(),
7482 self.arg.py_result()))
7485 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7487 self.arg.py_result(),
7488 code.error_goto_if_neg(self.result(), self.pos)))
7490 class CoerceToComplexNode(CoercionNode):
7492 def __init__(self, arg, dst_type, env):
7493 if arg.type.is_complex:
7494 arg = arg.coerce_to_simple(env)
7495 self.type = dst_type
7496 CoercionNode.__init__(self, arg)
7497 dst_type.create_declaration_utility_code(env)
7499 def calculate_result_code(self):
7500 if self.arg.type.is_complex:
7501 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7502 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7504 real_part = self.arg.result()
7506 return "%s(%s, %s)" % (
7507 self.type.from_parts,
7511 def generate_result_code(self, code):
7514 class CoerceToTempNode(CoercionNode):
7515 # This node is used to force the result of another node
7516 # to be stored in a temporary. It is only used if the
7517 # argument node's result is not already in a temporary.
7519 def __init__(self, arg, env):
7520 CoercionNode.__init__(self, arg)
7521 self.type = self.arg.type
7522 self.constant_result = self.arg.constant_result
7524 if self.type.is_pyobject:
7525 self.result_ctype = py_object_type
7527 gil_message = "Creating temporary Python reference"
7529 def analyse_types(self, env):
7530 # The arg is always already analysed
7533 def coerce_to_boolean(self, env):
7534 self.arg = self.arg.coerce_to_boolean(env)
7535 if self.arg.is_simple():
7537 self.type = self.arg.type
7538 self.result_ctype = self.type
7541 def generate_result_code(self, code):
7542 #self.arg.generate_evaluation_code(code) # Already done
7543 # by generic generate_subexpr_evaluation_code!
7544 code.putln("%s = %s;" % (
7545 self.result(), self.arg.result_as(self.ctype())))
7546 if self.type.is_pyobject and self.use_managed_ref:
7547 code.put_incref(self.result(), self.ctype())
7550 class CloneNode(CoercionNode):
7551 # This node is employed when the result of another node needs
7552 # to be used multiple times. The argument node's result must
7553 # be in a temporary. This node "borrows" the result from the
7554 # argument node, and does not generate any evaluation or
7555 # disposal code for it. The original owner of the argument
7556 # node is responsible for doing those things.
7558 subexprs = [] # Arg is not considered a subexpr
7561 def __init__(self, arg):
7562 CoercionNode.__init__(self, arg)
7563 if hasattr(arg, 'type'):
7564 self.type = arg.type
7565 self.result_ctype = arg.result_ctype
7566 if hasattr(arg, 'entry'):
7567 self.entry = arg.entry
7570 return self.arg.result()
7572 def type_dependencies(self, env):
7573 return self.arg.type_dependencies(env)
7575 def infer_type(self, env):
7576 return self.arg.infer_type(env)
7578 def analyse_types(self, env):
7579 self.type = self.arg.type
7580 self.result_ctype = self.arg.result_ctype
7582 if hasattr(self.arg, 'entry'):
7583 self.entry = self.arg.entry
7585 def is_simple(self):
7586 return True # result is always in a temp (or a name)
7588 def generate_evaluation_code(self, code):
7591 def generate_result_code(self, code):
7594 def generate_disposal_code(self, code):
7597 def free_temps(self, code):
7601 class ModuleRefNode(ExprNode):
7602 # Simple returns the module object
7604 type = py_object_type
7608 def analyse_types(self, env):
7611 def may_be_none(self):
7614 def calculate_result_code(self):
7615 return Naming.module_cname
7617 def generate_result_code(self, code):
7620 class DocstringRefNode(ExprNode):
7621 # Extracts the docstring of the body element
7624 type = py_object_type
7627 def __init__(self, pos, body):
7628 ExprNode.__init__(self, pos)
7629 assert body.type.is_pyobject
7632 def analyse_types(self, env):
7635 def generate_result_code(self, code):
7636 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7637 self.result(), self.body.result(),
7638 code.error_goto_if_null(self.result(), self.pos)))
7639 code.put_gotref(self.result())
7643 #------------------------------------------------------------------------------------
7645 # Runtime support code
7647 #------------------------------------------------------------------------------------
7649 get_name_interned_utility_code = UtilityCode(
7651 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7654 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7656 result = PyObject_GetAttr(dict, name);
7658 PyErr_SetObject(PyExc_NameError, name);
7663 #------------------------------------------------------------------------------------
7665 import_utility_code = UtilityCode(
7667 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level); /*proto*/
7670 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level) {
7671 PyObject *py_import = 0;
7672 PyObject *empty_list = 0;
7673 PyObject *module = 0;
7674 PyObject *global_dict = 0;
7675 PyObject *empty_dict = 0;
7677 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7683 empty_list = PyList_New(0);
7688 global_dict = PyModule_GetDict(%(GLOBALS)s);
7691 empty_dict = PyDict_New();
7694 #if PY_VERSION_HEX >= 0x02050000
7696 PyObject *py_level = PyInt_FromLong(level);
7699 module = PyObject_CallFunctionObjArgs(py_import,
7700 name, global_dict, empty_dict, list, py_level, NULL);
7701 Py_DECREF(py_level);
7705 PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
7708 module = PyObject_CallFunctionObjArgs(py_import,
7709 name, global_dict, empty_dict, list, NULL);
7712 Py_XDECREF(empty_list);
7713 Py_XDECREF(py_import);
7714 Py_XDECREF(empty_dict);
7718 "BUILTINS": Naming.builtins_cname,
7719 "GLOBALS": Naming.module_cname,
7722 #------------------------------------------------------------------------------------
7724 get_exception_utility_code = UtilityCode(
7726 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7729 static PyObject *__Pyx_GetExcValue(void) {
7730 PyObject *type = 0, *value = 0, *tb = 0;
7731 PyObject *tmp_type, *tmp_value, *tmp_tb;
7732 PyObject *result = 0;
7733 PyThreadState *tstate = PyThreadState_Get();
7734 PyErr_Fetch(&type, &value, &tb);
7735 PyErr_NormalizeException(&type, &value, &tb);
7736 if (PyErr_Occurred())
7742 tmp_type = tstate->exc_type;
7743 tmp_value = tstate->exc_value;
7744 tmp_tb = tstate->exc_traceback;
7745 tstate->exc_type = type;
7746 tstate->exc_value = value;
7747 tstate->exc_traceback = tb;
7748 /* Make sure tstate is in a consistent state when we XDECREF
7749 these objects (XDECREF may run arbitrary code). */
7750 Py_XDECREF(tmp_type);
7751 Py_XDECREF(tmp_value);
7766 #------------------------------------------------------------------------------------
7768 type_test_utility_code = UtilityCode(
7770 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7773 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7774 if (unlikely(!type)) {
7775 PyErr_Format(PyExc_SystemError, "Missing type object");
7778 if (likely(PyObject_TypeCheck(obj, type)))
7780 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7781 Py_TYPE(obj)->tp_name, type->tp_name);
7786 #------------------------------------------------------------------------------------
7788 find_py2_metaclass_utility_code = UtilityCode(
7790 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7793 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7794 PyObject *metaclass;
7795 /* Default metaclass */
7796 #if PY_MAJOR_VERSION < 3
7797 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7798 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7799 metaclass = PyObject_GetAttrString(base, (char *)"__class__");
7802 metaclass = (PyObject*) Py_TYPE(base);
7805 metaclass = (PyObject *) &PyClass_Type;
7808 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7809 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7810 metaclass = (PyObject*) Py_TYPE(base);
7812 metaclass = (PyObject *) &PyType_Type;
7815 Py_INCREF(metaclass);
7820 create_class_utility_code = UtilityCode(
7822 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7823 PyObject *modname); /*proto*/
7826 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7827 PyObject *modname) {
7829 PyObject *metaclass;
7831 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7834 /* Python2 __metaclass__ */
7835 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7837 Py_INCREF(metaclass);
7839 metaclass = __Pyx_FindPy2Metaclass(bases);
7841 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7842 Py_DECREF(metaclass);
7846 requires = [find_py2_metaclass_utility_code])
7848 #------------------------------------------------------------------------------------
7850 create_py3class_utility_code = UtilityCode(
7852 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7853 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7854 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7857 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7858 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7860 Py_INCREF(metaclass);
7861 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7862 Py_DECREF(metaclass);
7867 return __Pyx_FindPy2Metaclass(bases);
7870 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7871 PyObject *modname, PyObject *doc) {
7877 prep = PyObject_GetAttrString(metaclass, (char *)"__prepare__");
7879 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7882 return PyDict_New();
7884 pargs = PyTuple_New(2);
7892 PyTuple_SET_ITEM(pargs, 0, name);
7893 PyTuple_SET_ITEM(pargs, 1, bases);
7895 ns = PyObject_Call(prep, pargs, mkw);
7903 /* Required here to emulate assignment order */
7904 /* XXX: use consts here */
7905 #if PY_MAJOR_VERSION >= 3
7906 str = PyUnicode_FromString("__module__");
7908 str = PyString_FromString("__module__");
7915 if (PyObject_SetItem(ns, str, modname) < 0) {
7922 #if PY_MAJOR_VERSION >= 3
7923 str = PyUnicode_FromString("__doc__");
7925 str = PyString_FromString("__doc__");
7931 if (PyObject_SetItem(ns, str, doc) < 0) {
7941 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7943 PyObject *margs = PyTuple_New(3);
7949 PyTuple_SET_ITEM(margs, 0, name);
7950 PyTuple_SET_ITEM(margs, 1, bases);
7951 PyTuple_SET_ITEM(margs, 2, dict);
7952 result = PyObject_Call(metaclass, margs, mkw);
7957 requires = [find_py2_metaclass_utility_code])
7959 #------------------------------------------------------------------------------------
7961 cpp_exception_utility_code = UtilityCode(
7963 #ifndef __Pyx_CppExn2PyErr
7964 static void __Pyx_CppExn2PyErr() {
7966 if (PyErr_Occurred())
7967 ; // let the latest Python exn pass through and ignore the current one
7970 } catch (const std::invalid_argument& exn) {
7971 // Catch a handful of different errors here and turn them into the
7972 // equivalent Python errors.
7973 // Change invalid_argument to ValueError
7974 PyErr_SetString(PyExc_ValueError, exn.what());
7975 } catch (const std::out_of_range& exn) {
7976 // Change out_of_range to IndexError
7977 PyErr_SetString(PyExc_IndexError, exn.what());
7978 } catch (const std::exception& exn) {
7979 PyErr_SetString(PyExc_RuntimeError, exn.what());
7983 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7991 pyerr_occurred_withgil_utility_code= UtilityCode(
7993 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7996 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7999 PyGILState_STATE _save = PyGILState_Ensure();
8001 err = !!PyErr_Occurred();
8003 PyGILState_Release(_save);
8010 #------------------------------------------------------------------------------------
8012 raise_noneattr_error_utility_code = UtilityCode(
8014 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
8017 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
8018 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
8022 raise_noneindex_error_utility_code = UtilityCode(
8024 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
8027 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
8028 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
8032 raise_none_iter_error_utility_code = UtilityCode(
8034 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
8037 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
8038 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
8042 #------------------------------------------------------------------------------------
8044 getitem_dict_utility_code = UtilityCode(
8046 #if PY_MAJOR_VERSION >= 3
8047 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
8049 if (unlikely(d == Py_None)) {
8050 __Pyx_RaiseNoneIndexingError();
8053 value = PyDict_GetItemWithError(d, key);
8054 if (unlikely(!value)) {
8055 if (!PyErr_Occurred())
8056 PyErr_SetObject(PyExc_KeyError, key);
8063 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
8066 requires = [raise_noneindex_error_utility_code])
8068 #------------------------------------------------------------------------------------
8070 getitem_int_pyunicode_utility_code = UtilityCode(
8072 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8073 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
8074 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
8076 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
8077 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
8078 return PyUnicode_AS_UNICODE(ustring)[i];
8079 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
8080 i += PyUnicode_GET_SIZE(ustring);
8081 return PyUnicode_AS_UNICODE(ustring)[i];
8083 PyErr_SetString(PyExc_IndexError, "string index out of range");
8084 return (Py_UNICODE)-1;
8088 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
8090 PyObject *uchar_string;
8091 if (!j) return (Py_UNICODE)-1;
8092 uchar_string = PyObject_GetItem(ustring, j);
8094 if (!uchar_string) return (Py_UNICODE)-1;
8095 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
8096 Py_DECREF(uchar_string);
8101 getitem_int_utility_code = UtilityCode(
8104 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
8106 if (!j) return NULL;
8107 r = PyObject_GetItem(o, j);
8114 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8115 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
8116 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8118 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
8119 if (likely(o != Py_None)) {
8120 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
8121 PyObject *r = Py%(type)s_GET_ITEM(o, i);
8125 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
8126 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
8131 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8133 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
8136 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8137 __Pyx_GetItemInt_Fast(o, i) : \\
8138 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8140 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
8142 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8143 r = PyList_GET_ITEM(o, i);
8146 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
8147 r = PyTuple_GET_ITEM(o, i);
8150 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
8151 r = PySequence_GetItem(o, i);
8154 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8164 #------------------------------------------------------------------------------------
8166 setitem_int_utility_code = UtilityCode(
8168 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8169 __Pyx_SetItemInt_Fast(o, i, v) : \\
8170 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
8172 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
8175 r = PyObject_SetItem(o, j, v);
8180 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
8181 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8183 Py_DECREF(PyList_GET_ITEM(o, i));
8184 PyList_SET_ITEM(o, i, v);
8187 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
8188 return PySequence_SetItem(o, i, v);
8190 PyObject *j = PyInt_FromSsize_t(i);
8191 return __Pyx_SetItemInt_Generic(o, j, v);
8198 #------------------------------------------------------------------------------------
8200 delitem_int_utility_code = UtilityCode(
8202 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8203 __Pyx_DelItemInt_Fast(o, i) : \\
8204 __Pyx_DelItem_Generic(o, to_py_func(i)))
8206 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8209 r = PyObject_DelItem(o, j);
8214 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8215 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
8216 return PySequence_DelItem(o, i);
8218 PyObject *j = PyInt_FromSsize_t(i);
8219 return __Pyx_DelItem_Generic(o, j);
8226 #------------------------------------------------------------------------------------
8228 raise_too_many_values_to_unpack = UtilityCode(
8230 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8233 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
8234 PyErr_Format(PyExc_ValueError,
8235 #if PY_VERSION_HEX < 0x02050000
8236 "too many values to unpack (expected %d)", (int)expected);
8238 "too many values to unpack (expected %zd)", expected);
8243 raise_need_more_values_to_unpack = UtilityCode(
8245 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8248 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8249 PyErr_Format(PyExc_ValueError,
8250 #if PY_VERSION_HEX < 0x02050000
8251 "need more than %d value%s to unpack", (int)index,
8253 "need more than %zd value%s to unpack", index,
8255 (index == 1) ? "" : "s");
8259 #------------------------------------------------------------------------------------
8261 tuple_unpacking_error_code = UtilityCode(
8263 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8266 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
8268 __Pyx_RaiseNoneNotIterableError();
8269 } else if (PyTuple_GET_SIZE(t) < index) {
8270 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
8272 __Pyx_RaiseTooManyValuesError(index);
8276 requires = [raise_none_iter_error_utility_code,
8277 raise_need_more_values_to_unpack,
8278 raise_too_many_values_to_unpack]
8281 unpacking_utility_code = UtilityCode(
8283 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8284 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8287 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
8289 if (!(item = PyIter_Next(iter))) {
8290 if (!PyErr_Occurred()) {
8291 __Pyx_RaiseNeedMoreValuesError(index);
8297 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8299 if ((item = PyIter_Next(iter))) {
8301 __Pyx_RaiseTooManyValuesError(expected);
8304 else if (!PyErr_Occurred())
8310 requires = [raise_need_more_values_to_unpack,
8311 raise_too_many_values_to_unpack]
8314 #------------------------------------------------------------------------------------
8316 # CPython supports calling functions with non-dict kwargs by
8317 # converting them to a dict first
8319 kwargs_call_utility_code = UtilityCode(
8321 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
8324 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
8326 if (likely(PyDict_Check(kwargs))) {
8327 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
8329 PyObject* real_dict;
8330 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
8331 if (unlikely(!real_dict))
8333 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
8334 Py_DECREF(real_dict);
8335 return result; /* may be NULL */
8342 #------------------------------------------------------------------------------------
8344 int_pow_utility_code = UtilityCode(
8346 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8349 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8361 if (unlikely(e<0)) return 0;
8364 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8372 # ------------------------------ Division ------------------------------------
8374 div_int_utility_code = UtilityCode(
8376 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8379 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8381 %(type)s r = a - q*b;
8382 q -= ((r != 0) & ((r ^ b) < 0));
8387 mod_int_utility_code = UtilityCode(
8389 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8392 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8393 %(type)s r = a %% b;
8394 r += ((r != 0) & ((r ^ b) < 0)) * b;
8399 mod_float_utility_code = UtilityCode(
8401 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8404 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8405 %(type)s r = fmod%(math_h_modifier)s(a, b);
8406 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8411 cdivision_warning_utility_code = UtilityCode(
8413 static int __Pyx_cdivision_warning(void); /* proto */
8416 static int __Pyx_cdivision_warning(void) {
8417 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8418 "division with oppositely signed operands, C and Python semantics differ",
8425 'FILENAME': Naming.filename_cname,
8426 'LINENO': Naming.lineno_cname,
8430 division_overflow_test_code = UtilityCode(
8432 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8433 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8437 binding_cfunc_utility_code = UtilityCode(
8439 #define %(binding_cfunc)s_USED 1
8442 PyCFunctionObject func;
8443 } %(binding_cfunc)s_object;
8445 static PyTypeObject %(binding_cfunc)s_type;
8446 static PyTypeObject *%(binding_cfunc)s = NULL;
8448 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8449 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8451 static int %(binding_cfunc)s_init(void); /* proto */
8452 """ % Naming.__dict__,
8455 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8456 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8461 op->func.m_self = self;
8463 op->func.m_module = module;
8464 PyObject_GC_Track(op);
8465 return (PyObject *)op;
8468 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8469 PyObject_GC_UnTrack(m);
8470 Py_XDECREF(m->func.m_self);
8471 Py_XDECREF(m->func.m_module);
8475 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8478 return PyMethod_New(func, obj, type);
8481 static int %(binding_cfunc)s_init(void) {
8482 %(binding_cfunc)s_type = PyCFunction_Type;
8483 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8484 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8485 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8486 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8489 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8493 """ % Naming.__dict__)
8495 generator_utility_code = UtilityCode(
8497 static PyObject *__Pyx_Generator_Next(PyObject *self);
8498 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
8499 static PyObject *__Pyx_Generator_Close(PyObject *self);
8500 static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args, CYTHON_UNUSED PyObject *kwds);
8502 typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
8505 static CYTHON_INLINE void __Pyx_Generator_ExceptionClear(struct __pyx_Generator_object *self)
8507 Py_XDECREF(self->exc_type);
8508 Py_XDECREF(self->exc_value);
8509 Py_XDECREF(self->exc_traceback);
8511 self->exc_type = NULL;
8512 self->exc_value = NULL;
8513 self->exc_traceback = NULL;
8516 static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_object *self, PyObject *value)
8520 if (self->is_running) {
8521 PyErr_SetString(PyExc_ValueError,
8522 "generator already executing");
8526 if (self->resume_label == 0) {
8527 if (value && value != Py_None) {
8528 PyErr_SetString(PyExc_TypeError,
8529 "can't send non-None value to a "
8530 "just-started generator");
8535 if (self->resume_label == -1) {
8536 PyErr_SetNone(PyExc_StopIteration);
8542 __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
8544 __Pyx_Generator_ExceptionClear(self);
8546 self->is_running = 1;
8547 retval = self->body((PyObject *) self, value);
8548 self->is_running = 0;
8551 __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
8553 __Pyx_Generator_ExceptionClear(self);
8558 static PyObject *__Pyx_Generator_Next(PyObject *self)
8560 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, Py_None);
8563 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value)
8565 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, value);
8568 static PyObject *__Pyx_Generator_Close(PyObject *self)
8570 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8572 #if PY_VERSION_HEX < 0x02050000
8573 PyErr_SetNone(PyExc_StopIteration);
8575 PyErr_SetNone(PyExc_GeneratorExit);
8577 retval = __Pyx_Generator_SendEx(generator, NULL);
8580 PyErr_SetString(PyExc_RuntimeError,
8581 "generator ignored GeneratorExit");
8584 #if PY_VERSION_HEX < 0x02050000
8585 if (PyErr_ExceptionMatches(PyExc_StopIteration))
8587 if (PyErr_ExceptionMatches(PyExc_StopIteration)
8588 || PyErr_ExceptionMatches(PyExc_GeneratorExit))
8591 PyErr_Clear(); /* ignore these errors */
8598 static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args, CYTHON_UNUSED PyObject *kwds)
8600 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8602 PyObject *tb = NULL;
8603 PyObject *val = NULL;
8605 if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
8607 __Pyx_Raise(typ, val, tb);
8608 return __Pyx_Generator_SendEx(generator, NULL);
8611 proto_block='utility_code_proto_before_types',
8612 requires=[Nodes.raise_utility_code, Nodes.swap_exception_utility_code],