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.
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 float_value = float(self.constant_result)
871 return FloatNode(self.pos, value=repr(float_value), type=dst_type,
872 constant_result=float_value)
874 return FloatNode(self.pos, value=self.value, type=dst_type,
875 constant_result=not_a_constant)
876 if dst_type.is_numeric and not dst_type.is_complex:
877 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
878 type = dst_type, is_c_literal = True,
879 unsigned=self.unsigned, longness=self.longness)
881 elif dst_type.is_pyobject:
882 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
883 type = PyrexTypes.py_object_type, is_c_literal = False,
884 unsigned=self.unsigned, longness=self.longness)
886 # FIXME: not setting the type here to keep it working with
887 # complex numbers. Should they be special cased?
888 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
889 unsigned=self.unsigned, longness=self.longness)
890 # We still need to perform normal coerce_to processing on the
891 # result, because we might be coercing to an extension type,
892 # in which case a type test node will be needed.
893 return ConstNode.coerce_to(node, dst_type, env)
895 def coerce_to_boolean(self, env):
897 self.pos, value=self.value,
898 type = PyrexTypes.c_bint_type,
899 unsigned=self.unsigned, longness=self.longness)
901 def generate_evaluation_code(self, code):
902 if self.type.is_pyobject:
903 # pre-allocate a Python version of the number
904 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
905 self.result_code = code.get_py_num(plain_integer_string, self.longness)
907 self.result_code = self.get_constant_c_result_code()
909 def get_constant_c_result_code(self):
910 return self.value_as_c_integer_string() + self.unsigned + self.longness
912 def value_as_c_integer_string(self, plain_digits=False):
914 if isinstance(value, basestring) and len(value) > 2:
915 # must convert C-incompatible Py3 oct/bin notations
918 value = int(value[2:], 8)
920 value = value[0] + value[2:] # '0o123' => '0123'
921 elif value[1] in 'bB':
922 value = int(value[2:], 2)
923 elif plain_digits and value[1] in 'xX':
924 value = int(value[2:], 16)
927 def calculate_result_code(self):
928 return self.result_code
930 def calculate_constant_result(self):
931 self.constant_result = Utils.str_to_number(self.value)
933 def compile_time_value(self, denv):
934 return Utils.str_to_number(self.value)
937 class FloatNode(ConstNode):
938 type = PyrexTypes.c_double_type
940 def calculate_constant_result(self):
941 self.constant_result = float(self.value)
943 def compile_time_value(self, denv):
944 return float(self.value)
946 def calculate_result_code(self):
948 assert isinstance(strval, (str, unicode))
949 cmpval = repr(float(strval))
951 return "(Py_HUGE_VAL * 0)"
952 elif cmpval == 'inf':
954 elif cmpval == '-inf':
955 return "(-Py_HUGE_VAL)"
960 class BytesNode(ConstNode):
961 # A char* or bytes literal
965 # start off as Python 'bytes' to support len() in O(1)
968 def compile_time_value(self, denv):
971 def analyse_as_type(self, env):
972 type = PyrexTypes.parse_basic_type(self.value)
975 from TreeFragment import TreeFragment
976 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
977 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
978 sizeof_node = declaration.root.stats[0].expr
979 sizeof_node.analyse_types(env)
980 if isinstance(sizeof_node, SizeofTypeNode):
981 return sizeof_node.arg_type
983 def can_coerce_to_char_literal(self):
984 return len(self.value) == 1
986 def coerce_to_boolean(self, env):
987 # This is special because testing a C char* for truth directly
988 # would yield the wrong result.
989 return BoolNode(self.pos, value=bool(self.value))
991 def coerce_to(self, dst_type, env):
992 if self.type == dst_type:
995 if not self.can_coerce_to_char_literal():
996 error(self.pos, "Only single-character string literals can be coerced into ints.")
998 if dst_type.is_unicode_char:
999 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
1001 return CharNode(self.pos, value=self.value)
1003 node = BytesNode(self.pos, value=self.value)
1004 if dst_type.is_pyobject:
1005 if dst_type in (py_object_type, Builtin.bytes_type):
1006 node.type = Builtin.bytes_type
1008 self.check_for_coercion_error(dst_type, fail=True)
1010 elif dst_type == PyrexTypes.c_char_ptr_type:
1011 node.type = dst_type
1013 elif dst_type == PyrexTypes.c_uchar_ptr_type:
1014 node.type = PyrexTypes.c_char_ptr_type
1015 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
1016 elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
1017 node.type = dst_type
1020 # We still need to perform normal coerce_to processing on the
1021 # result, because we might be coercing to an extension type,
1022 # in which case a type test node will be needed.
1023 return ConstNode.coerce_to(node, dst_type, env)
1025 def generate_evaluation_code(self, code):
1026 if self.type.is_pyobject:
1027 self.result_code = code.get_py_string_const(self.value)
1029 self.result_code = code.get_string_const(self.value)
1031 def get_constant_c_result_code(self):
1034 def calculate_result_code(self):
1035 return self.result_code
1038 class UnicodeNode(PyConstNode):
1039 # A Python unicode object
1041 # value EncodedString
1042 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
1047 def coerce_to(self, dst_type, env):
1048 if dst_type is self.type:
1050 elif dst_type.is_unicode_char:
1051 if not self.can_coerce_to_char_literal():
1052 error(self.pos, "Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
1054 int_value = ord(self.value)
1055 return IntNode(self.pos, type=dst_type, value=str(int_value), constant_result=int_value)
1056 elif not dst_type.is_pyobject:
1057 if dst_type.is_string and self.bytes_value is not None:
1058 # special case: '-3' enforced unicode literal used in a C char* context
1059 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
1060 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE or Py_UCS4.")
1061 elif dst_type is not py_object_type:
1062 if not self.check_for_coercion_error(dst_type):
1063 self.fail_assignment(dst_type)
1066 def can_coerce_to_char_literal(self):
1067 return len(self.value) == 1
1068 ## or (len(self.value) == 2
1069 ## and (0xD800 <= self.value[0] <= 0xDBFF)
1070 ## and (0xDC00 <= self.value[1] <= 0xDFFF))
1072 def contains_surrogates(self):
1073 # Check if the unicode string contains surrogate code points
1074 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1075 # Unicode, i.e. characters that would be spelled as two
1076 # separate code units on a narrow platform.
1077 for c in map(ord, self.value):
1078 if c > 65535: # can only happen on wide platforms
1080 # We only look for the first code unit (D800-DBFF) of a
1081 # surrogate pair - if we find one, the other one
1082 # (DC00-DFFF) is likely there, too. If we don't find it,
1083 # any second code unit cannot make for a surrogate pair by
1085 if c >= 0xD800 and c <= 0xDBFF:
1089 def generate_evaluation_code(self, code):
1090 self.result_code = code.get_py_string_const(self.value)
1092 def calculate_result_code(self):
1093 return self.result_code
1095 def compile_time_value(self, env):
1099 class StringNode(PyConstNode):
1100 # A Python str object, i.e. a byte string in Python 2.x and a
1101 # unicode string in Python 3.x
1103 # value BytesLiteral (or EncodedString with ASCII content)
1104 # unicode_value EncodedString or None
1105 # is_identifier boolean
1108 is_identifier = None
1109 unicode_value = None
1111 def coerce_to(self, dst_type, env):
1112 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1113 # if dst_type is Builtin.bytes_type:
1114 # # special case: bytes = 'str literal'
1115 # return BytesNode(self.pos, value=self.value)
1116 if not dst_type.is_pyobject:
1117 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1118 self.check_for_coercion_error(dst_type, fail=True)
1120 # this will be a unicode string in Py3, so make sure we can decode it
1121 if self.value.encoding and isinstance(self.value, StringEncoding.BytesLiteral):
1123 self.value.decode(self.value.encoding)
1124 except UnicodeDecodeError:
1125 error(self.pos, ("Decoding unprefixed string literal from '%s' failed. Consider using"
1126 "a byte string or unicode string explicitly, "
1127 "or adjust the source code encoding.") % self.value.encoding)
1131 def can_coerce_to_char_literal(self):
1132 return not self.is_identifier and len(self.value) == 1
1134 def generate_evaluation_code(self, code):
1135 self.result_code = code.get_py_string_const(
1136 self.value, identifier=self.is_identifier, is_str=True)
1138 def get_constant_c_result_code(self):
1141 def calculate_result_code(self):
1142 return self.result_code
1144 def compile_time_value(self, env):
1148 class IdentifierStringNode(StringNode):
1149 # A special str value that represents an identifier (bytes in Py2,
1151 is_identifier = True
1154 class LongNode(AtomicExprNode):
1155 # Python long integer literal
1159 type = py_object_type
1161 def calculate_constant_result(self):
1162 self.constant_result = Utils.str_to_number(self.value)
1164 def compile_time_value(self, denv):
1165 return Utils.str_to_number(self.value)
1167 def analyse_types(self, env):
1170 def may_be_none(self):
1173 gil_message = "Constructing Python long int"
1175 def generate_result_code(self, code):
1177 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1180 code.error_goto_if_null(self.result(), self.pos)))
1181 code.put_gotref(self.py_result())
1184 class ImagNode(AtomicExprNode):
1185 # Imaginary number literal
1187 # value float imaginary part
1189 type = PyrexTypes.c_double_complex_type
1191 def calculate_constant_result(self):
1192 self.constant_result = complex(0.0, self.value)
1194 def compile_time_value(self, denv):
1195 return complex(0.0, self.value)
1197 def analyse_types(self, env):
1198 self.type.create_declaration_utility_code(env)
1200 def may_be_none(self):
1203 def coerce_to(self, dst_type, env):
1204 if self.type is dst_type:
1206 node = ImagNode(self.pos, value=self.value)
1207 if dst_type.is_pyobject:
1209 node.type = PyrexTypes.py_object_type
1210 # We still need to perform normal coerce_to processing on the
1211 # result, because we might be coercing to an extension type,
1212 # in which case a type test node will be needed.
1213 return AtomicExprNode.coerce_to(node, dst_type, env)
1215 gil_message = "Constructing complex number"
1217 def calculate_result_code(self):
1218 if self.type.is_pyobject:
1219 return self.result()
1221 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1223 def generate_result_code(self, code):
1224 if self.type.is_pyobject:
1226 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1229 code.error_goto_if_null(self.result(), self.pos)))
1230 code.put_gotref(self.py_result())
1233 class NewExprNode(AtomicExprNode):
1237 # cppclass node c++ class to create
1241 def infer_type(self, env):
1242 type = self.cppclass.analyse_as_type(env)
1243 if type is None or not type.is_cpp_class:
1244 error(self.pos, "new operator can only be applied to a C++ class")
1245 self.type = error_type
1248 constructor = type.scope.lookup(u'<init>')
1249 if constructor is None:
1250 return_type = PyrexTypes.CFuncType(type, [])
1251 return_type = PyrexTypes.CPtrType(return_type)
1252 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1253 constructor = type.scope.lookup(u'<init>')
1254 self.class_type = type
1255 self.entry = constructor
1256 self.type = constructor.type
1259 def analyse_types(self, env):
1260 if self.type is None:
1261 self.infer_type(env)
1263 def may_be_none(self):
1266 def generate_result_code(self, code):
1269 def calculate_result_code(self):
1270 return "new " + self.class_type.declaration_code("")
1273 class NameNode(AtomicExprNode):
1274 # Reference to a local or global variable name.
1276 # name string Python name of the variable
1277 # entry Entry Symbol table entry
1278 # type_entry Entry For extension type names, the original type entry
1281 is_cython_module = False
1282 cython_attribute = None
1283 lhs_of_first_assignment = False
1284 is_used_as_rvalue = 0
1288 def create_analysed_rvalue(pos, env, entry):
1289 node = NameNode(pos)
1290 node.analyse_types(env, entry=entry)
1293 def as_cython_attribute(self):
1294 return self.cython_attribute
1296 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1298 def type_dependencies(self, env):
1299 if self.entry is None:
1300 self.entry = env.lookup(self.name)
1301 if self.entry is not None and self.entry.type.is_unspecified:
1302 return (self.entry,)
1306 def infer_type(self, env):
1307 if self.entry is None:
1308 self.entry = env.lookup(self.name)
1309 if self.entry is None:
1310 return py_object_type
1311 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1312 self.name == self.entry.type.name:
1313 # Unfortunately the type attribute of type objects
1314 # is used for the pointer to the type they represent.
1316 elif self.entry.type.is_cfunction:
1317 # special case: referring to a C function must return its pointer
1318 return PyrexTypes.CPtrType(self.entry.type)
1320 return self.entry.type
1322 def compile_time_value(self, denv):
1324 return denv.lookup(self.name)
1326 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1328 def get_constant_c_result_code(self):
1329 if not self.entry or self.entry.type.is_pyobject:
1331 return self.entry.cname
1333 def coerce_to(self, dst_type, env):
1334 # If coercing to a generic pyobject and this is a builtin
1335 # C function with a Python equivalent, manufacture a NameNode
1336 # referring to the Python builtin.
1337 #print "NameNode.coerce_to:", self.name, dst_type ###
1338 if dst_type is py_object_type:
1340 if entry and entry.is_cfunction:
1341 var_entry = entry.as_variable
1343 if var_entry.is_builtin and Options.cache_builtins:
1344 var_entry = env.declare_builtin(var_entry.name, self.pos)
1345 node = NameNode(self.pos, name = self.name)
1346 node.entry = var_entry
1347 node.analyse_rvalue_entry(env)
1349 return super(NameNode, self).coerce_to(dst_type, env)
1351 def analyse_as_module(self, env):
1352 # Try to interpret this as a reference to a cimported module.
1353 # Returns the module scope, or None.
1356 entry = env.lookup(self.name)
1357 if entry and entry.as_module:
1358 return entry.as_module
1361 def analyse_as_type(self, env):
1362 if self.cython_attribute:
1363 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1365 type = PyrexTypes.parse_basic_type(self.name)
1370 entry = env.lookup(self.name)
1371 if entry and entry.is_type:
1376 def analyse_as_extension_type(self, env):
1377 # Try to interpret this as a reference to an extension type.
1378 # Returns the extension type, or None.
1381 entry = env.lookup(self.name)
1382 if entry and entry.is_type and entry.type.is_extension_type:
1387 def analyse_target_declaration(self, env):
1389 self.entry = env.lookup_here(self.name)
1391 if env.directives['warn.undeclared']:
1392 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1393 if env.directives['infer_types'] != False:
1394 type = unspecified_type
1396 type = py_object_type
1397 self.entry = env.declare_var(self.name, type, self.pos)
1398 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1399 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1400 if self.entry.is_declared_generic:
1401 self.result_ctype = py_object_type
1403 def analyse_types(self, env):
1404 if self.entry is None:
1405 self.entry = env.lookup(self.name)
1407 self.entry = env.declare_builtin(self.name, self.pos)
1409 self.type = PyrexTypes.error_type
1414 if entry.type.is_buffer:
1416 Buffer.used_buffer_aux_vars(entry)
1417 if entry.utility_code:
1418 env.use_utility_code(entry.utility_code)
1419 self.analyse_rvalue_entry(env)
1421 def analyse_target_types(self, env):
1422 self.analyse_entry(env)
1423 if not self.is_lvalue():
1424 error(self.pos, "Assignment to non-lvalue '%s'"
1426 self.type = PyrexTypes.error_type
1428 if self.entry.type.is_buffer:
1430 Buffer.used_buffer_aux_vars(self.entry)
1432 def analyse_rvalue_entry(self, env):
1433 #print "NameNode.analyse_rvalue_entry:", self.name ###
1434 #print "Entry:", self.entry.__dict__ ###
1435 self.analyse_entry(env)
1437 if entry.is_declared_generic:
1438 self.result_ctype = py_object_type
1439 if entry.is_pyglobal or entry.is_builtin:
1440 if Options.cache_builtins and entry.is_builtin:
1444 env.use_utility_code(get_name_interned_utility_code)
1445 self.is_used_as_rvalue = 1
1447 def nogil_check(self, env):
1448 if self.is_used_as_rvalue:
1450 if entry.is_builtin:
1451 if not Options.cache_builtins: # cached builtins are ok
1453 elif entry.is_pyglobal:
1456 gil_message = "Accessing Python global or builtin"
1458 def analyse_entry(self, env):
1459 #print "NameNode.analyse_entry:", self.name ###
1460 self.check_identifier_kind()
1465 def check_identifier_kind(self):
1466 # Check that this is an appropriate kind of name for use in an
1467 # expression. Also finds the variable entry associated with
1468 # an extension type.
1470 if entry.is_type and entry.type.is_extension_type:
1471 self.type_entry = entry
1472 if not (entry.is_const or entry.is_variable
1473 or entry.is_builtin or entry.is_cfunction
1474 or entry.is_cpp_class):
1475 if self.entry.as_variable:
1476 self.entry = self.entry.as_variable
1479 "'%s' is not a constant, variable or function identifier" % self.name)
1481 def is_simple(self):
1482 # If it's not a C variable, it'll be in a temp.
1485 def nonlocally_immutable(self):
1487 return entry and (entry.is_local or entry.is_arg) and not entry.in_closure
1489 def calculate_target_results(self, env):
1492 def check_const(self):
1494 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1499 def check_const_addr(self):
1501 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1502 self.addr_not_const()
1506 def is_lvalue(self):
1507 return self.entry.is_variable and \
1508 not self.entry.type.is_array and \
1509 not self.entry.is_readonly
1511 def is_ephemeral(self):
1512 # Name nodes are never ephemeral, even if the
1513 # result is in a temporary.
1516 def calculate_result_code(self):
1519 return "<error>" # There was an error earlier
1522 def generate_result_code(self, code):
1523 assert hasattr(self, 'entry')
1526 return # There was an error earlier
1527 if entry.is_builtin and Options.cache_builtins:
1528 return # Lookup already cached
1529 elif entry.is_pyclass_attr:
1530 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1531 interned_cname = code.intern_identifier(self.entry.name)
1532 if entry.is_builtin:
1533 namespace = Naming.builtins_cname
1534 else: # entry.is_pyglobal
1535 namespace = entry.scope.namespace_cname
1537 '%s = PyObject_GetItem(%s, %s); %s' % (
1541 code.error_goto_if_null(self.result(), self.pos)))
1542 code.put_gotref(self.py_result())
1544 elif entry.is_pyglobal or entry.is_builtin:
1545 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1546 interned_cname = code.intern_identifier(self.entry.name)
1547 if entry.is_builtin:
1548 namespace = Naming.builtins_cname
1549 else: # entry.is_pyglobal
1550 namespace = entry.scope.namespace_cname
1551 code.globalstate.use_utility_code(get_name_interned_utility_code)
1553 '%s = __Pyx_GetName(%s, %s); %s' % (
1557 code.error_goto_if_null(self.result(), self.pos)))
1558 code.put_gotref(self.py_result())
1560 elif entry.is_local and False:
1561 # control flow not good enough yet
1562 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1563 if assigned is False:
1564 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1565 elif not Options.init_local_none and assigned is None:
1566 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1567 (entry.cname, entry.name, code.error_goto(self.pos)))
1568 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1570 def generate_assignment_code(self, rhs, code):
1571 #print "NameNode.generate_assignment_code:", self.name ###
1574 return # There was an error earlier
1576 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1577 and not self.lhs_of_first_assignment):
1578 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1580 # is_pyglobal seems to be True for module level-globals only.
1581 # We use this to access class->tp_dict if necessary.
1582 if entry.is_pyglobal:
1583 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1584 interned_cname = code.intern_identifier(self.entry.name)
1585 namespace = self.entry.scope.namespace_cname
1587 # if the entry is a member we have to cheat: SetAttr does not work
1588 # on types, so we create a descriptor which is then added to tp_dict
1589 code.put_error_if_neg(self.pos,
1590 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1594 rhs.generate_disposal_code(code)
1595 rhs.free_temps(code)
1596 # in Py2.6+, we need to invalidate the method cache
1597 code.putln("PyType_Modified(%s);" %
1598 entry.scope.parent_type.typeptr_cname)
1599 elif entry.is_pyclass_attr:
1600 code.put_error_if_neg(self.pos,
1601 'PyObject_SetItem(%s, %s, %s)' % (
1605 rhs.generate_disposal_code(code)
1606 rhs.free_temps(code)
1608 code.put_error_if_neg(self.pos,
1609 'PyObject_SetAttr(%s, %s, %s)' % (
1613 if debug_disposal_code:
1614 print("NameNode.generate_assignment_code:")
1615 print("...generating disposal code for %s" % rhs)
1616 rhs.generate_disposal_code(code)
1617 rhs.free_temps(code)
1619 if self.type.is_buffer:
1620 # Generate code for doing the buffer release/acquisition.
1621 # This might raise an exception in which case the assignment (done
1622 # below) will not happen.
1624 # The reason this is not in a typetest-like node is because the
1625 # variables that the acquired buffer info is stored to is allocated
1626 # per entry and coupled with it.
1627 self.generate_acquire_buffer(rhs, code)
1629 if self.type.is_pyobject:
1630 #print "NameNode.generate_assignment_code: to", self.name ###
1631 #print "...from", rhs ###
1632 #print "...LHS type", self.type, "ctype", self.ctype() ###
1633 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1634 if self.use_managed_ref:
1635 rhs.make_owned_reference(code)
1636 is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
1637 if not self.lhs_of_first_assignment:
1639 code.put_gotref(self.py_result())
1640 if entry.is_local and not Options.init_local_none:
1641 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1642 if initialized is True:
1643 code.put_decref(self.result(), self.ctype())
1644 elif initialized is None:
1645 code.put_xdecref(self.result(), self.ctype())
1647 code.put_decref(self.result(), self.ctype())
1649 code.put_giveref(rhs.py_result())
1651 code.putln('%s = %s;' % (self.result(),
1652 rhs.result_as(self.ctype())))
1653 if debug_disposal_code:
1654 print("NameNode.generate_assignment_code:")
1655 print("...generating post-assignment code for %s" % rhs)
1656 rhs.generate_post_assignment_code(code)
1657 rhs.free_temps(code)
1659 def generate_acquire_buffer(self, rhs, code):
1660 # rhstmp is only used in case the rhs is a complicated expression leading to
1661 # the object, to avoid repeating the same C expression for every reference
1662 # to the rhs. It does NOT hold a reference.
1663 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1665 rhstmp = rhs.result_as(self.ctype())
1667 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1668 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1670 buffer_aux = self.entry.buffer_aux
1671 bufstruct = buffer_aux.buffer_info_var.cname
1673 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1674 is_initialized=not self.lhs_of_first_assignment,
1675 pos=self.pos, code=code)
1678 code.putln("%s = 0;" % rhstmp)
1679 code.funcstate.release_temp(rhstmp)
1681 def generate_deletion_code(self, code):
1682 if self.entry is None:
1683 return # There was an error earlier
1684 elif self.entry.is_pyglobal:
1685 code.put_error_if_neg(self.pos,
1686 '__Pyx_DelAttrString(%s, "%s")' % (
1687 Naming.module_cname,
1689 elif self.entry.is_pyclass_attr:
1690 namespace = self.entry.scope.namespace_cname
1691 code.put_error_if_neg(self.pos,
1692 'PyMapping_DelItemString(%s, "%s")' % (
1695 elif self.entry.type.is_pyobject:
1696 # Fake it until we can do it for real...
1697 self.generate_assignment_code(NoneNode(self.pos), code)
1699 error(self.pos, "Deletion of C names not supported")
1701 def annotate(self, code):
1702 if hasattr(self, 'is_called') and self.is_called:
1703 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1704 if self.type.is_pyobject:
1705 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1707 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1709 class BackquoteNode(ExprNode):
1714 type = py_object_type
1718 def analyse_types(self, env):
1719 self.arg.analyse_types(env)
1720 self.arg = self.arg.coerce_to_pyobject(env)
1723 gil_message = "Backquote expression"
1725 def calculate_constant_result(self):
1726 self.constant_result = repr(self.arg.constant_result)
1728 def generate_result_code(self, code):
1730 "%s = PyObject_Repr(%s); %s" % (
1732 self.arg.py_result(),
1733 code.error_goto_if_null(self.result(), self.pos)))
1734 code.put_gotref(self.py_result())
1738 class ImportNode(ExprNode):
1739 # Used as part of import statement implementation.
1740 # Implements result =
1741 # __import__(module_name, globals(), None, name_list)
1743 # module_name StringNode dotted name of module
1744 # name_list ListNode or None list of names to be imported
1746 type = py_object_type
1748 subexprs = ['module_name', 'name_list']
1750 def analyse_types(self, env):
1751 self.module_name.analyse_types(env)
1752 self.module_name = self.module_name.coerce_to_pyobject(env)
1754 self.name_list.analyse_types(env)
1755 self.name_list.coerce_to_pyobject(env)
1757 env.use_utility_code(import_utility_code)
1759 gil_message = "Python import"
1761 def generate_result_code(self, code):
1763 name_list_code = self.name_list.py_result()
1765 name_list_code = "0"
1767 "%s = __Pyx_Import(%s, %s); %s" % (
1769 self.module_name.py_result(),
1771 code.error_goto_if_null(self.result(), self.pos)))
1772 code.put_gotref(self.py_result())
1775 class IteratorNode(ExprNode):
1776 # Used as part of for statement implementation.
1778 # allocate_counter_temp/release_counter_temp needs to be called
1779 # by parent (ForInStatNode)
1781 # Implements result = iter(sequence)
1785 type = py_object_type
1787 subexprs = ['sequence']
1789 def analyse_types(self, env):
1790 self.sequence.analyse_types(env)
1791 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1792 not self.sequence.type.is_string:
1793 # C array iteration will be transformed later on
1794 self.type = self.sequence.type
1796 self.sequence = self.sequence.coerce_to_pyobject(env)
1797 if self.sequence.type is list_type or \
1798 self.sequence.type is tuple_type:
1799 self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
1802 gil_message = "Iterating over Python object"
1804 def allocate_counter_temp(self, code):
1805 self.counter_cname = code.funcstate.allocate_temp(
1806 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1808 def release_counter_temp(self, code):
1809 code.funcstate.release_temp(self.counter_cname)
1811 def generate_result_code(self, code):
1812 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1813 raise InternalError("for in carray slice not transformed")
1814 is_builtin_sequence = self.sequence.type is list_type or \
1815 self.sequence.type is tuple_type
1816 may_be_a_sequence = not self.sequence.type.is_builtin_type
1817 if may_be_a_sequence:
1819 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1820 self.sequence.py_result(),
1821 self.sequence.py_result()))
1822 if is_builtin_sequence or may_be_a_sequence:
1824 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1827 self.sequence.py_result(),
1829 if not is_builtin_sequence:
1830 if may_be_a_sequence:
1831 code.putln("} else {")
1832 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1835 self.sequence.py_result(),
1836 code.error_goto_if_null(self.result(), self.pos)))
1837 code.put_gotref(self.py_result())
1838 if may_be_a_sequence:
1842 class NextNode(AtomicExprNode):
1843 # Used as part of for statement implementation.
1844 # Implements result = iterator.next()
1845 # Created during analyse_types phase.
1846 # The iterator is not owned by this node.
1850 type = py_object_type
1852 def __init__(self, iterator, env):
1853 self.pos = iterator.pos
1854 self.iterator = iterator
1855 if iterator.type.is_ptr or iterator.type.is_array:
1856 self.type = iterator.type.base_type
1859 def generate_result_code(self, code):
1860 sequence_type = self.iterator.sequence.type
1861 if sequence_type is list_type:
1862 type_checks = [(list_type, "List")]
1863 elif sequence_type is tuple_type:
1864 type_checks = [(tuple_type, "Tuple")]
1865 elif not sequence_type.is_builtin_type:
1866 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1870 for py_type, prefix in type_checks:
1871 if len(type_checks) > 1:
1873 "if (likely(Py%s_CheckExact(%s))) {" % (
1874 prefix, self.iterator.py_result()))
1876 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1877 self.iterator.counter_cname,
1879 self.iterator.py_result()))
1881 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1884 self.iterator.py_result(),
1885 self.iterator.counter_cname,
1887 self.iterator.counter_cname))
1888 if len(type_checks) > 1:
1890 if len(type_checks) == 1:
1894 "%s = PyIter_Next(%s);" % (
1896 self.iterator.py_result()))
1900 code.putln(code.error_goto_if_PyErr(self.pos))
1901 code.putln("break;")
1903 code.put_gotref(self.py_result())
1907 class ExcValueNode(AtomicExprNode):
1908 # Node created during analyse_types phase
1909 # of an ExceptClauseNode to fetch the current
1912 type = py_object_type
1914 def __init__(self, pos, env):
1915 ExprNode.__init__(self, pos)
1917 def set_var(self, var):
1920 def calculate_result_code(self):
1923 def generate_result_code(self, code):
1926 def analyse_types(self, env):
1930 class TempNode(ExprNode):
1931 # Node created during analyse_types phase
1932 # of some nodes to hold a temporary value.
1934 # Note: One must call "allocate" and "release" on
1935 # the node during code generation to get/release the temp.
1936 # This is because the temp result is often used outside of
1937 # the regular cycle.
1941 def __init__(self, pos, type, env):
1942 ExprNode.__init__(self, pos)
1944 if type.is_pyobject:
1945 self.result_ctype = py_object_type
1948 def analyse_types(self, env):
1951 def generate_result_code(self, code):
1954 def allocate(self, code):
1955 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1957 def release(self, code):
1958 code.funcstate.release_temp(self.temp_cname)
1959 self.temp_cname = None
1963 return self.temp_cname
1965 assert False, "Remember to call allocate/release on TempNode"
1968 # Do not participate in normal temp alloc/dealloc:
1969 def allocate_temp_result(self, code):
1972 def release_temp_result(self, code):
1975 class PyTempNode(TempNode):
1976 # TempNode holding a Python value.
1978 def __init__(self, pos, env):
1979 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1981 class RawCNameExprNode(ExprNode):
1984 def __init__(self, pos, type=None):
1988 def analyse_types(self, env):
1991 def set_cname(self, cname):
1997 def generate_result_code(self, code):
2001 #-------------------------------------------------------------------
2005 #-------------------------------------------------------------------
2007 class IndexNode(ExprNode):
2008 # Sequence indexing.
2012 # indices [ExprNode]
2013 # is_buffer_access boolean Whether this is a buffer access.
2015 # indices is used on buffer access, index on non-buffer access.
2016 # The former contains a clean list of index parameters, the
2017 # latter whatever Python object is needed for index access.
2019 subexprs = ['base', 'index', 'indices']
2022 def __init__(self, pos, index, *args, **kw):
2023 ExprNode.__init__(self, pos, index=index, *args, **kw)
2026 def calculate_constant_result(self):
2027 self.constant_result = \
2028 self.base.constant_result[self.index.constant_result]
2030 def compile_time_value(self, denv):
2031 base = self.base.compile_time_value(denv)
2032 index = self.index.compile_time_value(denv)
2035 except Exception, e:
2036 self.compile_time_value_error(e)
2038 def is_ephemeral(self):
2039 return self.base.is_ephemeral()
2041 def is_simple(self):
2042 if self.is_buffer_access:
2045 return (base.is_simple() and self.index.is_simple()
2046 and base.type and (base.type.is_ptr or base.type.is_array))
2048 def analyse_target_declaration(self, env):
2051 def analyse_as_type(self, env):
2052 base_type = self.base.analyse_as_type(env)
2053 if base_type and not base_type.is_pyobject:
2054 if base_type.is_cpp_class:
2055 if isinstance(self.index, TupleNode):
2056 template_values = self.index.args
2058 template_values = [self.index]
2060 type_node = Nodes.TemplatedTypeNode(
2062 positional_args = template_values,
2063 keyword_args = None)
2064 return type_node.analyse(env, base_type = base_type)
2066 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2069 def type_dependencies(self, env):
2070 return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2072 def infer_type(self, env):
2073 base_type = self.base.infer_type(env)
2074 if isinstance(self.index, SliceNode):
2076 if base_type.is_string:
2077 # sliced C strings must coerce to Python
2079 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2080 # slicing these returns the same type
2083 # TODO: Handle buffers (hopefully without too much redundancy).
2084 return py_object_type
2086 index_type = self.index.infer_type(env)
2087 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2089 if base_type is unicode_type:
2090 # Py_UCS4 will automatically coerce to a unicode string
2091 # if required, so this is safe. We only infer Py_UCS4
2092 # when the index is a C integer type. Otherwise, we may
2093 # need to use normal Python item access, in which case
2094 # it's faster to return the one-char unicode string than
2095 # to receive it, throw it away, and potentially rebuild it
2096 # on a subsequent PyObject coercion.
2097 return PyrexTypes.c_py_ucs4_type
2098 elif base_type is str_type:
2099 # always returns str - Py2: bytes, Py3: unicode
2101 elif isinstance(self.base, BytesNode):
2102 #if env.global_scope().context.language_level >= 3:
2103 # # infering 'char' can be made to work in Python 3 mode
2104 # return PyrexTypes.c_char_type
2105 # Py2/3 return different types on indexing bytes objects
2106 return py_object_type
2107 elif base_type.is_ptr or base_type.is_array:
2108 return base_type.base_type
2110 # may be slicing or indexing, we don't know
2111 if base_type in (unicode_type, str_type):
2112 # these types always returns their own type on Python indexing/slicing
2115 # TODO: Handle buffers (hopefully without too much redundancy).
2116 return py_object_type
2118 def analyse_types(self, env):
2119 self.analyse_base_and_index_types(env, getting = 1)
2121 def analyse_target_types(self, env):
2122 self.analyse_base_and_index_types(env, setting = 1)
2124 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2125 # Note: This might be cleaned up by having IndexNode
2126 # parsed in a saner way and only construct the tuple if
2129 # Note that this function must leave IndexNode in a cloneable state.
2130 # For buffers, self.index is packed out on the initial analysis, and
2131 # when cloning self.indices is copied.
2132 self.is_buffer_access = False
2134 self.base.analyse_types(env)
2135 if self.base.type.is_error:
2136 # Do not visit child tree if base is undeclared to avoid confusing
2138 self.type = PyrexTypes.error_type
2141 is_slice = isinstance(self.index, SliceNode)
2142 # Potentially overflowing index value.
2143 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2144 self.index = self.index.coerce_to_pyobject(env)
2146 # Handle the case where base is a literal char* (and we expect a string, not an int)
2147 if isinstance(self.base, BytesNode) or is_slice:
2148 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2149 self.base = self.base.coerce_to_pyobject(env)
2151 skip_child_analysis = False
2152 buffer_access = False
2153 if self.base.type.is_buffer:
2155 indices = self.indices
2157 if isinstance(self.index, TupleNode):
2158 indices = self.index.args
2160 indices = [self.index]
2161 if len(indices) == self.base.type.ndim:
2162 buffer_access = True
2163 skip_child_analysis = True
2165 x.analyse_types(env)
2166 if not x.type.is_int:
2167 buffer_access = False
2169 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2171 # On cloning, indices is cloned. Otherwise, unpack index into indices
2172 assert not (buffer_access and isinstance(self.index, CloneNode))
2175 self.indices = indices
2177 self.type = self.base.type.dtype
2178 self.is_buffer_access = True
2179 self.buffer_type = self.base.entry.type
2181 if getting and self.type.is_pyobject:
2184 if not self.base.entry.type.writable:
2185 error(self.pos, "Writing to readonly buffer")
2187 self.base.entry.buffer_aux.writable_needed = True
2189 base_type = self.base.type
2190 if isinstance(self.index, TupleNode):
2191 self.index.analyse_types(env, skip_children=skip_child_analysis)
2192 elif not skip_child_analysis:
2193 self.index.analyse_types(env)
2194 self.original_index_type = self.index.type
2195 if base_type.is_unicode_char:
2196 # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
2197 # cases, but indexing must still work for them
2198 if self.index.constant_result in (0, -1):
2199 # FIXME: we know that this node is redundant -
2200 # currently, this needs to get handled in Optimize.py
2202 self.base = self.base.coerce_to_pyobject(env)
2203 base_type = self.base.type
2204 if base_type.is_pyobject:
2205 if self.index.type.is_int:
2207 and (base_type in (list_type, tuple_type, unicode_type))
2208 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2209 and not env.directives['boundscheck']):
2213 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2215 self.index = self.index.coerce_to_pyobject(env)
2217 if self.index.type.is_int and base_type is unicode_type:
2218 # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
2219 # if required, so this is fast and safe
2220 self.type = PyrexTypes.c_py_ucs4_type
2221 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2222 self.type = base_type
2224 self.type = py_object_type
2226 if base_type.is_ptr or base_type.is_array:
2227 self.type = base_type.base_type
2229 self.type = base_type
2230 elif self.index.type.is_pyobject:
2231 self.index = self.index.coerce_to(
2232 PyrexTypes.c_py_ssize_t_type, env)
2233 elif not self.index.type.is_int:
2235 "Invalid index type '%s'" %
2237 elif base_type.is_cpp_class:
2238 function = env.lookup_operator("[]", [self.base, self.index])
2239 if function is None:
2240 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2241 self.type = PyrexTypes.error_type
2242 self.result_code = "<error>"
2244 func_type = function.type
2245 if func_type.is_ptr:
2246 func_type = func_type.base_type
2247 self.index = self.index.coerce_to(func_type.args[0].type, env)
2248 self.type = func_type.return_type
2249 if setting and not func_type.return_type.is_reference:
2250 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2253 "Attempting to index non-array type '%s'" %
2255 self.type = PyrexTypes.error_type
2257 gil_message = "Indexing Python object"
2259 def nogil_check(self, env):
2260 if self.is_buffer_access:
2261 if env.directives['boundscheck']:
2262 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2264 elif self.type.is_pyobject:
2265 error(self.pos, "Cannot access buffer with object dtype without gil")
2267 super(IndexNode, self).nogil_check(env)
2270 def check_const_addr(self):
2271 return self.base.check_const_addr() and self.index.check_const()
2273 def is_lvalue(self):
2276 def calculate_result_code(self):
2277 if self.is_buffer_access:
2278 return "(*%s)" % self.buffer_ptr_code
2279 elif self.base.type is list_type:
2280 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2281 elif self.base.type is tuple_type:
2282 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2283 elif self.base.type is unicode_type and self.type.is_unicode_char:
2284 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2285 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2286 error(self.pos, "Invalid use of pointer slice")
2288 return "(%s[%s])" % (
2289 self.base.result(), self.index.result())
2291 def extra_index_params(self):
2292 if self.index.type.is_int:
2293 if self.original_index_type.signed:
2294 size_adjustment = ""
2296 size_adjustment = "+1"
2297 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2301 def generate_subexpr_evaluation_code(self, code):
2302 self.base.generate_evaluation_code(code)
2303 if not self.indices:
2304 self.index.generate_evaluation_code(code)
2306 for i in self.indices:
2307 i.generate_evaluation_code(code)
2309 def generate_subexpr_disposal_code(self, code):
2310 self.base.generate_disposal_code(code)
2311 if not self.indices:
2312 self.index.generate_disposal_code(code)
2314 for i in self.indices:
2315 i.generate_disposal_code(code)
2317 def free_subexpr_temps(self, code):
2318 self.base.free_temps(code)
2319 if not self.indices:
2320 self.index.free_temps(code)
2322 for i in self.indices:
2325 def generate_result_code(self, code):
2326 if self.is_buffer_access:
2327 if code.globalstate.directives['nonecheck']:
2328 self.put_nonecheck(code)
2329 self.buffer_ptr_code = self.buffer_lookup_code(code)
2330 if self.type.is_pyobject:
2331 # is_temp is True, so must pull out value and incref it.
2332 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2333 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2335 if self.type.is_pyobject:
2336 if self.index.type.is_int:
2337 index_code = self.index.result()
2338 if self.base.type is list_type:
2339 function = "__Pyx_GetItemInt_List"
2340 elif self.base.type is tuple_type:
2341 function = "__Pyx_GetItemInt_Tuple"
2343 function = "__Pyx_GetItemInt"
2344 code.globalstate.use_utility_code(getitem_int_utility_code)
2346 index_code = self.index.py_result()
2347 if self.base.type is dict_type:
2348 function = "__Pyx_PyDict_GetItem"
2349 code.globalstate.use_utility_code(getitem_dict_utility_code)
2351 function = "PyObject_GetItem"
2353 "%s = %s(%s, %s%s); if (!%s) %s" % (
2356 self.base.py_result(),
2358 self.extra_index_params(),
2360 code.error_goto(self.pos)))
2361 code.put_gotref(self.py_result())
2362 elif self.type.is_unicode_char and self.base.type is unicode_type:
2363 assert self.index.type.is_int
2364 index_code = self.index.result()
2365 function = "__Pyx_GetItemInt_Unicode"
2366 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2368 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2371 self.base.py_result(),
2373 self.extra_index_params(),
2375 code.error_goto(self.pos)))
2377 def generate_setitem_code(self, value_code, code):
2378 if self.index.type.is_int:
2379 function = "__Pyx_SetItemInt"
2380 index_code = self.index.result()
2381 code.globalstate.use_utility_code(setitem_int_utility_code)
2383 index_code = self.index.py_result()
2384 if self.base.type is dict_type:
2385 function = "PyDict_SetItem"
2386 # It would seem that we could specialized lists/tuples, but that
2387 # shouldn't happen here.
2388 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2389 # not a PyObject*, and bad conversion here would give the wrong
2390 # exception. Also, tuples are supposed to be immutable, and raise
2391 # TypeErrors when trying to set their entries (PyTuple_SetItem
2392 # is for creating new tuples from).
2394 function = "PyObject_SetItem"
2396 "if (%s(%s, %s, %s%s) < 0) %s" % (
2398 self.base.py_result(),
2401 self.extra_index_params(),
2402 code.error_goto(self.pos)))
2404 def generate_buffer_setitem_code(self, rhs, code, op=""):
2405 # Used from generate_assignment_code and InPlaceAssignmentNode
2406 if code.globalstate.directives['nonecheck']:
2407 self.put_nonecheck(code)
2408 ptrexpr = self.buffer_lookup_code(code)
2409 if self.buffer_type.dtype.is_pyobject:
2410 # Must manage refcounts. Decref what is already there
2411 # and incref what we put in.
2412 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2413 rhs_code = rhs.result()
2414 code.putln("%s = %s;" % (ptr, ptrexpr))
2415 code.put_gotref("*%s" % ptr)
2416 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2419 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2420 code.put_giveref("*%s" % ptr)
2421 code.funcstate.release_temp(ptr)
2424 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2426 def generate_assignment_code(self, rhs, code):
2427 self.generate_subexpr_evaluation_code(code)
2428 if self.is_buffer_access:
2429 self.generate_buffer_setitem_code(rhs, code)
2430 elif self.type.is_pyobject:
2431 self.generate_setitem_code(rhs.py_result(), code)
2435 self.result(), rhs.result()))
2436 self.generate_subexpr_disposal_code(code)
2437 self.free_subexpr_temps(code)
2438 rhs.generate_disposal_code(code)
2439 rhs.free_temps(code)
2441 def generate_deletion_code(self, code):
2442 self.generate_subexpr_evaluation_code(code)
2443 #if self.type.is_pyobject:
2444 if self.index.type.is_int:
2445 function = "__Pyx_DelItemInt"
2446 index_code = self.index.result()
2447 code.globalstate.use_utility_code(delitem_int_utility_code)
2449 index_code = self.index.py_result()
2450 if self.base.type is dict_type:
2451 function = "PyDict_DelItem"
2453 function = "PyObject_DelItem"
2455 "if (%s(%s, %s%s) < 0) %s" % (
2457 self.base.py_result(),
2459 self.extra_index_params(),
2460 code.error_goto(self.pos)))
2461 self.generate_subexpr_disposal_code(code)
2462 self.free_subexpr_temps(code)
2464 def buffer_lookup_code(self, code):
2465 # Assign indices to temps
2466 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2467 for temp, index in zip(index_temps, self.indices):
2468 code.putln("%s = %s;" % (temp, index.result()))
2469 # Generate buffer access code using these temps
2471 # The above could happen because child_attrs is wrong somewhere so that
2472 # options are not propagated.
2473 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2474 index_signeds=[i.type.signed for i in self.indices],
2475 index_cnames=index_temps,
2476 directives=code.globalstate.directives,
2477 pos=self.pos, code=code)
2479 def put_nonecheck(self, code):
2480 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2481 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2482 code.putln("__Pyx_RaiseNoneIndexingError();")
2483 code.putln(code.error_goto(self.pos))
2486 class SliceIndexNode(ExprNode):
2487 # 2-element slice indexing
2490 # start ExprNode or None
2491 # stop ExprNode or None
2493 subexprs = ['base', 'start', 'stop']
2495 def infer_type(self, env):
2496 base_type = self.base.infer_type(env)
2497 if base_type.is_string:
2499 elif base_type in (bytes_type, str_type, unicode_type,
2500 list_type, tuple_type):
2502 return py_object_type
2504 def calculate_constant_result(self):
2505 self.constant_result = self.base.constant_result[
2506 self.start.constant_result : self.stop.constant_result]
2508 def compile_time_value(self, denv):
2509 base = self.base.compile_time_value(denv)
2510 if self.start is None:
2513 start = self.start.compile_time_value(denv)
2514 if self.stop is None:
2517 stop = self.stop.compile_time_value(denv)
2519 return base[start:stop]
2520 except Exception, e:
2521 self.compile_time_value_error(e)
2523 def analyse_target_declaration(self, env):
2526 def analyse_target_types(self, env):
2527 self.analyse_types(env)
2528 # when assigning, we must accept any Python type
2529 if self.type.is_pyobject:
2530 self.type = py_object_type
2532 def analyse_types(self, env):
2533 self.base.analyse_types(env)
2535 self.start.analyse_types(env)
2537 self.stop.analyse_types(env)
2538 base_type = self.base.type
2539 if base_type.is_string:
2540 self.type = bytes_type
2541 elif base_type.is_ptr:
2542 self.type = base_type
2543 elif base_type.is_array:
2544 # we need a ptr type here instead of an array type, as
2545 # array types can result in invalid type casts in the C
2547 self.type = PyrexTypes.CPtrType(base_type.base_type)
2549 self.base = self.base.coerce_to_pyobject(env)
2550 self.type = py_object_type
2551 if base_type.is_builtin_type:
2552 # slicing builtin types returns something of the same type
2553 self.type = base_type
2554 c_int = PyrexTypes.c_py_ssize_t_type
2556 self.start = self.start.coerce_to(c_int, env)
2558 self.stop = self.stop.coerce_to(c_int, env)
2561 nogil_check = Node.gil_error
2562 gil_message = "Slicing Python object"
2564 def generate_result_code(self, code):
2565 if not self.type.is_pyobject:
2567 "Slicing is not currently supported for '%s'." % self.type)
2569 if self.base.type.is_string:
2570 if self.stop is None:
2572 "%s = PyBytes_FromString(%s + %s); %s" % (
2576 code.error_goto_if_null(self.result(), self.pos)))
2579 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2585 code.error_goto_if_null(self.result(), self.pos)))
2588 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2590 self.base.py_result(),
2593 code.error_goto_if_null(self.result(), self.pos)))
2594 code.put_gotref(self.py_result())
2596 def generate_assignment_code(self, rhs, code):
2597 self.generate_subexpr_evaluation_code(code)
2598 if self.type.is_pyobject:
2599 code.put_error_if_neg(self.pos,
2600 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2601 self.base.py_result(),
2608 start_offset = self.start_code()
2609 if start_offset == '0':
2613 if rhs.type.is_array:
2614 array_length = rhs.type.size
2615 self.generate_slice_guard_code(code, array_length)
2618 "Slice assignments from pointers are not yet supported.")
2619 # FIXME: fix the array size according to start/stop
2620 array_length = self.base.type.size
2621 for i in range(array_length):
2622 code.putln("%s[%s%s] = %s[%d];" % (
2623 self.base.result(), start_offset, i,
2625 self.generate_subexpr_disposal_code(code)
2626 self.free_subexpr_temps(code)
2627 rhs.generate_disposal_code(code)
2628 rhs.free_temps(code)
2630 def generate_deletion_code(self, code):
2631 if not self.base.type.is_pyobject:
2633 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2635 self.generate_subexpr_evaluation_code(code)
2636 code.put_error_if_neg(self.pos,
2637 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2638 self.base.py_result(),
2641 self.generate_subexpr_disposal_code(code)
2642 self.free_subexpr_temps(code)
2644 def generate_slice_guard_code(self, code, target_size):
2645 if not self.base.type.is_array:
2647 slice_size = self.base.type.size
2650 stop = self.stop.result()
2654 slice_size = self.base.type.size + stop
2661 start = self.start.result()
2665 start = self.base.type.size + start
2673 error(self.pos, "Assignment to empty slice.")
2674 elif start is None and stop is None:
2675 # we know the exact slice length
2676 if target_size != slice_size:
2677 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2678 slice_size, target_size))
2679 elif start is not None:
2682 check = "(%s)-(%s)" % (stop, start)
2683 else: # stop is not None:
2686 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2687 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));' % (
2688 target_size, check))
2689 code.putln(code.error_goto(self.pos))
2692 def start_code(self):
2694 return self.start.result()
2698 def stop_code(self):
2700 return self.stop.result()
2701 elif self.base.type.is_array:
2702 return self.base.type.size
2704 return "PY_SSIZE_T_MAX"
2706 def calculate_result_code(self):
2707 # self.result() is not used, but this method must exist
2711 class SliceNode(ExprNode):
2712 # start:stop:step in subscript list
2718 subexprs = ['start', 'stop', 'step']
2720 type = py_object_type
2723 def calculate_constant_result(self):
2724 self.constant_result = slice(
2725 self.start.constant_result,
2726 self.stop.constant_result,
2727 self.step.constant_result)
2729 def compile_time_value(self, denv):
2730 start = self.start.compile_time_value(denv)
2731 stop = self.stop.compile_time_value(denv)
2732 step = self.step.compile_time_value(denv)
2734 return slice(start, stop, step)
2735 except Exception, e:
2736 self.compile_time_value_error(e)
2738 def analyse_types(self, env):
2739 self.start.analyse_types(env)
2740 self.stop.analyse_types(env)
2741 self.step.analyse_types(env)
2742 self.start = self.start.coerce_to_pyobject(env)
2743 self.stop = self.stop.coerce_to_pyobject(env)
2744 self.step = self.step.coerce_to_pyobject(env)
2745 if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
2746 self.is_literal = True
2747 self.is_temp = False
2749 gil_message = "Constructing Python slice object"
2751 def calculate_result_code(self):
2752 return self.result_code
2754 def generate_result_code(self, code):
2756 self.result_code = code.get_py_const(py_object_type, 'slice_', cleanup_level=2)
2757 code = code.get_cached_constants_writer()
2758 code.mark_pos(self.pos)
2761 "%s = PySlice_New(%s, %s, %s); %s" % (
2763 self.start.py_result(),
2764 self.stop.py_result(),
2765 self.step.py_result(),
2766 code.error_goto_if_null(self.result(), self.pos)))
2767 code.put_gotref(self.py_result())
2769 code.put_giveref(self.py_result())
2772 class CallNode(ExprNode):
2774 # allow overriding the default 'may_be_none' behaviour
2775 may_return_none = None
2777 def may_be_none(self):
2778 if self.may_return_none is not None:
2779 return self.may_return_none
2780 return ExprNode.may_be_none(self)
2782 def analyse_as_type_constructor(self, env):
2783 type = self.function.analyse_as_type(env)
2784 if type and type.is_struct_or_union:
2785 args, kwds = self.explicit_args_kwds()
2787 for arg, member in zip(args, type.scope.var_entries):
2788 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2790 items += kwds.key_value_pairs
2791 self.key_value_pairs = items
2792 self.__class__ = DictNode
2793 self.analyse_types(env)
2794 self.coerce_to(type, env)
2796 elif type and type.is_cpp_class:
2797 for arg in self.args:
2798 arg.analyse_types(env)
2799 constructor = type.scope.lookup("<init>")
2800 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2801 self.function.entry = constructor
2802 self.function.set_cname(type.declaration_code(""))
2803 self.analyse_c_function_call(env)
2806 def is_lvalue(self):
2807 return self.type.is_reference
2809 def nogil_check(self, env):
2810 func_type = self.function_type()
2811 if func_type.is_pyobject:
2813 elif not getattr(func_type, 'nogil', False):
2816 gil_message = "Calling gil-requiring function"
2819 class SimpleCallNode(CallNode):
2820 # Function call without keyword, * or ** args.
2824 # arg_tuple ExprNode or None used internally
2825 # self ExprNode or None used internally
2826 # coerced_self ExprNode or None used internally
2827 # wrapper_call bool used internally
2828 # has_optional_args bool used internally
2829 # nogil bool used internally
2831 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2836 wrapper_call = False
2837 has_optional_args = False
2841 def compile_time_value(self, denv):
2842 function = self.function.compile_time_value(denv)
2843 args = [arg.compile_time_value(denv) for arg in self.args]
2845 return function(*args)
2846 except Exception, e:
2847 self.compile_time_value_error(e)
2849 def type_dependencies(self, env):
2850 # TODO: Update when Danilo's C++ code merged in to handle the
2851 # the case of function overloading.
2852 return self.function.type_dependencies(env)
2854 def infer_type(self, env):
2855 function = self.function
2856 func_type = function.infer_type(env)
2857 if isinstance(self.function, NewExprNode):
2858 return PyrexTypes.CPtrType(self.function.class_type)
2859 if func_type.is_ptr:
2860 func_type = func_type.base_type
2861 if func_type.is_cfunction:
2862 return func_type.return_type
2863 elif func_type is type_type:
2864 if function.is_name and function.entry and function.entry.type:
2865 result_type = function.entry.type
2866 if result_type.is_extension_type:
2868 elif result_type.is_builtin_type:
2869 if function.entry.name == 'float':
2870 return PyrexTypes.c_double_type
2871 elif function.entry.name in Builtin.types_that_construct_their_instance:
2873 return py_object_type
2875 def analyse_as_type(self, env):
2876 attr = self.function.as_cython_attribute()
2877 if attr == 'pointer':
2878 if len(self.args) != 1:
2879 error(self.args.pos, "only one type allowed.")
2881 type = self.args[0].analyse_as_type(env)
2883 error(self.args[0].pos, "Unknown type")
2885 return PyrexTypes.CPtrType(type)
2887 def explicit_args_kwds(self):
2888 return self.args, None
2890 def analyse_types(self, env):
2891 if self.analyse_as_type_constructor(env):
2895 self.analysed = True
2896 function = self.function
2897 function.is_called = 1
2898 self.function.analyse_types(env)
2899 if function.is_attribute and function.entry and function.entry.is_cmethod:
2900 # Take ownership of the object from which the attribute
2901 # was obtained, because we need to pass it as 'self'.
2902 self.self = function.obj
2903 function.obj = CloneNode(self.self)
2904 func_type = self.function_type()
2905 if func_type.is_pyobject:
2906 self.arg_tuple = TupleNode(self.pos, args = self.args)
2907 self.arg_tuple.analyse_types(env)
2909 if func_type is Builtin.type_type and function.is_name and \
2910 function.entry and \
2911 function.entry.is_builtin and \
2912 function.entry.name in Builtin.types_that_construct_their_instance:
2913 # calling a builtin type that returns a specific object type
2914 if function.entry.name == 'float':
2915 # the following will come true later on in a transform
2916 self.type = PyrexTypes.c_double_type
2917 self.result_ctype = PyrexTypes.c_double_type
2919 self.type = Builtin.builtin_types[function.entry.name]
2920 self.result_ctype = py_object_type
2921 self.may_return_none = False
2922 elif function.is_name and function.type_entry:
2923 # We are calling an extension type constructor. As
2924 # long as we do not support __new__(), the result type
2926 self.type = function.type_entry.type
2927 self.result_ctype = py_object_type
2928 self.may_return_none = False
2930 self.type = py_object_type
2933 for arg in self.args:
2934 arg.analyse_types(env)
2935 if self.self and func_type.args:
2936 # Coerce 'self' to the type expected by the method.
2937 self_arg = func_type.args[0]
2938 if self_arg.not_none: # C methods must do the None test for self at *call* time
2939 self.self = self.self.as_none_safe_node(
2940 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2941 'PyExc_AttributeError')
2942 expected_type = self_arg.type
2943 self.coerced_self = CloneNode(self.self).coerce_to(
2945 # Insert coerced 'self' argument into argument list.
2946 self.args.insert(0, self.coerced_self)
2947 self.analyse_c_function_call(env)
2949 def function_type(self):
2950 # Return the type of the function being called, coercing a function
2951 # pointer to a function if necessary.
2952 func_type = self.function.type
2953 if func_type.is_ptr:
2954 func_type = func_type.base_type
2957 def is_simple(self):
2958 # C function calls could be considered simple, but they may
2959 # have side-effects that may hit when multiple operations must
2960 # be effected in order, e.g. when constructing the argument
2961 # sequence for a function call or comparing values.
2964 def analyse_c_function_call(self, env):
2965 if self.function.type is error_type:
2966 self.type = error_type
2968 if self.function.type.is_cpp_class:
2969 overloaded_entry = self.function.type.scope.lookup("operator()")
2970 if overloaded_entry is None:
2971 self.type = PyrexTypes.error_type
2972 self.result_code = "<error>"
2974 elif hasattr(self.function, 'entry'):
2975 overloaded_entry = self.function.entry
2977 overloaded_entry = None
2978 if overloaded_entry:
2979 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2981 self.type = PyrexTypes.error_type
2982 self.result_code = "<error>"
2984 self.function.entry = entry
2985 self.function.type = entry.type
2986 func_type = self.function_type()
2988 func_type = self.function_type()
2989 if not func_type.is_cfunction:
2990 error(self.pos, "Calling non-function type '%s'" % func_type)
2991 self.type = PyrexTypes.error_type
2992 self.result_code = "<error>"
2995 max_nargs = len(func_type.args)
2996 expected_nargs = max_nargs - func_type.optional_arg_count
2997 actual_nargs = len(self.args)
2998 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2999 self.has_optional_args = 1
3002 some_args_in_temps = False
3003 for i in xrange(min(max_nargs, actual_nargs)):
3004 formal_type = func_type.args[i].type
3005 arg = self.args[i].coerce_to(formal_type, env)
3008 # first argument in temp doesn't impact subsequent arguments
3009 some_args_in_temps = True
3010 elif arg.type.is_pyobject and not env.nogil:
3011 if i == 0 and self.self is not None:
3012 # a method's cloned "self" argument is ok
3014 elif arg.nonlocally_immutable():
3015 # plain local variables are ok
3018 # we do not safely own the argument's reference,
3019 # but we must make sure it cannot be collected
3020 # before we return from the function, so we create
3021 # an owned temp reference to it
3022 if i > 0: # first argument doesn't matter
3023 some_args_in_temps = True
3024 arg = arg.coerce_to_temp(env)
3026 # handle additional varargs parameters
3027 for i in xrange(max_nargs, actual_nargs):
3029 if arg.type.is_pyobject:
3030 arg_ctype = arg.type.default_coerced_ctype()
3031 if arg_ctype is None:
3032 error(self.args[i].pos,
3033 "Python object cannot be passed as a varargs parameter")
3035 self.args[i] = arg = arg.coerce_to(arg_ctype, env)
3036 if arg.is_temp and i > 0:
3037 some_args_in_temps = True
3038 if some_args_in_temps:
3039 # if some args are temps and others are not, they may get
3040 # constructed in the wrong order (temps first) => make
3041 # sure they are either all temps or all not temps (except
3042 # for the last argument, which is evaluated last in any
3044 for i in xrange(actual_nargs-1):
3045 if i == 0 and self.self is not None:
3046 continue # self is ok
3048 if arg.is_name and arg.entry and (
3049 (arg.entry.is_local and not arg.entry.in_closure)
3050 or arg.entry.type.is_cfunction):
3051 # local variables and C functions are safe
3053 elif env.nogil and arg.type.is_pyobject:
3054 # can't copy a Python reference into a temp in nogil
3055 # env (this is safe: a construction would fail in
3059 self.args[i] = arg.coerce_to_temp(env)
3060 # Calc result type and code fragment
3061 if isinstance(self.function, NewExprNode):
3062 self.type = PyrexTypes.CPtrType(self.function.class_type)
3064 self.type = func_type.return_type
3065 if self.type.is_pyobject:
3066 self.result_ctype = py_object_type
3068 elif func_type.exception_value is not None \
3069 or func_type.exception_check:
3071 # Called in 'nogil' context?
3072 self.nogil = env.nogil
3074 func_type.exception_check and
3075 func_type.exception_check != '+'):
3076 env.use_utility_code(pyerr_occurred_withgil_utility_code)
3077 # C++ exception handler
3078 if func_type.exception_check == '+':
3079 if func_type.exception_value is None:
3080 env.use_utility_code(cpp_exception_utility_code)
3082 def calculate_result_code(self):
3083 return self.c_call_code()
3085 def c_call_code(self):
3086 func_type = self.function_type()
3087 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
3089 formal_args = func_type.args
3091 args = list(zip(formal_args, self.args))
3092 max_nargs = len(func_type.args)
3093 expected_nargs = max_nargs - func_type.optional_arg_count
3094 actual_nargs = len(self.args)
3095 for formal_arg, actual_arg in args[:expected_nargs]:
3096 arg_code = actual_arg.result_as(formal_arg.type)
3097 arg_list_code.append(arg_code)
3099 if func_type.is_overridable:
3100 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3102 if func_type.optional_arg_count:
3103 if expected_nargs == actual_nargs:
3104 optional_args = 'NULL'
3106 optional_args = "&%s" % self.opt_arg_struct
3107 arg_list_code.append(optional_args)
3109 for actual_arg in self.args[len(formal_args):]:
3110 arg_list_code.append(actual_arg.result())
3111 result = "%s(%s)" % (self.function.result(),
3112 ', '.join(arg_list_code))
3115 def generate_result_code(self, code):
3116 func_type = self.function_type()
3117 if func_type.is_pyobject:
3118 arg_code = self.arg_tuple.py_result()
3120 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3122 self.function.py_result(),
3124 code.error_goto_if_null(self.result(), self.pos)))
3125 code.put_gotref(self.py_result())
3126 elif func_type.is_cfunction:
3127 if self.has_optional_args:
3128 actual_nargs = len(self.args)
3129 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3130 self.opt_arg_struct = code.funcstate.allocate_temp(
3131 func_type.op_arg_struct.base_type, manage_ref=True)
3132 code.putln("%s.%s = %s;" % (
3133 self.opt_arg_struct,
3134 Naming.pyrex_prefix + "n",
3135 len(self.args) - expected_nargs))
3136 args = list(zip(func_type.args, self.args))
3137 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3138 code.putln("%s.%s = %s;" % (
3139 self.opt_arg_struct,
3140 func_type.opt_arg_cname(formal_arg.name),
3141 actual_arg.result_as(formal_arg.type)))
3143 if self.type.is_pyobject and self.is_temp:
3144 exc_checks.append("!%s" % self.result())
3146 exc_val = func_type.exception_value
3147 exc_check = func_type.exception_check
3148 if exc_val is not None:
3149 exc_checks.append("%s == %s" % (self.result(), exc_val))
3152 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3154 exc_checks.append("PyErr_Occurred()")
3155 if self.is_temp or exc_checks:
3156 rhs = self.c_call_code()
3158 lhs = "%s = " % self.result()
3159 if self.is_temp and self.type.is_pyobject:
3160 #return_type = self.type # func_type.return_type
3161 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3162 # "from", return_type, "to pyobject" ###
3163 rhs = typecast(py_object_type, self.type, rhs)
3166 if func_type.exception_check == '+':
3167 if func_type.exception_value is None:
3168 raise_py_exception = "__Pyx_CppExn2PyErr()"
3169 elif func_type.exception_value.type.is_pyobject:
3170 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3171 func_type.exception_value.entry.cname,
3172 func_type.exception_value.entry.cname)
3174 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3176 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3178 "try {%s%s;} catch(...) {%s; %s}" % (
3182 code.error_goto(self.pos)))
3185 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3188 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3189 if self.type.is_pyobject and self.result():
3190 code.put_gotref(self.py_result())
3191 if self.has_optional_args:
3192 code.funcstate.release_temp(self.opt_arg_struct)
3195 class PythonCapiFunctionNode(ExprNode):
3197 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3201 self.type = func_type
3202 self.utility_code = utility_code
3204 def analyse_types(self, env):
3207 def generate_result_code(self, code):
3208 if self.utility_code:
3209 code.globalstate.use_utility_code(self.utility_code)
3211 def calculate_result_code(self):
3214 class PythonCapiCallNode(SimpleCallNode):
3215 # Python C-API Function call (only created in transforms)
3217 # By default, we assume that the call never returns None, as this
3218 # is true for most C-API functions in CPython. If this does not
3219 # apply to a call, set the following to True (or None to inherit
3220 # the default behaviour).
3221 may_return_none = False
3223 def __init__(self, pos, function_name, func_type,
3224 utility_code = None, py_name=None, **kwargs):
3225 self.type = func_type.return_type
3226 self.result_ctype = self.type
3227 self.function = PythonCapiFunctionNode(
3228 pos, py_name, function_name, func_type,
3229 utility_code = utility_code)
3230 # call this last so that we can override the constructed
3231 # attributes above with explicit keyword arguments if required
3232 SimpleCallNode.__init__(self, pos, **kwargs)
3235 class GeneralCallNode(CallNode):
3236 # General Python function call, including keyword,
3237 # * and ** arguments.
3240 # positional_args ExprNode Tuple of positional arguments
3241 # keyword_args ExprNode or None Dict of keyword arguments
3242 # starstar_arg ExprNode or None Dict of extra keyword args
3244 type = py_object_type
3246 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3248 nogil_check = Node.gil_error
3250 def compile_time_value(self, denv):
3251 function = self.function.compile_time_value(denv)
3252 positional_args = self.positional_args.compile_time_value(denv)
3253 keyword_args = self.keyword_args.compile_time_value(denv)
3254 starstar_arg = self.starstar_arg.compile_time_value(denv)
3256 keyword_args.update(starstar_arg)
3257 return function(*positional_args, **keyword_args)
3258 except Exception, e:
3259 self.compile_time_value_error(e)
3261 def explicit_args_kwds(self):
3262 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3263 raise CompileError(self.pos,
3264 'Compile-time keyword arguments must be explicit.')
3265 return self.positional_args.args, self.keyword_args
3267 def analyse_types(self, env):
3268 if self.analyse_as_type_constructor(env):
3270 self.function.analyse_types(env)
3271 self.positional_args.analyse_types(env)
3272 if self.keyword_args:
3273 self.keyword_args.analyse_types(env)
3274 if self.starstar_arg:
3275 self.starstar_arg.analyse_types(env)
3276 if not self.function.type.is_pyobject:
3277 if self.function.type.is_error:
3278 self.type = error_type
3280 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3281 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3283 self.function = self.function.coerce_to_pyobject(env)
3284 self.positional_args = \
3285 self.positional_args.coerce_to_pyobject(env)
3286 if self.starstar_arg:
3287 self.starstar_arg = \
3288 self.starstar_arg.coerce_to_pyobject(env)
3289 function = self.function
3290 if function.is_name and function.type_entry:
3291 # We are calling an extension type constructor. As long
3292 # as we do not support __new__(), the result type is clear
3293 self.type = function.type_entry.type
3294 self.result_ctype = py_object_type
3295 self.may_return_none = False
3297 self.type = py_object_type
3300 def generate_result_code(self, code):
3301 if self.type.is_error: return
3302 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3303 if self.keyword_args and self.starstar_arg:
3304 code.put_error_if_neg(self.pos,
3305 "PyDict_Update(%s, %s)" % (
3306 self.keyword_args.py_result(),
3307 self.starstar_arg.py_result()))
3308 keyword_code = self.keyword_args.py_result()
3309 elif self.keyword_args:
3310 keyword_code = self.keyword_args.py_result()
3311 elif self.starstar_arg:
3312 keyword_code = self.starstar_arg.py_result()
3313 if self.starstar_arg.type is not Builtin.dict_type:
3314 # CPython supports calling functions with non-dicts, so do we
3315 code.globalstate.use_utility_code(kwargs_call_utility_code)
3316 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3319 if not keyword_code:
3320 call_code = "PyObject_Call(%s, %s, NULL)" % (
3321 self.function.py_result(),
3322 self.positional_args.py_result())
3324 call_code = "%s(%s, %s, %s)" % (
3325 kwargs_call_function,
3326 self.function.py_result(),
3327 self.positional_args.py_result(),
3333 code.error_goto_if_null(self.result(), self.pos)))
3334 code.put_gotref(self.py_result())
3337 class AsTupleNode(ExprNode):
3338 # Convert argument to tuple. Used for normalising
3339 # the * argument of a function call.
3345 def calculate_constant_result(self):
3346 self.constant_result = tuple(self.base.constant_result)
3348 def compile_time_value(self, denv):
3349 arg = self.arg.compile_time_value(denv)
3352 except Exception, e:
3353 self.compile_time_value_error(e)
3355 def analyse_types(self, env):
3356 self.arg.analyse_types(env)
3357 self.arg = self.arg.coerce_to_pyobject(env)
3358 self.type = tuple_type
3361 def may_be_none(self):
3364 nogil_check = Node.gil_error
3365 gil_message = "Constructing Python tuple"
3367 def generate_result_code(self, code):
3369 "%s = PySequence_Tuple(%s); %s" % (
3371 self.arg.py_result(),
3372 code.error_goto_if_null(self.result(), self.pos)))
3373 code.put_gotref(self.py_result())
3376 class AttributeNode(ExprNode):
3381 # needs_none_check boolean Used if obj is an extension type.
3382 # If set to True, it is known that the type is not None.
3386 # is_py_attr boolean Is a Python getattr operation
3387 # member string C name of struct member
3388 # is_called boolean Function call is being done on result
3389 # entry Entry Symbol table entry of attribute
3394 type = PyrexTypes.error_type
3397 needs_none_check = True
3399 def as_cython_attribute(self):
3400 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3401 return self.attribute
3402 cy = self.obj.as_cython_attribute()
3404 return "%s.%s" % (cy, self.attribute)
3406 def coerce_to(self, dst_type, env):
3407 # If coercing to a generic pyobject and this is a cpdef function
3408 # we can create the corresponding attribute
3409 if dst_type is py_object_type:
3411 if entry and entry.is_cfunction and entry.as_variable:
3412 # must be a cpdef function
3414 self.entry = entry.as_variable
3415 self.analyse_as_python_attribute(env)
3417 return ExprNode.coerce_to(self, dst_type, env)
3419 def calculate_constant_result(self):
3420 attr = self.attribute
3421 if attr.startswith("__") and attr.endswith("__"):
3423 self.constant_result = getattr(self.obj.constant_result, attr)
3425 def compile_time_value(self, denv):
3426 attr = self.attribute
3427 if attr.startswith("__") and attr.endswith("__"):
3429 "Invalid attribute name '%s' in compile-time expression" % attr)
3431 obj = self.obj.compile_time_value(denv)
3433 return getattr(obj, attr)
3434 except Exception, e:
3435 self.compile_time_value_error(e)
3437 def type_dependencies(self, env):
3438 return self.obj.type_dependencies(env)
3440 def infer_type(self, env):
3441 if self.analyse_as_cimported_attribute(env, 0):
3442 return self.entry.type
3443 elif self.analyse_as_unbound_cmethod(env):
3444 return self.entry.type
3446 obj_type = self.obj.infer_type(env)
3447 self.analyse_attribute(env, obj_type = obj_type)
3448 if obj_type.is_builtin_type and self.type.is_cfunction:
3449 # special case: C-API replacements for C methods of
3450 # builtin types cannot be inferred as C functions as
3451 # that would prevent their use as bound methods
3452 self.type = py_object_type
3453 return py_object_type
3456 def analyse_target_declaration(self, env):
3459 def analyse_target_types(self, env):
3460 self.analyse_types(env, target = 1)
3462 def analyse_types(self, env, target = 0):
3463 if self.analyse_as_cimported_attribute(env, target):
3465 if not target and self.analyse_as_unbound_cmethod(env):
3467 self.analyse_as_ordinary_attribute(env, target)
3469 def analyse_as_cimported_attribute(self, env, target):
3470 # Try to interpret this as a reference to an imported
3471 # C const, type, var or function. If successful, mutates
3472 # this node into a NameNode and returns 1, otherwise
3474 module_scope = self.obj.analyse_as_module(env)
3476 entry = module_scope.lookup_here(self.attribute)
3478 entry.is_cglobal or entry.is_cfunction
3479 or entry.is_type or entry.is_const):
3480 self.mutate_into_name_node(env, entry, target)
3484 def analyse_as_unbound_cmethod(self, env):
3485 # Try to interpret this as a reference to an unbound
3486 # C method of an extension type. If successful, mutates
3487 # this node into a NameNode and returns 1, otherwise
3489 type = self.obj.analyse_as_extension_type(env)
3491 entry = type.scope.lookup_here(self.attribute)
3492 if entry and entry.is_cmethod:
3493 # Create a temporary entry describing the C method
3494 # as an ordinary function.
3495 ubcm_entry = Symtab.Entry(entry.name,
3496 "%s->%s" % (type.vtabptr_cname, entry.cname),
3498 ubcm_entry.is_cfunction = 1
3499 ubcm_entry.func_cname = entry.func_cname
3500 ubcm_entry.is_unbound_cmethod = 1
3501 self.mutate_into_name_node(env, ubcm_entry, None)
3505 def analyse_as_type(self, env):
3506 module_scope = self.obj.analyse_as_module(env)
3508 return module_scope.lookup_type(self.attribute)
3509 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3510 base_type = self.obj.analyse_as_type(env)
3511 if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
3512 return base_type.scope.lookup_type(self.attribute)
3515 def analyse_as_extension_type(self, env):
3516 # Try to interpret this as a reference to an extension type
3517 # in a cimported module. Returns the extension type, or None.
3518 module_scope = self.obj.analyse_as_module(env)
3520 entry = module_scope.lookup_here(self.attribute)
3521 if entry and entry.is_type and entry.type.is_extension_type:
3525 def analyse_as_module(self, env):
3526 # Try to interpret this as a reference to a cimported module
3527 # in another cimported module. Returns the module scope, or None.
3528 module_scope = self.obj.analyse_as_module(env)
3530 entry = module_scope.lookup_here(self.attribute)
3531 if entry and entry.as_module:
3532 return entry.as_module
3535 def mutate_into_name_node(self, env, entry, target):
3536 # Mutate this node into a NameNode and complete the
3537 # analyse_types phase.
3538 self.__class__ = NameNode
3539 self.name = self.attribute
3544 NameNode.analyse_target_types(self, env)
3546 NameNode.analyse_rvalue_entry(self, env)
3548 def analyse_as_ordinary_attribute(self, env, target):
3549 self.obj.analyse_types(env)
3550 self.analyse_attribute(env)
3551 if self.entry and self.entry.is_cmethod and not self.is_called:
3552 # error(self.pos, "C method can only be called")
3554 ## Reference to C array turns into pointer to first element.
3555 #while self.type.is_array:
3556 # self.type = self.type.element_ptr_type()
3560 self.result_ctype = py_object_type
3561 elif target and self.obj.type.is_builtin_type:
3562 error(self.pos, "Assignment to an immutable object field")
3564 def analyse_attribute(self, env, obj_type = None):
3565 # Look up attribute and set self.type and self.member.
3567 self.member = self.attribute
3568 if obj_type is None:
3569 if self.obj.type.is_string:
3570 self.obj = self.obj.coerce_to_pyobject(env)
3571 obj_type = self.obj.type
3573 if obj_type.is_string:
3574 obj_type = py_object_type
3575 if obj_type.is_ptr or obj_type.is_array:
3576 obj_type = obj_type.base_type
3578 elif obj_type.is_extension_type or obj_type.is_builtin_type:
3582 if obj_type.has_attributes:
3584 if obj_type.attributes_known():
3585 entry = obj_type.scope.lookup_here(self.attribute)
3586 if entry and entry.is_member:
3590 "Cannot select attribute of incomplete type '%s'"
3592 self.type = PyrexTypes.error_type
3596 if obj_type.is_extension_type and entry.name == "__weakref__":
3597 error(self.pos, "Illegal use of special attribute __weakref__")
3598 # methods need the normal attribute lookup
3599 # because they do not have struct entries
3600 if entry.is_variable or entry.is_cmethod:
3601 self.type = entry.type
3602 self.member = entry.cname
3605 # If it's not a variable or C method, it must be a Python
3606 # method of an extension type, so we treat it like a Python
3609 # If we get here, the base object is not a struct/union/extension
3610 # type, or it is an extension type and the attribute is either not
3611 # declared or is declared as a Python method. Treat it as a Python
3612 # attribute reference.
3613 self.analyse_as_python_attribute(env, obj_type)
3615 def analyse_as_python_attribute(self, env, obj_type = None):
3616 if obj_type is None:
3617 obj_type = self.obj.type
3618 self.member = self.attribute
3619 self.type = py_object_type
3621 if not obj_type.is_pyobject and not obj_type.is_error:
3622 if obj_type.can_coerce_to_pyobject(env):
3623 self.obj = self.obj.coerce_to_pyobject(env)
3626 "Object of type '%s' has no attribute '%s'" %
3627 (obj_type, self.attribute))
3629 def nogil_check(self, env):
3633 gil_message = "Accessing Python attribute"
3635 def is_simple(self):
3637 return self.result_in_temp() or self.obj.is_simple()
3639 return NameNode.is_simple(self)
3641 def is_lvalue(self):
3645 return NameNode.is_lvalue(self)
3647 def is_ephemeral(self):
3649 return self.obj.is_ephemeral()
3651 return NameNode.is_ephemeral(self)
3653 def calculate_result_code(self):
3654 #print "AttributeNode.calculate_result_code:", self.member ###
3655 #print "...obj node =", self.obj, "code", self.obj.result() ###
3656 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3658 obj_code = obj.result_as(obj.type)
3659 #print "...obj_code =", obj_code ###
3660 if self.entry and self.entry.is_cmethod:
3661 if obj.type.is_extension_type:
3662 return "((struct %s *)%s%s%s)->%s" % (
3663 obj.type.vtabstruct_cname, obj_code, self.op,
3664 obj.type.vtabslot_cname, self.member)
3667 elif obj.type.is_complex:
3668 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3670 if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
3671 # accessing a field of a builtin type, need to cast better than result_as() does
3672 obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
3673 return "%s%s%s" % (obj_code, self.op, self.member)
3675 def generate_result_code(self, code):
3676 interned_attr_cname = code.intern_identifier(self.attribute)
3679 '%s = PyObject_GetAttr(%s, %s); %s' % (
3681 self.obj.py_result(),
3682 interned_attr_cname,
3683 code.error_goto_if_null(self.result(), self.pos)))
3684 code.put_gotref(self.py_result())
3686 # result_code contains what is needed, but we may need to insert
3687 # a check and raise an exception
3688 if (self.obj.type.is_extension_type
3689 and self.needs_none_check
3690 and code.globalstate.directives['nonecheck']):
3691 self.put_nonecheck(code)
3693 def generate_assignment_code(self, rhs, code):
3694 interned_attr_cname = code.intern_identifier(self.attribute)
3695 self.obj.generate_evaluation_code(code)
3697 code.put_error_if_neg(self.pos,
3698 'PyObject_SetAttr(%s, %s, %s)' % (
3699 self.obj.py_result(),
3700 interned_attr_cname,
3702 rhs.generate_disposal_code(code)
3703 rhs.free_temps(code)
3704 elif self.obj.type.is_complex:
3705 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3706 self.member.upper(),
3707 self.obj.result_as(self.obj.type),
3708 rhs.result_as(self.ctype())))
3710 if (self.obj.type.is_extension_type
3711 and self.needs_none_check
3712 and code.globalstate.directives['nonecheck']):
3713 self.put_nonecheck(code)
3715 select_code = self.result()
3716 if self.type.is_pyobject and self.use_managed_ref:
3717 rhs.make_owned_reference(code)
3718 code.put_giveref(rhs.py_result())
3719 code.put_gotref(select_code)
3720 code.put_decref(select_code, self.ctype())
3724 rhs.result_as(self.ctype())))
3726 rhs.generate_post_assignment_code(code)
3727 rhs.free_temps(code)
3728 self.obj.generate_disposal_code(code)
3729 self.obj.free_temps(code)
3731 def generate_deletion_code(self, code):
3732 interned_attr_cname = code.intern_identifier(self.attribute)
3733 self.obj.generate_evaluation_code(code)
3734 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3735 and u'__del__' in self.entry.scope.entries):
3736 code.put_error_if_neg(self.pos,
3737 'PyObject_DelAttr(%s, %s)' % (
3738 self.obj.py_result(),
3739 interned_attr_cname))
3741 error(self.pos, "Cannot delete C attribute of extension type")
3742 self.obj.generate_disposal_code(code)
3743 self.obj.free_temps(code)
3745 def annotate(self, code):
3747 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3749 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3751 def put_nonecheck(self, code):
3752 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3753 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3754 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3755 code.putln(code.error_goto(self.pos))
3759 #-------------------------------------------------------------------
3763 #-------------------------------------------------------------------
3765 class StarredTargetNode(ExprNode):
3766 # A starred expression like "*a"
3768 # This is only allowed in sequence assignment targets such as
3770 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3772 # and will be removed during type analysis (or generate an error
3773 # if it's found at unexpected places).
3777 subexprs = ['target']
3779 type = py_object_type
3782 def __init__(self, pos, target):
3784 self.target = target
3786 def analyse_declarations(self, env):
3787 error(self.pos, "can use starred expression only as assignment target")
3788 self.target.analyse_declarations(env)
3790 def analyse_types(self, env):
3791 error(self.pos, "can use starred expression only as assignment target")
3792 self.target.analyse_types(env)
3793 self.type = self.target.type
3795 def analyse_target_declaration(self, env):
3796 self.target.analyse_target_declaration(env)
3798 def analyse_target_types(self, env):
3799 self.target.analyse_target_types(env)
3800 self.type = self.target.type
3802 def calculate_result_code(self):
3805 def generate_result_code(self, code):
3809 class SequenceNode(ExprNode):
3810 # Base class for list and tuple constructor nodes.
3811 # Contains common code for performing sequence unpacking.
3815 # unpacked_items [ExprNode] or None
3816 # coerced_unpacked_items [ExprNode] or None
3820 is_sequence_constructor = 1
3821 unpacked_items = None
3823 def compile_time_value_list(self, denv):
3824 return [arg.compile_time_value(denv) for arg in self.args]
3826 def replace_starred_target_node(self):
3827 # replace a starred node in the targets by the contained expression
3828 self.starred_assignment = False
3830 for arg in self.args:
3832 if self.starred_assignment:
3833 error(arg.pos, "more than 1 starred expression in assignment")
3834 self.starred_assignment = True
3836 arg.is_starred = True
3840 def analyse_target_declaration(self, env):
3841 self.replace_starred_target_node()
3842 for arg in self.args:
3843 arg.analyse_target_declaration(env)
3845 def analyse_types(self, env, skip_children=False):
3846 for i in range(len(self.args)):
3848 if not skip_children: arg.analyse_types(env)
3849 self.args[i] = arg.coerce_to_pyobject(env)
3851 # not setting self.type here, subtypes do this
3853 def may_be_none(self):
3856 def analyse_target_types(self, env):
3857 self.iterator = PyTempNode(self.pos, env)
3858 self.unpacked_items = []
3859 self.coerced_unpacked_items = []
3860 for arg in self.args:
3861 arg.analyse_target_types(env)
3863 if not arg.type.assignable_from(Builtin.list_type):
3865 "starred target must have Python object (list) type")
3866 if arg.type is py_object_type:
3867 arg.type = Builtin.list_type
3868 unpacked_item = PyTempNode(self.pos, env)
3869 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3870 self.unpacked_items.append(unpacked_item)
3871 self.coerced_unpacked_items.append(coerced_unpacked_item)
3872 self.type = py_object_type
3874 def generate_result_code(self, code):
3875 self.generate_operation_code(code)
3877 def generate_assignment_code(self, rhs, code):
3878 if self.starred_assignment:
3879 self.generate_starred_assignment_code(rhs, code)
3881 self.generate_parallel_assignment_code(rhs, code)
3883 for item in self.unpacked_items:
3885 rhs.free_temps(code)
3887 def generate_parallel_assignment_code(self, rhs, code):
3888 # Need to work around the fact that generate_evaluation_code
3889 # allocates the temps in a rather hacky way -- the assignment
3890 # is evaluated twice, within each if-block.
3892 if rhs.type is tuple_type:
3893 tuple_check = "likely(%s != Py_None)"
3895 tuple_check = "PyTuple_CheckExact(%s)"
3897 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3898 tuple_check % rhs.py_result(),
3901 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3902 for item in self.unpacked_items:
3904 for i in range(len(self.args)):
3905 item = self.unpacked_items[i]
3907 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3910 code.put_incref(item.result(), item.ctype())
3911 value_node = self.coerced_unpacked_items[i]
3912 value_node.generate_evaluation_code(code)
3913 rhs.generate_disposal_code(code)
3915 for i in range(len(self.args)):
3916 self.args[i].generate_assignment_code(
3917 self.coerced_unpacked_items[i], code)
3919 code.putln("} else {")
3921 if rhs.type is tuple_type:
3922 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3923 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3924 rhs.py_result(), len(self.args)))
3925 code.putln(code.error_goto(self.pos))
3927 code.globalstate.use_utility_code(unpacking_utility_code)
3929 self.iterator.allocate(code)
3931 "%s = PyObject_GetIter(%s); %s" % (
3932 self.iterator.result(),
3934 code.error_goto_if_null(self.iterator.result(), self.pos)))
3935 code.put_gotref(self.iterator.py_result())
3936 rhs.generate_disposal_code(code)
3937 for i in range(len(self.args)):
3938 item = self.unpacked_items[i]
3939 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3940 self.iterator.py_result(), i)
3944 typecast(item.ctype(), py_object_type, unpack_code),
3945 code.error_goto_if_null(item.result(), self.pos)))
3946 code.put_gotref(item.py_result())
3947 value_node = self.coerced_unpacked_items[i]
3948 value_node.generate_evaluation_code(code)
3949 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3950 self.iterator.py_result(),
3952 if debug_disposal_code:
3953 print("UnpackNode.generate_assignment_code:")
3954 print("...generating disposal code for %s" % self.iterator)
3955 self.iterator.generate_disposal_code(code)
3956 self.iterator.free_temps(code)
3957 self.iterator.release(code)
3959 for i in range(len(self.args)):
3960 self.args[i].generate_assignment_code(
3961 self.coerced_unpacked_items[i], code)
3965 def generate_starred_assignment_code(self, rhs, code):
3966 code.globalstate.use_utility_code(unpacking_utility_code)
3968 for i, arg in enumerate(self.args):
3970 starred_target = self.unpacked_items[i]
3971 fixed_args_left = self.args[:i]
3972 fixed_args_right = self.args[i+1:]
3975 self.iterator.allocate(code)
3977 "%s = PyObject_GetIter(%s); %s" % (
3978 self.iterator.result(),
3980 code.error_goto_if_null(self.iterator.result(), self.pos)))
3981 code.put_gotref(self.iterator.py_result())
3982 rhs.generate_disposal_code(code)
3984 for item in self.unpacked_items:
3986 for i in range(len(fixed_args_left)):
3987 item = self.unpacked_items[i]
3988 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3989 self.iterator.py_result(), i)
3993 typecast(item.ctype(), py_object_type, unpack_code),
3994 code.error_goto_if_null(item.result(), self.pos)))
3995 code.put_gotref(item.py_result())
3996 value_node = self.coerced_unpacked_items[i]
3997 value_node.generate_evaluation_code(code)
3999 target_list = starred_target.result()
4000 code.putln("%s = PySequence_List(%s); %s" % (
4001 target_list, self.iterator.py_result(),
4002 code.error_goto_if_null(target_list, self.pos)))
4003 code.put_gotref(target_list)
4004 if fixed_args_right:
4005 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
4006 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
4007 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
4008 (target_list, len(unpacked_right_args))))
4009 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
4010 len(fixed_args_left), target_list,
4011 code.error_goto(self.pos)))
4013 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
4014 self.coerced_unpacked_items[::-1])):
4016 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
4018 target_list, target_list))
4019 # resize the list the hard way
4020 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
4021 code.put_gotref(arg.py_result())
4022 coerced_arg.generate_evaluation_code(code)
4024 self.iterator.generate_disposal_code(code)
4025 self.iterator.free_temps(code)
4026 self.iterator.release(code)
4028 for i in range(len(self.args)):
4029 self.args[i].generate_assignment_code(
4030 self.coerced_unpacked_items[i], code)
4032 def annotate(self, code):
4033 for arg in self.args:
4035 if self.unpacked_items:
4036 for arg in self.unpacked_items:
4038 for arg in self.coerced_unpacked_items:
4042 class TupleNode(SequenceNode):
4043 # Tuple constructor.
4047 gil_message = "Constructing Python tuple"
4049 def analyse_types(self, env, skip_children=False):
4050 if len(self.args) == 0:
4054 SequenceNode.analyse_types(self, env, skip_children)
4055 for child in self.args:
4056 if not child.is_literal:
4062 def is_simple(self):
4063 # either temp or constant => always simple
4066 def nonlocally_immutable(self):
4067 # either temp or constant => always safe
4070 def calculate_result_code(self):
4071 if len(self.args) > 0:
4072 return self.result_code
4074 return Naming.empty_tuple
4076 def calculate_constant_result(self):
4077 self.constant_result = tuple([
4078 arg.constant_result for arg in self.args])
4080 def compile_time_value(self, denv):
4081 values = self.compile_time_value_list(denv)
4083 return tuple(values)
4084 except Exception, e:
4085 self.compile_time_value_error(e)
4087 def generate_operation_code(self, code):
4088 if len(self.args) == 0:
4089 # result_code is Naming.empty_tuple
4092 # non-empty cached tuple => result is global constant,
4093 # creation code goes into separate code writer
4094 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
4095 code = code.get_cached_constants_writer()
4096 code.mark_pos(self.pos)
4099 "%s = PyTuple_New(%s); %s" % (
4102 code.error_goto_if_null(self.result(), self.pos)))
4103 code.put_gotref(self.py_result())
4104 for i in range(len(self.args)):
4106 if not arg.result_in_temp():
4107 code.put_incref(arg.result(), arg.ctype())
4109 "PyTuple_SET_ITEM(%s, %s, %s);" % (
4113 code.put_giveref(arg.py_result())
4115 code.put_giveref(self.py_result())
4117 def generate_subexpr_disposal_code(self, code):
4118 # We call generate_post_assignment_code here instead
4119 # of generate_disposal_code, because values were stored
4120 # in the tuple using a reference-stealing operation.
4121 for arg in self.args:
4122 arg.generate_post_assignment_code(code)
4123 # Should NOT call free_temps -- this is invoked by the default
4124 # generate_evaluation_code which will do that.
4127 class ListNode(SequenceNode):
4130 # obj_conversion_errors [PyrexError] used internally
4131 # orignial_args [ExprNode] used internally
4133 obj_conversion_errors = []
4136 gil_message = "Constructing Python list"
4138 def type_dependencies(self, env):
4141 def infer_type(self, env):
4142 # TOOD: Infer non-object list arrays.
4145 def analyse_expressions(self, env):
4146 SequenceNode.analyse_expressions(self, env)
4147 self.coerce_to_pyobject(env)
4149 def analyse_types(self, env):
4151 self.original_args = list(self.args)
4152 SequenceNode.analyse_types(self, env)
4153 self.obj_conversion_errors = held_errors()
4154 release_errors(ignore=True)
4156 def coerce_to(self, dst_type, env):
4157 if dst_type.is_pyobject:
4158 for err in self.obj_conversion_errors:
4160 self.obj_conversion_errors = []
4161 if not self.type.subtype_of(dst_type):
4162 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4163 elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
4164 base_type = dst_type.base_type
4165 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4166 for i in range(len(self.original_args)):
4168 if isinstance(arg, CoerceToPyTypeNode):
4170 self.args[i] = arg.coerce_to(base_type, env)
4171 elif dst_type.is_struct:
4172 if len(self.args) > len(dst_type.scope.var_entries):
4173 error(self.pos, "Too may members for '%s'" % dst_type)
4175 if len(self.args) < len(dst_type.scope.var_entries):
4176 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4177 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4178 if isinstance(arg, CoerceToPyTypeNode):
4180 self.args[i] = arg.coerce_to(member.type, env)
4181 self.type = dst_type
4183 self.type = error_type
4184 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4187 def release_temp(self, env):
4188 if self.type.is_array:
4189 # To be valid C++, we must allocate the memory on the stack
4190 # manually and be sure not to reuse it for something else.
4193 SequenceNode.release_temp(self, env)
4195 def calculate_constant_result(self):
4196 self.constant_result = [
4197 arg.constant_result for arg in self.args]
4199 def compile_time_value(self, denv):
4200 return self.compile_time_value_list(denv)
4202 def generate_operation_code(self, code):
4203 if self.type.is_pyobject:
4204 for err in self.obj_conversion_errors:
4206 code.putln("%s = PyList_New(%s); %s" %
4209 code.error_goto_if_null(self.result(), self.pos)))
4210 code.put_gotref(self.py_result())
4211 for i in range(len(self.args)):
4213 #if not arg.is_temp:
4214 if not arg.result_in_temp():
4215 code.put_incref(arg.result(), arg.ctype())
4216 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4220 code.put_giveref(arg.py_result())
4221 elif self.type.is_array:
4222 for i, arg in enumerate(self.args):
4223 code.putln("%s[%s] = %s;" % (
4227 elif self.type.is_struct:
4228 for arg, member in zip(self.args, self.type.scope.var_entries):
4229 code.putln("%s.%s = %s;" % (
4234 raise InternalError("List type never specified")
4236 def generate_subexpr_disposal_code(self, code):
4237 # We call generate_post_assignment_code here instead
4238 # of generate_disposal_code, because values were stored
4239 # in the list using a reference-stealing operation.
4240 for arg in self.args:
4241 arg.generate_post_assignment_code(code)
4242 # Should NOT call free_temps -- this is invoked by the default
4243 # generate_evaluation_code which will do that.
4246 class ScopedExprNode(ExprNode):
4247 # Abstract base class for ExprNodes that have their own local
4248 # scope, such as generator expressions.
4250 # expr_scope Scope the inner scope of the expression
4255 # does this node really have a local scope, e.g. does it leak loop
4256 # variables or not? non-leaking Py3 behaviour is default, except
4257 # for list comprehensions where the behaviour differs in Py2 and
4258 # Py3 (set in Parsing.py based on parser context)
4259 has_local_scope = True
4261 def init_scope(self, outer_scope, expr_scope=None):
4262 if expr_scope is not None:
4263 self.expr_scope = expr_scope
4264 elif self.has_local_scope:
4265 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4267 self.expr_scope = None
4269 def analyse_declarations(self, env):
4270 self.init_scope(env)
4272 def analyse_scoped_declarations(self, env):
4273 # this is called with the expr_scope as env
4276 def analyse_types(self, env):
4277 # no recursion here, the children will be analysed separately below
4280 def analyse_scoped_expressions(self, env):
4281 # this is called with the expr_scope as env
4284 def generate_evaluation_code(self, code):
4285 # set up local variables and free their references on exit
4286 generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
4287 if not self.has_local_scope or not self.expr_scope.var_entries:
4288 # no local variables => delegate, done
4289 generate_inner_evaluation_code(code)
4292 code.putln('{ /* enter inner scope */')
4294 for entry in self.expr_scope.var_entries:
4295 if not entry.in_closure:
4296 code.put_var_declaration(entry)
4297 if entry.type.is_pyobject and entry.used:
4298 py_entries.append(entry)
4300 # no local Python references => no cleanup required
4301 generate_inner_evaluation_code(code)
4302 code.putln('} /* exit inner scope */')
4304 for entry in py_entries:
4305 code.put_init_var_to_py_none(entry)
4307 # must free all local Python references at each exit point
4308 old_loop_labels = tuple(code.new_loop_labels())
4309 old_error_label = code.new_error_label()
4311 generate_inner_evaluation_code(code)
4313 # normal (non-error) exit
4314 for entry in py_entries:
4315 code.put_var_decref(entry)
4317 # error/loop body exit points
4318 exit_scope = code.new_label('exit_scope')
4319 code.put_goto(exit_scope)
4320 for label, old_label in ([(code.error_label, old_error_label)] +
4321 list(zip(code.get_loop_labels(), old_loop_labels))):
4322 if code.label_used(label):
4323 code.put_label(label)
4324 for entry in py_entries:
4325 code.put_var_decref(entry)
4326 code.put_goto(old_label)
4327 code.put_label(exit_scope)
4328 code.putln('} /* exit inner scope */')
4330 code.set_loop_labels(old_loop_labels)
4331 code.error_label = old_error_label
4334 class ComprehensionNode(ScopedExprNode):
4335 subexprs = ["target"]
4336 child_attrs = ["loop", "append"]
4338 def infer_type(self, env):
4339 return self.target.infer_type(env)
4341 def analyse_declarations(self, env):
4342 self.append.target = self # this is used in the PyList_Append of the inner loop
4343 self.init_scope(env)
4345 def analyse_scoped_declarations(self, env):
4346 self.loop.analyse_declarations(env)
4348 def analyse_types(self, env):
4349 self.target.analyse_expressions(env)
4350 self.type = self.target.type
4351 if not self.has_local_scope:
4352 self.loop.analyse_expressions(env)
4354 def analyse_scoped_expressions(self, env):
4355 if self.has_local_scope:
4356 self.loop.analyse_expressions(env)
4358 def may_be_none(self):
4361 def calculate_result_code(self):
4362 return self.target.result()
4364 def generate_result_code(self, code):
4365 self.generate_operation_code(code)
4367 def generate_operation_code(self, code):
4368 self.loop.generate_execution_code(code)
4370 def annotate(self, code):
4371 self.loop.annotate(code)
4374 class ComprehensionAppendNode(Node):
4375 # Need to be careful to avoid infinite recursion:
4376 # target must not be in child_attrs/subexprs
4378 child_attrs = ['expr']
4380 type = PyrexTypes.c_int_type
4382 def analyse_expressions(self, env):
4383 self.expr.analyse_expressions(env)
4384 if not self.expr.type.is_pyobject:
4385 self.expr = self.expr.coerce_to_pyobject(env)
4387 def generate_execution_code(self, code):
4388 if self.target.type is list_type:
4389 function = "PyList_Append"
4390 elif self.target.type is set_type:
4391 function = "PySet_Add"
4393 raise InternalError(
4394 "Invalid type for comprehension node: %s" % self.target.type)
4396 self.expr.generate_evaluation_code(code)
4397 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4399 self.target.result(),
4402 self.expr.generate_disposal_code(code)
4403 self.expr.free_temps(code)
4405 def generate_function_definitions(self, env, code):
4406 self.expr.generate_function_definitions(env, code)
4408 def annotate(self, code):
4409 self.expr.annotate(code)
4411 class DictComprehensionAppendNode(ComprehensionAppendNode):
4412 child_attrs = ['key_expr', 'value_expr']
4414 def analyse_expressions(self, env):
4415 self.key_expr.analyse_expressions(env)
4416 if not self.key_expr.type.is_pyobject:
4417 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4418 self.value_expr.analyse_expressions(env)
4419 if not self.value_expr.type.is_pyobject:
4420 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4422 def generate_execution_code(self, code):
4423 self.key_expr.generate_evaluation_code(code)
4424 self.value_expr.generate_evaluation_code(code)
4425 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4426 self.target.result(),
4427 self.key_expr.result(),
4428 self.value_expr.result()
4430 self.key_expr.generate_disposal_code(code)
4431 self.key_expr.free_temps(code)
4432 self.value_expr.generate_disposal_code(code)
4433 self.value_expr.free_temps(code)
4435 def generate_function_definitions(self, env, code):
4436 self.key_expr.generate_function_definitions(env, code)
4437 self.value_expr.generate_function_definitions(env, code)
4439 def annotate(self, code):
4440 self.key_expr.annotate(code)
4441 self.value_expr.annotate(code)
4444 class InlinedGeneratorExpressionNode(ScopedExprNode):
4445 # An inlined generator expression for which the result is
4446 # calculated inside of the loop. This will only be created by
4447 # transforms when replacing builtin calls on generator
4450 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4451 # result_node ResultRefNode the reference to the result value temp
4452 # orig_func String the name of the builtin function this node replaces
4454 child_attrs = ["loop"]
4455 loop_analysed = False
4456 type = py_object_type
4458 def analyse_scoped_declarations(self, env):
4459 self.loop.analyse_declarations(env)
4461 def analyse_types(self, env):
4462 if not self.has_local_scope:
4463 self.loop.analyse_expressions(env)
4466 def may_be_none(self):
4469 def annotate(self, code):
4470 self.loop.annotate(code)
4472 def infer_type(self, env):
4473 return self.result_node.infer_type(env)
4475 def analyse_types(self, env):
4476 if not self.has_local_scope:
4477 self.loop_analysed = True
4478 self.loop.analyse_expressions(env)
4479 self.type = self.result_node.type
4482 def analyse_scoped_expressions(self, env):
4483 self.loop_analysed = True
4484 if self.has_local_scope:
4485 self.loop.analyse_expressions(env)
4487 def coerce_to(self, dst_type, env):
4488 if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
4489 # We can optimise by dropping the aggregation variable and
4490 # the add operations into C. This can only be done safely
4491 # before analysing the loop body, after that, the result
4492 # reference type will have infected expressions and
4494 self.result_node.type = self.type = dst_type
4496 return super(InlinedGeneratorExpressionNode, self).coerce_to(dst_type, env)
4498 def generate_result_code(self, code):
4499 self.result_node.result_code = self.result()
4500 self.loop.generate_execution_code(code)
4503 class SetNode(ExprNode):
4510 gil_message = "Constructing Python set"
4512 def analyse_types(self, env):
4513 for i in range(len(self.args)):
4515 arg.analyse_types(env)
4516 self.args[i] = arg.coerce_to_pyobject(env)
4517 self.type = set_type
4520 def may_be_none(self):
4523 def calculate_constant_result(self):
4524 self.constant_result = set([
4525 arg.constant_result for arg in self.args])
4527 def compile_time_value(self, denv):
4528 values = [arg.compile_time_value(denv) for arg in self.args]
4531 except Exception, e:
4532 self.compile_time_value_error(e)
4534 def generate_evaluation_code(self, code):
4535 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4536 self.allocate_temp_result(code)
4538 "%s = PySet_New(0); %s" % (
4540 code.error_goto_if_null(self.result(), self.pos)))
4541 code.put_gotref(self.py_result())
4542 for arg in self.args:
4543 arg.generate_evaluation_code(code)
4545 code.error_goto_if_neg(
4546 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4548 arg.generate_disposal_code(code)
4549 arg.free_temps(code)
4552 class DictNode(ExprNode):
4553 # Dictionary constructor.
4555 # key_value_pairs [DictItemNode]
4557 # obj_conversion_errors [PyrexError] used internally
4559 subexprs = ['key_value_pairs']
4563 obj_conversion_errors = []
4565 def calculate_constant_result(self):
4566 self.constant_result = dict([
4567 item.constant_result for item in self.key_value_pairs])
4569 def compile_time_value(self, denv):
4570 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4571 for item in self.key_value_pairs]
4574 except Exception, e:
4575 self.compile_time_value_error(e)
4577 def type_dependencies(self, env):
4580 def infer_type(self, env):
4581 # TOOD: Infer struct constructors.
4584 def analyse_types(self, env):
4586 for item in self.key_value_pairs:
4587 item.analyse_types(env)
4588 self.obj_conversion_errors = held_errors()
4589 release_errors(ignore=True)
4591 def may_be_none(self):
4594 def coerce_to(self, dst_type, env):
4595 if dst_type.is_pyobject:
4596 self.release_errors()
4597 if not self.type.subtype_of(dst_type):
4598 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4599 elif dst_type.is_struct_or_union:
4600 self.type = dst_type
4601 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4602 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4603 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4604 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4605 for item in self.key_value_pairs:
4606 if isinstance(item.key, CoerceToPyTypeNode):
4607 item.key = item.key.arg
4608 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4609 error(item.key.pos, "Invalid struct field identifier")
4610 item.key = StringNode(item.key.pos, value="<error>")
4612 key = str(item.key.value) # converts string literals to unicode in Py3
4613 member = dst_type.scope.lookup_here(key)
4615 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4618 if isinstance(value, CoerceToPyTypeNode):
4620 item.value = value.coerce_to(member.type, env)
4622 self.type = error_type
4623 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4626 def release_errors(self):
4627 for err in self.obj_conversion_errors:
4629 self.obj_conversion_errors = []
4631 gil_message = "Constructing Python dict"
4633 def generate_evaluation_code(self, code):
4634 # Custom method used here because key-value
4635 # pairs are evaluated and used one at a time.
4636 code.mark_pos(self.pos)
4637 self.allocate_temp_result(code)
4638 if self.type.is_pyobject:
4639 self.release_errors()
4641 "%s = PyDict_New(); %s" % (
4643 code.error_goto_if_null(self.result(), self.pos)))
4644 code.put_gotref(self.py_result())
4645 for item in self.key_value_pairs:
4646 item.generate_evaluation_code(code)
4647 if self.type.is_pyobject:
4648 code.put_error_if_neg(self.pos,
4649 "PyDict_SetItem(%s, %s, %s)" % (
4651 item.key.py_result(),
4652 item.value.py_result()))
4654 code.putln("%s.%s = %s;" % (
4657 item.value.result()))
4658 item.generate_disposal_code(code)
4659 item.free_temps(code)
4661 def annotate(self, code):
4662 for item in self.key_value_pairs:
4665 class DictItemNode(ExprNode):
4666 # Represents a single item in a DictNode
4670 subexprs = ['key', 'value']
4672 nogil_check = None # Parent DictNode takes care of it
4674 def calculate_constant_result(self):
4675 self.constant_result = (
4676 self.key.constant_result, self.value.constant_result)
4678 def analyse_types(self, env):
4679 self.key.analyse_types(env)
4680 self.value.analyse_types(env)
4681 self.key = self.key.coerce_to_pyobject(env)
4682 self.value = self.value.coerce_to_pyobject(env)
4684 def generate_evaluation_code(self, code):
4685 self.key.generate_evaluation_code(code)
4686 self.value.generate_evaluation_code(code)
4688 def generate_disposal_code(self, code):
4689 self.key.generate_disposal_code(code)
4690 self.value.generate_disposal_code(code)
4692 def free_temps(self, code):
4693 self.key.free_temps(code)
4694 self.value.free_temps(code)
4697 return iter([self.key, self.value])
4699 class ModuleNameMixin(object):
4700 def set_mod_name(self, env):
4701 self.module_name = env.global_scope().qualified_name
4703 def get_py_mod_name(self, code):
4704 return code.get_py_string_const(
4705 self.module_name, identifier=True)
4707 class ClassNode(ExprNode, ModuleNameMixin):
4708 # Helper class used in the implementation of Python
4709 # class definitions. Constructs a class object given
4710 # a name, tuple of bases and class dictionary.
4712 # name EncodedString Name of the class
4713 # bases ExprNode Base class tuple
4714 # dict ExprNode Class dict (not owned by this node)
4715 # doc ExprNode or None Doc string
4716 # module_name EncodedString Name of defining module
4718 subexprs = ['bases', 'doc']
4720 def analyse_types(self, env):
4721 self.bases.analyse_types(env)
4723 self.doc.analyse_types(env)
4724 self.doc = self.doc.coerce_to_pyobject(env)
4725 self.type = py_object_type
4727 env.use_utility_code(create_class_utility_code);
4728 #TODO(craig,haoyu) This should be moved to a better place
4729 self.set_mod_name(env)
4731 def may_be_none(self):
4734 gil_message = "Constructing Python class"
4736 def generate_result_code(self, code):
4737 cname = code.intern_identifier(self.name)
4740 code.put_error_if_neg(self.pos,
4741 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4742 self.dict.py_result(),
4743 self.doc.py_result()))
4744 py_mod_name = self.get_py_mod_name(code)
4746 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4748 self.bases.py_result(),
4749 self.dict.py_result(),
4752 code.error_goto_if_null(self.result(), self.pos)))
4753 code.put_gotref(self.py_result())
4756 class Py3ClassNode(ExprNode):
4757 # Helper class used in the implementation of Python3+
4758 # class definitions. Constructs a class object given
4759 # a name, tuple of bases and class dictionary.
4761 # name EncodedString Name of the class
4762 # dict ExprNode Class dict (not owned by this node)
4763 # module_name EncodedString Name of defining module
4767 def analyse_types(self, env):
4768 self.type = py_object_type
4771 def may_be_none(self):
4774 gil_message = "Constructing Python class"
4776 def generate_result_code(self, code):
4777 code.globalstate.use_utility_code(create_py3class_utility_code)
4778 cname = code.intern_identifier(self.name)
4780 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4782 self.metaclass.result(),
4784 self.bases.py_result(),
4785 self.dict.py_result(),
4786 self.mkw.py_result(),
4787 code.error_goto_if_null(self.result(), self.pos)))
4788 code.put_gotref(self.py_result())
4790 class KeywordArgsNode(ExprNode):
4791 # Helper class for keyword arguments
4793 # keyword_args ExprNode or None Keyword arguments
4794 # starstar_arg ExprNode or None Extra arguments
4796 subexprs = ['keyword_args', 'starstar_arg']
4798 def analyse_types(self, env):
4799 if self.keyword_args:
4800 self.keyword_args.analyse_types(env)
4801 if self.starstar_arg:
4802 self.starstar_arg.analyse_types(env)
4803 # make sure we have a Python object as **kwargs mapping
4804 self.starstar_arg = \
4805 self.starstar_arg.coerce_to_pyobject(env)
4806 self.type = py_object_type
4809 gil_message = "Constructing Keyword Args"
4811 def generate_result_code(self, code):
4812 if self.keyword_args and self.starstar_arg:
4813 code.put_error_if_neg(self.pos,
4814 "PyDict_Update(%s, %s)" % (
4815 self.keyword_args.py_result(),
4816 self.starstar_arg.py_result()))
4817 if self.keyword_args:
4818 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4819 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4820 elif self.starstar_arg:
4822 "%s = PyDict_Copy(%s); %s" % (
4824 self.starstar_arg.py_result(),
4825 code.error_goto_if_null(self.result(), self.pos)))
4826 code.put_gotref(self.py_result())
4829 "%s = PyDict_New(); %s" % (
4831 code.error_goto_if_null(self.result(), self.pos)))
4832 code.put_gotref(self.py_result())
4834 class PyClassMetaclassNode(ExprNode):
4835 # Helper class holds Python3 metaclass object
4837 # bases ExprNode Base class tuple (not owned by this node)
4838 # mkw ExprNode Class keyword arguments (not owned by this node)
4842 def analyse_types(self, env):
4843 self.type = py_object_type
4846 def may_be_none(self):
4849 def generate_result_code(self, code):
4851 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4853 self.bases.result(),
4855 code.error_goto_if_null(self.result(), self.pos)))
4856 code.put_gotref(self.py_result())
4858 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4859 # Helper class holds Python3 namespace object
4861 # All this are not owned by this node
4862 # metaclass ExprNode Metaclass object
4863 # bases ExprNode Base class tuple
4864 # mkw ExprNode Class keyword arguments
4865 # doc ExprNode or None Doc string (owned)
4869 def analyse_types(self, env):
4870 self.bases.analyse_types(env)
4872 self.doc.analyse_types(env)
4873 self.doc = self.doc.coerce_to_pyobject(env)
4874 self.type = py_object_type
4876 #TODO(craig,haoyu) This should be moved to a better place
4877 self.set_mod_name(env)
4879 def may_be_none(self):
4882 def generate_result_code(self, code):
4883 cname = code.intern_identifier(self.name)
4884 py_mod_name = self.get_py_mod_name(code)
4886 doc_code = self.doc.result()
4888 doc_code = '(PyObject *) NULL'
4890 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4892 self.metaclass.result(),
4893 self.bases.result(),
4898 code.error_goto_if_null(self.result(), self.pos)))
4899 code.put_gotref(self.py_result())
4901 class BoundMethodNode(ExprNode):
4902 # Helper class used in the implementation of Python
4903 # class definitions. Constructs an bound method
4904 # object from a class and a function.
4906 # function ExprNode Function object
4907 # self_object ExprNode self object
4909 subexprs = ['function']
4911 def analyse_types(self, env):
4912 self.function.analyse_types(env)
4913 self.type = py_object_type
4916 gil_message = "Constructing an bound method"
4918 def generate_result_code(self, code):
4920 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4922 self.function.py_result(),
4923 self.self_object.py_result(),
4924 self.self_object.py_result(),
4925 code.error_goto_if_null(self.result(), self.pos)))
4926 code.put_gotref(self.py_result())
4928 class UnboundMethodNode(ExprNode):
4929 # Helper class used in the implementation of Python
4930 # class definitions. Constructs an unbound method
4931 # object from a class and a function.
4933 # function ExprNode Function object
4935 type = py_object_type
4938 subexprs = ['function']
4940 def analyse_types(self, env):
4941 self.function.analyse_types(env)
4943 def may_be_none(self):
4946 gil_message = "Constructing an unbound method"
4948 def generate_result_code(self, code):
4949 class_cname = code.pyclass_stack[-1].classobj.result()
4951 "%s = PyMethod_New(%s, 0, %s); %s" % (
4953 self.function.py_result(),
4955 code.error_goto_if_null(self.result(), self.pos)))
4956 code.put_gotref(self.py_result())
4959 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4960 # Helper class used in the implementation of Python
4961 # class definitions. Constructs a PyCFunction object
4962 # from a PyMethodDef struct.
4964 # pymethdef_cname string PyMethodDef structure
4965 # self_object ExprNode or None
4967 # module_name EncodedString Name of defining module
4973 type = py_object_type
4976 def analyse_types(self, env):
4978 env.use_utility_code(binding_cfunc_utility_code)
4980 #TODO(craig,haoyu) This should be moved to a better place
4981 self.set_mod_name(env)
4983 def may_be_none(self):
4986 gil_message = "Constructing Python function"
4988 def self_result_code(self):
4989 if self.self_object is None:
4990 self_result = "NULL"
4992 self_result = self.self_object.py_result()
4995 def generate_result_code(self, code):
4997 constructor = "%s_NewEx" % Naming.binding_cfunc
4999 constructor = "PyCFunction_NewEx"
5000 py_mod_name = self.get_py_mod_name(code)
5002 '%s = %s(&%s, %s, %s); %s' % (
5005 self.pymethdef_cname,
5006 self.self_result_code(),
5008 code.error_goto_if_null(self.result(), self.pos)))
5009 code.put_gotref(self.py_result())
5011 class InnerFunctionNode(PyCFunctionNode):
5012 # Special PyCFunctionNode that depends on a closure class
5016 needs_self_code = True
5018 def self_result_code(self):
5019 if self.needs_self_code:
5020 return "((PyObject*)%s)" % (Naming.cur_scope_cname)
5023 class LambdaNode(InnerFunctionNode):
5024 # Lambda expression node (only used as a function reference)
5026 # args [CArgDeclNode] formal arguments
5027 # star_arg PyArgDeclNode or None * argument
5028 # starstar_arg PyArgDeclNode or None ** argument
5029 # lambda_name string a module-globally unique lambda name
5030 # result_expr ExprNode
5031 # def_node DefNode the underlying function 'def' node
5033 child_attrs = ['def_node']
5036 name = StringEncoding.EncodedString('<lambda>')
5038 def analyse_declarations(self, env):
5039 self.def_node.analyse_declarations(env)
5040 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
5041 env.add_lambda_def(self.def_node)
5044 class GeneratorExpressionNode(LambdaNode):
5045 # A generator expression, e.g. (i for i in range(10))
5047 # Result is a generator.
5049 # loop ForStatNode the for-loop, containing a YieldExprNode
5050 # def_node DefNode the underlying generator 'def' node
5052 name = StringEncoding.EncodedString('genexpr')
5055 def analyse_declarations(self, env):
5056 self.def_node.no_assignment_synthesis = True
5057 self.def_node.analyse_declarations(env)
5058 env.add_lambda_def(self.def_node)
5060 def generate_result_code(self, code):
5062 '%s = %s(%s, NULL); %s' % (
5064 self.def_node.entry.func_cname,
5065 self.self_result_code(),
5066 code.error_goto_if_null(self.result(), self.pos)))
5067 code.put_gotref(self.py_result())
5070 class YieldExprNode(ExprNode):
5071 # Yield expression node
5073 # arg ExprNode the value to return from the generator
5074 # label_name string name of the C label used for this yield
5075 # label_num integer yield label number
5078 type = py_object_type
5081 def analyse_types(self, env):
5082 if not self.label_num:
5083 error(self.pos, "'yield' not supported here")
5085 if self.arg is not None:
5086 self.arg.analyse_types(env)
5087 if not self.arg.type.is_pyobject:
5088 self.arg = self.arg.coerce_to_pyobject(env)
5089 env.use_utility_code(generator_utility_code)
5091 def generate_evaluation_code(self, code):
5092 self.label_name = code.new_label('resume_from_yield')
5093 code.use_label(self.label_name)
5095 self.arg.generate_evaluation_code(code)
5096 self.arg.make_owned_reference(code)
5099 Naming.retval_cname,
5100 self.arg.result_as(py_object_type)))
5101 self.arg.generate_post_assignment_code(code)
5102 #self.arg.generate_disposal_code(code)
5103 self.arg.free_temps(code)
5105 code.put_init_to_py_none(Naming.retval_cname, py_object_type)
5107 code.funcstate.closure_temps.reset()
5108 for cname, type, manage_ref in code.funcstate.temps_in_use():
5109 save_cname = code.funcstate.closure_temps.allocate_temp(type)
5110 saved.append((cname, save_cname, type))
5111 if type.is_pyobject:
5112 code.put_xgiveref(cname)
5113 code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
5115 code.put_xgiveref(Naming.retval_cname)
5116 code.put_finish_refcount_context()
5117 code.putln("/* return from generator, yielding value */")
5118 code.putln("%s->%s.resume_label = %d;" % (Naming.cur_scope_cname, Naming.obj_base_cname, self.label_num))
5119 code.putln("return %s;" % Naming.retval_cname);
5120 code.put_label(self.label_name)
5121 for cname, save_cname, type in saved:
5122 code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
5123 if type.is_pyobject:
5124 code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
5125 if type.is_pyobject:
5126 code.put_xgotref(cname)
5127 if self.result_is_used:
5128 self.allocate_temp_result(code)
5129 code.putln('%s = %s; %s' %
5130 (self.result(), Naming.sent_value_cname,
5131 code.error_goto_if_null(self.result(), self.pos)))
5132 code.put_incref(self.result(), py_object_type)
5134 code.putln(code.error_goto_if_null(Naming.sent_value_cname, self.pos))
5136 #-------------------------------------------------------------------
5138 # Unary operator nodes
5140 #-------------------------------------------------------------------
5142 compile_time_unary_operators = {
5143 'not': operator.not_,
5149 class UnopNode(ExprNode):
5153 # Processing during analyse_expressions phase:
5155 # analyse_c_operation
5156 # Called when the operand is not a pyobject.
5157 # - Check operand type and coerce if needed.
5158 # - Determine result type and result code fragment.
5159 # - Allocate temporary for result if needed.
5161 subexprs = ['operand']
5164 def calculate_constant_result(self):
5165 func = compile_time_unary_operators[self.operator]
5166 self.constant_result = func(self.operand.constant_result)
5168 def compile_time_value(self, denv):
5169 func = compile_time_unary_operators.get(self.operator)
5172 "Unary '%s' not supported in compile-time expression"
5174 operand = self.operand.compile_time_value(denv)
5176 return func(operand)
5177 except Exception, e:
5178 self.compile_time_value_error(e)
5180 def infer_type(self, env):
5181 operand_type = self.operand.infer_type(env)
5182 if operand_type.is_pyobject:
5183 return py_object_type
5187 def analyse_types(self, env):
5188 self.operand.analyse_types(env)
5189 if self.is_py_operation():
5190 self.coerce_operand_to_pyobject(env)
5191 self.type = py_object_type
5193 elif self.is_cpp_operation():
5194 self.analyse_cpp_operation(env)
5196 self.analyse_c_operation(env)
5198 def check_const(self):
5199 return self.operand.check_const()
5201 def is_py_operation(self):
5202 return self.operand.type.is_pyobject
5204 def nogil_check(self, env):
5205 if self.is_py_operation():
5208 def is_cpp_operation(self):
5209 type = self.operand.type
5210 return type.is_cpp_class
5212 def coerce_operand_to_pyobject(self, env):
5213 self.operand = self.operand.coerce_to_pyobject(env)
5215 def generate_result_code(self, code):
5216 if self.operand.type.is_pyobject:
5217 self.generate_py_operation_code(code)
5219 def generate_py_operation_code(self, code):
5220 function = self.py_operation_function()
5222 "%s = %s(%s); %s" % (
5225 self.operand.py_result(),
5226 code.error_goto_if_null(self.result(), self.pos)))
5227 code.put_gotref(self.py_result())
5229 def type_error(self):
5230 if not self.operand.type.is_error:
5231 error(self.pos, "Invalid operand type for '%s' (%s)" %
5232 (self.operator, self.operand.type))
5233 self.type = PyrexTypes.error_type
5235 def analyse_cpp_operation(self, env):
5236 type = self.operand.type
5238 type = type.base_type
5239 function = type.scope.lookup("operator%s" % self.operator)
5241 error(self.pos, "'%s' operator not defined for %s"
5242 % (self.operator, type))
5245 func_type = function.type
5246 if func_type.is_ptr:
5247 func_type = func_type.base_type
5248 self.type = func_type.return_type
5251 class NotNode(ExprNode):
5256 type = PyrexTypes.c_bint_type
5258 subexprs = ['operand']
5260 def calculate_constant_result(self):
5261 self.constant_result = not self.operand.constant_result
5263 def compile_time_value(self, denv):
5264 operand = self.operand.compile_time_value(denv)
5267 except Exception, e:
5268 self.compile_time_value_error(e)
5270 def infer_type(self, env):
5271 return PyrexTypes.c_bint_type
5273 def analyse_types(self, env):
5274 self.operand.analyse_types(env)
5275 self.operand = self.operand.coerce_to_boolean(env)
5277 def calculate_result_code(self):
5278 return "(!%s)" % self.operand.result()
5280 def generate_result_code(self, code):
5284 class UnaryPlusNode(UnopNode):
5285 # unary '+' operator
5289 def analyse_c_operation(self, env):
5290 self.type = self.operand.type
5292 def py_operation_function(self):
5293 return "PyNumber_Positive"
5295 def calculate_result_code(self):
5296 if self.is_cpp_operation():
5297 return "(+%s)" % self.operand.result()
5299 return self.operand.result()
5302 class UnaryMinusNode(UnopNode):
5303 # unary '-' operator
5307 def analyse_c_operation(self, env):
5308 if self.operand.type.is_numeric:
5309 self.type = self.operand.type
5312 if self.type.is_complex:
5315 def py_operation_function(self):
5316 return "PyNumber_Negative"
5318 def calculate_result_code(self):
5320 return "(-%s)" % self.operand.result()
5322 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5324 def get_constant_c_result_code(self):
5325 value = self.operand.get_constant_c_result_code()
5327 return "(-%s)" % (value)
5329 class TildeNode(UnopNode):
5330 # unary '~' operator
5332 def analyse_c_operation(self, env):
5333 if self.operand.type.is_int:
5334 self.type = self.operand.type
5338 def py_operation_function(self):
5339 return "PyNumber_Invert"
5341 def calculate_result_code(self):
5342 return "(~%s)" % self.operand.result()
5345 class CUnopNode(UnopNode):
5347 def is_py_operation(self):
5350 class DereferenceNode(CUnopNode):
5355 def analyse_c_operation(self, env):
5356 if self.operand.type.is_ptr:
5357 self.type = self.operand.type.base_type
5361 def calculate_result_code(self):
5362 return "(*%s)" % self.operand.result()
5365 class DecrementIncrementNode(CUnopNode):
5366 # unary ++/-- operator
5368 def analyse_c_operation(self, env):
5369 if self.operand.type.is_ptr or self.operand.type.is_numeric:
5370 self.type = self.operand.type
5374 def calculate_result_code(self):
5376 return "(%s%s)" % (self.operator, self.operand.result())
5378 return "(%s%s)" % (self.operand.result(), self.operator)
5380 def inc_dec_constructor(is_prefix, operator):
5381 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5384 class AmpersandNode(ExprNode):
5385 # The C address-of operator.
5389 subexprs = ['operand']
5391 def infer_type(self, env):
5392 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5394 def analyse_types(self, env):
5395 self.operand.analyse_types(env)
5396 argtype = self.operand.type
5397 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5398 self.error("Taking address of non-lvalue")
5400 if argtype.is_pyobject:
5401 self.error("Cannot take address of Python variable")
5403 self.type = PyrexTypes.c_ptr_type(argtype)
5405 def check_const(self):
5406 return self.operand.check_const_addr()
5408 def error(self, mess):
5409 error(self.pos, mess)
5410 self.type = PyrexTypes.error_type
5411 self.result_code = "<error>"
5413 def calculate_result_code(self):
5414 return "(&%s)" % self.operand.result()
5416 def generate_result_code(self, code):
5420 unop_node_classes = {
5422 "-": UnaryMinusNode,
5426 def unop_node(pos, operator, operand):
5427 # Construct unnop node of appropriate class for
5429 if isinstance(operand, IntNode) and operator == '-':
5430 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5431 elif isinstance(operand, UnopNode) and operand.operator == operator:
5432 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5433 return unop_node_classes[operator](pos,
5434 operator = operator,
5438 class TypecastNode(ExprNode):
5442 # base_type CBaseTypeNode
5443 # declarator CDeclaratorNode
5445 # If used from a transform, one can if wanted specify the attribute
5446 # "type" directly and leave base_type and declarator to None
5448 subexprs = ['operand']
5449 base_type = declarator = type = None
5451 def type_dependencies(self, env):
5454 def infer_type(self, env):
5455 if self.type is None:
5456 base_type = self.base_type.analyse(env)
5457 _, self.type = self.declarator.analyse(base_type, env)
5460 def analyse_types(self, env):
5461 if self.type is None:
5462 base_type = self.base_type.analyse(env)
5463 _, self.type = self.declarator.analyse(base_type, env)
5464 if self.type.is_cfunction:
5466 "Cannot cast to a function type")
5467 self.type = PyrexTypes.error_type
5468 self.operand.analyse_types(env)
5469 to_py = self.type.is_pyobject
5470 from_py = self.operand.type.is_pyobject
5471 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5472 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5473 if to_py and not from_py:
5474 if self.type is bytes_type and self.operand.type.is_int:
5475 # FIXME: the type cast node isn't needed in this case
5476 # and can be dropped once analyse_types() can return a
5478 self.operand = CoerceIntToBytesNode(self.operand, env)
5479 elif self.operand.type.can_coerce_to_pyobject(env):
5480 self.result_ctype = py_object_type
5481 self.operand = self.operand.coerce_to_pyobject(env)
5483 if self.operand.type.is_ptr:
5484 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5485 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5487 # Should this be an error?
5488 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5489 self.operand = self.operand.coerce_to_simple(env)
5490 elif from_py and not to_py:
5491 if self.type.create_from_py_utility_code(env):
5492 self.operand = self.operand.coerce_to(self.type, env)
5493 elif self.type.is_ptr:
5494 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5495 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5497 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5498 elif from_py and to_py:
5499 if self.typecheck and self.type.is_extension_type:
5500 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5501 elif self.type.is_complex and self.operand.type.is_complex:
5502 self.operand = self.operand.coerce_to_simple(env)
5504 def is_simple(self):
5505 # either temp or a C cast => no side effects
5508 def nonlocally_immutable(self):
5509 return self.operand.nonlocally_immutable()
5511 def nogil_check(self, env):
5512 if self.type and self.type.is_pyobject and self.is_temp:
5515 def check_const(self):
5516 return self.operand.check_const()
5518 def calculate_constant_result(self):
5519 # we usually do not know the result of a type cast at code
5523 def calculate_result_code(self):
5524 if self.type.is_complex:
5525 operand_result = self.operand.result()
5526 if self.operand.type.is_complex:
5527 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5528 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5530 real_part = self.type.real_type.cast_code(operand_result)
5532 return "%s(%s, %s)" % (
5533 self.type.from_parts,
5537 return self.type.cast_code(self.operand.result())
5539 def get_constant_c_result_code(self):
5540 operand_result = self.operand.get_constant_c_result_code()
5542 return self.type.cast_code(operand_result)
5544 def result_as(self, type):
5545 if self.type.is_pyobject and not self.is_temp:
5546 # Optimise away some unnecessary casting
5547 return self.operand.result_as(type)
5549 return ExprNode.result_as(self, type)
5551 def generate_result_code(self, code):
5554 "%s = (PyObject *)%s;" % (
5556 self.operand.result()))
5557 code.put_incref(self.result(), self.ctype())
5560 class SizeofNode(ExprNode):
5561 # Abstract base class for sizeof(x) expression nodes.
5563 type = PyrexTypes.c_size_t_type
5565 def check_const(self):
5568 def generate_result_code(self, code):
5572 class SizeofTypeNode(SizeofNode):
5573 # C sizeof function applied to a type
5575 # base_type CBaseTypeNode
5576 # declarator CDeclaratorNode
5581 def analyse_types(self, env):
5582 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5583 # this could be better handled by more uniformly treating types as runtime-available objects
5584 if 0 and self.base_type.module_path:
5585 path = self.base_type.module_path
5586 obj = env.lookup(path[0])
5587 if obj.as_module is None:
5588 operand = NameNode(pos=self.pos, name=path[0])
5589 for attr in path[1:]:
5590 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5591 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5592 self.operand = operand
5593 self.__class__ = SizeofVarNode
5594 self.analyse_types(env)
5596 if self.arg_type is None:
5597 base_type = self.base_type.analyse(env)
5598 _, arg_type = self.declarator.analyse(base_type, env)
5599 self.arg_type = arg_type
5602 def check_type(self):
5603 arg_type = self.arg_type
5604 if arg_type.is_pyobject and not arg_type.is_extension_type:
5605 error(self.pos, "Cannot take sizeof Python object")
5606 elif arg_type.is_void:
5607 error(self.pos, "Cannot take sizeof void")
5608 elif not arg_type.is_complete():
5609 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5611 def calculate_result_code(self):
5612 if self.arg_type.is_extension_type:
5613 # the size of the pointer is boring
5614 # we want the size of the actual struct
5615 arg_code = self.arg_type.declaration_code("", deref=1)
5617 arg_code = self.arg_type.declaration_code("")
5618 return "(sizeof(%s))" % arg_code
5621 class SizeofVarNode(SizeofNode):
5622 # C sizeof function applied to a variable
5626 subexprs = ['operand']
5628 def analyse_types(self, env):
5629 # We may actually be looking at a type rather than a variable...
5630 # If we are, traditional analysis would fail...
5631 operand_as_type = self.operand.analyse_as_type(env)
5633 self.arg_type = operand_as_type
5634 self.__class__ = SizeofTypeNode
5637 self.operand.analyse_types(env)
5639 def calculate_result_code(self):
5640 return "(sizeof(%s))" % self.operand.result()
5642 def generate_result_code(self, code):
5645 class TypeofNode(ExprNode):
5646 # Compile-time type of an expression, as a string.
5649 # literal StringNode # internal
5652 type = py_object_type
5654 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5656 def analyse_types(self, env):
5657 self.operand.analyse_types(env)
5658 self.literal = StringNode(
5659 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5660 self.literal.analyse_types(env)
5661 self.literal = self.literal.coerce_to_pyobject(env)
5663 def may_be_none(self):
5666 def generate_evaluation_code(self, code):
5667 self.literal.generate_evaluation_code(code)
5669 def calculate_result_code(self):
5670 return self.literal.calculate_result_code()
5672 #-------------------------------------------------------------------
5674 # Binary operator nodes
5676 #-------------------------------------------------------------------
5678 def _not_in(x, seq):
5681 compile_time_binary_operators = {
5689 'is_not': operator.is_not,
5692 '/': operator.truediv,
5693 '//': operator.floordiv,
5694 '<<': operator.lshift,
5699 '>>': operator.rshift,
5702 'in': operator.contains,
5706 def get_compile_time_binop(node):
5707 func = compile_time_binary_operators.get(node.operator)
5710 "Binary '%s' not supported in compile-time expression"
5714 class BinopNode(ExprNode):
5719 # Processing during analyse_expressions phase:
5721 # analyse_c_operation
5722 # Called when neither operand is a pyobject.
5723 # - Check operand types and coerce if needed.
5724 # - Determine result type and result code fragment.
5725 # - Allocate temporary for result if needed.
5727 subexprs = ['operand1', 'operand2']
5730 def calculate_constant_result(self):
5731 func = compile_time_binary_operators[self.operator]
5732 self.constant_result = func(
5733 self.operand1.constant_result,
5734 self.operand2.constant_result)
5736 def compile_time_value(self, denv):
5737 func = get_compile_time_binop(self)
5738 operand1 = self.operand1.compile_time_value(denv)
5739 operand2 = self.operand2.compile_time_value(denv)
5741 return func(operand1, operand2)
5742 except Exception, e:
5743 self.compile_time_value_error(e)
5745 def infer_type(self, env):
5746 return self.result_type(self.operand1.infer_type(env),
5747 self.operand2.infer_type(env))
5749 def analyse_types(self, env):
5750 self.operand1.analyse_types(env)
5751 self.operand2.analyse_types(env)
5752 self.analyse_operation(env)
5754 def analyse_operation(self, env):
5755 if self.is_py_operation():
5756 self.coerce_operands_to_pyobjects(env)
5757 self.type = self.result_type(self.operand1.type,
5759 assert self.type.is_pyobject
5761 elif self.is_cpp_operation():
5762 self.analyse_cpp_operation(env)
5764 self.analyse_c_operation(env)
5766 def is_py_operation(self):
5767 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5769 def is_py_operation_types(self, type1, type2):
5770 return type1.is_pyobject or type2.is_pyobject
5772 def is_cpp_operation(self):
5773 return (self.operand1.type.is_cpp_class
5774 or self.operand2.type.is_cpp_class)
5776 def analyse_cpp_operation(self, env):
5777 type1 = self.operand1.type
5778 type2 = self.operand2.type
5779 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5783 func_type = entry.type
5784 if func_type.is_ptr:
5785 func_type = func_type.base_type
5786 if len(func_type.args) == 1:
5787 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5789 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5790 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5791 self.type = func_type.return_type
5793 def result_type(self, type1, type2):
5794 if self.is_py_operation_types(type1, type2):
5796 type2 = Builtin.bytes_type
5798 type1 = Builtin.bytes_type
5799 elif self.operator == '%' \
5800 and type1 in (Builtin.str_type, Builtin.unicode_type):
5801 # note that b'%s' % b'abc' doesn't work in Py3
5803 if type1.is_builtin_type:
5805 if self.operator in '**%+|&^':
5806 # FIXME: at least these operators should be safe - others?
5808 elif self.operator == '*':
5809 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5811 # multiplication of containers/numbers with an
5812 # integer value always (?) returns the same type
5815 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5816 # multiplication of containers/numbers with an
5817 # integer value always (?) returns the same type
5819 return py_object_type
5821 return self.compute_c_result_type(type1, type2)
5823 def nogil_check(self, env):
5824 if self.is_py_operation():
5827 def coerce_operands_to_pyobjects(self, env):
5828 self.operand1 = self.operand1.coerce_to_pyobject(env)
5829 self.operand2 = self.operand2.coerce_to_pyobject(env)
5831 def check_const(self):
5832 return self.operand1.check_const() and self.operand2.check_const()
5834 def generate_result_code(self, code):
5835 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5836 if self.operand1.type.is_pyobject:
5837 function = self.py_operation_function()
5838 if self.operator == '**':
5839 extra_args = ", Py_None"
5843 "%s = %s(%s, %s%s); %s" % (
5846 self.operand1.py_result(),
5847 self.operand2.py_result(),
5849 code.error_goto_if_null(self.result(), self.pos)))
5850 code.put_gotref(self.py_result())
5852 def type_error(self):
5853 if not (self.operand1.type.is_error
5854 or self.operand2.type.is_error):
5855 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5856 (self.operator, self.operand1.type,
5857 self.operand2.type))
5858 self.type = PyrexTypes.error_type
5861 class CBinopNode(BinopNode):
5863 def analyse_types(self, env):
5864 BinopNode.analyse_types(self, env)
5865 if self.is_py_operation():
5866 self.type = PyrexTypes.error_type
5868 def py_operation_function():
5871 def calculate_result_code(self):
5872 return "(%s %s %s)" % (
5873 self.operand1.result(),
5875 self.operand2.result())
5878 def c_binop_constructor(operator):
5879 def make_binop_node(pos, **operands):
5880 return CBinopNode(pos, operator=operator, **operands)
5881 return make_binop_node
5883 class NumBinopNode(BinopNode):
5884 # Binary operation taking numeric arguments.
5888 def analyse_c_operation(self, env):
5889 type1 = self.operand1.type
5890 type2 = self.operand2.type
5891 self.type = self.compute_c_result_type(type1, type2)
5895 if self.type.is_complex:
5897 if not self.infix or (type1.is_numeric and type2.is_numeric):
5898 self.operand1 = self.operand1.coerce_to(self.type, env)
5899 self.operand2 = self.operand2.coerce_to(self.type, env)
5901 def compute_c_result_type(self, type1, type2):
5902 if self.c_types_okay(type1, type2):
5903 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5904 if widest_type is PyrexTypes.c_bint_type:
5905 if self.operator not in '|^&':
5906 # False + False == 0 # not False!
5907 widest_type = PyrexTypes.c_int_type
5912 def get_constant_c_result_code(self):
5913 value1 = self.operand1.get_constant_c_result_code()
5914 value2 = self.operand2.get_constant_c_result_code()
5915 if value1 and value2:
5916 return "(%s %s %s)" % (value1, self.operator, value2)
5920 def c_types_okay(self, type1, type2):
5921 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5922 return (type1.is_numeric or type1.is_enum) \
5923 and (type2.is_numeric or type2.is_enum)
5925 def calculate_result_code(self):
5927 return "(%s %s %s)" % (
5928 self.operand1.result(),
5930 self.operand2.result())
5932 func = self.type.binary_op(self.operator)
5934 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5935 return "%s(%s, %s)" % (
5937 self.operand1.result(),
5938 self.operand2.result())
5940 def is_py_operation_types(self, type1, type2):
5941 return (type1.is_unicode_char or
5942 type2.is_unicode_char or
5943 BinopNode.is_py_operation_types(self, type1, type2))
5945 def py_operation_function(self):
5946 fuction = self.py_functions[self.operator]
5948 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
5953 "^": "PyNumber_Xor",
5954 "&": "PyNumber_And",
5955 "<<": "PyNumber_Lshift",
5956 ">>": "PyNumber_Rshift",
5957 "+": "PyNumber_Add",
5958 "-": "PyNumber_Subtract",
5959 "*": "PyNumber_Multiply",
5960 "/": "__Pyx_PyNumber_Divide",
5961 "//": "PyNumber_FloorDivide",
5962 "%": "PyNumber_Remainder",
5963 "**": "PyNumber_Power"
5966 class IntBinopNode(NumBinopNode):
5967 # Binary operation taking integer arguments.
5969 def c_types_okay(self, type1, type2):
5970 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5971 return (type1.is_int or type1.is_enum) \
5972 and (type2.is_int or type2.is_enum)
5975 class AddNode(NumBinopNode):
5978 def is_py_operation_types(self, type1, type2):
5979 if type1.is_string and type2.is_string:
5982 return NumBinopNode.is_py_operation_types(self, type1, type2)
5984 def compute_c_result_type(self, type1, type2):
5985 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5986 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5988 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5991 return NumBinopNode.compute_c_result_type(
5995 class SubNode(NumBinopNode):
5998 def compute_c_result_type(self, type1, type2):
5999 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
6001 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
6002 return PyrexTypes.c_int_type
6004 return NumBinopNode.compute_c_result_type(
6008 class MulNode(NumBinopNode):
6011 def is_py_operation_types(self, type1, type2):
6012 if (type1.is_string and type2.is_int) \
6013 or (type2.is_string and type1.is_int):
6016 return NumBinopNode.is_py_operation_types(self, type1, type2)
6019 class DivNode(NumBinopNode):
6020 # '/' or '//' operator.
6023 truedivision = None # == "unknown" if operator == '/'
6024 ctruedivision = False
6025 cdivision_warnings = False
6026 zerodivision_check = None
6028 def find_compile_time_binary_operator(self, op1, op2):
6029 func = compile_time_binary_operators[self.operator]
6030 if self.operator == '/' and self.truedivision is None:
6031 # => true div for floats, floor div for integers
6032 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
6033 func = compile_time_binary_operators['//']
6036 def calculate_constant_result(self):
6037 op1 = self.operand1.constant_result
6038 op2 = self.operand2.constant_result
6039 func = self.find_compile_time_binary_operator(op1, op2)
6040 self.constant_result = func(
6041 self.operand1.constant_result,
6042 self.operand2.constant_result)
6044 def compile_time_value(self, denv):
6045 operand1 = self.operand1.compile_time_value(denv)
6046 operand2 = self.operand2.compile_time_value(denv)
6048 func = self.find_compile_time_binary_operator(
6049 self, operand1, operand2)
6050 return func(operand1, operand2)
6051 except Exception, e:
6052 self.compile_time_value_error(e)
6054 def analyse_operation(self, env):
6055 if self.cdivision or env.directives['cdivision']:
6056 self.ctruedivision = False
6058 self.ctruedivision = self.truedivision
6059 NumBinopNode.analyse_operation(self, env)
6060 if self.is_cpp_operation():
6061 self.cdivision = True
6062 if not self.type.is_pyobject:
6063 self.zerodivision_check = (
6064 self.cdivision is None and not env.directives['cdivision']
6065 and (not self.operand2.has_constant_result() or
6066 self.operand2.constant_result == 0))
6067 if self.zerodivision_check or env.directives['cdivision_warnings']:
6068 # Need to check ahead of time to warn or raise zero division error
6069 self.operand1 = self.operand1.coerce_to_simple(env)
6070 self.operand2 = self.operand2.coerce_to_simple(env)
6072 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
6074 def compute_c_result_type(self, type1, type2):
6075 if self.operator == '/' and self.ctruedivision:
6076 if not type1.is_float and not type2.is_float:
6077 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
6078 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
6080 return NumBinopNode.compute_c_result_type(self, type1, type2)
6082 def zero_division_message(self):
6083 if self.type.is_int:
6084 return "integer division or modulo by zero"
6086 return "float division"
6088 def generate_evaluation_code(self, code):
6089 if not self.type.is_pyobject and not self.type.is_complex:
6090 if self.cdivision is None:
6091 self.cdivision = (code.globalstate.directives['cdivision']
6092 or not self.type.signed
6093 or self.type.is_float)
6094 if not self.cdivision:
6095 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
6096 NumBinopNode.generate_evaluation_code(self, code)
6097 self.generate_div_warning_code(code)
6099 def generate_div_warning_code(self, code):
6100 if not self.type.is_pyobject:
6101 if self.zerodivision_check:
6103 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
6105 zero_test = "%s == 0" % self.operand2.result()
6106 code.putln("if (unlikely(%s)) {" % zero_test)
6107 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
6108 code.putln(code.error_goto(self.pos))
6110 if self.type.is_int and self.type.signed and self.operator != '%':
6111 code.globalstate.use_utility_code(division_overflow_test_code)
6112 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6113 self.type.declaration_code(''),
6114 self.operand2.result(),
6115 self.operand1.result()))
6116 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
6117 code.putln(code.error_goto(self.pos))
6119 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6120 code.globalstate.use_utility_code(cdivision_warning_utility_code)
6121 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
6122 self.operand1.result(),
6123 self.operand2.result()))
6124 code.putln(code.set_error_info(self.pos));
6125 code.put("if (__Pyx_cdivision_warning()) ")
6126 code.put_goto(code.error_label)
6129 def calculate_result_code(self):
6130 if self.type.is_complex:
6131 return NumBinopNode.calculate_result_code(self)
6132 elif self.type.is_float and self.operator == '//':
6133 return "floor(%s / %s)" % (
6134 self.operand1.result(),
6135 self.operand2.result())
6136 elif self.truedivision or self.cdivision:
6137 op1 = self.operand1.result()
6138 op2 = self.operand2.result()
6139 if self.truedivision:
6140 if self.type != self.operand1.type:
6141 op1 = self.type.cast_code(op1)
6142 if self.type != self.operand2.type:
6143 op2 = self.type.cast_code(op2)
6144 return "(%s / %s)" % (op1, op2)
6146 return "__Pyx_div_%s(%s, %s)" % (
6147 self.type.specialization_name(),
6148 self.operand1.result(),
6149 self.operand2.result())
6152 class ModNode(DivNode):
6155 def is_py_operation_types(self, type1, type2):
6156 return (type1.is_string
6158 or NumBinopNode.is_py_operation_types(self, type1, type2))
6160 def zero_division_message(self):
6161 if self.type.is_int:
6162 return "integer division or modulo by zero"
6164 return "float divmod()"
6166 def generate_evaluation_code(self, code):
6167 if not self.type.is_pyobject:
6168 if self.cdivision is None:
6169 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
6170 if not self.cdivision:
6171 if self.type.is_int:
6172 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6174 code.globalstate.use_utility_code(
6175 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6176 NumBinopNode.generate_evaluation_code(self, code)
6177 self.generate_div_warning_code(code)
6179 def calculate_result_code(self):
6181 if self.type.is_float:
6182 return "fmod%s(%s, %s)" % (
6183 self.type.math_h_modifier,
6184 self.operand1.result(),
6185 self.operand2.result())
6187 return "(%s %% %s)" % (
6188 self.operand1.result(),
6189 self.operand2.result())
6191 return "__Pyx_mod_%s(%s, %s)" % (
6192 self.type.specialization_name(),
6193 self.operand1.result(),
6194 self.operand2.result())
6196 class PowNode(NumBinopNode):
6199 def analyse_c_operation(self, env):
6200 NumBinopNode.analyse_c_operation(self, env)
6201 if self.type.is_complex:
6202 if self.type.real_type.is_float:
6203 self.operand1 = self.operand1.coerce_to(self.type, env)
6204 self.operand2 = self.operand2.coerce_to(self.type, env)
6205 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
6207 error(self.pos, "complex int powers not supported")
6208 self.pow_func = "<error>"
6209 elif self.type.is_float:
6210 self.pow_func = "pow" + self.type.math_h_modifier
6212 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
6213 env.use_utility_code(
6214 int_pow_utility_code.specialize(func_name=self.pow_func,
6215 type=self.type.declaration_code('')))
6217 def calculate_result_code(self):
6218 # Work around MSVC overloading ambiguity.
6219 def typecast(operand):
6220 if self.type == operand.type:
6221 return operand.result()
6223 return self.type.cast_code(operand.result())
6224 return "%s(%s, %s)" % (
6226 typecast(self.operand1),
6227 typecast(self.operand2))
6230 # Note: This class is temporarily "shut down" into an ineffective temp
6233 # More sophisticated temp reuse was going on before, one could have a
6234 # look at adding this again after /all/ classes are converted to the
6235 # new temp scheme. (The temp juggling cannot work otherwise).
6236 class BoolBinopNode(ExprNode):
6237 # Short-circuiting boolean operation.
6243 subexprs = ['operand1', 'operand2']
6245 def infer_type(self, env):
6246 type1 = self.operand1.infer_type(env)
6247 type2 = self.operand2.infer_type(env)
6248 return PyrexTypes.independent_spanning_type(type1, type2)
6250 def may_be_none(self):
6251 if self.operator == 'or':
6252 return self.operand2.may_be_none()
6254 return self.operand1.may_be_none() or self.operand2.may_be_none()
6256 def calculate_constant_result(self):
6257 if self.operator == 'and':
6258 self.constant_result = \
6259 self.operand1.constant_result and \
6260 self.operand2.constant_result
6262 self.constant_result = \
6263 self.operand1.constant_result or \
6264 self.operand2.constant_result
6266 def compile_time_value(self, denv):
6267 if self.operator == 'and':
6268 return self.operand1.compile_time_value(denv) \
6269 and self.operand2.compile_time_value(denv)
6271 return self.operand1.compile_time_value(denv) \
6272 or self.operand2.compile_time_value(denv)
6274 def coerce_to_boolean(self, env):
6275 return BoolBinopNode(
6277 operator = self.operator,
6278 operand1 = self.operand1.coerce_to_boolean(env),
6279 operand2 = self.operand2.coerce_to_boolean(env),
6280 type = PyrexTypes.c_bint_type,
6281 is_temp = self.is_temp)
6283 def analyse_types(self, env):
6284 self.operand1.analyse_types(env)
6285 self.operand2.analyse_types(env)
6286 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6287 self.operand1 = self.operand1.coerce_to(self.type, env)
6288 self.operand2 = self.operand2.coerce_to(self.type, env)
6290 # For what we're about to do, it's vital that
6291 # both operands be temp nodes.
6292 self.operand1 = self.operand1.coerce_to_simple(env)
6293 self.operand2 = self.operand2.coerce_to_simple(env)
6296 gil_message = "Truth-testing Python object"
6298 def check_const(self):
6299 return self.operand1.check_const() and self.operand2.check_const()
6301 def generate_evaluation_code(self, code):
6302 code.mark_pos(self.pos)
6303 self.operand1.generate_evaluation_code(code)
6304 test_result, uses_temp = self.generate_operand1_test(code)
6305 if self.operator == 'and':
6314 code.funcstate.release_temp(test_result)
6315 self.operand1.generate_disposal_code(code)
6316 self.operand2.generate_evaluation_code(code)
6317 self.allocate_temp_result(code)
6318 self.operand2.make_owned_reference(code)
6319 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6320 self.operand2.generate_post_assignment_code(code)
6321 self.operand2.free_temps(code)
6322 code.putln("} else {")
6323 self.operand1.make_owned_reference(code)
6324 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6325 self.operand1.generate_post_assignment_code(code)
6326 self.operand1.free_temps(code)
6329 def generate_operand1_test(self, code):
6330 # Generate code to test the truth of the first operand.
6331 if self.type.is_pyobject:
6332 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6335 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6337 self.operand1.py_result(),
6338 code.error_goto_if_neg(test_result, self.pos)))
6340 test_result = self.operand1.result()
6341 return (test_result, self.type.is_pyobject)
6344 class CondExprNode(ExprNode):
6345 # Short-circuiting conditional expression.
6349 # false_val ExprNode
6354 subexprs = ['test', 'true_val', 'false_val']
6356 def type_dependencies(self, env):
6357 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6359 def infer_type(self, env):
6360 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6361 self.false_val.infer_type(env))
6363 def calculate_constant_result(self):
6364 if self.test.constant_result:
6365 self.constant_result = self.true_val.constant_result
6367 self.constant_result = self.false_val.constant_result
6369 def analyse_types(self, env):
6370 self.test.analyse_types(env)
6371 self.test = self.test.coerce_to_boolean(env)
6372 self.true_val.analyse_types(env)
6373 self.false_val.analyse_types(env)
6374 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6375 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6376 self.true_val = self.true_val.coerce_to(self.type, env)
6377 self.false_val = self.false_val.coerce_to(self.type, env)
6379 if self.type == PyrexTypes.error_type:
6382 def type_error(self):
6383 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6384 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6385 (self.true_val.type, self.false_val.type))
6386 self.type = PyrexTypes.error_type
6388 def check_const(self):
6389 return (self.test.check_const()
6390 and self.true_val.check_const()
6391 and self.false_val.check_const())
6393 def generate_evaluation_code(self, code):
6394 # Because subexprs may not be evaluated we can use a more optimal
6395 # subexpr allocation strategy than the default, so override evaluation_code.
6397 code.mark_pos(self.pos)
6398 self.allocate_temp_result(code)
6399 self.test.generate_evaluation_code(code)
6400 code.putln("if (%s) {" % self.test.result() )
6401 self.eval_and_get(code, self.true_val)
6402 code.putln("} else {")
6403 self.eval_and_get(code, self.false_val)
6405 self.test.generate_disposal_code(code)
6406 self.test.free_temps(code)
6408 def eval_and_get(self, code, expr):
6409 expr.generate_evaluation_code(code)
6410 expr.make_owned_reference(code)
6411 code.putln("%s = %s;" % (self.result(), expr.result()))
6412 expr.generate_post_assignment_code(code)
6413 expr.free_temps(code)
6415 richcmp_constants = {
6425 class CmpNode(object):
6426 # Mixin class containing code common to PrimaryCmpNodes
6427 # and CascadedCmpNodes.
6429 special_bool_cmp_function = None
6431 def infer_type(self, env):
6432 # TODO: Actually implement this (after merging with -unstable).
6433 return py_object_type
6435 def calculate_cascaded_constant_result(self, operand1_result):
6436 func = compile_time_binary_operators[self.operator]
6437 operand2_result = self.operand2.constant_result
6438 result = func(operand1_result, operand2_result)
6440 self.cascade.calculate_cascaded_constant_result(operand2_result)
6441 if self.cascade.constant_result:
6442 self.constant_result = result and self.cascade.constant_result
6444 self.constant_result = result
6446 def cascaded_compile_time_value(self, operand1, denv):
6447 func = get_compile_time_binop(self)
6448 operand2 = self.operand2.compile_time_value(denv)
6450 result = func(operand1, operand2)
6451 except Exception, e:
6452 self.compile_time_value_error(e)
6455 cascade = self.cascade
6457 # FIXME: I bet this must call cascaded_compile_time_value()
6458 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6461 def is_cpp_comparison(self):
6462 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6464 def find_common_int_type(self, env, op, operand1, operand2):
6465 # type1 != type2 and at least one of the types is not a C int
6466 type1 = operand1.type
6467 type2 = operand2.type
6468 type1_can_be_int = False
6469 type2_can_be_int = False
6471 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6472 and operand1.can_coerce_to_char_literal():
6473 type1_can_be_int = True
6474 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6475 and operand2.can_coerce_to_char_literal():
6476 type2_can_be_int = True
6479 if type2_can_be_int:
6482 if type1_can_be_int:
6484 elif type1_can_be_int:
6485 if type2_can_be_int:
6486 return PyrexTypes.c_uchar_type
6490 def find_common_type(self, env, op, operand1, common_type=None):
6491 operand2 = self.operand2
6492 type1 = operand1.type
6493 type2 = operand2.type
6495 new_common_type = None
6497 # catch general errors
6498 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6499 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6500 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6501 new_common_type = error_type
6503 # try to use numeric comparisons where possible
6504 elif type1.is_complex or type2.is_complex:
6505 if op not in ('==', '!='):
6506 error(self.pos, "complex types are unordered")
6507 new_common_type = error_type
6508 if type1.is_pyobject:
6509 new_common_type = type1
6510 elif type2.is_pyobject:
6511 new_common_type = type2
6513 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6514 elif type1.is_numeric and type2.is_numeric:
6515 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6516 elif common_type is None or not common_type.is_pyobject:
6517 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6519 if new_common_type is None:
6520 # fall back to generic type compatibility tests
6522 new_common_type = type1
6523 elif type1.is_pyobject or type2.is_pyobject:
6524 if type2.is_numeric or type2.is_string:
6525 if operand2.check_for_coercion_error(type1):
6526 new_common_type = error_type
6528 new_common_type = py_object_type
6529 elif type1.is_numeric or type1.is_string:
6530 if operand1.check_for_coercion_error(type2):
6531 new_common_type = error_type
6533 new_common_type = py_object_type
6534 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6535 new_common_type = py_object_type
6537 # one Python type and one non-Python type, not assignable
6538 self.invalid_types_error(operand1, op, operand2)
6539 new_common_type = error_type
6540 elif type1.assignable_from(type2):
6541 new_common_type = type1
6542 elif type2.assignable_from(type1):
6543 new_common_type = type2
6545 # C types that we couldn't handle up to here are an error
6546 self.invalid_types_error(operand1, op, operand2)
6547 new_common_type = error_type
6549 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6550 isinstance(operand2, BytesNode)):
6551 # special case when comparing char* to bytes literal: must
6552 # compare string values!
6553 new_common_type = bytes_type
6555 # recursively merge types
6556 if common_type is None or new_common_type.is_error:
6557 common_type = new_common_type
6559 # we could do a lot better by splitting the comparison
6560 # into a non-Python part and a Python part, but this is
6562 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6565 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6569 def invalid_types_error(self, operand1, op, operand2):
6570 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6571 (op, operand1.type, operand2.type))
6573 def is_python_comparison(self):
6574 return (not self.is_ptr_contains()
6575 and not self.is_c_string_contains()
6576 and (self.has_python_operands()
6577 or (self.cascade and self.cascade.is_python_comparison())
6578 or self.operator in ('in', 'not_in')))
6580 def coerce_operands_to(self, dst_type, env):
6581 operand2 = self.operand2
6582 if operand2.type != dst_type:
6583 self.operand2 = operand2.coerce_to(dst_type, env)
6585 self.cascade.coerce_operands_to(dst_type, env)
6587 def is_python_result(self):
6588 return ((self.has_python_operands() and
6589 self.special_bool_cmp_function is None and
6590 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6591 not self.is_c_string_contains() and
6592 not self.is_ptr_contains())
6593 or (self.cascade and self.cascade.is_python_result()))
6595 def is_c_string_contains(self):
6596 return self.operator in ('in', 'not_in') and \
6597 ((self.operand1.type.is_int
6598 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6599 (self.operand1.type.is_unicode_char
6600 and self.operand2.type is unicode_type))
6602 def is_ptr_contains(self):
6603 if self.operator in ('in', 'not_in'):
6604 container_type = self.operand2.type
6605 return (container_type.is_ptr or container_type.is_array) \
6606 and not container_type.is_string
6608 def find_special_bool_compare_function(self, env):
6609 if self.operator in ('==', '!='):
6610 type1, type2 = self.operand1.type, self.operand2.type
6611 if type1.is_pyobject and type2.is_pyobject:
6612 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6613 env.use_utility_code(pyunicode_equals_utility_code)
6614 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6618 def generate_operation_code(self, code, result_code,
6619 operand1, op , operand2):
6620 if self.type.is_pyobject:
6621 coerce_result = "__Pyx_PyBool_FromLong"
6628 if self.special_bool_cmp_function:
6629 if operand1.type.is_pyobject:
6630 result1 = operand1.py_result()
6632 result1 = operand1.result()
6633 if operand2.type.is_pyobject:
6634 result2 = operand2.py_result()
6636 result2 = operand2.result()
6637 code.putln("%s = %s(%s, %s, %s); %s" % (
6639 self.special_bool_cmp_function,
6642 richcmp_constants[op],
6643 code.error_goto_if_neg(result_code, self.pos)))
6644 elif op == 'in' or op == 'not_in':
6645 code.globalstate.use_utility_code(contains_utility_code)
6646 if self.type.is_pyobject:
6647 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6649 negation = "__Pyx_NegateNonNeg"
6650 if operand2.type is dict_type:
6651 method = "PyDict_Contains"
6653 method = "PySequence_Contains"
6654 if self.type.is_pyobject:
6655 error_clause = code.error_goto_if_null
6656 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6658 error_clause = code.error_goto_if_neg
6661 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6666 operand2.py_result(),
6667 operand1.py_result(),
6669 error_clause(result_code, self.pos)))
6670 elif (operand1.type.is_pyobject
6671 and op not in ('is', 'is_not')):
6672 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6674 operand1.py_result(),
6675 operand2.py_result(),
6676 richcmp_constants[op],
6677 code.error_goto_if_null(result_code, self.pos)))
6678 code.put_gotref(result_code)
6679 elif operand1.type.is_complex:
6684 code.putln("%s = %s(%s%s(%s, %s));" % (
6688 operand1.type.unary_op('eq'),
6692 type1 = operand1.type
6693 type2 = operand2.type
6694 if (type1.is_extension_type or type2.is_extension_type) \
6695 and not type1.same_as(type2):
6696 common_type = py_object_type
6697 elif type1.is_numeric:
6698 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6701 code1 = operand1.result_as(common_type)
6702 code2 = operand2.result_as(common_type)
6703 code.putln("%s = %s(%s %s %s);" % (
6707 self.c_operator(op),
6710 def c_operator(self, op):
6713 elif op == 'is_not':
6718 contains_utility_code = UtilityCode(
6720 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6721 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6722 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6726 char_in_bytes_utility_code = UtilityCode(
6728 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6731 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6732 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6733 char* char_start = PyBytes_AS_STRING(bytes);
6735 for (pos=char_start; pos < char_start+length; pos++) {
6736 if (character == pos[0]) return 1;
6742 pyunicode_in_unicode_utility_code = UtilityCode(
6744 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6747 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6749 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6750 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6752 for (pos=char_start; pos < char_start+length; pos++) {
6753 if (unlikely(character == pos[0])) return 1;
6759 py_ucs4_in_unicode_utility_code = UtilityCode(
6761 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
6763 # additionally handles surrogate pairs in 16bit Unicode builds
6765 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
6768 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6769 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6771 #if Py_UNICODE_SIZE == 2
6772 if (unlikely(character > 65535)) {
6773 Py_UNICODE high_val, low_val;
6774 high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
6775 low_val = (Py_UNICODE) (0xDC00 | ( (character - 0x10000) & ((1<<10)-1)));
6776 for (pos=char_start; pos < char_start+length-1; pos++) {
6777 if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
6782 uchar = (Py_UNICODE) character;
6783 for (pos=char_start; pos < char_start+length; pos++) {
6784 if (unlikely(uchar == pos[0])) return 1;
6790 pyunicode_equals_utility_code = UtilityCode(
6792 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6795 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6796 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6797 return (equals == Py_EQ);
6798 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6799 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6800 return (equals == Py_NE);
6801 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6802 if (equals == Py_EQ)
6803 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6805 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6807 int result = PyUnicode_Compare(s1, s2);
6808 if ((result == -1) && unlikely(PyErr_Occurred()))
6810 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6812 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6813 return (equals == Py_EQ);
6814 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6815 return (equals == Py_NE);
6816 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6817 return (equals == Py_NE);
6820 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6823 result = __Pyx_PyObject_IsTrue(py_result);
6824 Py_DECREF(py_result);
6831 class PrimaryCmpNode(ExprNode, CmpNode):
6832 # Non-cascaded comparison or first comparison of
6833 # a cascaded sequence.
6838 # cascade CascadedCmpNode
6840 # We don't use the subexprs mechanism, because
6841 # things here are too complicated for it to handle.
6842 # Instead, we override all the framework methods
6845 child_attrs = ['operand1', 'operand2', 'cascade']
6849 def infer_type(self, env):
6850 # TODO: Actually implement this (after merging with -unstable).
6851 return py_object_type
6853 def type_dependencies(self, env):
6856 def calculate_constant_result(self):
6857 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6859 def compile_time_value(self, denv):
6860 operand1 = self.operand1.compile_time_value(denv)
6861 return self.cascaded_compile_time_value(operand1, denv)
6863 def analyse_types(self, env):
6864 self.operand1.analyse_types(env)
6865 self.operand2.analyse_types(env)
6866 if self.is_cpp_comparison():
6867 self.analyse_cpp_comparison(env)
6869 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6872 self.cascade.analyse_types(env)
6874 if self.operator in ('in', 'not_in'):
6875 if self.is_c_string_contains():
6876 self.is_pycmp = False
6879 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6881 if self.operand2.type is unicode_type:
6882 self.uchar_test_type = PyrexTypes.widest_numeric_type(
6883 self.operand1.type, PyrexTypes.c_py_unicode_type)
6884 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
6885 env.use_utility_code(pyunicode_in_unicode_utility_code)
6887 env.use_utility_code(py_ucs4_in_unicode_utility_code)
6889 if self.operand1.type is PyrexTypes.c_uchar_type:
6890 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6891 if self.operand2.type is not bytes_type:
6892 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6893 env.use_utility_code(char_in_bytes_utility_code)
6894 self.operand2 = self.operand2.as_none_safe_node(
6895 "argument of type 'NoneType' is not iterable")
6896 elif self.is_ptr_contains():
6898 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6899 self.type = PyrexTypes.c_bint_type
6900 # Will be transformed by IterationTransform
6903 if self.operand2.type is dict_type:
6904 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6905 common_type = py_object_type
6906 self.is_pycmp = True
6907 elif self.find_special_bool_compare_function(env):
6908 common_type = None # if coercion needed, the method call above has already done it
6909 self.is_pycmp = False # result is bint
6910 self.is_temp = True # must check for error return
6912 common_type = self.find_common_type(env, self.operator, self.operand1)
6913 self.is_pycmp = common_type.is_pyobject
6915 if common_type is not None and not common_type.is_error:
6916 if self.operand1.type != common_type:
6917 self.operand1 = self.operand1.coerce_to(common_type, env)
6918 self.coerce_operands_to(common_type, env)
6921 self.operand2 = self.operand2.coerce_to_simple(env)
6922 self.cascade.coerce_cascaded_operands_to_temp(env)
6923 if self.is_python_result():
6924 self.type = PyrexTypes.py_object_type
6926 self.type = PyrexTypes.c_bint_type
6929 cdr.type = self.type
6931 if self.is_pycmp or self.cascade:
6934 def analyse_cpp_comparison(self, env):
6935 type1 = self.operand1.type
6936 type2 = self.operand2.type
6937 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6939 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6940 (self.operator, type1, type2))
6941 self.type = PyrexTypes.error_type
6942 self.result_code = "<error>"
6944 func_type = entry.type
6945 if func_type.is_ptr:
6946 func_type = func_type.base_type
6947 if len(func_type.args) == 1:
6948 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6950 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6951 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6952 self.type = func_type.return_type
6954 def has_python_operands(self):
6955 return (self.operand1.type.is_pyobject
6956 or self.operand2.type.is_pyobject)
6958 def check_const(self):
6963 return self.operand1.check_const() and self.operand2.check_const()
6965 def calculate_result_code(self):
6966 if self.operand1.type.is_complex:
6967 if self.operator == "!=":
6971 return "(%s%s(%s, %s))" % (
6973 self.operand1.type.binary_op('=='),
6974 self.operand1.result(),
6975 self.operand2.result())
6976 elif self.is_c_string_contains():
6977 if self.operand2.type is unicode_type:
6978 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
6979 method = "__Pyx_UnicodeContains"
6981 method = "__Pyx_UnicodeContainsUCS4"
6983 method = "__Pyx_BytesContains"
6984 if self.operator == "not_in":
6988 return "(%s%s(%s, %s))" % (
6991 self.operand2.result(),
6992 self.operand1.result())
6994 return "(%s %s %s)" % (
6995 self.operand1.result(),
6996 self.c_operator(self.operator),
6997 self.operand2.result())
6999 def generate_evaluation_code(self, code):
7000 self.operand1.generate_evaluation_code(code)
7001 self.operand2.generate_evaluation_code(code)
7003 self.allocate_temp_result(code)
7004 self.generate_operation_code(code, self.result(),
7005 self.operand1, self.operator, self.operand2)
7007 self.cascade.generate_evaluation_code(code,
7008 self.result(), self.operand2)
7009 self.operand1.generate_disposal_code(code)
7010 self.operand1.free_temps(code)
7011 self.operand2.generate_disposal_code(code)
7012 self.operand2.free_temps(code)
7014 def generate_subexpr_disposal_code(self, code):
7015 # If this is called, it is a non-cascaded cmp,
7016 # so only need to dispose of the two main operands.
7017 self.operand1.generate_disposal_code(code)
7018 self.operand2.generate_disposal_code(code)
7020 def free_subexpr_temps(self, code):
7021 # If this is called, it is a non-cascaded cmp,
7022 # so only need to dispose of the two main operands.
7023 self.operand1.free_temps(code)
7024 self.operand2.free_temps(code)
7026 def annotate(self, code):
7027 self.operand1.annotate(code)
7028 self.operand2.annotate(code)
7030 self.cascade.annotate(code)
7033 class CascadedCmpNode(Node, CmpNode):
7034 # A CascadedCmpNode is not a complete expression node. It
7035 # hangs off the side of another comparison node, shares
7036 # its left operand with that node, and shares its result
7037 # with the PrimaryCmpNode at the head of the chain.
7041 # cascade CascadedCmpNode
7043 child_attrs = ['operand2', 'cascade']
7046 constant_result = constant_value_not_set # FIXME: where to calculate this?
7048 def infer_type(self, env):
7049 # TODO: Actually implement this (after merging with -unstable).
7050 return py_object_type
7052 def type_dependencies(self, env):
7055 def has_constant_result(self):
7056 return self.constant_result is not constant_value_not_set and \
7057 self.constant_result is not not_a_constant
7059 def analyse_types(self, env):
7060 self.operand2.analyse_types(env)
7062 self.cascade.analyse_types(env)
7064 def has_python_operands(self):
7065 return self.operand2.type.is_pyobject
7067 def coerce_operands_to_pyobjects(self, env):
7068 self.operand2 = self.operand2.coerce_to_pyobject(env)
7069 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
7070 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
7072 self.cascade.coerce_operands_to_pyobjects(env)
7074 def coerce_cascaded_operands_to_temp(self, env):
7076 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
7077 self.operand2 = self.operand2.coerce_to_simple(env)
7078 self.cascade.coerce_cascaded_operands_to_temp(env)
7080 def generate_evaluation_code(self, code, result, operand1):
7081 if self.type.is_pyobject:
7082 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
7083 code.put_decref(result, self.type)
7085 code.putln("if (%s) {" % result)
7086 self.operand2.generate_evaluation_code(code)
7087 self.generate_operation_code(code, result,
7088 operand1, self.operator, self.operand2)
7090 self.cascade.generate_evaluation_code(
7091 code, result, self.operand2)
7092 # Cascaded cmp result is always temp
7093 self.operand2.generate_disposal_code(code)
7094 self.operand2.free_temps(code)
7097 def annotate(self, code):
7098 self.operand2.annotate(code)
7100 self.cascade.annotate(code)
7103 binop_node_classes = {
7104 "or": BoolBinopNode,
7105 "and": BoolBinopNode,
7120 def binop_node(pos, operator, operand1, operand2, inplace=False):
7121 # Construct binop node of appropriate class for
7123 return binop_node_classes[operator](pos,
7124 operator = operator,
7125 operand1 = operand1,
7126 operand2 = operand2,
7129 #-------------------------------------------------------------------
7133 # Coercion nodes are special in that they are created during
7134 # the analyse_types phase of parse tree processing.
7135 # Their __init__ methods consequently incorporate some aspects
7138 #-------------------------------------------------------------------
7140 class CoercionNode(ExprNode):
7141 # Abstract base class for coercion nodes.
7143 # arg ExprNode node being coerced
7146 constant_result = not_a_constant
7148 def __init__(self, arg):
7152 print("%s Coercing %s" % (self, self.arg))
7154 def calculate_constant_result(self):
7155 # constant folding can break type coercion, so this is disabled
7158 def annotate(self, code):
7159 self.arg.annotate(code)
7160 if self.arg.type != self.type:
7161 file, line, col = self.pos
7162 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
7165 class CastNode(CoercionNode):
7166 # Wrap a node in a C type cast.
7168 def __init__(self, arg, new_type):
7169 CoercionNode.__init__(self, arg)
7170 self.type = new_type
7172 def may_be_none(self):
7173 return self.arg.may_be_none()
7175 def calculate_result_code(self):
7176 return self.arg.result_as(self.type)
7178 def generate_result_code(self, code):
7179 self.arg.generate_result_code(code)
7182 class PyTypeTestNode(CoercionNode):
7183 # This node is used to check that a generic Python
7184 # object is an instance of a particular extension type.
7185 # This node borrows the result of its argument node.
7187 def __init__(self, arg, dst_type, env, notnone=False):
7188 # The arg is know to be a Python object, and
7189 # the dst_type is known to be an extension type.
7190 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
7191 CoercionNode.__init__(self, arg)
7192 self.type = dst_type
7193 self.result_ctype = arg.ctype()
7194 self.notnone = notnone
7196 nogil_check = Node.gil_error
7197 gil_message = "Python type test"
7199 def analyse_types(self, env):
7202 def may_be_none(self):
7205 return self.arg.may_be_none()
7207 def is_simple(self):
7208 return self.arg.is_simple()
7210 def result_in_temp(self):
7211 return self.arg.result_in_temp()
7213 def is_ephemeral(self):
7214 return self.arg.is_ephemeral()
7216 def calculate_constant_result(self):
7220 def calculate_result_code(self):
7221 return self.arg.result()
7223 def generate_result_code(self, code):
7224 if self.type.typeobj_is_available():
7225 if not self.type.is_builtin_type:
7226 code.globalstate.use_utility_code(type_test_utility_code)
7229 self.type.type_test_code(self.arg.py_result(), self.notnone),
7230 code.error_goto(self.pos)))
7232 error(self.pos, "Cannot test type of extern C class "
7233 "without type object name specification")
7235 def generate_post_assignment_code(self, code):
7236 self.arg.generate_post_assignment_code(code)
7238 def free_temps(self, code):
7239 self.arg.free_temps(code)
7242 class NoneCheckNode(CoercionNode):
7243 # This node is used to check that a Python object is not None and
7244 # raises an appropriate exception (as specified by the creating
7247 def __init__(self, arg, exception_type_cname, exception_message):
7248 CoercionNode.__init__(self, arg)
7249 self.type = arg.type
7250 self.result_ctype = arg.ctype()
7251 self.exception_type_cname = exception_type_cname
7252 self.exception_message = exception_message
7254 def analyse_types(self, env):
7257 def may_be_none(self):
7260 def is_simple(self):
7261 return self.arg.is_simple()
7263 def result_in_temp(self):
7264 return self.arg.result_in_temp()
7266 def calculate_result_code(self):
7267 return self.arg.result()
7269 def generate_result_code(self, code):
7271 "if (unlikely(%s == Py_None)) {" % self.arg.result())
7272 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
7273 self.exception_type_cname,
7274 StringEncoding.escape_byte_string(
7275 self.exception_message.encode('UTF-8')),
7276 code.error_goto(self.pos)))
7279 def generate_post_assignment_code(self, code):
7280 self.arg.generate_post_assignment_code(code)
7282 def free_temps(self, code):
7283 self.arg.free_temps(code)
7286 class CoerceToPyTypeNode(CoercionNode):
7287 # This node is used to convert a C data type
7288 # to a Python object.
7290 type = py_object_type
7293 def __init__(self, arg, env, type=py_object_type):
7294 CoercionNode.__init__(self, arg)
7295 if not arg.type.create_to_py_utility_code(env):
7297 "Cannot convert '%s' to Python object" % arg.type)
7298 if type is py_object_type:
7299 # be specific about some known types
7300 if arg.type.is_string:
7301 self.type = bytes_type
7302 elif arg.type.is_unicode_char:
7303 self.type = unicode_type
7304 elif arg.type.is_complex:
7305 self.type = Builtin.complex_type
7307 # FIXME: check that the target type and the resulting type are compatible
7310 gil_message = "Converting to Python object"
7312 def may_be_none(self):
7313 # FIXME: is this always safe?
7316 def coerce_to_boolean(self, env):
7317 arg_type = self.arg.type
7318 if (arg_type == PyrexTypes.c_bint_type or
7319 (arg_type.is_pyobject and arg_type.name == 'bool')):
7320 return self.arg.coerce_to_temp(env)
7322 return CoerceToBooleanNode(self, env)
7324 def coerce_to_integer(self, env):
7325 # If not already some C integer type, coerce to longint.
7326 if self.arg.type.is_int:
7329 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7331 def analyse_types(self, env):
7332 # The arg is always already analysed
7335 def generate_result_code(self, code):
7336 function = self.arg.type.to_py_function
7337 code.putln('%s = %s(%s); %s' % (
7341 code.error_goto_if_null(self.result(), self.pos)))
7342 code.put_gotref(self.py_result())
7345 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7346 # This node is used to convert a C int type to a Python bytes
7351 def __init__(self, arg, env):
7352 arg = arg.coerce_to_simple(env)
7353 CoercionNode.__init__(self, arg)
7354 self.type = Builtin.bytes_type
7356 def generate_result_code(self, code):
7358 arg_result = arg.result()
7359 if arg.type not in (PyrexTypes.c_char_type,
7360 PyrexTypes.c_uchar_type,
7361 PyrexTypes.c_schar_type):
7363 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7364 arg_result, arg_result))
7366 code.putln("if (%s > 255) {" % arg_result)
7367 code.putln('PyErr_Format(PyExc_OverflowError, '
7368 '"value too large to pack into a byte"); %s' % (
7369 code.error_goto(self.pos)))
7372 if arg.type is not PyrexTypes.c_char_type:
7373 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7374 code.putln("%s = (char)%s;" % (temp, arg_result))
7376 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7379 code.error_goto_if_null(self.result(), self.pos)))
7380 if temp is not None:
7381 code.funcstate.release_temp(temp)
7382 code.put_gotref(self.py_result())
7385 class CoerceFromPyTypeNode(CoercionNode):
7386 # This node is used to convert a Python object
7389 def __init__(self, result_type, arg, env):
7390 CoercionNode.__init__(self, arg)
7391 self.type = result_type
7393 if not result_type.create_from_py_utility_code(env):
7395 "Cannot convert Python object to '%s'" % result_type)
7396 if self.type.is_string and self.arg.is_ephemeral():
7398 "Obtaining char * from temporary Python value")
7400 def analyse_types(self, env):
7401 # The arg is always already analysed
7404 def generate_result_code(self, code):
7405 function = self.type.from_py_function
7406 operand = self.arg.py_result()
7407 rhs = "%s(%s)" % (function, operand)
7408 if self.type.is_enum:
7409 rhs = typecast(self.type, c_long_type, rhs)
7410 code.putln('%s = %s; %s' % (
7413 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7414 if self.type.is_pyobject:
7415 code.put_gotref(self.py_result())
7418 class CoerceToBooleanNode(CoercionNode):
7419 # This node is used when a result needs to be used
7420 # in a boolean context.
7422 type = PyrexTypes.c_bint_type
7424 _special_builtins = {
7425 Builtin.list_type : 'PyList_GET_SIZE',
7426 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7427 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7428 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7431 def __init__(self, arg, env):
7432 CoercionNode.__init__(self, arg)
7433 if arg.type.is_pyobject:
7436 def nogil_check(self, env):
7437 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7440 gil_message = "Truth-testing Python object"
7442 def check_const(self):
7446 return self.arg.check_const()
7448 def calculate_result_code(self):
7449 return "(%s != 0)" % self.arg.result()
7451 def generate_result_code(self, code):
7452 if not self.is_temp:
7454 test_func = self._special_builtins.get(self.arg.type)
7455 if test_func is not None:
7456 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7458 self.arg.py_result(),
7460 self.arg.py_result()))
7463 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7465 self.arg.py_result(),
7466 code.error_goto_if_neg(self.result(), self.pos)))
7468 class CoerceToComplexNode(CoercionNode):
7470 def __init__(self, arg, dst_type, env):
7471 if arg.type.is_complex:
7472 arg = arg.coerce_to_simple(env)
7473 self.type = dst_type
7474 CoercionNode.__init__(self, arg)
7475 dst_type.create_declaration_utility_code(env)
7477 def calculate_result_code(self):
7478 if self.arg.type.is_complex:
7479 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7480 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7482 real_part = self.arg.result()
7484 return "%s(%s, %s)" % (
7485 self.type.from_parts,
7489 def generate_result_code(self, code):
7492 class CoerceToTempNode(CoercionNode):
7493 # This node is used to force the result of another node
7494 # to be stored in a temporary. It is only used if the
7495 # argument node's result is not already in a temporary.
7497 def __init__(self, arg, env):
7498 CoercionNode.__init__(self, arg)
7499 self.type = self.arg.type
7500 self.constant_result = self.arg.constant_result
7502 if self.type.is_pyobject:
7503 self.result_ctype = py_object_type
7505 gil_message = "Creating temporary Python reference"
7507 def analyse_types(self, env):
7508 # The arg is always already analysed
7511 def coerce_to_boolean(self, env):
7512 self.arg = self.arg.coerce_to_boolean(env)
7513 if self.arg.is_simple():
7515 self.type = self.arg.type
7516 self.result_ctype = self.type
7519 def generate_result_code(self, code):
7520 #self.arg.generate_evaluation_code(code) # Already done
7521 # by generic generate_subexpr_evaluation_code!
7522 code.putln("%s = %s;" % (
7523 self.result(), self.arg.result_as(self.ctype())))
7524 if self.type.is_pyobject and self.use_managed_ref:
7525 code.put_incref(self.result(), self.ctype())
7528 class CloneNode(CoercionNode):
7529 # This node is employed when the result of another node needs
7530 # to be used multiple times. The argument node's result must
7531 # be in a temporary. This node "borrows" the result from the
7532 # argument node, and does not generate any evaluation or
7533 # disposal code for it. The original owner of the argument
7534 # node is responsible for doing those things.
7536 subexprs = [] # Arg is not considered a subexpr
7539 def __init__(self, arg):
7540 CoercionNode.__init__(self, arg)
7541 if hasattr(arg, 'type'):
7542 self.type = arg.type
7543 self.result_ctype = arg.result_ctype
7544 if hasattr(arg, 'entry'):
7545 self.entry = arg.entry
7548 return self.arg.result()
7550 def type_dependencies(self, env):
7551 return self.arg.type_dependencies(env)
7553 def infer_type(self, env):
7554 return self.arg.infer_type(env)
7556 def analyse_types(self, env):
7557 self.type = self.arg.type
7558 self.result_ctype = self.arg.result_ctype
7560 if hasattr(self.arg, 'entry'):
7561 self.entry = self.arg.entry
7563 def is_simple(self):
7564 return True # result is always in a temp (or a name)
7566 def generate_evaluation_code(self, code):
7569 def generate_result_code(self, code):
7572 def generate_disposal_code(self, code):
7575 def free_temps(self, code):
7579 class ModuleRefNode(ExprNode):
7580 # Simple returns the module object
7582 type = py_object_type
7586 def analyse_types(self, env):
7589 def may_be_none(self):
7592 def calculate_result_code(self):
7593 return Naming.module_cname
7595 def generate_result_code(self, code):
7598 class DocstringRefNode(ExprNode):
7599 # Extracts the docstring of the body element
7602 type = py_object_type
7605 def __init__(self, pos, body):
7606 ExprNode.__init__(self, pos)
7607 assert body.type.is_pyobject
7610 def analyse_types(self, env):
7613 def generate_result_code(self, code):
7614 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7615 self.result(), self.body.result(),
7616 code.error_goto_if_null(self.result(), self.pos)))
7617 code.put_gotref(self.result())
7621 #------------------------------------------------------------------------------------
7623 # Runtime support code
7625 #------------------------------------------------------------------------------------
7627 get_name_interned_utility_code = UtilityCode(
7629 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7632 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7634 result = PyObject_GetAttr(dict, name);
7636 PyErr_SetObject(PyExc_NameError, name);
7641 #------------------------------------------------------------------------------------
7643 import_utility_code = UtilityCode(
7645 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7648 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7649 PyObject *py_import = 0;
7650 PyObject *empty_list = 0;
7651 PyObject *module = 0;
7652 PyObject *global_dict = 0;
7653 PyObject *empty_dict = 0;
7655 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7661 empty_list = PyList_New(0);
7666 global_dict = PyModule_GetDict(%(GLOBALS)s);
7669 empty_dict = PyDict_New();
7672 module = PyObject_CallFunctionObjArgs(py_import,
7673 name, global_dict, empty_dict, list, NULL);
7675 Py_XDECREF(empty_list);
7676 Py_XDECREF(py_import);
7677 Py_XDECREF(empty_dict);
7681 "BUILTINS": Naming.builtins_cname,
7682 "GLOBALS": Naming.module_cname,
7685 #------------------------------------------------------------------------------------
7687 get_exception_utility_code = UtilityCode(
7689 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7692 static PyObject *__Pyx_GetExcValue(void) {
7693 PyObject *type = 0, *value = 0, *tb = 0;
7694 PyObject *tmp_type, *tmp_value, *tmp_tb;
7695 PyObject *result = 0;
7696 PyThreadState *tstate = PyThreadState_Get();
7697 PyErr_Fetch(&type, &value, &tb);
7698 PyErr_NormalizeException(&type, &value, &tb);
7699 if (PyErr_Occurred())
7705 tmp_type = tstate->exc_type;
7706 tmp_value = tstate->exc_value;
7707 tmp_tb = tstate->exc_traceback;
7708 tstate->exc_type = type;
7709 tstate->exc_value = value;
7710 tstate->exc_traceback = tb;
7711 /* Make sure tstate is in a consistent state when we XDECREF
7712 these objects (XDECREF may run arbitrary code). */
7713 Py_XDECREF(tmp_type);
7714 Py_XDECREF(tmp_value);
7729 #------------------------------------------------------------------------------------
7731 type_test_utility_code = UtilityCode(
7733 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7736 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7737 if (unlikely(!type)) {
7738 PyErr_Format(PyExc_SystemError, "Missing type object");
7741 if (likely(PyObject_TypeCheck(obj, type)))
7743 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7744 Py_TYPE(obj)->tp_name, type->tp_name);
7749 #------------------------------------------------------------------------------------
7751 find_py2_metaclass_utility_code = UtilityCode(
7753 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7756 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7757 PyObject *metaclass;
7758 /* Default metaclass */
7759 #if PY_MAJOR_VERSION < 3
7760 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7761 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7762 metaclass = PyObject_GetAttrString(base, "__class__");
7765 metaclass = (PyObject*) Py_TYPE(base);
7768 metaclass = (PyObject *) &PyClass_Type;
7771 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7772 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7773 metaclass = (PyObject*) Py_TYPE(base);
7775 metaclass = (PyObject *) &PyType_Type;
7778 Py_INCREF(metaclass);
7783 create_class_utility_code = UtilityCode(
7785 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7786 PyObject *modname); /*proto*/
7789 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7790 PyObject *modname) {
7792 PyObject *metaclass;
7794 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7797 /* Python2 __metaclass__ */
7798 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7800 Py_INCREF(metaclass);
7802 metaclass = __Pyx_FindPy2Metaclass(bases);
7804 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7805 Py_DECREF(metaclass);
7809 requires = [find_py2_metaclass_utility_code])
7811 #------------------------------------------------------------------------------------
7813 create_py3class_utility_code = UtilityCode(
7815 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7816 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7817 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7820 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7821 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7823 Py_INCREF(metaclass);
7824 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7825 Py_DECREF(metaclass);
7830 return __Pyx_FindPy2Metaclass(bases);
7833 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7834 PyObject *modname, PyObject *doc) {
7840 prep = PyObject_GetAttrString(metaclass, "__prepare__");
7842 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7845 return PyDict_New();
7847 pargs = PyTuple_New(2);
7855 PyTuple_SET_ITEM(pargs, 0, name);
7856 PyTuple_SET_ITEM(pargs, 1, bases);
7858 ns = PyObject_Call(prep, pargs, mkw);
7866 /* Required here to emulate assignment order */
7867 /* XXX: use consts here */
7868 #if PY_MAJOR_VERSION >= 3
7869 str = PyUnicode_FromString("__module__");
7871 str = PyString_FromString("__module__");
7878 if (PyObject_SetItem(ns, str, modname) < 0) {
7885 #if PY_MAJOR_VERSION >= 3
7886 str = PyUnicode_FromString("__doc__");
7888 str = PyString_FromString("__doc__");
7894 if (PyObject_SetItem(ns, str, doc) < 0) {
7904 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7906 PyObject *margs = PyTuple_New(3);
7912 PyTuple_SET_ITEM(margs, 0, name);
7913 PyTuple_SET_ITEM(margs, 1, bases);
7914 PyTuple_SET_ITEM(margs, 2, dict);
7915 result = PyObject_Call(metaclass, margs, mkw);
7920 requires = [find_py2_metaclass_utility_code])
7922 #------------------------------------------------------------------------------------
7924 cpp_exception_utility_code = UtilityCode(
7926 #ifndef __Pyx_CppExn2PyErr
7927 static void __Pyx_CppExn2PyErr() {
7929 if (PyErr_Occurred())
7930 ; // let the latest Python exn pass through and ignore the current one
7933 } catch (const std::invalid_argument& exn) {
7934 // Catch a handful of different errors here and turn them into the
7935 // equivalent Python errors.
7936 // Change invalid_argument to ValueError
7937 PyErr_SetString(PyExc_ValueError, exn.what());
7938 } catch (const std::out_of_range& exn) {
7939 // Change out_of_range to IndexError
7940 PyErr_SetString(PyExc_IndexError, exn.what());
7941 } catch (const std::exception& exn) {
7942 PyErr_SetString(PyExc_RuntimeError, exn.what());
7946 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7954 pyerr_occurred_withgil_utility_code= UtilityCode(
7956 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7959 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7962 PyGILState_STATE _save = PyGILState_Ensure();
7964 err = !!PyErr_Occurred();
7966 PyGILState_Release(_save);
7973 #------------------------------------------------------------------------------------
7975 raise_noneattr_error_utility_code = UtilityCode(
7977 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7980 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7981 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7985 raise_noneindex_error_utility_code = UtilityCode(
7987 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7990 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7991 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7995 raise_none_iter_error_utility_code = UtilityCode(
7997 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
8000 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
8001 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
8005 #------------------------------------------------------------------------------------
8007 getitem_dict_utility_code = UtilityCode(
8009 #if PY_MAJOR_VERSION >= 3
8010 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
8012 if (unlikely(d == Py_None)) {
8013 __Pyx_RaiseNoneIndexingError();
8016 value = PyDict_GetItemWithError(d, key);
8017 if (unlikely(!value)) {
8018 if (!PyErr_Occurred())
8019 PyErr_SetObject(PyExc_KeyError, key);
8026 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
8029 requires = [raise_noneindex_error_utility_code])
8031 #------------------------------------------------------------------------------------
8033 getitem_int_pyunicode_utility_code = UtilityCode(
8035 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8036 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
8037 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
8039 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
8040 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
8041 return PyUnicode_AS_UNICODE(ustring)[i];
8042 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
8043 i += PyUnicode_GET_SIZE(ustring);
8044 return PyUnicode_AS_UNICODE(ustring)[i];
8046 PyErr_SetString(PyExc_IndexError, "string index out of range");
8047 return (Py_UNICODE)-1;
8051 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
8053 PyObject *uchar_string;
8054 if (!j) return (Py_UNICODE)-1;
8055 uchar_string = PyObject_GetItem(ustring, j);
8057 if (!uchar_string) return (Py_UNICODE)-1;
8058 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
8059 Py_DECREF(uchar_string);
8064 getitem_int_utility_code = UtilityCode(
8067 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
8069 if (!j) return NULL;
8070 r = PyObject_GetItem(o, j);
8077 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8078 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
8079 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8081 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
8082 if (likely(o != Py_None)) {
8083 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
8084 PyObject *r = Py%(type)s_GET_ITEM(o, i);
8088 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
8089 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
8094 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8096 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
8099 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8100 __Pyx_GetItemInt_Fast(o, i) : \\
8101 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8103 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
8105 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8106 r = PyList_GET_ITEM(o, i);
8109 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
8110 r = PyTuple_GET_ITEM(o, i);
8113 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
8114 r = PySequence_GetItem(o, i);
8117 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8127 #------------------------------------------------------------------------------------
8129 setitem_int_utility_code = UtilityCode(
8131 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8132 __Pyx_SetItemInt_Fast(o, i, v) : \\
8133 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
8135 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
8138 r = PyObject_SetItem(o, j, v);
8143 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
8144 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8146 Py_DECREF(PyList_GET_ITEM(o, i));
8147 PyList_SET_ITEM(o, i, v);
8150 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
8151 return PySequence_SetItem(o, i, v);
8153 PyObject *j = PyInt_FromSsize_t(i);
8154 return __Pyx_SetItemInt_Generic(o, j, v);
8161 #------------------------------------------------------------------------------------
8163 delitem_int_utility_code = UtilityCode(
8165 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8166 __Pyx_DelItemInt_Fast(o, i) : \\
8167 __Pyx_DelItem_Generic(o, to_py_func(i)))
8169 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8172 r = PyObject_DelItem(o, j);
8177 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8178 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
8179 return PySequence_DelItem(o, i);
8181 PyObject *j = PyInt_FromSsize_t(i);
8182 return __Pyx_DelItem_Generic(o, j);
8189 #------------------------------------------------------------------------------------
8191 raise_too_many_values_to_unpack = UtilityCode(
8193 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8196 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
8197 PyErr_Format(PyExc_ValueError,
8198 #if PY_VERSION_HEX < 0x02050000
8199 "too many values to unpack (expected %d)", (int)expected);
8201 "too many values to unpack (expected %zd)", expected);
8206 raise_need_more_values_to_unpack = UtilityCode(
8208 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8211 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8212 PyErr_Format(PyExc_ValueError,
8213 #if PY_VERSION_HEX < 0x02050000
8214 "need more than %d value%s to unpack", (int)index,
8216 "need more than %zd value%s to unpack", index,
8218 (index == 1) ? "" : "s");
8222 #------------------------------------------------------------------------------------
8224 tuple_unpacking_error_code = UtilityCode(
8226 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8229 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
8231 __Pyx_RaiseNoneNotIterableError();
8232 } else if (PyTuple_GET_SIZE(t) < index) {
8233 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
8235 __Pyx_RaiseTooManyValuesError(index);
8239 requires = [raise_none_iter_error_utility_code,
8240 raise_need_more_values_to_unpack,
8241 raise_too_many_values_to_unpack]
8244 unpacking_utility_code = UtilityCode(
8246 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8247 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8250 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
8252 if (!(item = PyIter_Next(iter))) {
8253 if (!PyErr_Occurred()) {
8254 __Pyx_RaiseNeedMoreValuesError(index);
8260 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8262 if ((item = PyIter_Next(iter))) {
8264 __Pyx_RaiseTooManyValuesError(expected);
8267 else if (!PyErr_Occurred())
8273 requires = [raise_need_more_values_to_unpack,
8274 raise_too_many_values_to_unpack]
8277 #------------------------------------------------------------------------------------
8279 # CPython supports calling functions with non-dict kwargs by
8280 # converting them to a dict first
8282 kwargs_call_utility_code = UtilityCode(
8284 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
8287 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
8289 if (likely(PyDict_Check(kwargs))) {
8290 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
8292 PyObject* real_dict;
8293 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
8294 if (unlikely(!real_dict))
8296 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
8297 Py_DECREF(real_dict);
8298 return result; /* may be NULL */
8305 #------------------------------------------------------------------------------------
8307 int_pow_utility_code = UtilityCode(
8309 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8312 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8324 if (unlikely(e<0)) return 0;
8327 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8335 # ------------------------------ Division ------------------------------------
8337 div_int_utility_code = UtilityCode(
8339 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8342 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8344 %(type)s r = a - q*b;
8345 q -= ((r != 0) & ((r ^ b) < 0));
8350 mod_int_utility_code = UtilityCode(
8352 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8355 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8356 %(type)s r = a %% b;
8357 r += ((r != 0) & ((r ^ b) < 0)) * b;
8362 mod_float_utility_code = UtilityCode(
8364 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8367 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8368 %(type)s r = fmod%(math_h_modifier)s(a, b);
8369 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8374 cdivision_warning_utility_code = UtilityCode(
8376 static int __Pyx_cdivision_warning(void); /* proto */
8379 static int __Pyx_cdivision_warning(void) {
8380 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8381 "division with oppositely signed operands, C and Python semantics differ",
8388 'FILENAME': Naming.filename_cname,
8389 'LINENO': Naming.lineno_cname,
8393 division_overflow_test_code = UtilityCode(
8395 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8396 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8400 binding_cfunc_utility_code = UtilityCode(
8402 #define %(binding_cfunc)s_USED 1
8405 PyCFunctionObject func;
8406 } %(binding_cfunc)s_object;
8408 static PyTypeObject %(binding_cfunc)s_type;
8409 static PyTypeObject *%(binding_cfunc)s = NULL;
8411 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8412 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8414 static int %(binding_cfunc)s_init(void); /* proto */
8415 """ % Naming.__dict__,
8418 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8419 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8424 op->func.m_self = self;
8426 op->func.m_module = module;
8427 PyObject_GC_Track(op);
8428 return (PyObject *)op;
8431 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8432 PyObject_GC_UnTrack(m);
8433 Py_XDECREF(m->func.m_self);
8434 Py_XDECREF(m->func.m_module);
8438 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8441 return PyMethod_New(func, obj, type);
8444 static int %(binding_cfunc)s_init(void) {
8445 %(binding_cfunc)s_type = PyCFunction_Type;
8446 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8447 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8448 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8449 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8452 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8456 """ % Naming.__dict__)
8458 generator_utility_code = UtilityCode(
8460 static PyObject *__Pyx_Generator_Next(PyObject *self);
8461 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
8462 static PyObject *__Pyx_Generator_Close(PyObject *self);
8463 static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args, CYTHON_UNUSED PyObject *kwds);
8465 typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
8468 static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_object *self, PyObject *value)
8472 if (self->is_running) {
8473 PyErr_SetString(PyExc_ValueError,
8474 "generator already executing");
8478 if (self->resume_label == 0) {
8479 if (value && value != Py_None) {
8480 PyErr_SetString(PyExc_TypeError,
8481 "can't send non-None value to a "
8482 "just-started generator");
8487 if (self->resume_label == -1) {
8488 PyErr_SetNone(PyExc_StopIteration);
8492 self->is_running = 1;
8493 retval = self->body((PyObject *) self, value);
8494 self->is_running = 0;
8499 static PyObject *__Pyx_Generator_Next(PyObject *self)
8501 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, Py_None);
8504 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value)
8506 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, value);
8509 static PyObject *__Pyx_Generator_Close(PyObject *self)
8511 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8513 #if PY_VERSION_HEX < 0x02050000
8514 PyErr_SetNone(PyExc_StopIteration);
8516 PyErr_SetNone(PyExc_GeneratorExit);
8518 retval = __Pyx_Generator_SendEx(generator, NULL);
8521 PyErr_SetString(PyExc_RuntimeError,
8522 "generator ignored GeneratorExit");
8525 #if PY_VERSION_HEX < 0x02050000
8526 if (PyErr_ExceptionMatches(PyExc_StopIteration))
8528 if (PyErr_ExceptionMatches(PyExc_StopIteration)
8529 || PyErr_ExceptionMatches(PyExc_GeneratorExit))
8532 PyErr_Clear(); /* ignore these errors */
8539 static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args, CYTHON_UNUSED PyObject *kwds)
8541 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8543 PyObject *tb = NULL;
8544 PyObject *val = NULL;
8546 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
8548 __Pyx_Raise(typ, val, tb);
8549 return __Pyx_Generator_SendEx(generator, NULL);
8552 proto_block='utility_code_proto_before_types',
8553 requires=[Nodes.raise_utility_code],