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 WithExitCallNode(ExprNode):
1914 # The __exit__() call of a 'with' statement. Used in both the
1915 # except and finally clauses.
1917 # with_stat WithStatNode the surrounding 'with' statement
1918 # args TupleNode or ResultStatNode the exception info tuple
1922 def analyse_types(self, env):
1923 self.args.analyse_types(env)
1924 self.type = PyrexTypes.c_bint_type
1927 def generate_result_code(self, code):
1928 if isinstance(self.args, TupleNode):
1929 # call only if it was not already called (and decref-cleared)
1930 code.putln("if (%s) {" % self.with_stat.exit_var)
1931 result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
1932 code.putln("%s = PyObject_Call(%s, %s, NULL);" % (
1934 self.with_stat.exit_var,
1935 self.args.result()))
1936 code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
1937 code.putln(code.error_goto_if_null(result_var, self.pos))
1938 code.put_gotref(result_var)
1939 code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
1940 code.put_decref_clear(result_var, type=py_object_type)
1941 code.putln(code.error_goto_if_neg(self.result(), self.pos))
1942 code.funcstate.release_temp(result_var)
1943 if isinstance(self.args, TupleNode):
1947 class ExcValueNode(AtomicExprNode):
1948 # Node created during analyse_types phase
1949 # of an ExceptClauseNode to fetch the current
1952 type = py_object_type
1954 def __init__(self, pos, env):
1955 ExprNode.__init__(self, pos)
1957 def set_var(self, var):
1960 def calculate_result_code(self):
1963 def generate_result_code(self, code):
1966 def analyse_types(self, env):
1970 class TempNode(ExprNode):
1971 # Node created during analyse_types phase
1972 # of some nodes to hold a temporary value.
1974 # Note: One must call "allocate" and "release" on
1975 # the node during code generation to get/release the temp.
1976 # This is because the temp result is often used outside of
1977 # the regular cycle.
1981 def __init__(self, pos, type, env=None):
1982 ExprNode.__init__(self, pos)
1984 if type.is_pyobject:
1985 self.result_ctype = py_object_type
1988 def analyse_types(self, env):
1991 def analyse_target_declaration(self, env):
1994 def generate_result_code(self, code):
1997 def allocate(self, code):
1998 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
2000 def release(self, code):
2001 code.funcstate.release_temp(self.temp_cname)
2002 self.temp_cname = None
2006 return self.temp_cname
2008 assert False, "Remember to call allocate/release on TempNode"
2011 # Do not participate in normal temp alloc/dealloc:
2012 def allocate_temp_result(self, code):
2015 def release_temp_result(self, code):
2018 class PyTempNode(TempNode):
2019 # TempNode holding a Python value.
2021 def __init__(self, pos, env):
2022 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
2024 class RawCNameExprNode(ExprNode):
2027 def __init__(self, pos, type=None):
2031 def analyse_types(self, env):
2034 def set_cname(self, cname):
2040 def generate_result_code(self, code):
2044 #-------------------------------------------------------------------
2048 #-------------------------------------------------------------------
2050 class IndexNode(ExprNode):
2051 # Sequence indexing.
2055 # indices [ExprNode]
2056 # is_buffer_access boolean Whether this is a buffer access.
2058 # indices is used on buffer access, index on non-buffer access.
2059 # The former contains a clean list of index parameters, the
2060 # latter whatever Python object is needed for index access.
2062 subexprs = ['base', 'index', 'indices']
2065 def __init__(self, pos, index, *args, **kw):
2066 ExprNode.__init__(self, pos, index=index, *args, **kw)
2069 def calculate_constant_result(self):
2070 self.constant_result = \
2071 self.base.constant_result[self.index.constant_result]
2073 def compile_time_value(self, denv):
2074 base = self.base.compile_time_value(denv)
2075 index = self.index.compile_time_value(denv)
2078 except Exception, e:
2079 self.compile_time_value_error(e)
2081 def is_ephemeral(self):
2082 return self.base.is_ephemeral()
2084 def is_simple(self):
2085 if self.is_buffer_access:
2088 return (base.is_simple() and self.index.is_simple()
2089 and base.type and (base.type.is_ptr or base.type.is_array))
2091 def analyse_target_declaration(self, env):
2094 def analyse_as_type(self, env):
2095 base_type = self.base.analyse_as_type(env)
2096 if base_type and not base_type.is_pyobject:
2097 if base_type.is_cpp_class:
2098 if isinstance(self.index, TupleNode):
2099 template_values = self.index.args
2101 template_values = [self.index]
2103 type_node = Nodes.TemplatedTypeNode(
2105 positional_args = template_values,
2106 keyword_args = None)
2107 return type_node.analyse(env, base_type = base_type)
2109 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2112 def type_dependencies(self, env):
2113 return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2115 def infer_type(self, env):
2116 base_type = self.base.infer_type(env)
2117 if isinstance(self.index, SliceNode):
2119 if base_type.is_string:
2120 # sliced C strings must coerce to Python
2122 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2123 # slicing these returns the same type
2126 # TODO: Handle buffers (hopefully without too much redundancy).
2127 return py_object_type
2129 index_type = self.index.infer_type(env)
2130 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2132 if base_type is unicode_type:
2133 # Py_UCS4 will automatically coerce to a unicode string
2134 # if required, so this is safe. We only infer Py_UCS4
2135 # when the index is a C integer type. Otherwise, we may
2136 # need to use normal Python item access, in which case
2137 # it's faster to return the one-char unicode string than
2138 # to receive it, throw it away, and potentially rebuild it
2139 # on a subsequent PyObject coercion.
2140 return PyrexTypes.c_py_ucs4_type
2141 elif base_type is str_type:
2142 # always returns str - Py2: bytes, Py3: unicode
2144 elif isinstance(self.base, BytesNode):
2145 #if env.global_scope().context.language_level >= 3:
2146 # # infering 'char' can be made to work in Python 3 mode
2147 # return PyrexTypes.c_char_type
2148 # Py2/3 return different types on indexing bytes objects
2149 return py_object_type
2150 elif base_type.is_ptr or base_type.is_array:
2151 return base_type.base_type
2153 # may be slicing or indexing, we don't know
2154 if base_type in (unicode_type, str_type):
2155 # these types always returns their own type on Python indexing/slicing
2158 # TODO: Handle buffers (hopefully without too much redundancy).
2159 return py_object_type
2161 def analyse_types(self, env):
2162 self.analyse_base_and_index_types(env, getting = 1)
2164 def analyse_target_types(self, env):
2165 self.analyse_base_and_index_types(env, setting = 1)
2167 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2168 # Note: This might be cleaned up by having IndexNode
2169 # parsed in a saner way and only construct the tuple if
2172 # Note that this function must leave IndexNode in a cloneable state.
2173 # For buffers, self.index is packed out on the initial analysis, and
2174 # when cloning self.indices is copied.
2175 self.is_buffer_access = False
2177 self.base.analyse_types(env)
2178 if self.base.type.is_error:
2179 # Do not visit child tree if base is undeclared to avoid confusing
2181 self.type = PyrexTypes.error_type
2184 is_slice = isinstance(self.index, SliceNode)
2185 # Potentially overflowing index value.
2186 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2187 self.index = self.index.coerce_to_pyobject(env)
2189 # Handle the case where base is a literal char* (and we expect a string, not an int)
2190 if isinstance(self.base, BytesNode) or is_slice:
2191 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2192 self.base = self.base.coerce_to_pyobject(env)
2194 skip_child_analysis = False
2195 buffer_access = False
2196 if self.base.type.is_buffer:
2198 indices = self.indices
2200 if isinstance(self.index, TupleNode):
2201 indices = self.index.args
2203 indices = [self.index]
2204 if len(indices) == self.base.type.ndim:
2205 buffer_access = True
2206 skip_child_analysis = True
2208 x.analyse_types(env)
2209 if not x.type.is_int:
2210 buffer_access = False
2212 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2214 # On cloning, indices is cloned. Otherwise, unpack index into indices
2215 assert not (buffer_access and isinstance(self.index, CloneNode))
2218 self.indices = indices
2220 self.type = self.base.type.dtype
2221 self.is_buffer_access = True
2222 self.buffer_type = self.base.entry.type
2224 if getting and self.type.is_pyobject:
2227 if not self.base.entry.type.writable:
2228 error(self.pos, "Writing to readonly buffer")
2230 self.base.entry.buffer_aux.writable_needed = True
2232 base_type = self.base.type
2233 if isinstance(self.index, TupleNode):
2234 self.index.analyse_types(env, skip_children=skip_child_analysis)
2235 elif not skip_child_analysis:
2236 self.index.analyse_types(env)
2237 self.original_index_type = self.index.type
2238 if base_type.is_unicode_char:
2239 # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
2240 # cases, but indexing must still work for them
2241 if self.index.constant_result in (0, -1):
2242 # FIXME: we know that this node is redundant -
2243 # currently, this needs to get handled in Optimize.py
2245 self.base = self.base.coerce_to_pyobject(env)
2246 base_type = self.base.type
2247 if base_type.is_pyobject:
2248 if self.index.type.is_int:
2250 and (base_type in (list_type, tuple_type, unicode_type))
2251 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2252 and not env.directives['boundscheck']):
2256 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2258 self.index = self.index.coerce_to_pyobject(env)
2260 if self.index.type.is_int and base_type is unicode_type:
2261 # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
2262 # if required, so this is fast and safe
2263 self.type = PyrexTypes.c_py_ucs4_type
2264 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2265 self.type = base_type
2267 self.type = py_object_type
2269 if base_type.is_ptr or base_type.is_array:
2270 self.type = base_type.base_type
2272 self.type = base_type
2273 elif self.index.type.is_pyobject:
2274 self.index = self.index.coerce_to(
2275 PyrexTypes.c_py_ssize_t_type, env)
2276 elif not self.index.type.is_int:
2278 "Invalid index type '%s'" %
2280 elif base_type.is_cpp_class:
2281 function = env.lookup_operator("[]", [self.base, self.index])
2282 if function is None:
2283 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2284 self.type = PyrexTypes.error_type
2285 self.result_code = "<error>"
2287 func_type = function.type
2288 if func_type.is_ptr:
2289 func_type = func_type.base_type
2290 self.index = self.index.coerce_to(func_type.args[0].type, env)
2291 self.type = func_type.return_type
2292 if setting and not func_type.return_type.is_reference:
2293 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2296 "Attempting to index non-array type '%s'" %
2298 self.type = PyrexTypes.error_type
2300 gil_message = "Indexing Python object"
2302 def nogil_check(self, env):
2303 if self.is_buffer_access:
2304 if env.directives['boundscheck']:
2305 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2307 elif self.type.is_pyobject:
2308 error(self.pos, "Cannot access buffer with object dtype without gil")
2310 super(IndexNode, self).nogil_check(env)
2313 def check_const_addr(self):
2314 return self.base.check_const_addr() and self.index.check_const()
2316 def is_lvalue(self):
2319 def calculate_result_code(self):
2320 if self.is_buffer_access:
2321 return "(*%s)" % self.buffer_ptr_code
2322 elif self.base.type is list_type:
2323 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2324 elif self.base.type is tuple_type:
2325 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2326 elif self.base.type is unicode_type and self.type.is_unicode_char:
2327 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2328 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2329 error(self.pos, "Invalid use of pointer slice")
2331 return "(%s[%s])" % (
2332 self.base.result(), self.index.result())
2334 def extra_index_params(self):
2335 if self.index.type.is_int:
2336 if self.original_index_type.signed:
2337 size_adjustment = ""
2339 size_adjustment = "+1"
2340 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2344 def generate_subexpr_evaluation_code(self, code):
2345 self.base.generate_evaluation_code(code)
2346 if not self.indices:
2347 self.index.generate_evaluation_code(code)
2349 for i in self.indices:
2350 i.generate_evaluation_code(code)
2352 def generate_subexpr_disposal_code(self, code):
2353 self.base.generate_disposal_code(code)
2354 if not self.indices:
2355 self.index.generate_disposal_code(code)
2357 for i in self.indices:
2358 i.generate_disposal_code(code)
2360 def free_subexpr_temps(self, code):
2361 self.base.free_temps(code)
2362 if not self.indices:
2363 self.index.free_temps(code)
2365 for i in self.indices:
2368 def generate_result_code(self, code):
2369 if self.is_buffer_access:
2370 if code.globalstate.directives['nonecheck']:
2371 self.put_nonecheck(code)
2372 self.buffer_ptr_code = self.buffer_lookup_code(code)
2373 if self.type.is_pyobject:
2374 # is_temp is True, so must pull out value and incref it.
2375 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2376 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2378 if self.type.is_pyobject:
2379 if self.index.type.is_int:
2380 index_code = self.index.result()
2381 if self.base.type is list_type:
2382 function = "__Pyx_GetItemInt_List"
2383 elif self.base.type is tuple_type:
2384 function = "__Pyx_GetItemInt_Tuple"
2386 function = "__Pyx_GetItemInt"
2387 code.globalstate.use_utility_code(getitem_int_utility_code)
2389 index_code = self.index.py_result()
2390 if self.base.type is dict_type:
2391 function = "__Pyx_PyDict_GetItem"
2392 code.globalstate.use_utility_code(getitem_dict_utility_code)
2394 function = "PyObject_GetItem"
2396 "%s = %s(%s, %s%s); if (!%s) %s" % (
2399 self.base.py_result(),
2401 self.extra_index_params(),
2403 code.error_goto(self.pos)))
2404 code.put_gotref(self.py_result())
2405 elif self.type.is_unicode_char and self.base.type is unicode_type:
2406 assert self.index.type.is_int
2407 index_code = self.index.result()
2408 function = "__Pyx_GetItemInt_Unicode"
2409 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2411 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2414 self.base.py_result(),
2416 self.extra_index_params(),
2418 code.error_goto(self.pos)))
2420 def generate_setitem_code(self, value_code, code):
2421 if self.index.type.is_int:
2422 function = "__Pyx_SetItemInt"
2423 index_code = self.index.result()
2424 code.globalstate.use_utility_code(setitem_int_utility_code)
2426 index_code = self.index.py_result()
2427 if self.base.type is dict_type:
2428 function = "PyDict_SetItem"
2429 # It would seem that we could specialized lists/tuples, but that
2430 # shouldn't happen here.
2431 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2432 # not a PyObject*, and bad conversion here would give the wrong
2433 # exception. Also, tuples are supposed to be immutable, and raise
2434 # TypeErrors when trying to set their entries (PyTuple_SetItem
2435 # is for creating new tuples from).
2437 function = "PyObject_SetItem"
2439 "if (%s(%s, %s, %s%s) < 0) %s" % (
2441 self.base.py_result(),
2444 self.extra_index_params(),
2445 code.error_goto(self.pos)))
2447 def generate_buffer_setitem_code(self, rhs, code, op=""):
2448 # Used from generate_assignment_code and InPlaceAssignmentNode
2449 if code.globalstate.directives['nonecheck']:
2450 self.put_nonecheck(code)
2451 ptrexpr = self.buffer_lookup_code(code)
2452 if self.buffer_type.dtype.is_pyobject:
2453 # Must manage refcounts. Decref what is already there
2454 # and incref what we put in.
2455 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2456 rhs_code = rhs.result()
2457 code.putln("%s = %s;" % (ptr, ptrexpr))
2458 code.put_gotref("*%s" % ptr)
2459 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2462 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2463 code.put_giveref("*%s" % ptr)
2464 code.funcstate.release_temp(ptr)
2467 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2469 def generate_assignment_code(self, rhs, code):
2470 self.generate_subexpr_evaluation_code(code)
2471 if self.is_buffer_access:
2472 self.generate_buffer_setitem_code(rhs, code)
2473 elif self.type.is_pyobject:
2474 self.generate_setitem_code(rhs.py_result(), code)
2478 self.result(), rhs.result()))
2479 self.generate_subexpr_disposal_code(code)
2480 self.free_subexpr_temps(code)
2481 rhs.generate_disposal_code(code)
2482 rhs.free_temps(code)
2484 def generate_deletion_code(self, code):
2485 self.generate_subexpr_evaluation_code(code)
2486 #if self.type.is_pyobject:
2487 if self.index.type.is_int:
2488 function = "__Pyx_DelItemInt"
2489 index_code = self.index.result()
2490 code.globalstate.use_utility_code(delitem_int_utility_code)
2492 index_code = self.index.py_result()
2493 if self.base.type is dict_type:
2494 function = "PyDict_DelItem"
2496 function = "PyObject_DelItem"
2498 "if (%s(%s, %s%s) < 0) %s" % (
2500 self.base.py_result(),
2502 self.extra_index_params(),
2503 code.error_goto(self.pos)))
2504 self.generate_subexpr_disposal_code(code)
2505 self.free_subexpr_temps(code)
2507 def buffer_lookup_code(self, code):
2508 # Assign indices to temps
2509 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2510 for temp, index in zip(index_temps, self.indices):
2511 code.putln("%s = %s;" % (temp, index.result()))
2512 # Generate buffer access code using these temps
2514 # The above could happen because child_attrs is wrong somewhere so that
2515 # options are not propagated.
2516 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2517 index_signeds=[i.type.signed for i in self.indices],
2518 index_cnames=index_temps,
2519 directives=code.globalstate.directives,
2520 pos=self.pos, code=code)
2522 def put_nonecheck(self, code):
2523 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2524 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2525 code.putln("__Pyx_RaiseNoneIndexingError();")
2526 code.putln(code.error_goto(self.pos))
2529 class SliceIndexNode(ExprNode):
2530 # 2-element slice indexing
2533 # start ExprNode or None
2534 # stop ExprNode or None
2536 subexprs = ['base', 'start', 'stop']
2538 def infer_type(self, env):
2539 base_type = self.base.infer_type(env)
2540 if base_type.is_string:
2542 elif base_type in (bytes_type, str_type, unicode_type,
2543 list_type, tuple_type):
2545 elif base_type.is_ptr or base_type.is_array:
2546 return PyrexTypes.c_array_type(base_type.base_type, None)
2547 return py_object_type
2549 def calculate_constant_result(self):
2550 self.constant_result = self.base.constant_result[
2551 self.start.constant_result : self.stop.constant_result]
2553 def compile_time_value(self, denv):
2554 base = self.base.compile_time_value(denv)
2555 if self.start is None:
2558 start = self.start.compile_time_value(denv)
2559 if self.stop is None:
2562 stop = self.stop.compile_time_value(denv)
2564 return base[start:stop]
2565 except Exception, e:
2566 self.compile_time_value_error(e)
2568 def analyse_target_declaration(self, env):
2571 def analyse_target_types(self, env):
2572 self.analyse_types(env)
2573 # when assigning, we must accept any Python type
2574 if self.type.is_pyobject:
2575 self.type = py_object_type
2577 def analyse_types(self, env):
2578 self.base.analyse_types(env)
2580 self.start.analyse_types(env)
2582 self.stop.analyse_types(env)
2583 base_type = self.base.type
2584 if base_type.is_string:
2585 self.type = bytes_type
2586 elif base_type.is_ptr:
2587 self.type = base_type
2588 elif base_type.is_array:
2589 # we need a ptr type here instead of an array type, as
2590 # array types can result in invalid type casts in the C
2592 self.type = PyrexTypes.CPtrType(base_type.base_type)
2594 self.base = self.base.coerce_to_pyobject(env)
2595 self.type = py_object_type
2596 if base_type.is_builtin_type:
2597 # slicing builtin types returns something of the same type
2598 self.type = base_type
2599 c_int = PyrexTypes.c_py_ssize_t_type
2601 self.start = self.start.coerce_to(c_int, env)
2603 self.stop = self.stop.coerce_to(c_int, env)
2606 nogil_check = Node.gil_error
2607 gil_message = "Slicing Python object"
2609 def generate_result_code(self, code):
2610 if not self.type.is_pyobject:
2612 "Slicing is not currently supported for '%s'." % self.type)
2614 if self.base.type.is_string:
2615 if self.stop is None:
2617 "%s = PyBytes_FromString(%s + %s); %s" % (
2621 code.error_goto_if_null(self.result(), self.pos)))
2624 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2630 code.error_goto_if_null(self.result(), self.pos)))
2633 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2635 self.base.py_result(),
2638 code.error_goto_if_null(self.result(), self.pos)))
2639 code.put_gotref(self.py_result())
2641 def generate_assignment_code(self, rhs, code):
2642 self.generate_subexpr_evaluation_code(code)
2643 if self.type.is_pyobject:
2644 code.put_error_if_neg(self.pos,
2645 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2646 self.base.py_result(),
2653 start_offset = self.start_code()
2654 if start_offset == '0':
2658 if rhs.type.is_array:
2659 array_length = rhs.type.size
2660 self.generate_slice_guard_code(code, array_length)
2663 "Slice assignments from pointers are not yet supported.")
2664 # FIXME: fix the array size according to start/stop
2665 array_length = self.base.type.size
2666 for i in range(array_length):
2667 code.putln("%s[%s%s] = %s[%d];" % (
2668 self.base.result(), start_offset, i,
2670 self.generate_subexpr_disposal_code(code)
2671 self.free_subexpr_temps(code)
2672 rhs.generate_disposal_code(code)
2673 rhs.free_temps(code)
2675 def generate_deletion_code(self, code):
2676 if not self.base.type.is_pyobject:
2678 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2680 self.generate_subexpr_evaluation_code(code)
2681 code.put_error_if_neg(self.pos,
2682 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2683 self.base.py_result(),
2686 self.generate_subexpr_disposal_code(code)
2687 self.free_subexpr_temps(code)
2689 def generate_slice_guard_code(self, code, target_size):
2690 if not self.base.type.is_array:
2692 slice_size = self.base.type.size
2695 stop = self.stop.result()
2699 slice_size = self.base.type.size + stop
2706 start = self.start.result()
2710 start = self.base.type.size + start
2718 error(self.pos, "Assignment to empty slice.")
2719 elif start is None and stop is None:
2720 # we know the exact slice length
2721 if target_size != slice_size:
2722 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2723 slice_size, target_size))
2724 elif start is not None:
2727 check = "(%s)-(%s)" % (stop, start)
2728 else: # stop is not None:
2731 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2732 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));' % (
2733 target_size, check))
2734 code.putln(code.error_goto(self.pos))
2737 def start_code(self):
2739 return self.start.result()
2743 def stop_code(self):
2745 return self.stop.result()
2746 elif self.base.type.is_array:
2747 return self.base.type.size
2749 return "PY_SSIZE_T_MAX"
2751 def calculate_result_code(self):
2752 # self.result() is not used, but this method must exist
2756 class SliceNode(ExprNode):
2757 # start:stop:step in subscript list
2763 subexprs = ['start', 'stop', 'step']
2765 type = py_object_type
2768 def calculate_constant_result(self):
2769 self.constant_result = slice(
2770 self.start.constant_result,
2771 self.stop.constant_result,
2772 self.step.constant_result)
2774 def compile_time_value(self, denv):
2775 start = self.start.compile_time_value(denv)
2776 stop = self.stop.compile_time_value(denv)
2777 step = self.step.compile_time_value(denv)
2779 return slice(start, stop, step)
2780 except Exception, e:
2781 self.compile_time_value_error(e)
2783 def analyse_types(self, env):
2784 self.start.analyse_types(env)
2785 self.stop.analyse_types(env)
2786 self.step.analyse_types(env)
2787 self.start = self.start.coerce_to_pyobject(env)
2788 self.stop = self.stop.coerce_to_pyobject(env)
2789 self.step = self.step.coerce_to_pyobject(env)
2790 if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
2791 self.is_literal = True
2792 self.is_temp = False
2794 gil_message = "Constructing Python slice object"
2796 def calculate_result_code(self):
2797 return self.result_code
2799 def generate_result_code(self, code):
2801 self.result_code = code.get_py_const(py_object_type, 'slice_', cleanup_level=2)
2802 code = code.get_cached_constants_writer()
2803 code.mark_pos(self.pos)
2806 "%s = PySlice_New(%s, %s, %s); %s" % (
2808 self.start.py_result(),
2809 self.stop.py_result(),
2810 self.step.py_result(),
2811 code.error_goto_if_null(self.result(), self.pos)))
2812 code.put_gotref(self.py_result())
2814 code.put_giveref(self.py_result())
2817 class CallNode(ExprNode):
2819 # allow overriding the default 'may_be_none' behaviour
2820 may_return_none = None
2822 def may_be_none(self):
2823 if self.may_return_none is not None:
2824 return self.may_return_none
2825 return ExprNode.may_be_none(self)
2827 def analyse_as_type_constructor(self, env):
2828 type = self.function.analyse_as_type(env)
2829 if type and type.is_struct_or_union:
2830 args, kwds = self.explicit_args_kwds()
2832 for arg, member in zip(args, type.scope.var_entries):
2833 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2835 items += kwds.key_value_pairs
2836 self.key_value_pairs = items
2837 self.__class__ = DictNode
2838 self.analyse_types(env)
2839 self.coerce_to(type, env)
2841 elif type and type.is_cpp_class:
2842 for arg in self.args:
2843 arg.analyse_types(env)
2844 constructor = type.scope.lookup("<init>")
2845 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2846 self.function.entry = constructor
2847 self.function.set_cname(type.declaration_code(""))
2848 self.analyse_c_function_call(env)
2851 def is_lvalue(self):
2852 return self.type.is_reference
2854 def nogil_check(self, env):
2855 func_type = self.function_type()
2856 if func_type.is_pyobject:
2858 elif not getattr(func_type, 'nogil', False):
2861 gil_message = "Calling gil-requiring function"
2864 class SimpleCallNode(CallNode):
2865 # Function call without keyword, * or ** args.
2869 # arg_tuple ExprNode or None used internally
2870 # self ExprNode or None used internally
2871 # coerced_self ExprNode or None used internally
2872 # wrapper_call bool used internally
2873 # has_optional_args bool used internally
2874 # nogil bool used internally
2876 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2881 wrapper_call = False
2882 has_optional_args = False
2886 def compile_time_value(self, denv):
2887 function = self.function.compile_time_value(denv)
2888 args = [arg.compile_time_value(denv) for arg in self.args]
2890 return function(*args)
2891 except Exception, e:
2892 self.compile_time_value_error(e)
2894 def type_dependencies(self, env):
2895 # TODO: Update when Danilo's C++ code merged in to handle the
2896 # the case of function overloading.
2897 return self.function.type_dependencies(env)
2899 def infer_type(self, env):
2900 function = self.function
2901 func_type = function.infer_type(env)
2902 if isinstance(self.function, NewExprNode):
2903 return PyrexTypes.CPtrType(self.function.class_type)
2904 if func_type.is_ptr:
2905 func_type = func_type.base_type
2906 if func_type.is_cfunction:
2907 return func_type.return_type
2908 elif func_type is type_type:
2909 if function.is_name and function.entry and function.entry.type:
2910 result_type = function.entry.type
2911 if result_type.is_extension_type:
2913 elif result_type.is_builtin_type:
2914 if function.entry.name == 'float':
2915 return PyrexTypes.c_double_type
2916 elif function.entry.name in Builtin.types_that_construct_their_instance:
2918 return py_object_type
2920 def analyse_as_type(self, env):
2921 attr = self.function.as_cython_attribute()
2922 if attr == 'pointer':
2923 if len(self.args) != 1:
2924 error(self.args.pos, "only one type allowed.")
2926 type = self.args[0].analyse_as_type(env)
2928 error(self.args[0].pos, "Unknown type")
2930 return PyrexTypes.CPtrType(type)
2932 def explicit_args_kwds(self):
2933 return self.args, None
2935 def analyse_types(self, env):
2936 if self.analyse_as_type_constructor(env):
2940 self.analysed = True
2941 function = self.function
2942 function.is_called = 1
2943 self.function.analyse_types(env)
2944 if function.is_attribute and function.entry and function.entry.is_cmethod:
2945 # Take ownership of the object from which the attribute
2946 # was obtained, because we need to pass it as 'self'.
2947 self.self = function.obj
2948 function.obj = CloneNode(self.self)
2949 func_type = self.function_type()
2950 if func_type.is_pyobject:
2951 self.arg_tuple = TupleNode(self.pos, args = self.args)
2952 self.arg_tuple.analyse_types(env)
2954 if func_type is Builtin.type_type and function.is_name and \
2955 function.entry and \
2956 function.entry.is_builtin and \
2957 function.entry.name in Builtin.types_that_construct_their_instance:
2958 # calling a builtin type that returns a specific object type
2959 if function.entry.name == 'float':
2960 # the following will come true later on in a transform
2961 self.type = PyrexTypes.c_double_type
2962 self.result_ctype = PyrexTypes.c_double_type
2964 self.type = Builtin.builtin_types[function.entry.name]
2965 self.result_ctype = py_object_type
2966 self.may_return_none = False
2967 elif function.is_name and function.type_entry:
2968 # We are calling an extension type constructor. As
2969 # long as we do not support __new__(), the result type
2971 self.type = function.type_entry.type
2972 self.result_ctype = py_object_type
2973 self.may_return_none = False
2975 self.type = py_object_type
2978 for arg in self.args:
2979 arg.analyse_types(env)
2980 if self.self and func_type.args:
2981 # Coerce 'self' to the type expected by the method.
2982 self_arg = func_type.args[0]
2983 if self_arg.not_none: # C methods must do the None test for self at *call* time
2984 self.self = self.self.as_none_safe_node(
2985 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2986 'PyExc_AttributeError')
2987 expected_type = self_arg.type
2988 self.coerced_self = CloneNode(self.self).coerce_to(
2990 # Insert coerced 'self' argument into argument list.
2991 self.args.insert(0, self.coerced_self)
2992 self.analyse_c_function_call(env)
2994 def function_type(self):
2995 # Return the type of the function being called, coercing a function
2996 # pointer to a function if necessary.
2997 func_type = self.function.type
2998 if func_type.is_ptr:
2999 func_type = func_type.base_type
3002 def is_simple(self):
3003 # C function calls could be considered simple, but they may
3004 # have side-effects that may hit when multiple operations must
3005 # be effected in order, e.g. when constructing the argument
3006 # sequence for a function call or comparing values.
3009 def analyse_c_function_call(self, env):
3010 if self.function.type is error_type:
3011 self.type = error_type
3013 if self.function.type.is_cpp_class:
3014 overloaded_entry = self.function.type.scope.lookup("operator()")
3015 if overloaded_entry is None:
3016 self.type = PyrexTypes.error_type
3017 self.result_code = "<error>"
3019 elif hasattr(self.function, 'entry'):
3020 overloaded_entry = self.function.entry
3022 overloaded_entry = None
3023 if overloaded_entry:
3024 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
3026 self.type = PyrexTypes.error_type
3027 self.result_code = "<error>"
3029 self.function.entry = entry
3030 self.function.type = entry.type
3031 func_type = self.function_type()
3033 func_type = self.function_type()
3034 if not func_type.is_cfunction:
3035 error(self.pos, "Calling non-function type '%s'" % func_type)
3036 self.type = PyrexTypes.error_type
3037 self.result_code = "<error>"
3040 max_nargs = len(func_type.args)
3041 expected_nargs = max_nargs - func_type.optional_arg_count
3042 actual_nargs = len(self.args)
3043 if func_type.optional_arg_count and expected_nargs != actual_nargs:
3044 self.has_optional_args = 1
3047 some_args_in_temps = False
3048 for i in xrange(min(max_nargs, actual_nargs)):
3049 formal_type = func_type.args[i].type
3050 arg = self.args[i].coerce_to(formal_type, env)
3053 # first argument in temp doesn't impact subsequent arguments
3054 some_args_in_temps = True
3055 elif arg.type.is_pyobject and not env.nogil:
3056 if i == 0 and self.self is not None:
3057 # a method's cloned "self" argument is ok
3059 elif arg.nonlocally_immutable():
3060 # plain local variables are ok
3063 # we do not safely own the argument's reference,
3064 # but we must make sure it cannot be collected
3065 # before we return from the function, so we create
3066 # an owned temp reference to it
3067 if i > 0: # first argument doesn't matter
3068 some_args_in_temps = True
3069 arg = arg.coerce_to_temp(env)
3071 # handle additional varargs parameters
3072 for i in xrange(max_nargs, actual_nargs):
3074 if arg.type.is_pyobject:
3075 arg_ctype = arg.type.default_coerced_ctype()
3076 if arg_ctype is None:
3077 error(self.args[i].pos,
3078 "Python object cannot be passed as a varargs parameter")
3080 self.args[i] = arg = arg.coerce_to(arg_ctype, env)
3081 if arg.is_temp and i > 0:
3082 some_args_in_temps = True
3083 if some_args_in_temps:
3084 # if some args are temps and others are not, they may get
3085 # constructed in the wrong order (temps first) => make
3086 # sure they are either all temps or all not temps (except
3087 # for the last argument, which is evaluated last in any
3089 for i in xrange(actual_nargs-1):
3090 if i == 0 and self.self is not None:
3091 continue # self is ok
3093 if arg.nonlocally_immutable():
3094 # locals, C functions, unassignable types are safe.
3096 elif arg.type.is_cpp_class:
3097 # Assignment has side effects, avoid.
3099 elif env.nogil and arg.type.is_pyobject:
3100 # can't copy a Python reference into a temp in nogil
3101 # env (this is safe: a construction would fail in
3105 #self.args[i] = arg.coerce_to_temp(env)
3106 # instead: issue a warning
3107 if i > 0 or i == 1 and self.self is not None: # skip first arg
3108 warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
3110 # Calc result type and code fragment
3111 if isinstance(self.function, NewExprNode):
3112 self.type = PyrexTypes.CPtrType(self.function.class_type)
3114 self.type = func_type.return_type
3115 if self.type.is_pyobject:
3116 self.result_ctype = py_object_type
3118 elif func_type.exception_value is not None \
3119 or func_type.exception_check:
3121 # Called in 'nogil' context?
3122 self.nogil = env.nogil
3124 func_type.exception_check and
3125 func_type.exception_check != '+'):
3126 env.use_utility_code(pyerr_occurred_withgil_utility_code)
3127 # C++ exception handler
3128 if func_type.exception_check == '+':
3129 if func_type.exception_value is None:
3130 env.use_utility_code(cpp_exception_utility_code)
3132 def calculate_result_code(self):
3133 return self.c_call_code()
3135 def c_call_code(self):
3136 func_type = self.function_type()
3137 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
3139 formal_args = func_type.args
3141 args = list(zip(formal_args, self.args))
3142 max_nargs = len(func_type.args)
3143 expected_nargs = max_nargs - func_type.optional_arg_count
3144 actual_nargs = len(self.args)
3145 for formal_arg, actual_arg in args[:expected_nargs]:
3146 arg_code = actual_arg.result_as(formal_arg.type)
3147 arg_list_code.append(arg_code)
3149 if func_type.is_overridable:
3150 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3152 if func_type.optional_arg_count:
3153 if expected_nargs == actual_nargs:
3154 optional_args = 'NULL'
3156 optional_args = "&%s" % self.opt_arg_struct
3157 arg_list_code.append(optional_args)
3159 for actual_arg in self.args[len(formal_args):]:
3160 arg_list_code.append(actual_arg.result())
3161 result = "%s(%s)" % (self.function.result(),
3162 ', '.join(arg_list_code))
3165 def generate_result_code(self, code):
3166 func_type = self.function_type()
3167 if func_type.is_pyobject:
3168 arg_code = self.arg_tuple.py_result()
3170 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3172 self.function.py_result(),
3174 code.error_goto_if_null(self.result(), self.pos)))
3175 code.put_gotref(self.py_result())
3176 elif func_type.is_cfunction:
3177 if self.has_optional_args:
3178 actual_nargs = len(self.args)
3179 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3180 self.opt_arg_struct = code.funcstate.allocate_temp(
3181 func_type.op_arg_struct.base_type, manage_ref=True)
3182 code.putln("%s.%s = %s;" % (
3183 self.opt_arg_struct,
3184 Naming.pyrex_prefix + "n",
3185 len(self.args) - expected_nargs))
3186 args = list(zip(func_type.args, self.args))
3187 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3188 code.putln("%s.%s = %s;" % (
3189 self.opt_arg_struct,
3190 func_type.opt_arg_cname(formal_arg.name),
3191 actual_arg.result_as(formal_arg.type)))
3193 if self.type.is_pyobject and self.is_temp:
3194 exc_checks.append("!%s" % self.result())
3196 exc_val = func_type.exception_value
3197 exc_check = func_type.exception_check
3198 if exc_val is not None:
3199 exc_checks.append("%s == %s" % (self.result(), exc_val))
3202 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3204 exc_checks.append("PyErr_Occurred()")
3205 if self.is_temp or exc_checks:
3206 rhs = self.c_call_code()
3208 lhs = "%s = " % self.result()
3209 if self.is_temp and self.type.is_pyobject:
3210 #return_type = self.type # func_type.return_type
3211 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3212 # "from", return_type, "to pyobject" ###
3213 rhs = typecast(py_object_type, self.type, rhs)
3216 if func_type.exception_check == '+':
3217 if func_type.exception_value is None:
3218 raise_py_exception = "__Pyx_CppExn2PyErr()"
3219 elif func_type.exception_value.type.is_pyobject:
3220 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3221 func_type.exception_value.entry.cname,
3222 func_type.exception_value.entry.cname)
3224 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3226 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3228 "try {%s%s;} catch(...) {%s; %s}" % (
3232 code.error_goto(self.pos)))
3235 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3238 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3239 if self.type.is_pyobject and self.result():
3240 code.put_gotref(self.py_result())
3241 if self.has_optional_args:
3242 code.funcstate.release_temp(self.opt_arg_struct)
3245 class PythonCapiFunctionNode(ExprNode):
3247 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3251 self.type = func_type
3252 self.utility_code = utility_code
3254 def analyse_types(self, env):
3257 def generate_result_code(self, code):
3258 if self.utility_code:
3259 code.globalstate.use_utility_code(self.utility_code)
3261 def calculate_result_code(self):
3264 class PythonCapiCallNode(SimpleCallNode):
3265 # Python C-API Function call (only created in transforms)
3267 # By default, we assume that the call never returns None, as this
3268 # is true for most C-API functions in CPython. If this does not
3269 # apply to a call, set the following to True (or None to inherit
3270 # the default behaviour).
3271 may_return_none = False
3273 def __init__(self, pos, function_name, func_type,
3274 utility_code = None, py_name=None, **kwargs):
3275 self.type = func_type.return_type
3276 self.result_ctype = self.type
3277 self.function = PythonCapiFunctionNode(
3278 pos, py_name, function_name, func_type,
3279 utility_code = utility_code)
3280 # call this last so that we can override the constructed
3281 # attributes above with explicit keyword arguments if required
3282 SimpleCallNode.__init__(self, pos, **kwargs)
3285 class GeneralCallNode(CallNode):
3286 # General Python function call, including keyword,
3287 # * and ** arguments.
3290 # positional_args ExprNode Tuple of positional arguments
3291 # keyword_args ExprNode or None Dict of keyword arguments
3292 # starstar_arg ExprNode or None Dict of extra keyword args
3294 type = py_object_type
3296 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3298 nogil_check = Node.gil_error
3300 def compile_time_value(self, denv):
3301 function = self.function.compile_time_value(denv)
3302 positional_args = self.positional_args.compile_time_value(denv)
3303 keyword_args = self.keyword_args.compile_time_value(denv)
3304 starstar_arg = self.starstar_arg.compile_time_value(denv)
3306 keyword_args.update(starstar_arg)
3307 return function(*positional_args, **keyword_args)
3308 except Exception, e:
3309 self.compile_time_value_error(e)
3311 def explicit_args_kwds(self):
3312 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3313 raise CompileError(self.pos,
3314 'Compile-time keyword arguments must be explicit.')
3315 return self.positional_args.args, self.keyword_args
3317 def analyse_types(self, env):
3318 if self.analyse_as_type_constructor(env):
3320 self.function.analyse_types(env)
3321 self.positional_args.analyse_types(env)
3322 if self.keyword_args:
3323 self.keyword_args.analyse_types(env)
3324 if self.starstar_arg:
3325 self.starstar_arg.analyse_types(env)
3326 if not self.function.type.is_pyobject:
3327 if self.function.type.is_error:
3328 self.type = error_type
3330 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3331 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3333 self.function = self.function.coerce_to_pyobject(env)
3334 self.positional_args = \
3335 self.positional_args.coerce_to_pyobject(env)
3336 if self.starstar_arg:
3337 self.starstar_arg = \
3338 self.starstar_arg.coerce_to_pyobject(env)
3339 function = self.function
3340 if function.is_name and function.type_entry:
3341 # We are calling an extension type constructor. As long
3342 # as we do not support __new__(), the result type is clear
3343 self.type = function.type_entry.type
3344 self.result_ctype = py_object_type
3345 self.may_return_none = False
3347 self.type = py_object_type
3350 def generate_result_code(self, code):
3351 if self.type.is_error: return
3352 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3353 if self.keyword_args and self.starstar_arg:
3354 code.put_error_if_neg(self.pos,
3355 "PyDict_Update(%s, %s)" % (
3356 self.keyword_args.py_result(),
3357 self.starstar_arg.py_result()))
3358 keyword_code = self.keyword_args.py_result()
3359 elif self.keyword_args:
3360 keyword_code = self.keyword_args.py_result()
3361 elif self.starstar_arg:
3362 keyword_code = self.starstar_arg.py_result()
3363 if self.starstar_arg.type is not Builtin.dict_type:
3364 # CPython supports calling functions with non-dicts, so do we
3365 code.globalstate.use_utility_code(kwargs_call_utility_code)
3366 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3369 if not keyword_code:
3370 call_code = "PyObject_Call(%s, %s, NULL)" % (
3371 self.function.py_result(),
3372 self.positional_args.py_result())
3374 call_code = "%s(%s, %s, %s)" % (
3375 kwargs_call_function,
3376 self.function.py_result(),
3377 self.positional_args.py_result(),
3383 code.error_goto_if_null(self.result(), self.pos)))
3384 code.put_gotref(self.py_result())
3387 class AsTupleNode(ExprNode):
3388 # Convert argument to tuple. Used for normalising
3389 # the * argument of a function call.
3395 def calculate_constant_result(self):
3396 self.constant_result = tuple(self.base.constant_result)
3398 def compile_time_value(self, denv):
3399 arg = self.arg.compile_time_value(denv)
3402 except Exception, e:
3403 self.compile_time_value_error(e)
3405 def analyse_types(self, env):
3406 self.arg.analyse_types(env)
3407 self.arg = self.arg.coerce_to_pyobject(env)
3408 self.type = tuple_type
3411 def may_be_none(self):
3414 nogil_check = Node.gil_error
3415 gil_message = "Constructing Python tuple"
3417 def generate_result_code(self, code):
3419 "%s = PySequence_Tuple(%s); %s" % (
3421 self.arg.py_result(),
3422 code.error_goto_if_null(self.result(), self.pos)))
3423 code.put_gotref(self.py_result())
3426 class AttributeNode(ExprNode):
3431 # needs_none_check boolean Used if obj is an extension type.
3432 # If set to True, it is known that the type is not None.
3436 # is_py_attr boolean Is a Python getattr operation
3437 # member string C name of struct member
3438 # is_called boolean Function call is being done on result
3439 # entry Entry Symbol table entry of attribute
3444 type = PyrexTypes.error_type
3447 needs_none_check = True
3449 def as_cython_attribute(self):
3450 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3451 return self.attribute
3452 cy = self.obj.as_cython_attribute()
3454 return "%s.%s" % (cy, self.attribute)
3456 def coerce_to(self, dst_type, env):
3457 # If coercing to a generic pyobject and this is a cpdef function
3458 # we can create the corresponding attribute
3459 if dst_type is py_object_type:
3461 if entry and entry.is_cfunction and entry.as_variable:
3462 # must be a cpdef function
3464 self.entry = entry.as_variable
3465 self.analyse_as_python_attribute(env)
3467 return ExprNode.coerce_to(self, dst_type, env)
3469 def calculate_constant_result(self):
3470 attr = self.attribute
3471 if attr.startswith("__") and attr.endswith("__"):
3473 self.constant_result = getattr(self.obj.constant_result, attr)
3475 def compile_time_value(self, denv):
3476 attr = self.attribute
3477 if attr.startswith("__") and attr.endswith("__"):
3479 "Invalid attribute name '%s' in compile-time expression" % attr)
3481 obj = self.obj.compile_time_value(denv)
3483 return getattr(obj, attr)
3484 except Exception, e:
3485 self.compile_time_value_error(e)
3487 def type_dependencies(self, env):
3488 return self.obj.type_dependencies(env)
3490 def infer_type(self, env):
3491 if self.analyse_as_cimported_attribute(env, 0):
3492 return self.entry.type
3493 elif self.analyse_as_unbound_cmethod(env):
3494 return self.entry.type
3496 obj_type = self.obj.infer_type(env)
3497 self.analyse_attribute(env, obj_type = obj_type)
3498 if obj_type.is_builtin_type and self.type.is_cfunction:
3499 # special case: C-API replacements for C methods of
3500 # builtin types cannot be inferred as C functions as
3501 # that would prevent their use as bound methods
3502 self.type = py_object_type
3503 return py_object_type
3506 def analyse_target_declaration(self, env):
3509 def analyse_target_types(self, env):
3510 self.analyse_types(env, target = 1)
3512 def analyse_types(self, env, target = 0):
3513 if self.analyse_as_cimported_attribute(env, target):
3515 if not target and self.analyse_as_unbound_cmethod(env):
3517 self.analyse_as_ordinary_attribute(env, target)
3519 def analyse_as_cimported_attribute(self, env, target):
3520 # Try to interpret this as a reference to an imported
3521 # C const, type, var or function. If successful, mutates
3522 # this node into a NameNode and returns 1, otherwise
3524 module_scope = self.obj.analyse_as_module(env)
3526 entry = module_scope.lookup_here(self.attribute)
3528 entry.is_cglobal or entry.is_cfunction
3529 or entry.is_type or entry.is_const):
3530 self.mutate_into_name_node(env, entry, target)
3534 def analyse_as_unbound_cmethod(self, env):
3535 # Try to interpret this as a reference to an unbound
3536 # C method of an extension type. If successful, mutates
3537 # this node into a NameNode and returns 1, otherwise
3539 type = self.obj.analyse_as_extension_type(env)
3541 entry = type.scope.lookup_here(self.attribute)
3542 if entry and entry.is_cmethod:
3543 # Create a temporary entry describing the C method
3544 # as an ordinary function.
3545 ubcm_entry = Symtab.Entry(entry.name,
3546 "%s->%s" % (type.vtabptr_cname, entry.cname),
3548 ubcm_entry.is_cfunction = 1
3549 ubcm_entry.func_cname = entry.func_cname
3550 ubcm_entry.is_unbound_cmethod = 1
3551 self.mutate_into_name_node(env, ubcm_entry, None)
3555 def analyse_as_type(self, env):
3556 module_scope = self.obj.analyse_as_module(env)
3558 return module_scope.lookup_type(self.attribute)
3559 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3560 base_type = self.obj.analyse_as_type(env)
3561 if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
3562 return base_type.scope.lookup_type(self.attribute)
3565 def analyse_as_extension_type(self, env):
3566 # Try to interpret this as a reference to an extension type
3567 # in a cimported module. Returns the extension type, or None.
3568 module_scope = self.obj.analyse_as_module(env)
3570 entry = module_scope.lookup_here(self.attribute)
3571 if entry and entry.is_type and entry.type.is_extension_type:
3575 def analyse_as_module(self, env):
3576 # Try to interpret this as a reference to a cimported module
3577 # in another cimported module. Returns the module scope, or None.
3578 module_scope = self.obj.analyse_as_module(env)
3580 entry = module_scope.lookup_here(self.attribute)
3581 if entry and entry.as_module:
3582 return entry.as_module
3585 def mutate_into_name_node(self, env, entry, target):
3586 # Mutate this node into a NameNode and complete the
3587 # analyse_types phase.
3588 self.__class__ = NameNode
3589 self.name = self.attribute
3594 NameNode.analyse_target_types(self, env)
3596 NameNode.analyse_rvalue_entry(self, env)
3598 def analyse_as_ordinary_attribute(self, env, target):
3599 self.obj.analyse_types(env)
3600 self.analyse_attribute(env)
3601 if self.entry and self.entry.is_cmethod and not self.is_called:
3602 # error(self.pos, "C method can only be called")
3604 ## Reference to C array turns into pointer to first element.
3605 #while self.type.is_array:
3606 # self.type = self.type.element_ptr_type()
3610 self.result_ctype = py_object_type
3611 elif target and self.obj.type.is_builtin_type:
3612 error(self.pos, "Assignment to an immutable object field")
3614 def analyse_attribute(self, env, obj_type = None):
3615 # Look up attribute and set self.type and self.member.
3617 self.member = self.attribute
3618 if obj_type is None:
3619 if self.obj.type.is_string:
3620 self.obj = self.obj.coerce_to_pyobject(env)
3621 obj_type = self.obj.type
3623 if obj_type.is_string:
3624 obj_type = py_object_type
3625 if obj_type.is_ptr or obj_type.is_array:
3626 obj_type = obj_type.base_type
3628 elif obj_type.is_extension_type or obj_type.is_builtin_type:
3632 if obj_type.has_attributes:
3634 if obj_type.attributes_known():
3635 entry = obj_type.scope.lookup_here(self.attribute)
3636 if entry and entry.is_member:
3640 "Cannot select attribute of incomplete type '%s'"
3642 self.type = PyrexTypes.error_type
3646 if obj_type.is_extension_type and entry.name == "__weakref__":
3647 error(self.pos, "Illegal use of special attribute __weakref__")
3648 # methods need the normal attribute lookup
3649 # because they do not have struct entries
3650 if entry.is_variable or entry.is_cmethod:
3651 self.type = entry.type
3652 self.member = entry.cname
3655 # If it's not a variable or C method, it must be a Python
3656 # method of an extension type, so we treat it like a Python
3659 # If we get here, the base object is not a struct/union/extension
3660 # type, or it is an extension type and the attribute is either not
3661 # declared or is declared as a Python method. Treat it as a Python
3662 # attribute reference.
3663 self.analyse_as_python_attribute(env, obj_type)
3665 def analyse_as_python_attribute(self, env, obj_type = None):
3666 if obj_type is None:
3667 obj_type = self.obj.type
3668 self.member = self.attribute
3669 self.type = py_object_type
3671 if not obj_type.is_pyobject and not obj_type.is_error:
3672 if obj_type.can_coerce_to_pyobject(env):
3673 self.obj = self.obj.coerce_to_pyobject(env)
3676 "Object of type '%s' has no attribute '%s'" %
3677 (obj_type, self.attribute))
3679 def nogil_check(self, env):
3683 gil_message = "Accessing Python attribute"
3685 def is_simple(self):
3687 return self.result_in_temp() or self.obj.is_simple()
3689 return NameNode.is_simple(self)
3691 def is_lvalue(self):
3695 return NameNode.is_lvalue(self)
3697 def is_ephemeral(self):
3699 return self.obj.is_ephemeral()
3701 return NameNode.is_ephemeral(self)
3703 def calculate_result_code(self):
3704 #print "AttributeNode.calculate_result_code:", self.member ###
3705 #print "...obj node =", self.obj, "code", self.obj.result() ###
3706 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3708 obj_code = obj.result_as(obj.type)
3709 #print "...obj_code =", obj_code ###
3710 if self.entry and self.entry.is_cmethod:
3711 if obj.type.is_extension_type:
3712 return "((struct %s *)%s%s%s)->%s" % (
3713 obj.type.vtabstruct_cname, obj_code, self.op,
3714 obj.type.vtabslot_cname, self.member)
3717 elif obj.type.is_complex:
3718 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3720 if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
3721 # accessing a field of a builtin type, need to cast better than result_as() does
3722 obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
3723 return "%s%s%s" % (obj_code, self.op, self.member)
3725 def generate_result_code(self, code):
3726 interned_attr_cname = code.intern_identifier(self.attribute)
3729 '%s = PyObject_GetAttr(%s, %s); %s' % (
3731 self.obj.py_result(),
3732 interned_attr_cname,
3733 code.error_goto_if_null(self.result(), self.pos)))
3734 code.put_gotref(self.py_result())
3736 # result_code contains what is needed, but we may need to insert
3737 # a check and raise an exception
3738 if (self.obj.type.is_extension_type
3739 and self.needs_none_check
3740 and code.globalstate.directives['nonecheck']):
3741 self.put_nonecheck(code)
3743 def generate_assignment_code(self, rhs, code):
3744 interned_attr_cname = code.intern_identifier(self.attribute)
3745 self.obj.generate_evaluation_code(code)
3747 code.put_error_if_neg(self.pos,
3748 'PyObject_SetAttr(%s, %s, %s)' % (
3749 self.obj.py_result(),
3750 interned_attr_cname,
3752 rhs.generate_disposal_code(code)
3753 rhs.free_temps(code)
3754 elif self.obj.type.is_complex:
3755 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3756 self.member.upper(),
3757 self.obj.result_as(self.obj.type),
3758 rhs.result_as(self.ctype())))
3760 if (self.obj.type.is_extension_type
3761 and self.needs_none_check
3762 and code.globalstate.directives['nonecheck']):
3763 self.put_nonecheck(code)
3765 select_code = self.result()
3766 if self.type.is_pyobject and self.use_managed_ref:
3767 rhs.make_owned_reference(code)
3768 code.put_giveref(rhs.py_result())
3769 code.put_gotref(select_code)
3770 code.put_decref(select_code, self.ctype())
3774 rhs.result_as(self.ctype())))
3776 rhs.generate_post_assignment_code(code)
3777 rhs.free_temps(code)
3778 self.obj.generate_disposal_code(code)
3779 self.obj.free_temps(code)
3781 def generate_deletion_code(self, code):
3782 interned_attr_cname = code.intern_identifier(self.attribute)
3783 self.obj.generate_evaluation_code(code)
3784 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3785 and u'__del__' in self.entry.scope.entries):
3786 code.put_error_if_neg(self.pos,
3787 'PyObject_DelAttr(%s, %s)' % (
3788 self.obj.py_result(),
3789 interned_attr_cname))
3791 error(self.pos, "Cannot delete C attribute of extension type")
3792 self.obj.generate_disposal_code(code)
3793 self.obj.free_temps(code)
3795 def annotate(self, code):
3797 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3799 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3801 def put_nonecheck(self, code):
3802 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3803 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3804 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3805 code.putln(code.error_goto(self.pos))
3809 #-------------------------------------------------------------------
3813 #-------------------------------------------------------------------
3815 class StarredTargetNode(ExprNode):
3816 # A starred expression like "*a"
3818 # This is only allowed in sequence assignment targets such as
3820 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3822 # and will be removed during type analysis (or generate an error
3823 # if it's found at unexpected places).
3827 subexprs = ['target']
3829 type = py_object_type
3832 def __init__(self, pos, target):
3834 self.target = target
3836 def analyse_declarations(self, env):
3837 error(self.pos, "can use starred expression only as assignment target")
3838 self.target.analyse_declarations(env)
3840 def analyse_types(self, env):
3841 error(self.pos, "can use starred expression only as assignment target")
3842 self.target.analyse_types(env)
3843 self.type = self.target.type
3845 def analyse_target_declaration(self, env):
3846 self.target.analyse_target_declaration(env)
3848 def analyse_target_types(self, env):
3849 self.target.analyse_target_types(env)
3850 self.type = self.target.type
3852 def calculate_result_code(self):
3855 def generate_result_code(self, code):
3859 class SequenceNode(ExprNode):
3860 # Base class for list and tuple constructor nodes.
3861 # Contains common code for performing sequence unpacking.
3865 # unpacked_items [ExprNode] or None
3866 # coerced_unpacked_items [ExprNode] or None
3870 is_sequence_constructor = 1
3871 unpacked_items = None
3873 def compile_time_value_list(self, denv):
3874 return [arg.compile_time_value(denv) for arg in self.args]
3876 def replace_starred_target_node(self):
3877 # replace a starred node in the targets by the contained expression
3878 self.starred_assignment = False
3880 for arg in self.args:
3882 if self.starred_assignment:
3883 error(arg.pos, "more than 1 starred expression in assignment")
3884 self.starred_assignment = True
3886 arg.is_starred = True
3890 def analyse_target_declaration(self, env):
3891 self.replace_starred_target_node()
3892 for arg in self.args:
3893 arg.analyse_target_declaration(env)
3895 def analyse_types(self, env, skip_children=False):
3896 for i in range(len(self.args)):
3898 if not skip_children: arg.analyse_types(env)
3899 self.args[i] = arg.coerce_to_pyobject(env)
3901 # not setting self.type here, subtypes do this
3903 def may_be_none(self):
3906 def analyse_target_types(self, env):
3907 self.iterator = PyTempNode(self.pos, env)
3908 self.unpacked_items = []
3909 self.coerced_unpacked_items = []
3910 for arg in self.args:
3911 arg.analyse_target_types(env)
3913 if not arg.type.assignable_from(Builtin.list_type):
3915 "starred target must have Python object (list) type")
3916 if arg.type is py_object_type:
3917 arg.type = Builtin.list_type
3918 unpacked_item = PyTempNode(self.pos, env)
3919 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3920 self.unpacked_items.append(unpacked_item)
3921 self.coerced_unpacked_items.append(coerced_unpacked_item)
3922 self.type = py_object_type
3924 def generate_result_code(self, code):
3925 self.generate_operation_code(code)
3927 def generate_assignment_code(self, rhs, code):
3928 if self.starred_assignment:
3929 self.generate_starred_assignment_code(rhs, code)
3931 self.generate_parallel_assignment_code(rhs, code)
3933 for item in self.unpacked_items:
3935 rhs.free_temps(code)
3937 def generate_parallel_assignment_code(self, rhs, code):
3938 # Need to work around the fact that generate_evaluation_code
3939 # allocates the temps in a rather hacky way -- the assignment
3940 # is evaluated twice, within each if-block.
3942 if rhs.type is tuple_type:
3943 tuple_check = "likely(%s != Py_None)"
3945 tuple_check = "PyTuple_CheckExact(%s)"
3947 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3948 tuple_check % rhs.py_result(),
3951 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3952 for item in self.unpacked_items:
3954 for i in range(len(self.args)):
3955 item = self.unpacked_items[i]
3957 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3960 code.put_incref(item.result(), item.ctype())
3961 value_node = self.coerced_unpacked_items[i]
3962 value_node.generate_evaluation_code(code)
3963 rhs.generate_disposal_code(code)
3965 for i in range(len(self.args)):
3966 self.args[i].generate_assignment_code(
3967 self.coerced_unpacked_items[i], code)
3969 code.putln("} else {")
3971 if rhs.type is tuple_type:
3972 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3973 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3974 rhs.py_result(), len(self.args)))
3975 code.putln(code.error_goto(self.pos))
3977 code.globalstate.use_utility_code(unpacking_utility_code)
3979 self.iterator.allocate(code)
3981 "%s = PyObject_GetIter(%s); %s" % (
3982 self.iterator.result(),
3984 code.error_goto_if_null(self.iterator.result(), self.pos)))
3985 code.put_gotref(self.iterator.py_result())
3986 rhs.generate_disposal_code(code)
3987 for i in range(len(self.args)):
3988 item = self.unpacked_items[i]
3989 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3990 self.iterator.py_result(), i)
3994 typecast(item.ctype(), py_object_type, unpack_code),
3995 code.error_goto_if_null(item.result(), self.pos)))
3996 code.put_gotref(item.py_result())
3997 value_node = self.coerced_unpacked_items[i]
3998 value_node.generate_evaluation_code(code)
3999 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
4000 self.iterator.py_result(),
4002 if debug_disposal_code:
4003 print("UnpackNode.generate_assignment_code:")
4004 print("...generating disposal code for %s" % self.iterator)
4005 self.iterator.generate_disposal_code(code)
4006 self.iterator.free_temps(code)
4007 self.iterator.release(code)
4009 for i in range(len(self.args)):
4010 self.args[i].generate_assignment_code(
4011 self.coerced_unpacked_items[i], code)
4015 def generate_starred_assignment_code(self, rhs, code):
4016 code.globalstate.use_utility_code(unpacking_utility_code)
4018 for i, arg in enumerate(self.args):
4020 starred_target = self.unpacked_items[i]
4021 fixed_args_left = self.args[:i]
4022 fixed_args_right = self.args[i+1:]
4025 self.iterator.allocate(code)
4027 "%s = PyObject_GetIter(%s); %s" % (
4028 self.iterator.result(),
4030 code.error_goto_if_null(self.iterator.result(), self.pos)))
4031 code.put_gotref(self.iterator.py_result())
4032 rhs.generate_disposal_code(code)
4034 for item in self.unpacked_items:
4036 for i in range(len(fixed_args_left)):
4037 item = self.unpacked_items[i]
4038 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
4039 self.iterator.py_result(), i)
4043 typecast(item.ctype(), py_object_type, unpack_code),
4044 code.error_goto_if_null(item.result(), self.pos)))
4045 code.put_gotref(item.py_result())
4046 value_node = self.coerced_unpacked_items[i]
4047 value_node.generate_evaluation_code(code)
4049 target_list = starred_target.result()
4050 code.putln("%s = PySequence_List(%s); %s" % (
4051 target_list, self.iterator.py_result(),
4052 code.error_goto_if_null(target_list, self.pos)))
4053 code.put_gotref(target_list)
4054 if fixed_args_right:
4055 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
4056 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
4057 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
4058 (target_list, len(unpacked_right_args))))
4059 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
4060 len(fixed_args_left), target_list,
4061 code.error_goto(self.pos)))
4063 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
4064 self.coerced_unpacked_items[::-1])):
4066 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
4068 target_list, target_list))
4069 # resize the list the hard way
4070 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
4071 code.put_gotref(arg.py_result())
4072 coerced_arg.generate_evaluation_code(code)
4074 self.iterator.generate_disposal_code(code)
4075 self.iterator.free_temps(code)
4076 self.iterator.release(code)
4078 for i in range(len(self.args)):
4079 self.args[i].generate_assignment_code(
4080 self.coerced_unpacked_items[i], code)
4082 def annotate(self, code):
4083 for arg in self.args:
4085 if self.unpacked_items:
4086 for arg in self.unpacked_items:
4088 for arg in self.coerced_unpacked_items:
4092 class TupleNode(SequenceNode):
4093 # Tuple constructor.
4097 gil_message = "Constructing Python tuple"
4099 def analyse_types(self, env, skip_children=False):
4100 if len(self.args) == 0:
4104 SequenceNode.analyse_types(self, env, skip_children)
4105 for child in self.args:
4106 if not child.is_literal:
4112 def is_simple(self):
4113 # either temp or constant => always simple
4116 def nonlocally_immutable(self):
4117 # either temp or constant => always safe
4120 def calculate_result_code(self):
4121 if len(self.args) > 0:
4122 return self.result_code
4124 return Naming.empty_tuple
4126 def calculate_constant_result(self):
4127 self.constant_result = tuple([
4128 arg.constant_result for arg in self.args])
4130 def compile_time_value(self, denv):
4131 values = self.compile_time_value_list(denv)
4133 return tuple(values)
4134 except Exception, e:
4135 self.compile_time_value_error(e)
4137 def generate_operation_code(self, code):
4138 if len(self.args) == 0:
4139 # result_code is Naming.empty_tuple
4142 # non-empty cached tuple => result is global constant,
4143 # creation code goes into separate code writer
4144 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
4145 code = code.get_cached_constants_writer()
4146 code.mark_pos(self.pos)
4149 "%s = PyTuple_New(%s); %s" % (
4152 code.error_goto_if_null(self.result(), self.pos)))
4153 code.put_gotref(self.py_result())
4154 for i in range(len(self.args)):
4156 if not arg.result_in_temp():
4157 code.put_incref(arg.result(), arg.ctype())
4159 "PyTuple_SET_ITEM(%s, %s, %s);" % (
4163 code.put_giveref(arg.py_result())
4165 code.put_giveref(self.py_result())
4167 def generate_subexpr_disposal_code(self, code):
4168 # We call generate_post_assignment_code here instead
4169 # of generate_disposal_code, because values were stored
4170 # in the tuple using a reference-stealing operation.
4171 for arg in self.args:
4172 arg.generate_post_assignment_code(code)
4173 # Should NOT call free_temps -- this is invoked by the default
4174 # generate_evaluation_code which will do that.
4177 class ListNode(SequenceNode):
4180 # obj_conversion_errors [PyrexError] used internally
4181 # orignial_args [ExprNode] used internally
4183 obj_conversion_errors = []
4186 gil_message = "Constructing Python list"
4188 def type_dependencies(self, env):
4191 def infer_type(self, env):
4192 # TOOD: Infer non-object list arrays.
4195 def analyse_expressions(self, env):
4196 SequenceNode.analyse_expressions(self, env)
4197 self.coerce_to_pyobject(env)
4199 def analyse_types(self, env):
4201 self.original_args = list(self.args)
4202 SequenceNode.analyse_types(self, env)
4203 self.obj_conversion_errors = held_errors()
4204 release_errors(ignore=True)
4206 def coerce_to(self, dst_type, env):
4207 if dst_type.is_pyobject:
4208 for err in self.obj_conversion_errors:
4210 self.obj_conversion_errors = []
4211 if not self.type.subtype_of(dst_type):
4212 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4213 elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
4214 base_type = dst_type.base_type
4215 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4216 for i in range(len(self.original_args)):
4218 if isinstance(arg, CoerceToPyTypeNode):
4220 self.args[i] = arg.coerce_to(base_type, env)
4221 elif dst_type.is_struct:
4222 if len(self.args) > len(dst_type.scope.var_entries):
4223 error(self.pos, "Too may members for '%s'" % dst_type)
4225 if len(self.args) < len(dst_type.scope.var_entries):
4226 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4227 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4228 if isinstance(arg, CoerceToPyTypeNode):
4230 self.args[i] = arg.coerce_to(member.type, env)
4231 self.type = dst_type
4233 self.type = error_type
4234 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4237 def release_temp(self, env):
4238 if self.type.is_array:
4239 # To be valid C++, we must allocate the memory on the stack
4240 # manually and be sure not to reuse it for something else.
4243 SequenceNode.release_temp(self, env)
4245 def calculate_constant_result(self):
4246 self.constant_result = [
4247 arg.constant_result for arg in self.args]
4249 def compile_time_value(self, denv):
4250 return self.compile_time_value_list(denv)
4252 def generate_operation_code(self, code):
4253 if self.type.is_pyobject:
4254 for err in self.obj_conversion_errors:
4256 code.putln("%s = PyList_New(%s); %s" %
4259 code.error_goto_if_null(self.result(), self.pos)))
4260 code.put_gotref(self.py_result())
4261 for i in range(len(self.args)):
4263 #if not arg.is_temp:
4264 if not arg.result_in_temp():
4265 code.put_incref(arg.result(), arg.ctype())
4266 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4270 code.put_giveref(arg.py_result())
4271 elif self.type.is_array:
4272 for i, arg in enumerate(self.args):
4273 code.putln("%s[%s] = %s;" % (
4277 elif self.type.is_struct:
4278 for arg, member in zip(self.args, self.type.scope.var_entries):
4279 code.putln("%s.%s = %s;" % (
4284 raise InternalError("List type never specified")
4286 def generate_subexpr_disposal_code(self, code):
4287 # We call generate_post_assignment_code here instead
4288 # of generate_disposal_code, because values were stored
4289 # in the list using a reference-stealing operation.
4290 for arg in self.args:
4291 arg.generate_post_assignment_code(code)
4292 # Should NOT call free_temps -- this is invoked by the default
4293 # generate_evaluation_code which will do that.
4296 class ScopedExprNode(ExprNode):
4297 # Abstract base class for ExprNodes that have their own local
4298 # scope, such as generator expressions.
4300 # expr_scope Scope the inner scope of the expression
4305 # does this node really have a local scope, e.g. does it leak loop
4306 # variables or not? non-leaking Py3 behaviour is default, except
4307 # for list comprehensions where the behaviour differs in Py2 and
4308 # Py3 (set in Parsing.py based on parser context)
4309 has_local_scope = True
4311 def init_scope(self, outer_scope, expr_scope=None):
4312 if expr_scope is not None:
4313 self.expr_scope = expr_scope
4314 elif self.has_local_scope:
4315 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4317 self.expr_scope = None
4319 def analyse_declarations(self, env):
4320 self.init_scope(env)
4322 def analyse_scoped_declarations(self, env):
4323 # this is called with the expr_scope as env
4326 def analyse_types(self, env):
4327 # no recursion here, the children will be analysed separately below
4330 def analyse_scoped_expressions(self, env):
4331 # this is called with the expr_scope as env
4334 def generate_evaluation_code(self, code):
4335 # set up local variables and free their references on exit
4336 generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
4337 if not self.has_local_scope or not self.expr_scope.var_entries:
4338 # no local variables => delegate, done
4339 generate_inner_evaluation_code(code)
4342 code.putln('{ /* enter inner scope */')
4344 for entry in self.expr_scope.var_entries:
4345 if not entry.in_closure:
4346 code.put_var_declaration(entry)
4347 if entry.type.is_pyobject and entry.used:
4348 py_entries.append(entry)
4350 # no local Python references => no cleanup required
4351 generate_inner_evaluation_code(code)
4352 code.putln('} /* exit inner scope */')
4354 for entry in py_entries:
4355 code.put_init_var_to_py_none(entry)
4357 # must free all local Python references at each exit point
4358 old_loop_labels = tuple(code.new_loop_labels())
4359 old_error_label = code.new_error_label()
4361 generate_inner_evaluation_code(code)
4363 # normal (non-error) exit
4364 for entry in py_entries:
4365 code.put_var_decref(entry)
4367 # error/loop body exit points
4368 exit_scope = code.new_label('exit_scope')
4369 code.put_goto(exit_scope)
4370 for label, old_label in ([(code.error_label, old_error_label)] +
4371 list(zip(code.get_loop_labels(), old_loop_labels))):
4372 if code.label_used(label):
4373 code.put_label(label)
4374 for entry in py_entries:
4375 code.put_var_decref(entry)
4376 code.put_goto(old_label)
4377 code.put_label(exit_scope)
4378 code.putln('} /* exit inner scope */')
4380 code.set_loop_labels(old_loop_labels)
4381 code.error_label = old_error_label
4384 class ComprehensionNode(ScopedExprNode):
4385 subexprs = ["target"]
4386 child_attrs = ["loop", "append"]
4388 def infer_type(self, env):
4389 return self.target.infer_type(env)
4391 def analyse_declarations(self, env):
4392 self.append.target = self # this is used in the PyList_Append of the inner loop
4393 self.init_scope(env)
4395 def analyse_scoped_declarations(self, env):
4396 self.loop.analyse_declarations(env)
4398 def analyse_types(self, env):
4399 self.target.analyse_expressions(env)
4400 self.type = self.target.type
4401 if not self.has_local_scope:
4402 self.loop.analyse_expressions(env)
4404 def analyse_scoped_expressions(self, env):
4405 if self.has_local_scope:
4406 self.loop.analyse_expressions(env)
4408 def may_be_none(self):
4411 def calculate_result_code(self):
4412 return self.target.result()
4414 def generate_result_code(self, code):
4415 self.generate_operation_code(code)
4417 def generate_operation_code(self, code):
4418 self.loop.generate_execution_code(code)
4420 def annotate(self, code):
4421 self.loop.annotate(code)
4424 class ComprehensionAppendNode(Node):
4425 # Need to be careful to avoid infinite recursion:
4426 # target must not be in child_attrs/subexprs
4428 child_attrs = ['expr']
4430 type = PyrexTypes.c_int_type
4432 def analyse_expressions(self, env):
4433 self.expr.analyse_expressions(env)
4434 if not self.expr.type.is_pyobject:
4435 self.expr = self.expr.coerce_to_pyobject(env)
4437 def generate_execution_code(self, code):
4438 if self.target.type is list_type:
4439 function = "PyList_Append"
4440 elif self.target.type is set_type:
4441 function = "PySet_Add"
4443 raise InternalError(
4444 "Invalid type for comprehension node: %s" % self.target.type)
4446 self.expr.generate_evaluation_code(code)
4447 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4449 self.target.result(),
4452 self.expr.generate_disposal_code(code)
4453 self.expr.free_temps(code)
4455 def generate_function_definitions(self, env, code):
4456 self.expr.generate_function_definitions(env, code)
4458 def annotate(self, code):
4459 self.expr.annotate(code)
4461 class DictComprehensionAppendNode(ComprehensionAppendNode):
4462 child_attrs = ['key_expr', 'value_expr']
4464 def analyse_expressions(self, env):
4465 self.key_expr.analyse_expressions(env)
4466 if not self.key_expr.type.is_pyobject:
4467 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4468 self.value_expr.analyse_expressions(env)
4469 if not self.value_expr.type.is_pyobject:
4470 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4472 def generate_execution_code(self, code):
4473 self.key_expr.generate_evaluation_code(code)
4474 self.value_expr.generate_evaluation_code(code)
4475 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4476 self.target.result(),
4477 self.key_expr.result(),
4478 self.value_expr.result()
4480 self.key_expr.generate_disposal_code(code)
4481 self.key_expr.free_temps(code)
4482 self.value_expr.generate_disposal_code(code)
4483 self.value_expr.free_temps(code)
4485 def generate_function_definitions(self, env, code):
4486 self.key_expr.generate_function_definitions(env, code)
4487 self.value_expr.generate_function_definitions(env, code)
4489 def annotate(self, code):
4490 self.key_expr.annotate(code)
4491 self.value_expr.annotate(code)
4494 class InlinedGeneratorExpressionNode(ScopedExprNode):
4495 # An inlined generator expression for which the result is
4496 # calculated inside of the loop. This will only be created by
4497 # transforms when replacing builtin calls on generator
4500 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4501 # result_node ResultRefNode the reference to the result value temp
4502 # orig_func String the name of the builtin function this node replaces
4504 child_attrs = ["loop"]
4505 loop_analysed = False
4506 type = py_object_type
4508 def analyse_scoped_declarations(self, env):
4509 self.loop.analyse_declarations(env)
4511 def analyse_types(self, env):
4512 if not self.has_local_scope:
4513 self.loop.analyse_expressions(env)
4516 def may_be_none(self):
4519 def annotate(self, code):
4520 self.loop.annotate(code)
4522 def infer_type(self, env):
4523 return self.result_node.infer_type(env)
4525 def analyse_types(self, env):
4526 if not self.has_local_scope:
4527 self.loop_analysed = True
4528 self.loop.analyse_expressions(env)
4529 self.type = self.result_node.type
4532 def analyse_scoped_expressions(self, env):
4533 self.loop_analysed = True
4534 if self.has_local_scope:
4535 self.loop.analyse_expressions(env)
4537 def coerce_to(self, dst_type, env):
4538 if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
4539 # We can optimise by dropping the aggregation variable and
4540 # the add operations into C. This can only be done safely
4541 # before analysing the loop body, after that, the result
4542 # reference type will have infected expressions and
4544 self.result_node.type = self.type = dst_type
4546 return super(InlinedGeneratorExpressionNode, self).coerce_to(dst_type, env)
4548 def generate_result_code(self, code):
4549 self.result_node.result_code = self.result()
4550 self.loop.generate_execution_code(code)
4553 class SetNode(ExprNode):
4560 gil_message = "Constructing Python set"
4562 def analyse_types(self, env):
4563 for i in range(len(self.args)):
4565 arg.analyse_types(env)
4566 self.args[i] = arg.coerce_to_pyobject(env)
4567 self.type = set_type
4570 def may_be_none(self):
4573 def calculate_constant_result(self):
4574 self.constant_result = set([
4575 arg.constant_result for arg in self.args])
4577 def compile_time_value(self, denv):
4578 values = [arg.compile_time_value(denv) for arg in self.args]
4581 except Exception, e:
4582 self.compile_time_value_error(e)
4584 def generate_evaluation_code(self, code):
4585 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4586 self.allocate_temp_result(code)
4588 "%s = PySet_New(0); %s" % (
4590 code.error_goto_if_null(self.result(), self.pos)))
4591 code.put_gotref(self.py_result())
4592 for arg in self.args:
4593 arg.generate_evaluation_code(code)
4595 code.error_goto_if_neg(
4596 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4598 arg.generate_disposal_code(code)
4599 arg.free_temps(code)
4602 class DictNode(ExprNode):
4603 # Dictionary constructor.
4605 # key_value_pairs [DictItemNode]
4607 # obj_conversion_errors [PyrexError] used internally
4609 subexprs = ['key_value_pairs']
4613 obj_conversion_errors = []
4615 def calculate_constant_result(self):
4616 self.constant_result = dict([
4617 item.constant_result for item in self.key_value_pairs])
4619 def compile_time_value(self, denv):
4620 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4621 for item in self.key_value_pairs]
4624 except Exception, e:
4625 self.compile_time_value_error(e)
4627 def type_dependencies(self, env):
4630 def infer_type(self, env):
4631 # TOOD: Infer struct constructors.
4634 def analyse_types(self, env):
4636 for item in self.key_value_pairs:
4637 item.analyse_types(env)
4638 self.obj_conversion_errors = held_errors()
4639 release_errors(ignore=True)
4641 def may_be_none(self):
4644 def coerce_to(self, dst_type, env):
4645 if dst_type.is_pyobject:
4646 self.release_errors()
4647 if not self.type.subtype_of(dst_type):
4648 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4649 elif dst_type.is_struct_or_union:
4650 self.type = dst_type
4651 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4652 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4653 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4654 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4655 for item in self.key_value_pairs:
4656 if isinstance(item.key, CoerceToPyTypeNode):
4657 item.key = item.key.arg
4658 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4659 error(item.key.pos, "Invalid struct field identifier")
4660 item.key = StringNode(item.key.pos, value="<error>")
4662 key = str(item.key.value) # converts string literals to unicode in Py3
4663 member = dst_type.scope.lookup_here(key)
4665 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4668 if isinstance(value, CoerceToPyTypeNode):
4670 item.value = value.coerce_to(member.type, env)
4672 self.type = error_type
4673 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4676 def release_errors(self):
4677 for err in self.obj_conversion_errors:
4679 self.obj_conversion_errors = []
4681 gil_message = "Constructing Python dict"
4683 def generate_evaluation_code(self, code):
4684 # Custom method used here because key-value
4685 # pairs are evaluated and used one at a time.
4686 code.mark_pos(self.pos)
4687 self.allocate_temp_result(code)
4688 if self.type.is_pyobject:
4689 self.release_errors()
4691 "%s = PyDict_New(); %s" % (
4693 code.error_goto_if_null(self.result(), self.pos)))
4694 code.put_gotref(self.py_result())
4695 for item in self.key_value_pairs:
4696 item.generate_evaluation_code(code)
4697 if self.type.is_pyobject:
4698 code.put_error_if_neg(self.pos,
4699 "PyDict_SetItem(%s, %s, %s)" % (
4701 item.key.py_result(),
4702 item.value.py_result()))
4704 code.putln("%s.%s = %s;" % (
4707 item.value.result()))
4708 item.generate_disposal_code(code)
4709 item.free_temps(code)
4711 def annotate(self, code):
4712 for item in self.key_value_pairs:
4715 class DictItemNode(ExprNode):
4716 # Represents a single item in a DictNode
4720 subexprs = ['key', 'value']
4722 nogil_check = None # Parent DictNode takes care of it
4724 def calculate_constant_result(self):
4725 self.constant_result = (
4726 self.key.constant_result, self.value.constant_result)
4728 def analyse_types(self, env):
4729 self.key.analyse_types(env)
4730 self.value.analyse_types(env)
4731 self.key = self.key.coerce_to_pyobject(env)
4732 self.value = self.value.coerce_to_pyobject(env)
4734 def generate_evaluation_code(self, code):
4735 self.key.generate_evaluation_code(code)
4736 self.value.generate_evaluation_code(code)
4738 def generate_disposal_code(self, code):
4739 self.key.generate_disposal_code(code)
4740 self.value.generate_disposal_code(code)
4742 def free_temps(self, code):
4743 self.key.free_temps(code)
4744 self.value.free_temps(code)
4747 return iter([self.key, self.value])
4749 class ModuleNameMixin(object):
4750 def set_mod_name(self, env):
4751 self.module_name = env.global_scope().qualified_name
4753 def get_py_mod_name(self, code):
4754 return code.get_py_string_const(
4755 self.module_name, identifier=True)
4757 class ClassNode(ExprNode, ModuleNameMixin):
4758 # Helper class used in the implementation of Python
4759 # class definitions. Constructs a class object given
4760 # a name, tuple of bases and class dictionary.
4762 # name EncodedString Name of the class
4763 # bases ExprNode Base class tuple
4764 # dict ExprNode Class dict (not owned by this node)
4765 # doc ExprNode or None Doc string
4766 # module_name EncodedString Name of defining module
4768 subexprs = ['bases', 'doc']
4770 def analyse_types(self, env):
4771 self.bases.analyse_types(env)
4773 self.doc.analyse_types(env)
4774 self.doc = self.doc.coerce_to_pyobject(env)
4775 self.type = py_object_type
4777 env.use_utility_code(create_class_utility_code);
4778 #TODO(craig,haoyu) This should be moved to a better place
4779 self.set_mod_name(env)
4781 def may_be_none(self):
4784 gil_message = "Constructing Python class"
4786 def generate_result_code(self, code):
4787 cname = code.intern_identifier(self.name)
4790 code.put_error_if_neg(self.pos,
4791 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4792 self.dict.py_result(),
4793 self.doc.py_result()))
4794 py_mod_name = self.get_py_mod_name(code)
4796 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4798 self.bases.py_result(),
4799 self.dict.py_result(),
4802 code.error_goto_if_null(self.result(), self.pos)))
4803 code.put_gotref(self.py_result())
4806 class Py3ClassNode(ExprNode):
4807 # Helper class used in the implementation of Python3+
4808 # class definitions. Constructs a class object given
4809 # a name, tuple of bases and class dictionary.
4811 # name EncodedString Name of the class
4812 # dict ExprNode Class dict (not owned by this node)
4813 # module_name EncodedString Name of defining module
4817 def analyse_types(self, env):
4818 self.type = py_object_type
4821 def may_be_none(self):
4824 gil_message = "Constructing Python class"
4826 def generate_result_code(self, code):
4827 code.globalstate.use_utility_code(create_py3class_utility_code)
4828 cname = code.intern_identifier(self.name)
4830 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4832 self.metaclass.result(),
4834 self.bases.py_result(),
4835 self.dict.py_result(),
4836 self.mkw.py_result(),
4837 code.error_goto_if_null(self.result(), self.pos)))
4838 code.put_gotref(self.py_result())
4840 class KeywordArgsNode(ExprNode):
4841 # Helper class for keyword arguments
4843 # keyword_args ExprNode or None Keyword arguments
4844 # starstar_arg ExprNode or None Extra arguments
4846 subexprs = ['keyword_args', 'starstar_arg']
4848 def analyse_types(self, env):
4849 if self.keyword_args:
4850 self.keyword_args.analyse_types(env)
4851 if self.starstar_arg:
4852 self.starstar_arg.analyse_types(env)
4853 # make sure we have a Python object as **kwargs mapping
4854 self.starstar_arg = \
4855 self.starstar_arg.coerce_to_pyobject(env)
4856 self.type = py_object_type
4859 gil_message = "Constructing Keyword Args"
4861 def generate_result_code(self, code):
4862 if self.keyword_args and self.starstar_arg:
4863 code.put_error_if_neg(self.pos,
4864 "PyDict_Update(%s, %s)" % (
4865 self.keyword_args.py_result(),
4866 self.starstar_arg.py_result()))
4867 if self.keyword_args:
4868 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4869 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4870 elif self.starstar_arg:
4872 "%s = PyDict_Copy(%s); %s" % (
4874 self.starstar_arg.py_result(),
4875 code.error_goto_if_null(self.result(), self.pos)))
4876 code.put_gotref(self.py_result())
4879 "%s = PyDict_New(); %s" % (
4881 code.error_goto_if_null(self.result(), self.pos)))
4882 code.put_gotref(self.py_result())
4884 class PyClassMetaclassNode(ExprNode):
4885 # Helper class holds Python3 metaclass object
4887 # bases ExprNode Base class tuple (not owned by this node)
4888 # mkw ExprNode Class keyword arguments (not owned by this node)
4892 def analyse_types(self, env):
4893 self.type = py_object_type
4896 def may_be_none(self):
4899 def generate_result_code(self, code):
4901 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4903 self.bases.result(),
4905 code.error_goto_if_null(self.result(), self.pos)))
4906 code.put_gotref(self.py_result())
4908 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4909 # Helper class holds Python3 namespace object
4911 # All this are not owned by this node
4912 # metaclass ExprNode Metaclass object
4913 # bases ExprNode Base class tuple
4914 # mkw ExprNode Class keyword arguments
4915 # doc ExprNode or None Doc string (owned)
4919 def analyse_types(self, env):
4920 self.bases.analyse_types(env)
4922 self.doc.analyse_types(env)
4923 self.doc = self.doc.coerce_to_pyobject(env)
4924 self.type = py_object_type
4926 #TODO(craig,haoyu) This should be moved to a better place
4927 self.set_mod_name(env)
4929 def may_be_none(self):
4932 def generate_result_code(self, code):
4933 cname = code.intern_identifier(self.name)
4934 py_mod_name = self.get_py_mod_name(code)
4936 doc_code = self.doc.result()
4938 doc_code = '(PyObject *) NULL'
4940 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4942 self.metaclass.result(),
4943 self.bases.result(),
4948 code.error_goto_if_null(self.result(), self.pos)))
4949 code.put_gotref(self.py_result())
4951 class BoundMethodNode(ExprNode):
4952 # Helper class used in the implementation of Python
4953 # class definitions. Constructs an bound method
4954 # object from a class and a function.
4956 # function ExprNode Function object
4957 # self_object ExprNode self object
4959 subexprs = ['function']
4961 def analyse_types(self, env):
4962 self.function.analyse_types(env)
4963 self.type = py_object_type
4966 gil_message = "Constructing an bound method"
4968 def generate_result_code(self, code):
4970 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4972 self.function.py_result(),
4973 self.self_object.py_result(),
4974 self.self_object.py_result(),
4975 code.error_goto_if_null(self.result(), self.pos)))
4976 code.put_gotref(self.py_result())
4978 class UnboundMethodNode(ExprNode):
4979 # Helper class used in the implementation of Python
4980 # class definitions. Constructs an unbound method
4981 # object from a class and a function.
4983 # function ExprNode Function object
4985 type = py_object_type
4988 subexprs = ['function']
4990 def analyse_types(self, env):
4991 self.function.analyse_types(env)
4993 def may_be_none(self):
4996 gil_message = "Constructing an unbound method"
4998 def generate_result_code(self, code):
4999 class_cname = code.pyclass_stack[-1].classobj.result()
5001 "%s = PyMethod_New(%s, 0, %s); %s" % (
5003 self.function.py_result(),
5005 code.error_goto_if_null(self.result(), self.pos)))
5006 code.put_gotref(self.py_result())
5009 class PyCFunctionNode(ExprNode, ModuleNameMixin):
5010 # Helper class used in the implementation of Python
5011 # class definitions. Constructs a PyCFunction object
5012 # from a PyMethodDef struct.
5014 # pymethdef_cname string PyMethodDef structure
5015 # self_object ExprNode or None
5017 # module_name EncodedString Name of defining module
5023 type = py_object_type
5026 def analyse_types(self, env):
5028 env.use_utility_code(binding_cfunc_utility_code)
5030 #TODO(craig,haoyu) This should be moved to a better place
5031 self.set_mod_name(env)
5033 def may_be_none(self):
5036 gil_message = "Constructing Python function"
5038 def self_result_code(self):
5039 if self.self_object is None:
5040 self_result = "NULL"
5042 self_result = self.self_object.py_result()
5045 def generate_result_code(self, code):
5047 constructor = "%s_NewEx" % Naming.binding_cfunc
5049 constructor = "PyCFunction_NewEx"
5050 py_mod_name = self.get_py_mod_name(code)
5052 '%s = %s(&%s, %s, %s); %s' % (
5055 self.pymethdef_cname,
5056 self.self_result_code(),
5058 code.error_goto_if_null(self.result(), self.pos)))
5059 code.put_gotref(self.py_result())
5061 class InnerFunctionNode(PyCFunctionNode):
5062 # Special PyCFunctionNode that depends on a closure class
5066 needs_self_code = True
5068 def self_result_code(self):
5069 if self.needs_self_code:
5070 return "((PyObject*)%s)" % (Naming.cur_scope_cname)
5073 class LambdaNode(InnerFunctionNode):
5074 # Lambda expression node (only used as a function reference)
5076 # args [CArgDeclNode] formal arguments
5077 # star_arg PyArgDeclNode or None * argument
5078 # starstar_arg PyArgDeclNode or None ** argument
5079 # lambda_name string a module-globally unique lambda name
5080 # result_expr ExprNode
5081 # def_node DefNode the underlying function 'def' node
5083 child_attrs = ['def_node']
5086 name = StringEncoding.EncodedString('<lambda>')
5088 def analyse_declarations(self, env):
5089 self.def_node.analyse_declarations(env)
5090 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
5091 env.add_lambda_def(self.def_node)
5094 class GeneratorExpressionNode(LambdaNode):
5095 # A generator expression, e.g. (i for i in range(10))
5097 # Result is a generator.
5099 # loop ForStatNode the for-loop, containing a YieldExprNode
5100 # def_node DefNode the underlying generator 'def' node
5102 name = StringEncoding.EncodedString('genexpr')
5105 def analyse_declarations(self, env):
5106 self.def_node.no_assignment_synthesis = True
5107 self.def_node.analyse_declarations(env)
5108 env.add_lambda_def(self.def_node)
5110 def generate_result_code(self, code):
5112 '%s = %s(%s, NULL); %s' % (
5114 self.def_node.entry.func_cname,
5115 self.self_result_code(),
5116 code.error_goto_if_null(self.result(), self.pos)))
5117 code.put_gotref(self.py_result())
5120 class YieldExprNode(ExprNode):
5121 # Yield expression node
5123 # arg ExprNode the value to return from the generator
5124 # label_name string name of the C label used for this yield
5125 # label_num integer yield label number
5128 type = py_object_type
5131 def analyse_types(self, env):
5132 if not self.label_num:
5133 error(self.pos, "'yield' not supported here")
5135 if self.arg is not None:
5136 self.arg.analyse_types(env)
5137 if not self.arg.type.is_pyobject:
5138 self.arg = self.arg.coerce_to_pyobject(env)
5139 env.use_utility_code(generator_utility_code)
5141 def generate_evaluation_code(self, code):
5142 self.label_name = code.new_label('resume_from_yield')
5143 code.use_label(self.label_name)
5145 self.arg.generate_evaluation_code(code)
5146 self.arg.make_owned_reference(code)
5149 Naming.retval_cname,
5150 self.arg.result_as(py_object_type)))
5151 self.arg.generate_post_assignment_code(code)
5152 #self.arg.generate_disposal_code(code)
5153 self.arg.free_temps(code)
5155 code.put_init_to_py_none(Naming.retval_cname, py_object_type)
5157 code.funcstate.closure_temps.reset()
5158 for cname, type, manage_ref in code.funcstate.temps_in_use():
5159 save_cname = code.funcstate.closure_temps.allocate_temp(type)
5160 saved.append((cname, save_cname, type))
5161 if type.is_pyobject:
5162 code.put_xgiveref(cname)
5163 code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
5165 code.put_xgiveref(Naming.retval_cname)
5166 code.put_finish_refcount_context()
5167 code.putln("/* return from generator, yielding value */")
5168 code.putln("%s->%s.resume_label = %d;" % (Naming.cur_scope_cname, Naming.obj_base_cname, self.label_num))
5169 code.putln("return %s;" % Naming.retval_cname);
5170 code.put_label(self.label_name)
5171 for cname, save_cname, type in saved:
5172 code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
5173 if type.is_pyobject:
5174 code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
5175 if type.is_pyobject:
5176 code.put_xgotref(cname)
5177 if self.result_is_used:
5178 self.allocate_temp_result(code)
5179 code.putln('%s = %s; %s' %
5180 (self.result(), Naming.sent_value_cname,
5181 code.error_goto_if_null(self.result(), self.pos)))
5182 code.put_incref(self.result(), py_object_type)
5184 code.putln(code.error_goto_if_null(Naming.sent_value_cname, self.pos))
5186 #-------------------------------------------------------------------
5188 # Unary operator nodes
5190 #-------------------------------------------------------------------
5192 compile_time_unary_operators = {
5193 'not': operator.not_,
5199 class UnopNode(ExprNode):
5203 # Processing during analyse_expressions phase:
5205 # analyse_c_operation
5206 # Called when the operand is not a pyobject.
5207 # - Check operand type and coerce if needed.
5208 # - Determine result type and result code fragment.
5209 # - Allocate temporary for result if needed.
5211 subexprs = ['operand']
5214 def calculate_constant_result(self):
5215 func = compile_time_unary_operators[self.operator]
5216 self.constant_result = func(self.operand.constant_result)
5218 def compile_time_value(self, denv):
5219 func = compile_time_unary_operators.get(self.operator)
5222 "Unary '%s' not supported in compile-time expression"
5224 operand = self.operand.compile_time_value(denv)
5226 return func(operand)
5227 except Exception, e:
5228 self.compile_time_value_error(e)
5230 def infer_type(self, env):
5231 operand_type = self.operand.infer_type(env)
5232 if operand_type.is_pyobject:
5233 return py_object_type
5237 def analyse_types(self, env):
5238 self.operand.analyse_types(env)
5239 if self.is_py_operation():
5240 self.coerce_operand_to_pyobject(env)
5241 self.type = py_object_type
5243 elif self.is_cpp_operation():
5244 self.analyse_cpp_operation(env)
5246 self.analyse_c_operation(env)
5248 def check_const(self):
5249 return self.operand.check_const()
5251 def is_py_operation(self):
5252 return self.operand.type.is_pyobject
5254 def nogil_check(self, env):
5255 if self.is_py_operation():
5258 def is_cpp_operation(self):
5259 type = self.operand.type
5260 return type.is_cpp_class
5262 def coerce_operand_to_pyobject(self, env):
5263 self.operand = self.operand.coerce_to_pyobject(env)
5265 def generate_result_code(self, code):
5266 if self.operand.type.is_pyobject:
5267 self.generate_py_operation_code(code)
5269 def generate_py_operation_code(self, code):
5270 function = self.py_operation_function()
5272 "%s = %s(%s); %s" % (
5275 self.operand.py_result(),
5276 code.error_goto_if_null(self.result(), self.pos)))
5277 code.put_gotref(self.py_result())
5279 def type_error(self):
5280 if not self.operand.type.is_error:
5281 error(self.pos, "Invalid operand type for '%s' (%s)" %
5282 (self.operator, self.operand.type))
5283 self.type = PyrexTypes.error_type
5285 def analyse_cpp_operation(self, env):
5286 type = self.operand.type
5288 type = type.base_type
5289 function = type.scope.lookup("operator%s" % self.operator)
5291 error(self.pos, "'%s' operator not defined for %s"
5292 % (self.operator, type))
5295 func_type = function.type
5296 if func_type.is_ptr:
5297 func_type = func_type.base_type
5298 self.type = func_type.return_type
5301 class NotNode(ExprNode):
5306 type = PyrexTypes.c_bint_type
5308 subexprs = ['operand']
5310 def calculate_constant_result(self):
5311 self.constant_result = not self.operand.constant_result
5313 def compile_time_value(self, denv):
5314 operand = self.operand.compile_time_value(denv)
5317 except Exception, e:
5318 self.compile_time_value_error(e)
5320 def infer_type(self, env):
5321 return PyrexTypes.c_bint_type
5323 def analyse_types(self, env):
5324 self.operand.analyse_types(env)
5325 self.operand = self.operand.coerce_to_boolean(env)
5327 def calculate_result_code(self):
5328 return "(!%s)" % self.operand.result()
5330 def generate_result_code(self, code):
5334 class UnaryPlusNode(UnopNode):
5335 # unary '+' operator
5339 def analyse_c_operation(self, env):
5340 self.type = PyrexTypes.widest_numeric_type(
5341 self.operand.type, PyrexTypes.c_int_type)
5343 def py_operation_function(self):
5344 return "PyNumber_Positive"
5346 def calculate_result_code(self):
5347 if self.is_cpp_operation():
5348 return "(+%s)" % self.operand.result()
5350 return self.operand.result()
5353 class UnaryMinusNode(UnopNode):
5354 # unary '-' operator
5358 def analyse_c_operation(self, env):
5359 if self.operand.type.is_numeric:
5360 self.type = PyrexTypes.widest_numeric_type(
5361 self.operand.type, PyrexTypes.c_int_type)
5364 if self.type.is_complex:
5367 def py_operation_function(self):
5368 return "PyNumber_Negative"
5370 def calculate_result_code(self):
5372 return "(-%s)" % self.operand.result()
5374 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5376 def get_constant_c_result_code(self):
5377 value = self.operand.get_constant_c_result_code()
5379 return "(-%s)" % (value)
5381 class TildeNode(UnopNode):
5382 # unary '~' operator
5384 def analyse_c_operation(self, env):
5385 if self.operand.type.is_int:
5386 self.type = PyrexTypes.widest_numeric_type(
5387 self.operand.type, PyrexTypes.c_int_type)
5391 def py_operation_function(self):
5392 return "PyNumber_Invert"
5394 def calculate_result_code(self):
5395 return "(~%s)" % self.operand.result()
5398 class CUnopNode(UnopNode):
5400 def is_py_operation(self):
5403 class DereferenceNode(CUnopNode):
5408 def analyse_c_operation(self, env):
5409 if self.operand.type.is_ptr:
5410 self.type = self.operand.type.base_type
5414 def calculate_result_code(self):
5415 return "(*%s)" % self.operand.result()
5418 class DecrementIncrementNode(CUnopNode):
5419 # unary ++/-- operator
5421 def analyse_c_operation(self, env):
5422 if self.operand.type.is_numeric:
5423 self.type = PyrexTypes.widest_numeric_type(
5424 self.operand.type, PyrexTypes.c_int_type)
5425 elif self.operand.type.is_ptr:
5426 self.type = self.operand.type
5430 def calculate_result_code(self):
5432 return "(%s%s)" % (self.operator, self.operand.result())
5434 return "(%s%s)" % (self.operand.result(), self.operator)
5436 def inc_dec_constructor(is_prefix, operator):
5437 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5440 class AmpersandNode(ExprNode):
5441 # The C address-of operator.
5445 subexprs = ['operand']
5447 def infer_type(self, env):
5448 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5450 def analyse_types(self, env):
5451 self.operand.analyse_types(env)
5452 argtype = self.operand.type
5453 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5454 self.error("Taking address of non-lvalue")
5456 if argtype.is_pyobject:
5457 self.error("Cannot take address of Python variable")
5459 self.type = PyrexTypes.c_ptr_type(argtype)
5461 def check_const(self):
5462 return self.operand.check_const_addr()
5464 def error(self, mess):
5465 error(self.pos, mess)
5466 self.type = PyrexTypes.error_type
5467 self.result_code = "<error>"
5469 def calculate_result_code(self):
5470 return "(&%s)" % self.operand.result()
5472 def generate_result_code(self, code):
5476 unop_node_classes = {
5478 "-": UnaryMinusNode,
5482 def unop_node(pos, operator, operand):
5483 # Construct unnop node of appropriate class for
5485 if isinstance(operand, IntNode) and operator == '-':
5486 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5487 elif isinstance(operand, UnopNode) and operand.operator == operator:
5488 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5489 return unop_node_classes[operator](pos,
5490 operator = operator,
5494 class TypecastNode(ExprNode):
5498 # base_type CBaseTypeNode
5499 # declarator CDeclaratorNode
5501 # If used from a transform, one can if wanted specify the attribute
5502 # "type" directly and leave base_type and declarator to None
5504 subexprs = ['operand']
5505 base_type = declarator = type = None
5507 def type_dependencies(self, env):
5510 def infer_type(self, env):
5511 if self.type is None:
5512 base_type = self.base_type.analyse(env)
5513 _, self.type = self.declarator.analyse(base_type, env)
5516 def analyse_types(self, env):
5517 if self.type is None:
5518 base_type = self.base_type.analyse(env)
5519 _, self.type = self.declarator.analyse(base_type, env)
5520 if self.type.is_cfunction:
5522 "Cannot cast to a function type")
5523 self.type = PyrexTypes.error_type
5524 self.operand.analyse_types(env)
5525 to_py = self.type.is_pyobject
5526 from_py = self.operand.type.is_pyobject
5527 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5528 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5529 if to_py and not from_py:
5530 if self.type is bytes_type and self.operand.type.is_int:
5531 # FIXME: the type cast node isn't needed in this case
5532 # and can be dropped once analyse_types() can return a
5534 self.operand = CoerceIntToBytesNode(self.operand, env)
5535 elif self.operand.type.can_coerce_to_pyobject(env):
5536 self.result_ctype = py_object_type
5537 self.operand = self.operand.coerce_to_pyobject(env)
5539 if self.operand.type.is_ptr:
5540 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5541 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5543 # Should this be an error?
5544 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5545 self.operand = self.operand.coerce_to_simple(env)
5546 elif from_py and not to_py:
5547 if self.type.create_from_py_utility_code(env):
5548 self.operand = self.operand.coerce_to(self.type, env)
5549 elif self.type.is_ptr:
5550 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5551 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5553 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5554 elif from_py and to_py:
5555 if self.typecheck and self.type.is_extension_type:
5556 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5557 elif self.type.is_complex and self.operand.type.is_complex:
5558 self.operand = self.operand.coerce_to_simple(env)
5560 def is_simple(self):
5561 # either temp or a C cast => no side effects
5564 def nonlocally_immutable(self):
5565 return self.operand.nonlocally_immutable()
5567 def nogil_check(self, env):
5568 if self.type and self.type.is_pyobject and self.is_temp:
5571 def check_const(self):
5572 return self.operand.check_const()
5574 def calculate_constant_result(self):
5575 # we usually do not know the result of a type cast at code
5579 def calculate_result_code(self):
5580 if self.type.is_complex:
5581 operand_result = self.operand.result()
5582 if self.operand.type.is_complex:
5583 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5584 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5586 real_part = self.type.real_type.cast_code(operand_result)
5588 return "%s(%s, %s)" % (
5589 self.type.from_parts,
5593 return self.type.cast_code(self.operand.result())
5595 def get_constant_c_result_code(self):
5596 operand_result = self.operand.get_constant_c_result_code()
5598 return self.type.cast_code(operand_result)
5600 def result_as(self, type):
5601 if self.type.is_pyobject and not self.is_temp:
5602 # Optimise away some unnecessary casting
5603 return self.operand.result_as(type)
5605 return ExprNode.result_as(self, type)
5607 def generate_result_code(self, code):
5610 "%s = (PyObject *)%s;" % (
5612 self.operand.result()))
5613 code.put_incref(self.result(), self.ctype())
5616 class SizeofNode(ExprNode):
5617 # Abstract base class for sizeof(x) expression nodes.
5619 type = PyrexTypes.c_size_t_type
5621 def check_const(self):
5624 def generate_result_code(self, code):
5628 class SizeofTypeNode(SizeofNode):
5629 # C sizeof function applied to a type
5631 # base_type CBaseTypeNode
5632 # declarator CDeclaratorNode
5637 def analyse_types(self, env):
5638 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5639 # this could be better handled by more uniformly treating types as runtime-available objects
5640 if 0 and self.base_type.module_path:
5641 path = self.base_type.module_path
5642 obj = env.lookup(path[0])
5643 if obj.as_module is None:
5644 operand = NameNode(pos=self.pos, name=path[0])
5645 for attr in path[1:]:
5646 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5647 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5648 self.operand = operand
5649 self.__class__ = SizeofVarNode
5650 self.analyse_types(env)
5652 if self.arg_type is None:
5653 base_type = self.base_type.analyse(env)
5654 _, arg_type = self.declarator.analyse(base_type, env)
5655 self.arg_type = arg_type
5658 def check_type(self):
5659 arg_type = self.arg_type
5660 if arg_type.is_pyobject and not arg_type.is_extension_type:
5661 error(self.pos, "Cannot take sizeof Python object")
5662 elif arg_type.is_void:
5663 error(self.pos, "Cannot take sizeof void")
5664 elif not arg_type.is_complete():
5665 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5667 def calculate_result_code(self):
5668 if self.arg_type.is_extension_type:
5669 # the size of the pointer is boring
5670 # we want the size of the actual struct
5671 arg_code = self.arg_type.declaration_code("", deref=1)
5673 arg_code = self.arg_type.declaration_code("")
5674 return "(sizeof(%s))" % arg_code
5677 class SizeofVarNode(SizeofNode):
5678 # C sizeof function applied to a variable
5682 subexprs = ['operand']
5684 def analyse_types(self, env):
5685 # We may actually be looking at a type rather than a variable...
5686 # If we are, traditional analysis would fail...
5687 operand_as_type = self.operand.analyse_as_type(env)
5689 self.arg_type = operand_as_type
5690 self.__class__ = SizeofTypeNode
5693 self.operand.analyse_types(env)
5695 def calculate_result_code(self):
5696 return "(sizeof(%s))" % self.operand.result()
5698 def generate_result_code(self, code):
5701 class TypeofNode(ExprNode):
5702 # Compile-time type of an expression, as a string.
5705 # literal StringNode # internal
5708 type = py_object_type
5710 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5712 def analyse_types(self, env):
5713 self.operand.analyse_types(env)
5714 self.literal = StringNode(
5715 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5716 self.literal.analyse_types(env)
5717 self.literal = self.literal.coerce_to_pyobject(env)
5719 def may_be_none(self):
5722 def generate_evaluation_code(self, code):
5723 self.literal.generate_evaluation_code(code)
5725 def calculate_result_code(self):
5726 return self.literal.calculate_result_code()
5728 #-------------------------------------------------------------------
5730 # Binary operator nodes
5732 #-------------------------------------------------------------------
5734 def _not_in(x, seq):
5737 compile_time_binary_operators = {
5745 'is_not': operator.is_not,
5748 '/': operator.truediv,
5749 '//': operator.floordiv,
5750 '<<': operator.lshift,
5755 '>>': operator.rshift,
5758 'in': operator.contains,
5762 def get_compile_time_binop(node):
5763 func = compile_time_binary_operators.get(node.operator)
5766 "Binary '%s' not supported in compile-time expression"
5770 class BinopNode(ExprNode):
5775 # Processing during analyse_expressions phase:
5777 # analyse_c_operation
5778 # Called when neither operand is a pyobject.
5779 # - Check operand types and coerce if needed.
5780 # - Determine result type and result code fragment.
5781 # - Allocate temporary for result if needed.
5783 subexprs = ['operand1', 'operand2']
5786 def calculate_constant_result(self):
5787 func = compile_time_binary_operators[self.operator]
5788 self.constant_result = func(
5789 self.operand1.constant_result,
5790 self.operand2.constant_result)
5792 def compile_time_value(self, denv):
5793 func = get_compile_time_binop(self)
5794 operand1 = self.operand1.compile_time_value(denv)
5795 operand2 = self.operand2.compile_time_value(denv)
5797 return func(operand1, operand2)
5798 except Exception, e:
5799 self.compile_time_value_error(e)
5801 def infer_type(self, env):
5802 return self.result_type(self.operand1.infer_type(env),
5803 self.operand2.infer_type(env))
5805 def analyse_types(self, env):
5806 self.operand1.analyse_types(env)
5807 self.operand2.analyse_types(env)
5808 self.analyse_operation(env)
5810 def analyse_operation(self, env):
5811 if self.is_py_operation():
5812 self.coerce_operands_to_pyobjects(env)
5813 self.type = self.result_type(self.operand1.type,
5815 assert self.type.is_pyobject
5817 elif self.is_cpp_operation():
5818 self.analyse_cpp_operation(env)
5820 self.analyse_c_operation(env)
5822 def is_py_operation(self):
5823 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5825 def is_py_operation_types(self, type1, type2):
5826 return type1.is_pyobject or type2.is_pyobject
5828 def is_cpp_operation(self):
5829 return (self.operand1.type.is_cpp_class
5830 or self.operand2.type.is_cpp_class)
5832 def analyse_cpp_operation(self, env):
5833 type1 = self.operand1.type
5834 type2 = self.operand2.type
5835 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5839 func_type = entry.type
5840 if func_type.is_ptr:
5841 func_type = func_type.base_type
5842 if len(func_type.args) == 1:
5843 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5845 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5846 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5847 self.type = func_type.return_type
5849 def result_type(self, type1, type2):
5850 if self.is_py_operation_types(type1, type2):
5852 type2 = Builtin.bytes_type
5854 type1 = Builtin.bytes_type
5855 elif self.operator == '%' \
5856 and type1 in (Builtin.str_type, Builtin.unicode_type):
5857 # note that b'%s' % b'abc' doesn't work in Py3
5859 if type1.is_builtin_type:
5861 if self.operator in '**%+|&^':
5862 # FIXME: at least these operators should be safe - others?
5864 elif self.operator == '*':
5865 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5867 # multiplication of containers/numbers with an
5868 # integer value always (?) returns the same type
5871 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5872 # multiplication of containers/numbers with an
5873 # integer value always (?) returns the same type
5875 return py_object_type
5877 return self.compute_c_result_type(type1, type2)
5879 def nogil_check(self, env):
5880 if self.is_py_operation():
5883 def coerce_operands_to_pyobjects(self, env):
5884 self.operand1 = self.operand1.coerce_to_pyobject(env)
5885 self.operand2 = self.operand2.coerce_to_pyobject(env)
5887 def check_const(self):
5888 return self.operand1.check_const() and self.operand2.check_const()
5890 def generate_result_code(self, code):
5891 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5892 if self.operand1.type.is_pyobject:
5893 function = self.py_operation_function()
5894 if self.operator == '**':
5895 extra_args = ", Py_None"
5899 "%s = %s(%s, %s%s); %s" % (
5902 self.operand1.py_result(),
5903 self.operand2.py_result(),
5905 code.error_goto_if_null(self.result(), self.pos)))
5906 code.put_gotref(self.py_result())
5908 def type_error(self):
5909 if not (self.operand1.type.is_error
5910 or self.operand2.type.is_error):
5911 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5912 (self.operator, self.operand1.type,
5913 self.operand2.type))
5914 self.type = PyrexTypes.error_type
5917 class CBinopNode(BinopNode):
5919 def analyse_types(self, env):
5920 BinopNode.analyse_types(self, env)
5921 if self.is_py_operation():
5922 self.type = PyrexTypes.error_type
5924 def py_operation_function():
5927 def calculate_result_code(self):
5928 return "(%s %s %s)" % (
5929 self.operand1.result(),
5931 self.operand2.result())
5934 def c_binop_constructor(operator):
5935 def make_binop_node(pos, **operands):
5936 return CBinopNode(pos, operator=operator, **operands)
5937 return make_binop_node
5939 class NumBinopNode(BinopNode):
5940 # Binary operation taking numeric arguments.
5944 def analyse_c_operation(self, env):
5945 type1 = self.operand1.type
5946 type2 = self.operand2.type
5947 self.type = self.compute_c_result_type(type1, type2)
5951 if self.type.is_complex:
5953 if not self.infix or (type1.is_numeric and type2.is_numeric):
5954 self.operand1 = self.operand1.coerce_to(self.type, env)
5955 self.operand2 = self.operand2.coerce_to(self.type, env)
5957 def compute_c_result_type(self, type1, type2):
5958 if self.c_types_okay(type1, type2):
5959 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5960 if widest_type is PyrexTypes.c_bint_type:
5961 if self.operator not in '|^&':
5962 # False + False == 0 # not False!
5963 widest_type = PyrexTypes.c_int_type
5965 widest_type = PyrexTypes.widest_numeric_type(
5966 widest_type, PyrexTypes.c_int_type)
5971 def get_constant_c_result_code(self):
5972 value1 = self.operand1.get_constant_c_result_code()
5973 value2 = self.operand2.get_constant_c_result_code()
5974 if value1 and value2:
5975 return "(%s %s %s)" % (value1, self.operator, value2)
5979 def c_types_okay(self, type1, type2):
5980 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5981 return (type1.is_numeric or type1.is_enum) \
5982 and (type2.is_numeric or type2.is_enum)
5984 def calculate_result_code(self):
5986 return "(%s %s %s)" % (
5987 self.operand1.result(),
5989 self.operand2.result())
5991 func = self.type.binary_op(self.operator)
5993 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5994 return "%s(%s, %s)" % (
5996 self.operand1.result(),
5997 self.operand2.result())
5999 def is_py_operation_types(self, type1, type2):
6000 return (type1.is_unicode_char or
6001 type2.is_unicode_char or
6002 BinopNode.is_py_operation_types(self, type1, type2))
6004 def py_operation_function(self):
6005 fuction = self.py_functions[self.operator]
6007 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
6012 "^": "PyNumber_Xor",
6013 "&": "PyNumber_And",
6014 "<<": "PyNumber_Lshift",
6015 ">>": "PyNumber_Rshift",
6016 "+": "PyNumber_Add",
6017 "-": "PyNumber_Subtract",
6018 "*": "PyNumber_Multiply",
6019 "/": "__Pyx_PyNumber_Divide",
6020 "//": "PyNumber_FloorDivide",
6021 "%": "PyNumber_Remainder",
6022 "**": "PyNumber_Power"
6025 class IntBinopNode(NumBinopNode):
6026 # Binary operation taking integer arguments.
6028 def c_types_okay(self, type1, type2):
6029 #print "IntBinopNode.c_types_okay:", type1, type2 ###
6030 return (type1.is_int or type1.is_enum) \
6031 and (type2.is_int or type2.is_enum)
6034 class AddNode(NumBinopNode):
6037 def is_py_operation_types(self, type1, type2):
6038 if type1.is_string and type2.is_string:
6041 return NumBinopNode.is_py_operation_types(self, type1, type2)
6043 def compute_c_result_type(self, type1, type2):
6044 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
6045 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
6047 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
6050 return NumBinopNode.compute_c_result_type(
6054 class SubNode(NumBinopNode):
6057 def compute_c_result_type(self, type1, type2):
6058 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
6060 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
6061 return PyrexTypes.c_int_type
6063 return NumBinopNode.compute_c_result_type(
6067 class MulNode(NumBinopNode):
6070 def is_py_operation_types(self, type1, type2):
6071 if (type1.is_string and type2.is_int) \
6072 or (type2.is_string and type1.is_int):
6075 return NumBinopNode.is_py_operation_types(self, type1, type2)
6078 class DivNode(NumBinopNode):
6079 # '/' or '//' operator.
6082 truedivision = None # == "unknown" if operator == '/'
6083 ctruedivision = False
6084 cdivision_warnings = False
6085 zerodivision_check = None
6087 def find_compile_time_binary_operator(self, op1, op2):
6088 func = compile_time_binary_operators[self.operator]
6089 if self.operator == '/' and self.truedivision is None:
6090 # => true div for floats, floor div for integers
6091 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
6092 func = compile_time_binary_operators['//']
6095 def calculate_constant_result(self):
6096 op1 = self.operand1.constant_result
6097 op2 = self.operand2.constant_result
6098 func = self.find_compile_time_binary_operator(op1, op2)
6099 self.constant_result = func(
6100 self.operand1.constant_result,
6101 self.operand2.constant_result)
6103 def compile_time_value(self, denv):
6104 operand1 = self.operand1.compile_time_value(denv)
6105 operand2 = self.operand2.compile_time_value(denv)
6107 func = self.find_compile_time_binary_operator(
6109 return func(operand1, operand2)
6110 except Exception, e:
6111 self.compile_time_value_error(e)
6113 def analyse_operation(self, env):
6114 if self.cdivision or env.directives['cdivision']:
6115 self.ctruedivision = False
6117 self.ctruedivision = self.truedivision
6118 NumBinopNode.analyse_operation(self, env)
6119 if self.is_cpp_operation():
6120 self.cdivision = True
6121 if not self.type.is_pyobject:
6122 self.zerodivision_check = (
6123 self.cdivision is None and not env.directives['cdivision']
6124 and (not self.operand2.has_constant_result() or
6125 self.operand2.constant_result == 0))
6126 if self.zerodivision_check or env.directives['cdivision_warnings']:
6127 # Need to check ahead of time to warn or raise zero division error
6128 self.operand1 = self.operand1.coerce_to_simple(env)
6129 self.operand2 = self.operand2.coerce_to_simple(env)
6131 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
6133 def compute_c_result_type(self, type1, type2):
6134 if self.operator == '/' and self.ctruedivision:
6135 if not type1.is_float and not type2.is_float:
6136 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
6137 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
6139 return NumBinopNode.compute_c_result_type(self, type1, type2)
6141 def zero_division_message(self):
6142 if self.type.is_int:
6143 return "integer division or modulo by zero"
6145 return "float division"
6147 def generate_evaluation_code(self, code):
6148 if not self.type.is_pyobject and not self.type.is_complex:
6149 if self.cdivision is None:
6150 self.cdivision = (code.globalstate.directives['cdivision']
6151 or not self.type.signed
6152 or self.type.is_float)
6153 if not self.cdivision:
6154 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
6155 NumBinopNode.generate_evaluation_code(self, code)
6156 self.generate_div_warning_code(code)
6158 def generate_div_warning_code(self, code):
6159 if not self.type.is_pyobject:
6160 if self.zerodivision_check:
6162 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
6164 zero_test = "%s == 0" % self.operand2.result()
6165 code.putln("if (unlikely(%s)) {" % zero_test)
6166 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
6167 code.putln(code.error_goto(self.pos))
6169 if self.type.is_int and self.type.signed and self.operator != '%':
6170 code.globalstate.use_utility_code(division_overflow_test_code)
6171 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6172 self.type.declaration_code(''),
6173 self.operand2.result(),
6174 self.operand1.result()))
6175 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
6176 code.putln(code.error_goto(self.pos))
6178 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6179 code.globalstate.use_utility_code(cdivision_warning_utility_code)
6180 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
6181 self.operand1.result(),
6182 self.operand2.result()))
6183 code.putln(code.set_error_info(self.pos));
6184 code.put("if (__Pyx_cdivision_warning()) ")
6185 code.put_goto(code.error_label)
6188 def calculate_result_code(self):
6189 if self.type.is_complex:
6190 return NumBinopNode.calculate_result_code(self)
6191 elif self.type.is_float and self.operator == '//':
6192 return "floor(%s / %s)" % (
6193 self.operand1.result(),
6194 self.operand2.result())
6195 elif self.truedivision or self.cdivision:
6196 op1 = self.operand1.result()
6197 op2 = self.operand2.result()
6198 if self.truedivision:
6199 if self.type != self.operand1.type:
6200 op1 = self.type.cast_code(op1)
6201 if self.type != self.operand2.type:
6202 op2 = self.type.cast_code(op2)
6203 return "(%s / %s)" % (op1, op2)
6205 return "__Pyx_div_%s(%s, %s)" % (
6206 self.type.specialization_name(),
6207 self.operand1.result(),
6208 self.operand2.result())
6211 class ModNode(DivNode):
6214 def is_py_operation_types(self, type1, type2):
6215 return (type1.is_string
6217 or NumBinopNode.is_py_operation_types(self, type1, type2))
6219 def zero_division_message(self):
6220 if self.type.is_int:
6221 return "integer division or modulo by zero"
6223 return "float divmod()"
6225 def generate_evaluation_code(self, code):
6226 if not self.type.is_pyobject:
6227 if self.cdivision is None:
6228 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
6229 if not self.cdivision:
6230 if self.type.is_int:
6231 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6233 code.globalstate.use_utility_code(
6234 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6235 NumBinopNode.generate_evaluation_code(self, code)
6236 self.generate_div_warning_code(code)
6238 def calculate_result_code(self):
6240 if self.type.is_float:
6241 return "fmod%s(%s, %s)" % (
6242 self.type.math_h_modifier,
6243 self.operand1.result(),
6244 self.operand2.result())
6246 return "(%s %% %s)" % (
6247 self.operand1.result(),
6248 self.operand2.result())
6250 return "__Pyx_mod_%s(%s, %s)" % (
6251 self.type.specialization_name(),
6252 self.operand1.result(),
6253 self.operand2.result())
6255 class PowNode(NumBinopNode):
6258 def analyse_c_operation(self, env):
6259 NumBinopNode.analyse_c_operation(self, env)
6260 if self.type.is_complex:
6261 if self.type.real_type.is_float:
6262 self.operand1 = self.operand1.coerce_to(self.type, env)
6263 self.operand2 = self.operand2.coerce_to(self.type, env)
6264 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
6266 error(self.pos, "complex int powers not supported")
6267 self.pow_func = "<error>"
6268 elif self.type.is_float:
6269 self.pow_func = "pow" + self.type.math_h_modifier
6271 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
6272 env.use_utility_code(
6273 int_pow_utility_code.specialize(func_name=self.pow_func,
6274 type=self.type.declaration_code('')))
6276 def calculate_result_code(self):
6277 # Work around MSVC overloading ambiguity.
6278 def typecast(operand):
6279 if self.type == operand.type:
6280 return operand.result()
6282 return self.type.cast_code(operand.result())
6283 return "%s(%s, %s)" % (
6285 typecast(self.operand1),
6286 typecast(self.operand2))
6289 # Note: This class is temporarily "shut down" into an ineffective temp
6292 # More sophisticated temp reuse was going on before, one could have a
6293 # look at adding this again after /all/ classes are converted to the
6294 # new temp scheme. (The temp juggling cannot work otherwise).
6295 class BoolBinopNode(ExprNode):
6296 # Short-circuiting boolean operation.
6302 subexprs = ['operand1', 'operand2']
6304 def infer_type(self, env):
6305 type1 = self.operand1.infer_type(env)
6306 type2 = self.operand2.infer_type(env)
6307 return PyrexTypes.independent_spanning_type(type1, type2)
6309 def may_be_none(self):
6310 if self.operator == 'or':
6311 return self.operand2.may_be_none()
6313 return self.operand1.may_be_none() or self.operand2.may_be_none()
6315 def calculate_constant_result(self):
6316 if self.operator == 'and':
6317 self.constant_result = \
6318 self.operand1.constant_result and \
6319 self.operand2.constant_result
6321 self.constant_result = \
6322 self.operand1.constant_result or \
6323 self.operand2.constant_result
6325 def compile_time_value(self, denv):
6326 if self.operator == 'and':
6327 return self.operand1.compile_time_value(denv) \
6328 and self.operand2.compile_time_value(denv)
6330 return self.operand1.compile_time_value(denv) \
6331 or self.operand2.compile_time_value(denv)
6333 def coerce_to_boolean(self, env):
6334 return BoolBinopNode(
6336 operator = self.operator,
6337 operand1 = self.operand1.coerce_to_boolean(env),
6338 operand2 = self.operand2.coerce_to_boolean(env),
6339 type = PyrexTypes.c_bint_type,
6340 is_temp = self.is_temp)
6342 def analyse_types(self, env):
6343 self.operand1.analyse_types(env)
6344 self.operand2.analyse_types(env)
6345 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6346 self.operand1 = self.operand1.coerce_to(self.type, env)
6347 self.operand2 = self.operand2.coerce_to(self.type, env)
6349 # For what we're about to do, it's vital that
6350 # both operands be temp nodes.
6351 self.operand1 = self.operand1.coerce_to_simple(env)
6352 self.operand2 = self.operand2.coerce_to_simple(env)
6355 gil_message = "Truth-testing Python object"
6357 def check_const(self):
6358 return self.operand1.check_const() and self.operand2.check_const()
6360 def generate_evaluation_code(self, code):
6361 code.mark_pos(self.pos)
6362 self.operand1.generate_evaluation_code(code)
6363 test_result, uses_temp = self.generate_operand1_test(code)
6364 if self.operator == 'and':
6373 code.funcstate.release_temp(test_result)
6374 self.operand1.generate_disposal_code(code)
6375 self.operand2.generate_evaluation_code(code)
6376 self.allocate_temp_result(code)
6377 self.operand2.make_owned_reference(code)
6378 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6379 self.operand2.generate_post_assignment_code(code)
6380 self.operand2.free_temps(code)
6381 code.putln("} else {")
6382 self.operand1.make_owned_reference(code)
6383 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6384 self.operand1.generate_post_assignment_code(code)
6385 self.operand1.free_temps(code)
6388 def generate_operand1_test(self, code):
6389 # Generate code to test the truth of the first operand.
6390 if self.type.is_pyobject:
6391 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6394 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6396 self.operand1.py_result(),
6397 code.error_goto_if_neg(test_result, self.pos)))
6399 test_result = self.operand1.result()
6400 return (test_result, self.type.is_pyobject)
6403 class CondExprNode(ExprNode):
6404 # Short-circuiting conditional expression.
6408 # false_val ExprNode
6413 subexprs = ['test', 'true_val', 'false_val']
6415 def type_dependencies(self, env):
6416 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6418 def infer_type(self, env):
6419 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6420 self.false_val.infer_type(env))
6422 def calculate_constant_result(self):
6423 if self.test.constant_result:
6424 self.constant_result = self.true_val.constant_result
6426 self.constant_result = self.false_val.constant_result
6428 def analyse_types(self, env):
6429 self.test.analyse_types(env)
6430 self.test = self.test.coerce_to_boolean(env)
6431 self.true_val.analyse_types(env)
6432 self.false_val.analyse_types(env)
6433 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6434 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6435 self.true_val = self.true_val.coerce_to(self.type, env)
6436 self.false_val = self.false_val.coerce_to(self.type, env)
6438 if self.type == PyrexTypes.error_type:
6441 def type_error(self):
6442 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6443 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6444 (self.true_val.type, self.false_val.type))
6445 self.type = PyrexTypes.error_type
6447 def check_const(self):
6448 return (self.test.check_const()
6449 and self.true_val.check_const()
6450 and self.false_val.check_const())
6452 def generate_evaluation_code(self, code):
6453 # Because subexprs may not be evaluated we can use a more optimal
6454 # subexpr allocation strategy than the default, so override evaluation_code.
6456 code.mark_pos(self.pos)
6457 self.allocate_temp_result(code)
6458 self.test.generate_evaluation_code(code)
6459 code.putln("if (%s) {" % self.test.result() )
6460 self.eval_and_get(code, self.true_val)
6461 code.putln("} else {")
6462 self.eval_and_get(code, self.false_val)
6464 self.test.generate_disposal_code(code)
6465 self.test.free_temps(code)
6467 def eval_and_get(self, code, expr):
6468 expr.generate_evaluation_code(code)
6469 expr.make_owned_reference(code)
6470 code.putln("%s = %s;" % (self.result(), expr.result()))
6471 expr.generate_post_assignment_code(code)
6472 expr.free_temps(code)
6474 richcmp_constants = {
6484 class CmpNode(object):
6485 # Mixin class containing code common to PrimaryCmpNodes
6486 # and CascadedCmpNodes.
6488 special_bool_cmp_function = None
6490 def infer_type(self, env):
6491 # TODO: Actually implement this (after merging with -unstable).
6492 return py_object_type
6494 def calculate_cascaded_constant_result(self, operand1_result):
6495 func = compile_time_binary_operators[self.operator]
6496 operand2_result = self.operand2.constant_result
6497 result = func(operand1_result, operand2_result)
6499 self.cascade.calculate_cascaded_constant_result(operand2_result)
6500 if self.cascade.constant_result:
6501 self.constant_result = result and self.cascade.constant_result
6503 self.constant_result = result
6505 def cascaded_compile_time_value(self, operand1, denv):
6506 func = get_compile_time_binop(self)
6507 operand2 = self.operand2.compile_time_value(denv)
6509 result = func(operand1, operand2)
6510 except Exception, e:
6511 self.compile_time_value_error(e)
6514 cascade = self.cascade
6516 # FIXME: I bet this must call cascaded_compile_time_value()
6517 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6520 def is_cpp_comparison(self):
6521 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6523 def find_common_int_type(self, env, op, operand1, operand2):
6524 # type1 != type2 and at least one of the types is not a C int
6525 type1 = operand1.type
6526 type2 = operand2.type
6527 type1_can_be_int = False
6528 type2_can_be_int = False
6530 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6531 and operand1.can_coerce_to_char_literal():
6532 type1_can_be_int = True
6533 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6534 and operand2.can_coerce_to_char_literal():
6535 type2_can_be_int = True
6538 if type2_can_be_int:
6541 if type1_can_be_int:
6543 elif type1_can_be_int:
6544 if type2_can_be_int:
6545 return PyrexTypes.c_uchar_type
6549 def find_common_type(self, env, op, operand1, common_type=None):
6550 operand2 = self.operand2
6551 type1 = operand1.type
6552 type2 = operand2.type
6554 new_common_type = None
6556 # catch general errors
6557 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6558 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6559 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6560 new_common_type = error_type
6562 # try to use numeric comparisons where possible
6563 elif type1.is_complex or type2.is_complex:
6564 if op not in ('==', '!='):
6565 error(self.pos, "complex types are unordered")
6566 new_common_type = error_type
6567 if type1.is_pyobject:
6568 new_common_type = type1
6569 elif type2.is_pyobject:
6570 new_common_type = type2
6572 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6573 elif type1.is_numeric and type2.is_numeric:
6574 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6575 elif common_type is None or not common_type.is_pyobject:
6576 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6578 if new_common_type is None:
6579 # fall back to generic type compatibility tests
6581 new_common_type = type1
6582 elif type1.is_pyobject or type2.is_pyobject:
6583 if type2.is_numeric or type2.is_string:
6584 if operand2.check_for_coercion_error(type1):
6585 new_common_type = error_type
6587 new_common_type = py_object_type
6588 elif type1.is_numeric or type1.is_string:
6589 if operand1.check_for_coercion_error(type2):
6590 new_common_type = error_type
6592 new_common_type = py_object_type
6593 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6594 new_common_type = py_object_type
6596 # one Python type and one non-Python type, not assignable
6597 self.invalid_types_error(operand1, op, operand2)
6598 new_common_type = error_type
6599 elif type1.assignable_from(type2):
6600 new_common_type = type1
6601 elif type2.assignable_from(type1):
6602 new_common_type = type2
6604 # C types that we couldn't handle up to here are an error
6605 self.invalid_types_error(operand1, op, operand2)
6606 new_common_type = error_type
6608 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6609 isinstance(operand2, BytesNode)):
6610 # special case when comparing char* to bytes literal: must
6611 # compare string values!
6612 new_common_type = bytes_type
6614 # recursively merge types
6615 if common_type is None or new_common_type.is_error:
6616 common_type = new_common_type
6618 # we could do a lot better by splitting the comparison
6619 # into a non-Python part and a Python part, but this is
6621 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6624 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6628 def invalid_types_error(self, operand1, op, operand2):
6629 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6630 (op, operand1.type, operand2.type))
6632 def is_python_comparison(self):
6633 return (not self.is_ptr_contains()
6634 and not self.is_c_string_contains()
6635 and (self.has_python_operands()
6636 or (self.cascade and self.cascade.is_python_comparison())
6637 or self.operator in ('in', 'not_in')))
6639 def coerce_operands_to(self, dst_type, env):
6640 operand2 = self.operand2
6641 if operand2.type != dst_type:
6642 self.operand2 = operand2.coerce_to(dst_type, env)
6644 self.cascade.coerce_operands_to(dst_type, env)
6646 def is_python_result(self):
6647 return ((self.has_python_operands() and
6648 self.special_bool_cmp_function is None and
6649 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6650 not self.is_c_string_contains() and
6651 not self.is_ptr_contains())
6652 or (self.cascade and self.cascade.is_python_result()))
6654 def is_c_string_contains(self):
6655 return self.operator in ('in', 'not_in') and \
6656 ((self.operand1.type.is_int
6657 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6658 (self.operand1.type.is_unicode_char
6659 and self.operand2.type is unicode_type))
6661 def is_ptr_contains(self):
6662 if self.operator in ('in', 'not_in'):
6663 container_type = self.operand2.type
6664 return (container_type.is_ptr or container_type.is_array) \
6665 and not container_type.is_string
6667 def find_special_bool_compare_function(self, env):
6668 if self.operator in ('==', '!='):
6669 type1, type2 = self.operand1.type, self.operand2.type
6670 if type1.is_pyobject and type2.is_pyobject:
6671 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6672 env.use_utility_code(pyunicode_equals_utility_code)
6673 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6677 def generate_operation_code(self, code, result_code,
6678 operand1, op , operand2):
6679 if self.type.is_pyobject:
6680 coerce_result = "__Pyx_PyBool_FromLong"
6687 if self.special_bool_cmp_function:
6688 if operand1.type.is_pyobject:
6689 result1 = operand1.py_result()
6691 result1 = operand1.result()
6692 if operand2.type.is_pyobject:
6693 result2 = operand2.py_result()
6695 result2 = operand2.result()
6696 code.putln("%s = %s(%s, %s, %s); %s" % (
6698 self.special_bool_cmp_function,
6701 richcmp_constants[op],
6702 code.error_goto_if_neg(result_code, self.pos)))
6703 elif op == 'in' or op == 'not_in':
6704 code.globalstate.use_utility_code(contains_utility_code)
6705 if self.type.is_pyobject:
6706 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6708 negation = "__Pyx_NegateNonNeg"
6709 if operand2.type is dict_type:
6710 method = "PyDict_Contains"
6712 method = "PySequence_Contains"
6713 if self.type.is_pyobject:
6714 error_clause = code.error_goto_if_null
6715 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6717 error_clause = code.error_goto_if_neg
6720 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6725 operand2.py_result(),
6726 operand1.py_result(),
6728 error_clause(result_code, self.pos)))
6729 elif (operand1.type.is_pyobject
6730 and op not in ('is', 'is_not')):
6731 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6733 operand1.py_result(),
6734 operand2.py_result(),
6735 richcmp_constants[op],
6736 code.error_goto_if_null(result_code, self.pos)))
6737 code.put_gotref(result_code)
6738 elif operand1.type.is_complex:
6743 code.putln("%s = %s(%s%s(%s, %s));" % (
6747 operand1.type.unary_op('eq'),
6751 type1 = operand1.type
6752 type2 = operand2.type
6753 if (type1.is_extension_type or type2.is_extension_type) \
6754 and not type1.same_as(type2):
6755 common_type = py_object_type
6756 elif type1.is_numeric:
6757 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6760 code1 = operand1.result_as(common_type)
6761 code2 = operand2.result_as(common_type)
6762 code.putln("%s = %s(%s %s %s);" % (
6766 self.c_operator(op),
6769 def c_operator(self, op):
6772 elif op == 'is_not':
6777 contains_utility_code = UtilityCode(
6779 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6780 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6781 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6785 char_in_bytes_utility_code = UtilityCode(
6787 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6790 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6791 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6792 char* char_start = PyBytes_AS_STRING(bytes);
6794 for (pos=char_start; pos < char_start+length; pos++) {
6795 if (character == pos[0]) return 1;
6801 pyunicode_in_unicode_utility_code = UtilityCode(
6803 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6806 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6808 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6809 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6811 for (pos=char_start; pos < char_start+length; pos++) {
6812 if (unlikely(character == pos[0])) return 1;
6818 py_ucs4_in_unicode_utility_code = UtilityCode(
6820 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
6822 # additionally handles surrogate pairs in 16bit Unicode builds
6824 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
6827 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6828 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6830 #if Py_UNICODE_SIZE == 2
6831 if (unlikely(character > 65535)) {
6832 Py_UNICODE high_val, low_val;
6833 high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
6834 low_val = (Py_UNICODE) (0xDC00 | ( (character - 0x10000) & ((1<<10)-1)));
6835 for (pos=char_start; pos < char_start+length-1; pos++) {
6836 if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
6841 uchar = (Py_UNICODE) character;
6842 for (pos=char_start; pos < char_start+length; pos++) {
6843 if (unlikely(uchar == pos[0])) return 1;
6849 pyunicode_equals_utility_code = UtilityCode(
6851 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6854 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6855 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6856 return (equals == Py_EQ);
6857 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6858 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6859 return (equals == Py_NE);
6860 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6861 if (equals == Py_EQ)
6862 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6864 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6866 int result = PyUnicode_Compare(s1, s2);
6867 if ((result == -1) && unlikely(PyErr_Occurred()))
6869 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6871 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6872 return (equals == Py_EQ);
6873 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6874 return (equals == Py_NE);
6875 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6876 return (equals == Py_NE);
6879 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6882 result = __Pyx_PyObject_IsTrue(py_result);
6883 Py_DECREF(py_result);
6890 class PrimaryCmpNode(ExprNode, CmpNode):
6891 # Non-cascaded comparison or first comparison of
6892 # a cascaded sequence.
6897 # cascade CascadedCmpNode
6899 # We don't use the subexprs mechanism, because
6900 # things here are too complicated for it to handle.
6901 # Instead, we override all the framework methods
6904 child_attrs = ['operand1', 'operand2', 'cascade']
6908 def infer_type(self, env):
6909 # TODO: Actually implement this (after merging with -unstable).
6910 return py_object_type
6912 def type_dependencies(self, env):
6915 def calculate_constant_result(self):
6916 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6918 def compile_time_value(self, denv):
6919 operand1 = self.operand1.compile_time_value(denv)
6920 return self.cascaded_compile_time_value(operand1, denv)
6922 def analyse_types(self, env):
6923 self.operand1.analyse_types(env)
6924 self.operand2.analyse_types(env)
6925 if self.is_cpp_comparison():
6926 self.analyse_cpp_comparison(env)
6928 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6931 self.cascade.analyse_types(env)
6933 if self.operator in ('in', 'not_in'):
6934 if self.is_c_string_contains():
6935 self.is_pycmp = False
6938 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6940 if self.operand2.type is unicode_type:
6941 self.uchar_test_type = PyrexTypes.widest_numeric_type(
6942 self.operand1.type, PyrexTypes.c_py_unicode_type)
6943 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
6944 env.use_utility_code(pyunicode_in_unicode_utility_code)
6946 env.use_utility_code(py_ucs4_in_unicode_utility_code)
6948 if self.operand1.type is PyrexTypes.c_uchar_type:
6949 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6950 if self.operand2.type is not bytes_type:
6951 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6952 env.use_utility_code(char_in_bytes_utility_code)
6953 self.operand2 = self.operand2.as_none_safe_node(
6954 "argument of type 'NoneType' is not iterable")
6955 elif self.is_ptr_contains():
6957 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6958 self.type = PyrexTypes.c_bint_type
6959 # Will be transformed by IterationTransform
6962 if self.operand2.type is dict_type:
6963 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6964 common_type = py_object_type
6965 self.is_pycmp = True
6966 elif self.find_special_bool_compare_function(env):
6967 common_type = None # if coercion needed, the method call above has already done it
6968 self.is_pycmp = False # result is bint
6969 self.is_temp = True # must check for error return
6971 common_type = self.find_common_type(env, self.operator, self.operand1)
6972 self.is_pycmp = common_type.is_pyobject
6974 if common_type is not None and not common_type.is_error:
6975 if self.operand1.type != common_type:
6976 self.operand1 = self.operand1.coerce_to(common_type, env)
6977 self.coerce_operands_to(common_type, env)
6980 self.operand2 = self.operand2.coerce_to_simple(env)
6981 self.cascade.coerce_cascaded_operands_to_temp(env)
6982 if self.is_python_result():
6983 self.type = PyrexTypes.py_object_type
6985 self.type = PyrexTypes.c_bint_type
6988 cdr.type = self.type
6990 if self.is_pycmp or self.cascade:
6993 def analyse_cpp_comparison(self, env):
6994 type1 = self.operand1.type
6995 type2 = self.operand2.type
6996 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6998 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6999 (self.operator, type1, type2))
7000 self.type = PyrexTypes.error_type
7001 self.result_code = "<error>"
7003 func_type = entry.type
7004 if func_type.is_ptr:
7005 func_type = func_type.base_type
7006 if len(func_type.args) == 1:
7007 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
7009 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
7010 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
7011 self.type = func_type.return_type
7013 def has_python_operands(self):
7014 return (self.operand1.type.is_pyobject
7015 or self.operand2.type.is_pyobject)
7017 def check_const(self):
7022 return self.operand1.check_const() and self.operand2.check_const()
7024 def calculate_result_code(self):
7025 if self.operand1.type.is_complex:
7026 if self.operator == "!=":
7030 return "(%s%s(%s, %s))" % (
7032 self.operand1.type.binary_op('=='),
7033 self.operand1.result(),
7034 self.operand2.result())
7035 elif self.is_c_string_contains():
7036 if self.operand2.type is unicode_type:
7037 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
7038 method = "__Pyx_UnicodeContains"
7040 method = "__Pyx_UnicodeContainsUCS4"
7042 method = "__Pyx_BytesContains"
7043 if self.operator == "not_in":
7047 return "(%s%s(%s, %s))" % (
7050 self.operand2.result(),
7051 self.operand1.result())
7053 return "(%s %s %s)" % (
7054 self.operand1.result(),
7055 self.c_operator(self.operator),
7056 self.operand2.result())
7058 def generate_evaluation_code(self, code):
7059 self.operand1.generate_evaluation_code(code)
7060 self.operand2.generate_evaluation_code(code)
7062 self.allocate_temp_result(code)
7063 self.generate_operation_code(code, self.result(),
7064 self.operand1, self.operator, self.operand2)
7066 self.cascade.generate_evaluation_code(code,
7067 self.result(), self.operand2)
7068 self.operand1.generate_disposal_code(code)
7069 self.operand1.free_temps(code)
7070 self.operand2.generate_disposal_code(code)
7071 self.operand2.free_temps(code)
7073 def generate_subexpr_disposal_code(self, code):
7074 # If this is called, it is a non-cascaded cmp,
7075 # so only need to dispose of the two main operands.
7076 self.operand1.generate_disposal_code(code)
7077 self.operand2.generate_disposal_code(code)
7079 def free_subexpr_temps(self, code):
7080 # If this is called, it is a non-cascaded cmp,
7081 # so only need to dispose of the two main operands.
7082 self.operand1.free_temps(code)
7083 self.operand2.free_temps(code)
7085 def annotate(self, code):
7086 self.operand1.annotate(code)
7087 self.operand2.annotate(code)
7089 self.cascade.annotate(code)
7092 class CascadedCmpNode(Node, CmpNode):
7093 # A CascadedCmpNode is not a complete expression node. It
7094 # hangs off the side of another comparison node, shares
7095 # its left operand with that node, and shares its result
7096 # with the PrimaryCmpNode at the head of the chain.
7100 # cascade CascadedCmpNode
7102 child_attrs = ['operand2', 'cascade']
7105 constant_result = constant_value_not_set # FIXME: where to calculate this?
7107 def infer_type(self, env):
7108 # TODO: Actually implement this (after merging with -unstable).
7109 return py_object_type
7111 def type_dependencies(self, env):
7114 def has_constant_result(self):
7115 return self.constant_result is not constant_value_not_set and \
7116 self.constant_result is not not_a_constant
7118 def analyse_types(self, env):
7119 self.operand2.analyse_types(env)
7121 self.cascade.analyse_types(env)
7123 def has_python_operands(self):
7124 return self.operand2.type.is_pyobject
7126 def coerce_operands_to_pyobjects(self, env):
7127 self.operand2 = self.operand2.coerce_to_pyobject(env)
7128 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
7129 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
7131 self.cascade.coerce_operands_to_pyobjects(env)
7133 def coerce_cascaded_operands_to_temp(self, env):
7135 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
7136 self.operand2 = self.operand2.coerce_to_simple(env)
7137 self.cascade.coerce_cascaded_operands_to_temp(env)
7139 def generate_evaluation_code(self, code, result, operand1):
7140 if self.type.is_pyobject:
7141 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
7142 code.put_decref(result, self.type)
7144 code.putln("if (%s) {" % result)
7145 self.operand2.generate_evaluation_code(code)
7146 self.generate_operation_code(code, result,
7147 operand1, self.operator, self.operand2)
7149 self.cascade.generate_evaluation_code(
7150 code, result, self.operand2)
7151 # Cascaded cmp result is always temp
7152 self.operand2.generate_disposal_code(code)
7153 self.operand2.free_temps(code)
7156 def annotate(self, code):
7157 self.operand2.annotate(code)
7159 self.cascade.annotate(code)
7162 binop_node_classes = {
7163 "or": BoolBinopNode,
7164 "and": BoolBinopNode,
7179 def binop_node(pos, operator, operand1, operand2, inplace=False):
7180 # Construct binop node of appropriate class for
7182 return binop_node_classes[operator](pos,
7183 operator = operator,
7184 operand1 = operand1,
7185 operand2 = operand2,
7188 #-------------------------------------------------------------------
7192 # Coercion nodes are special in that they are created during
7193 # the analyse_types phase of parse tree processing.
7194 # Their __init__ methods consequently incorporate some aspects
7197 #-------------------------------------------------------------------
7199 class CoercionNode(ExprNode):
7200 # Abstract base class for coercion nodes.
7202 # arg ExprNode node being coerced
7205 constant_result = not_a_constant
7207 def __init__(self, arg):
7211 print("%s Coercing %s" % (self, self.arg))
7213 def calculate_constant_result(self):
7214 # constant folding can break type coercion, so this is disabled
7217 def annotate(self, code):
7218 self.arg.annotate(code)
7219 if self.arg.type != self.type:
7220 file, line, col = self.pos
7221 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
7224 class CastNode(CoercionNode):
7225 # Wrap a node in a C type cast.
7227 def __init__(self, arg, new_type):
7228 CoercionNode.__init__(self, arg)
7229 self.type = new_type
7231 def may_be_none(self):
7232 return self.arg.may_be_none()
7234 def calculate_result_code(self):
7235 return self.arg.result_as(self.type)
7237 def generate_result_code(self, code):
7238 self.arg.generate_result_code(code)
7241 class PyTypeTestNode(CoercionNode):
7242 # This node is used to check that a generic Python
7243 # object is an instance of a particular extension type.
7244 # This node borrows the result of its argument node.
7246 def __init__(self, arg, dst_type, env, notnone=False):
7247 # The arg is know to be a Python object, and
7248 # the dst_type is known to be an extension type.
7249 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
7250 CoercionNode.__init__(self, arg)
7251 self.type = dst_type
7252 self.result_ctype = arg.ctype()
7253 self.notnone = notnone
7255 nogil_check = Node.gil_error
7256 gil_message = "Python type test"
7258 def analyse_types(self, env):
7261 def may_be_none(self):
7264 return self.arg.may_be_none()
7266 def is_simple(self):
7267 return self.arg.is_simple()
7269 def result_in_temp(self):
7270 return self.arg.result_in_temp()
7272 def is_ephemeral(self):
7273 return self.arg.is_ephemeral()
7275 def calculate_constant_result(self):
7279 def calculate_result_code(self):
7280 return self.arg.result()
7282 def generate_result_code(self, code):
7283 if self.type.typeobj_is_available():
7284 if not self.type.is_builtin_type:
7285 code.globalstate.use_utility_code(type_test_utility_code)
7288 self.type.type_test_code(self.arg.py_result(), self.notnone),
7289 code.error_goto(self.pos)))
7291 error(self.pos, "Cannot test type of extern C class "
7292 "without type object name specification")
7294 def generate_post_assignment_code(self, code):
7295 self.arg.generate_post_assignment_code(code)
7297 def free_temps(self, code):
7298 self.arg.free_temps(code)
7301 class NoneCheckNode(CoercionNode):
7302 # This node is used to check that a Python object is not None and
7303 # raises an appropriate exception (as specified by the creating
7306 def __init__(self, arg, exception_type_cname, exception_message):
7307 CoercionNode.__init__(self, arg)
7308 self.type = arg.type
7309 self.result_ctype = arg.ctype()
7310 self.exception_type_cname = exception_type_cname
7311 self.exception_message = exception_message
7313 def analyse_types(self, env):
7316 def may_be_none(self):
7319 def is_simple(self):
7320 return self.arg.is_simple()
7322 def result_in_temp(self):
7323 return self.arg.result_in_temp()
7325 def calculate_result_code(self):
7326 return self.arg.result()
7328 def generate_result_code(self, code):
7330 "if (unlikely(%s == Py_None)) {" % self.arg.result())
7331 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
7332 self.exception_type_cname,
7333 StringEncoding.escape_byte_string(
7334 self.exception_message.encode('UTF-8')),
7335 code.error_goto(self.pos)))
7338 def generate_post_assignment_code(self, code):
7339 self.arg.generate_post_assignment_code(code)
7341 def free_temps(self, code):
7342 self.arg.free_temps(code)
7345 class CoerceToPyTypeNode(CoercionNode):
7346 # This node is used to convert a C data type
7347 # to a Python object.
7349 type = py_object_type
7352 def __init__(self, arg, env, type=py_object_type):
7353 CoercionNode.__init__(self, arg)
7354 if not arg.type.create_to_py_utility_code(env):
7356 "Cannot convert '%s' to Python object" % arg.type)
7357 if type is py_object_type:
7358 # be specific about some known types
7359 if arg.type.is_string:
7360 self.type = bytes_type
7361 elif arg.type.is_unicode_char:
7362 self.type = unicode_type
7363 elif arg.type.is_complex:
7364 self.type = Builtin.complex_type
7366 # FIXME: check that the target type and the resulting type are compatible
7369 gil_message = "Converting to Python object"
7371 def may_be_none(self):
7372 # FIXME: is this always safe?
7375 def coerce_to_boolean(self, env):
7376 arg_type = self.arg.type
7377 if (arg_type == PyrexTypes.c_bint_type or
7378 (arg_type.is_pyobject and arg_type.name == 'bool')):
7379 return self.arg.coerce_to_temp(env)
7381 return CoerceToBooleanNode(self, env)
7383 def coerce_to_integer(self, env):
7384 # If not already some C integer type, coerce to longint.
7385 if self.arg.type.is_int:
7388 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7390 def analyse_types(self, env):
7391 # The arg is always already analysed
7394 def generate_result_code(self, code):
7395 function = self.arg.type.to_py_function
7396 code.putln('%s = %s(%s); %s' % (
7400 code.error_goto_if_null(self.result(), self.pos)))
7401 code.put_gotref(self.py_result())
7404 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7405 # This node is used to convert a C int type to a Python bytes
7410 def __init__(self, arg, env):
7411 arg = arg.coerce_to_simple(env)
7412 CoercionNode.__init__(self, arg)
7413 self.type = Builtin.bytes_type
7415 def generate_result_code(self, code):
7417 arg_result = arg.result()
7418 if arg.type not in (PyrexTypes.c_char_type,
7419 PyrexTypes.c_uchar_type,
7420 PyrexTypes.c_schar_type):
7422 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7423 arg_result, arg_result))
7425 code.putln("if (%s > 255) {" % arg_result)
7426 code.putln('PyErr_Format(PyExc_OverflowError, '
7427 '"value too large to pack into a byte"); %s' % (
7428 code.error_goto(self.pos)))
7431 if arg.type is not PyrexTypes.c_char_type:
7432 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7433 code.putln("%s = (char)%s;" % (temp, arg_result))
7435 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7438 code.error_goto_if_null(self.result(), self.pos)))
7439 if temp is not None:
7440 code.funcstate.release_temp(temp)
7441 code.put_gotref(self.py_result())
7444 class CoerceFromPyTypeNode(CoercionNode):
7445 # This node is used to convert a Python object
7448 def __init__(self, result_type, arg, env):
7449 CoercionNode.__init__(self, arg)
7450 self.type = result_type
7452 if not result_type.create_from_py_utility_code(env):
7454 "Cannot convert Python object to '%s'" % result_type)
7455 if self.type.is_string and self.arg.is_ephemeral():
7457 "Obtaining char * from temporary Python value")
7459 def analyse_types(self, env):
7460 # The arg is always already analysed
7463 def generate_result_code(self, code):
7464 function = self.type.from_py_function
7465 operand = self.arg.py_result()
7466 rhs = "%s(%s)" % (function, operand)
7467 if self.type.is_enum:
7468 rhs = typecast(self.type, c_long_type, rhs)
7469 code.putln('%s = %s; %s' % (
7472 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7473 if self.type.is_pyobject:
7474 code.put_gotref(self.py_result())
7477 class CoerceToBooleanNode(CoercionNode):
7478 # This node is used when a result needs to be used
7479 # in a boolean context.
7481 type = PyrexTypes.c_bint_type
7483 _special_builtins = {
7484 Builtin.list_type : 'PyList_GET_SIZE',
7485 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7486 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7487 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7490 def __init__(self, arg, env):
7491 CoercionNode.__init__(self, arg)
7492 if arg.type.is_pyobject:
7495 def nogil_check(self, env):
7496 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7499 gil_message = "Truth-testing Python object"
7501 def check_const(self):
7505 return self.arg.check_const()
7507 def calculate_result_code(self):
7508 return "(%s != 0)" % self.arg.result()
7510 def generate_result_code(self, code):
7511 if not self.is_temp:
7513 test_func = self._special_builtins.get(self.arg.type)
7514 if test_func is not None:
7515 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7517 self.arg.py_result(),
7519 self.arg.py_result()))
7522 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7524 self.arg.py_result(),
7525 code.error_goto_if_neg(self.result(), self.pos)))
7527 class CoerceToComplexNode(CoercionNode):
7529 def __init__(self, arg, dst_type, env):
7530 if arg.type.is_complex:
7531 arg = arg.coerce_to_simple(env)
7532 self.type = dst_type
7533 CoercionNode.__init__(self, arg)
7534 dst_type.create_declaration_utility_code(env)
7536 def calculate_result_code(self):
7537 if self.arg.type.is_complex:
7538 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7539 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7541 real_part = self.arg.result()
7543 return "%s(%s, %s)" % (
7544 self.type.from_parts,
7548 def generate_result_code(self, code):
7551 class CoerceToTempNode(CoercionNode):
7552 # This node is used to force the result of another node
7553 # to be stored in a temporary. It is only used if the
7554 # argument node's result is not already in a temporary.
7556 def __init__(self, arg, env):
7557 CoercionNode.__init__(self, arg)
7558 self.type = self.arg.type
7559 self.constant_result = self.arg.constant_result
7561 if self.type.is_pyobject:
7562 self.result_ctype = py_object_type
7564 gil_message = "Creating temporary Python reference"
7566 def analyse_types(self, env):
7567 # The arg is always already analysed
7570 def coerce_to_boolean(self, env):
7571 self.arg = self.arg.coerce_to_boolean(env)
7572 if self.arg.is_simple():
7574 self.type = self.arg.type
7575 self.result_ctype = self.type
7578 def generate_result_code(self, code):
7579 #self.arg.generate_evaluation_code(code) # Already done
7580 # by generic generate_subexpr_evaluation_code!
7581 code.putln("%s = %s;" % (
7582 self.result(), self.arg.result_as(self.ctype())))
7583 if self.type.is_pyobject and self.use_managed_ref:
7584 code.put_incref(self.result(), self.ctype())
7587 class CloneNode(CoercionNode):
7588 # This node is employed when the result of another node needs
7589 # to be used multiple times. The argument node's result must
7590 # be in a temporary. This node "borrows" the result from the
7591 # argument node, and does not generate any evaluation or
7592 # disposal code for it. The original owner of the argument
7593 # node is responsible for doing those things.
7595 subexprs = [] # Arg is not considered a subexpr
7598 def __init__(self, arg):
7599 CoercionNode.__init__(self, arg)
7600 if hasattr(arg, 'type'):
7601 self.type = arg.type
7602 self.result_ctype = arg.result_ctype
7603 if hasattr(arg, 'entry'):
7604 self.entry = arg.entry
7607 return self.arg.result()
7609 def type_dependencies(self, env):
7610 return self.arg.type_dependencies(env)
7612 def infer_type(self, env):
7613 return self.arg.infer_type(env)
7615 def analyse_types(self, env):
7616 self.type = self.arg.type
7617 self.result_ctype = self.arg.result_ctype
7619 if hasattr(self.arg, 'entry'):
7620 self.entry = self.arg.entry
7622 def is_simple(self):
7623 return True # result is always in a temp (or a name)
7625 def generate_evaluation_code(self, code):
7628 def generate_result_code(self, code):
7631 def generate_disposal_code(self, code):
7634 def free_temps(self, code):
7638 class ModuleRefNode(ExprNode):
7639 # Simple returns the module object
7641 type = py_object_type
7645 def analyse_types(self, env):
7648 def may_be_none(self):
7651 def calculate_result_code(self):
7652 return Naming.module_cname
7654 def generate_result_code(self, code):
7657 class DocstringRefNode(ExprNode):
7658 # Extracts the docstring of the body element
7661 type = py_object_type
7664 def __init__(self, pos, body):
7665 ExprNode.__init__(self, pos)
7666 assert body.type.is_pyobject
7669 def analyse_types(self, env):
7672 def generate_result_code(self, code):
7673 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7674 self.result(), self.body.result(),
7675 code.error_goto_if_null(self.result(), self.pos)))
7676 code.put_gotref(self.result())
7680 #------------------------------------------------------------------------------------
7682 # Runtime support code
7684 #------------------------------------------------------------------------------------
7686 get_name_interned_utility_code = UtilityCode(
7688 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7691 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7693 result = PyObject_GetAttr(dict, name);
7695 PyErr_SetObject(PyExc_NameError, name);
7700 #------------------------------------------------------------------------------------
7702 import_utility_code = UtilityCode(
7704 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level); /*proto*/
7707 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level) {
7708 PyObject *py_import = 0;
7709 PyObject *empty_list = 0;
7710 PyObject *module = 0;
7711 PyObject *global_dict = 0;
7712 PyObject *empty_dict = 0;
7714 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7720 empty_list = PyList_New(0);
7725 global_dict = PyModule_GetDict(%(GLOBALS)s);
7728 empty_dict = PyDict_New();
7731 #if PY_VERSION_HEX >= 0x02050000
7733 PyObject *py_level = PyInt_FromLong(level);
7736 module = PyObject_CallFunctionObjArgs(py_import,
7737 name, global_dict, empty_dict, list, py_level, NULL);
7738 Py_DECREF(py_level);
7742 PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
7745 module = PyObject_CallFunctionObjArgs(py_import,
7746 name, global_dict, empty_dict, list, NULL);
7749 Py_XDECREF(empty_list);
7750 Py_XDECREF(py_import);
7751 Py_XDECREF(empty_dict);
7755 "BUILTINS": Naming.builtins_cname,
7756 "GLOBALS": Naming.module_cname,
7759 #------------------------------------------------------------------------------------
7761 get_exception_utility_code = UtilityCode(
7763 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7766 static PyObject *__Pyx_GetExcValue(void) {
7767 PyObject *type = 0, *value = 0, *tb = 0;
7768 PyObject *tmp_type, *tmp_value, *tmp_tb;
7769 PyObject *result = 0;
7770 PyThreadState *tstate = PyThreadState_Get();
7771 PyErr_Fetch(&type, &value, &tb);
7772 PyErr_NormalizeException(&type, &value, &tb);
7773 if (PyErr_Occurred())
7779 tmp_type = tstate->exc_type;
7780 tmp_value = tstate->exc_value;
7781 tmp_tb = tstate->exc_traceback;
7782 tstate->exc_type = type;
7783 tstate->exc_value = value;
7784 tstate->exc_traceback = tb;
7785 /* Make sure tstate is in a consistent state when we XDECREF
7786 these objects (XDECREF may run arbitrary code). */
7787 Py_XDECREF(tmp_type);
7788 Py_XDECREF(tmp_value);
7803 #------------------------------------------------------------------------------------
7805 type_test_utility_code = UtilityCode(
7807 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7810 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7811 if (unlikely(!type)) {
7812 PyErr_Format(PyExc_SystemError, "Missing type object");
7815 if (likely(PyObject_TypeCheck(obj, type)))
7817 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7818 Py_TYPE(obj)->tp_name, type->tp_name);
7823 #------------------------------------------------------------------------------------
7825 find_py2_metaclass_utility_code = UtilityCode(
7827 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7830 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7831 PyObject *metaclass;
7832 /* Default metaclass */
7833 #if PY_MAJOR_VERSION < 3
7834 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7835 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7836 metaclass = PyObject_GetAttrString(base, (char *)"__class__");
7839 metaclass = (PyObject*) Py_TYPE(base);
7842 metaclass = (PyObject *) &PyClass_Type;
7845 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7846 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7847 metaclass = (PyObject*) Py_TYPE(base);
7849 metaclass = (PyObject *) &PyType_Type;
7852 Py_INCREF(metaclass);
7857 create_class_utility_code = UtilityCode(
7859 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7860 PyObject *modname); /*proto*/
7863 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7864 PyObject *modname) {
7866 PyObject *metaclass;
7868 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7871 /* Python2 __metaclass__ */
7872 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7874 Py_INCREF(metaclass);
7876 metaclass = __Pyx_FindPy2Metaclass(bases);
7878 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7879 Py_DECREF(metaclass);
7883 requires = [find_py2_metaclass_utility_code])
7885 #------------------------------------------------------------------------------------
7887 create_py3class_utility_code = UtilityCode(
7889 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7890 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7891 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7894 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7895 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7897 Py_INCREF(metaclass);
7898 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7899 Py_DECREF(metaclass);
7904 return __Pyx_FindPy2Metaclass(bases);
7907 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7908 PyObject *modname, PyObject *doc) {
7914 prep = PyObject_GetAttrString(metaclass, (char *)"__prepare__");
7916 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7919 return PyDict_New();
7921 pargs = PyTuple_New(2);
7929 PyTuple_SET_ITEM(pargs, 0, name);
7930 PyTuple_SET_ITEM(pargs, 1, bases);
7932 ns = PyObject_Call(prep, pargs, mkw);
7940 /* Required here to emulate assignment order */
7941 /* XXX: use consts here */
7942 #if PY_MAJOR_VERSION >= 3
7943 str = PyUnicode_FromString("__module__");
7945 str = PyString_FromString("__module__");
7952 if (PyObject_SetItem(ns, str, modname) < 0) {
7959 #if PY_MAJOR_VERSION >= 3
7960 str = PyUnicode_FromString("__doc__");
7962 str = PyString_FromString("__doc__");
7968 if (PyObject_SetItem(ns, str, doc) < 0) {
7978 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7980 PyObject *margs = PyTuple_New(3);
7986 PyTuple_SET_ITEM(margs, 0, name);
7987 PyTuple_SET_ITEM(margs, 1, bases);
7988 PyTuple_SET_ITEM(margs, 2, dict);
7989 result = PyObject_Call(metaclass, margs, mkw);
7994 requires = [find_py2_metaclass_utility_code])
7996 #------------------------------------------------------------------------------------
7998 cpp_exception_utility_code = UtilityCode(
8000 #ifndef __Pyx_CppExn2PyErr
8001 static void __Pyx_CppExn2PyErr() {
8003 if (PyErr_Occurred())
8004 ; // let the latest Python exn pass through and ignore the current one
8007 } catch (const std::invalid_argument& exn) {
8008 // Catch a handful of different errors here and turn them into the
8009 // equivalent Python errors.
8010 // Change invalid_argument to ValueError
8011 PyErr_SetString(PyExc_ValueError, exn.what());
8012 } catch (const std::out_of_range& exn) {
8013 // Change out_of_range to IndexError
8014 PyErr_SetString(PyExc_IndexError, exn.what());
8015 } catch (const std::exception& exn) {
8016 PyErr_SetString(PyExc_RuntimeError, exn.what());
8020 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
8028 pyerr_occurred_withgil_utility_code= UtilityCode(
8030 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
8033 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
8036 PyGILState_STATE _save = PyGILState_Ensure();
8038 err = !!PyErr_Occurred();
8040 PyGILState_Release(_save);
8047 #------------------------------------------------------------------------------------
8049 raise_noneattr_error_utility_code = UtilityCode(
8051 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
8054 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
8055 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
8059 raise_noneindex_error_utility_code = UtilityCode(
8061 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
8064 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
8065 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
8069 raise_none_iter_error_utility_code = UtilityCode(
8071 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
8074 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
8075 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
8079 #------------------------------------------------------------------------------------
8081 getitem_dict_utility_code = UtilityCode(
8083 #if PY_MAJOR_VERSION >= 3
8084 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
8086 if (unlikely(d == Py_None)) {
8087 __Pyx_RaiseNoneIndexingError();
8090 value = PyDict_GetItemWithError(d, key);
8091 if (unlikely(!value)) {
8092 if (!PyErr_Occurred())
8093 PyErr_SetObject(PyExc_KeyError, key);
8100 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
8103 requires = [raise_noneindex_error_utility_code])
8105 #------------------------------------------------------------------------------------
8107 getitem_int_pyunicode_utility_code = UtilityCode(
8109 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8110 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
8111 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
8113 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
8114 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
8115 return PyUnicode_AS_UNICODE(ustring)[i];
8116 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
8117 i += PyUnicode_GET_SIZE(ustring);
8118 return PyUnicode_AS_UNICODE(ustring)[i];
8120 PyErr_SetString(PyExc_IndexError, "string index out of range");
8121 return (Py_UNICODE)-1;
8125 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
8127 PyObject *uchar_string;
8128 if (!j) return (Py_UNICODE)-1;
8129 uchar_string = PyObject_GetItem(ustring, j);
8131 if (!uchar_string) return (Py_UNICODE)-1;
8132 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
8133 Py_DECREF(uchar_string);
8138 getitem_int_utility_code = UtilityCode(
8141 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
8143 if (!j) return NULL;
8144 r = PyObject_GetItem(o, j);
8151 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8152 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
8153 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8155 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
8156 if (likely(o != Py_None)) {
8157 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
8158 PyObject *r = Py%(type)s_GET_ITEM(o, i);
8162 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
8163 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
8168 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8170 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
8173 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8174 __Pyx_GetItemInt_Fast(o, i) : \\
8175 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8177 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
8179 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8180 r = PyList_GET_ITEM(o, i);
8183 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
8184 r = PyTuple_GET_ITEM(o, i);
8187 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
8188 r = PySequence_GetItem(o, i);
8191 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8201 #------------------------------------------------------------------------------------
8203 setitem_int_utility_code = UtilityCode(
8205 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8206 __Pyx_SetItemInt_Fast(o, i, v) : \\
8207 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
8209 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
8212 r = PyObject_SetItem(o, j, v);
8217 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
8218 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8220 Py_DECREF(PyList_GET_ITEM(o, i));
8221 PyList_SET_ITEM(o, i, v);
8224 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
8225 return PySequence_SetItem(o, i, v);
8227 PyObject *j = PyInt_FromSsize_t(i);
8228 return __Pyx_SetItemInt_Generic(o, j, v);
8235 #------------------------------------------------------------------------------------
8237 delitem_int_utility_code = UtilityCode(
8239 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8240 __Pyx_DelItemInt_Fast(o, i) : \\
8241 __Pyx_DelItem_Generic(o, to_py_func(i)))
8243 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8246 r = PyObject_DelItem(o, j);
8251 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8252 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
8253 return PySequence_DelItem(o, i);
8255 PyObject *j = PyInt_FromSsize_t(i);
8256 return __Pyx_DelItem_Generic(o, j);
8263 #------------------------------------------------------------------------------------
8265 raise_too_many_values_to_unpack = UtilityCode(
8267 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8270 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
8271 PyErr_Format(PyExc_ValueError,
8272 #if PY_VERSION_HEX < 0x02050000
8273 "too many values to unpack (expected %d)", (int)expected);
8275 "too many values to unpack (expected %zd)", expected);
8280 raise_need_more_values_to_unpack = UtilityCode(
8282 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8285 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8286 PyErr_Format(PyExc_ValueError,
8287 #if PY_VERSION_HEX < 0x02050000
8288 "need more than %d value%s to unpack", (int)index,
8290 "need more than %zd value%s to unpack", index,
8292 (index == 1) ? "" : "s");
8296 #------------------------------------------------------------------------------------
8298 tuple_unpacking_error_code = UtilityCode(
8300 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8303 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
8305 __Pyx_RaiseNoneNotIterableError();
8306 } else if (PyTuple_GET_SIZE(t) < index) {
8307 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
8309 __Pyx_RaiseTooManyValuesError(index);
8313 requires = [raise_none_iter_error_utility_code,
8314 raise_need_more_values_to_unpack,
8315 raise_too_many_values_to_unpack]
8318 unpacking_utility_code = UtilityCode(
8320 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8321 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8324 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
8326 if (!(item = PyIter_Next(iter))) {
8327 if (!PyErr_Occurred()) {
8328 __Pyx_RaiseNeedMoreValuesError(index);
8334 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8336 if ((item = PyIter_Next(iter))) {
8338 __Pyx_RaiseTooManyValuesError(expected);
8341 else if (!PyErr_Occurred())
8347 requires = [raise_need_more_values_to_unpack,
8348 raise_too_many_values_to_unpack]
8351 #------------------------------------------------------------------------------------
8353 # CPython supports calling functions with non-dict kwargs by
8354 # converting them to a dict first
8356 kwargs_call_utility_code = UtilityCode(
8358 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
8361 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
8363 if (likely(PyDict_Check(kwargs))) {
8364 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
8366 PyObject* real_dict;
8367 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
8368 if (unlikely(!real_dict))
8370 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
8371 Py_DECREF(real_dict);
8372 return result; /* may be NULL */
8379 #------------------------------------------------------------------------------------
8381 int_pow_utility_code = UtilityCode(
8383 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8386 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8398 if (unlikely(e<0)) return 0;
8401 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8409 # ------------------------------ Division ------------------------------------
8411 div_int_utility_code = UtilityCode(
8413 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8416 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8418 %(type)s r = a - q*b;
8419 q -= ((r != 0) & ((r ^ b) < 0));
8424 mod_int_utility_code = UtilityCode(
8426 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8429 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8430 %(type)s r = a %% b;
8431 r += ((r != 0) & ((r ^ b) < 0)) * b;
8436 mod_float_utility_code = UtilityCode(
8438 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8441 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8442 %(type)s r = fmod%(math_h_modifier)s(a, b);
8443 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8448 cdivision_warning_utility_code = UtilityCode(
8450 static int __Pyx_cdivision_warning(void); /* proto */
8453 static int __Pyx_cdivision_warning(void) {
8454 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8455 "division with oppositely signed operands, C and Python semantics differ",
8462 'FILENAME': Naming.filename_cname,
8463 'LINENO': Naming.lineno_cname,
8467 division_overflow_test_code = UtilityCode(
8469 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8470 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8474 binding_cfunc_utility_code = UtilityCode(
8476 #define %(binding_cfunc)s_USED 1
8479 PyCFunctionObject func;
8480 } %(binding_cfunc)s_object;
8482 static PyTypeObject %(binding_cfunc)s_type;
8483 static PyTypeObject *%(binding_cfunc)s = NULL;
8485 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8486 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8488 static int %(binding_cfunc)s_init(void); /* proto */
8489 """ % Naming.__dict__,
8492 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8493 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8498 op->func.m_self = self;
8500 op->func.m_module = module;
8501 PyObject_GC_Track(op);
8502 return (PyObject *)op;
8505 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8506 PyObject_GC_UnTrack(m);
8507 Py_XDECREF(m->func.m_self);
8508 Py_XDECREF(m->func.m_module);
8512 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8515 return PyMethod_New(func, obj, type);
8518 static int %(binding_cfunc)s_init(void) {
8519 %(binding_cfunc)s_type = PyCFunction_Type;
8520 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8521 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8522 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8523 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8526 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8530 """ % Naming.__dict__)
8532 generator_utility_code = UtilityCode(
8534 static PyObject *__Pyx_Generator_Next(PyObject *self);
8535 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
8536 static PyObject *__Pyx_Generator_Close(PyObject *self);
8537 static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args, CYTHON_UNUSED PyObject *kwds);
8539 typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
8542 static CYTHON_INLINE void __Pyx_Generator_ExceptionClear(struct __pyx_Generator_object *self)
8544 Py_XDECREF(self->exc_type);
8545 Py_XDECREF(self->exc_value);
8546 Py_XDECREF(self->exc_traceback);
8548 self->exc_type = NULL;
8549 self->exc_value = NULL;
8550 self->exc_traceback = NULL;
8553 static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_object *self, PyObject *value)
8557 if (self->is_running) {
8558 PyErr_SetString(PyExc_ValueError,
8559 "generator already executing");
8563 if (self->resume_label == 0) {
8564 if (value && value != Py_None) {
8565 PyErr_SetString(PyExc_TypeError,
8566 "can't send non-None value to a "
8567 "just-started generator");
8572 if (self->resume_label == -1) {
8573 PyErr_SetNone(PyExc_StopIteration);
8579 __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
8581 __Pyx_Generator_ExceptionClear(self);
8583 self->is_running = 1;
8584 retval = self->body((PyObject *) self, value);
8585 self->is_running = 0;
8588 __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
8590 __Pyx_Generator_ExceptionClear(self);
8595 static PyObject *__Pyx_Generator_Next(PyObject *self)
8597 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, Py_None);
8600 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value)
8602 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, value);
8605 static PyObject *__Pyx_Generator_Close(PyObject *self)
8607 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8609 #if PY_VERSION_HEX < 0x02050000
8610 PyErr_SetNone(PyExc_StopIteration);
8612 PyErr_SetNone(PyExc_GeneratorExit);
8614 retval = __Pyx_Generator_SendEx(generator, NULL);
8617 PyErr_SetString(PyExc_RuntimeError,
8618 "generator ignored GeneratorExit");
8621 #if PY_VERSION_HEX < 0x02050000
8622 if (PyErr_ExceptionMatches(PyExc_StopIteration))
8624 if (PyErr_ExceptionMatches(PyExc_StopIteration)
8625 || PyErr_ExceptionMatches(PyExc_GeneratorExit))
8628 PyErr_Clear(); /* ignore these errors */
8635 static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args, CYTHON_UNUSED PyObject *kwds)
8637 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8639 PyObject *tb = NULL;
8640 PyObject *val = NULL;
8642 if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
8644 __Pyx_Raise(typ, val, tb, NULL);
8645 return __Pyx_Generator_SendEx(generator, NULL);
8648 proto_block='utility_code_proto_before_types',
8649 requires=[Nodes.raise_utility_code, Nodes.swap_exception_utility_code],