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 # --------------- Type Analysis ------------------
373 def analyse_as_module(self, env):
374 # If this node can be interpreted as a reference to a
375 # cimported module, return its scope, else None.
378 def analyse_as_type(self, env):
379 # If this node can be interpreted as a reference to a
380 # type, return that type, else None.
383 def analyse_as_extension_type(self, env):
384 # If this node can be interpreted as a reference to an
385 # extension type, return its type, else None.
388 def analyse_types(self, env):
389 self.not_implemented("analyse_types")
391 def analyse_target_types(self, env):
392 self.analyse_types(env)
394 def nogil_check(self, env):
395 # By default, any expression based on Python objects is
396 # prevented in nogil environments. Subtypes must override
397 # this if they can work without the GIL.
398 if self.type.is_pyobject:
401 def gil_assignment_check(self, env):
402 if env.nogil and self.type.is_pyobject:
403 error(self.pos, "Assignment of Python object not allowed without gil")
405 def check_const(self):
410 error(self.pos, "Not allowed in a constant expression")
412 def check_const_addr(self):
413 self.addr_not_const()
416 def addr_not_const(self):
417 error(self.pos, "Address is not constant")
419 # ----------------- Result Allocation -----------------
421 def result_in_temp(self):
422 # Return true if result is in a temporary owned by
423 # this node or one of its subexpressions. Overridden
424 # by certain nodes which can share the result of
428 def target_code(self):
429 # Return code fragment for use as LHS of a C assignment.
430 return self.calculate_result_code()
432 def calculate_result_code(self):
433 self.not_implemented("calculate_result_code")
435 # def release_target_temp(self, env):
436 # # Release temporaries used by LHS of an assignment.
437 # self.release_subexpr_temps(env)
439 def allocate_temp_result(self, code):
441 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
445 type = PyrexTypes.py_object_type
446 self.temp_code = code.funcstate.allocate_temp(
447 type, manage_ref=self.use_managed_ref)
449 self.temp_code = None
451 def release_temp_result(self, code):
452 if not self.temp_code:
453 if not self.result_is_used:
454 # not used anyway, so ignore if not set up
457 raise RuntimeError("temp %s released multiple times in %s" % (
458 self.old_temp, self.__class__.__name__))
460 raise RuntimeError("no temp, but release requested in %s" % (
461 self.__class__.__name__))
462 code.funcstate.release_temp(self.temp_code)
463 self.old_temp = self.temp_code
464 self.temp_code = None
466 # ---------------- Code Generation -----------------
468 def make_owned_reference(self, code):
469 # If result is a pyobject, make sure we own
471 if self.type.is_pyobject and not self.result_in_temp():
472 code.put_incref(self.result(), self.ctype())
474 def generate_evaluation_code(self, code):
475 code.mark_pos(self.pos)
477 # Generate code to evaluate this node and
478 # its sub-expressions, and dispose of any
479 # temporary results of its sub-expressions.
480 self.generate_subexpr_evaluation_code(code)
483 self.allocate_temp_result(code)
485 self.generate_result_code(code)
487 # If we are temp we do not need to wait until this node is disposed
488 # before disposing children.
489 self.generate_subexpr_disposal_code(code)
490 self.free_subexpr_temps(code)
492 def generate_subexpr_evaluation_code(self, code):
493 for node in self.subexpr_nodes():
494 node.generate_evaluation_code(code)
496 def generate_result_code(self, code):
497 self.not_implemented("generate_result_code")
499 def generate_disposal_code(self, code):
501 if self.type.is_pyobject and self.result():
502 code.put_decref_clear(self.result(), self.ctype())
504 # Already done if self.is_temp
505 self.generate_subexpr_disposal_code(code)
507 def generate_subexpr_disposal_code(self, code):
508 # Generate code to dispose of temporary results
509 # of all sub-expressions.
510 for node in self.subexpr_nodes():
511 node.generate_disposal_code(code)
513 def generate_post_assignment_code(self, code):
515 if self.type.is_pyobject:
516 code.putln("%s = 0;" % self.result())
518 self.generate_subexpr_disposal_code(code)
520 def generate_assignment_code(self, rhs, code):
521 # Stub method for nodes which are not legal as
522 # the LHS of an assignment. An error will have
523 # been reported earlier.
526 def generate_deletion_code(self, code):
527 # Stub method for nodes that are not legal as
528 # the argument of a del statement. An error
529 # will have been reported earlier.
532 def free_temps(self, code):
534 if not self.type.is_void:
535 self.release_temp_result(code)
537 self.free_subexpr_temps(code)
539 def free_subexpr_temps(self, code):
540 for sub in self.subexpr_nodes():
543 def generate_function_definitions(self, env, code):
546 # ---------------- Annotation ---------------------
548 def annotate(self, code):
549 for node in self.subexpr_nodes():
552 # ----------------- Coercion ----------------------
554 def coerce_to(self, dst_type, env):
555 # Coerce the result so that it can be assigned to
556 # something of type dst_type. If processing is necessary,
557 # wraps this node in a coercion node and returns that.
558 # Otherwise, returns this node unchanged.
560 # This method is called during the analyse_expressions
561 # phase of the src_node's processing.
563 # Note that subclasses that override this (especially
564 # ConstNodes) must not (re-)set their own .type attribute
565 # here. Since expression nodes may turn up in different
566 # places in the tree (e.g. inside of CloneNodes in cascaded
567 # assignments), this method must return a new node instance
568 # if it changes the type.
572 src_is_py_type = src_type.is_pyobject
573 dst_is_py_type = dst_type.is_pyobject
575 if self.check_for_coercion_error(dst_type):
578 if dst_type.is_reference:
579 dst_type = dst_type.ref_base_type
581 if dst_type.is_pyobject:
582 if not src.type.is_pyobject:
583 if dst_type is bytes_type and src.type.is_int:
584 src = CoerceIntToBytesNode(src, env)
586 src = CoerceToPyTypeNode(src, env)
587 if not src.type.subtype_of(dst_type):
588 if not isinstance(src, NoneNode):
589 src = PyTypeTestNode(src, dst_type, env)
590 elif src.type.is_pyobject:
591 src = CoerceFromPyTypeNode(dst_type, src, env)
592 elif (dst_type.is_complex
593 and src_type != dst_type
594 and dst_type.assignable_from(src_type)):
595 src = CoerceToComplexNode(src, dst_type, env)
596 else: # neither src nor dst are py types
597 # Added the string comparison, since for c types that
598 # is enough, but Cython gets confused when the types are
599 # in different pxi files.
600 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
601 self.fail_assignment(dst_type)
604 def fail_assignment(self, dst_type):
605 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
607 def check_for_coercion_error(self, dst_type, fail=False, default=None):
608 if fail and not default:
609 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
610 message = find_coercion_error((self.type, dst_type), default)
611 if message is not None:
612 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
615 self.fail_assignment(dst_type)
619 def coerce_to_pyobject(self, env):
620 return self.coerce_to(PyrexTypes.py_object_type, env)
622 def coerce_to_boolean(self, env):
623 # Coerce result to something acceptable as
626 # if it's constant, calculate the result now
627 if self.has_constant_result():
628 bool_value = bool(self.constant_result)
629 return BoolNode(self.pos, value=bool_value,
630 constant_result=bool_value)
633 if type.is_pyobject or type.is_ptr or type.is_float:
634 return CoerceToBooleanNode(self, env)
636 if not (type.is_int or type.is_enum or type.is_error):
638 "Type '%s' not acceptable as a boolean" % type)
641 def coerce_to_integer(self, env):
642 # If not already some C integer type, coerce to longint.
646 return self.coerce_to(PyrexTypes.c_long_type, env)
648 def coerce_to_temp(self, env):
649 # Ensure that the result is in a temporary.
650 if self.result_in_temp():
653 return CoerceToTempNode(self, env)
655 def coerce_to_simple(self, env):
656 # Ensure that the result is simple (see is_simple).
660 return self.coerce_to_temp(env)
663 # A node is simple if its result is something that can
664 # be referred to without performing any operations, e.g.
665 # a constant, local var, C global var, struct member
666 # reference, or temporary.
667 return self.result_in_temp()
669 def may_be_none(self):
670 if not self.type.is_pyobject:
672 if self.constant_result not in (not_a_constant, constant_value_not_set):
673 return self.constant_result is not None
676 def as_cython_attribute(self):
679 def as_none_safe_node(self, message, error="PyExc_TypeError"):
680 # Wraps the node in a NoneCheckNode if it is not known to be
681 # not-None (e.g. because it is a Python literal).
682 if self.may_be_none():
683 return NoneCheckNode(self, error, message)
688 class AtomicExprNode(ExprNode):
689 # Abstract base class for expression nodes which have
690 # no sub-expressions.
694 # Override to optimize -- we know we have no children
695 def generate_subexpr_evaluation_code(self, code):
697 def generate_subexpr_disposal_code(self, code):
700 class PyConstNode(AtomicExprNode):
701 # Abstract base class for constant Python values.
704 type = py_object_type
709 def may_be_none(self):
712 def analyse_types(self, env):
715 def calculate_result_code(self):
718 def generate_result_code(self, code):
722 class NoneNode(PyConstNode):
723 # The constant value None
727 constant_result = None
731 def compile_time_value(self, denv):
734 def may_be_none(self):
738 class EllipsisNode(PyConstNode):
739 # '...' in a subscript list.
741 value = "Py_Ellipsis"
743 constant_result = Ellipsis
745 def compile_time_value(self, denv):
749 class ConstNode(AtomicExprNode):
750 # Abstract base type for literal constant nodes.
752 # value string C code fragment
760 def may_be_none(self):
763 def analyse_types(self, env):
764 pass # Types are held in class variables
766 def check_const(self):
769 def get_constant_c_result_code(self):
770 return self.calculate_result_code()
772 def calculate_result_code(self):
773 return str(self.value)
775 def generate_result_code(self, code):
779 class BoolNode(ConstNode):
780 type = PyrexTypes.c_bint_type
781 # The constant value True or False
783 def calculate_constant_result(self):
784 self.constant_result = self.value
786 def compile_time_value(self, denv):
789 def calculate_result_code(self):
790 return str(int(self.value))
793 class NullNode(ConstNode):
794 type = PyrexTypes.c_null_ptr_type
798 def get_constant_c_result_code(self):
802 class CharNode(ConstNode):
803 type = PyrexTypes.c_char_type
805 def calculate_constant_result(self):
806 self.constant_result = ord(self.value)
808 def compile_time_value(self, denv):
809 return ord(self.value)
811 def calculate_result_code(self):
812 return "'%s'" % StringEncoding.escape_char(self.value)
815 class IntNode(ConstNode):
818 # longness "" or "L" or "LL"
819 # is_c_literal True/False/None creator considers this a C integer literal
823 is_c_literal = None # unknown
825 def __init__(self, pos, **kwds):
826 ExprNode.__init__(self, pos, **kwds)
827 if 'type' not in kwds:
828 self.type = self.find_suitable_type_for_value()
830 def find_suitable_type_for_value(self):
831 if self.constant_result is constant_value_not_set:
833 self.calculate_constant_result()
836 # we ignore 'is_c_literal = True' and instead map signed 32bit
837 # integers as C long values
838 if self.is_c_literal or \
839 self.constant_result in (constant_value_not_set, not_a_constant) or \
840 self.unsigned or self.longness == 'LL':
841 # clearly a C literal
842 rank = (self.longness == 'LL') and 2 or 1
843 suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
845 suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
847 # C literal or Python literal - split at 32bit boundary
848 if self.constant_result >= -2**31 and self.constant_result < 2**31:
849 if self.type and self.type.is_int:
850 suitable_type = self.type
852 suitable_type = PyrexTypes.c_long_type
854 suitable_type = PyrexTypes.py_object_type
857 def coerce_to(self, dst_type, env):
858 if self.type is dst_type:
860 elif dst_type.is_float:
861 if self.constant_result is not not_a_constant:
862 float_value = float(self.constant_result)
863 return FloatNode(self.pos, value=repr(float_value), type=dst_type,
864 constant_result=float_value)
866 return FloatNode(self.pos, value=self.value, type=dst_type,
867 constant_result=not_a_constant)
868 if dst_type.is_numeric and not dst_type.is_complex:
869 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
870 type = dst_type, is_c_literal = True,
871 unsigned=self.unsigned, longness=self.longness)
873 elif dst_type.is_pyobject:
874 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
875 type = PyrexTypes.py_object_type, is_c_literal = False,
876 unsigned=self.unsigned, longness=self.longness)
878 # FIXME: not setting the type here to keep it working with
879 # complex numbers. Should they be special cased?
880 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
881 unsigned=self.unsigned, longness=self.longness)
882 # We still need to perform normal coerce_to processing on the
883 # result, because we might be coercing to an extension type,
884 # in which case a type test node will be needed.
885 return ConstNode.coerce_to(node, dst_type, env)
887 def coerce_to_boolean(self, env):
889 self.pos, value=self.value,
890 type = PyrexTypes.c_bint_type,
891 unsigned=self.unsigned, longness=self.longness)
893 def generate_evaluation_code(self, code):
894 if self.type.is_pyobject:
895 # pre-allocate a Python version of the number
896 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
897 self.result_code = code.get_py_num(plain_integer_string, self.longness)
899 self.result_code = self.get_constant_c_result_code()
901 def get_constant_c_result_code(self):
902 return self.value_as_c_integer_string() + self.unsigned + self.longness
904 def value_as_c_integer_string(self, plain_digits=False):
906 if isinstance(value, basestring) and len(value) > 2:
907 # must convert C-incompatible Py3 oct/bin notations
910 value = int(value[2:], 8)
912 value = value[0] + value[2:] # '0o123' => '0123'
913 elif value[1] in 'bB':
914 value = int(value[2:], 2)
915 elif plain_digits and value[1] in 'xX':
916 value = int(value[2:], 16)
919 def calculate_result_code(self):
920 return self.result_code
922 def calculate_constant_result(self):
923 self.constant_result = Utils.str_to_number(self.value)
925 def compile_time_value(self, denv):
926 return Utils.str_to_number(self.value)
929 class FloatNode(ConstNode):
930 type = PyrexTypes.c_double_type
932 def calculate_constant_result(self):
933 self.constant_result = float(self.value)
935 def compile_time_value(self, denv):
936 return float(self.value)
938 def calculate_result_code(self):
940 assert isinstance(strval, (str, unicode))
941 cmpval = repr(float(strval))
943 return "(Py_HUGE_VAL * 0)"
944 elif cmpval == 'inf':
946 elif cmpval == '-inf':
947 return "(-Py_HUGE_VAL)"
952 class BytesNode(ConstNode):
953 # A char* or bytes literal
957 # start off as Python 'bytes' to support len() in O(1)
960 def compile_time_value(self, denv):
963 def analyse_as_type(self, env):
964 type = PyrexTypes.parse_basic_type(self.value)
967 from TreeFragment import TreeFragment
968 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
969 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
970 sizeof_node = declaration.root.stats[0].expr
971 sizeof_node.analyse_types(env)
972 if isinstance(sizeof_node, SizeofTypeNode):
973 return sizeof_node.arg_type
975 def can_coerce_to_char_literal(self):
976 return len(self.value) == 1
978 def coerce_to_boolean(self, env):
979 # This is special because testing a C char* for truth directly
980 # would yield the wrong result.
981 return BoolNode(self.pos, value=bool(self.value))
983 def coerce_to(self, dst_type, env):
984 if self.type == dst_type:
987 if not self.can_coerce_to_char_literal():
988 error(self.pos, "Only single-character string literals can be coerced into ints.")
990 if dst_type is PyrexTypes.c_py_unicode_type:
991 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.")
993 return CharNode(self.pos, value=self.value)
995 node = BytesNode(self.pos, value=self.value)
996 if dst_type.is_pyobject:
997 if dst_type in (py_object_type, Builtin.bytes_type):
998 node.type = Builtin.bytes_type
1000 self.check_for_coercion_error(dst_type, fail=True)
1002 elif dst_type == PyrexTypes.c_char_ptr_type:
1003 node.type = dst_type
1005 elif dst_type == PyrexTypes.c_uchar_ptr_type:
1006 node.type = PyrexTypes.c_char_ptr_type
1007 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
1008 elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
1009 node.type = dst_type
1012 # We still need to perform normal coerce_to processing on the
1013 # result, because we might be coercing to an extension type,
1014 # in which case a type test node will be needed.
1015 return ConstNode.coerce_to(node, dst_type, env)
1017 def generate_evaluation_code(self, code):
1018 if self.type.is_pyobject:
1019 self.result_code = code.get_py_string_const(self.value)
1021 self.result_code = code.get_string_const(self.value)
1023 def get_constant_c_result_code(self):
1026 def calculate_result_code(self):
1027 return self.result_code
1030 class UnicodeNode(PyConstNode):
1031 # A Python unicode object
1033 # value EncodedString
1034 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
1039 def coerce_to(self, dst_type, env):
1040 if dst_type is self.type:
1042 elif dst_type is PyrexTypes.c_py_unicode_type:
1043 if not self.can_coerce_to_char_literal():
1044 error(self.pos, "Only single-character Unicode string literals can be coerced into Py_UNICODE.")
1046 int_value = ord(self.value)
1047 return IntNode(self.pos, value=int_value, constant_result=int_value)
1048 elif not dst_type.is_pyobject:
1049 if dst_type.is_string and self.bytes_value is not None:
1050 # special case: '-3' enforced unicode literal used in a C char* context
1051 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
1052 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE.")
1053 elif dst_type is not py_object_type:
1054 if not self.check_for_coercion_error(dst_type):
1055 self.fail_assignment(dst_type)
1058 def can_coerce_to_char_literal(self):
1059 return len(self.value) == 1
1061 def contains_surrogates(self):
1062 # Check if the unicode string contains surrogate code points
1063 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1064 # Unicode, i.e. characters that would be spelled as two
1065 # separate code units on a narrow platform.
1066 for c in map(ord, self.value):
1067 if c > 65535: # can only happen on wide platforms
1069 # We only look for the first code unit (D800-DBFF) of a
1070 # surrogate pair - if we find one, the other one
1071 # (DC00-DFFF) is likely there, too. If we don't find it,
1072 # any second code unit cannot make for a surrogate pair by
1074 if c >= 0xD800 and c <= 0xDBFF:
1078 def generate_evaluation_code(self, code):
1079 self.result_code = code.get_py_string_const(self.value)
1081 def calculate_result_code(self):
1082 return self.result_code
1084 def compile_time_value(self, env):
1088 class StringNode(PyConstNode):
1089 # A Python str object, i.e. a byte string in Python 2.x and a
1090 # unicode string in Python 3.x
1092 # value BytesLiteral (or EncodedString with ASCII content)
1093 # unicode_value EncodedString or None
1094 # is_identifier boolean
1097 is_identifier = None
1098 unicode_value = None
1100 def coerce_to(self, dst_type, env):
1101 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1102 # if dst_type is Builtin.bytes_type:
1103 # # special case: bytes = 'str literal'
1104 # return BytesNode(self.pos, value=self.value)
1105 if not dst_type.is_pyobject:
1106 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1107 self.check_for_coercion_error(dst_type, fail=True)
1109 # this will be a unicode string in Py3, so make sure we can decode it
1110 if self.value.encoding and isinstance(self.value, StringEncoding.BytesLiteral):
1112 self.value.decode(self.value.encoding)
1113 except UnicodeDecodeError:
1114 error(self.pos, ("Decoding unprefixed string literal from '%s' failed. Consider using"
1115 "a byte string or unicode string explicitly, "
1116 "or adjust the source code encoding.") % self.value.encoding)
1120 def can_coerce_to_char_literal(self):
1121 return not self.is_identifier and len(self.value) == 1
1123 def generate_evaluation_code(self, code):
1124 self.result_code = code.get_py_string_const(
1125 self.value, identifier=self.is_identifier, is_str=True)
1127 def get_constant_c_result_code(self):
1130 def calculate_result_code(self):
1131 return self.result_code
1133 def compile_time_value(self, env):
1137 class IdentifierStringNode(StringNode):
1138 # A special str value that represents an identifier (bytes in Py2,
1140 is_identifier = True
1143 class LongNode(AtomicExprNode):
1144 # Python long integer literal
1148 type = py_object_type
1150 def calculate_constant_result(self):
1151 self.constant_result = Utils.str_to_number(self.value)
1153 def compile_time_value(self, denv):
1154 return Utils.str_to_number(self.value)
1156 def analyse_types(self, env):
1159 def may_be_none(self):
1162 gil_message = "Constructing Python long int"
1164 def generate_result_code(self, code):
1166 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1169 code.error_goto_if_null(self.result(), self.pos)))
1170 code.put_gotref(self.py_result())
1173 class ImagNode(AtomicExprNode):
1174 # Imaginary number literal
1176 # value float imaginary part
1178 type = PyrexTypes.c_double_complex_type
1180 def calculate_constant_result(self):
1181 self.constant_result = complex(0.0, self.value)
1183 def compile_time_value(self, denv):
1184 return complex(0.0, self.value)
1186 def analyse_types(self, env):
1187 self.type.create_declaration_utility_code(env)
1189 def may_be_none(self):
1192 def coerce_to(self, dst_type, env):
1193 if self.type is dst_type:
1195 node = ImagNode(self.pos, value=self.value)
1196 if dst_type.is_pyobject:
1198 node.type = PyrexTypes.py_object_type
1199 # We still need to perform normal coerce_to processing on the
1200 # result, because we might be coercing to an extension type,
1201 # in which case a type test node will be needed.
1202 return AtomicExprNode.coerce_to(node, dst_type, env)
1204 gil_message = "Constructing complex number"
1206 def calculate_result_code(self):
1207 if self.type.is_pyobject:
1208 return self.result()
1210 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1212 def generate_result_code(self, code):
1213 if self.type.is_pyobject:
1215 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1218 code.error_goto_if_null(self.result(), self.pos)))
1219 code.put_gotref(self.py_result())
1222 class NewExprNode(AtomicExprNode):
1226 # cppclass node c++ class to create
1230 def infer_type(self, env):
1231 type = self.cppclass.analyse_as_type(env)
1232 if type is None or not type.is_cpp_class:
1233 error(self.pos, "new operator can only be applied to a C++ class")
1234 self.type = error_type
1237 constructor = type.scope.lookup(u'<init>')
1238 if constructor is None:
1239 return_type = PyrexTypes.CFuncType(type, [])
1240 return_type = PyrexTypes.CPtrType(return_type)
1241 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1242 constructor = type.scope.lookup(u'<init>')
1243 self.class_type = type
1244 self.entry = constructor
1245 self.type = constructor.type
1248 def analyse_types(self, env):
1249 if self.type is None:
1250 self.infer_type(env)
1252 def may_be_none(self):
1255 def generate_result_code(self, code):
1258 def calculate_result_code(self):
1259 return "new " + self.class_type.declaration_code("")
1262 class NameNode(AtomicExprNode):
1263 # Reference to a local or global variable name.
1265 # name string Python name of the variable
1266 # entry Entry Symbol table entry
1267 # type_entry Entry For extension type names, the original type entry
1270 is_cython_module = False
1271 cython_attribute = None
1272 lhs_of_first_assignment = False
1273 is_used_as_rvalue = 0
1277 def create_analysed_rvalue(pos, env, entry):
1278 node = NameNode(pos)
1279 node.analyse_types(env, entry=entry)
1282 def as_cython_attribute(self):
1283 return self.cython_attribute
1285 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1287 def type_dependencies(self, env):
1288 if self.entry is None:
1289 self.entry = env.lookup(self.name)
1290 if self.entry is not None and self.entry.type.is_unspecified:
1291 return (self.entry,)
1295 def infer_type(self, env):
1296 if self.entry is None:
1297 self.entry = env.lookup(self.name)
1298 if self.entry is None:
1299 return py_object_type
1300 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1301 self.name == self.entry.type.name:
1302 # Unfortunately the type attribute of type objects
1303 # is used for the pointer to the type they represent.
1305 elif self.entry.type.is_cfunction:
1306 # special case: referring to a C function must return its pointer
1307 return PyrexTypes.CPtrType(self.entry.type)
1309 return self.entry.type
1311 def compile_time_value(self, denv):
1313 return denv.lookup(self.name)
1315 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1317 def get_constant_c_result_code(self):
1318 if not self.entry or self.entry.type.is_pyobject:
1320 return self.entry.cname
1322 def coerce_to(self, dst_type, env):
1323 # If coercing to a generic pyobject and this is a builtin
1324 # C function with a Python equivalent, manufacture a NameNode
1325 # referring to the Python builtin.
1326 #print "NameNode.coerce_to:", self.name, dst_type ###
1327 if dst_type is py_object_type:
1329 if entry and entry.is_cfunction:
1330 var_entry = entry.as_variable
1332 if var_entry.is_builtin and Options.cache_builtins:
1333 var_entry = env.declare_builtin(var_entry.name, self.pos)
1334 node = NameNode(self.pos, name = self.name)
1335 node.entry = var_entry
1336 node.analyse_rvalue_entry(env)
1338 return super(NameNode, self).coerce_to(dst_type, env)
1340 def analyse_as_module(self, env):
1341 # Try to interpret this as a reference to a cimported module.
1342 # Returns the module scope, or None.
1345 entry = env.lookup(self.name)
1346 if entry and entry.as_module:
1347 return entry.as_module
1350 def analyse_as_type(self, env):
1351 if self.cython_attribute:
1352 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1354 type = PyrexTypes.parse_basic_type(self.name)
1359 entry = env.lookup(self.name)
1360 if entry and entry.is_type:
1365 def analyse_as_extension_type(self, env):
1366 # Try to interpret this as a reference to an extension type.
1367 # Returns the extension type, or None.
1370 entry = env.lookup(self.name)
1371 if entry and entry.is_type and entry.type.is_extension_type:
1376 def analyse_target_declaration(self, env):
1378 self.entry = env.lookup_here(self.name)
1380 if env.directives['warn.undeclared']:
1381 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1382 if env.directives['infer_types'] != False:
1383 type = unspecified_type
1385 type = py_object_type
1386 self.entry = env.declare_var(self.name, type, self.pos)
1387 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1388 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1389 if self.entry.is_declared_generic:
1390 self.result_ctype = py_object_type
1392 def analyse_types(self, env):
1393 if self.entry is None:
1394 self.entry = env.lookup(self.name)
1396 self.entry = env.declare_builtin(self.name, self.pos)
1398 self.type = PyrexTypes.error_type
1403 if entry.type.is_buffer:
1405 Buffer.used_buffer_aux_vars(entry)
1406 if entry.utility_code:
1407 env.use_utility_code(entry.utility_code)
1408 self.analyse_rvalue_entry(env)
1410 def analyse_target_types(self, env):
1411 self.analyse_entry(env)
1412 if not self.is_lvalue():
1413 error(self.pos, "Assignment to non-lvalue '%s'"
1415 self.type = PyrexTypes.error_type
1417 if self.entry.type.is_buffer:
1419 Buffer.used_buffer_aux_vars(self.entry)
1421 def analyse_rvalue_entry(self, env):
1422 #print "NameNode.analyse_rvalue_entry:", self.name ###
1423 #print "Entry:", self.entry.__dict__ ###
1424 self.analyse_entry(env)
1426 if entry.is_declared_generic:
1427 self.result_ctype = py_object_type
1428 if entry.is_pyglobal or entry.is_builtin:
1429 if Options.cache_builtins and entry.is_builtin:
1433 env.use_utility_code(get_name_interned_utility_code)
1434 self.is_used_as_rvalue = 1
1436 def nogil_check(self, env):
1437 if self.is_used_as_rvalue:
1439 if entry.is_builtin:
1440 if not Options.cache_builtins: # cached builtins are ok
1442 elif entry.is_pyglobal:
1445 gil_message = "Accessing Python global or builtin"
1447 def analyse_entry(self, env):
1448 #print "NameNode.analyse_entry:", self.name ###
1449 self.check_identifier_kind()
1454 def check_identifier_kind(self):
1455 # Check that this is an appropriate kind of name for use in an
1456 # expression. Also finds the variable entry associated with
1457 # an extension type.
1459 if entry.is_type and entry.type.is_extension_type:
1460 self.type_entry = entry
1461 if not (entry.is_const or entry.is_variable
1462 or entry.is_builtin or entry.is_cfunction
1463 or entry.is_cpp_class):
1464 if self.entry.as_variable:
1465 self.entry = self.entry.as_variable
1468 "'%s' is not a constant, variable or function identifier" % self.name)
1470 def is_simple(self):
1471 # If it's not a C variable, it'll be in a temp.
1474 def calculate_target_results(self, env):
1477 def check_const(self):
1479 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1484 def check_const_addr(self):
1486 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1487 self.addr_not_const()
1491 def is_lvalue(self):
1492 return self.entry.is_variable and \
1493 not self.entry.type.is_array and \
1494 not self.entry.is_readonly
1496 def is_ephemeral(self):
1497 # Name nodes are never ephemeral, even if the
1498 # result is in a temporary.
1501 def calculate_result_code(self):
1504 return "<error>" # There was an error earlier
1507 def generate_result_code(self, code):
1508 assert hasattr(self, 'entry')
1511 return # There was an error earlier
1512 if entry.is_builtin and Options.cache_builtins:
1513 return # Lookup already cached
1514 elif entry.is_pyclass_attr:
1515 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1516 interned_cname = code.intern_identifier(self.entry.name)
1517 if entry.is_builtin:
1518 namespace = Naming.builtins_cname
1519 else: # entry.is_pyglobal
1520 namespace = entry.scope.namespace_cname
1522 '%s = PyObject_GetItem(%s, %s); %s' % (
1526 code.error_goto_if_null(self.result(), self.pos)))
1527 code.put_gotref(self.py_result())
1529 elif entry.is_pyglobal or entry.is_builtin:
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
1536 code.globalstate.use_utility_code(get_name_interned_utility_code)
1538 '%s = __Pyx_GetName(%s, %s); %s' % (
1542 code.error_goto_if_null(self.result(), self.pos)))
1543 code.put_gotref(self.py_result())
1545 elif entry.is_local and False:
1546 # control flow not good enough yet
1547 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1548 if assigned is False:
1549 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1550 elif not Options.init_local_none and assigned is None:
1551 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1552 (entry.cname, entry.name, code.error_goto(self.pos)))
1553 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1555 def generate_assignment_code(self, rhs, code):
1556 #print "NameNode.generate_assignment_code:", self.name ###
1559 return # There was an error earlier
1561 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1562 and not self.lhs_of_first_assignment):
1563 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1565 # is_pyglobal seems to be True for module level-globals only.
1566 # We use this to access class->tp_dict if necessary.
1567 if entry.is_pyglobal:
1568 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1569 interned_cname = code.intern_identifier(self.entry.name)
1570 namespace = self.entry.scope.namespace_cname
1572 # if the entry is a member we have to cheat: SetAttr does not work
1573 # on types, so we create a descriptor which is then added to tp_dict
1574 code.put_error_if_neg(self.pos,
1575 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1579 rhs.generate_disposal_code(code)
1580 rhs.free_temps(code)
1581 # in Py2.6+, we need to invalidate the method cache
1582 code.putln("PyType_Modified(%s);" %
1583 entry.scope.parent_type.typeptr_cname)
1584 elif entry.is_pyclass_attr:
1585 code.put_error_if_neg(self.pos,
1586 'PyObject_SetItem(%s, %s, %s)' % (
1590 rhs.generate_disposal_code(code)
1591 rhs.free_temps(code)
1593 code.put_error_if_neg(self.pos,
1594 'PyObject_SetAttr(%s, %s, %s)' % (
1598 if debug_disposal_code:
1599 print("NameNode.generate_assignment_code:")
1600 print("...generating disposal code for %s" % rhs)
1601 rhs.generate_disposal_code(code)
1602 rhs.free_temps(code)
1604 if self.type.is_buffer:
1605 # Generate code for doing the buffer release/acquisition.
1606 # This might raise an exception in which case the assignment (done
1607 # below) will not happen.
1609 # The reason this is not in a typetest-like node is because the
1610 # variables that the acquired buffer info is stored to is allocated
1611 # per entry and coupled with it.
1612 self.generate_acquire_buffer(rhs, code)
1614 if self.type.is_pyobject:
1615 #print "NameNode.generate_assignment_code: to", self.name ###
1616 #print "...from", rhs ###
1617 #print "...LHS type", self.type, "ctype", self.ctype() ###
1618 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1619 if self.use_managed_ref:
1620 rhs.make_owned_reference(code)
1621 is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
1622 if not self.lhs_of_first_assignment:
1624 code.put_gotref(self.py_result())
1625 if entry.is_local and not Options.init_local_none:
1626 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1627 if initialized is True:
1628 code.put_decref(self.result(), self.ctype())
1629 elif initialized is None:
1630 code.put_xdecref(self.result(), self.ctype())
1632 code.put_decref(self.result(), self.ctype())
1634 code.put_giveref(rhs.py_result())
1636 code.putln('%s = %s;' % (self.result(),
1637 rhs.result_as(self.ctype())))
1638 if debug_disposal_code:
1639 print("NameNode.generate_assignment_code:")
1640 print("...generating post-assignment code for %s" % rhs)
1641 rhs.generate_post_assignment_code(code)
1642 rhs.free_temps(code)
1644 def generate_acquire_buffer(self, rhs, code):
1645 # rhstmp is only used in case the rhs is a complicated expression leading to
1646 # the object, to avoid repeating the same C expression for every reference
1647 # to the rhs. It does NOT hold a reference.
1648 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1650 rhstmp = rhs.result_as(self.ctype())
1652 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1653 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1655 buffer_aux = self.entry.buffer_aux
1656 bufstruct = buffer_aux.buffer_info_var.cname
1658 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1659 is_initialized=not self.lhs_of_first_assignment,
1660 pos=self.pos, code=code)
1663 code.putln("%s = 0;" % rhstmp)
1664 code.funcstate.release_temp(rhstmp)
1666 def generate_deletion_code(self, code):
1667 if self.entry is None:
1668 return # There was an error earlier
1669 if not self.entry.is_pyglobal:
1670 error(self.pos, "Deletion of local or C global name not supported")
1672 if self.entry.is_pyclass_attr:
1673 namespace = self.entry.scope.namespace_cname
1674 code.put_error_if_neg(self.pos,
1675 'PyMapping_DelItemString(%s, "%s")' % (
1679 code.put_error_if_neg(self.pos,
1680 '__Pyx_DelAttrString(%s, "%s")' % (
1681 Naming.module_cname,
1684 def annotate(self, code):
1685 if hasattr(self, 'is_called') and self.is_called:
1686 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1687 if self.type.is_pyobject:
1688 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1690 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1692 class BackquoteNode(ExprNode):
1697 type = py_object_type
1701 def analyse_types(self, env):
1702 self.arg.analyse_types(env)
1703 self.arg = self.arg.coerce_to_pyobject(env)
1706 gil_message = "Backquote expression"
1708 def calculate_constant_result(self):
1709 self.constant_result = repr(self.arg.constant_result)
1711 def generate_result_code(self, code):
1713 "%s = PyObject_Repr(%s); %s" % (
1715 self.arg.py_result(),
1716 code.error_goto_if_null(self.result(), self.pos)))
1717 code.put_gotref(self.py_result())
1721 class ImportNode(ExprNode):
1722 # Used as part of import statement implementation.
1723 # Implements result =
1724 # __import__(module_name, globals(), None, name_list)
1726 # module_name StringNode dotted name of module
1727 # name_list ListNode or None list of names to be imported
1729 type = py_object_type
1731 subexprs = ['module_name', 'name_list']
1733 def analyse_types(self, env):
1734 self.module_name.analyse_types(env)
1735 self.module_name = self.module_name.coerce_to_pyobject(env)
1737 self.name_list.analyse_types(env)
1738 self.name_list.coerce_to_pyobject(env)
1740 env.use_utility_code(import_utility_code)
1742 gil_message = "Python import"
1744 def generate_result_code(self, code):
1746 name_list_code = self.name_list.py_result()
1748 name_list_code = "0"
1750 "%s = __Pyx_Import(%s, %s); %s" % (
1752 self.module_name.py_result(),
1754 code.error_goto_if_null(self.result(), self.pos)))
1755 code.put_gotref(self.py_result())
1758 class IteratorNode(ExprNode):
1759 # Used as part of for statement implementation.
1761 # allocate_counter_temp/release_counter_temp needs to be called
1762 # by parent (ForInStatNode)
1764 # Implements result = iter(sequence)
1768 type = py_object_type
1770 subexprs = ['sequence']
1772 def analyse_types(self, env):
1773 self.sequence.analyse_types(env)
1774 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1775 not self.sequence.type.is_string:
1776 # C array iteration will be transformed later on
1777 self.type = self.sequence.type
1779 self.sequence = self.sequence.coerce_to_pyobject(env)
1780 if self.sequence.type is list_type or \
1781 self.sequence.type is tuple_type:
1782 self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
1785 gil_message = "Iterating over Python object"
1787 def allocate_counter_temp(self, code):
1788 self.counter_cname = code.funcstate.allocate_temp(
1789 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1791 def release_counter_temp(self, code):
1792 code.funcstate.release_temp(self.counter_cname)
1794 def generate_result_code(self, code):
1795 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1796 raise InternalError("for in carray slice not transformed")
1797 is_builtin_sequence = self.sequence.type is list_type or \
1798 self.sequence.type is tuple_type
1799 may_be_a_sequence = not self.sequence.type.is_builtin_type
1800 if may_be_a_sequence:
1802 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1803 self.sequence.py_result(),
1804 self.sequence.py_result()))
1805 if is_builtin_sequence or may_be_a_sequence:
1807 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1810 self.sequence.py_result(),
1812 if not is_builtin_sequence:
1813 if may_be_a_sequence:
1814 code.putln("} else {")
1815 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1818 self.sequence.py_result(),
1819 code.error_goto_if_null(self.result(), self.pos)))
1820 code.put_gotref(self.py_result())
1821 if may_be_a_sequence:
1825 class NextNode(AtomicExprNode):
1826 # Used as part of for statement implementation.
1827 # Implements result = iterator.next()
1828 # Created during analyse_types phase.
1829 # The iterator is not owned by this node.
1833 type = py_object_type
1835 def __init__(self, iterator, env):
1836 self.pos = iterator.pos
1837 self.iterator = iterator
1838 if iterator.type.is_ptr or iterator.type.is_array:
1839 self.type = iterator.type.base_type
1842 def generate_result_code(self, code):
1843 sequence_type = self.iterator.sequence.type
1844 if sequence_type is list_type:
1845 type_checks = [(list_type, "List")]
1846 elif sequence_type is tuple_type:
1847 type_checks = [(tuple_type, "Tuple")]
1848 elif not sequence_type.is_builtin_type:
1849 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1853 for py_type, prefix in type_checks:
1854 if len(type_checks) > 1:
1856 "if (likely(Py%s_CheckExact(%s))) {" % (
1857 prefix, self.iterator.py_result()))
1859 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1860 self.iterator.counter_cname,
1862 self.iterator.py_result()))
1864 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1867 self.iterator.py_result(),
1868 self.iterator.counter_cname,
1870 self.iterator.counter_cname))
1871 if len(type_checks) > 1:
1873 if len(type_checks) == 1:
1877 "%s = PyIter_Next(%s);" % (
1879 self.iterator.py_result()))
1883 code.putln(code.error_goto_if_PyErr(self.pos))
1884 code.putln("break;")
1886 code.put_gotref(self.py_result())
1890 class ExcValueNode(AtomicExprNode):
1891 # Node created during analyse_types phase
1892 # of an ExceptClauseNode to fetch the current
1895 type = py_object_type
1897 def __init__(self, pos, env):
1898 ExprNode.__init__(self, pos)
1900 def set_var(self, var):
1903 def calculate_result_code(self):
1906 def generate_result_code(self, code):
1909 def analyse_types(self, env):
1913 class TempNode(ExprNode):
1914 # Node created during analyse_types phase
1915 # of some nodes to hold a temporary value.
1917 # Note: One must call "allocate" and "release" on
1918 # the node during code generation to get/release the temp.
1919 # This is because the temp result is often used outside of
1920 # the regular cycle.
1924 def __init__(self, pos, type, env):
1925 ExprNode.__init__(self, pos)
1927 if type.is_pyobject:
1928 self.result_ctype = py_object_type
1931 def analyse_types(self, env):
1934 def generate_result_code(self, code):
1937 def allocate(self, code):
1938 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1940 def release(self, code):
1941 code.funcstate.release_temp(self.temp_cname)
1942 self.temp_cname = None
1946 return self.temp_cname
1948 assert False, "Remember to call allocate/release on TempNode"
1951 # Do not participate in normal temp alloc/dealloc:
1952 def allocate_temp_result(self, code):
1955 def release_temp_result(self, code):
1958 class PyTempNode(TempNode):
1959 # TempNode holding a Python value.
1961 def __init__(self, pos, env):
1962 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1964 class RawCNameExprNode(ExprNode):
1967 def __init__(self, pos, type=None):
1971 def analyse_types(self, env):
1974 def set_cname(self, cname):
1980 def generate_result_code(self, code):
1984 #-------------------------------------------------------------------
1988 #-------------------------------------------------------------------
1990 class IndexNode(ExprNode):
1991 # Sequence indexing.
1995 # indices [ExprNode]
1996 # is_buffer_access boolean Whether this is a buffer access.
1998 # indices is used on buffer access, index on non-buffer access.
1999 # The former contains a clean list of index parameters, the
2000 # latter whatever Python object is needed for index access.
2002 subexprs = ['base', 'index', 'indices']
2005 def __init__(self, pos, index, *args, **kw):
2006 ExprNode.__init__(self, pos, index=index, *args, **kw)
2009 def calculate_constant_result(self):
2010 self.constant_result = \
2011 self.base.constant_result[self.index.constant_result]
2013 def compile_time_value(self, denv):
2014 base = self.base.compile_time_value(denv)
2015 index = self.index.compile_time_value(denv)
2018 except Exception, e:
2019 self.compile_time_value_error(e)
2021 def is_ephemeral(self):
2022 return self.base.is_ephemeral()
2024 def analyse_target_declaration(self, env):
2027 def analyse_as_type(self, env):
2028 base_type = self.base.analyse_as_type(env)
2029 if base_type and not base_type.is_pyobject:
2030 if base_type.is_cpp_class:
2031 if isinstance(self.index, TupleNode):
2032 template_values = self.index.args
2034 template_values = [self.index]
2036 type_node = Nodes.TemplatedTypeNode(
2038 positional_args = template_values,
2039 keyword_args = None)
2040 return type_node.analyse(env, base_type = base_type)
2042 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2045 def type_dependencies(self, env):
2046 return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2048 def infer_type(self, env):
2049 base_type = self.base.infer_type(env)
2050 if isinstance(self.index, SliceNode):
2052 if base_type.is_string:
2053 # sliced C strings must coerce to Python
2055 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2056 # slicing these returns the same type
2059 # TODO: Handle buffers (hopefully without too much redundancy).
2060 return py_object_type
2062 index_type = self.index.infer_type(env)
2063 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2065 if base_type is unicode_type:
2066 # Py_UNICODE will automatically coerce to a unicode string
2067 # if required, so this is safe. We only infer Py_UNICODE
2068 # when the index is a C integer type. Otherwise, we may
2069 # need to use normal Python item access, in which case
2070 # it's faster to return the one-char unicode string than
2071 # to receive it, throw it away, and potentially rebuild it
2072 # on a subsequent PyObject coercion.
2073 return PyrexTypes.c_py_unicode_type
2074 elif isinstance(self.base, BytesNode):
2075 #if env.global_scope().context.language_level >= 3:
2076 # # infering 'char' can be made to work in Python 3 mode
2077 # return PyrexTypes.c_char_type
2078 # Py2/3 return different types on indexing bytes objects
2079 return py_object_type
2080 elif base_type.is_ptr or base_type.is_array:
2081 return base_type.base_type
2083 # may be slicing or indexing, we don't know
2084 if base_type is unicode_type:
2085 # this type always returns its own type on Python indexing/slicing
2088 # TODO: Handle buffers (hopefully without too much redundancy).
2089 return py_object_type
2091 def analyse_types(self, env):
2092 self.analyse_base_and_index_types(env, getting = 1)
2094 def analyse_target_types(self, env):
2095 self.analyse_base_and_index_types(env, setting = 1)
2097 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2098 # Note: This might be cleaned up by having IndexNode
2099 # parsed in a saner way and only construct the tuple if
2102 # Note that this function must leave IndexNode in a cloneable state.
2103 # For buffers, self.index is packed out on the initial analysis, and
2104 # when cloning self.indices is copied.
2105 self.is_buffer_access = False
2107 self.base.analyse_types(env)
2108 if self.base.type.is_error:
2109 # Do not visit child tree if base is undeclared to avoid confusing
2111 self.type = PyrexTypes.error_type
2114 is_slice = isinstance(self.index, SliceNode)
2115 # Potentially overflowing index value.
2116 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2117 self.index = self.index.coerce_to_pyobject(env)
2119 # Handle the case where base is a literal char* (and we expect a string, not an int)
2120 if isinstance(self.base, BytesNode) or is_slice:
2121 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2122 self.base = self.base.coerce_to_pyobject(env)
2124 skip_child_analysis = False
2125 buffer_access = False
2126 if self.base.type.is_buffer:
2128 indices = self.indices
2130 if isinstance(self.index, TupleNode):
2131 indices = self.index.args
2133 indices = [self.index]
2134 if len(indices) == self.base.type.ndim:
2135 buffer_access = True
2136 skip_child_analysis = True
2138 x.analyse_types(env)
2139 if not x.type.is_int:
2140 buffer_access = False
2142 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2144 # On cloning, indices is cloned. Otherwise, unpack index into indices
2145 assert not (buffer_access and isinstance(self.index, CloneNode))
2148 self.indices = indices
2150 self.type = self.base.type.dtype
2151 self.is_buffer_access = True
2152 self.buffer_type = self.base.entry.type
2154 if getting and self.type.is_pyobject:
2157 if not self.base.entry.type.writable:
2158 error(self.pos, "Writing to readonly buffer")
2160 self.base.entry.buffer_aux.writable_needed = True
2162 base_type = self.base.type
2163 if isinstance(self.index, TupleNode):
2164 self.index.analyse_types(env, skip_children=skip_child_analysis)
2165 elif not skip_child_analysis:
2166 self.index.analyse_types(env)
2167 self.original_index_type = self.index.type
2168 if base_type is PyrexTypes.c_py_unicode_type:
2169 # we infer Py_UNICODE for unicode strings in some
2170 # cases, but indexing must still work for them
2171 if self.index.constant_result in (0, -1):
2172 # FIXME: we know that this node is redundant -
2173 # currently, this needs to get handled in Optimize.py
2175 self.base = self.base.coerce_to_pyobject(env)
2176 base_type = self.base.type
2177 if base_type.is_pyobject:
2178 if self.index.type.is_int:
2180 and (base_type in (list_type, tuple_type, unicode_type))
2181 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2182 and not env.directives['boundscheck']):
2186 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2188 self.index = self.index.coerce_to_pyobject(env)
2190 if self.index.type.is_int and base_type is unicode_type:
2191 # Py_UNICODE will automatically coerce to a unicode string
2192 # if required, so this is fast and safe
2193 self.type = PyrexTypes.c_py_unicode_type
2194 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2195 self.type = base_type
2197 self.type = py_object_type
2199 if base_type.is_ptr or base_type.is_array:
2200 self.type = base_type.base_type
2202 self.type = base_type
2203 elif self.index.type.is_pyobject:
2204 self.index = self.index.coerce_to(
2205 PyrexTypes.c_py_ssize_t_type, env)
2206 elif not self.index.type.is_int:
2208 "Invalid index type '%s'" %
2210 elif base_type.is_cpp_class:
2211 function = env.lookup_operator("[]", [self.base, self.index])
2212 if function is None:
2213 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2214 self.type = PyrexTypes.error_type
2215 self.result_code = "<error>"
2217 func_type = function.type
2218 if func_type.is_ptr:
2219 func_type = func_type.base_type
2220 self.index = self.index.coerce_to(func_type.args[0].type, env)
2221 self.type = func_type.return_type
2222 if setting and not func_type.return_type.is_reference:
2223 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2226 "Attempting to index non-array type '%s'" %
2228 self.type = PyrexTypes.error_type
2230 gil_message = "Indexing Python object"
2232 def nogil_check(self, env):
2233 if self.is_buffer_access:
2234 if env.directives['boundscheck']:
2235 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2237 elif self.type.is_pyobject:
2238 error(self.pos, "Cannot access buffer with object dtype without gil")
2240 super(IndexNode, self).nogil_check(env)
2243 def check_const_addr(self):
2244 return self.base.check_const_addr() and self.index.check_const()
2246 def is_lvalue(self):
2249 def calculate_result_code(self):
2250 if self.is_buffer_access:
2251 return "(*%s)" % self.buffer_ptr_code
2252 elif self.base.type is list_type:
2253 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2254 elif self.base.type is tuple_type:
2255 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2256 elif self.base.type is unicode_type and self.type is PyrexTypes.c_py_unicode_type:
2257 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2258 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2259 error(self.pos, "Invalid use of pointer slice")
2261 return "(%s[%s])" % (
2262 self.base.result(), self.index.result())
2264 def extra_index_params(self):
2265 if self.index.type.is_int:
2266 if self.original_index_type.signed:
2267 size_adjustment = ""
2269 size_adjustment = "+1"
2270 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2274 def generate_subexpr_evaluation_code(self, code):
2275 self.base.generate_evaluation_code(code)
2276 if not self.indices:
2277 self.index.generate_evaluation_code(code)
2279 for i in self.indices:
2280 i.generate_evaluation_code(code)
2282 def generate_subexpr_disposal_code(self, code):
2283 self.base.generate_disposal_code(code)
2284 if not self.indices:
2285 self.index.generate_disposal_code(code)
2287 for i in self.indices:
2288 i.generate_disposal_code(code)
2290 def free_subexpr_temps(self, code):
2291 self.base.free_temps(code)
2292 if not self.indices:
2293 self.index.free_temps(code)
2295 for i in self.indices:
2298 def generate_result_code(self, code):
2299 if self.is_buffer_access:
2300 if code.globalstate.directives['nonecheck']:
2301 self.put_nonecheck(code)
2302 self.buffer_ptr_code = self.buffer_lookup_code(code)
2303 if self.type.is_pyobject:
2304 # is_temp is True, so must pull out value and incref it.
2305 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2306 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2308 if self.type.is_pyobject:
2309 if self.index.type.is_int:
2310 index_code = self.index.result()
2311 if self.base.type is list_type:
2312 function = "__Pyx_GetItemInt_List"
2313 elif self.base.type is tuple_type:
2314 function = "__Pyx_GetItemInt_Tuple"
2316 function = "__Pyx_GetItemInt"
2317 code.globalstate.use_utility_code(getitem_int_utility_code)
2319 index_code = self.index.py_result()
2320 if self.base.type is dict_type:
2321 function = "__Pyx_PyDict_GetItem"
2322 code.globalstate.use_utility_code(getitem_dict_utility_code)
2324 function = "PyObject_GetItem"
2326 "%s = %s(%s, %s%s); if (!%s) %s" % (
2329 self.base.py_result(),
2331 self.extra_index_params(),
2333 code.error_goto(self.pos)))
2334 code.put_gotref(self.py_result())
2335 elif self.type is PyrexTypes.c_py_unicode_type and self.base.type is unicode_type:
2336 assert self.index.type.is_int
2337 index_code = self.index.result()
2338 function = "__Pyx_GetItemInt_Unicode"
2339 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2341 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2344 self.base.py_result(),
2346 self.extra_index_params(),
2348 code.error_goto(self.pos)))
2350 def generate_setitem_code(self, value_code, code):
2351 if self.index.type.is_int:
2352 function = "__Pyx_SetItemInt"
2353 index_code = self.index.result()
2354 code.globalstate.use_utility_code(setitem_int_utility_code)
2356 index_code = self.index.py_result()
2357 if self.base.type is dict_type:
2358 function = "PyDict_SetItem"
2359 # It would seem that we could specialized lists/tuples, but that
2360 # shouldn't happen here.
2361 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2362 # not a PyObject*, and bad conversion here would give the wrong
2363 # exception. Also, tuples are supposed to be immutable, and raise
2364 # TypeErrors when trying to set their entries (PyTuple_SetItem
2365 # is for creating new tuples from).
2367 function = "PyObject_SetItem"
2369 "if (%s(%s, %s, %s%s) < 0) %s" % (
2371 self.base.py_result(),
2374 self.extra_index_params(),
2375 code.error_goto(self.pos)))
2377 def generate_buffer_setitem_code(self, rhs, code, op=""):
2378 # Used from generate_assignment_code and InPlaceAssignmentNode
2379 if code.globalstate.directives['nonecheck']:
2380 self.put_nonecheck(code)
2381 ptrexpr = self.buffer_lookup_code(code)
2382 if self.buffer_type.dtype.is_pyobject:
2383 # Must manage refcounts. Decref what is already there
2384 # and incref what we put in.
2385 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2386 rhs_code = rhs.result()
2387 code.putln("%s = %s;" % (ptr, ptrexpr))
2388 code.put_gotref("*%s" % ptr)
2389 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2392 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2393 code.put_giveref("*%s" % ptr)
2394 code.funcstate.release_temp(ptr)
2397 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2399 def generate_assignment_code(self, rhs, code):
2400 self.generate_subexpr_evaluation_code(code)
2401 if self.is_buffer_access:
2402 self.generate_buffer_setitem_code(rhs, code)
2403 elif self.type.is_pyobject:
2404 self.generate_setitem_code(rhs.py_result(), code)
2408 self.result(), rhs.result()))
2409 self.generate_subexpr_disposal_code(code)
2410 self.free_subexpr_temps(code)
2411 rhs.generate_disposal_code(code)
2412 rhs.free_temps(code)
2414 def generate_deletion_code(self, code):
2415 self.generate_subexpr_evaluation_code(code)
2416 #if self.type.is_pyobject:
2417 if self.index.type.is_int:
2418 function = "__Pyx_DelItemInt"
2419 index_code = self.index.result()
2420 code.globalstate.use_utility_code(delitem_int_utility_code)
2422 index_code = self.index.py_result()
2423 if self.base.type is dict_type:
2424 function = "PyDict_DelItem"
2426 function = "PyObject_DelItem"
2428 "if (%s(%s, %s%s) < 0) %s" % (
2430 self.base.py_result(),
2432 self.extra_index_params(),
2433 code.error_goto(self.pos)))
2434 self.generate_subexpr_disposal_code(code)
2435 self.free_subexpr_temps(code)
2437 def buffer_lookup_code(self, code):
2438 # Assign indices to temps
2439 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2440 for temp, index in zip(index_temps, self.indices):
2441 code.putln("%s = %s;" % (temp, index.result()))
2442 # Generate buffer access code using these temps
2444 # The above could happen because child_attrs is wrong somewhere so that
2445 # options are not propagated.
2446 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2447 index_signeds=[i.type.signed for i in self.indices],
2448 index_cnames=index_temps,
2449 directives=code.globalstate.directives,
2450 pos=self.pos, code=code)
2452 def put_nonecheck(self, code):
2453 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2454 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2455 code.putln("__Pyx_RaiseNoneIndexingError();")
2456 code.putln(code.error_goto(self.pos))
2459 class SliceIndexNode(ExprNode):
2460 # 2-element slice indexing
2463 # start ExprNode or None
2464 # stop ExprNode or None
2466 subexprs = ['base', 'start', 'stop']
2468 def infer_type(self, env):
2469 base_type = self.base.infer_type(env)
2470 if base_type.is_string:
2472 elif base_type in (bytes_type, str_type, unicode_type,
2473 list_type, tuple_type):
2475 return py_object_type
2477 def calculate_constant_result(self):
2478 self.constant_result = self.base.constant_result[
2479 self.start.constant_result : self.stop.constant_result]
2481 def compile_time_value(self, denv):
2482 base = self.base.compile_time_value(denv)
2483 if self.start is None:
2486 start = self.start.compile_time_value(denv)
2487 if self.stop is None:
2490 stop = self.stop.compile_time_value(denv)
2492 return base[start:stop]
2493 except Exception, e:
2494 self.compile_time_value_error(e)
2496 def analyse_target_declaration(self, env):
2499 def analyse_target_types(self, env):
2500 self.analyse_types(env)
2501 # when assigning, we must accept any Python type
2502 if self.type.is_pyobject:
2503 self.type = py_object_type
2505 def analyse_types(self, env):
2506 self.base.analyse_types(env)
2508 self.start.analyse_types(env)
2510 self.stop.analyse_types(env)
2511 base_type = self.base.type
2512 if base_type.is_string:
2513 self.type = bytes_type
2514 elif base_type.is_ptr:
2515 self.type = base_type
2516 elif base_type.is_array:
2517 # we need a ptr type here instead of an array type, as
2518 # array types can result in invalid type casts in the C
2520 self.type = PyrexTypes.CPtrType(base_type.base_type)
2522 self.base = self.base.coerce_to_pyobject(env)
2523 self.type = py_object_type
2524 if base_type.is_builtin_type:
2525 # slicing builtin types returns something of the same type
2526 self.type = base_type
2527 c_int = PyrexTypes.c_py_ssize_t_type
2529 self.start = self.start.coerce_to(c_int, env)
2531 self.stop = self.stop.coerce_to(c_int, env)
2534 nogil_check = Node.gil_error
2535 gil_message = "Slicing Python object"
2537 def generate_result_code(self, code):
2538 if not self.type.is_pyobject:
2540 "Slicing is not currently supported for '%s'." % self.type)
2542 if self.base.type.is_string:
2543 if self.stop is None:
2545 "%s = PyBytes_FromString(%s + %s); %s" % (
2549 code.error_goto_if_null(self.result(), self.pos)))
2552 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2558 code.error_goto_if_null(self.result(), self.pos)))
2561 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2563 self.base.py_result(),
2566 code.error_goto_if_null(self.result(), self.pos)))
2567 code.put_gotref(self.py_result())
2569 def generate_assignment_code(self, rhs, code):
2570 self.generate_subexpr_evaluation_code(code)
2571 if self.type.is_pyobject:
2572 code.put_error_if_neg(self.pos,
2573 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2574 self.base.py_result(),
2581 start_offset = self.start_code()
2582 if start_offset == '0':
2586 if rhs.type.is_array:
2587 array_length = rhs.type.size
2588 self.generate_slice_guard_code(code, array_length)
2591 "Slice assignments from pointers are not yet supported.")
2592 # FIXME: fix the array size according to start/stop
2593 array_length = self.base.type.size
2594 for i in range(array_length):
2595 code.putln("%s[%s%s] = %s[%d];" % (
2596 self.base.result(), start_offset, i,
2598 self.generate_subexpr_disposal_code(code)
2599 self.free_subexpr_temps(code)
2600 rhs.generate_disposal_code(code)
2601 rhs.free_temps(code)
2603 def generate_deletion_code(self, code):
2604 if not self.base.type.is_pyobject:
2606 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2608 self.generate_subexpr_evaluation_code(code)
2609 code.put_error_if_neg(self.pos,
2610 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2611 self.base.py_result(),
2614 self.generate_subexpr_disposal_code(code)
2615 self.free_subexpr_temps(code)
2617 def generate_slice_guard_code(self, code, target_size):
2618 if not self.base.type.is_array:
2620 slice_size = self.base.type.size
2623 stop = self.stop.result()
2627 slice_size = self.base.type.size + stop
2634 start = self.start.result()
2638 start = self.base.type.size + start
2646 error(self.pos, "Assignment to empty slice.")
2647 elif start is None and stop is None:
2648 # we know the exact slice length
2649 if target_size != slice_size:
2650 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2651 slice_size, target_size))
2652 elif start is not None:
2655 check = "(%s)-(%s)" % (stop, start)
2656 else: # stop is not None:
2659 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2660 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));' % (
2661 target_size, check))
2662 code.putln(code.error_goto(self.pos))
2665 def start_code(self):
2667 return self.start.result()
2671 def stop_code(self):
2673 return self.stop.result()
2674 elif self.base.type.is_array:
2675 return self.base.type.size
2677 return "PY_SSIZE_T_MAX"
2679 def calculate_result_code(self):
2680 # self.result() is not used, but this method must exist
2684 class SliceNode(ExprNode):
2685 # start:stop:step in subscript list
2691 type = py_object_type
2694 def calculate_constant_result(self):
2695 self.constant_result = self.base.constant_result[
2696 self.start.constant_result : \
2697 self.stop.constant_result : \
2698 self.step.constant_result]
2700 def compile_time_value(self, denv):
2701 start = self.start.compile_time_value(denv)
2702 if self.stop is None:
2705 stop = self.stop.compile_time_value(denv)
2706 if self.step is None:
2709 step = self.step.compile_time_value(denv)
2711 return slice(start, stop, step)
2712 except Exception, e:
2713 self.compile_time_value_error(e)
2715 subexprs = ['start', 'stop', 'step']
2717 def analyse_types(self, env):
2718 self.start.analyse_types(env)
2719 self.stop.analyse_types(env)
2720 self.step.analyse_types(env)
2721 self.start = self.start.coerce_to_pyobject(env)
2722 self.stop = self.stop.coerce_to_pyobject(env)
2723 self.step = self.step.coerce_to_pyobject(env)
2725 gil_message = "Constructing Python slice object"
2727 def generate_result_code(self, code):
2729 "%s = PySlice_New(%s, %s, %s); %s" % (
2731 self.start.py_result(),
2732 self.stop.py_result(),
2733 self.step.py_result(),
2734 code.error_goto_if_null(self.result(), self.pos)))
2735 code.put_gotref(self.py_result())
2738 class CallNode(ExprNode):
2740 # allow overriding the default 'may_be_none' behaviour
2741 may_return_none = None
2743 def may_be_none(self):
2744 if self.may_return_none is not None:
2745 return self.may_return_none
2746 return ExprNode.may_be_none(self)
2748 def analyse_as_type_constructor(self, env):
2749 type = self.function.analyse_as_type(env)
2750 if type and type.is_struct_or_union:
2751 args, kwds = self.explicit_args_kwds()
2753 for arg, member in zip(args, type.scope.var_entries):
2754 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2756 items += kwds.key_value_pairs
2757 self.key_value_pairs = items
2758 self.__class__ = DictNode
2759 self.analyse_types(env)
2760 self.coerce_to(type, env)
2762 elif type and type.is_cpp_class:
2763 for arg in self.args:
2764 arg.analyse_types(env)
2765 constructor = type.scope.lookup("<init>")
2766 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2767 self.function.entry = constructor
2768 self.function.set_cname(type.declaration_code(""))
2769 self.analyse_c_function_call(env)
2772 def is_lvalue(self):
2773 return self.type.is_reference
2775 def nogil_check(self, env):
2776 func_type = self.function_type()
2777 if func_type.is_pyobject:
2779 elif not getattr(func_type, 'nogil', False):
2782 gil_message = "Calling gil-requiring function"
2785 class SimpleCallNode(CallNode):
2786 # Function call without keyword, * or ** args.
2790 # arg_tuple ExprNode or None used internally
2791 # self ExprNode or None used internally
2792 # coerced_self ExprNode or None used internally
2793 # wrapper_call bool used internally
2794 # has_optional_args bool used internally
2795 # nogil bool used internally
2797 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2802 wrapper_call = False
2803 has_optional_args = False
2807 def compile_time_value(self, denv):
2808 function = self.function.compile_time_value(denv)
2809 args = [arg.compile_time_value(denv) for arg in self.args]
2811 return function(*args)
2812 except Exception, e:
2813 self.compile_time_value_error(e)
2815 def type_dependencies(self, env):
2816 # TODO: Update when Danilo's C++ code merged in to handle the
2817 # the case of function overloading.
2818 return self.function.type_dependencies(env)
2820 def infer_type(self, env):
2821 function = self.function
2822 func_type = function.infer_type(env)
2823 if isinstance(self.function, NewExprNode):
2824 return PyrexTypes.CPtrType(self.function.class_type)
2825 if func_type.is_ptr:
2826 func_type = func_type.base_type
2827 if func_type.is_cfunction:
2828 return func_type.return_type
2829 elif func_type is type_type:
2830 if function.is_name and function.entry and function.entry.type:
2831 result_type = function.entry.type
2832 if result_type.is_extension_type:
2834 elif result_type.is_builtin_type:
2835 if function.entry.name == 'float':
2836 return PyrexTypes.c_double_type
2837 elif function.entry.name in Builtin.types_that_construct_their_instance:
2839 return py_object_type
2841 def analyse_as_type(self, env):
2842 attr = self.function.as_cython_attribute()
2843 if attr == 'pointer':
2844 if len(self.args) != 1:
2845 error(self.args.pos, "only one type allowed.")
2847 type = self.args[0].analyse_as_type(env)
2849 error(self.args[0].pos, "Unknown type")
2851 return PyrexTypes.CPtrType(type)
2853 def explicit_args_kwds(self):
2854 return self.args, None
2856 def analyse_types(self, env):
2857 if self.analyse_as_type_constructor(env):
2861 self.analysed = True
2862 function = self.function
2863 function.is_called = 1
2864 self.function.analyse_types(env)
2865 if function.is_attribute and function.entry and function.entry.is_cmethod:
2866 # Take ownership of the object from which the attribute
2867 # was obtained, because we need to pass it as 'self'.
2868 self.self = function.obj
2869 function.obj = CloneNode(self.self)
2870 func_type = self.function_type()
2871 if func_type.is_pyobject:
2872 self.arg_tuple = TupleNode(self.pos, args = self.args)
2873 self.arg_tuple.analyse_types(env)
2875 if func_type is Builtin.type_type and function.is_name and \
2876 function.entry and \
2877 function.entry.is_builtin and \
2878 function.entry.name in Builtin.types_that_construct_their_instance:
2879 # calling a builtin type that returns a specific object type
2880 if function.entry.name == 'float':
2881 # the following will come true later on in a transform
2882 self.type = PyrexTypes.c_double_type
2883 self.result_ctype = PyrexTypes.c_double_type
2885 self.type = Builtin.builtin_types[function.entry.name]
2886 self.result_ctype = py_object_type
2887 self.may_return_none = False
2888 elif function.is_name and function.type_entry:
2889 # We are calling an extension type constructor. As
2890 # long as we do not support __new__(), the result type
2892 self.type = function.type_entry.type
2893 self.result_ctype = py_object_type
2894 self.may_return_none = False
2896 self.type = py_object_type
2899 for arg in self.args:
2900 arg.analyse_types(env)
2901 if self.self and func_type.args:
2902 # Coerce 'self' to the type expected by the method.
2903 self_arg = func_type.args[0]
2904 if self_arg.not_none: # C methods must do the None test for self at *call* time
2905 self.self = self.self.as_none_safe_node(
2906 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2907 'PyExc_AttributeError')
2908 expected_type = self_arg.type
2909 self.coerced_self = CloneNode(self.self).coerce_to(
2911 # Insert coerced 'self' argument into argument list.
2912 self.args.insert(0, self.coerced_self)
2913 self.analyse_c_function_call(env)
2915 def function_type(self):
2916 # Return the type of the function being called, coercing a function
2917 # pointer to a function if necessary.
2918 func_type = self.function.type
2919 if func_type.is_ptr:
2920 func_type = func_type.base_type
2923 def analyse_c_function_call(self, env):
2924 if self.function.type is error_type:
2925 self.type = error_type
2927 if self.function.type.is_cpp_class:
2928 overloaded_entry = self.function.type.scope.lookup("operator()")
2929 if overloaded_entry is None:
2930 self.type = PyrexTypes.error_type
2931 self.result_code = "<error>"
2933 elif hasattr(self.function, 'entry'):
2934 overloaded_entry = self.function.entry
2936 overloaded_entry = None
2937 if overloaded_entry:
2938 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2940 self.type = PyrexTypes.error_type
2941 self.result_code = "<error>"
2943 self.function.entry = entry
2944 self.function.type = entry.type
2945 func_type = self.function_type()
2947 func_type = self.function_type()
2948 if not func_type.is_cfunction:
2949 error(self.pos, "Calling non-function type '%s'" % func_type)
2950 self.type = PyrexTypes.error_type
2951 self.result_code = "<error>"
2954 max_nargs = len(func_type.args)
2955 expected_nargs = max_nargs - func_type.optional_arg_count
2956 actual_nargs = len(self.args)
2957 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2958 self.has_optional_args = 1
2961 for i in range(min(max_nargs, actual_nargs)):
2962 formal_type = func_type.args[i].type
2963 arg = self.args[i].coerce_to(formal_type, env)
2964 if arg.type.is_pyobject and not env.nogil and (arg.is_attribute or not arg.is_simple):
2965 # we do not own the argument's reference, but we must
2966 # make sure it cannot be collected before we return
2967 # from the function, so we create an owned temp
2969 arg = arg.coerce_to_temp(env)
2971 for i in range(max_nargs, actual_nargs):
2973 if arg.type.is_pyobject:
2974 arg_ctype = arg.type.default_coerced_ctype()
2975 if arg_ctype is None:
2976 error(self.args[i].pos,
2977 "Python object cannot be passed as a varargs parameter")
2979 self.args[i] = arg.coerce_to(arg_ctype, env)
2980 # Calc result type and code fragment
2981 if isinstance(self.function, NewExprNode):
2982 self.type = PyrexTypes.CPtrType(self.function.class_type)
2984 self.type = func_type.return_type
2985 if self.type.is_pyobject:
2986 self.result_ctype = py_object_type
2988 elif func_type.exception_value is not None \
2989 or func_type.exception_check:
2991 # Called in 'nogil' context?
2992 self.nogil = env.nogil
2994 func_type.exception_check and
2995 func_type.exception_check != '+'):
2996 env.use_utility_code(pyerr_occurred_withgil_utility_code)
2997 # C++ exception handler
2998 if func_type.exception_check == '+':
2999 if func_type.exception_value is None:
3000 env.use_utility_code(cpp_exception_utility_code)
3002 def calculate_result_code(self):
3003 return self.c_call_code()
3005 def c_call_code(self):
3006 func_type = self.function_type()
3007 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
3009 formal_args = func_type.args
3011 args = list(zip(formal_args, self.args))
3012 max_nargs = len(func_type.args)
3013 expected_nargs = max_nargs - func_type.optional_arg_count
3014 actual_nargs = len(self.args)
3015 for formal_arg, actual_arg in args[:expected_nargs]:
3016 arg_code = actual_arg.result_as(formal_arg.type)
3017 arg_list_code.append(arg_code)
3019 if func_type.is_overridable:
3020 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3022 if func_type.optional_arg_count:
3023 if expected_nargs == actual_nargs:
3024 optional_args = 'NULL'
3026 optional_args = "&%s" % self.opt_arg_struct
3027 arg_list_code.append(optional_args)
3029 for actual_arg in self.args[len(formal_args):]:
3030 arg_list_code.append(actual_arg.result())
3031 result = "%s(%s)" % (self.function.result(),
3032 ', '.join(arg_list_code))
3035 def generate_result_code(self, code):
3036 func_type = self.function_type()
3037 if func_type.is_pyobject:
3038 arg_code = self.arg_tuple.py_result()
3040 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3042 self.function.py_result(),
3044 code.error_goto_if_null(self.result(), self.pos)))
3045 code.put_gotref(self.py_result())
3046 elif func_type.is_cfunction:
3047 if self.has_optional_args:
3048 actual_nargs = len(self.args)
3049 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3050 self.opt_arg_struct = code.funcstate.allocate_temp(
3051 func_type.op_arg_struct.base_type, manage_ref=True)
3052 code.putln("%s.%s = %s;" % (
3053 self.opt_arg_struct,
3054 Naming.pyrex_prefix + "n",
3055 len(self.args) - expected_nargs))
3056 args = list(zip(func_type.args, self.args))
3057 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3058 code.putln("%s.%s = %s;" % (
3059 self.opt_arg_struct,
3060 func_type.opt_arg_cname(formal_arg.name),
3061 actual_arg.result_as(formal_arg.type)))
3063 if self.type.is_pyobject and self.is_temp:
3064 exc_checks.append("!%s" % self.result())
3066 exc_val = func_type.exception_value
3067 exc_check = func_type.exception_check
3068 if exc_val is not None:
3069 exc_checks.append("%s == %s" % (self.result(), exc_val))
3072 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3074 exc_checks.append("PyErr_Occurred()")
3075 if self.is_temp or exc_checks:
3076 rhs = self.c_call_code()
3078 lhs = "%s = " % self.result()
3079 if self.is_temp and self.type.is_pyobject:
3080 #return_type = self.type # func_type.return_type
3081 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3082 # "from", return_type, "to pyobject" ###
3083 rhs = typecast(py_object_type, self.type, rhs)
3086 if func_type.exception_check == '+':
3087 if func_type.exception_value is None:
3088 raise_py_exception = "__Pyx_CppExn2PyErr()"
3089 elif func_type.exception_value.type.is_pyobject:
3090 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3091 func_type.exception_value.entry.cname,
3092 func_type.exception_value.entry.cname)
3094 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3096 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3098 "try {%s%s;} catch(...) {%s; %s}" % (
3102 code.error_goto(self.pos)))
3105 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3108 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3109 if self.type.is_pyobject and self.result():
3110 code.put_gotref(self.py_result())
3111 if self.has_optional_args:
3112 code.funcstate.release_temp(self.opt_arg_struct)
3115 class PythonCapiFunctionNode(ExprNode):
3117 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3121 self.type = func_type
3122 self.utility_code = utility_code
3124 def analyse_types(self, env):
3127 def generate_result_code(self, code):
3128 if self.utility_code:
3129 code.globalstate.use_utility_code(self.utility_code)
3131 def calculate_result_code(self):
3134 class PythonCapiCallNode(SimpleCallNode):
3135 # Python C-API Function call (only created in transforms)
3137 # By default, we assume that the call never returns None, as this
3138 # is true for most C-API functions in CPython. If this does not
3139 # apply to a call, set the following to True (or None to inherit
3140 # the default behaviour).
3141 may_return_none = False
3143 def __init__(self, pos, function_name, func_type,
3144 utility_code = None, py_name=None, **kwargs):
3145 self.type = func_type.return_type
3146 self.result_ctype = self.type
3147 self.function = PythonCapiFunctionNode(
3148 pos, py_name, function_name, func_type,
3149 utility_code = utility_code)
3150 # call this last so that we can override the constructed
3151 # attributes above with explicit keyword arguments if required
3152 SimpleCallNode.__init__(self, pos, **kwargs)
3155 class GeneralCallNode(CallNode):
3156 # General Python function call, including keyword,
3157 # * and ** arguments.
3160 # positional_args ExprNode Tuple of positional arguments
3161 # keyword_args ExprNode or None Dict of keyword arguments
3162 # starstar_arg ExprNode or None Dict of extra keyword args
3164 type = py_object_type
3166 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3168 nogil_check = Node.gil_error
3170 def compile_time_value(self, denv):
3171 function = self.function.compile_time_value(denv)
3172 positional_args = self.positional_args.compile_time_value(denv)
3173 keyword_args = self.keyword_args.compile_time_value(denv)
3174 starstar_arg = self.starstar_arg.compile_time_value(denv)
3176 keyword_args.update(starstar_arg)
3177 return function(*positional_args, **keyword_args)
3178 except Exception, e:
3179 self.compile_time_value_error(e)
3181 def explicit_args_kwds(self):
3182 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3183 raise CompileError(self.pos,
3184 'Compile-time keyword arguments must be explicit.')
3185 return self.positional_args.args, self.keyword_args
3187 def analyse_types(self, env):
3188 if self.analyse_as_type_constructor(env):
3190 self.function.analyse_types(env)
3191 self.positional_args.analyse_types(env)
3192 if self.keyword_args:
3193 self.keyword_args.analyse_types(env)
3194 if self.starstar_arg:
3195 self.starstar_arg.analyse_types(env)
3196 if not self.function.type.is_pyobject:
3197 if self.function.type.is_error:
3198 self.type = error_type
3200 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3201 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3203 self.function = self.function.coerce_to_pyobject(env)
3204 self.positional_args = \
3205 self.positional_args.coerce_to_pyobject(env)
3206 if self.starstar_arg:
3207 self.starstar_arg = \
3208 self.starstar_arg.coerce_to_pyobject(env)
3209 function = self.function
3210 if function.is_name and function.type_entry:
3211 # We are calling an extension type constructor. As long
3212 # as we do not support __new__(), the result type is clear
3213 self.type = function.type_entry.type
3214 self.result_ctype = py_object_type
3215 self.may_return_none = False
3217 self.type = py_object_type
3220 def generate_result_code(self, code):
3221 if self.type.is_error: return
3222 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3223 if self.keyword_args and self.starstar_arg:
3224 code.put_error_if_neg(self.pos,
3225 "PyDict_Update(%s, %s)" % (
3226 self.keyword_args.py_result(),
3227 self.starstar_arg.py_result()))
3228 keyword_code = self.keyword_args.py_result()
3229 elif self.keyword_args:
3230 keyword_code = self.keyword_args.py_result()
3231 elif self.starstar_arg:
3232 keyword_code = self.starstar_arg.py_result()
3233 if self.starstar_arg.type is not Builtin.dict_type:
3234 # CPython supports calling functions with non-dicts, so do we
3235 code.globalstate.use_utility_code(kwargs_call_utility_code)
3236 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3239 if not keyword_code:
3240 call_code = "PyObject_Call(%s, %s, NULL)" % (
3241 self.function.py_result(),
3242 self.positional_args.py_result())
3244 call_code = "%s(%s, %s, %s)" % (
3245 kwargs_call_function,
3246 self.function.py_result(),
3247 self.positional_args.py_result(),
3253 code.error_goto_if_null(self.result(), self.pos)))
3254 code.put_gotref(self.py_result())
3257 class AsTupleNode(ExprNode):
3258 # Convert argument to tuple. Used for normalising
3259 # the * argument of a function call.
3265 def calculate_constant_result(self):
3266 self.constant_result = tuple(self.base.constant_result)
3268 def compile_time_value(self, denv):
3269 arg = self.arg.compile_time_value(denv)
3272 except Exception, e:
3273 self.compile_time_value_error(e)
3275 def analyse_types(self, env):
3276 self.arg.analyse_types(env)
3277 self.arg = self.arg.coerce_to_pyobject(env)
3278 self.type = tuple_type
3281 def may_be_none(self):
3284 nogil_check = Node.gil_error
3285 gil_message = "Constructing Python tuple"
3287 def generate_result_code(self, code):
3289 "%s = PySequence_Tuple(%s); %s" % (
3291 self.arg.py_result(),
3292 code.error_goto_if_null(self.result(), self.pos)))
3293 code.put_gotref(self.py_result())
3296 class AttributeNode(ExprNode):
3301 # needs_none_check boolean Used if obj is an extension type.
3302 # If set to True, it is known that the type is not None.
3306 # is_py_attr boolean Is a Python getattr operation
3307 # member string C name of struct member
3308 # is_called boolean Function call is being done on result
3309 # entry Entry Symbol table entry of attribute
3314 type = PyrexTypes.error_type
3317 needs_none_check = True
3319 def as_cython_attribute(self):
3320 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3321 return self.attribute
3322 cy = self.obj.as_cython_attribute()
3324 return "%s.%s" % (cy, self.attribute)
3326 def coerce_to(self, dst_type, env):
3327 # If coercing to a generic pyobject and this is a cpdef function
3328 # we can create the corresponding attribute
3329 if dst_type is py_object_type:
3331 if entry and entry.is_cfunction and entry.as_variable:
3332 # must be a cpdef function
3334 self.entry = entry.as_variable
3335 self.analyse_as_python_attribute(env)
3337 return ExprNode.coerce_to(self, dst_type, env)
3339 def calculate_constant_result(self):
3340 attr = self.attribute
3341 if attr.startswith("__") and attr.endswith("__"):
3343 self.constant_result = getattr(self.obj.constant_result, attr)
3345 def compile_time_value(self, denv):
3346 attr = self.attribute
3347 if attr.startswith("__") and attr.endswith("__"):
3349 "Invalid attribute name '%s' in compile-time expression" % attr)
3351 obj = self.obj.compile_time_value(denv)
3353 return getattr(obj, attr)
3354 except Exception, e:
3355 self.compile_time_value_error(e)
3357 def type_dependencies(self, env):
3358 return self.obj.type_dependencies(env)
3360 def infer_type(self, env):
3361 if self.analyse_as_cimported_attribute(env, 0):
3362 return self.entry.type
3363 elif self.analyse_as_unbound_cmethod(env):
3364 return self.entry.type
3366 obj_type = self.obj.infer_type(env)
3367 self.analyse_attribute(env, obj_type = obj_type)
3368 if obj_type.is_builtin_type and self.type.is_cfunction:
3369 # special case: C-API replacements for C methods of
3370 # builtin types cannot be inferred as C functions as
3371 # that would prevent their use as bound methods
3372 self.type = py_object_type
3373 return py_object_type
3376 def analyse_target_declaration(self, env):
3379 def analyse_target_types(self, env):
3380 self.analyse_types(env, target = 1)
3382 def analyse_types(self, env, target = 0):
3383 if self.analyse_as_cimported_attribute(env, target):
3385 if not target and self.analyse_as_unbound_cmethod(env):
3387 self.analyse_as_ordinary_attribute(env, target)
3389 def analyse_as_cimported_attribute(self, env, target):
3390 # Try to interpret this as a reference to an imported
3391 # C const, type, var or function. If successful, mutates
3392 # this node into a NameNode and returns 1, otherwise
3394 module_scope = self.obj.analyse_as_module(env)
3396 entry = module_scope.lookup_here(self.attribute)
3398 entry.is_cglobal or entry.is_cfunction
3399 or entry.is_type or entry.is_const):
3400 self.mutate_into_name_node(env, entry, target)
3404 def analyse_as_unbound_cmethod(self, env):
3405 # Try to interpret this as a reference to an unbound
3406 # C method of an extension type. If successful, mutates
3407 # this node into a NameNode and returns 1, otherwise
3409 type = self.obj.analyse_as_extension_type(env)
3411 entry = type.scope.lookup_here(self.attribute)
3412 if entry and entry.is_cmethod:
3413 # Create a temporary entry describing the C method
3414 # as an ordinary function.
3415 ubcm_entry = Symtab.Entry(entry.name,
3416 "%s->%s" % (type.vtabptr_cname, entry.cname),
3418 ubcm_entry.is_cfunction = 1
3419 ubcm_entry.func_cname = entry.func_cname
3420 ubcm_entry.is_unbound_cmethod = 1
3421 self.mutate_into_name_node(env, ubcm_entry, None)
3425 def analyse_as_type(self, env):
3426 module_scope = self.obj.analyse_as_module(env)
3428 return module_scope.lookup_type(self.attribute)
3429 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3430 base_type = self.obj.analyse_as_type(env)
3431 if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
3432 return base_type.scope.lookup_type(self.attribute)
3435 def analyse_as_extension_type(self, env):
3436 # Try to interpret this as a reference to an extension type
3437 # in a cimported module. Returns the extension type, or None.
3438 module_scope = self.obj.analyse_as_module(env)
3440 entry = module_scope.lookup_here(self.attribute)
3441 if entry and entry.is_type and entry.type.is_extension_type:
3445 def analyse_as_module(self, env):
3446 # Try to interpret this as a reference to a cimported module
3447 # in another cimported module. Returns the module scope, or None.
3448 module_scope = self.obj.analyse_as_module(env)
3450 entry = module_scope.lookup_here(self.attribute)
3451 if entry and entry.as_module:
3452 return entry.as_module
3455 def mutate_into_name_node(self, env, entry, target):
3456 # Mutate this node into a NameNode and complete the
3457 # analyse_types phase.
3458 self.__class__ = NameNode
3459 self.name = self.attribute
3464 NameNode.analyse_target_types(self, env)
3466 NameNode.analyse_rvalue_entry(self, env)
3468 def analyse_as_ordinary_attribute(self, env, target):
3469 self.obj.analyse_types(env)
3470 self.analyse_attribute(env)
3471 if self.entry and self.entry.is_cmethod and not self.is_called:
3472 # error(self.pos, "C method can only be called")
3474 ## Reference to C array turns into pointer to first element.
3475 #while self.type.is_array:
3476 # self.type = self.type.element_ptr_type()
3480 self.result_ctype = py_object_type
3481 elif target and self.obj.type.is_builtin_type:
3482 error(self.pos, "Assignment to an immutable object field")
3484 def analyse_attribute(self, env, obj_type = None):
3485 # Look up attribute and set self.type and self.member.
3487 self.member = self.attribute
3488 if obj_type is None:
3489 if self.obj.type.is_string:
3490 self.obj = self.obj.coerce_to_pyobject(env)
3491 obj_type = self.obj.type
3493 if obj_type.is_string:
3494 obj_type = py_object_type
3495 if obj_type.is_ptr or obj_type.is_array:
3496 obj_type = obj_type.base_type
3498 elif obj_type.is_extension_type or obj_type.is_builtin_type:
3502 if obj_type.has_attributes:
3504 if obj_type.attributes_known():
3505 entry = obj_type.scope.lookup_here(self.attribute)
3506 if entry and entry.is_member:
3510 "Cannot select attribute of incomplete type '%s'"
3512 self.type = PyrexTypes.error_type
3516 if obj_type.is_extension_type and entry.name == "__weakref__":
3517 error(self.pos, "Illegal use of special attribute __weakref__")
3518 # methods need the normal attribute lookup
3519 # because they do not have struct entries
3520 if entry.is_variable or entry.is_cmethod:
3521 self.type = entry.type
3522 self.member = entry.cname
3525 # If it's not a variable or C method, it must be a Python
3526 # method of an extension type, so we treat it like a Python
3529 # If we get here, the base object is not a struct/union/extension
3530 # type, or it is an extension type and the attribute is either not
3531 # declared or is declared as a Python method. Treat it as a Python
3532 # attribute reference.
3533 self.analyse_as_python_attribute(env, obj_type)
3535 def analyse_as_python_attribute(self, env, obj_type = None):
3536 if obj_type is None:
3537 obj_type = self.obj.type
3538 self.member = self.attribute
3539 self.type = py_object_type
3541 if not obj_type.is_pyobject and not obj_type.is_error:
3542 if obj_type.can_coerce_to_pyobject(env):
3543 self.obj = self.obj.coerce_to_pyobject(env)
3546 "Object of type '%s' has no attribute '%s'" %
3547 (obj_type, self.attribute))
3549 def nogil_check(self, env):
3553 gil_message = "Accessing Python attribute"
3555 def is_simple(self):
3557 return self.result_in_temp() or self.obj.is_simple()
3559 return NameNode.is_simple(self)
3561 def is_lvalue(self):
3565 return NameNode.is_lvalue(self)
3567 def is_ephemeral(self):
3569 return self.obj.is_ephemeral()
3571 return NameNode.is_ephemeral(self)
3573 def calculate_result_code(self):
3574 #print "AttributeNode.calculate_result_code:", self.member ###
3575 #print "...obj node =", self.obj, "code", self.obj.result() ###
3576 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3578 obj_code = obj.result_as(obj.type)
3579 #print "...obj_code =", obj_code ###
3580 if self.entry and self.entry.is_cmethod:
3581 if obj.type.is_extension_type:
3582 return "((struct %s *)%s%s%s)->%s" % (
3583 obj.type.vtabstruct_cname, obj_code, self.op,
3584 obj.type.vtabslot_cname, self.member)
3587 elif obj.type.is_complex:
3588 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3590 if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
3591 # accessing a field of a builtin type, need to cast better than result_as() does
3592 obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
3593 return "%s%s%s" % (obj_code, self.op, self.member)
3595 def generate_result_code(self, code):
3596 interned_attr_cname = code.intern_identifier(self.attribute)
3599 '%s = PyObject_GetAttr(%s, %s); %s' % (
3601 self.obj.py_result(),
3602 interned_attr_cname,
3603 code.error_goto_if_null(self.result(), self.pos)))
3604 code.put_gotref(self.py_result())
3606 # result_code contains what is needed, but we may need to insert
3607 # a check and raise an exception
3608 if (self.obj.type.is_extension_type
3609 and self.needs_none_check
3610 and code.globalstate.directives['nonecheck']):
3611 self.put_nonecheck(code)
3613 def generate_assignment_code(self, rhs, code):
3614 interned_attr_cname = code.intern_identifier(self.attribute)
3615 self.obj.generate_evaluation_code(code)
3617 code.put_error_if_neg(self.pos,
3618 'PyObject_SetAttr(%s, %s, %s)' % (
3619 self.obj.py_result(),
3620 interned_attr_cname,
3622 rhs.generate_disposal_code(code)
3623 rhs.free_temps(code)
3624 elif self.obj.type.is_complex:
3625 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3626 self.member.upper(),
3627 self.obj.result_as(self.obj.type),
3628 rhs.result_as(self.ctype())))
3630 if (self.obj.type.is_extension_type
3631 and self.needs_none_check
3632 and code.globalstate.directives['nonecheck']):
3633 self.put_nonecheck(code)
3635 select_code = self.result()
3636 if self.type.is_pyobject and self.use_managed_ref:
3637 rhs.make_owned_reference(code)
3638 code.put_giveref(rhs.py_result())
3639 code.put_gotref(select_code)
3640 code.put_decref(select_code, self.ctype())
3644 rhs.result_as(self.ctype())))
3646 rhs.generate_post_assignment_code(code)
3647 rhs.free_temps(code)
3648 self.obj.generate_disposal_code(code)
3649 self.obj.free_temps(code)
3651 def generate_deletion_code(self, code):
3652 interned_attr_cname = code.intern_identifier(self.attribute)
3653 self.obj.generate_evaluation_code(code)
3654 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3655 and u'__del__' in self.entry.scope.entries):
3656 code.put_error_if_neg(self.pos,
3657 'PyObject_DelAttr(%s, %s)' % (
3658 self.obj.py_result(),
3659 interned_attr_cname))
3661 error(self.pos, "Cannot delete C attribute of extension type")
3662 self.obj.generate_disposal_code(code)
3663 self.obj.free_temps(code)
3665 def annotate(self, code):
3667 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3669 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3671 def put_nonecheck(self, code):
3672 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3673 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3674 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3675 code.putln(code.error_goto(self.pos))
3679 #-------------------------------------------------------------------
3683 #-------------------------------------------------------------------
3685 class StarredTargetNode(ExprNode):
3686 # A starred expression like "*a"
3688 # This is only allowed in sequence assignment targets such as
3690 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3692 # and will be removed during type analysis (or generate an error
3693 # if it's found at unexpected places).
3697 subexprs = ['target']
3699 type = py_object_type
3702 def __init__(self, pos, target):
3704 self.target = target
3706 def analyse_declarations(self, env):
3707 error(self.pos, "can use starred expression only as assignment target")
3708 self.target.analyse_declarations(env)
3710 def analyse_types(self, env):
3711 error(self.pos, "can use starred expression only as assignment target")
3712 self.target.analyse_types(env)
3713 self.type = self.target.type
3715 def analyse_target_declaration(self, env):
3716 self.target.analyse_target_declaration(env)
3718 def analyse_target_types(self, env):
3719 self.target.analyse_target_types(env)
3720 self.type = self.target.type
3722 def calculate_result_code(self):
3725 def generate_result_code(self, code):
3729 class SequenceNode(ExprNode):
3730 # Base class for list and tuple constructor nodes.
3731 # Contains common code for performing sequence unpacking.
3735 # unpacked_items [ExprNode] or None
3736 # coerced_unpacked_items [ExprNode] or None
3740 is_sequence_constructor = 1
3741 unpacked_items = None
3743 def compile_time_value_list(self, denv):
3744 return [arg.compile_time_value(denv) for arg in self.args]
3746 def replace_starred_target_node(self):
3747 # replace a starred node in the targets by the contained expression
3748 self.starred_assignment = False
3750 for arg in self.args:
3752 if self.starred_assignment:
3753 error(arg.pos, "more than 1 starred expression in assignment")
3754 self.starred_assignment = True
3756 arg.is_starred = True
3760 def analyse_target_declaration(self, env):
3761 self.replace_starred_target_node()
3762 for arg in self.args:
3763 arg.analyse_target_declaration(env)
3765 def analyse_types(self, env, skip_children=False):
3766 for i in range(len(self.args)):
3768 if not skip_children: arg.analyse_types(env)
3769 self.args[i] = arg.coerce_to_pyobject(env)
3771 # not setting self.type here, subtypes do this
3773 def may_be_none(self):
3776 def analyse_target_types(self, env):
3777 self.iterator = PyTempNode(self.pos, env)
3778 self.unpacked_items = []
3779 self.coerced_unpacked_items = []
3780 for arg in self.args:
3781 arg.analyse_target_types(env)
3783 if not arg.type.assignable_from(Builtin.list_type):
3785 "starred target must have Python object (list) type")
3786 if arg.type is py_object_type:
3787 arg.type = Builtin.list_type
3788 unpacked_item = PyTempNode(self.pos, env)
3789 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3790 self.unpacked_items.append(unpacked_item)
3791 self.coerced_unpacked_items.append(coerced_unpacked_item)
3792 self.type = py_object_type
3794 def generate_result_code(self, code):
3795 self.generate_operation_code(code)
3797 def generate_assignment_code(self, rhs, code):
3798 if self.starred_assignment:
3799 self.generate_starred_assignment_code(rhs, code)
3801 self.generate_parallel_assignment_code(rhs, code)
3803 for item in self.unpacked_items:
3805 rhs.free_temps(code)
3807 def generate_parallel_assignment_code(self, rhs, code):
3808 # Need to work around the fact that generate_evaluation_code
3809 # allocates the temps in a rather hacky way -- the assignment
3810 # is evaluated twice, within each if-block.
3812 if rhs.type is tuple_type:
3813 tuple_check = "likely(%s != Py_None)"
3815 tuple_check = "PyTuple_CheckExact(%s)"
3817 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3818 tuple_check % rhs.py_result(),
3821 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3822 for item in self.unpacked_items:
3824 for i in range(len(self.args)):
3825 item = self.unpacked_items[i]
3827 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3830 code.put_incref(item.result(), item.ctype())
3831 value_node = self.coerced_unpacked_items[i]
3832 value_node.generate_evaluation_code(code)
3833 rhs.generate_disposal_code(code)
3835 for i in range(len(self.args)):
3836 self.args[i].generate_assignment_code(
3837 self.coerced_unpacked_items[i], code)
3839 code.putln("} else {")
3841 if rhs.type is tuple_type:
3842 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3843 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3844 rhs.py_result(), len(self.args)))
3845 code.putln(code.error_goto(self.pos))
3847 code.globalstate.use_utility_code(unpacking_utility_code)
3849 self.iterator.allocate(code)
3851 "%s = PyObject_GetIter(%s); %s" % (
3852 self.iterator.result(),
3854 code.error_goto_if_null(self.iterator.result(), self.pos)))
3855 code.put_gotref(self.iterator.py_result())
3856 rhs.generate_disposal_code(code)
3857 for i in range(len(self.args)):
3858 item = self.unpacked_items[i]
3859 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3860 self.iterator.py_result(), i)
3864 typecast(item.ctype(), py_object_type, unpack_code),
3865 code.error_goto_if_null(item.result(), self.pos)))
3866 code.put_gotref(item.py_result())
3867 value_node = self.coerced_unpacked_items[i]
3868 value_node.generate_evaluation_code(code)
3869 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3870 self.iterator.py_result(),
3872 if debug_disposal_code:
3873 print("UnpackNode.generate_assignment_code:")
3874 print("...generating disposal code for %s" % self.iterator)
3875 self.iterator.generate_disposal_code(code)
3876 self.iterator.free_temps(code)
3877 self.iterator.release(code)
3879 for i in range(len(self.args)):
3880 self.args[i].generate_assignment_code(
3881 self.coerced_unpacked_items[i], code)
3885 def generate_starred_assignment_code(self, rhs, code):
3886 code.globalstate.use_utility_code(unpacking_utility_code)
3888 for i, arg in enumerate(self.args):
3890 starred_target = self.unpacked_items[i]
3891 fixed_args_left = self.args[:i]
3892 fixed_args_right = self.args[i+1:]
3895 self.iterator.allocate(code)
3897 "%s = PyObject_GetIter(%s); %s" % (
3898 self.iterator.result(),
3900 code.error_goto_if_null(self.iterator.result(), self.pos)))
3901 code.put_gotref(self.iterator.py_result())
3902 rhs.generate_disposal_code(code)
3904 for item in self.unpacked_items:
3906 for i in range(len(fixed_args_left)):
3907 item = self.unpacked_items[i]
3908 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3909 self.iterator.py_result(), i)
3913 typecast(item.ctype(), py_object_type, unpack_code),
3914 code.error_goto_if_null(item.result(), self.pos)))
3915 code.put_gotref(item.py_result())
3916 value_node = self.coerced_unpacked_items[i]
3917 value_node.generate_evaluation_code(code)
3919 target_list = starred_target.result()
3920 code.putln("%s = PySequence_List(%s); %s" % (
3921 target_list, self.iterator.py_result(),
3922 code.error_goto_if_null(target_list, self.pos)))
3923 code.put_gotref(target_list)
3924 if fixed_args_right:
3925 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3926 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3927 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3928 (target_list, len(unpacked_right_args))))
3929 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3930 len(fixed_args_left), target_list,
3931 code.error_goto(self.pos)))
3933 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3934 self.coerced_unpacked_items[::-1])):
3936 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3938 target_list, target_list))
3939 # resize the list the hard way
3940 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3941 code.put_gotref(arg.py_result())
3942 coerced_arg.generate_evaluation_code(code)
3944 self.iterator.generate_disposal_code(code)
3945 self.iterator.free_temps(code)
3946 self.iterator.release(code)
3948 for i in range(len(self.args)):
3949 self.args[i].generate_assignment_code(
3950 self.coerced_unpacked_items[i], code)
3952 def annotate(self, code):
3953 for arg in self.args:
3955 if self.unpacked_items:
3956 for arg in self.unpacked_items:
3958 for arg in self.coerced_unpacked_items:
3962 class TupleNode(SequenceNode):
3963 # Tuple constructor.
3967 gil_message = "Constructing Python tuple"
3969 def analyse_types(self, env, skip_children=False):
3970 if len(self.args) == 0:
3974 SequenceNode.analyse_types(self, env, skip_children)
3975 for child in self.args:
3976 if not child.is_literal:
3982 def calculate_result_code(self):
3983 if len(self.args) > 0:
3984 return self.result_code
3986 return Naming.empty_tuple
3988 def calculate_constant_result(self):
3989 self.constant_result = tuple([
3990 arg.constant_result for arg in self.args])
3992 def compile_time_value(self, denv):
3993 values = self.compile_time_value_list(denv)
3995 return tuple(values)
3996 except Exception, e:
3997 self.compile_time_value_error(e)
3999 def generate_operation_code(self, code):
4000 if len(self.args) == 0:
4001 # result_code is Naming.empty_tuple
4004 # non-empty cached tuple => result is global constant,
4005 # creation code goes into separate code writer
4006 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
4007 code = code.get_cached_constants_writer()
4008 code.mark_pos(self.pos)
4011 "%s = PyTuple_New(%s); %s" % (
4014 code.error_goto_if_null(self.result(), self.pos)))
4015 code.put_gotref(self.py_result())
4016 for i in range(len(self.args)):
4018 if not arg.result_in_temp():
4019 code.put_incref(arg.result(), arg.ctype())
4021 "PyTuple_SET_ITEM(%s, %s, %s);" % (
4025 code.put_giveref(arg.py_result())
4027 code.put_giveref(self.py_result())
4029 def generate_subexpr_disposal_code(self, code):
4030 # We call generate_post_assignment_code here instead
4031 # of generate_disposal_code, because values were stored
4032 # in the tuple using a reference-stealing operation.
4033 for arg in self.args:
4034 arg.generate_post_assignment_code(code)
4035 # Should NOT call free_temps -- this is invoked by the default
4036 # generate_evaluation_code which will do that.
4039 class ListNode(SequenceNode):
4042 # obj_conversion_errors [PyrexError] used internally
4043 # orignial_args [ExprNode] used internally
4045 obj_conversion_errors = []
4048 gil_message = "Constructing Python list"
4050 def type_dependencies(self, env):
4053 def infer_type(self, env):
4054 # TOOD: Infer non-object list arrays.
4057 def analyse_expressions(self, env):
4058 SequenceNode.analyse_expressions(self, env)
4059 self.coerce_to_pyobject(env)
4061 def analyse_types(self, env):
4063 self.original_args = list(self.args)
4064 SequenceNode.analyse_types(self, env)
4065 self.obj_conversion_errors = held_errors()
4066 release_errors(ignore=True)
4068 def coerce_to(self, dst_type, env):
4069 if dst_type.is_pyobject:
4070 for err in self.obj_conversion_errors:
4072 self.obj_conversion_errors = []
4073 if not self.type.subtype_of(dst_type):
4074 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4075 elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
4076 base_type = dst_type.base_type
4077 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4078 for i in range(len(self.original_args)):
4080 if isinstance(arg, CoerceToPyTypeNode):
4082 self.args[i] = arg.coerce_to(base_type, env)
4083 elif dst_type.is_struct:
4084 if len(self.args) > len(dst_type.scope.var_entries):
4085 error(self.pos, "Too may members for '%s'" % dst_type)
4087 if len(self.args) < len(dst_type.scope.var_entries):
4088 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4089 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4090 if isinstance(arg, CoerceToPyTypeNode):
4092 self.args[i] = arg.coerce_to(member.type, env)
4093 self.type = dst_type
4095 self.type = error_type
4096 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4099 def release_temp(self, env):
4100 if self.type.is_array:
4101 # To be valid C++, we must allocate the memory on the stack
4102 # manually and be sure not to reuse it for something else.
4105 SequenceNode.release_temp(self, env)
4107 def calculate_constant_result(self):
4108 self.constant_result = [
4109 arg.constant_result for arg in self.args]
4111 def compile_time_value(self, denv):
4112 return self.compile_time_value_list(denv)
4114 def generate_operation_code(self, code):
4115 if self.type.is_pyobject:
4116 for err in self.obj_conversion_errors:
4118 code.putln("%s = PyList_New(%s); %s" %
4121 code.error_goto_if_null(self.result(), self.pos)))
4122 code.put_gotref(self.py_result())
4123 for i in range(len(self.args)):
4125 #if not arg.is_temp:
4126 if not arg.result_in_temp():
4127 code.put_incref(arg.result(), arg.ctype())
4128 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4132 code.put_giveref(arg.py_result())
4133 elif self.type.is_array:
4134 for i, arg in enumerate(self.args):
4135 code.putln("%s[%s] = %s;" % (
4139 elif self.type.is_struct:
4140 for arg, member in zip(self.args, self.type.scope.var_entries):
4141 code.putln("%s.%s = %s;" % (
4146 raise InternalError("List type never specified")
4148 def generate_subexpr_disposal_code(self, code):
4149 # We call generate_post_assignment_code here instead
4150 # of generate_disposal_code, because values were stored
4151 # in the list using a reference-stealing operation.
4152 for arg in self.args:
4153 arg.generate_post_assignment_code(code)
4154 # Should NOT call free_temps -- this is invoked by the default
4155 # generate_evaluation_code which will do that.
4158 class ScopedExprNode(ExprNode):
4159 # Abstract base class for ExprNodes that have their own local
4160 # scope, such as generator expressions.
4162 # expr_scope Scope the inner scope of the expression
4167 # does this node really have a local scope, e.g. does it leak loop
4168 # variables or not? non-leaking Py3 behaviour is default, except
4169 # for list comprehensions where the behaviour differs in Py2 and
4170 # Py3 (set in Parsing.py based on parser context)
4171 has_local_scope = True
4173 def init_scope(self, outer_scope, expr_scope=None):
4174 if expr_scope is not None:
4175 self.expr_scope = expr_scope
4176 elif self.has_local_scope:
4177 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4179 self.expr_scope = None
4181 def analyse_declarations(self, env):
4182 self.init_scope(env)
4184 def analyse_scoped_declarations(self, env):
4185 # this is called with the expr_scope as env
4188 def analyse_types(self, env):
4189 # no recursion here, the children will be analysed separately below
4192 def analyse_scoped_expressions(self, env):
4193 # this is called with the expr_scope as env
4196 def generate_evaluation_code(self, code):
4197 # set up local variables and free their references on exit
4198 generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
4199 if not self.has_local_scope or not self.expr_scope.var_entries:
4200 # no local variables => delegate, done
4201 generate_inner_evaluation_code(code)
4204 code.putln('{ /* enter inner scope */')
4206 for entry in self.expr_scope.var_entries:
4207 if not entry.in_closure:
4208 code.put_var_declaration(entry)
4209 if entry.type.is_pyobject and entry.used:
4210 py_entries.append(entry)
4212 # no local Python references => no cleanup required
4213 generate_inner_evaluation_code(code)
4214 code.putln('} /* exit inner scope */')
4216 for entry in py_entries:
4217 code.put_init_var_to_py_none(entry)
4219 # must free all local Python references at each exit point
4220 old_loop_labels = tuple(code.new_loop_labels())
4221 old_error_label = code.new_error_label()
4223 generate_inner_evaluation_code(code)
4225 # normal (non-error) exit
4226 for entry in py_entries:
4227 code.put_var_decref(entry)
4229 # error/loop body exit points
4230 exit_scope = code.new_label('exit_scope')
4231 code.put_goto(exit_scope)
4232 for label, old_label in ([(code.error_label, old_error_label)] +
4233 list(zip(code.get_loop_labels(), old_loop_labels))):
4234 if code.label_used(label):
4235 code.put_label(label)
4236 for entry in py_entries:
4237 code.put_var_decref(entry)
4238 code.put_goto(old_label)
4239 code.put_label(exit_scope)
4240 code.putln('} /* exit inner scope */')
4242 code.set_loop_labels(old_loop_labels)
4243 code.error_label = old_error_label
4246 class ComprehensionNode(ScopedExprNode):
4247 subexprs = ["target"]
4248 child_attrs = ["loop", "append"]
4250 def infer_type(self, env):
4251 return self.target.infer_type(env)
4253 def analyse_declarations(self, env):
4254 self.append.target = self # this is used in the PyList_Append of the inner loop
4255 self.init_scope(env)
4257 def analyse_scoped_declarations(self, env):
4258 self.loop.analyse_declarations(env)
4260 def analyse_types(self, env):
4261 self.target.analyse_expressions(env)
4262 self.type = self.target.type
4263 if not self.has_local_scope:
4264 self.loop.analyse_expressions(env)
4266 def analyse_scoped_expressions(self, env):
4267 if self.has_local_scope:
4268 self.loop.analyse_expressions(env)
4270 def may_be_none(self):
4273 def calculate_result_code(self):
4274 return self.target.result()
4276 def generate_result_code(self, code):
4277 self.generate_operation_code(code)
4279 def generate_operation_code(self, code):
4280 self.loop.generate_execution_code(code)
4282 def annotate(self, code):
4283 self.loop.annotate(code)
4286 class ComprehensionAppendNode(Node):
4287 # Need to be careful to avoid infinite recursion:
4288 # target must not be in child_attrs/subexprs
4290 child_attrs = ['expr']
4292 type = PyrexTypes.c_int_type
4294 def analyse_expressions(self, env):
4295 self.expr.analyse_expressions(env)
4296 if not self.expr.type.is_pyobject:
4297 self.expr = self.expr.coerce_to_pyobject(env)
4299 def generate_execution_code(self, code):
4300 if self.target.type is list_type:
4301 function = "PyList_Append"
4302 elif self.target.type is set_type:
4303 function = "PySet_Add"
4305 raise InternalError(
4306 "Invalid type for comprehension node: %s" % self.target.type)
4308 self.expr.generate_evaluation_code(code)
4309 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4311 self.target.result(),
4314 self.expr.generate_disposal_code(code)
4315 self.expr.free_temps(code)
4317 def generate_function_definitions(self, env, code):
4318 self.expr.generate_function_definitions(env, code)
4320 def annotate(self, code):
4321 self.expr.annotate(code)
4323 class DictComprehensionAppendNode(ComprehensionAppendNode):
4324 child_attrs = ['key_expr', 'value_expr']
4326 def analyse_expressions(self, env):
4327 self.key_expr.analyse_expressions(env)
4328 if not self.key_expr.type.is_pyobject:
4329 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4330 self.value_expr.analyse_expressions(env)
4331 if not self.value_expr.type.is_pyobject:
4332 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4334 def generate_execution_code(self, code):
4335 self.key_expr.generate_evaluation_code(code)
4336 self.value_expr.generate_evaluation_code(code)
4337 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4338 self.target.result(),
4339 self.key_expr.result(),
4340 self.value_expr.result()
4342 self.key_expr.generate_disposal_code(code)
4343 self.key_expr.free_temps(code)
4344 self.value_expr.generate_disposal_code(code)
4345 self.value_expr.free_temps(code)
4347 def generate_function_definitions(self, env, code):
4348 self.key_expr.generate_function_definitions(env, code)
4349 self.value_expr.generate_function_definitions(env, code)
4351 def annotate(self, code):
4352 self.key_expr.annotate(code)
4353 self.value_expr.annotate(code)
4356 class InlinedGeneratorExpressionNode(ScopedExprNode):
4357 # An inlined generator expression for which the result is
4358 # calculated inside of the loop. This will only be created by
4359 # transforms when replacing builtin calls on generator
4362 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4363 # result_node ResultRefNode the reference to the result value temp
4364 # orig_func String the name of the builtin function this node replaces
4366 child_attrs = ["loop"]
4367 loop_analysed = False
4368 type = py_object_type
4370 def analyse_scoped_declarations(self, env):
4371 self.loop.analyse_declarations(env)
4373 def analyse_types(self, env):
4374 if not self.has_local_scope:
4375 self.loop.analyse_expressions(env)
4378 def may_be_none(self):
4381 def annotate(self, code):
4382 self.loop.annotate(code)
4384 def infer_type(self, env):
4385 return self.result_node.infer_type(env)
4387 def analyse_types(self, env):
4388 if not self.has_local_scope:
4389 self.loop_analysed = True
4390 self.loop.analyse_expressions(env)
4391 self.type = self.result_node.type
4394 def analyse_scoped_expressions(self, env):
4395 self.loop_analysed = True
4396 if self.has_local_scope:
4397 self.loop.analyse_expressions(env)
4399 def coerce_to(self, dst_type, env):
4400 if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
4401 # We can optimise by dropping the aggregation variable and
4402 # the add operations into C. This can only be done safely
4403 # before analysing the loop body, after that, the result
4404 # reference type will have infected expressions and
4406 self.result_node.type = self.type = dst_type
4408 return super(InlinedGeneratorExpressionNode, self).coerce_to(dst_type, env)
4410 def generate_result_code(self, code):
4411 self.result_node.result_code = self.result()
4412 self.loop.generate_execution_code(code)
4415 class SetNode(ExprNode):
4422 gil_message = "Constructing Python set"
4424 def analyse_types(self, env):
4425 for i in range(len(self.args)):
4427 arg.analyse_types(env)
4428 self.args[i] = arg.coerce_to_pyobject(env)
4429 self.type = set_type
4432 def may_be_none(self):
4435 def calculate_constant_result(self):
4436 self.constant_result = set([
4437 arg.constant_result for arg in self.args])
4439 def compile_time_value(self, denv):
4440 values = [arg.compile_time_value(denv) for arg in self.args]
4443 except Exception, e:
4444 self.compile_time_value_error(e)
4446 def generate_evaluation_code(self, code):
4447 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4448 self.allocate_temp_result(code)
4450 "%s = PySet_New(0); %s" % (
4452 code.error_goto_if_null(self.result(), self.pos)))
4453 code.put_gotref(self.py_result())
4454 for arg in self.args:
4455 arg.generate_evaluation_code(code)
4457 code.error_goto_if_neg(
4458 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4460 arg.generate_disposal_code(code)
4461 arg.free_temps(code)
4464 class DictNode(ExprNode):
4465 # Dictionary constructor.
4467 # key_value_pairs [DictItemNode]
4469 # obj_conversion_errors [PyrexError] used internally
4471 subexprs = ['key_value_pairs']
4475 obj_conversion_errors = []
4477 def calculate_constant_result(self):
4478 self.constant_result = dict([
4479 item.constant_result for item in self.key_value_pairs])
4481 def compile_time_value(self, denv):
4482 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4483 for item in self.key_value_pairs]
4486 except Exception, e:
4487 self.compile_time_value_error(e)
4489 def type_dependencies(self, env):
4492 def infer_type(self, env):
4493 # TOOD: Infer struct constructors.
4496 def analyse_types(self, env):
4498 for item in self.key_value_pairs:
4499 item.analyse_types(env)
4500 self.obj_conversion_errors = held_errors()
4501 release_errors(ignore=True)
4503 def may_be_none(self):
4506 def coerce_to(self, dst_type, env):
4507 if dst_type.is_pyobject:
4508 self.release_errors()
4509 if not self.type.subtype_of(dst_type):
4510 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4511 elif dst_type.is_struct_or_union:
4512 self.type = dst_type
4513 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4514 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4515 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4516 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4517 for item in self.key_value_pairs:
4518 if isinstance(item.key, CoerceToPyTypeNode):
4519 item.key = item.key.arg
4520 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4521 error(item.key.pos, "Invalid struct field identifier")
4522 item.key = StringNode(item.key.pos, value="<error>")
4524 key = str(item.key.value) # converts string literals to unicode in Py3
4525 member = dst_type.scope.lookup_here(key)
4527 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4530 if isinstance(value, CoerceToPyTypeNode):
4532 item.value = value.coerce_to(member.type, env)
4534 self.type = error_type
4535 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4538 def release_errors(self):
4539 for err in self.obj_conversion_errors:
4541 self.obj_conversion_errors = []
4543 gil_message = "Constructing Python dict"
4545 def generate_evaluation_code(self, code):
4546 # Custom method used here because key-value
4547 # pairs are evaluated and used one at a time.
4548 code.mark_pos(self.pos)
4549 self.allocate_temp_result(code)
4550 if self.type.is_pyobject:
4551 self.release_errors()
4553 "%s = PyDict_New(); %s" % (
4555 code.error_goto_if_null(self.result(), self.pos)))
4556 code.put_gotref(self.py_result())
4557 for item in self.key_value_pairs:
4558 item.generate_evaluation_code(code)
4559 if self.type.is_pyobject:
4560 code.put_error_if_neg(self.pos,
4561 "PyDict_SetItem(%s, %s, %s)" % (
4563 item.key.py_result(),
4564 item.value.py_result()))
4566 code.putln("%s.%s = %s;" % (
4569 item.value.result()))
4570 item.generate_disposal_code(code)
4571 item.free_temps(code)
4573 def annotate(self, code):
4574 for item in self.key_value_pairs:
4577 class DictItemNode(ExprNode):
4578 # Represents a single item in a DictNode
4582 subexprs = ['key', 'value']
4584 nogil_check = None # Parent DictNode takes care of it
4586 def calculate_constant_result(self):
4587 self.constant_result = (
4588 self.key.constant_result, self.value.constant_result)
4590 def analyse_types(self, env):
4591 self.key.analyse_types(env)
4592 self.value.analyse_types(env)
4593 self.key = self.key.coerce_to_pyobject(env)
4594 self.value = self.value.coerce_to_pyobject(env)
4596 def generate_evaluation_code(self, code):
4597 self.key.generate_evaluation_code(code)
4598 self.value.generate_evaluation_code(code)
4600 def generate_disposal_code(self, code):
4601 self.key.generate_disposal_code(code)
4602 self.value.generate_disposal_code(code)
4604 def free_temps(self, code):
4605 self.key.free_temps(code)
4606 self.value.free_temps(code)
4609 return iter([self.key, self.value])
4611 class ModuleNameMixin(object):
4612 def set_mod_name(self, env):
4613 self.module_name = env.global_scope().qualified_name
4615 def get_py_mod_name(self, code):
4616 return code.get_py_string_const(
4617 self.module_name, identifier=True)
4619 class ClassNode(ExprNode, ModuleNameMixin):
4620 # Helper class used in the implementation of Python
4621 # class definitions. Constructs a class object given
4622 # a name, tuple of bases and class dictionary.
4624 # name EncodedString Name of the class
4625 # bases ExprNode Base class tuple
4626 # dict ExprNode Class dict (not owned by this node)
4627 # doc ExprNode or None Doc string
4628 # module_name EncodedString Name of defining module
4630 subexprs = ['bases', 'doc']
4632 def analyse_types(self, env):
4633 self.bases.analyse_types(env)
4635 self.doc.analyse_types(env)
4636 self.doc = self.doc.coerce_to_pyobject(env)
4637 self.type = py_object_type
4639 env.use_utility_code(create_class_utility_code);
4640 #TODO(craig,haoyu) This should be moved to a better place
4641 self.set_mod_name(env)
4643 def may_be_none(self):
4646 gil_message = "Constructing Python class"
4648 def generate_result_code(self, code):
4649 cname = code.intern_identifier(self.name)
4652 code.put_error_if_neg(self.pos,
4653 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4654 self.dict.py_result(),
4655 self.doc.py_result()))
4656 py_mod_name = self.get_py_mod_name(code)
4658 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4660 self.bases.py_result(),
4661 self.dict.py_result(),
4664 code.error_goto_if_null(self.result(), self.pos)))
4665 code.put_gotref(self.py_result())
4668 class Py3ClassNode(ExprNode):
4669 # Helper class used in the implementation of Python3+
4670 # class definitions. Constructs a class object given
4671 # a name, tuple of bases and class dictionary.
4673 # name EncodedString Name of the class
4674 # dict ExprNode Class dict (not owned by this node)
4675 # module_name EncodedString Name of defining module
4679 def analyse_types(self, env):
4680 self.type = py_object_type
4683 def may_be_none(self):
4686 gil_message = "Constructing Python class"
4688 def generate_result_code(self, code):
4689 code.globalstate.use_utility_code(create_py3class_utility_code)
4690 cname = code.intern_identifier(self.name)
4692 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4694 self.metaclass.result(),
4696 self.bases.py_result(),
4697 self.dict.py_result(),
4698 self.mkw.py_result(),
4699 code.error_goto_if_null(self.result(), self.pos)))
4700 code.put_gotref(self.py_result())
4702 class KeywordArgsNode(ExprNode):
4703 # Helper class for keyword arguments
4705 # keyword_args ExprNode or None Keyword arguments
4706 # starstar_arg ExprNode or None Extra arguments
4708 subexprs = ['keyword_args', 'starstar_arg']
4710 def analyse_types(self, env):
4711 if self.keyword_args:
4712 self.keyword_args.analyse_types(env)
4713 if self.starstar_arg:
4714 self.starstar_arg.analyse_types(env)
4715 # make sure we have a Python object as **kwargs mapping
4716 self.starstar_arg = \
4717 self.starstar_arg.coerce_to_pyobject(env)
4718 self.type = py_object_type
4721 gil_message = "Constructing Keyword Args"
4723 def generate_result_code(self, code):
4724 if self.keyword_args and self.starstar_arg:
4725 code.put_error_if_neg(self.pos,
4726 "PyDict_Update(%s, %s)" % (
4727 self.keyword_args.py_result(),
4728 self.starstar_arg.py_result()))
4729 if self.keyword_args:
4730 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4731 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4732 elif self.starstar_arg:
4734 "%s = PyDict_Copy(%s); %s" % (
4736 self.starstar_arg.py_result(),
4737 code.error_goto_if_null(self.result(), self.pos)))
4738 code.put_gotref(self.py_result())
4741 "%s = PyDict_New(); %s" % (
4743 code.error_goto_if_null(self.result(), self.pos)))
4744 code.put_gotref(self.py_result())
4746 class PyClassMetaclassNode(ExprNode):
4747 # Helper class holds Python3 metaclass object
4749 # bases ExprNode Base class tuple (not owned by this node)
4750 # mkw ExprNode Class keyword arguments (not owned by this node)
4754 def analyse_types(self, env):
4755 self.type = py_object_type
4758 def may_be_none(self):
4761 def generate_result_code(self, code):
4763 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4765 self.bases.result(),
4767 code.error_goto_if_null(self.result(), self.pos)))
4768 code.put_gotref(self.py_result())
4770 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4771 # Helper class holds Python3 namespace object
4773 # All this are not owned by this node
4774 # metaclass ExprNode Metaclass object
4775 # bases ExprNode Base class tuple
4776 # mkw ExprNode Class keyword arguments
4777 # doc ExprNode or None Doc string (owned)
4781 def analyse_types(self, env):
4782 self.bases.analyse_types(env)
4784 self.doc.analyse_types(env)
4785 self.doc = self.doc.coerce_to_pyobject(env)
4786 self.type = py_object_type
4788 #TODO(craig,haoyu) This should be moved to a better place
4789 self.set_mod_name(env)
4791 def may_be_none(self):
4794 def generate_result_code(self, code):
4795 cname = code.intern_identifier(self.name)
4796 py_mod_name = self.get_py_mod_name(code)
4798 doc_code = self.doc.result()
4800 doc_code = '(PyObject *) NULL'
4802 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4804 self.metaclass.result(),
4805 self.bases.result(),
4810 code.error_goto_if_null(self.result(), self.pos)))
4811 code.put_gotref(self.py_result())
4813 class BoundMethodNode(ExprNode):
4814 # Helper class used in the implementation of Python
4815 # class definitions. Constructs an bound method
4816 # object from a class and a function.
4818 # function ExprNode Function object
4819 # self_object ExprNode self object
4821 subexprs = ['function']
4823 def analyse_types(self, env):
4824 self.function.analyse_types(env)
4825 self.type = py_object_type
4828 gil_message = "Constructing an bound method"
4830 def generate_result_code(self, code):
4832 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4834 self.function.py_result(),
4835 self.self_object.py_result(),
4836 self.self_object.py_result(),
4837 code.error_goto_if_null(self.result(), self.pos)))
4838 code.put_gotref(self.py_result())
4840 class UnboundMethodNode(ExprNode):
4841 # Helper class used in the implementation of Python
4842 # class definitions. Constructs an unbound method
4843 # object from a class and a function.
4845 # function ExprNode Function object
4847 type = py_object_type
4850 subexprs = ['function']
4852 def analyse_types(self, env):
4853 self.function.analyse_types(env)
4855 def may_be_none(self):
4858 gil_message = "Constructing an unbound method"
4860 def generate_result_code(self, code):
4861 class_cname = code.pyclass_stack[-1].classobj.result()
4863 "%s = PyMethod_New(%s, 0, %s); %s" % (
4865 self.function.py_result(),
4867 code.error_goto_if_null(self.result(), self.pos)))
4868 code.put_gotref(self.py_result())
4871 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4872 # Helper class used in the implementation of Python
4873 # class definitions. Constructs a PyCFunction object
4874 # from a PyMethodDef struct.
4876 # pymethdef_cname string PyMethodDef structure
4877 # self_object ExprNode or None
4879 # module_name EncodedString Name of defining module
4885 type = py_object_type
4888 def analyse_types(self, env):
4890 env.use_utility_code(binding_cfunc_utility_code)
4892 #TODO(craig,haoyu) This should be moved to a better place
4893 self.set_mod_name(env)
4895 def may_be_none(self):
4898 gil_message = "Constructing Python function"
4900 def self_result_code(self):
4901 if self.self_object is None:
4902 self_result = "NULL"
4904 self_result = self.self_object.py_result()
4907 def generate_result_code(self, code):
4909 constructor = "%s_NewEx" % Naming.binding_cfunc
4911 constructor = "PyCFunction_NewEx"
4912 py_mod_name = self.get_py_mod_name(code)
4914 '%s = %s(&%s, %s, %s); %s' % (
4917 self.pymethdef_cname,
4918 self.self_result_code(),
4920 code.error_goto_if_null(self.result(), self.pos)))
4921 code.put_gotref(self.py_result())
4923 class InnerFunctionNode(PyCFunctionNode):
4924 # Special PyCFunctionNode that depends on a closure class
4928 needs_self_code = True
4930 def self_result_code(self):
4931 if self.needs_self_code:
4932 return "((PyObject*)%s)" % (Naming.cur_scope_cname)
4935 class LambdaNode(InnerFunctionNode):
4936 # Lambda expression node (only used as a function reference)
4938 # args [CArgDeclNode] formal arguments
4939 # star_arg PyArgDeclNode or None * argument
4940 # starstar_arg PyArgDeclNode or None ** argument
4941 # lambda_name string a module-globally unique lambda name
4942 # result_expr ExprNode
4943 # def_node DefNode the underlying function 'def' node
4945 child_attrs = ['def_node']
4948 name = StringEncoding.EncodedString('<lambda>')
4950 def analyse_declarations(self, env):
4951 self.def_node.analyse_declarations(env)
4952 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
4953 env.add_lambda_def(self.def_node)
4956 class GeneratorExpressionNode(LambdaNode):
4957 # A generator expression, e.g. (i for i in range(10))
4959 # Result is a generator.
4961 # loop ForStatNode the for-loop, containing a YieldExprNode
4962 # def_node DefNode the underlying generator 'def' node
4964 name = StringEncoding.EncodedString('genexpr')
4967 def analyse_declarations(self, env):
4968 self.def_node.no_assignment_synthesis = True
4969 self.def_node.analyse_declarations(env)
4970 env.add_lambda_def(self.def_node)
4972 def generate_result_code(self, code):
4974 '%s = %s(%s, NULL); %s' % (
4976 self.def_node.entry.func_cname,
4977 self.self_result_code(),
4978 code.error_goto_if_null(self.result(), self.pos)))
4979 code.put_gotref(self.py_result())
4982 class YieldExprNode(ExprNode):
4983 # Yield expression node
4985 # arg ExprNode the value to return from the generator
4986 # label_name string name of the C label used for this yield
4987 # label_num integer yield label number
4990 type = py_object_type
4993 def analyse_types(self, env):
4994 if not self.label_num:
4995 error(self.pos, "'yield' not supported here")
4997 if self.arg is not None:
4998 self.arg.analyse_types(env)
4999 if not self.arg.type.is_pyobject:
5000 self.arg = self.arg.coerce_to_pyobject(env)
5001 env.use_utility_code(generator_utility_code)
5003 def generate_evaluation_code(self, code):
5004 self.label_name = code.new_label('resume_from_yield')
5005 code.use_label(self.label_name)
5007 self.arg.generate_evaluation_code(code)
5008 self.arg.make_owned_reference(code)
5011 Naming.retval_cname,
5012 self.arg.result_as(py_object_type)))
5013 self.arg.generate_post_assignment_code(code)
5014 #self.arg.generate_disposal_code(code)
5015 self.arg.free_temps(code)
5017 code.put_init_to_py_none(Naming.retval_cname, py_object_type)
5019 code.funcstate.closure_temps.reset()
5020 for cname, type, manage_ref in code.funcstate.temps_in_use():
5021 save_cname = code.funcstate.closure_temps.allocate_temp(type)
5022 saved.append((cname, save_cname, type))
5023 if type.is_pyobject:
5024 code.put_xgiveref(cname)
5025 code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
5027 code.put_xgiveref(Naming.retval_cname)
5028 code.put_finish_refcount_context()
5029 code.putln("/* return from generator, yielding value */")
5030 code.putln("%s->%s.resume_label = %d;" % (Naming.cur_scope_cname, Naming.obj_base_cname, self.label_num))
5031 code.putln("return %s;" % Naming.retval_cname);
5032 code.put_label(self.label_name)
5033 for cname, save_cname, type in saved:
5034 code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
5035 if type.is_pyobject:
5036 code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
5037 if type.is_pyobject:
5038 code.put_xgotref(cname)
5039 if self.result_is_used:
5040 self.allocate_temp_result(code)
5041 code.putln('%s = %s; %s' %
5042 (self.result(), Naming.sent_value_cname,
5043 code.error_goto_if_null(self.result(), self.pos)))
5044 code.put_incref(self.result(), py_object_type)
5046 code.putln(code.error_goto_if_null(Naming.sent_value_cname, self.pos))
5048 #-------------------------------------------------------------------
5050 # Unary operator nodes
5052 #-------------------------------------------------------------------
5054 compile_time_unary_operators = {
5055 'not': operator.not_,
5061 class UnopNode(ExprNode):
5065 # Processing during analyse_expressions phase:
5067 # analyse_c_operation
5068 # Called when the operand is not a pyobject.
5069 # - Check operand type and coerce if needed.
5070 # - Determine result type and result code fragment.
5071 # - Allocate temporary for result if needed.
5073 subexprs = ['operand']
5076 def calculate_constant_result(self):
5077 func = compile_time_unary_operators[self.operator]
5078 self.constant_result = func(self.operand.constant_result)
5080 def compile_time_value(self, denv):
5081 func = compile_time_unary_operators.get(self.operator)
5084 "Unary '%s' not supported in compile-time expression"
5086 operand = self.operand.compile_time_value(denv)
5088 return func(operand)
5089 except Exception, e:
5090 self.compile_time_value_error(e)
5092 def infer_type(self, env):
5093 operand_type = self.operand.infer_type(env)
5094 if operand_type.is_pyobject:
5095 return py_object_type
5099 def analyse_types(self, env):
5100 self.operand.analyse_types(env)
5101 if self.is_py_operation():
5102 self.coerce_operand_to_pyobject(env)
5103 self.type = py_object_type
5105 elif self.is_cpp_operation():
5106 self.analyse_cpp_operation(env)
5108 self.analyse_c_operation(env)
5110 def check_const(self):
5111 return self.operand.check_const()
5113 def is_py_operation(self):
5114 return self.operand.type.is_pyobject
5116 def nogil_check(self, env):
5117 if self.is_py_operation():
5120 def is_cpp_operation(self):
5121 type = self.operand.type
5122 return type.is_cpp_class
5124 def coerce_operand_to_pyobject(self, env):
5125 self.operand = self.operand.coerce_to_pyobject(env)
5127 def generate_result_code(self, code):
5128 if self.operand.type.is_pyobject:
5129 self.generate_py_operation_code(code)
5131 def generate_py_operation_code(self, code):
5132 function = self.py_operation_function()
5134 "%s = %s(%s); %s" % (
5137 self.operand.py_result(),
5138 code.error_goto_if_null(self.result(), self.pos)))
5139 code.put_gotref(self.py_result())
5141 def type_error(self):
5142 if not self.operand.type.is_error:
5143 error(self.pos, "Invalid operand type for '%s' (%s)" %
5144 (self.operator, self.operand.type))
5145 self.type = PyrexTypes.error_type
5147 def analyse_cpp_operation(self, env):
5148 type = self.operand.type
5150 type = type.base_type
5151 function = type.scope.lookup("operator%s" % self.operator)
5153 error(self.pos, "'%s' operator not defined for %s"
5154 % (self.operator, type))
5157 func_type = function.type
5158 if func_type.is_ptr:
5159 func_type = func_type.base_type
5160 self.type = func_type.return_type
5163 class NotNode(ExprNode):
5168 type = PyrexTypes.c_bint_type
5170 subexprs = ['operand']
5172 def calculate_constant_result(self):
5173 self.constant_result = not self.operand.constant_result
5175 def compile_time_value(self, denv):
5176 operand = self.operand.compile_time_value(denv)
5179 except Exception, e:
5180 self.compile_time_value_error(e)
5182 def infer_type(self, env):
5183 return PyrexTypes.c_bint_type
5185 def analyse_types(self, env):
5186 self.operand.analyse_types(env)
5187 self.operand = self.operand.coerce_to_boolean(env)
5189 def calculate_result_code(self):
5190 return "(!%s)" % self.operand.result()
5192 def generate_result_code(self, code):
5196 class UnaryPlusNode(UnopNode):
5197 # unary '+' operator
5201 def analyse_c_operation(self, env):
5202 self.type = self.operand.type
5204 def py_operation_function(self):
5205 return "PyNumber_Positive"
5207 def calculate_result_code(self):
5208 if self.is_cpp_operation():
5209 return "(+%s)" % self.operand.result()
5211 return self.operand.result()
5214 class UnaryMinusNode(UnopNode):
5215 # unary '-' operator
5219 def analyse_c_operation(self, env):
5220 if self.operand.type.is_numeric:
5221 self.type = self.operand.type
5224 if self.type.is_complex:
5227 def py_operation_function(self):
5228 return "PyNumber_Negative"
5230 def calculate_result_code(self):
5232 return "(-%s)" % self.operand.result()
5234 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5236 def get_constant_c_result_code(self):
5237 value = self.operand.get_constant_c_result_code()
5239 return "(-%s)" % (value)
5241 class TildeNode(UnopNode):
5242 # unary '~' operator
5244 def analyse_c_operation(self, env):
5245 if self.operand.type.is_int:
5246 self.type = self.operand.type
5250 def py_operation_function(self):
5251 return "PyNumber_Invert"
5253 def calculate_result_code(self):
5254 return "(~%s)" % self.operand.result()
5257 class CUnopNode(UnopNode):
5259 def is_py_operation(self):
5262 class DereferenceNode(CUnopNode):
5267 def analyse_c_operation(self, env):
5268 if self.operand.type.is_ptr:
5269 self.type = self.operand.type.base_type
5273 def calculate_result_code(self):
5274 return "(*%s)" % self.operand.result()
5277 class DecrementIncrementNode(CUnopNode):
5278 # unary ++/-- operator
5280 def analyse_c_operation(self, env):
5281 if self.operand.type.is_ptr or self.operand.type.is_numeric:
5282 self.type = self.operand.type
5286 def calculate_result_code(self):
5288 return "(%s%s)" % (self.operator, self.operand.result())
5290 return "(%s%s)" % (self.operand.result(), self.operator)
5292 def inc_dec_constructor(is_prefix, operator):
5293 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5296 class AmpersandNode(ExprNode):
5297 # The C address-of operator.
5301 subexprs = ['operand']
5303 def infer_type(self, env):
5304 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5306 def analyse_types(self, env):
5307 self.operand.analyse_types(env)
5308 argtype = self.operand.type
5309 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5310 self.error("Taking address of non-lvalue")
5312 if argtype.is_pyobject:
5313 self.error("Cannot take address of Python variable")
5315 self.type = PyrexTypes.c_ptr_type(argtype)
5317 def check_const(self):
5318 return self.operand.check_const_addr()
5320 def error(self, mess):
5321 error(self.pos, mess)
5322 self.type = PyrexTypes.error_type
5323 self.result_code = "<error>"
5325 def calculate_result_code(self):
5326 return "(&%s)" % self.operand.result()
5328 def generate_result_code(self, code):
5332 unop_node_classes = {
5334 "-": UnaryMinusNode,
5338 def unop_node(pos, operator, operand):
5339 # Construct unnop node of appropriate class for
5341 if isinstance(operand, IntNode) and operator == '-':
5342 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5343 elif isinstance(operand, UnopNode) and operand.operator == operator:
5344 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5345 return unop_node_classes[operator](pos,
5346 operator = operator,
5350 class TypecastNode(ExprNode):
5354 # base_type CBaseTypeNode
5355 # declarator CDeclaratorNode
5357 # If used from a transform, one can if wanted specify the attribute
5358 # "type" directly and leave base_type and declarator to None
5360 subexprs = ['operand']
5361 base_type = declarator = type = None
5363 def type_dependencies(self, env):
5366 def infer_type(self, env):
5367 if self.type is None:
5368 base_type = self.base_type.analyse(env)
5369 _, self.type = self.declarator.analyse(base_type, env)
5372 def analyse_types(self, env):
5373 if self.type is None:
5374 base_type = self.base_type.analyse(env)
5375 _, self.type = self.declarator.analyse(base_type, env)
5376 if self.type.is_cfunction:
5378 "Cannot cast to a function type")
5379 self.type = PyrexTypes.error_type
5380 self.operand.analyse_types(env)
5381 to_py = self.type.is_pyobject
5382 from_py = self.operand.type.is_pyobject
5383 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5384 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5385 if to_py and not from_py:
5386 if self.type is bytes_type and self.operand.type.is_int:
5387 # FIXME: the type cast node isn't needed in this case
5388 # and can be dropped once analyse_types() can return a
5390 self.operand = CoerceIntToBytesNode(self.operand, env)
5391 elif self.operand.type.can_coerce_to_pyobject(env):
5392 self.result_ctype = py_object_type
5393 self.operand = self.operand.coerce_to_pyobject(env)
5395 if self.operand.type.is_ptr:
5396 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5397 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5399 # Should this be an error?
5400 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5401 self.operand = self.operand.coerce_to_simple(env)
5402 elif from_py and not to_py:
5403 if self.type.create_from_py_utility_code(env):
5404 self.operand = self.operand.coerce_to(self.type, env)
5405 elif self.type.is_ptr:
5406 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5407 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5409 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5410 elif from_py and to_py:
5411 if self.typecheck and self.type.is_extension_type:
5412 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5413 elif self.type.is_complex and self.operand.type.is_complex:
5414 self.operand = self.operand.coerce_to_simple(env)
5416 def nogil_check(self, env):
5417 if self.type and self.type.is_pyobject and self.is_temp:
5420 def check_const(self):
5421 return self.operand.check_const()
5423 def calculate_constant_result(self):
5424 # we usually do not know the result of a type cast at code
5428 def calculate_result_code(self):
5429 if self.type.is_complex:
5430 operand_result = self.operand.result()
5431 if self.operand.type.is_complex:
5432 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5433 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5435 real_part = self.type.real_type.cast_code(operand_result)
5437 return "%s(%s, %s)" % (
5438 self.type.from_parts,
5442 return self.type.cast_code(self.operand.result())
5444 def get_constant_c_result_code(self):
5445 operand_result = self.operand.get_constant_c_result_code()
5447 return self.type.cast_code(operand_result)
5449 def result_as(self, type):
5450 if self.type.is_pyobject and not self.is_temp:
5451 # Optimise away some unnecessary casting
5452 return self.operand.result_as(type)
5454 return ExprNode.result_as(self, type)
5456 def generate_result_code(self, code):
5459 "%s = (PyObject *)%s;" % (
5461 self.operand.result()))
5462 code.put_incref(self.result(), self.ctype())
5465 class SizeofNode(ExprNode):
5466 # Abstract base class for sizeof(x) expression nodes.
5468 type = PyrexTypes.c_size_t_type
5470 def check_const(self):
5473 def generate_result_code(self, code):
5477 class SizeofTypeNode(SizeofNode):
5478 # C sizeof function applied to a type
5480 # base_type CBaseTypeNode
5481 # declarator CDeclaratorNode
5486 def analyse_types(self, env):
5487 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5488 # this could be better handled by more uniformly treating types as runtime-available objects
5489 if 0 and self.base_type.module_path:
5490 path = self.base_type.module_path
5491 obj = env.lookup(path[0])
5492 if obj.as_module is None:
5493 operand = NameNode(pos=self.pos, name=path[0])
5494 for attr in path[1:]:
5495 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5496 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5497 self.operand = operand
5498 self.__class__ = SizeofVarNode
5499 self.analyse_types(env)
5501 if self.arg_type is None:
5502 base_type = self.base_type.analyse(env)
5503 _, arg_type = self.declarator.analyse(base_type, env)
5504 self.arg_type = arg_type
5507 def check_type(self):
5508 arg_type = self.arg_type
5509 if arg_type.is_pyobject and not arg_type.is_extension_type:
5510 error(self.pos, "Cannot take sizeof Python object")
5511 elif arg_type.is_void:
5512 error(self.pos, "Cannot take sizeof void")
5513 elif not arg_type.is_complete():
5514 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5516 def calculate_result_code(self):
5517 if self.arg_type.is_extension_type:
5518 # the size of the pointer is boring
5519 # we want the size of the actual struct
5520 arg_code = self.arg_type.declaration_code("", deref=1)
5522 arg_code = self.arg_type.declaration_code("")
5523 return "(sizeof(%s))" % arg_code
5526 class SizeofVarNode(SizeofNode):
5527 # C sizeof function applied to a variable
5531 subexprs = ['operand']
5533 def analyse_types(self, env):
5534 # We may actually be looking at a type rather than a variable...
5535 # If we are, traditional analysis would fail...
5536 operand_as_type = self.operand.analyse_as_type(env)
5538 self.arg_type = operand_as_type
5539 self.__class__ = SizeofTypeNode
5542 self.operand.analyse_types(env)
5544 def calculate_result_code(self):
5545 return "(sizeof(%s))" % self.operand.result()
5547 def generate_result_code(self, code):
5550 class TypeofNode(ExprNode):
5551 # Compile-time type of an expression, as a string.
5554 # literal StringNode # internal
5557 type = py_object_type
5559 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5561 def analyse_types(self, env):
5562 self.operand.analyse_types(env)
5563 self.literal = StringNode(
5564 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5565 self.literal.analyse_types(env)
5566 self.literal = self.literal.coerce_to_pyobject(env)
5568 def may_be_none(self):
5571 def generate_evaluation_code(self, code):
5572 self.literal.generate_evaluation_code(code)
5574 def calculate_result_code(self):
5575 return self.literal.calculate_result_code()
5577 #-------------------------------------------------------------------
5579 # Binary operator nodes
5581 #-------------------------------------------------------------------
5583 def _not_in(x, seq):
5586 compile_time_binary_operators = {
5594 'is_not': operator.is_not,
5597 '/': operator.truediv,
5598 '//': operator.floordiv,
5599 '<<': operator.lshift,
5604 '>>': operator.rshift,
5607 'in': operator.contains,
5611 def get_compile_time_binop(node):
5612 func = compile_time_binary_operators.get(node.operator)
5615 "Binary '%s' not supported in compile-time expression"
5619 class BinopNode(ExprNode):
5624 # Processing during analyse_expressions phase:
5626 # analyse_c_operation
5627 # Called when neither operand is a pyobject.
5628 # - Check operand types and coerce if needed.
5629 # - Determine result type and result code fragment.
5630 # - Allocate temporary for result if needed.
5632 subexprs = ['operand1', 'operand2']
5635 def calculate_constant_result(self):
5636 func = compile_time_binary_operators[self.operator]
5637 self.constant_result = func(
5638 self.operand1.constant_result,
5639 self.operand2.constant_result)
5641 def compile_time_value(self, denv):
5642 func = get_compile_time_binop(self)
5643 operand1 = self.operand1.compile_time_value(denv)
5644 operand2 = self.operand2.compile_time_value(denv)
5646 return func(operand1, operand2)
5647 except Exception, e:
5648 self.compile_time_value_error(e)
5650 def infer_type(self, env):
5651 return self.result_type(self.operand1.infer_type(env),
5652 self.operand2.infer_type(env))
5654 def analyse_types(self, env):
5655 self.operand1.analyse_types(env)
5656 self.operand2.analyse_types(env)
5657 self.analyse_operation(env)
5659 def analyse_operation(self, env):
5660 if self.is_py_operation():
5661 self.coerce_operands_to_pyobjects(env)
5662 self.type = self.result_type(self.operand1.type,
5664 assert self.type.is_pyobject
5666 elif self.is_cpp_operation():
5667 self.analyse_cpp_operation(env)
5669 self.analyse_c_operation(env)
5671 def is_py_operation(self):
5672 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5674 def is_py_operation_types(self, type1, type2):
5675 return type1.is_pyobject or type2.is_pyobject
5677 def is_cpp_operation(self):
5678 return (self.operand1.type.is_cpp_class
5679 or self.operand2.type.is_cpp_class)
5681 def analyse_cpp_operation(self, env):
5682 type1 = self.operand1.type
5683 type2 = self.operand2.type
5684 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5688 func_type = entry.type
5689 if func_type.is_ptr:
5690 func_type = func_type.base_type
5691 if len(func_type.args) == 1:
5692 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5694 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5695 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5696 self.type = func_type.return_type
5698 def result_type(self, type1, type2):
5699 if self.is_py_operation_types(type1, type2):
5701 type2 = Builtin.bytes_type
5703 type1 = Builtin.bytes_type
5704 elif self.operator == '%' \
5705 and type1 in (Builtin.str_type, Builtin.unicode_type):
5706 # note that b'%s' % b'abc' doesn't work in Py3
5708 if type1.is_builtin_type:
5710 if self.operator in '**%+|&^':
5711 # FIXME: at least these operators should be safe - others?
5713 elif self.operator == '*':
5714 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5716 # multiplication of containers/numbers with an
5717 # integer value always (?) returns the same type
5720 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5721 # multiplication of containers/numbers with an
5722 # integer value always (?) returns the same type
5724 return py_object_type
5726 return self.compute_c_result_type(type1, type2)
5728 def nogil_check(self, env):
5729 if self.is_py_operation():
5732 def coerce_operands_to_pyobjects(self, env):
5733 self.operand1 = self.operand1.coerce_to_pyobject(env)
5734 self.operand2 = self.operand2.coerce_to_pyobject(env)
5736 def check_const(self):
5737 return self.operand1.check_const() and self.operand2.check_const()
5739 def generate_result_code(self, code):
5740 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5741 if self.operand1.type.is_pyobject:
5742 function = self.py_operation_function()
5743 if self.operator == '**':
5744 extra_args = ", Py_None"
5748 "%s = %s(%s, %s%s); %s" % (
5751 self.operand1.py_result(),
5752 self.operand2.py_result(),
5754 code.error_goto_if_null(self.result(), self.pos)))
5755 code.put_gotref(self.py_result())
5757 def type_error(self):
5758 if not (self.operand1.type.is_error
5759 or self.operand2.type.is_error):
5760 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5761 (self.operator, self.operand1.type,
5762 self.operand2.type))
5763 self.type = PyrexTypes.error_type
5766 class CBinopNode(BinopNode):
5768 def analyse_types(self, env):
5769 BinopNode.analyse_types(self, env)
5770 if self.is_py_operation():
5771 self.type = PyrexTypes.error_type
5773 def py_operation_function():
5776 def calculate_result_code(self):
5777 return "(%s %s %s)" % (
5778 self.operand1.result(),
5780 self.operand2.result())
5783 def c_binop_constructor(operator):
5784 def make_binop_node(pos, **operands):
5785 return CBinopNode(pos, operator=operator, **operands)
5786 return make_binop_node
5788 class NumBinopNode(BinopNode):
5789 # Binary operation taking numeric arguments.
5793 def analyse_c_operation(self, env):
5794 type1 = self.operand1.type
5795 type2 = self.operand2.type
5796 self.type = self.compute_c_result_type(type1, type2)
5800 if self.type.is_complex:
5802 if not self.infix or (type1.is_numeric and type2.is_numeric):
5803 self.operand1 = self.operand1.coerce_to(self.type, env)
5804 self.operand2 = self.operand2.coerce_to(self.type, env)
5806 def compute_c_result_type(self, type1, type2):
5807 if self.c_types_okay(type1, type2):
5808 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5809 if widest_type is PyrexTypes.c_bint_type:
5810 if self.operator not in '|^&':
5811 # False + False == 0 # not False!
5812 widest_type = PyrexTypes.c_int_type
5817 def get_constant_c_result_code(self):
5818 value1 = self.operand1.get_constant_c_result_code()
5819 value2 = self.operand2.get_constant_c_result_code()
5820 if value1 and value2:
5821 return "(%s %s %s)" % (value1, self.operator, value2)
5825 def c_types_okay(self, type1, type2):
5826 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5827 return (type1.is_numeric or type1.is_enum) \
5828 and (type2.is_numeric or type2.is_enum)
5830 def calculate_result_code(self):
5832 return "(%s %s %s)" % (
5833 self.operand1.result(),
5835 self.operand2.result())
5837 func = self.type.binary_op(self.operator)
5839 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5840 return "%s(%s, %s)" % (
5842 self.operand1.result(),
5843 self.operand2.result())
5845 def is_py_operation_types(self, type1, type2):
5846 return (type1 is PyrexTypes.c_py_unicode_type or
5847 type2 is PyrexTypes.c_py_unicode_type or
5848 BinopNode.is_py_operation_types(self, type1, type2))
5850 def py_operation_function(self):
5851 fuction = self.py_functions[self.operator]
5853 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
5858 "^": "PyNumber_Xor",
5859 "&": "PyNumber_And",
5860 "<<": "PyNumber_Lshift",
5861 ">>": "PyNumber_Rshift",
5862 "+": "PyNumber_Add",
5863 "-": "PyNumber_Subtract",
5864 "*": "PyNumber_Multiply",
5865 "/": "__Pyx_PyNumber_Divide",
5866 "//": "PyNumber_FloorDivide",
5867 "%": "PyNumber_Remainder",
5868 "**": "PyNumber_Power"
5871 class IntBinopNode(NumBinopNode):
5872 # Binary operation taking integer arguments.
5874 def c_types_okay(self, type1, type2):
5875 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5876 return (type1.is_int or type1.is_enum) \
5877 and (type2.is_int or type2.is_enum)
5880 class AddNode(NumBinopNode):
5883 def is_py_operation_types(self, type1, type2):
5884 if type1.is_string and type2.is_string:
5887 return NumBinopNode.is_py_operation_types(self, type1, type2)
5889 def compute_c_result_type(self, type1, type2):
5890 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5891 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5893 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5896 return NumBinopNode.compute_c_result_type(
5900 class SubNode(NumBinopNode):
5903 def compute_c_result_type(self, type1, type2):
5904 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5906 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5907 return PyrexTypes.c_int_type
5909 return NumBinopNode.compute_c_result_type(
5913 class MulNode(NumBinopNode):
5916 def is_py_operation_types(self, type1, type2):
5917 if (type1.is_string and type2.is_int) \
5918 or (type2.is_string and type1.is_int):
5921 return NumBinopNode.is_py_operation_types(self, type1, type2)
5924 class DivNode(NumBinopNode):
5925 # '/' or '//' operator.
5928 truedivision = None # == "unknown" if operator == '/'
5929 ctruedivision = False
5930 cdivision_warnings = False
5931 zerodivision_check = None
5933 def find_compile_time_binary_operator(self, op1, op2):
5934 func = compile_time_binary_operators[self.operator]
5935 if self.operator == '/' and self.truedivision is None:
5936 # => true div for floats, floor div for integers
5937 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5938 func = compile_time_binary_operators['//']
5941 def calculate_constant_result(self):
5942 op1 = self.operand1.constant_result
5943 op2 = self.operand2.constant_result
5944 func = self.find_compile_time_binary_operator(op1, op2)
5945 self.constant_result = func(
5946 self.operand1.constant_result,
5947 self.operand2.constant_result)
5949 def compile_time_value(self, denv):
5950 operand1 = self.operand1.compile_time_value(denv)
5951 operand2 = self.operand2.compile_time_value(denv)
5953 func = self.find_compile_time_binary_operator(
5954 self, operand1, operand2)
5955 return func(operand1, operand2)
5956 except Exception, e:
5957 self.compile_time_value_error(e)
5959 def analyse_operation(self, env):
5960 if self.cdivision or env.directives['cdivision']:
5961 self.ctruedivision = False
5963 self.ctruedivision = self.truedivision
5964 NumBinopNode.analyse_operation(self, env)
5965 if self.is_cpp_operation():
5966 self.cdivision = True
5967 if not self.type.is_pyobject:
5968 self.zerodivision_check = (
5969 self.cdivision is None and not env.directives['cdivision']
5970 and (not self.operand2.has_constant_result() or
5971 self.operand2.constant_result == 0))
5972 if self.zerodivision_check or env.directives['cdivision_warnings']:
5973 # Need to check ahead of time to warn or raise zero division error
5974 self.operand1 = self.operand1.coerce_to_simple(env)
5975 self.operand2 = self.operand2.coerce_to_simple(env)
5977 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5979 def compute_c_result_type(self, type1, type2):
5980 if self.operator == '/' and self.ctruedivision:
5981 if not type1.is_float and not type2.is_float:
5982 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5983 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5985 return NumBinopNode.compute_c_result_type(self, type1, type2)
5987 def zero_division_message(self):
5988 if self.type.is_int:
5989 return "integer division or modulo by zero"
5991 return "float division"
5993 def generate_evaluation_code(self, code):
5994 if not self.type.is_pyobject and not self.type.is_complex:
5995 if self.cdivision is None:
5996 self.cdivision = (code.globalstate.directives['cdivision']
5997 or not self.type.signed
5998 or self.type.is_float)
5999 if not self.cdivision:
6000 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
6001 NumBinopNode.generate_evaluation_code(self, code)
6002 self.generate_div_warning_code(code)
6004 def generate_div_warning_code(self, code):
6005 if not self.type.is_pyobject:
6006 if self.zerodivision_check:
6008 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
6010 zero_test = "%s == 0" % self.operand2.result()
6011 code.putln("if (unlikely(%s)) {" % zero_test)
6012 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
6013 code.putln(code.error_goto(self.pos))
6015 if self.type.is_int and self.type.signed and self.operator != '%':
6016 code.globalstate.use_utility_code(division_overflow_test_code)
6017 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6018 self.type.declaration_code(''),
6019 self.operand2.result(),
6020 self.operand1.result()))
6021 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
6022 code.putln(code.error_goto(self.pos))
6024 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6025 code.globalstate.use_utility_code(cdivision_warning_utility_code)
6026 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
6027 self.operand1.result(),
6028 self.operand2.result()))
6029 code.putln(code.set_error_info(self.pos));
6030 code.put("if (__Pyx_cdivision_warning()) ")
6031 code.put_goto(code.error_label)
6034 def calculate_result_code(self):
6035 if self.type.is_complex:
6036 return NumBinopNode.calculate_result_code(self)
6037 elif self.type.is_float and self.operator == '//':
6038 return "floor(%s / %s)" % (
6039 self.operand1.result(),
6040 self.operand2.result())
6041 elif self.truedivision or self.cdivision:
6042 op1 = self.operand1.result()
6043 op2 = self.operand2.result()
6044 if self.truedivision:
6045 if self.type != self.operand1.type:
6046 op1 = self.type.cast_code(op1)
6047 if self.type != self.operand2.type:
6048 op2 = self.type.cast_code(op2)
6049 return "(%s / %s)" % (op1, op2)
6051 return "__Pyx_div_%s(%s, %s)" % (
6052 self.type.specialization_name(),
6053 self.operand1.result(),
6054 self.operand2.result())
6057 class ModNode(DivNode):
6060 def is_py_operation_types(self, type1, type2):
6061 return (type1.is_string
6063 or NumBinopNode.is_py_operation_types(self, type1, type2))
6065 def zero_division_message(self):
6066 if self.type.is_int:
6067 return "integer division or modulo by zero"
6069 return "float divmod()"
6071 def generate_evaluation_code(self, code):
6072 if not self.type.is_pyobject:
6073 if self.cdivision is None:
6074 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
6075 if not self.cdivision:
6076 if self.type.is_int:
6077 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6079 code.globalstate.use_utility_code(
6080 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6081 NumBinopNode.generate_evaluation_code(self, code)
6082 self.generate_div_warning_code(code)
6084 def calculate_result_code(self):
6086 if self.type.is_float:
6087 return "fmod%s(%s, %s)" % (
6088 self.type.math_h_modifier,
6089 self.operand1.result(),
6090 self.operand2.result())
6092 return "(%s %% %s)" % (
6093 self.operand1.result(),
6094 self.operand2.result())
6096 return "__Pyx_mod_%s(%s, %s)" % (
6097 self.type.specialization_name(),
6098 self.operand1.result(),
6099 self.operand2.result())
6101 class PowNode(NumBinopNode):
6104 def analyse_c_operation(self, env):
6105 NumBinopNode.analyse_c_operation(self, env)
6106 if self.type.is_complex:
6107 if self.type.real_type.is_float:
6108 self.operand1 = self.operand1.coerce_to(self.type, env)
6109 self.operand2 = self.operand2.coerce_to(self.type, env)
6110 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
6112 error(self.pos, "complex int powers not supported")
6113 self.pow_func = "<error>"
6114 elif self.type.is_float:
6115 self.pow_func = "pow" + self.type.math_h_modifier
6117 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
6118 env.use_utility_code(
6119 int_pow_utility_code.specialize(func_name=self.pow_func,
6120 type=self.type.declaration_code('')))
6122 def calculate_result_code(self):
6123 # Work around MSVC overloading ambiguity.
6124 def typecast(operand):
6125 if self.type == operand.type:
6126 return operand.result()
6128 return self.type.cast_code(operand.result())
6129 return "%s(%s, %s)" % (
6131 typecast(self.operand1),
6132 typecast(self.operand2))
6135 # Note: This class is temporarily "shut down" into an ineffective temp
6138 # More sophisticated temp reuse was going on before, one could have a
6139 # look at adding this again after /all/ classes are converted to the
6140 # new temp scheme. (The temp juggling cannot work otherwise).
6141 class BoolBinopNode(ExprNode):
6142 # Short-circuiting boolean operation.
6148 subexprs = ['operand1', 'operand2']
6150 def infer_type(self, env):
6151 type1 = self.operand1.infer_type(env)
6152 type2 = self.operand2.infer_type(env)
6153 return PyrexTypes.independent_spanning_type(type1, type2)
6155 def may_be_none(self):
6156 if self.operator == 'or':
6157 return self.operand2.may_be_none()
6159 return self.operand1.may_be_none() or self.operand2.may_be_none()
6161 def calculate_constant_result(self):
6162 if self.operator == 'and':
6163 self.constant_result = \
6164 self.operand1.constant_result and \
6165 self.operand2.constant_result
6167 self.constant_result = \
6168 self.operand1.constant_result or \
6169 self.operand2.constant_result
6171 def compile_time_value(self, denv):
6172 if self.operator == 'and':
6173 return self.operand1.compile_time_value(denv) \
6174 and self.operand2.compile_time_value(denv)
6176 return self.operand1.compile_time_value(denv) \
6177 or self.operand2.compile_time_value(denv)
6179 def coerce_to_boolean(self, env):
6180 return BoolBinopNode(
6182 operator = self.operator,
6183 operand1 = self.operand1.coerce_to_boolean(env),
6184 operand2 = self.operand2.coerce_to_boolean(env),
6185 type = PyrexTypes.c_bint_type,
6186 is_temp = self.is_temp)
6188 def analyse_types(self, env):
6189 self.operand1.analyse_types(env)
6190 self.operand2.analyse_types(env)
6191 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6192 self.operand1 = self.operand1.coerce_to(self.type, env)
6193 self.operand2 = self.operand2.coerce_to(self.type, env)
6195 # For what we're about to do, it's vital that
6196 # both operands be temp nodes.
6197 self.operand1 = self.operand1.coerce_to_simple(env)
6198 self.operand2 = self.operand2.coerce_to_simple(env)
6201 gil_message = "Truth-testing Python object"
6203 def check_const(self):
6204 return self.operand1.check_const() and self.operand2.check_const()
6206 def generate_evaluation_code(self, code):
6207 code.mark_pos(self.pos)
6208 self.operand1.generate_evaluation_code(code)
6209 test_result, uses_temp = self.generate_operand1_test(code)
6210 if self.operator == 'and':
6219 code.funcstate.release_temp(test_result)
6220 self.operand1.generate_disposal_code(code)
6221 self.operand2.generate_evaluation_code(code)
6222 self.allocate_temp_result(code)
6223 self.operand2.make_owned_reference(code)
6224 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6225 self.operand2.generate_post_assignment_code(code)
6226 self.operand2.free_temps(code)
6227 code.putln("} else {")
6228 self.operand1.make_owned_reference(code)
6229 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6230 self.operand1.generate_post_assignment_code(code)
6231 self.operand1.free_temps(code)
6234 def generate_operand1_test(self, code):
6235 # Generate code to test the truth of the first operand.
6236 if self.type.is_pyobject:
6237 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6240 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6242 self.operand1.py_result(),
6243 code.error_goto_if_neg(test_result, self.pos)))
6245 test_result = self.operand1.result()
6246 return (test_result, self.type.is_pyobject)
6249 class CondExprNode(ExprNode):
6250 # Short-circuiting conditional expression.
6254 # false_val ExprNode
6259 subexprs = ['test', 'true_val', 'false_val']
6261 def type_dependencies(self, env):
6262 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6264 def infer_type(self, env):
6265 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6266 self.false_val.infer_type(env))
6268 def calculate_constant_result(self):
6269 if self.test.constant_result:
6270 self.constant_result = self.true_val.constant_result
6272 self.constant_result = self.false_val.constant_result
6274 def analyse_types(self, env):
6275 self.test.analyse_types(env)
6276 self.test = self.test.coerce_to_boolean(env)
6277 self.true_val.analyse_types(env)
6278 self.false_val.analyse_types(env)
6279 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6280 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6281 self.true_val = self.true_val.coerce_to(self.type, env)
6282 self.false_val = self.false_val.coerce_to(self.type, env)
6284 if self.type == PyrexTypes.error_type:
6287 def type_error(self):
6288 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6289 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6290 (self.true_val.type, self.false_val.type))
6291 self.type = PyrexTypes.error_type
6293 def check_const(self):
6294 return (self.test.check_const()
6295 and self.true_val.check_const()
6296 and self.false_val.check_const())
6298 def generate_evaluation_code(self, code):
6299 # Because subexprs may not be evaluated we can use a more optimal
6300 # subexpr allocation strategy than the default, so override evaluation_code.
6302 code.mark_pos(self.pos)
6303 self.allocate_temp_result(code)
6304 self.test.generate_evaluation_code(code)
6305 code.putln("if (%s) {" % self.test.result() )
6306 self.eval_and_get(code, self.true_val)
6307 code.putln("} else {")
6308 self.eval_and_get(code, self.false_val)
6310 self.test.generate_disposal_code(code)
6311 self.test.free_temps(code)
6313 def eval_and_get(self, code, expr):
6314 expr.generate_evaluation_code(code)
6315 expr.make_owned_reference(code)
6316 code.putln("%s = %s;" % (self.result(), expr.result()))
6317 expr.generate_post_assignment_code(code)
6318 expr.free_temps(code)
6320 richcmp_constants = {
6330 class CmpNode(object):
6331 # Mixin class containing code common to PrimaryCmpNodes
6332 # and CascadedCmpNodes.
6334 special_bool_cmp_function = None
6336 def infer_type(self, env):
6337 # TODO: Actually implement this (after merging with -unstable).
6338 return py_object_type
6340 def calculate_cascaded_constant_result(self, operand1_result):
6341 func = compile_time_binary_operators[self.operator]
6342 operand2_result = self.operand2.constant_result
6343 result = func(operand1_result, operand2_result)
6345 self.cascade.calculate_cascaded_constant_result(operand2_result)
6346 if self.cascade.constant_result:
6347 self.constant_result = result and self.cascade.constant_result
6349 self.constant_result = result
6351 def cascaded_compile_time_value(self, operand1, denv):
6352 func = get_compile_time_binop(self)
6353 operand2 = self.operand2.compile_time_value(denv)
6355 result = func(operand1, operand2)
6356 except Exception, e:
6357 self.compile_time_value_error(e)
6360 cascade = self.cascade
6362 # FIXME: I bet this must call cascaded_compile_time_value()
6363 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6366 def is_cpp_comparison(self):
6367 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6369 def find_common_int_type(self, env, op, operand1, operand2):
6370 # type1 != type2 and at least one of the types is not a C int
6371 type1 = operand1.type
6372 type2 = operand2.type
6373 type1_can_be_int = False
6374 type2_can_be_int = False
6376 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6377 and operand1.can_coerce_to_char_literal():
6378 type1_can_be_int = True
6379 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6380 and operand2.can_coerce_to_char_literal():
6381 type2_can_be_int = True
6384 if type2_can_be_int:
6387 if type1_can_be_int:
6389 elif type1_can_be_int:
6390 if type2_can_be_int:
6391 return PyrexTypes.c_uchar_type
6395 def find_common_type(self, env, op, operand1, common_type=None):
6396 operand2 = self.operand2
6397 type1 = operand1.type
6398 type2 = operand2.type
6400 new_common_type = None
6402 # catch general errors
6403 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6404 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6405 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6406 new_common_type = error_type
6408 # try to use numeric comparisons where possible
6409 elif type1.is_complex or type2.is_complex:
6410 if op not in ('==', '!='):
6411 error(self.pos, "complex types are unordered")
6412 new_common_type = error_type
6413 if type1.is_pyobject:
6414 new_common_type = type1
6415 elif type2.is_pyobject:
6416 new_common_type = type2
6418 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6419 elif type1.is_numeric and type2.is_numeric:
6420 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6421 elif common_type is None or not common_type.is_pyobject:
6422 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6424 if new_common_type is None:
6425 # fall back to generic type compatibility tests
6427 new_common_type = type1
6428 elif type1.is_pyobject or type2.is_pyobject:
6429 if type2.is_numeric or type2.is_string:
6430 if operand2.check_for_coercion_error(type1):
6431 new_common_type = error_type
6433 new_common_type = py_object_type
6434 elif type1.is_numeric or type1.is_string:
6435 if operand1.check_for_coercion_error(type2):
6436 new_common_type = error_type
6438 new_common_type = py_object_type
6439 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6440 new_common_type = py_object_type
6442 # one Python type and one non-Python type, not assignable
6443 self.invalid_types_error(operand1, op, operand2)
6444 new_common_type = error_type
6445 elif type1.assignable_from(type2):
6446 new_common_type = type1
6447 elif type2.assignable_from(type1):
6448 new_common_type = type2
6450 # C types that we couldn't handle up to here are an error
6451 self.invalid_types_error(operand1, op, operand2)
6452 new_common_type = error_type
6454 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6455 isinstance(operand2, BytesNode)):
6456 # special case when comparing char* to bytes literal: must
6457 # compare string values!
6458 new_common_type = bytes_type
6460 # recursively merge types
6461 if common_type is None or new_common_type.is_error:
6462 common_type = new_common_type
6464 # we could do a lot better by splitting the comparison
6465 # into a non-Python part and a Python part, but this is
6467 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6470 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6474 def invalid_types_error(self, operand1, op, operand2):
6475 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6476 (op, operand1.type, operand2.type))
6478 def is_python_comparison(self):
6479 return (not self.is_ptr_contains()
6480 and not self.is_c_string_contains()
6481 and (self.has_python_operands()
6482 or (self.cascade and self.cascade.is_python_comparison())
6483 or self.operator in ('in', 'not_in')))
6485 def coerce_operands_to(self, dst_type, env):
6486 operand2 = self.operand2
6487 if operand2.type != dst_type:
6488 self.operand2 = operand2.coerce_to(dst_type, env)
6490 self.cascade.coerce_operands_to(dst_type, env)
6492 def is_python_result(self):
6493 return ((self.has_python_operands() and
6494 self.special_bool_cmp_function is None and
6495 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6496 not self.is_c_string_contains() and
6497 not self.is_ptr_contains())
6498 or (self.cascade and self.cascade.is_python_result()))
6500 def is_c_string_contains(self):
6501 return self.operator in ('in', 'not_in') and \
6502 ((self.operand1.type.is_int
6503 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6504 (self.operand1.type is PyrexTypes.c_py_unicode_type
6505 and self.operand2.type is unicode_type))
6507 def is_ptr_contains(self):
6508 if self.operator in ('in', 'not_in'):
6509 container_type = self.operand2.type
6510 return (container_type.is_ptr or container_type.is_array) \
6511 and not container_type.is_string
6513 def find_special_bool_compare_function(self, env):
6514 if self.operator in ('==', '!='):
6515 type1, type2 = self.operand1.type, self.operand2.type
6516 if type1.is_pyobject and type2.is_pyobject:
6517 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6518 env.use_utility_code(pyunicode_equals_utility_code)
6519 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6523 def generate_operation_code(self, code, result_code,
6524 operand1, op , operand2):
6525 if self.type.is_pyobject:
6526 coerce_result = "__Pyx_PyBool_FromLong"
6533 if self.special_bool_cmp_function:
6534 if operand1.type.is_pyobject:
6535 result1 = operand1.py_result()
6537 result1 = operand1.result()
6538 if operand2.type.is_pyobject:
6539 result2 = operand2.py_result()
6541 result2 = operand2.result()
6542 code.putln("%s = %s(%s, %s, %s); %s" % (
6544 self.special_bool_cmp_function,
6547 richcmp_constants[op],
6548 code.error_goto_if_neg(result_code, self.pos)))
6549 elif op == 'in' or op == 'not_in':
6550 code.globalstate.use_utility_code(contains_utility_code)
6551 if self.type.is_pyobject:
6552 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6554 negation = "__Pyx_NegateNonNeg"
6555 if operand2.type is dict_type:
6556 method = "PyDict_Contains"
6558 method = "PySequence_Contains"
6559 if self.type.is_pyobject:
6560 error_clause = code.error_goto_if_null
6561 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6563 error_clause = code.error_goto_if_neg
6566 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6571 operand2.py_result(),
6572 operand1.py_result(),
6574 error_clause(result_code, self.pos)))
6575 elif (operand1.type.is_pyobject
6576 and op not in ('is', 'is_not')):
6577 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6579 operand1.py_result(),
6580 operand2.py_result(),
6581 richcmp_constants[op],
6582 code.error_goto_if_null(result_code, self.pos)))
6583 code.put_gotref(result_code)
6584 elif operand1.type.is_complex:
6589 code.putln("%s = %s(%s%s(%s, %s));" % (
6593 operand1.type.unary_op('eq'),
6597 type1 = operand1.type
6598 type2 = operand2.type
6599 if (type1.is_extension_type or type2.is_extension_type) \
6600 and not type1.same_as(type2):
6601 common_type = py_object_type
6602 elif type1.is_numeric:
6603 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6606 code1 = operand1.result_as(common_type)
6607 code2 = operand2.result_as(common_type)
6608 code.putln("%s = %s(%s %s %s);" % (
6612 self.c_operator(op),
6615 def c_operator(self, op):
6618 elif op == 'is_not':
6623 contains_utility_code = UtilityCode(
6625 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6626 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6627 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6631 char_in_bytes_utility_code = UtilityCode(
6633 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6636 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6637 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6638 char* char_start = PyBytes_AS_STRING(bytes);
6640 for (pos=char_start; pos < char_start+length; pos++) {
6641 if (character == pos[0]) return 1;
6647 pyunicode_in_unicode_utility_code = UtilityCode(
6649 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6652 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6653 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6654 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6656 for (pos=char_start; pos < char_start+length; pos++) {
6657 if (character == pos[0]) return 1;
6663 pyunicode_equals_utility_code = UtilityCode(
6665 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6668 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6669 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6670 return (equals == Py_EQ);
6671 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6672 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6673 return (equals == Py_NE);
6674 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6675 if (equals == Py_EQ)
6676 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6678 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6680 int result = PyUnicode_Compare(s1, s2);
6681 if ((result == -1) && unlikely(PyErr_Occurred()))
6683 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6685 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6686 return (equals == Py_EQ);
6687 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6688 return (equals == Py_NE);
6689 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6690 return (equals == Py_NE);
6693 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6696 result = __Pyx_PyObject_IsTrue(py_result);
6697 Py_DECREF(py_result);
6704 class PrimaryCmpNode(ExprNode, CmpNode):
6705 # Non-cascaded comparison or first comparison of
6706 # a cascaded sequence.
6711 # cascade CascadedCmpNode
6713 # We don't use the subexprs mechanism, because
6714 # things here are too complicated for it to handle.
6715 # Instead, we override all the framework methods
6718 child_attrs = ['operand1', 'operand2', 'cascade']
6722 def infer_type(self, env):
6723 # TODO: Actually implement this (after merging with -unstable).
6724 return py_object_type
6726 def type_dependencies(self, env):
6729 def calculate_constant_result(self):
6730 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6732 def compile_time_value(self, denv):
6733 operand1 = self.operand1.compile_time_value(denv)
6734 return self.cascaded_compile_time_value(operand1, denv)
6736 def analyse_types(self, env):
6737 self.operand1.analyse_types(env)
6738 self.operand2.analyse_types(env)
6739 if self.is_cpp_comparison():
6740 self.analyse_cpp_comparison(env)
6742 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6745 self.cascade.analyse_types(env)
6747 if self.operator in ('in', 'not_in'):
6748 if self.is_c_string_contains():
6749 self.is_pycmp = False
6752 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6754 if self.operand2.type is unicode_type:
6755 env.use_utility_code(pyunicode_in_unicode_utility_code)
6757 if self.operand1.type is PyrexTypes.c_uchar_type:
6758 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6759 if self.operand2.type is not bytes_type:
6760 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6761 env.use_utility_code(char_in_bytes_utility_code)
6762 self.operand2 = self.operand2.as_none_safe_node(
6763 "argument of type 'NoneType' is not iterable")
6764 elif self.is_ptr_contains():
6766 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6767 self.type = PyrexTypes.c_bint_type
6768 # Will be transformed by IterationTransform
6771 if self.operand2.type is dict_type:
6772 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6773 common_type = py_object_type
6774 self.is_pycmp = True
6775 elif self.find_special_bool_compare_function(env):
6776 common_type = None # if coercion needed, the method call above has already done it
6777 self.is_pycmp = False # result is bint
6778 self.is_temp = True # must check for error return
6780 common_type = self.find_common_type(env, self.operator, self.operand1)
6781 self.is_pycmp = common_type.is_pyobject
6783 if common_type is not None and not common_type.is_error:
6784 if self.operand1.type != common_type:
6785 self.operand1 = self.operand1.coerce_to(common_type, env)
6786 self.coerce_operands_to(common_type, env)
6789 self.operand2 = self.operand2.coerce_to_simple(env)
6790 self.cascade.coerce_cascaded_operands_to_temp(env)
6791 if self.is_python_result():
6792 self.type = PyrexTypes.py_object_type
6794 self.type = PyrexTypes.c_bint_type
6797 cdr.type = self.type
6799 if self.is_pycmp or self.cascade:
6802 def analyse_cpp_comparison(self, env):
6803 type1 = self.operand1.type
6804 type2 = self.operand2.type
6805 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6807 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6808 (self.operator, type1, type2))
6809 self.type = PyrexTypes.error_type
6810 self.result_code = "<error>"
6812 func_type = entry.type
6813 if func_type.is_ptr:
6814 func_type = func_type.base_type
6815 if len(func_type.args) == 1:
6816 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6818 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6819 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6820 self.type = func_type.return_type
6822 def has_python_operands(self):
6823 return (self.operand1.type.is_pyobject
6824 or self.operand2.type.is_pyobject)
6826 def check_const(self):
6831 return self.operand1.check_const() and self.operand2.check_const()
6833 def calculate_result_code(self):
6834 if self.operand1.type.is_complex:
6835 if self.operator == "!=":
6839 return "(%s%s(%s, %s))" % (
6841 self.operand1.type.binary_op('=='),
6842 self.operand1.result(),
6843 self.operand2.result())
6844 elif self.is_c_string_contains():
6845 if self.operand2.type is bytes_type:
6846 method = "__Pyx_BytesContains"
6848 method = "__Pyx_UnicodeContains"
6849 if self.operator == "not_in":
6853 return "(%s%s(%s, %s))" % (
6856 self.operand2.result(),
6857 self.operand1.result())
6859 return "(%s %s %s)" % (
6860 self.operand1.result(),
6861 self.c_operator(self.operator),
6862 self.operand2.result())
6864 def generate_evaluation_code(self, code):
6865 self.operand1.generate_evaluation_code(code)
6866 self.operand2.generate_evaluation_code(code)
6868 self.allocate_temp_result(code)
6869 self.generate_operation_code(code, self.result(),
6870 self.operand1, self.operator, self.operand2)
6872 self.cascade.generate_evaluation_code(code,
6873 self.result(), self.operand2)
6874 self.operand1.generate_disposal_code(code)
6875 self.operand1.free_temps(code)
6876 self.operand2.generate_disposal_code(code)
6877 self.operand2.free_temps(code)
6879 def generate_subexpr_disposal_code(self, code):
6880 # If this is called, it is a non-cascaded cmp,
6881 # so only need to dispose of the two main operands.
6882 self.operand1.generate_disposal_code(code)
6883 self.operand2.generate_disposal_code(code)
6885 def free_subexpr_temps(self, code):
6886 # If this is called, it is a non-cascaded cmp,
6887 # so only need to dispose of the two main operands.
6888 self.operand1.free_temps(code)
6889 self.operand2.free_temps(code)
6891 def annotate(self, code):
6892 self.operand1.annotate(code)
6893 self.operand2.annotate(code)
6895 self.cascade.annotate(code)
6898 class CascadedCmpNode(Node, CmpNode):
6899 # A CascadedCmpNode is not a complete expression node. It
6900 # hangs off the side of another comparison node, shares
6901 # its left operand with that node, and shares its result
6902 # with the PrimaryCmpNode at the head of the chain.
6906 # cascade CascadedCmpNode
6908 child_attrs = ['operand2', 'cascade']
6911 constant_result = constant_value_not_set # FIXME: where to calculate this?
6913 def infer_type(self, env):
6914 # TODO: Actually implement this (after merging with -unstable).
6915 return py_object_type
6917 def type_dependencies(self, env):
6920 def has_constant_result(self):
6921 return self.constant_result is not constant_value_not_set and \
6922 self.constant_result is not not_a_constant
6924 def analyse_types(self, env):
6925 self.operand2.analyse_types(env)
6927 self.cascade.analyse_types(env)
6929 def has_python_operands(self):
6930 return self.operand2.type.is_pyobject
6932 def coerce_operands_to_pyobjects(self, env):
6933 self.operand2 = self.operand2.coerce_to_pyobject(env)
6934 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
6935 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6937 self.cascade.coerce_operands_to_pyobjects(env)
6939 def coerce_cascaded_operands_to_temp(self, env):
6941 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6942 self.operand2 = self.operand2.coerce_to_simple(env)
6943 self.cascade.coerce_cascaded_operands_to_temp(env)
6945 def generate_evaluation_code(self, code, result, operand1):
6946 if self.type.is_pyobject:
6947 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
6948 code.put_decref(result, self.type)
6950 code.putln("if (%s) {" % result)
6951 self.operand2.generate_evaluation_code(code)
6952 self.generate_operation_code(code, result,
6953 operand1, self.operator, self.operand2)
6955 self.cascade.generate_evaluation_code(
6956 code, result, self.operand2)
6957 # Cascaded cmp result is always temp
6958 self.operand2.generate_disposal_code(code)
6959 self.operand2.free_temps(code)
6962 def annotate(self, code):
6963 self.operand2.annotate(code)
6965 self.cascade.annotate(code)
6968 binop_node_classes = {
6969 "or": BoolBinopNode,
6970 "and": BoolBinopNode,
6985 def binop_node(pos, operator, operand1, operand2, inplace=False):
6986 # Construct binop node of appropriate class for
6988 return binop_node_classes[operator](pos,
6989 operator = operator,
6990 operand1 = operand1,
6991 operand2 = operand2,
6994 #-------------------------------------------------------------------
6998 # Coercion nodes are special in that they are created during
6999 # the analyse_types phase of parse tree processing.
7000 # Their __init__ methods consequently incorporate some aspects
7003 #-------------------------------------------------------------------
7005 class CoercionNode(ExprNode):
7006 # Abstract base class for coercion nodes.
7008 # arg ExprNode node being coerced
7011 constant_result = not_a_constant
7013 def __init__(self, arg):
7017 print("%s Coercing %s" % (self, self.arg))
7019 def calculate_constant_result(self):
7020 # constant folding can break type coercion, so this is disabled
7023 def annotate(self, code):
7024 self.arg.annotate(code)
7025 if self.arg.type != self.type:
7026 file, line, col = self.pos
7027 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
7030 class CastNode(CoercionNode):
7031 # Wrap a node in a C type cast.
7033 def __init__(self, arg, new_type):
7034 CoercionNode.__init__(self, arg)
7035 self.type = new_type
7037 def may_be_none(self):
7038 return self.arg.may_be_none()
7040 def calculate_result_code(self):
7041 return self.arg.result_as(self.type)
7043 def generate_result_code(self, code):
7044 self.arg.generate_result_code(code)
7047 class PyTypeTestNode(CoercionNode):
7048 # This node is used to check that a generic Python
7049 # object is an instance of a particular extension type.
7050 # This node borrows the result of its argument node.
7052 def __init__(self, arg, dst_type, env, notnone=False):
7053 # The arg is know to be a Python object, and
7054 # the dst_type is known to be an extension type.
7055 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
7056 CoercionNode.__init__(self, arg)
7057 self.type = dst_type
7058 self.result_ctype = arg.ctype()
7059 self.notnone = notnone
7061 nogil_check = Node.gil_error
7062 gil_message = "Python type test"
7064 def analyse_types(self, env):
7067 def may_be_none(self):
7070 return self.arg.may_be_none()
7072 def result_in_temp(self):
7073 return self.arg.result_in_temp()
7075 def is_ephemeral(self):
7076 return self.arg.is_ephemeral()
7078 def calculate_constant_result(self):
7082 def calculate_result_code(self):
7083 return self.arg.result()
7085 def generate_result_code(self, code):
7086 if self.type.typeobj_is_available():
7087 if not self.type.is_builtin_type:
7088 code.globalstate.use_utility_code(type_test_utility_code)
7091 self.type.type_test_code(self.arg.py_result(), self.notnone),
7092 code.error_goto(self.pos)))
7094 error(self.pos, "Cannot test type of extern C class "
7095 "without type object name specification")
7097 def generate_post_assignment_code(self, code):
7098 self.arg.generate_post_assignment_code(code)
7100 def free_temps(self, code):
7101 self.arg.free_temps(code)
7104 class NoneCheckNode(CoercionNode):
7105 # This node is used to check that a Python object is not None and
7106 # raises an appropriate exception (as specified by the creating
7109 def __init__(self, arg, exception_type_cname, exception_message):
7110 CoercionNode.__init__(self, arg)
7111 self.type = arg.type
7112 self.result_ctype = arg.ctype()
7113 self.exception_type_cname = exception_type_cname
7114 self.exception_message = exception_message
7116 def analyse_types(self, env):
7119 def may_be_none(self):
7122 def result_in_temp(self):
7123 return self.arg.result_in_temp()
7125 def calculate_result_code(self):
7126 return self.arg.result()
7128 def generate_result_code(self, code):
7130 "if (unlikely(%s == Py_None)) {" % self.arg.result())
7131 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
7132 self.exception_type_cname,
7133 StringEncoding.escape_byte_string(
7134 self.exception_message.encode('UTF-8')),
7135 code.error_goto(self.pos)))
7138 def generate_post_assignment_code(self, code):
7139 self.arg.generate_post_assignment_code(code)
7141 def free_temps(self, code):
7142 self.arg.free_temps(code)
7145 class CoerceToPyTypeNode(CoercionNode):
7146 # This node is used to convert a C data type
7147 # to a Python object.
7149 type = py_object_type
7152 def __init__(self, arg, env, type=py_object_type):
7153 CoercionNode.__init__(self, arg)
7154 if not arg.type.create_to_py_utility_code(env):
7156 "Cannot convert '%s' to Python object" % arg.type)
7157 if type is py_object_type:
7158 # be specific about some known types
7159 if arg.type.is_string:
7160 self.type = bytes_type
7161 elif arg.type is PyrexTypes.c_py_unicode_type:
7162 self.type = unicode_type
7163 elif arg.type.is_complex:
7164 self.type = Builtin.complex_type
7166 # FIXME: check that the target type and the resulting type are compatible
7169 gil_message = "Converting to Python object"
7171 def may_be_none(self):
7172 # FIXME: is this always safe?
7175 def coerce_to_boolean(self, env):
7176 arg_type = self.arg.type
7177 if (arg_type == PyrexTypes.c_bint_type or
7178 (arg_type.is_pyobject and arg_type.name == 'bool')):
7179 return self.arg.coerce_to_temp(env)
7181 return CoerceToBooleanNode(self, env)
7183 def coerce_to_integer(self, env):
7184 # If not already some C integer type, coerce to longint.
7185 if self.arg.type.is_int:
7188 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7190 def analyse_types(self, env):
7191 # The arg is always already analysed
7194 def generate_result_code(self, code):
7195 function = self.arg.type.to_py_function
7196 code.putln('%s = %s(%s); %s' % (
7200 code.error_goto_if_null(self.result(), self.pos)))
7201 code.put_gotref(self.py_result())
7204 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7205 # This node is used to convert a C int type to a Python bytes
7210 def __init__(self, arg, env):
7211 arg = arg.coerce_to_simple(env)
7212 CoercionNode.__init__(self, arg)
7213 self.type = Builtin.bytes_type
7215 def generate_result_code(self, code):
7217 arg_result = arg.result()
7218 if arg.type not in (PyrexTypes.c_char_type,
7219 PyrexTypes.c_uchar_type,
7220 PyrexTypes.c_schar_type):
7222 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7223 arg_result, arg_result))
7225 code.putln("if (%s > 255) {" % arg_result)
7226 code.putln('PyErr_Format(PyExc_OverflowError, '
7227 '"value too large to pack into a byte"); %s' % (
7228 code.error_goto(self.pos)))
7231 if arg.type is not PyrexTypes.c_char_type:
7232 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7233 code.putln("%s = (char)%s;" % (temp, arg_result))
7235 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7238 code.error_goto_if_null(self.result(), self.pos)))
7239 if temp is not None:
7240 code.funcstate.release_temp(temp)
7241 code.put_gotref(self.py_result())
7244 class CoerceFromPyTypeNode(CoercionNode):
7245 # This node is used to convert a Python object
7248 def __init__(self, result_type, arg, env):
7249 CoercionNode.__init__(self, arg)
7250 self.type = result_type
7252 if not result_type.create_from_py_utility_code(env):
7254 "Cannot convert Python object to '%s'" % result_type)
7255 if self.type.is_string and self.arg.is_ephemeral():
7257 "Obtaining char * from temporary Python value")
7259 def analyse_types(self, env):
7260 # The arg is always already analysed
7263 def generate_result_code(self, code):
7264 function = self.type.from_py_function
7265 operand = self.arg.py_result()
7266 rhs = "%s(%s)" % (function, operand)
7267 if self.type.is_enum:
7268 rhs = typecast(self.type, c_long_type, rhs)
7269 code.putln('%s = %s; %s' % (
7272 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7273 if self.type.is_pyobject:
7274 code.put_gotref(self.py_result())
7277 class CoerceToBooleanNode(CoercionNode):
7278 # This node is used when a result needs to be used
7279 # in a boolean context.
7281 type = PyrexTypes.c_bint_type
7283 _special_builtins = {
7284 Builtin.list_type : 'PyList_GET_SIZE',
7285 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7286 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7287 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7290 def __init__(self, arg, env):
7291 CoercionNode.__init__(self, arg)
7292 if arg.type.is_pyobject:
7295 def nogil_check(self, env):
7296 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7299 gil_message = "Truth-testing Python object"
7301 def check_const(self):
7305 return self.arg.check_const()
7307 def calculate_result_code(self):
7308 return "(%s != 0)" % self.arg.result()
7310 def generate_result_code(self, code):
7311 if not self.is_temp:
7313 test_func = self._special_builtins.get(self.arg.type)
7314 if test_func is not None:
7315 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7317 self.arg.py_result(),
7319 self.arg.py_result()))
7322 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7324 self.arg.py_result(),
7325 code.error_goto_if_neg(self.result(), self.pos)))
7327 class CoerceToComplexNode(CoercionNode):
7329 def __init__(self, arg, dst_type, env):
7330 if arg.type.is_complex:
7331 arg = arg.coerce_to_simple(env)
7332 self.type = dst_type
7333 CoercionNode.__init__(self, arg)
7334 dst_type.create_declaration_utility_code(env)
7336 def calculate_result_code(self):
7337 if self.arg.type.is_complex:
7338 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7339 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7341 real_part = self.arg.result()
7343 return "%s(%s, %s)" % (
7344 self.type.from_parts,
7348 def generate_result_code(self, code):
7351 class CoerceToTempNode(CoercionNode):
7352 # This node is used to force the result of another node
7353 # to be stored in a temporary. It is only used if the
7354 # argument node's result is not already in a temporary.
7356 def __init__(self, arg, env):
7357 CoercionNode.__init__(self, arg)
7358 self.type = self.arg.type
7359 self.constant_result = self.arg.constant_result
7361 if self.type.is_pyobject:
7362 self.result_ctype = py_object_type
7364 gil_message = "Creating temporary Python reference"
7366 def analyse_types(self, env):
7367 # The arg is always already analysed
7370 def coerce_to_boolean(self, env):
7371 self.arg = self.arg.coerce_to_boolean(env)
7372 if self.arg.is_simple():
7374 self.type = self.arg.type
7375 self.result_ctype = self.type
7378 def generate_result_code(self, code):
7379 #self.arg.generate_evaluation_code(code) # Already done
7380 # by generic generate_subexpr_evaluation_code!
7381 code.putln("%s = %s;" % (
7382 self.result(), self.arg.result_as(self.ctype())))
7383 if self.type.is_pyobject and self.use_managed_ref:
7384 code.put_incref(self.result(), self.ctype())
7387 class CloneNode(CoercionNode):
7388 # This node is employed when the result of another node needs
7389 # to be used multiple times. The argument node's result must
7390 # be in a temporary. This node "borrows" the result from the
7391 # argument node, and does not generate any evaluation or
7392 # disposal code for it. The original owner of the argument
7393 # node is responsible for doing those things.
7395 subexprs = [] # Arg is not considered a subexpr
7398 def __init__(self, arg):
7399 CoercionNode.__init__(self, arg)
7400 if hasattr(arg, 'type'):
7401 self.type = arg.type
7402 self.result_ctype = arg.result_ctype
7403 if hasattr(arg, 'entry'):
7404 self.entry = arg.entry
7407 return self.arg.result()
7409 def type_dependencies(self, env):
7410 return self.arg.type_dependencies(env)
7412 def infer_type(self, env):
7413 return self.arg.infer_type(env)
7415 def analyse_types(self, env):
7416 self.type = self.arg.type
7417 self.result_ctype = self.arg.result_ctype
7419 if hasattr(self.arg, 'entry'):
7420 self.entry = self.arg.entry
7422 def generate_evaluation_code(self, code):
7425 def generate_result_code(self, code):
7428 def generate_disposal_code(self, code):
7431 def free_temps(self, code):
7435 class ModuleRefNode(ExprNode):
7436 # Simple returns the module object
7438 type = py_object_type
7442 def analyse_types(self, env):
7445 def may_be_none(self):
7448 def calculate_result_code(self):
7449 return Naming.module_cname
7451 def generate_result_code(self, code):
7454 class DocstringRefNode(ExprNode):
7455 # Extracts the docstring of the body element
7458 type = py_object_type
7461 def __init__(self, pos, body):
7462 ExprNode.__init__(self, pos)
7463 assert body.type.is_pyobject
7466 def analyse_types(self, env):
7469 def generate_result_code(self, code):
7470 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7471 self.result(), self.body.result(),
7472 code.error_goto_if_null(self.result(), self.pos)))
7473 code.put_gotref(self.result())
7477 #------------------------------------------------------------------------------------
7479 # Runtime support code
7481 #------------------------------------------------------------------------------------
7483 get_name_interned_utility_code = UtilityCode(
7485 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7488 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7490 result = PyObject_GetAttr(dict, name);
7492 PyErr_SetObject(PyExc_NameError, name);
7497 #------------------------------------------------------------------------------------
7499 import_utility_code = UtilityCode(
7501 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7504 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7505 PyObject *py_import = 0;
7506 PyObject *empty_list = 0;
7507 PyObject *module = 0;
7508 PyObject *global_dict = 0;
7509 PyObject *empty_dict = 0;
7511 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7517 empty_list = PyList_New(0);
7522 global_dict = PyModule_GetDict(%(GLOBALS)s);
7525 empty_dict = PyDict_New();
7528 module = PyObject_CallFunctionObjArgs(py_import,
7529 name, global_dict, empty_dict, list, NULL);
7531 Py_XDECREF(empty_list);
7532 Py_XDECREF(py_import);
7533 Py_XDECREF(empty_dict);
7537 "BUILTINS": Naming.builtins_cname,
7538 "GLOBALS": Naming.module_cname,
7541 #------------------------------------------------------------------------------------
7543 get_exception_utility_code = UtilityCode(
7545 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7548 static PyObject *__Pyx_GetExcValue(void) {
7549 PyObject *type = 0, *value = 0, *tb = 0;
7550 PyObject *tmp_type, *tmp_value, *tmp_tb;
7551 PyObject *result = 0;
7552 PyThreadState *tstate = PyThreadState_Get();
7553 PyErr_Fetch(&type, &value, &tb);
7554 PyErr_NormalizeException(&type, &value, &tb);
7555 if (PyErr_Occurred())
7561 tmp_type = tstate->exc_type;
7562 tmp_value = tstate->exc_value;
7563 tmp_tb = tstate->exc_traceback;
7564 tstate->exc_type = type;
7565 tstate->exc_value = value;
7566 tstate->exc_traceback = tb;
7567 /* Make sure tstate is in a consistent state when we XDECREF
7568 these objects (XDECREF may run arbitrary code). */
7569 Py_XDECREF(tmp_type);
7570 Py_XDECREF(tmp_value);
7585 #------------------------------------------------------------------------------------
7587 type_test_utility_code = UtilityCode(
7589 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7592 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7593 if (unlikely(!type)) {
7594 PyErr_Format(PyExc_SystemError, "Missing type object");
7597 if (likely(PyObject_TypeCheck(obj, type)))
7599 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7600 Py_TYPE(obj)->tp_name, type->tp_name);
7605 #------------------------------------------------------------------------------------
7607 find_py2_metaclass_utility_code = UtilityCode(
7609 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7612 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7613 PyObject *metaclass;
7614 /* Default metaclass */
7615 #if PY_MAJOR_VERSION < 3
7616 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7617 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7618 metaclass = PyObject_GetAttrString(base, "__class__");
7621 metaclass = (PyObject*) Py_TYPE(base);
7624 metaclass = (PyObject *) &PyClass_Type;
7627 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7628 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7629 metaclass = (PyObject*) Py_TYPE(base);
7631 metaclass = (PyObject *) &PyType_Type;
7634 Py_INCREF(metaclass);
7639 create_class_utility_code = UtilityCode(
7641 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7642 PyObject *modname); /*proto*/
7645 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7646 PyObject *modname) {
7648 PyObject *metaclass;
7650 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7653 /* Python2 __metaclass__ */
7654 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7656 Py_INCREF(metaclass);
7658 metaclass = __Pyx_FindPy2Metaclass(bases);
7660 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7661 Py_DECREF(metaclass);
7665 requires = [find_py2_metaclass_utility_code])
7667 #------------------------------------------------------------------------------------
7669 create_py3class_utility_code = UtilityCode(
7671 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7672 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7673 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7676 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7677 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7679 Py_INCREF(metaclass);
7680 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7681 Py_DECREF(metaclass);
7686 return __Pyx_FindPy2Metaclass(bases);
7689 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7690 PyObject *modname, PyObject *doc) {
7696 prep = PyObject_GetAttrString(metaclass, "__prepare__");
7698 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7701 return PyDict_New();
7703 pargs = PyTuple_New(2);
7711 PyTuple_SET_ITEM(pargs, 0, name);
7712 PyTuple_SET_ITEM(pargs, 1, bases);
7714 ns = PyObject_Call(prep, pargs, mkw);
7722 /* Required here to emulate assignment order */
7723 /* XXX: use consts here */
7724 #if PY_MAJOR_VERSION >= 3
7725 str = PyUnicode_FromString("__module__");
7727 str = PyString_FromString("__module__");
7734 if (PyObject_SetItem(ns, str, modname) < 0) {
7741 #if PY_MAJOR_VERSION >= 3
7742 str = PyUnicode_FromString("__doc__");
7744 str = PyString_FromString("__doc__");
7750 if (PyObject_SetItem(ns, str, doc) < 0) {
7760 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7762 PyObject *margs = PyTuple_New(3);
7768 PyTuple_SET_ITEM(margs, 0, name);
7769 PyTuple_SET_ITEM(margs, 1, bases);
7770 PyTuple_SET_ITEM(margs, 2, dict);
7771 result = PyObject_Call(metaclass, margs, mkw);
7776 requires = [find_py2_metaclass_utility_code])
7778 #------------------------------------------------------------------------------------
7780 cpp_exception_utility_code = UtilityCode(
7782 #ifndef __Pyx_CppExn2PyErr
7783 static void __Pyx_CppExn2PyErr() {
7785 if (PyErr_Occurred())
7786 ; // let the latest Python exn pass through and ignore the current one
7789 } catch (const std::invalid_argument& exn) {
7790 // Catch a handful of different errors here and turn them into the
7791 // equivalent Python errors.
7792 // Change invalid_argument to ValueError
7793 PyErr_SetString(PyExc_ValueError, exn.what());
7794 } catch (const std::out_of_range& exn) {
7795 // Change out_of_range to IndexError
7796 PyErr_SetString(PyExc_IndexError, exn.what());
7797 } catch (const std::exception& exn) {
7798 PyErr_SetString(PyExc_RuntimeError, exn.what());
7802 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7810 pyerr_occurred_withgil_utility_code= UtilityCode(
7812 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7815 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7818 PyGILState_STATE _save = PyGILState_Ensure();
7820 err = !!PyErr_Occurred();
7822 PyGILState_Release(_save);
7829 #------------------------------------------------------------------------------------
7831 raise_noneattr_error_utility_code = UtilityCode(
7833 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7836 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7837 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7841 raise_noneindex_error_utility_code = UtilityCode(
7843 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7846 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7847 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7851 raise_none_iter_error_utility_code = UtilityCode(
7853 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7856 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7857 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7861 #------------------------------------------------------------------------------------
7863 getitem_dict_utility_code = UtilityCode(
7865 #if PY_MAJOR_VERSION >= 3
7866 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7868 if (unlikely(d == Py_None)) {
7869 __Pyx_RaiseNoneIndexingError();
7872 value = PyDict_GetItemWithError(d, key);
7873 if (unlikely(!value)) {
7874 if (!PyErr_Occurred())
7875 PyErr_SetObject(PyExc_KeyError, key);
7882 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7885 requires = [raise_noneindex_error_utility_code])
7887 #------------------------------------------------------------------------------------
7889 getitem_int_pyunicode_utility_code = UtilityCode(
7891 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7892 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7893 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7895 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7896 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7897 return PyUnicode_AS_UNICODE(ustring)[i];
7898 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7899 i += PyUnicode_GET_SIZE(ustring);
7900 return PyUnicode_AS_UNICODE(ustring)[i];
7902 PyErr_SetString(PyExc_IndexError, "string index out of range");
7903 return (Py_UNICODE)-1;
7907 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7909 PyObject *uchar_string;
7910 if (!j) return (Py_UNICODE)-1;
7911 uchar_string = PyObject_GetItem(ustring, j);
7913 if (!uchar_string) return (Py_UNICODE)-1;
7914 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7915 Py_DECREF(uchar_string);
7920 getitem_int_utility_code = UtilityCode(
7923 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7925 if (!j) return NULL;
7926 r = PyObject_GetItem(o, j);
7933 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7934 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7935 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7937 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
7938 if (likely(o != Py_None)) {
7939 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
7940 PyObject *r = Py%(type)s_GET_ITEM(o, i);
7944 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
7945 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
7950 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7952 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
7955 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7956 __Pyx_GetItemInt_Fast(o, i) : \\
7957 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7959 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
7961 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7962 r = PyList_GET_ITEM(o, i);
7965 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
7966 r = PyTuple_GET_ITEM(o, i);
7969 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
7970 r = PySequence_GetItem(o, i);
7973 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7983 #------------------------------------------------------------------------------------
7985 setitem_int_utility_code = UtilityCode(
7987 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7988 __Pyx_SetItemInt_Fast(o, i, v) : \\
7989 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
7991 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
7994 r = PyObject_SetItem(o, j, v);
7999 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
8000 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8002 Py_DECREF(PyList_GET_ITEM(o, i));
8003 PyList_SET_ITEM(o, i, v);
8006 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
8007 return PySequence_SetItem(o, i, v);
8009 PyObject *j = PyInt_FromSsize_t(i);
8010 return __Pyx_SetItemInt_Generic(o, j, v);
8017 #------------------------------------------------------------------------------------
8019 delitem_int_utility_code = UtilityCode(
8021 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8022 __Pyx_DelItemInt_Fast(o, i) : \\
8023 __Pyx_DelItem_Generic(o, to_py_func(i)))
8025 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8028 r = PyObject_DelItem(o, j);
8033 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8034 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
8035 return PySequence_DelItem(o, i);
8037 PyObject *j = PyInt_FromSsize_t(i);
8038 return __Pyx_DelItem_Generic(o, j);
8045 #------------------------------------------------------------------------------------
8047 raise_too_many_values_to_unpack = UtilityCode(
8049 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8052 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
8053 PyErr_Format(PyExc_ValueError,
8054 #if PY_VERSION_HEX < 0x02050000
8055 "too many values to unpack (expected %d)", (int)expected);
8057 "too many values to unpack (expected %zd)", expected);
8062 raise_need_more_values_to_unpack = UtilityCode(
8064 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8067 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8068 PyErr_Format(PyExc_ValueError,
8069 #if PY_VERSION_HEX < 0x02050000
8070 "need more than %d value%s to unpack", (int)index,
8072 "need more than %zd value%s to unpack", index,
8074 (index == 1) ? "" : "s");
8078 #------------------------------------------------------------------------------------
8080 tuple_unpacking_error_code = UtilityCode(
8082 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8085 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
8087 __Pyx_RaiseNoneNotIterableError();
8088 } else if (PyTuple_GET_SIZE(t) < index) {
8089 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
8091 __Pyx_RaiseTooManyValuesError(index);
8095 requires = [raise_none_iter_error_utility_code,
8096 raise_need_more_values_to_unpack,
8097 raise_too_many_values_to_unpack]
8100 unpacking_utility_code = UtilityCode(
8102 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8103 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8106 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
8108 if (!(item = PyIter_Next(iter))) {
8109 if (!PyErr_Occurred()) {
8110 __Pyx_RaiseNeedMoreValuesError(index);
8116 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8118 if ((item = PyIter_Next(iter))) {
8120 __Pyx_RaiseTooManyValuesError(expected);
8123 else if (!PyErr_Occurred())
8129 requires = [raise_need_more_values_to_unpack,
8130 raise_too_many_values_to_unpack]
8133 #------------------------------------------------------------------------------------
8135 # CPython supports calling functions with non-dict kwargs by
8136 # converting them to a dict first
8138 kwargs_call_utility_code = UtilityCode(
8140 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
8143 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
8145 if (likely(PyDict_Check(kwargs))) {
8146 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
8148 PyObject* real_dict;
8149 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
8150 if (unlikely(!real_dict))
8152 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
8153 Py_DECREF(real_dict);
8154 return result; /* may be NULL */
8161 #------------------------------------------------------------------------------------
8163 int_pow_utility_code = UtilityCode(
8165 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8168 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8180 if (unlikely(e<0)) return 0;
8183 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8191 # ------------------------------ Division ------------------------------------
8193 div_int_utility_code = UtilityCode(
8195 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8198 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8200 %(type)s r = a - q*b;
8201 q -= ((r != 0) & ((r ^ b) < 0));
8206 mod_int_utility_code = UtilityCode(
8208 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8211 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8212 %(type)s r = a %% b;
8213 r += ((r != 0) & ((r ^ b) < 0)) * b;
8218 mod_float_utility_code = UtilityCode(
8220 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8223 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8224 %(type)s r = fmod%(math_h_modifier)s(a, b);
8225 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8230 cdivision_warning_utility_code = UtilityCode(
8232 static int __Pyx_cdivision_warning(void); /* proto */
8235 static int __Pyx_cdivision_warning(void) {
8236 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8237 "division with oppositely signed operands, C and Python semantics differ",
8244 'FILENAME': Naming.filename_cname,
8245 'LINENO': Naming.lineno_cname,
8249 division_overflow_test_code = UtilityCode(
8251 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8252 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8256 binding_cfunc_utility_code = UtilityCode(
8258 #define %(binding_cfunc)s_USED 1
8261 PyCFunctionObject func;
8262 } %(binding_cfunc)s_object;
8264 static PyTypeObject %(binding_cfunc)s_type;
8265 static PyTypeObject *%(binding_cfunc)s = NULL;
8267 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8268 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8270 static int %(binding_cfunc)s_init(void); /* proto */
8271 """ % Naming.__dict__,
8274 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8275 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8280 op->func.m_self = self;
8282 op->func.m_module = module;
8283 PyObject_GC_Track(op);
8284 return (PyObject *)op;
8287 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8288 PyObject_GC_UnTrack(m);
8289 Py_XDECREF(m->func.m_self);
8290 Py_XDECREF(m->func.m_module);
8294 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8297 return PyMethod_New(func, obj, type);
8300 static int %(binding_cfunc)s_init(void) {
8301 %(binding_cfunc)s_type = PyCFunction_Type;
8302 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8303 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8304 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8305 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8308 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8312 """ % Naming.__dict__)
8314 generator_utility_code = UtilityCode(
8316 static PyObject *__Pyx_Generator_Next(PyObject *self);
8317 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
8318 static PyObject *__Pyx_Generator_Close(PyObject *self);
8319 static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args, CYTHON_UNUSED PyObject *kwds);
8321 typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
8324 static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_object *self, PyObject *value)
8328 if (self->is_running) {
8329 PyErr_SetString(PyExc_ValueError,
8330 "generator already executing");
8334 if (self->resume_label == 0) {
8335 if (value && value != Py_None) {
8336 PyErr_SetString(PyExc_TypeError,
8337 "can't send non-None value to a "
8338 "just-started generator");
8343 if (self->resume_label == -1) {
8344 PyErr_SetNone(PyExc_StopIteration);
8348 self->is_running = 1;
8349 retval = self->body((PyObject *) self, value);
8350 self->is_running = 0;
8355 static PyObject *__Pyx_Generator_Next(PyObject *self)
8357 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, Py_None);
8360 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value)
8362 return __Pyx_Generator_SendEx((struct __pyx_Generator_object *) self, value);
8365 static PyObject *__Pyx_Generator_Close(PyObject *self)
8367 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8369 #if PY_VERSION_HEX < 0x02050000
8370 PyErr_SetNone(PyExc_StopIteration);
8372 PyErr_SetNone(PyExc_GeneratorExit);
8374 retval = __Pyx_Generator_SendEx(generator, NULL);
8377 PyErr_SetString(PyExc_RuntimeError,
8378 "generator ignored GeneratorExit");
8381 #if PY_VERSION_HEX < 0x02050000
8382 if (PyErr_ExceptionMatches(PyExc_StopIteration))
8384 if (PyErr_ExceptionMatches(PyExc_StopIteration)
8385 || PyErr_ExceptionMatches(PyExc_GeneratorExit))
8388 PyErr_Clear(); /* ignore these errors */
8395 static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args, CYTHON_UNUSED PyObject *kwds)
8397 struct __pyx_Generator_object *generator = (struct __pyx_Generator_object *) self;
8399 PyObject *tb = NULL;
8400 PyObject *val = NULL;
8402 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
8404 __Pyx_Raise(typ, val, tb);
8405 return __Pyx_Generator_SendEx(generator, NULL);
8408 proto_block='utility_code_proto_before_types',
8409 requires=[Nodes.raise_utility_code],