2 # Pyrex - Parse tree nodes for expressions
7 from Errors import error, warning, warn_once, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Code import UtilityCode
13 from Nodes import Node
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
17 from Builtin import list_type, tuple_type, set_type, dict_type, \
18 unicode_type, str_type, bytes_type, type_type
22 from Cython import Utils
23 from Annotate import AnnotationItem
24 from Cython import Utils
26 from Cython.Debugging import print_call_chain
27 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
33 from sets import Set as set
35 class NotConstant(object):
37 return "<NOT CONSTANT>"
39 not_a_constant = NotConstant()
40 constant_value_not_set = object()
42 # error messages when coercing from key[0] to key[1]
43 find_coercion_error = {
44 # string related errors
45 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
46 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
47 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
48 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
49 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
50 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
51 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
52 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
53 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
54 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
59 # subexprs [string] Class var holding names of subexpr node attrs
60 # type PyrexType Type of the result
61 # result_code string Code fragment
62 # result_ctype string C type of result_code if different from type
63 # is_temp boolean Result is in a temporary variable
64 # is_sequence_constructor
65 # boolean Is a list or tuple constructor expression
66 # is_starred boolean Is a starred expression (e.g. '*a')
68 # [ExprNode or [ExprNode or None] or None]
69 # Cached result of subexpr_nodes()
70 # use_managed_ref boolean use ref-counted temps/assignments/etc.
75 old_temp = None # error checker for multiple frees etc.
76 use_managed_ref = True # can be set by optimisation transforms
78 # The Analyse Expressions phase for expressions is split
79 # into two sub-phases:
82 # Determines the result type of the expression based
83 # on the types of its sub-expressions, and inserts
84 # coercion nodes into the expression tree where needed.
85 # Marks nodes which will need to have temporary variables
89 # Allocates temporary variables where needed, and fills
90 # in the result_code field of each node.
92 # ExprNode provides some convenience routines which
93 # perform both of the above phases. These should only
94 # be called from statement nodes, and only when no
95 # coercion nodes need to be added around the expression
96 # being analysed. In that case, the above two phases
97 # should be invoked separately.
99 # Framework code in ExprNode provides much of the common
100 # processing for the various phases. It makes use of the
101 # 'subexprs' class attribute of ExprNodes, which should
102 # contain a list of the names of attributes which can
103 # hold sub-nodes or sequences of sub-nodes.
105 # The framework makes use of a number of abstract methods.
106 # Their responsibilities are as follows.
108 # Declaration Analysis phase
110 # analyse_target_declaration
111 # Called during the Analyse Declarations phase to analyse
112 # the LHS of an assignment or argument of a del statement.
113 # Nodes which cannot be the LHS of an assignment need not
116 # Expression Analysis phase
119 # - Call analyse_types on all sub-expressions.
120 # - Check operand types, and wrap coercion nodes around
121 # sub-expressions where needed.
122 # - Set the type of this node.
123 # - If a temporary variable will be required for the
124 # result, set the is_temp flag of this node.
126 # analyse_target_types
127 # Called during the Analyse Types phase to analyse
128 # the LHS of an assignment or argument of a del
129 # statement. Similar responsibilities to analyse_types.
132 # Called by the default implementation of allocate_target_temps.
133 # Should return a C lvalue for assigning to the node. The default
134 # implementation calls calculate_result_code.
137 # - Check that this node and its subnodes form a
138 # legal constant expression. If so, do nothing,
139 # otherwise call not_const.
141 # The default implementation of check_const
142 # assumes that the expression is not constant.
145 # - Same as check_const, except check that the
146 # expression is a C lvalue whose address is
147 # constant. Otherwise, call addr_not_const.
149 # The default implementation of calc_const_addr
150 # assumes that the expression is not a constant
153 # Code Generation phase
155 # generate_evaluation_code
156 # - Call generate_evaluation_code for sub-expressions.
157 # - Perform the functions of generate_result_code
159 # - If result is temporary, call generate_disposal_code
160 # on all sub-expressions.
162 # A default implementation of generate_evaluation_code
163 # is provided which uses the following abstract methods:
165 # generate_result_code
166 # - Generate any C statements necessary to calculate
167 # the result of this node from the results of its
170 # calculate_result_code
171 # - Should return a C code fragment evaluating to the
172 # result. This is only called when the result is not
175 # generate_assignment_code
176 # Called on the LHS of an assignment.
177 # - Call generate_evaluation_code for sub-expressions.
178 # - Generate code to perform the assignment.
179 # - If the assignment absorbed a reference, call
180 # generate_post_assignment_code on the RHS,
181 # otherwise call generate_disposal_code on it.
183 # generate_deletion_code
184 # Called on an argument of a del statement.
185 # - Call generate_evaluation_code for sub-expressions.
186 # - Generate code to perform the deletion.
187 # - Call generate_disposal_code on all sub-expressions.
191 is_sequence_constructor = 0
194 saved_subexpr_nodes = None
199 constant_result = constant_value_not_set
202 _get_child_attrs = operator.attrgetter('subexprs')
203 except AttributeError:
205 def _get_child_attrs(self):
207 child_attrs = property(fget=_get_child_attrs)
209 def not_implemented(self, method_name):
210 print_call_chain(method_name, "not implemented") ###
212 "%s.%s not implemented" %
213 (self.__class__.__name__, method_name))
218 def is_ephemeral(self):
219 # An ephemeral node is one whose result is in
220 # a Python temporary and we suspect there are no
221 # other references to it. Certain operations are
222 # disallowed on such values, since they are
223 # likely to result in a dangling pointer.
224 return self.type.is_pyobject and self.is_temp
226 def subexpr_nodes(self):
227 # Extract a list of subexpression nodes based
228 # on the contents of the subexprs class attribute.
230 for name in self.subexprs:
231 item = getattr(self, name)
233 if type(item) is list:
241 return self.temp_code
243 return self.calculate_result_code()
245 def result_as(self, type = None):
246 # Return the result code cast to the specified C type.
247 return typecast(type, self.ctype(), self.result())
250 # Return the result code cast to PyObject *.
251 return self.result_as(py_object_type)
254 # Return the native C type of the result (i.e. the
255 # C type of the result_code expression).
256 return self.result_ctype or self.type
258 def get_constant_c_result_code(self):
259 # Return the constant value of this node as a result code
260 # string, or None if the node is not constant. This method
261 # can be called when the constant result code is required
262 # before the code generation phase.
264 # The return value is a string that can represent a simple C
265 # value, a constant C name or a constant C expression. If the
266 # node type depends on Python code, this must return None.
269 def calculate_constant_result(self):
270 # Calculate the constant compile time result value of this
271 # expression and store it in ``self.constant_result``. Does
272 # nothing by default, thus leaving ``self.constant_result``
273 # unknown. If valid, the result can be an arbitrary Python
276 # This must only be called when it is assured that all
277 # sub-expressions have a valid constant_result value. The
278 # ConstantFolding transform will do this.
281 def has_constant_result(self):
282 return self.constant_result is not constant_value_not_set and \
283 self.constant_result is not not_a_constant
285 def compile_time_value(self, denv):
286 # Return value of compile-time expression, or report error.
287 error(self.pos, "Invalid compile-time expression")
289 def compile_time_value_error(self, e):
290 error(self.pos, "Error in compile-time expression: %s: %s" % (
291 e.__class__.__name__, e))
293 # ------------- Declaration Analysis ----------------
295 def analyse_target_declaration(self, env):
296 error(self.pos, "Cannot assign to or delete this")
298 # ------------- Expression Analysis ----------------
300 def analyse_const_expression(self, env):
301 # Called during the analyse_declarations phase of a
302 # constant expression. Analyses the expression's type,
303 # checks whether it is a legal const expression,
304 # and determines its value.
305 self.analyse_types(env)
306 return self.check_const()
308 def analyse_expressions(self, env):
309 # Convenience routine performing both the Type
310 # Analysis and Temp Allocation phases for a whole
312 self.analyse_types(env)
314 def analyse_target_expression(self, env, rhs):
315 # Convenience routine performing both the Type
316 # Analysis and Temp Allocation phases for the LHS of
318 self.analyse_target_types(env)
320 def analyse_boolean_expression(self, env):
321 # Analyse expression and coerce to a boolean.
322 self.analyse_types(env)
323 bool = self.coerce_to_boolean(env)
326 def analyse_temp_boolean_expression(self, env):
327 # Analyse boolean expression and coerce result into
328 # a temporary. This is used when a branch is to be
329 # performed on the result and we won't have an
330 # opportunity to ensure disposal code is executed
331 # afterwards. By forcing the result into a temporary,
332 # we ensure that all disposal has been done by the
333 # time we get the result.
334 self.analyse_types(env)
335 return self.coerce_to_boolean(env).coerce_to_simple(env)
337 # --------------- Type Inference -----------------
339 def type_dependencies(self, env):
340 # Returns the list of entries whose types must be determined
341 # before the type of self can be infered.
342 if hasattr(self, 'type') and self.type is not None:
344 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
346 def infer_type(self, env):
347 # Attempt to deduce the type of self.
348 # Differs from analyse_types as it avoids unnecessary
349 # analysis of subexpressions, but can assume everything
350 # in self.type_dependencies() has been resolved.
351 if hasattr(self, 'type') and self.type is not None:
353 elif hasattr(self, 'entry') and self.entry is not None:
354 return self.entry.type
356 self.not_implemented("infer_type")
358 # --------------- Type Analysis ------------------
360 def analyse_as_module(self, env):
361 # If this node can be interpreted as a reference to a
362 # cimported module, return its scope, else None.
365 def analyse_as_type(self, env):
366 # If this node can be interpreted as a reference to a
367 # type, return that type, else None.
370 def analyse_as_extension_type(self, env):
371 # If this node can be interpreted as a reference to an
372 # extension type, return its type, else None.
375 def analyse_types(self, env):
376 self.not_implemented("analyse_types")
378 def analyse_target_types(self, env):
379 self.analyse_types(env)
381 def nogil_check(self, env):
382 # By default, any expression based on Python objects is
383 # prevented in nogil environments. Subtypes must override
384 # this if they can work without the GIL.
385 if self.type.is_pyobject:
388 def gil_assignment_check(self, env):
389 if env.nogil and self.type.is_pyobject:
390 error(self.pos, "Assignment of Python object not allowed without gil")
392 def check_const(self):
397 error(self.pos, "Not allowed in a constant expression")
399 def check_const_addr(self):
400 self.addr_not_const()
403 def addr_not_const(self):
404 error(self.pos, "Address is not constant")
406 # ----------------- Result Allocation -----------------
408 def result_in_temp(self):
409 # Return true if result is in a temporary owned by
410 # this node or one of its subexpressions. Overridden
411 # by certain nodes which can share the result of
415 def target_code(self):
416 # Return code fragment for use as LHS of a C assignment.
417 return self.calculate_result_code()
419 def calculate_result_code(self):
420 self.not_implemented("calculate_result_code")
422 # def release_target_temp(self, env):
423 # # Release temporaries used by LHS of an assignment.
424 # self.release_subexpr_temps(env)
426 def allocate_temp_result(self, code):
428 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
432 type = PyrexTypes.py_object_type
433 self.temp_code = code.funcstate.allocate_temp(
434 type, manage_ref=self.use_managed_ref)
436 self.temp_code = None
438 def release_temp_result(self, code):
439 if not self.temp_code:
441 raise RuntimeError("temp %s released multiple times in %s" % (
442 self.old_temp, self.__class__.__name__))
444 raise RuntimeError("no temp, but release requested in %s" % (
445 self.__class__.__name__))
446 code.funcstate.release_temp(self.temp_code)
447 self.old_temp = self.temp_code
448 self.temp_code = None
450 # ---------------- Code Generation -----------------
452 def make_owned_reference(self, code):
453 # If result is a pyobject, make sure we own
455 if self.type.is_pyobject and not self.result_in_temp():
456 code.put_incref(self.result(), self.ctype())
458 def generate_evaluation_code(self, code):
459 code.mark_pos(self.pos)
461 # Generate code to evaluate this node and
462 # its sub-expressions, and dispose of any
463 # temporary results of its sub-expressions.
464 self.generate_subexpr_evaluation_code(code)
467 self.allocate_temp_result(code)
469 self.generate_result_code(code)
471 # If we are temp we do not need to wait until this node is disposed
472 # before disposing children.
473 self.generate_subexpr_disposal_code(code)
474 self.free_subexpr_temps(code)
476 def generate_subexpr_evaluation_code(self, code):
477 for node in self.subexpr_nodes():
478 node.generate_evaluation_code(code)
480 def generate_result_code(self, code):
481 self.not_implemented("generate_result_code")
483 def generate_disposal_code(self, code):
485 if self.type.is_pyobject:
486 code.put_decref_clear(self.result(), self.ctype())
488 # Already done if self.is_temp
489 self.generate_subexpr_disposal_code(code)
491 def generate_subexpr_disposal_code(self, code):
492 # Generate code to dispose of temporary results
493 # of all sub-expressions.
494 for node in self.subexpr_nodes():
495 node.generate_disposal_code(code)
497 def generate_post_assignment_code(self, code):
499 if self.type.is_pyobject:
500 code.putln("%s = 0;" % self.result())
502 self.generate_subexpr_disposal_code(code)
504 def generate_assignment_code(self, rhs, code):
505 # Stub method for nodes which are not legal as
506 # the LHS of an assignment. An error will have
507 # been reported earlier.
510 def generate_deletion_code(self, code):
511 # Stub method for nodes that are not legal as
512 # the argument of a del statement. An error
513 # will have been reported earlier.
516 def free_temps(self, code):
518 if not self.type.is_void:
519 self.release_temp_result(code)
521 self.free_subexpr_temps(code)
523 def free_subexpr_temps(self, code):
524 for sub in self.subexpr_nodes():
527 def generate_function_definitions(self, env, code):
530 # ---------------- Annotation ---------------------
532 def annotate(self, code):
533 for node in self.subexpr_nodes():
536 # ----------------- Coercion ----------------------
538 def coerce_to(self, dst_type, env):
539 # Coerce the result so that it can be assigned to
540 # something of type dst_type. If processing is necessary,
541 # wraps this node in a coercion node and returns that.
542 # Otherwise, returns this node unchanged.
544 # This method is called during the analyse_expressions
545 # phase of the src_node's processing.
547 # Note that subclasses that override this (especially
548 # ConstNodes) must not (re-)set their own .type attribute
549 # here. Since expression nodes may turn up in different
550 # places in the tree (e.g. inside of CloneNodes in cascaded
551 # assignments), this method must return a new node instance
552 # if it changes the type.
556 src_is_py_type = src_type.is_pyobject
557 dst_is_py_type = dst_type.is_pyobject
559 if self.check_for_coercion_error(dst_type):
562 if dst_type.is_reference:
563 dst_type = dst_type.ref_base_type
565 if dst_type.is_pyobject:
566 if not src.type.is_pyobject:
567 if dst_type is bytes_type and src.type.is_int:
568 src = CoerceIntToBytesNode(src, env)
570 src = CoerceToPyTypeNode(src, env)
571 if not src.type.subtype_of(dst_type):
572 if not isinstance(src, NoneNode):
573 src = PyTypeTestNode(src, dst_type, env)
574 elif src.type.is_pyobject:
575 src = CoerceFromPyTypeNode(dst_type, src, env)
576 elif (dst_type.is_complex
577 and src_type != dst_type
578 and dst_type.assignable_from(src_type)):
579 src = CoerceToComplexNode(src, dst_type, env)
580 else: # neither src nor dst are py types
581 # Added the string comparison, since for c types that
582 # is enough, but Cython gets confused when the types are
583 # in different pxi files.
584 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
585 self.fail_assignment(dst_type)
588 def fail_assignment(self, dst_type):
589 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
591 def check_for_coercion_error(self, dst_type, fail=False, default=None):
592 if fail and not default:
593 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
594 message = find_coercion_error((self.type, dst_type), default)
595 if message is not None:
596 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
599 self.fail_assignment(dst_type)
603 def coerce_to_pyobject(self, env):
604 return self.coerce_to(PyrexTypes.py_object_type, env)
606 def coerce_to_boolean(self, env):
607 # Coerce result to something acceptable as
610 # if it's constant, calculate the result now
611 if self.has_constant_result():
612 bool_value = bool(self.constant_result)
613 return BoolNode(self.pos, value=bool_value,
614 constant_result=bool_value)
617 if type.is_pyobject or type.is_ptr or type.is_float:
618 return CoerceToBooleanNode(self, env)
620 if not (type.is_int or type.is_enum or type.is_error):
622 "Type '%s' not acceptable as a boolean" % type)
625 def coerce_to_integer(self, env):
626 # If not already some C integer type, coerce to longint.
630 return self.coerce_to(PyrexTypes.c_long_type, env)
632 def coerce_to_temp(self, env):
633 # Ensure that the result is in a temporary.
634 if self.result_in_temp():
637 return CoerceToTempNode(self, env)
639 def coerce_to_simple(self, env):
640 # Ensure that the result is simple (see is_simple).
644 return self.coerce_to_temp(env)
647 # A node is simple if its result is something that can
648 # be referred to without performing any operations, e.g.
649 # a constant, local var, C global var, struct member
650 # reference, or temporary.
651 return self.result_in_temp()
653 def may_be_none(self):
654 if not self.type.is_pyobject:
656 if self.constant_result not in (not_a_constant, constant_value_not_set):
657 return self.constant_result is not None
660 def as_cython_attribute(self):
663 def as_none_safe_node(self, message, error="PyExc_TypeError"):
664 # Wraps the node in a NoneCheckNode if it is not known to be
665 # not-None (e.g. because it is a Python literal).
666 if self.may_be_none():
667 return NoneCheckNode(self, error, message)
672 class AtomicExprNode(ExprNode):
673 # Abstract base class for expression nodes which have
674 # no sub-expressions.
678 # Override to optimize -- we know we have no children
679 def generate_subexpr_evaluation_code(self, code):
681 def generate_subexpr_disposal_code(self, code):
684 class PyConstNode(AtomicExprNode):
685 # Abstract base class for constant Python values.
688 type = py_object_type
693 def may_be_none(self):
696 def analyse_types(self, env):
699 def calculate_result_code(self):
702 def generate_result_code(self, code):
706 class NoneNode(PyConstNode):
707 # The constant value None
711 constant_result = None
715 def compile_time_value(self, denv):
718 def may_be_none(self):
722 class EllipsisNode(PyConstNode):
723 # '...' in a subscript list.
725 value = "Py_Ellipsis"
727 constant_result = Ellipsis
729 def compile_time_value(self, denv):
733 class ConstNode(AtomicExprNode):
734 # Abstract base type for literal constant nodes.
736 # value string C code fragment
744 def may_be_none(self):
747 def analyse_types(self, env):
748 pass # Types are held in class variables
750 def check_const(self):
753 def get_constant_c_result_code(self):
754 return self.calculate_result_code()
756 def calculate_result_code(self):
757 return str(self.value)
759 def generate_result_code(self, code):
763 class BoolNode(ConstNode):
764 type = PyrexTypes.c_bint_type
765 # The constant value True or False
767 def calculate_constant_result(self):
768 self.constant_result = self.value
770 def compile_time_value(self, denv):
773 def calculate_result_code(self):
774 return str(int(self.value))
777 class NullNode(ConstNode):
778 type = PyrexTypes.c_null_ptr_type
782 def get_constant_c_result_code(self):
786 class CharNode(ConstNode):
787 type = PyrexTypes.c_char_type
789 def calculate_constant_result(self):
790 self.constant_result = ord(self.value)
792 def compile_time_value(self, denv):
793 return ord(self.value)
795 def calculate_result_code(self):
796 return "'%s'" % StringEncoding.escape_char(self.value)
799 class IntNode(ConstNode):
802 # longness "" or "L" or "LL"
803 # is_c_literal True/False/None creator considers this a C integer literal
807 is_c_literal = None # unknown
809 def __init__(self, pos, **kwds):
810 ExprNode.__init__(self, pos, **kwds)
811 if 'type' not in kwds:
812 self.type = self.find_suitable_type_for_value()
814 def find_suitable_type_for_value(self):
815 if self.constant_result is constant_value_not_set:
817 self.calculate_constant_result()
820 # we ignore 'is_c_literal = True' and instead map signed 32bit
821 # integers as C long values
822 if self.is_c_literal or \
823 self.constant_result in (constant_value_not_set, not_a_constant) or \
824 self.unsigned or self.longness == 'LL':
825 # clearly a C literal
826 rank = (self.longness == 'LL') and 2 or 1
827 suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
829 suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
831 # C literal or Python literal - split at 32bit boundary
832 if self.constant_result >= -2**31 and self.constant_result < 2**31:
833 if self.type and self.type.is_int:
834 suitable_type = self.type
836 suitable_type = PyrexTypes.c_long_type
838 suitable_type = PyrexTypes.py_object_type
841 def coerce_to(self, dst_type, env):
842 if self.type is dst_type:
844 elif dst_type.is_float:
845 if self.constant_result is not not_a_constant:
846 float_value = float(self.constant_result)
847 return FloatNode(self.pos, value=repr(float_value), type=dst_type,
848 constant_result=float_value)
850 return FloatNode(self.pos, value=self.value, type=dst_type,
851 constant_result=not_a_constant)
852 if dst_type.is_numeric and not dst_type.is_complex:
853 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
854 type = dst_type, is_c_literal = True,
855 unsigned=self.unsigned, longness=self.longness)
857 elif dst_type.is_pyobject:
858 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
859 type = PyrexTypes.py_object_type, is_c_literal = False,
860 unsigned=self.unsigned, longness=self.longness)
862 # FIXME: not setting the type here to keep it working with
863 # complex numbers. Should they be special cased?
864 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
865 unsigned=self.unsigned, longness=self.longness)
866 # We still need to perform normal coerce_to processing on the
867 # result, because we might be coercing to an extension type,
868 # in which case a type test node will be needed.
869 return ConstNode.coerce_to(node, dst_type, env)
871 def coerce_to_boolean(self, env):
873 self.pos, value=self.value,
874 type = PyrexTypes.c_bint_type,
875 unsigned=self.unsigned, longness=self.longness)
877 def generate_evaluation_code(self, code):
878 if self.type.is_pyobject:
879 # pre-allocate a Python version of the number
880 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
881 self.result_code = code.get_py_num(plain_integer_string, self.longness)
883 self.result_code = self.get_constant_c_result_code()
885 def get_constant_c_result_code(self):
886 return self.value_as_c_integer_string() + self.unsigned + self.longness
888 def value_as_c_integer_string(self, plain_digits=False):
890 if isinstance(value, basestring) and len(value) > 2:
891 # must convert C-incompatible Py3 oct/bin notations
894 value = int(value[2:], 8)
896 value = value[0] + value[2:] # '0o123' => '0123'
897 elif value[1] in 'bB':
898 value = int(value[2:], 2)
899 elif plain_digits and value[1] in 'xX':
900 value = int(value[2:], 16)
903 def calculate_result_code(self):
904 return self.result_code
906 def calculate_constant_result(self):
907 self.constant_result = Utils.str_to_number(self.value)
909 def compile_time_value(self, denv):
910 return Utils.str_to_number(self.value)
913 class FloatNode(ConstNode):
914 type = PyrexTypes.c_double_type
916 def calculate_constant_result(self):
917 self.constant_result = float(self.value)
919 def compile_time_value(self, denv):
920 return float(self.value)
922 def calculate_result_code(self):
924 assert isinstance(strval, (str, unicode))
925 cmpval = repr(float(strval))
927 return "(Py_HUGE_VAL * 0)"
928 elif cmpval == 'inf':
930 elif cmpval == '-inf':
931 return "(-Py_HUGE_VAL)"
936 class BytesNode(ConstNode):
937 # A char* or bytes literal
941 type = PyrexTypes.c_char_ptr_type
943 def compile_time_value(self, denv):
946 def analyse_as_type(self, env):
947 type = PyrexTypes.parse_basic_type(self.value)
950 from TreeFragment import TreeFragment
951 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
952 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
953 sizeof_node = declaration.root.stats[0].expr
954 sizeof_node.analyse_types(env)
955 if isinstance(sizeof_node, SizeofTypeNode):
956 return sizeof_node.arg_type
958 def can_coerce_to_char_literal(self):
959 return len(self.value) == 1
961 def coerce_to_boolean(self, env):
962 # This is special because we start off as a C char*. Testing
963 # that for truth directly would yield the wrong result.
964 return BoolNode(self.pos, value=bool(self.value))
966 def coerce_to(self, dst_type, env):
968 if not self.can_coerce_to_char_literal():
969 error(self.pos, "Only single-character string literals can be coerced into ints.")
971 if dst_type is PyrexTypes.c_py_unicode_type:
972 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.")
974 return CharNode(self.pos, value=self.value)
976 node = BytesNode(self.pos, value=self.value)
977 if dst_type == PyrexTypes.c_char_ptr_type:
978 node.type = PyrexTypes.c_char_ptr_type
980 elif dst_type == PyrexTypes.c_uchar_ptr_type:
981 node.type = PyrexTypes.c_char_ptr_type
982 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
984 if not self.type.is_pyobject:
985 if dst_type in (py_object_type, Builtin.bytes_type):
986 node.type = Builtin.bytes_type
987 elif dst_type.is_pyobject:
988 self.fail_assignment(dst_type)
990 elif dst_type.is_pyobject and dst_type is not py_object_type:
991 self.check_for_coercion_error(dst_type, fail=True)
994 # We still need to perform normal coerce_to processing on the
995 # result, because we might be coercing to an extension type,
996 # in which case a type test node will be needed.
997 return ConstNode.coerce_to(node, dst_type, env)
999 def as_py_string_node(self, env):
1000 # Return a new BytesNode with the same value as this node
1001 # but whose type is a Python type instead of a C type.
1002 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
1004 def generate_evaluation_code(self, code):
1005 if self.type.is_pyobject:
1006 self.result_code = code.get_py_string_const(self.value)
1008 self.result_code = code.get_string_const(self.value)
1010 def get_constant_c_result_code(self):
1013 def calculate_result_code(self):
1014 return self.result_code
1017 class UnicodeNode(PyConstNode):
1018 # A Python unicode object
1020 # value EncodedString
1021 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
1026 def coerce_to(self, dst_type, env):
1027 if dst_type is self.type:
1029 elif dst_type is PyrexTypes.c_py_unicode_type:
1030 if not self.can_coerce_to_char_literal():
1031 error(self.pos, "Only single-character Unicode string literals can be coerced into Py_UNICODE.")
1033 int_value = ord(self.value)
1034 return IntNode(self.pos, value=int_value, constant_result=int_value)
1035 elif not dst_type.is_pyobject:
1036 if dst_type.is_string and self.bytes_value is not None:
1037 # special case: '-3' enforced unicode literal used in a C char* context
1038 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
1039 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE.")
1040 elif dst_type is not py_object_type:
1041 if not self.check_for_coercion_error(dst_type):
1042 self.fail_assignment(dst_type)
1045 def can_coerce_to_char_literal(self):
1046 return len(self.value) == 1
1048 def contains_surrogates(self):
1049 # Check if the unicode string contains surrogate code points
1050 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1051 # Unicode, i.e. characters that would be spelled as two
1052 # separate code units on a narrow platform.
1053 for c in map(ord, self.value):
1054 if c > 65535: # can only happen on wide platforms
1056 # We only look for the first code unit (D800-DBFF) of a
1057 # surrogate pair - if we find one, the other one
1058 # (DC00-DFFF) is likely there, too. If we don't find it,
1059 # any second code unit cannot make for a surrogate pair by
1061 if c >= 0xD800 and c <= 0xDBFF:
1065 def generate_evaluation_code(self, code):
1066 self.result_code = code.get_py_string_const(self.value)
1068 def calculate_result_code(self):
1069 return self.result_code
1071 def compile_time_value(self, env):
1075 class StringNode(PyConstNode):
1076 # A Python str object, i.e. a byte string in Python 2.x and a
1077 # unicode string in Python 3.x
1079 # value BytesLiteral (or EncodedString with ASCII content)
1080 # unicode_value EncodedString or None
1081 # is_identifier boolean
1084 is_identifier = None
1085 unicode_value = None
1087 def coerce_to(self, dst_type, env):
1088 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1089 # if dst_type is Builtin.bytes_type:
1090 # # special case: bytes = 'str literal'
1091 # return BytesNode(self.pos, value=self.value)
1092 if not dst_type.is_pyobject:
1093 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1094 self.check_for_coercion_error(dst_type, fail=True)
1096 # this will be a unicode string in Py3, so make sure we can decode it
1097 if self.value.encoding and isinstance(self.value, StringEncoding.BytesLiteral):
1099 self.value.decode(self.value.encoding)
1100 except UnicodeDecodeError:
1101 error(self.pos, ("Decoding unprefixed string literal from '%s' failed. Consider using"
1102 "a byte string or unicode string explicitly, "
1103 "or adjust the source code encoding.") % self.value.encoding)
1107 def can_coerce_to_char_literal(self):
1108 return not self.is_identifier and len(self.value) == 1
1110 def generate_evaluation_code(self, code):
1111 self.result_code = code.get_py_string_const(
1112 self.value, identifier=self.is_identifier, is_str=True)
1114 def get_constant_c_result_code(self):
1117 def calculate_result_code(self):
1118 return self.result_code
1120 def compile_time_value(self, env):
1124 class IdentifierStringNode(StringNode):
1125 # A special str value that represents an identifier (bytes in Py2,
1127 is_identifier = True
1130 class LongNode(AtomicExprNode):
1131 # Python long integer literal
1135 type = py_object_type
1137 def calculate_constant_result(self):
1138 self.constant_result = Utils.str_to_number(self.value)
1140 def compile_time_value(self, denv):
1141 return Utils.str_to_number(self.value)
1143 def analyse_types(self, env):
1146 def may_be_none(self):
1149 gil_message = "Constructing Python long int"
1151 def generate_result_code(self, code):
1153 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1156 code.error_goto_if_null(self.result(), self.pos)))
1157 code.put_gotref(self.py_result())
1160 class ImagNode(AtomicExprNode):
1161 # Imaginary number literal
1163 # value float imaginary part
1165 type = PyrexTypes.c_double_complex_type
1167 def calculate_constant_result(self):
1168 self.constant_result = complex(0.0, self.value)
1170 def compile_time_value(self, denv):
1171 return complex(0.0, self.value)
1173 def analyse_types(self, env):
1174 self.type.create_declaration_utility_code(env)
1176 def may_be_none(self):
1179 def coerce_to(self, dst_type, env):
1180 if self.type is dst_type:
1182 node = ImagNode(self.pos, value=self.value)
1183 if dst_type.is_pyobject:
1185 node.type = PyrexTypes.py_object_type
1186 # We still need to perform normal coerce_to processing on the
1187 # result, because we might be coercing to an extension type,
1188 # in which case a type test node will be needed.
1189 return AtomicExprNode.coerce_to(node, dst_type, env)
1191 gil_message = "Constructing complex number"
1193 def calculate_result_code(self):
1194 if self.type.is_pyobject:
1195 return self.result()
1197 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1199 def generate_result_code(self, code):
1200 if self.type.is_pyobject:
1202 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1205 code.error_goto_if_null(self.result(), self.pos)))
1206 code.put_gotref(self.py_result())
1209 class NewExprNode(AtomicExprNode):
1213 # cppclass node c++ class to create
1217 def infer_type(self, env):
1218 type = self.cppclass.analyse_as_type(env)
1219 if type is None or not type.is_cpp_class:
1220 error(self.pos, "new operator can only be applied to a C++ class")
1221 self.type = error_type
1224 constructor = type.scope.lookup(u'<init>')
1225 if constructor is None:
1226 return_type = PyrexTypes.CFuncType(type, [])
1227 return_type = PyrexTypes.CPtrType(return_type)
1228 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1229 constructor = type.scope.lookup(u'<init>')
1230 self.class_type = type
1231 self.entry = constructor
1232 self.type = constructor.type
1235 def analyse_types(self, env):
1236 if self.type is None:
1237 self.infer_type(env)
1239 def may_be_none(self):
1242 def generate_result_code(self, code):
1245 def calculate_result_code(self):
1246 return "new " + self.class_type.declaration_code("")
1249 class NameNode(AtomicExprNode):
1250 # Reference to a local or global variable name.
1252 # name string Python name of the variable
1253 # entry Entry Symbol table entry
1254 # type_entry Entry For extension type names, the original type entry
1257 is_cython_module = False
1258 cython_attribute = None
1259 lhs_of_first_assignment = False
1260 is_used_as_rvalue = 0
1264 def create_analysed_rvalue(pos, env, entry):
1265 node = NameNode(pos)
1266 node.analyse_types(env, entry=entry)
1269 def as_cython_attribute(self):
1270 return self.cython_attribute
1272 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1274 def type_dependencies(self, env):
1275 if self.entry is None:
1276 self.entry = env.lookup(self.name)
1277 if self.entry is not None and self.entry.type.is_unspecified:
1278 return (self.entry,)
1282 def infer_type(self, env):
1283 if self.entry is None:
1284 self.entry = env.lookup(self.name)
1285 if self.entry is None:
1286 return py_object_type
1287 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1288 self.name == self.entry.type.name:
1289 # Unfortunately the type attribute of type objects
1290 # is used for the pointer to the type they represent.
1293 return self.entry.type
1295 def compile_time_value(self, denv):
1297 return denv.lookup(self.name)
1299 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1301 def get_constant_c_result_code(self):
1302 if not self.entry or self.entry.type.is_pyobject:
1304 return self.entry.cname
1306 def coerce_to(self, dst_type, env):
1307 # If coercing to a generic pyobject and this is a builtin
1308 # C function with a Python equivalent, manufacture a NameNode
1309 # referring to the Python builtin.
1310 #print "NameNode.coerce_to:", self.name, dst_type ###
1311 if dst_type is py_object_type:
1313 if entry and entry.is_cfunction:
1314 var_entry = entry.as_variable
1316 if var_entry.is_builtin and Options.cache_builtins:
1317 var_entry = env.declare_builtin(var_entry.name, self.pos)
1318 node = NameNode(self.pos, name = self.name)
1319 node.entry = var_entry
1320 node.analyse_rvalue_entry(env)
1322 return super(NameNode, self).coerce_to(dst_type, env)
1324 def analyse_as_module(self, env):
1325 # Try to interpret this as a reference to a cimported module.
1326 # Returns the module scope, or None.
1329 entry = env.lookup(self.name)
1330 if entry and entry.as_module:
1331 return entry.as_module
1334 def analyse_as_type(self, env):
1335 if self.cython_attribute:
1336 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1338 type = PyrexTypes.parse_basic_type(self.name)
1343 entry = env.lookup(self.name)
1344 if entry and entry.is_type:
1349 def analyse_as_extension_type(self, env):
1350 # Try to interpret this as a reference to an extension type.
1351 # Returns the extension type, or None.
1354 entry = env.lookup(self.name)
1355 if entry and entry.is_type and entry.type.is_extension_type:
1360 def analyse_target_declaration(self, env):
1362 self.entry = env.lookup_here(self.name)
1364 if env.directives['warn.undeclared']:
1365 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1366 if env.directives['infer_types'] != False:
1367 type = unspecified_type
1369 type = py_object_type
1370 self.entry = env.declare_var(self.name, type, self.pos)
1371 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1372 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1373 if self.entry.is_declared_generic:
1374 self.result_ctype = py_object_type
1376 def analyse_types(self, env):
1377 if self.entry is None:
1378 self.entry = env.lookup(self.name)
1380 self.entry = env.declare_builtin(self.name, self.pos)
1382 self.type = PyrexTypes.error_type
1387 if entry.type.is_buffer:
1389 Buffer.used_buffer_aux_vars(entry)
1390 if entry.utility_code:
1391 env.use_utility_code(entry.utility_code)
1392 self.analyse_rvalue_entry(env)
1394 def analyse_target_types(self, env):
1395 self.analyse_entry(env)
1396 if not self.is_lvalue():
1397 error(self.pos, "Assignment to non-lvalue '%s'"
1399 self.type = PyrexTypes.error_type
1401 if self.entry.type.is_buffer:
1403 Buffer.used_buffer_aux_vars(self.entry)
1405 def analyse_rvalue_entry(self, env):
1406 #print "NameNode.analyse_rvalue_entry:", self.name ###
1407 #print "Entry:", self.entry.__dict__ ###
1408 self.analyse_entry(env)
1410 if entry.is_declared_generic:
1411 self.result_ctype = py_object_type
1412 if entry.is_pyglobal or entry.is_builtin:
1413 if Options.cache_builtins and entry.is_builtin:
1417 env.use_utility_code(get_name_interned_utility_code)
1418 self.is_used_as_rvalue = 1
1420 def nogil_check(self, env):
1421 if self.is_used_as_rvalue:
1423 if entry.is_builtin:
1424 # if not Options.cache_builtins: # cached builtins are ok
1426 elif entry.is_pyglobal:
1429 gil_message = "Accessing Python global or builtin"
1431 def analyse_entry(self, env):
1432 #print "NameNode.analyse_entry:", self.name ###
1433 self.check_identifier_kind()
1438 def check_identifier_kind(self):
1439 # Check that this is an appropriate kind of name for use in an
1440 # expression. Also finds the variable entry associated with
1441 # an extension type.
1443 if entry.is_type and entry.type.is_extension_type:
1444 self.type_entry = entry
1445 if not (entry.is_const or entry.is_variable
1446 or entry.is_builtin or entry.is_cfunction
1447 or entry.is_cpp_class):
1448 if self.entry.as_variable:
1449 self.entry = self.entry.as_variable
1452 "'%s' is not a constant, variable or function identifier" % self.name)
1454 def is_simple(self):
1455 # If it's not a C variable, it'll be in a temp.
1458 def calculate_target_results(self, env):
1461 def check_const(self):
1463 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1468 def check_const_addr(self):
1470 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1471 self.addr_not_const()
1475 def is_lvalue(self):
1476 return self.entry.is_variable and \
1477 not self.entry.type.is_array and \
1478 not self.entry.is_readonly
1480 def is_ephemeral(self):
1481 # Name nodes are never ephemeral, even if the
1482 # result is in a temporary.
1485 def calculate_result_code(self):
1488 return "<error>" # There was an error earlier
1491 def generate_result_code(self, code):
1492 assert hasattr(self, 'entry')
1495 return # There was an error earlier
1496 if entry.is_builtin and Options.cache_builtins:
1497 return # Lookup already cached
1498 elif entry.is_pyclass_attr:
1499 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1500 interned_cname = code.intern_identifier(self.entry.name)
1501 if entry.is_builtin:
1502 namespace = Naming.builtins_cname
1503 else: # entry.is_pyglobal
1504 namespace = entry.scope.namespace_cname
1506 '%s = PyObject_GetItem(%s, %s); %s' % (
1510 code.error_goto_if_null(self.result(), self.pos)))
1511 code.put_gotref(self.py_result())
1513 elif entry.is_pyglobal or entry.is_builtin:
1514 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1515 interned_cname = code.intern_identifier(self.entry.name)
1516 if entry.is_builtin:
1517 namespace = Naming.builtins_cname
1518 else: # entry.is_pyglobal
1519 namespace = entry.scope.namespace_cname
1520 code.globalstate.use_utility_code(get_name_interned_utility_code)
1522 '%s = __Pyx_GetName(%s, %s); %s' % (
1526 code.error_goto_if_null(self.result(), self.pos)))
1527 code.put_gotref(self.py_result())
1529 elif entry.is_local and False:
1530 # control flow not good enough yet
1531 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1532 if assigned is False:
1533 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1534 elif not Options.init_local_none and assigned is None:
1535 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1536 (entry.cname, entry.name, code.error_goto(self.pos)))
1537 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1539 def generate_assignment_code(self, rhs, code):
1540 #print "NameNode.generate_assignment_code:", self.name ###
1543 return # There was an error earlier
1545 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1546 and not self.lhs_of_first_assignment):
1547 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1549 # is_pyglobal seems to be True for module level-globals only.
1550 # We use this to access class->tp_dict if necessary.
1551 if entry.is_pyglobal:
1552 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1553 interned_cname = code.intern_identifier(self.entry.name)
1554 namespace = self.entry.scope.namespace_cname
1556 # if the entry is a member we have to cheat: SetAttr does not work
1557 # on types, so we create a descriptor which is then added to tp_dict
1558 code.put_error_if_neg(self.pos,
1559 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1563 rhs.generate_disposal_code(code)
1564 rhs.free_temps(code)
1565 # in Py2.6+, we need to invalidate the method cache
1566 code.putln("PyType_Modified(%s);" %
1567 entry.scope.parent_type.typeptr_cname)
1568 elif entry.is_pyclass_attr:
1569 code.put_error_if_neg(self.pos,
1570 'PyObject_SetItem(%s, %s, %s)' % (
1574 rhs.generate_disposal_code(code)
1575 rhs.free_temps(code)
1577 code.put_error_if_neg(self.pos,
1578 'PyObject_SetAttr(%s, %s, %s)' % (
1582 if debug_disposal_code:
1583 print("NameNode.generate_assignment_code:")
1584 print("...generating disposal code for %s" % rhs)
1585 rhs.generate_disposal_code(code)
1586 rhs.free_temps(code)
1588 if self.type.is_buffer:
1589 # Generate code for doing the buffer release/acquisition.
1590 # This might raise an exception in which case the assignment (done
1591 # below) will not happen.
1593 # The reason this is not in a typetest-like node is because the
1594 # variables that the acquired buffer info is stored to is allocated
1595 # per entry and coupled with it.
1596 self.generate_acquire_buffer(rhs, code)
1598 if self.type.is_pyobject:
1599 #print "NameNode.generate_assignment_code: to", self.name ###
1600 #print "...from", rhs ###
1601 #print "...LHS type", self.type, "ctype", self.ctype() ###
1602 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1603 if self.use_managed_ref:
1604 rhs.make_owned_reference(code)
1605 if entry.is_cglobal:
1606 code.put_gotref(self.py_result())
1607 if not self.lhs_of_first_assignment:
1608 if entry.is_local and not Options.init_local_none:
1609 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1610 if initialized is True:
1611 code.put_decref(self.result(), self.ctype())
1612 elif initialized is None:
1613 code.put_xdecref(self.result(), self.ctype())
1615 code.put_decref(self.result(), self.ctype())
1616 if entry.is_cglobal:
1617 code.put_giveref(rhs.py_result())
1619 code.putln('%s = %s;' % (self.result(),
1620 rhs.result_as(self.ctype())))
1621 if debug_disposal_code:
1622 print("NameNode.generate_assignment_code:")
1623 print("...generating post-assignment code for %s" % rhs)
1624 rhs.generate_post_assignment_code(code)
1625 rhs.free_temps(code)
1627 def generate_acquire_buffer(self, rhs, code):
1628 # rhstmp is only used in case the rhs is a complicated expression leading to
1629 # the object, to avoid repeating the same C expression for every reference
1630 # to the rhs. It does NOT hold a reference.
1631 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1633 rhstmp = rhs.result_as(self.ctype())
1635 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1636 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1638 buffer_aux = self.entry.buffer_aux
1639 bufstruct = buffer_aux.buffer_info_var.cname
1641 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1642 is_initialized=not self.lhs_of_first_assignment,
1643 pos=self.pos, code=code)
1646 code.putln("%s = 0;" % rhstmp)
1647 code.funcstate.release_temp(rhstmp)
1649 def generate_deletion_code(self, code):
1650 if self.entry is None:
1651 return # There was an error earlier
1652 if not self.entry.is_pyglobal:
1653 error(self.pos, "Deletion of local or C global name not supported")
1655 if self.entry.is_pyclass_attr:
1656 namespace = self.entry.scope.namespace_cname
1657 code.put_error_if_neg(self.pos,
1658 'PyMapping_DelItemString(%s, "%s")' % (
1662 code.put_error_if_neg(self.pos,
1663 '__Pyx_DelAttrString(%s, "%s")' % (
1664 Naming.module_cname,
1667 def annotate(self, code):
1668 if hasattr(self, 'is_called') and self.is_called:
1669 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1670 if self.type.is_pyobject:
1671 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1673 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1675 class BackquoteNode(ExprNode):
1680 type = py_object_type
1684 def analyse_types(self, env):
1685 self.arg.analyse_types(env)
1686 self.arg = self.arg.coerce_to_pyobject(env)
1689 gil_message = "Backquote expression"
1691 def calculate_constant_result(self):
1692 self.constant_result = repr(self.arg.constant_result)
1694 def generate_result_code(self, code):
1696 "%s = PyObject_Repr(%s); %s" % (
1698 self.arg.py_result(),
1699 code.error_goto_if_null(self.result(), self.pos)))
1700 code.put_gotref(self.py_result())
1704 class ImportNode(ExprNode):
1705 # Used as part of import statement implementation.
1706 # Implements result =
1707 # __import__(module_name, globals(), None, name_list)
1709 # module_name StringNode dotted name of module
1710 # name_list ListNode or None list of names to be imported
1712 type = py_object_type
1714 subexprs = ['module_name', 'name_list']
1716 def analyse_types(self, env):
1717 self.module_name.analyse_types(env)
1718 self.module_name = self.module_name.coerce_to_pyobject(env)
1720 self.name_list.analyse_types(env)
1721 self.name_list.coerce_to_pyobject(env)
1723 env.use_utility_code(import_utility_code)
1725 gil_message = "Python import"
1727 def generate_result_code(self, code):
1729 name_list_code = self.name_list.py_result()
1731 name_list_code = "0"
1733 "%s = __Pyx_Import(%s, %s); %s" % (
1735 self.module_name.py_result(),
1737 code.error_goto_if_null(self.result(), self.pos)))
1738 code.put_gotref(self.py_result())
1741 class IteratorNode(ExprNode):
1742 # Used as part of for statement implementation.
1744 # allocate_counter_temp/release_counter_temp needs to be called
1745 # by parent (ForInStatNode)
1747 # Implements result = iter(sequence)
1751 type = py_object_type
1753 subexprs = ['sequence']
1755 def analyse_types(self, env):
1756 self.sequence.analyse_types(env)
1757 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1758 not self.sequence.type.is_string:
1759 # C array iteration will be transformed later on
1760 self.type = self.sequence.type
1762 self.sequence = self.sequence.coerce_to_pyobject(env)
1765 gil_message = "Iterating over Python object"
1767 def allocate_counter_temp(self, code):
1768 self.counter_cname = code.funcstate.allocate_temp(
1769 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1771 def release_counter_temp(self, code):
1772 code.funcstate.release_temp(self.counter_cname)
1774 def generate_result_code(self, code):
1775 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1776 raise InternalError("for in carray slice not transformed")
1777 is_builtin_sequence = self.sequence.type is list_type or \
1778 self.sequence.type is tuple_type
1779 may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1780 if is_builtin_sequence:
1782 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1783 elif may_be_a_sequence:
1785 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1786 self.sequence.py_result(),
1787 self.sequence.py_result()))
1788 if may_be_a_sequence:
1790 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1793 self.sequence.py_result(),
1795 code.putln("} else {")
1796 if is_builtin_sequence:
1798 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1799 code.error_goto(self.pos))
1801 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1804 self.sequence.py_result(),
1805 code.error_goto_if_null(self.result(), self.pos)))
1806 code.put_gotref(self.py_result())
1807 if may_be_a_sequence:
1811 class NextNode(AtomicExprNode):
1812 # Used as part of for statement implementation.
1813 # Implements result = iterator.next()
1814 # Created during analyse_types phase.
1815 # The iterator is not owned by this node.
1819 type = py_object_type
1821 def __init__(self, iterator, env):
1822 self.pos = iterator.pos
1823 self.iterator = iterator
1824 if iterator.type.is_ptr or iterator.type.is_array:
1825 self.type = iterator.type.base_type
1828 def generate_result_code(self, code):
1829 sequence_type = self.iterator.sequence.type
1830 if sequence_type is list_type:
1831 type_checks = [(list_type, "List")]
1832 elif sequence_type is tuple_type:
1833 type_checks = [(tuple_type, "Tuple")]
1834 elif not sequence_type.is_builtin_type:
1835 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1839 for py_type, prefix in type_checks:
1840 if len(type_checks) > 1:
1842 "if (likely(Py%s_CheckExact(%s))) {" % (
1843 prefix, self.iterator.py_result()))
1845 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1846 self.iterator.counter_cname,
1848 self.iterator.py_result()))
1850 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1853 self.iterator.py_result(),
1854 self.iterator.counter_cname,
1856 self.iterator.counter_cname))
1857 if len(type_checks) > 1:
1859 if len(type_checks) == 1:
1863 "%s = PyIter_Next(%s);" % (
1865 self.iterator.py_result()))
1869 code.putln(code.error_goto_if_PyErr(self.pos))
1870 code.putln("break;")
1872 code.put_gotref(self.py_result())
1876 class ExcValueNode(AtomicExprNode):
1877 # Node created during analyse_types phase
1878 # of an ExceptClauseNode to fetch the current
1881 type = py_object_type
1883 def __init__(self, pos, env):
1884 ExprNode.__init__(self, pos)
1886 def set_var(self, var):
1889 def calculate_result_code(self):
1892 def generate_result_code(self, code):
1895 def analyse_types(self, env):
1899 class TempNode(ExprNode):
1900 # Node created during analyse_types phase
1901 # of some nodes to hold a temporary value.
1903 # Note: One must call "allocate" and "release" on
1904 # the node during code generation to get/release the temp.
1905 # This is because the temp result is often used outside of
1906 # the regular cycle.
1910 def __init__(self, pos, type, env):
1911 ExprNode.__init__(self, pos)
1913 if type.is_pyobject:
1914 self.result_ctype = py_object_type
1917 def analyse_types(self, env):
1920 def generate_result_code(self, code):
1923 def allocate(self, code):
1924 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1926 def release(self, code):
1927 code.funcstate.release_temp(self.temp_cname)
1928 self.temp_cname = None
1932 return self.temp_cname
1934 assert False, "Remember to call allocate/release on TempNode"
1937 # Do not participate in normal temp alloc/dealloc:
1938 def allocate_temp_result(self, code):
1941 def release_temp_result(self, code):
1944 class PyTempNode(TempNode):
1945 # TempNode holding a Python value.
1947 def __init__(self, pos, env):
1948 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1950 class RawCNameExprNode(ExprNode):
1953 def __init__(self, pos, type=None):
1957 def analyse_types(self, env):
1960 def set_cname(self, cname):
1966 def generate_result_code(self, code):
1970 #-------------------------------------------------------------------
1974 #-------------------------------------------------------------------
1976 class IndexNode(ExprNode):
1977 # Sequence indexing.
1981 # indices [ExprNode]
1982 # is_buffer_access boolean Whether this is a buffer access.
1984 # indices is used on buffer access, index on non-buffer access.
1985 # The former contains a clean list of index parameters, the
1986 # latter whatever Python object is needed for index access.
1988 subexprs = ['base', 'index', 'indices']
1991 def __init__(self, pos, index, *args, **kw):
1992 ExprNode.__init__(self, pos, index=index, *args, **kw)
1995 def calculate_constant_result(self):
1996 self.constant_result = \
1997 self.base.constant_result[self.index.constant_result]
1999 def compile_time_value(self, denv):
2000 base = self.base.compile_time_value(denv)
2001 index = self.index.compile_time_value(denv)
2004 except Exception, e:
2005 self.compile_time_value_error(e)
2007 def is_ephemeral(self):
2008 return self.base.is_ephemeral()
2010 def analyse_target_declaration(self, env):
2013 def analyse_as_type(self, env):
2014 base_type = self.base.analyse_as_type(env)
2015 if base_type and not base_type.is_pyobject:
2016 if base_type.is_cpp_class:
2017 if isinstance(self.index, TupleNode):
2018 template_values = self.index.args
2020 template_values = [self.index]
2022 type_node = Nodes.TemplatedTypeNode(
2024 positional_args = template_values,
2025 keyword_args = None)
2026 return type_node.analyse(env, base_type = base_type)
2028 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2031 def type_dependencies(self, env):
2032 return self.base.type_dependencies(env)
2034 def infer_type(self, env):
2035 base_type = self.base.infer_type(env)
2036 if isinstance(self.index, SliceNode):
2038 if base_type.is_string:
2039 # sliced C strings must coerce to Python
2041 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2042 # slicing these returns the same type
2045 # TODO: Handle buffers (hopefully without too much redundancy).
2046 return py_object_type
2048 index_type = self.index.infer_type(env)
2049 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2051 if base_type is unicode_type:
2052 # Py_UNICODE will automatically coerce to a unicode string
2053 # if required, so this is safe. We only infer Py_UNICODE
2054 # when the index is a C integer type. Otherwise, we may
2055 # need to use normal Python item access, in which case
2056 # it's faster to return the one-char unicode string than
2057 # to receive it, throw it away, and potentially rebuild it
2058 # on a subsequent PyObject coercion.
2059 return PyrexTypes.c_py_unicode_type
2060 elif isinstance(self.base, BytesNode):
2061 #if env.global_scope().context.language_level >= 3:
2062 # # infering 'char' can be made to work in Python 3 mode
2063 # return PyrexTypes.c_char_type
2064 # Py2/3 return different types on indexing bytes objects
2065 return py_object_type
2066 elif base_type.is_ptr or base_type.is_array:
2067 return base_type.base_type
2069 # may be slicing or indexing, we don't know
2070 if base_type is unicode_type:
2071 # this type always returns its own type on Python indexing/slicing
2074 # TODO: Handle buffers (hopefully without too much redundancy).
2075 return py_object_type
2077 def analyse_types(self, env):
2078 self.analyse_base_and_index_types(env, getting = 1)
2080 def analyse_target_types(self, env):
2081 self.analyse_base_and_index_types(env, setting = 1)
2083 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2084 # Note: This might be cleaned up by having IndexNode
2085 # parsed in a saner way and only construct the tuple if
2088 # Note that this function must leave IndexNode in a cloneable state.
2089 # For buffers, self.index is packed out on the initial analysis, and
2090 # when cloning self.indices is copied.
2091 self.is_buffer_access = False
2093 self.base.analyse_types(env)
2094 if self.base.type.is_error:
2095 # Do not visit child tree if base is undeclared to avoid confusing
2097 self.type = PyrexTypes.error_type
2100 is_slice = isinstance(self.index, SliceNode)
2101 # Potentially overflowing index value.
2102 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2103 self.index = self.index.coerce_to_pyobject(env)
2105 # Handle the case where base is a literal char* (and we expect a string, not an int)
2106 if isinstance(self.base, BytesNode) or is_slice:
2107 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2108 self.base = self.base.coerce_to_pyobject(env)
2110 skip_child_analysis = False
2111 buffer_access = False
2112 if self.base.type.is_buffer:
2114 indices = self.indices
2116 if isinstance(self.index, TupleNode):
2117 indices = self.index.args
2119 indices = [self.index]
2120 if len(indices) == self.base.type.ndim:
2121 buffer_access = True
2122 skip_child_analysis = True
2124 x.analyse_types(env)
2125 if not x.type.is_int:
2126 buffer_access = False
2128 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2130 # On cloning, indices is cloned. Otherwise, unpack index into indices
2131 assert not (buffer_access and isinstance(self.index, CloneNode))
2134 self.indices = indices
2136 self.type = self.base.type.dtype
2137 self.is_buffer_access = True
2138 self.buffer_type = self.base.entry.type
2140 if getting and self.type.is_pyobject:
2143 if not self.base.entry.type.writable:
2144 error(self.pos, "Writing to readonly buffer")
2146 self.base.entry.buffer_aux.writable_needed = True
2148 base_type = self.base.type
2149 if isinstance(self.index, TupleNode):
2150 self.index.analyse_types(env, skip_children=skip_child_analysis)
2151 elif not skip_child_analysis:
2152 self.index.analyse_types(env)
2153 self.original_index_type = self.index.type
2154 if base_type is PyrexTypes.c_py_unicode_type:
2155 # we infer Py_UNICODE for unicode strings in some
2156 # cases, but indexing must still work for them
2157 if self.index.constant_result in (0, -1):
2158 # FIXME: we know that this node is redundant -
2159 # currently, this needs to get handled in Optimize.py
2161 self.base = self.base.coerce_to_pyobject(env)
2162 base_type = self.base.type
2163 if base_type.is_pyobject:
2164 if self.index.type.is_int:
2166 and (base_type in (list_type, tuple_type, unicode_type))
2167 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2168 and not env.directives['boundscheck']):
2172 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2174 self.index = self.index.coerce_to_pyobject(env)
2176 if self.index.type.is_int and base_type is unicode_type:
2177 # Py_UNICODE will automatically coerce to a unicode string
2178 # if required, so this is fast and safe
2179 self.type = PyrexTypes.c_py_unicode_type
2180 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2181 self.type = base_type
2183 self.type = py_object_type
2185 if base_type.is_ptr or base_type.is_array:
2186 self.type = base_type.base_type
2188 self.type = base_type
2189 elif self.index.type.is_pyobject:
2190 self.index = self.index.coerce_to(
2191 PyrexTypes.c_py_ssize_t_type, env)
2192 elif not self.index.type.is_int:
2194 "Invalid index type '%s'" %
2196 elif base_type.is_cpp_class:
2197 function = env.lookup_operator("[]", [self.base, self.index])
2198 if function is None:
2199 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2200 self.type = PyrexTypes.error_type
2201 self.result_code = "<error>"
2203 func_type = function.type
2204 if func_type.is_ptr:
2205 func_type = func_type.base_type
2206 self.index = self.index.coerce_to(func_type.args[0].type, env)
2207 self.type = func_type.return_type
2208 if setting and not func_type.return_type.is_reference:
2209 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2212 "Attempting to index non-array type '%s'" %
2214 self.type = PyrexTypes.error_type
2216 gil_message = "Indexing Python object"
2218 def nogil_check(self, env):
2219 if self.is_buffer_access:
2220 if env.directives['boundscheck']:
2221 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2223 elif self.type.is_pyobject:
2224 error(self.pos, "Cannot access buffer with object dtype without gil")
2226 super(IndexNode, self).nogil_check(env)
2229 def check_const_addr(self):
2230 return self.base.check_const_addr() and self.index.check_const()
2232 def is_lvalue(self):
2235 def calculate_result_code(self):
2236 if self.is_buffer_access:
2237 return "(*%s)" % self.buffer_ptr_code
2238 elif self.base.type is list_type:
2239 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2240 elif self.base.type is tuple_type:
2241 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2242 elif self.base.type is unicode_type and self.type is PyrexTypes.c_py_unicode_type:
2243 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2244 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2245 error(self.pos, "Invalid use of pointer slice")
2247 return "(%s[%s])" % (
2248 self.base.result(), self.index.result())
2250 def extra_index_params(self):
2251 if self.index.type.is_int:
2252 if self.original_index_type.signed:
2253 size_adjustment = ""
2255 size_adjustment = "+1"
2256 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2260 def generate_subexpr_evaluation_code(self, code):
2261 self.base.generate_evaluation_code(code)
2262 if not self.indices:
2263 self.index.generate_evaluation_code(code)
2265 for i in self.indices:
2266 i.generate_evaluation_code(code)
2268 def generate_subexpr_disposal_code(self, code):
2269 self.base.generate_disposal_code(code)
2270 if not self.indices:
2271 self.index.generate_disposal_code(code)
2273 for i in self.indices:
2274 i.generate_disposal_code(code)
2276 def free_subexpr_temps(self, code):
2277 self.base.free_temps(code)
2278 if not self.indices:
2279 self.index.free_temps(code)
2281 for i in self.indices:
2284 def generate_result_code(self, code):
2285 if self.is_buffer_access:
2286 if code.globalstate.directives['nonecheck']:
2287 self.put_nonecheck(code)
2288 self.buffer_ptr_code = self.buffer_lookup_code(code)
2289 if self.type.is_pyobject:
2290 # is_temp is True, so must pull out value and incref it.
2291 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2292 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2294 if self.type.is_pyobject:
2295 if self.index.type.is_int:
2296 index_code = self.index.result()
2297 if self.base.type is list_type:
2298 function = "__Pyx_GetItemInt_List"
2299 elif self.base.type is tuple_type:
2300 function = "__Pyx_GetItemInt_Tuple"
2302 function = "__Pyx_GetItemInt"
2303 code.globalstate.use_utility_code(getitem_int_utility_code)
2305 index_code = self.index.py_result()
2306 if self.base.type is dict_type:
2307 function = "__Pyx_PyDict_GetItem"
2308 code.globalstate.use_utility_code(getitem_dict_utility_code)
2310 function = "PyObject_GetItem"
2312 "%s = %s(%s, %s%s); if (!%s) %s" % (
2315 self.base.py_result(),
2317 self.extra_index_params(),
2319 code.error_goto(self.pos)))
2320 code.put_gotref(self.py_result())
2321 elif self.type is PyrexTypes.c_py_unicode_type and self.base.type is unicode_type:
2322 assert self.index.type.is_int
2323 index_code = self.index.result()
2324 function = "__Pyx_GetItemInt_Unicode"
2325 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2327 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2330 self.base.py_result(),
2332 self.extra_index_params(),
2334 code.error_goto(self.pos)))
2336 def generate_setitem_code(self, value_code, code):
2337 if self.index.type.is_int:
2338 function = "__Pyx_SetItemInt"
2339 index_code = self.index.result()
2340 code.globalstate.use_utility_code(setitem_int_utility_code)
2342 index_code = self.index.py_result()
2343 if self.base.type is dict_type:
2344 function = "PyDict_SetItem"
2345 # It would seem that we could specialized lists/tuples, but that
2346 # shouldn't happen here.
2347 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2348 # not a PyObject*, and bad conversion here would give the wrong
2349 # exception. Also, tuples are supposed to be immutable, and raise
2350 # TypeErrors when trying to set their entries (PyTuple_SetItem
2351 # is for creating new tuples from).
2353 function = "PyObject_SetItem"
2355 "if (%s(%s, %s, %s%s) < 0) %s" % (
2357 self.base.py_result(),
2360 self.extra_index_params(),
2361 code.error_goto(self.pos)))
2363 def generate_buffer_setitem_code(self, rhs, code, op=""):
2364 # Used from generate_assignment_code and InPlaceAssignmentNode
2365 if code.globalstate.directives['nonecheck']:
2366 self.put_nonecheck(code)
2367 ptrexpr = self.buffer_lookup_code(code)
2368 if self.buffer_type.dtype.is_pyobject:
2369 # Must manage refcounts. Decref what is already there
2370 # and incref what we put in.
2371 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2372 rhs_code = rhs.result()
2373 code.putln("%s = %s;" % (ptr, ptrexpr))
2374 code.put_gotref("*%s" % ptr)
2375 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2378 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2379 code.put_giveref("*%s" % ptr)
2380 code.funcstate.release_temp(ptr)
2383 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2385 def generate_assignment_code(self, rhs, code):
2386 self.generate_subexpr_evaluation_code(code)
2387 if self.is_buffer_access:
2388 self.generate_buffer_setitem_code(rhs, code)
2389 elif self.type.is_pyobject:
2390 self.generate_setitem_code(rhs.py_result(), code)
2394 self.result(), rhs.result()))
2395 self.generate_subexpr_disposal_code(code)
2396 self.free_subexpr_temps(code)
2397 rhs.generate_disposal_code(code)
2398 rhs.free_temps(code)
2400 def generate_deletion_code(self, code):
2401 self.generate_subexpr_evaluation_code(code)
2402 #if self.type.is_pyobject:
2403 if self.index.type.is_int:
2404 function = "__Pyx_DelItemInt"
2405 index_code = self.index.result()
2406 code.globalstate.use_utility_code(delitem_int_utility_code)
2408 index_code = self.index.py_result()
2409 if self.base.type is dict_type:
2410 function = "PyDict_DelItem"
2412 function = "PyObject_DelItem"
2414 "if (%s(%s, %s%s) < 0) %s" % (
2416 self.base.py_result(),
2418 self.extra_index_params(),
2419 code.error_goto(self.pos)))
2420 self.generate_subexpr_disposal_code(code)
2421 self.free_subexpr_temps(code)
2423 def buffer_lookup_code(self, code):
2424 # Assign indices to temps
2425 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2426 for temp, index in zip(index_temps, self.indices):
2427 code.putln("%s = %s;" % (temp, index.result()))
2428 # Generate buffer access code using these temps
2430 # The above could happen because child_attrs is wrong somewhere so that
2431 # options are not propagated.
2432 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2433 index_signeds=[i.type.signed for i in self.indices],
2434 index_cnames=index_temps,
2435 directives=code.globalstate.directives,
2436 pos=self.pos, code=code)
2438 def put_nonecheck(self, code):
2439 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2440 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2441 code.putln("__Pyx_RaiseNoneIndexingError();")
2442 code.putln(code.error_goto(self.pos))
2445 class SliceIndexNode(ExprNode):
2446 # 2-element slice indexing
2449 # start ExprNode or None
2450 # stop ExprNode or None
2452 subexprs = ['base', 'start', 'stop']
2454 def infer_type(self, env):
2455 base_type = self.base.infer_type(env)
2456 if base_type.is_string:
2458 elif base_type in (bytes_type, str_type, unicode_type,
2459 list_type, tuple_type):
2461 return py_object_type
2463 def calculate_constant_result(self):
2464 self.constant_result = self.base.constant_result[
2465 self.start.constant_result : self.stop.constant_result]
2467 def compile_time_value(self, denv):
2468 base = self.base.compile_time_value(denv)
2469 if self.start is None:
2472 start = self.start.compile_time_value(denv)
2473 if self.stop is None:
2476 stop = self.stop.compile_time_value(denv)
2478 return base[start:stop]
2479 except Exception, e:
2480 self.compile_time_value_error(e)
2482 def analyse_target_declaration(self, env):
2485 def analyse_target_types(self, env):
2486 self.analyse_types(env)
2487 # when assigning, we must accept any Python type
2488 if self.type.is_pyobject:
2489 self.type = py_object_type
2491 def analyse_types(self, env):
2492 self.base.analyse_types(env)
2494 self.start.analyse_types(env)
2496 self.stop.analyse_types(env)
2497 base_type = self.base.type
2498 if base_type.is_string:
2499 self.type = bytes_type
2500 elif base_type.is_ptr:
2501 self.type = base_type
2502 elif base_type.is_array:
2503 # we need a ptr type here instead of an array type, as
2504 # array types can result in invalid type casts in the C
2506 self.type = PyrexTypes.CPtrType(base_type.base_type)
2508 self.base = self.base.coerce_to_pyobject(env)
2509 self.type = py_object_type
2510 if base_type.is_builtin_type:
2511 # slicing builtin types returns something of the same type
2512 self.type = base_type
2513 c_int = PyrexTypes.c_py_ssize_t_type
2515 self.start = self.start.coerce_to(c_int, env)
2517 self.stop = self.stop.coerce_to(c_int, env)
2520 nogil_check = Node.gil_error
2521 gil_message = "Slicing Python object"
2523 def generate_result_code(self, code):
2524 if not self.type.is_pyobject:
2526 "Slicing is not currently supported for '%s'." % self.type)
2528 if self.base.type.is_string:
2529 if self.stop is None:
2531 "%s = PyBytes_FromString(%s + %s); %s" % (
2535 code.error_goto_if_null(self.result(), self.pos)))
2538 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2544 code.error_goto_if_null(self.result(), self.pos)))
2547 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2549 self.base.py_result(),
2552 code.error_goto_if_null(self.result(), self.pos)))
2553 code.put_gotref(self.py_result())
2555 def generate_assignment_code(self, rhs, code):
2556 self.generate_subexpr_evaluation_code(code)
2557 if self.type.is_pyobject:
2558 code.put_error_if_neg(self.pos,
2559 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2560 self.base.py_result(),
2567 start_offset = self.start_code()
2568 if start_offset == '0':
2572 if rhs.type.is_array:
2573 array_length = rhs.type.size
2574 self.generate_slice_guard_code(code, array_length)
2577 "Slice assignments from pointers are not yet supported.")
2578 # FIXME: fix the array size according to start/stop
2579 array_length = self.base.type.size
2580 for i in range(array_length):
2581 code.putln("%s[%s%s] = %s[%d];" % (
2582 self.base.result(), start_offset, i,
2584 self.generate_subexpr_disposal_code(code)
2585 self.free_subexpr_temps(code)
2586 rhs.generate_disposal_code(code)
2587 rhs.free_temps(code)
2589 def generate_deletion_code(self, code):
2590 if not self.base.type.is_pyobject:
2592 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2594 self.generate_subexpr_evaluation_code(code)
2595 code.put_error_if_neg(self.pos,
2596 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2597 self.base.py_result(),
2600 self.generate_subexpr_disposal_code(code)
2602 def generate_slice_guard_code(self, code, target_size):
2603 if not self.base.type.is_array:
2605 slice_size = self.base.type.size
2608 stop = self.stop.result()
2612 slice_size = self.base.type.size + stop
2619 start = self.start.result()
2623 start = self.base.type.size + start
2631 error(self.pos, "Assignment to empty slice.")
2632 elif start is None and stop is None:
2633 # we know the exact slice length
2634 if target_size != slice_size:
2635 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2636 slice_size, target_size))
2637 elif start is not None:
2640 check = "(%s)-(%s)" % (stop, start)
2641 else: # stop is not None:
2644 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2645 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));' % (
2646 target_size, check))
2647 code.putln(code.error_goto(self.pos))
2650 def start_code(self):
2652 return self.start.result()
2656 def stop_code(self):
2658 return self.stop.result()
2659 elif self.base.type.is_array:
2660 return self.base.type.size
2662 return "PY_SSIZE_T_MAX"
2664 def calculate_result_code(self):
2665 # self.result() is not used, but this method must exist
2669 class SliceNode(ExprNode):
2670 # start:stop:step in subscript list
2676 type = py_object_type
2679 def calculate_constant_result(self):
2680 self.constant_result = self.base.constant_result[
2681 self.start.constant_result : \
2682 self.stop.constant_result : \
2683 self.step.constant_result]
2685 def compile_time_value(self, denv):
2686 start = self.start.compile_time_value(denv)
2687 if self.stop is None:
2690 stop = self.stop.compile_time_value(denv)
2691 if self.step is None:
2694 step = self.step.compile_time_value(denv)
2696 return slice(start, stop, step)
2697 except Exception, e:
2698 self.compile_time_value_error(e)
2700 subexprs = ['start', 'stop', 'step']
2702 def analyse_types(self, env):
2703 self.start.analyse_types(env)
2704 self.stop.analyse_types(env)
2705 self.step.analyse_types(env)
2706 self.start = self.start.coerce_to_pyobject(env)
2707 self.stop = self.stop.coerce_to_pyobject(env)
2708 self.step = self.step.coerce_to_pyobject(env)
2710 gil_message = "Constructing Python slice object"
2712 def generate_result_code(self, code):
2714 "%s = PySlice_New(%s, %s, %s); %s" % (
2716 self.start.py_result(),
2717 self.stop.py_result(),
2718 self.step.py_result(),
2719 code.error_goto_if_null(self.result(), self.pos)))
2720 code.put_gotref(self.py_result())
2723 class CallNode(ExprNode):
2725 # allow overriding the default 'may_be_none' behaviour
2726 may_return_none = None
2728 def may_be_none(self):
2729 if self.may_return_none is not None:
2730 return self.may_return_none
2731 return ExprNode.may_be_none(self)
2733 def analyse_as_type_constructor(self, env):
2734 type = self.function.analyse_as_type(env)
2735 if type and type.is_struct_or_union:
2736 args, kwds = self.explicit_args_kwds()
2738 for arg, member in zip(args, type.scope.var_entries):
2739 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2741 items += kwds.key_value_pairs
2742 self.key_value_pairs = items
2743 self.__class__ = DictNode
2744 self.analyse_types(env)
2745 self.coerce_to(type, env)
2747 elif type and type.is_cpp_class:
2748 for arg in self.args:
2749 arg.analyse_types(env)
2750 constructor = type.scope.lookup("<init>")
2751 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2752 self.function.entry = constructor
2753 self.function.set_cname(type.declaration_code(""))
2754 self.analyse_c_function_call(env)
2757 def is_lvalue(self):
2758 return self.type.is_reference
2760 def nogil_check(self, env):
2761 func_type = self.function_type()
2762 if func_type.is_pyobject:
2764 elif not getattr(func_type, 'nogil', False):
2767 gil_message = "Calling gil-requiring function"
2770 class SimpleCallNode(CallNode):
2771 # Function call without keyword, * or ** args.
2775 # arg_tuple ExprNode or None used internally
2776 # self ExprNode or None used internally
2777 # coerced_self ExprNode or None used internally
2778 # wrapper_call bool used internally
2779 # has_optional_args bool used internally
2780 # nogil bool used internally
2782 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2787 wrapper_call = False
2788 has_optional_args = False
2792 def compile_time_value(self, denv):
2793 function = self.function.compile_time_value(denv)
2794 args = [arg.compile_time_value(denv) for arg in self.args]
2796 return function(*args)
2797 except Exception, e:
2798 self.compile_time_value_error(e)
2800 def type_dependencies(self, env):
2801 # TODO: Update when Danilo's C++ code merged in to handle the
2802 # the case of function overloading.
2803 return self.function.type_dependencies(env)
2805 def infer_type(self, env):
2806 function = self.function
2807 func_type = function.infer_type(env)
2808 if isinstance(self.function, NewExprNode):
2809 return PyrexTypes.CPtrType(self.function.class_type)
2810 if func_type.is_ptr:
2811 func_type = func_type.base_type
2812 if func_type.is_cfunction:
2813 return func_type.return_type
2814 elif func_type is type_type:
2815 if function.is_name and function.entry and function.entry.type:
2816 result_type = function.entry.type
2817 if result_type.is_extension_type:
2819 elif result_type.is_builtin_type:
2820 if function.entry.name == 'float':
2821 return PyrexTypes.c_double_type
2822 elif function.entry.name in Builtin.types_that_construct_their_instance:
2824 return py_object_type
2826 def analyse_as_type(self, env):
2827 attr = self.function.as_cython_attribute()
2828 if attr == 'pointer':
2829 if len(self.args) != 1:
2830 error(self.args.pos, "only one type allowed.")
2832 type = self.args[0].analyse_as_type(env)
2834 error(self.args[0].pos, "Unknown type")
2836 return PyrexTypes.CPtrType(type)
2838 def explicit_args_kwds(self):
2839 return self.args, None
2841 def analyse_types(self, env):
2842 if self.analyse_as_type_constructor(env):
2846 self.analysed = True
2847 function = self.function
2848 function.is_called = 1
2849 self.function.analyse_types(env)
2850 if function.is_attribute and function.entry and function.entry.is_cmethod:
2851 # Take ownership of the object from which the attribute
2852 # was obtained, because we need to pass it as 'self'.
2853 self.self = function.obj
2854 function.obj = CloneNode(self.self)
2855 func_type = self.function_type()
2856 if func_type.is_pyobject:
2857 self.arg_tuple = TupleNode(self.pos, args = self.args)
2858 self.arg_tuple.analyse_types(env)
2860 if func_type is Builtin.type_type and function.is_name and \
2861 function.entry and \
2862 function.entry.is_builtin and \
2863 function.entry.name in Builtin.types_that_construct_their_instance:
2864 # calling a builtin type that returns a specific object type
2865 if function.entry.name == 'float':
2866 # the following will come true later on in a transform
2867 self.type = PyrexTypes.c_double_type
2868 self.result_ctype = PyrexTypes.c_double_type
2870 self.type = Builtin.builtin_types[function.entry.name]
2871 self.result_ctype = py_object_type
2872 self.may_return_none = False
2873 elif function.is_name and function.type_entry:
2874 # We are calling an extension type constructor. As
2875 # long as we do not support __new__(), the result type
2877 self.type = function.type_entry.type
2878 self.result_ctype = py_object_type
2879 self.may_return_none = False
2881 self.type = py_object_type
2884 for arg in self.args:
2885 arg.analyse_types(env)
2886 if self.self and func_type.args:
2887 # Coerce 'self' to the type expected by the method.
2888 self_arg = func_type.args[0]
2889 if self_arg.not_none: # C methods must do the None test for self at *call* time
2890 self.self = self.self.as_none_safe_node(
2891 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2892 'PyExc_AttributeError')
2893 expected_type = self_arg.type
2894 self.coerced_self = CloneNode(self.self).coerce_to(
2896 # Insert coerced 'self' argument into argument list.
2897 self.args.insert(0, self.coerced_self)
2898 self.analyse_c_function_call(env)
2900 def function_type(self):
2901 # Return the type of the function being called, coercing a function
2902 # pointer to a function if necessary.
2903 func_type = self.function.type
2904 if func_type.is_ptr:
2905 func_type = func_type.base_type
2908 def analyse_c_function_call(self, env):
2909 if self.function.type is error_type:
2910 self.type = error_type
2912 if self.function.type.is_cpp_class:
2913 overloaded_entry = self.function.type.scope.lookup("operator()")
2914 if overloaded_entry is None:
2915 self.type = PyrexTypes.error_type
2916 self.result_code = "<error>"
2918 elif hasattr(self.function, 'entry'):
2919 overloaded_entry = self.function.entry
2921 overloaded_entry = None
2922 if overloaded_entry:
2923 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2925 self.type = PyrexTypes.error_type
2926 self.result_code = "<error>"
2928 self.function.entry = entry
2929 self.function.type = entry.type
2930 func_type = self.function_type()
2932 func_type = self.function_type()
2933 if not func_type.is_cfunction:
2934 error(self.pos, "Calling non-function type '%s'" % func_type)
2935 self.type = PyrexTypes.error_type
2936 self.result_code = "<error>"
2939 max_nargs = len(func_type.args)
2940 expected_nargs = max_nargs - func_type.optional_arg_count
2941 actual_nargs = len(self.args)
2942 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2943 self.has_optional_args = 1
2946 for i in range(min(max_nargs, actual_nargs)):
2947 formal_type = func_type.args[i].type
2948 self.args[i] = self.args[i].coerce_to(formal_type, env)
2949 for i in range(max_nargs, actual_nargs):
2950 if self.args[i].type.is_pyobject:
2951 error(self.args[i].pos,
2952 "Python object cannot be passed as a varargs parameter")
2953 # Calc result type and code fragment
2954 if isinstance(self.function, NewExprNode):
2955 self.type = PyrexTypes.CPtrType(self.function.class_type)
2957 self.type = func_type.return_type
2958 if self.type.is_pyobject:
2959 self.result_ctype = py_object_type
2961 elif func_type.exception_value is not None \
2962 or func_type.exception_check:
2964 # Called in 'nogil' context?
2965 self.nogil = env.nogil
2967 func_type.exception_check and
2968 func_type.exception_check != '+'):
2969 env.use_utility_code(pyerr_occurred_withgil_utility_code)
2970 # C++ exception handler
2971 if func_type.exception_check == '+':
2972 if func_type.exception_value is None:
2973 env.use_utility_code(cpp_exception_utility_code)
2975 def calculate_result_code(self):
2976 return self.c_call_code()
2978 def c_call_code(self):
2979 func_type = self.function_type()
2980 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2982 formal_args = func_type.args
2984 args = zip(formal_args, self.args)
2985 max_nargs = len(func_type.args)
2986 expected_nargs = max_nargs - func_type.optional_arg_count
2987 actual_nargs = len(self.args)
2988 for formal_arg, actual_arg in args[:expected_nargs]:
2989 arg_code = actual_arg.result_as(formal_arg.type)
2990 arg_list_code.append(arg_code)
2992 if func_type.is_overridable:
2993 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2995 if func_type.optional_arg_count:
2996 if expected_nargs == actual_nargs:
2997 optional_args = 'NULL'
2999 optional_args = "&%s" % self.opt_arg_struct
3000 arg_list_code.append(optional_args)
3002 for actual_arg in self.args[len(formal_args):]:
3003 arg_list_code.append(actual_arg.result())
3004 result = "%s(%s)" % (self.function.result(),
3005 ', '.join(arg_list_code))
3008 def generate_result_code(self, code):
3009 func_type = self.function_type()
3010 if func_type.is_pyobject:
3011 arg_code = self.arg_tuple.py_result()
3013 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3015 self.function.py_result(),
3017 code.error_goto_if_null(self.result(), self.pos)))
3018 code.put_gotref(self.py_result())
3019 elif func_type.is_cfunction:
3020 if self.has_optional_args:
3021 actual_nargs = len(self.args)
3022 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3023 self.opt_arg_struct = code.funcstate.allocate_temp(
3024 func_type.op_arg_struct.base_type, manage_ref=True)
3025 code.putln("%s.%s = %s;" % (
3026 self.opt_arg_struct,
3027 Naming.pyrex_prefix + "n",
3028 len(self.args) - expected_nargs))
3029 args = zip(func_type.args, self.args)
3030 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3031 code.putln("%s.%s = %s;" % (
3032 self.opt_arg_struct,
3033 func_type.opt_arg_cname(formal_arg.name),
3034 actual_arg.result_as(formal_arg.type)))
3036 if self.type.is_pyobject and self.is_temp:
3037 exc_checks.append("!%s" % self.result())
3039 exc_val = func_type.exception_value
3040 exc_check = func_type.exception_check
3041 if exc_val is not None:
3042 exc_checks.append("%s == %s" % (self.result(), exc_val))
3045 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3047 exc_checks.append("PyErr_Occurred()")
3048 if self.is_temp or exc_checks:
3049 rhs = self.c_call_code()
3051 lhs = "%s = " % self.result()
3052 if self.is_temp and self.type.is_pyobject:
3053 #return_type = self.type # func_type.return_type
3054 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3055 # "from", return_type, "to pyobject" ###
3056 rhs = typecast(py_object_type, self.type, rhs)
3059 if func_type.exception_check == '+':
3060 if func_type.exception_value is None:
3061 raise_py_exception = "__Pyx_CppExn2PyErr()"
3062 elif func_type.exception_value.type.is_pyobject:
3063 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3064 func_type.exception_value.entry.cname,
3065 func_type.exception_value.entry.cname)
3067 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3069 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3071 "try {%s%s;} catch(...) {%s; %s}" % (
3075 code.error_goto(self.pos)))
3078 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3081 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3082 if self.type.is_pyobject and self.result():
3083 code.put_gotref(self.py_result())
3084 if self.has_optional_args:
3085 code.funcstate.release_temp(self.opt_arg_struct)
3088 class PythonCapiFunctionNode(ExprNode):
3090 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3094 self.type = func_type
3095 self.utility_code = utility_code
3097 def analyse_types(self, env):
3100 def generate_result_code(self, code):
3101 if self.utility_code:
3102 code.globalstate.use_utility_code(self.utility_code)
3104 def calculate_result_code(self):
3107 class PythonCapiCallNode(SimpleCallNode):
3108 # Python C-API Function call (only created in transforms)
3110 # By default, we assume that the call never returns None, as this
3111 # is true for most C-API functions in CPython. If this does not
3112 # apply to a call, set the following to True (or None to inherit
3113 # the default behaviour).
3114 may_return_none = False
3116 def __init__(self, pos, function_name, func_type,
3117 utility_code = None, py_name=None, **kwargs):
3118 self.type = func_type.return_type
3119 self.result_ctype = self.type
3120 self.function = PythonCapiFunctionNode(
3121 pos, py_name, function_name, func_type,
3122 utility_code = utility_code)
3123 # call this last so that we can override the constructed
3124 # attributes above with explicit keyword arguments if required
3125 SimpleCallNode.__init__(self, pos, **kwargs)
3128 class GeneralCallNode(CallNode):
3129 # General Python function call, including keyword,
3130 # * and ** arguments.
3133 # positional_args ExprNode Tuple of positional arguments
3134 # keyword_args ExprNode or None Dict of keyword arguments
3135 # starstar_arg ExprNode or None Dict of extra keyword args
3137 type = py_object_type
3139 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3141 nogil_check = Node.gil_error
3143 def compile_time_value(self, denv):
3144 function = self.function.compile_time_value(denv)
3145 positional_args = self.positional_args.compile_time_value(denv)
3146 keyword_args = self.keyword_args.compile_time_value(denv)
3147 starstar_arg = self.starstar_arg.compile_time_value(denv)
3149 keyword_args.update(starstar_arg)
3150 return function(*positional_args, **keyword_args)
3151 except Exception, e:
3152 self.compile_time_value_error(e)
3154 def explicit_args_kwds(self):
3155 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3156 raise PostParseError(self.pos,
3157 'Compile-time keyword arguments must be explicit.')
3158 return self.positional_args.args, self.keyword_args
3160 def analyse_types(self, env):
3161 if self.analyse_as_type_constructor(env):
3163 self.function.analyse_types(env)
3164 self.positional_args.analyse_types(env)
3165 if self.keyword_args:
3166 self.keyword_args.analyse_types(env)
3167 if self.starstar_arg:
3168 self.starstar_arg.analyse_types(env)
3169 if not self.function.type.is_pyobject:
3170 if self.function.type.is_error:
3171 self.type = error_type
3173 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3174 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3176 self.function = self.function.coerce_to_pyobject(env)
3177 self.positional_args = \
3178 self.positional_args.coerce_to_pyobject(env)
3179 if self.starstar_arg:
3180 self.starstar_arg = \
3181 self.starstar_arg.coerce_to_pyobject(env)
3182 function = self.function
3183 if function.is_name and function.type_entry:
3184 # We are calling an extension type constructor. As long
3185 # as we do not support __new__(), the result type is clear
3186 self.type = function.type_entry.type
3187 self.result_ctype = py_object_type
3188 self.may_return_none = False
3190 self.type = py_object_type
3193 def generate_result_code(self, code):
3194 if self.type.is_error: return
3195 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3196 if self.keyword_args and self.starstar_arg:
3197 code.put_error_if_neg(self.pos,
3198 "PyDict_Update(%s, %s)" % (
3199 self.keyword_args.py_result(),
3200 self.starstar_arg.py_result()))
3201 keyword_code = self.keyword_args.py_result()
3202 elif self.keyword_args:
3203 keyword_code = self.keyword_args.py_result()
3204 elif self.starstar_arg:
3205 keyword_code = self.starstar_arg.py_result()
3206 if self.starstar_arg.type is not Builtin.dict_type:
3207 # CPython supports calling functions with non-dicts, so do we
3208 code.globalstate.use_utility_code(kwargs_call_utility_code)
3209 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3212 if not keyword_code:
3213 call_code = "PyObject_Call(%s, %s, NULL)" % (
3214 self.function.py_result(),
3215 self.positional_args.py_result())
3217 call_code = "%s(%s, %s, %s)" % (
3218 kwargs_call_function,
3219 self.function.py_result(),
3220 self.positional_args.py_result(),
3226 code.error_goto_if_null(self.result(), self.pos)))
3227 code.put_gotref(self.py_result())
3230 class AsTupleNode(ExprNode):
3231 # Convert argument to tuple. Used for normalising
3232 # the * argument of a function call.
3238 def calculate_constant_result(self):
3239 self.constant_result = tuple(self.base.constant_result)
3241 def compile_time_value(self, denv):
3242 arg = self.arg.compile_time_value(denv)
3245 except Exception, e:
3246 self.compile_time_value_error(e)
3248 def analyse_types(self, env):
3249 self.arg.analyse_types(env)
3250 self.arg = self.arg.coerce_to_pyobject(env)
3251 self.type = tuple_type
3254 def may_be_none(self):
3257 nogil_check = Node.gil_error
3258 gil_message = "Constructing Python tuple"
3260 def generate_result_code(self, code):
3262 "%s = PySequence_Tuple(%s); %s" % (
3264 self.arg.py_result(),
3265 code.error_goto_if_null(self.result(), self.pos)))
3266 code.put_gotref(self.py_result())
3269 class AttributeNode(ExprNode):
3274 # needs_none_check boolean Used if obj is an extension type.
3275 # If set to True, it is known that the type is not None.
3279 # is_py_attr boolean Is a Python getattr operation
3280 # member string C name of struct member
3281 # is_called boolean Function call is being done on result
3282 # entry Entry Symbol table entry of attribute
3287 type = PyrexTypes.error_type
3290 needs_none_check = True
3292 def as_cython_attribute(self):
3293 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3294 return self.attribute
3295 cy = self.obj.as_cython_attribute()
3297 return "%s.%s" % (cy, self.attribute)
3299 def coerce_to(self, dst_type, env):
3300 # If coercing to a generic pyobject and this is a cpdef function
3301 # we can create the corresponding attribute
3302 if dst_type is py_object_type:
3304 if entry and entry.is_cfunction and entry.as_variable:
3305 # must be a cpdef function
3307 self.entry = entry.as_variable
3308 self.analyse_as_python_attribute(env)
3310 return ExprNode.coerce_to(self, dst_type, env)
3312 def calculate_constant_result(self):
3313 attr = self.attribute
3314 if attr.startswith("__") and attr.endswith("__"):
3316 self.constant_result = getattr(self.obj.constant_result, attr)
3318 def compile_time_value(self, denv):
3319 attr = self.attribute
3320 if attr.startswith("__") and attr.endswith("__"):
3322 "Invalid attribute name '%s' in compile-time expression" % attr)
3324 obj = self.obj.compile_time_value(denv)
3326 return getattr(obj, attr)
3327 except Exception, e:
3328 self.compile_time_value_error(e)
3330 def type_dependencies(self, env):
3331 return self.obj.type_dependencies(env)
3333 def infer_type(self, env):
3334 if self.analyse_as_cimported_attribute(env, 0):
3335 return self.entry.type
3336 elif self.analyse_as_unbound_cmethod(env):
3337 return self.entry.type
3339 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3342 def analyse_target_declaration(self, env):
3345 def analyse_target_types(self, env):
3346 self.analyse_types(env, target = 1)
3348 def analyse_types(self, env, target = 0):
3349 if self.analyse_as_cimported_attribute(env, target):
3351 if not target and self.analyse_as_unbound_cmethod(env):
3353 self.analyse_as_ordinary_attribute(env, target)
3355 def analyse_as_cimported_attribute(self, env, target):
3356 # Try to interpret this as a reference to an imported
3357 # C const, type, var or function. If successful, mutates
3358 # this node into a NameNode and returns 1, otherwise
3360 module_scope = self.obj.analyse_as_module(env)
3362 entry = module_scope.lookup_here(self.attribute)
3364 entry.is_cglobal or entry.is_cfunction
3365 or entry.is_type or entry.is_const):
3366 self.mutate_into_name_node(env, entry, target)
3370 def analyse_as_unbound_cmethod(self, env):
3371 # Try to interpret this as a reference to an unbound
3372 # C method of an extension type. If successful, mutates
3373 # this node into a NameNode and returns 1, otherwise
3375 type = self.obj.analyse_as_extension_type(env)
3377 entry = type.scope.lookup_here(self.attribute)
3378 if entry and entry.is_cmethod:
3379 # Create a temporary entry describing the C method
3380 # as an ordinary function.
3381 ubcm_entry = Symtab.Entry(entry.name,
3382 "%s->%s" % (type.vtabptr_cname, entry.cname),
3384 ubcm_entry.is_cfunction = 1
3385 ubcm_entry.func_cname = entry.func_cname
3386 ubcm_entry.is_unbound_cmethod = 1
3387 self.mutate_into_name_node(env, ubcm_entry, None)
3391 def analyse_as_type(self, env):
3392 module_scope = self.obj.analyse_as_module(env)
3394 return module_scope.lookup_type(self.attribute)
3395 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3396 base_type = self.obj.analyse_as_type(env)
3397 if base_type and hasattr(base_type, 'scope'):
3398 return base_type.scope.lookup_type(self.attribute)
3401 def analyse_as_extension_type(self, env):
3402 # Try to interpret this as a reference to an extension type
3403 # in a cimported module. Returns the extension type, or None.
3404 module_scope = self.obj.analyse_as_module(env)
3406 entry = module_scope.lookup_here(self.attribute)
3407 if entry and entry.is_type and entry.type.is_extension_type:
3411 def analyse_as_module(self, env):
3412 # Try to interpret this as a reference to a cimported module
3413 # in another cimported module. Returns the module scope, or None.
3414 module_scope = self.obj.analyse_as_module(env)
3416 entry = module_scope.lookup_here(self.attribute)
3417 if entry and entry.as_module:
3418 return entry.as_module
3421 def mutate_into_name_node(self, env, entry, target):
3422 # Mutate this node into a NameNode and complete the
3423 # analyse_types phase.
3424 self.__class__ = NameNode
3425 self.name = self.attribute
3430 NameNode.analyse_target_types(self, env)
3432 NameNode.analyse_rvalue_entry(self, env)
3434 def analyse_as_ordinary_attribute(self, env, target):
3435 self.obj.analyse_types(env)
3436 self.analyse_attribute(env)
3437 if self.entry and self.entry.is_cmethod and not self.is_called:
3438 # error(self.pos, "C method can only be called")
3440 ## Reference to C array turns into pointer to first element.
3441 #while self.type.is_array:
3442 # self.type = self.type.element_ptr_type()
3446 self.result_ctype = py_object_type
3448 def analyse_attribute(self, env, obj_type = None):
3449 # Look up attribute and set self.type and self.member.
3451 self.member = self.attribute
3452 if obj_type is None:
3453 if self.obj.type.is_string:
3454 self.obj = self.obj.coerce_to_pyobject(env)
3455 obj_type = self.obj.type
3457 if obj_type.is_string:
3458 obj_type = py_object_type
3459 if obj_type.is_ptr or obj_type.is_array:
3460 obj_type = obj_type.base_type
3462 elif obj_type.is_extension_type:
3466 if obj_type.has_attributes:
3468 if obj_type.attributes_known():
3469 entry = obj_type.scope.lookup_here(self.attribute)
3470 if entry and entry.is_member:
3474 "Cannot select attribute of incomplete type '%s'"
3476 self.type = PyrexTypes.error_type
3480 if obj_type.is_extension_type and entry.name == "__weakref__":
3481 error(self.pos, "Illegal use of special attribute __weakref__")
3482 # methods need the normal attribute lookup
3483 # because they do not have struct entries
3484 if entry.is_variable or entry.is_cmethod:
3485 self.type = entry.type
3486 self.member = entry.cname
3489 # If it's not a variable or C method, it must be a Python
3490 # method of an extension type, so we treat it like a Python
3493 # If we get here, the base object is not a struct/union/extension
3494 # type, or it is an extension type and the attribute is either not
3495 # declared or is declared as a Python method. Treat it as a Python
3496 # attribute reference.
3497 self.analyse_as_python_attribute(env, obj_type)
3499 def analyse_as_python_attribute(self, env, obj_type = None):
3500 if obj_type is None:
3501 obj_type = self.obj.type
3502 self.member = self.attribute
3503 self.type = py_object_type
3505 if not obj_type.is_pyobject and not obj_type.is_error:
3506 if obj_type.can_coerce_to_pyobject(env):
3507 self.obj = self.obj.coerce_to_pyobject(env)
3510 "Object of type '%s' has no attribute '%s'" %
3511 (obj_type, self.attribute))
3513 def nogil_check(self, env):
3517 gil_message = "Accessing Python attribute"
3519 def is_simple(self):
3521 return self.result_in_temp() or self.obj.is_simple()
3523 return NameNode.is_simple(self)
3525 def is_lvalue(self):
3529 return NameNode.is_lvalue(self)
3531 def is_ephemeral(self):
3533 return self.obj.is_ephemeral()
3535 return NameNode.is_ephemeral(self)
3537 def calculate_result_code(self):
3538 #print "AttributeNode.calculate_result_code:", self.member ###
3539 #print "...obj node =", self.obj, "code", self.obj.result() ###
3540 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3542 obj_code = obj.result_as(obj.type)
3543 #print "...obj_code =", obj_code ###
3544 if self.entry and self.entry.is_cmethod:
3545 if obj.type.is_extension_type:
3546 return "((struct %s *)%s%s%s)->%s" % (
3547 obj.type.vtabstruct_cname, obj_code, self.op,
3548 obj.type.vtabslot_cname, self.member)
3551 elif obj.type.is_complex:
3552 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3554 return "%s%s%s" % (obj_code, self.op, self.member)
3556 def generate_result_code(self, code):
3557 interned_attr_cname = code.intern_identifier(self.attribute)
3560 '%s = PyObject_GetAttr(%s, %s); %s' % (
3562 self.obj.py_result(),
3563 interned_attr_cname,
3564 code.error_goto_if_null(self.result(), self.pos)))
3565 code.put_gotref(self.py_result())
3567 # result_code contains what is needed, but we may need to insert
3568 # a check and raise an exception
3569 if (self.obj.type.is_extension_type
3570 and self.needs_none_check
3571 and code.globalstate.directives['nonecheck']):
3572 self.put_nonecheck(code)
3574 def generate_assignment_code(self, rhs, code):
3575 interned_attr_cname = code.intern_identifier(self.attribute)
3576 self.obj.generate_evaluation_code(code)
3578 code.put_error_if_neg(self.pos,
3579 'PyObject_SetAttr(%s, %s, %s)' % (
3580 self.obj.py_result(),
3581 interned_attr_cname,
3583 rhs.generate_disposal_code(code)
3584 rhs.free_temps(code)
3585 elif self.obj.type.is_complex:
3586 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3587 self.member.upper(),
3588 self.obj.result_as(self.obj.type),
3589 rhs.result_as(self.ctype())))
3591 if (self.obj.type.is_extension_type
3592 and self.needs_none_check
3593 and code.globalstate.directives['nonecheck']):
3594 self.put_nonecheck(code)
3596 select_code = self.result()
3597 if self.type.is_pyobject and self.use_managed_ref:
3598 rhs.make_owned_reference(code)
3599 code.put_giveref(rhs.py_result())
3600 code.put_gotref(select_code)
3601 code.put_decref(select_code, self.ctype())
3605 rhs.result_as(self.ctype())))
3607 rhs.generate_post_assignment_code(code)
3608 rhs.free_temps(code)
3609 self.obj.generate_disposal_code(code)
3610 self.obj.free_temps(code)
3612 def generate_deletion_code(self, code):
3613 interned_attr_cname = code.intern_identifier(self.attribute)
3614 self.obj.generate_evaluation_code(code)
3615 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3616 and self.entry.scope.entries.has_key(u'__del__')):
3617 code.put_error_if_neg(self.pos,
3618 'PyObject_DelAttr(%s, %s)' % (
3619 self.obj.py_result(),
3620 interned_attr_cname))
3622 error(self.pos, "Cannot delete C attribute of extension type")
3623 self.obj.generate_disposal_code(code)
3624 self.obj.free_temps(code)
3626 def annotate(self, code):
3628 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3630 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3632 def put_nonecheck(self, code):
3633 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3634 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3635 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3636 code.putln(code.error_goto(self.pos))
3640 #-------------------------------------------------------------------
3644 #-------------------------------------------------------------------
3646 class StarredTargetNode(ExprNode):
3647 # A starred expression like "*a"
3649 # This is only allowed in sequence assignment targets such as
3651 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3653 # and will be removed during type analysis (or generate an error
3654 # if it's found at unexpected places).
3658 subexprs = ['target']
3660 type = py_object_type
3663 def __init__(self, pos, target):
3665 self.target = target
3667 def analyse_declarations(self, env):
3668 error(self.pos, "can use starred expression only as assignment target")
3669 self.target.analyse_declarations(env)
3671 def analyse_types(self, env):
3672 error(self.pos, "can use starred expression only as assignment target")
3673 self.target.analyse_types(env)
3674 self.type = self.target.type
3676 def analyse_target_declaration(self, env):
3677 self.target.analyse_target_declaration(env)
3679 def analyse_target_types(self, env):
3680 self.target.analyse_target_types(env)
3681 self.type = self.target.type
3683 def calculate_result_code(self):
3686 def generate_result_code(self, code):
3690 class SequenceNode(ExprNode):
3691 # Base class for list and tuple constructor nodes.
3692 # Contains common code for performing sequence unpacking.
3696 # unpacked_items [ExprNode] or None
3697 # coerced_unpacked_items [ExprNode] or None
3701 is_sequence_constructor = 1
3702 unpacked_items = None
3704 def compile_time_value_list(self, denv):
3705 return [arg.compile_time_value(denv) for arg in self.args]
3707 def replace_starred_target_node(self):
3708 # replace a starred node in the targets by the contained expression
3709 self.starred_assignment = False
3711 for arg in self.args:
3713 if self.starred_assignment:
3714 error(arg.pos, "more than 1 starred expression in assignment")
3715 self.starred_assignment = True
3717 arg.is_starred = True
3721 def analyse_target_declaration(self, env):
3722 self.replace_starred_target_node()
3723 for arg in self.args:
3724 arg.analyse_target_declaration(env)
3726 def analyse_types(self, env, skip_children=False):
3727 for i in range(len(self.args)):
3729 if not skip_children: arg.analyse_types(env)
3730 self.args[i] = arg.coerce_to_pyobject(env)
3732 # not setting self.type here, subtypes do this
3734 def may_be_none(self):
3737 def analyse_target_types(self, env):
3738 self.iterator = PyTempNode(self.pos, env)
3739 self.unpacked_items = []
3740 self.coerced_unpacked_items = []
3741 for arg in self.args:
3742 arg.analyse_target_types(env)
3744 if not arg.type.assignable_from(Builtin.list_type):
3746 "starred target must have Python object (list) type")
3747 if arg.type is py_object_type:
3748 arg.type = Builtin.list_type
3749 unpacked_item = PyTempNode(self.pos, env)
3750 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3751 self.unpacked_items.append(unpacked_item)
3752 self.coerced_unpacked_items.append(coerced_unpacked_item)
3753 self.type = py_object_type
3755 def generate_result_code(self, code):
3756 self.generate_operation_code(code)
3758 def generate_assignment_code(self, rhs, code):
3759 if self.starred_assignment:
3760 self.generate_starred_assignment_code(rhs, code)
3762 self.generate_parallel_assignment_code(rhs, code)
3764 for item in self.unpacked_items:
3766 rhs.free_temps(code)
3768 def generate_parallel_assignment_code(self, rhs, code):
3769 # Need to work around the fact that generate_evaluation_code
3770 # allocates the temps in a rather hacky way -- the assignment
3771 # is evaluated twice, within each if-block.
3773 if rhs.type is tuple_type:
3774 tuple_check = "likely(%s != Py_None)"
3776 tuple_check = "PyTuple_CheckExact(%s)"
3778 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3779 tuple_check % rhs.py_result(),
3782 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3783 for item in self.unpacked_items:
3785 for i in range(len(self.args)):
3786 item = self.unpacked_items[i]
3788 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3791 code.put_incref(item.result(), item.ctype())
3792 value_node = self.coerced_unpacked_items[i]
3793 value_node.generate_evaluation_code(code)
3794 rhs.generate_disposal_code(code)
3796 for i in range(len(self.args)):
3797 self.args[i].generate_assignment_code(
3798 self.coerced_unpacked_items[i], code)
3800 code.putln("} else {")
3802 if rhs.type is tuple_type:
3803 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3804 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3805 rhs.py_result(), len(self.args)))
3806 code.putln(code.error_goto(self.pos))
3808 code.globalstate.use_utility_code(unpacking_utility_code)
3810 self.iterator.allocate(code)
3812 "%s = PyObject_GetIter(%s); %s" % (
3813 self.iterator.result(),
3815 code.error_goto_if_null(self.iterator.result(), self.pos)))
3816 code.put_gotref(self.iterator.py_result())
3817 rhs.generate_disposal_code(code)
3818 for i in range(len(self.args)):
3819 item = self.unpacked_items[i]
3820 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3821 self.iterator.py_result(), i)
3825 typecast(item.ctype(), py_object_type, unpack_code),
3826 code.error_goto_if_null(item.result(), self.pos)))
3827 code.put_gotref(item.py_result())
3828 value_node = self.coerced_unpacked_items[i]
3829 value_node.generate_evaluation_code(code)
3830 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3831 self.iterator.py_result(),
3833 if debug_disposal_code:
3834 print("UnpackNode.generate_assignment_code:")
3835 print("...generating disposal code for %s" % self.iterator)
3836 self.iterator.generate_disposal_code(code)
3837 self.iterator.free_temps(code)
3838 self.iterator.release(code)
3840 for i in range(len(self.args)):
3841 self.args[i].generate_assignment_code(
3842 self.coerced_unpacked_items[i], code)
3846 def generate_starred_assignment_code(self, rhs, code):
3847 code.globalstate.use_utility_code(unpacking_utility_code)
3849 for i, arg in enumerate(self.args):
3851 starred_target = self.unpacked_items[i]
3852 fixed_args_left = self.args[:i]
3853 fixed_args_right = self.args[i+1:]
3856 self.iterator.allocate(code)
3858 "%s = PyObject_GetIter(%s); %s" % (
3859 self.iterator.result(),
3861 code.error_goto_if_null(self.iterator.result(), self.pos)))
3862 code.put_gotref(self.iterator.py_result())
3863 rhs.generate_disposal_code(code)
3865 for item in self.unpacked_items:
3867 for i in range(len(fixed_args_left)):
3868 item = self.unpacked_items[i]
3869 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3870 self.iterator.py_result(), i)
3874 typecast(item.ctype(), py_object_type, unpack_code),
3875 code.error_goto_if_null(item.result(), self.pos)))
3876 code.put_gotref(item.py_result())
3877 value_node = self.coerced_unpacked_items[i]
3878 value_node.generate_evaluation_code(code)
3880 target_list = starred_target.result()
3881 code.putln("%s = PySequence_List(%s); %s" % (
3882 target_list, self.iterator.py_result(),
3883 code.error_goto_if_null(target_list, self.pos)))
3884 code.put_gotref(target_list)
3885 if fixed_args_right:
3886 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3887 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3888 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3889 (target_list, len(unpacked_right_args))))
3890 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3891 len(fixed_args_left), target_list,
3892 code.error_goto(self.pos)))
3894 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3895 self.coerced_unpacked_items[::-1])):
3897 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3899 target_list, target_list))
3900 # resize the list the hard way
3901 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3902 code.put_gotref(arg.py_result())
3903 coerced_arg.generate_evaluation_code(code)
3905 self.iterator.generate_disposal_code(code)
3906 self.iterator.free_temps(code)
3907 self.iterator.release(code)
3909 for i in range(len(self.args)):
3910 self.args[i].generate_assignment_code(
3911 self.coerced_unpacked_items[i], code)
3913 def annotate(self, code):
3914 for arg in self.args:
3916 if self.unpacked_items:
3917 for arg in self.unpacked_items:
3919 for arg in self.coerced_unpacked_items:
3923 class TupleNode(SequenceNode):
3924 # Tuple constructor.
3928 gil_message = "Constructing Python tuple"
3930 def analyse_types(self, env, skip_children=False):
3931 if len(self.args) == 0:
3935 SequenceNode.analyse_types(self, env, skip_children)
3936 for child in self.args:
3937 if not child.is_literal:
3943 def calculate_result_code(self):
3944 if len(self.args) > 0:
3945 return self.result_code
3947 return Naming.empty_tuple
3949 def calculate_constant_result(self):
3950 self.constant_result = tuple([
3951 arg.constant_result for arg in self.args])
3953 def compile_time_value(self, denv):
3954 values = self.compile_time_value_list(denv)
3956 return tuple(values)
3957 except Exception, e:
3958 self.compile_time_value_error(e)
3960 def generate_operation_code(self, code):
3961 if len(self.args) == 0:
3962 # result_code is Naming.empty_tuple
3965 # non-empty cached tuple => result is global constant,
3966 # creation code goes into separate code writer
3967 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
3968 code = code.get_cached_constants_writer()
3969 code.mark_pos(self.pos)
3972 "%s = PyTuple_New(%s); %s" % (
3975 code.error_goto_if_null(self.result(), self.pos)))
3976 code.put_gotref(self.py_result())
3977 for i in range(len(self.args)):
3979 if not arg.result_in_temp():
3980 code.put_incref(arg.result(), arg.ctype())
3982 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3986 code.put_giveref(arg.py_result())
3988 code.put_giveref(self.py_result())
3990 def generate_subexpr_disposal_code(self, code):
3991 # We call generate_post_assignment_code here instead
3992 # of generate_disposal_code, because values were stored
3993 # in the tuple using a reference-stealing operation.
3994 for arg in self.args:
3995 arg.generate_post_assignment_code(code)
3996 # Should NOT call free_temps -- this is invoked by the default
3997 # generate_evaluation_code which will do that.
4000 class ListNode(SequenceNode):
4003 # obj_conversion_errors [PyrexError] used internally
4004 # orignial_args [ExprNode] used internally
4006 obj_conversion_errors = []
4009 gil_message = "Constructing Python list"
4011 def type_dependencies(self, env):
4014 def infer_type(self, env):
4015 # TOOD: Infer non-object list arrays.
4018 def analyse_expressions(self, env):
4019 SequenceNode.analyse_expressions(self, env)
4020 self.coerce_to_pyobject(env)
4022 def analyse_types(self, env):
4024 self.original_args = list(self.args)
4025 SequenceNode.analyse_types(self, env)
4026 self.obj_conversion_errors = held_errors()
4027 release_errors(ignore=True)
4029 def coerce_to(self, dst_type, env):
4030 if dst_type.is_pyobject:
4031 for err in self.obj_conversion_errors:
4033 self.obj_conversion_errors = []
4034 if not self.type.subtype_of(dst_type):
4035 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4036 elif dst_type.is_ptr:
4037 base_type = dst_type.base_type
4038 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4039 for i in range(len(self.original_args)):
4041 if isinstance(arg, CoerceToPyTypeNode):
4043 self.args[i] = arg.coerce_to(base_type, env)
4044 elif dst_type.is_struct:
4045 if len(self.args) > len(dst_type.scope.var_entries):
4046 error(self.pos, "Too may members for '%s'" % dst_type)
4048 if len(self.args) < len(dst_type.scope.var_entries):
4049 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4050 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4051 if isinstance(arg, CoerceToPyTypeNode):
4053 self.args[i] = arg.coerce_to(member.type, env)
4054 self.type = dst_type
4056 self.type = error_type
4057 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4060 def release_temp(self, env):
4061 if self.type.is_array:
4062 # To be valid C++, we must allocate the memory on the stack
4063 # manually and be sure not to reuse it for something else.
4066 SequenceNode.release_temp(self, env)
4068 def calculate_constant_result(self):
4069 self.constant_result = [
4070 arg.constant_result for arg in self.args]
4072 def compile_time_value(self, denv):
4073 return self.compile_time_value_list(denv)
4075 def generate_operation_code(self, code):
4076 if self.type.is_pyobject:
4077 for err in self.obj_conversion_errors:
4079 code.putln("%s = PyList_New(%s); %s" %
4082 code.error_goto_if_null(self.result(), self.pos)))
4083 code.put_gotref(self.py_result())
4084 for i in range(len(self.args)):
4086 #if not arg.is_temp:
4087 if not arg.result_in_temp():
4088 code.put_incref(arg.result(), arg.ctype())
4089 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4093 code.put_giveref(arg.py_result())
4094 elif self.type.is_array:
4095 for i, arg in enumerate(self.args):
4096 code.putln("%s[%s] = %s;" % (
4100 elif self.type.is_struct:
4101 for arg, member in zip(self.args, self.type.scope.var_entries):
4102 code.putln("%s.%s = %s;" % (
4107 raise InternalError("List type never specified")
4109 def generate_subexpr_disposal_code(self, code):
4110 # We call generate_post_assignment_code here instead
4111 # of generate_disposal_code, because values were stored
4112 # in the list using a reference-stealing operation.
4113 for arg in self.args:
4114 arg.generate_post_assignment_code(code)
4115 # Should NOT call free_temps -- this is invoked by the default
4116 # generate_evaluation_code which will do that.
4119 class ScopedExprNode(ExprNode):
4120 # Abstract base class for ExprNodes that have their own local
4121 # scope, such as generator expressions.
4123 # expr_scope Scope the inner scope of the expression
4128 def analyse_types(self, env):
4129 # nothing to do here, the children will be analysed separately
4132 def analyse_expressions(self, env):
4133 # nothing to do here, the children will be analysed separately
4136 def analyse_scoped_expressions(self, env):
4137 # this is called with the expr_scope as env
4140 def init_scope(self, outer_scope, expr_scope=None):
4141 self.expr_scope = expr_scope
4144 class ComprehensionNode(ScopedExprNode):
4145 subexprs = ["target"]
4146 child_attrs = ["loop", "append"]
4148 # leak loop variables or not? non-leaking Py3 behaviour is
4149 # default, except for list comprehensions where the behaviour
4150 # differs in Py2 and Py3 (see Parsing.py)
4151 has_local_scope = True
4153 def infer_type(self, env):
4154 return self.target.infer_type(env)
4156 def analyse_declarations(self, env):
4157 self.append.target = self # this is used in the PyList_Append of the inner loop
4158 self.init_scope(env)
4159 self.loop.analyse_declarations(self.expr_scope or env)
4161 def init_scope(self, outer_scope, expr_scope=None):
4162 if expr_scope is not None:
4163 self.expr_scope = expr_scope
4164 elif self.has_local_scope:
4165 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4167 self.expr_scope = None
4169 def analyse_types(self, env):
4170 self.target.analyse_expressions(env)
4171 self.type = self.target.type
4172 if not self.has_local_scope:
4173 self.loop.analyse_expressions(env)
4175 def analyse_expressions(self, env):
4176 self.analyse_types(env)
4178 def analyse_scoped_expressions(self, env):
4179 if self.has_local_scope:
4180 self.loop.analyse_expressions(env)
4182 def may_be_none(self):
4185 def calculate_result_code(self):
4186 return self.target.result()
4188 def generate_result_code(self, code):
4189 self.generate_operation_code(code)
4191 def generate_operation_code(self, code):
4192 self.loop.generate_execution_code(code)
4194 def annotate(self, code):
4195 self.loop.annotate(code)
4198 class ComprehensionAppendNode(Node):
4199 # Need to be careful to avoid infinite recursion:
4200 # target must not be in child_attrs/subexprs
4202 child_attrs = ['expr']
4204 type = PyrexTypes.c_int_type
4206 def analyse_expressions(self, env):
4207 self.expr.analyse_expressions(env)
4208 if not self.expr.type.is_pyobject:
4209 self.expr = self.expr.coerce_to_pyobject(env)
4211 def generate_execution_code(self, code):
4212 if self.target.type is list_type:
4213 function = "PyList_Append"
4214 elif self.target.type is set_type:
4215 function = "PySet_Add"
4217 raise InternalError(
4218 "Invalid type for comprehension node: %s" % self.target.type)
4220 self.expr.generate_evaluation_code(code)
4221 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4223 self.target.result(),
4226 self.expr.generate_disposal_code(code)
4227 self.expr.free_temps(code)
4229 def generate_function_definitions(self, env, code):
4230 self.expr.generate_function_definitions(env, code)
4232 def annotate(self, code):
4233 self.expr.annotate(code)
4235 class DictComprehensionAppendNode(ComprehensionAppendNode):
4236 child_attrs = ['key_expr', 'value_expr']
4238 def analyse_expressions(self, env):
4239 self.key_expr.analyse_expressions(env)
4240 if not self.key_expr.type.is_pyobject:
4241 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4242 self.value_expr.analyse_expressions(env)
4243 if not self.value_expr.type.is_pyobject:
4244 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4246 def generate_execution_code(self, code):
4247 self.key_expr.generate_evaluation_code(code)
4248 self.value_expr.generate_evaluation_code(code)
4249 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4250 self.target.result(),
4251 self.key_expr.result(),
4252 self.value_expr.result()
4254 self.key_expr.generate_disposal_code(code)
4255 self.key_expr.free_temps(code)
4256 self.value_expr.generate_disposal_code(code)
4257 self.value_expr.free_temps(code)
4259 def generate_function_definitions(self, env, code):
4260 self.key_expr.generate_function_definitions(env, code)
4261 self.value_expr.generate_function_definitions(env, code)
4263 def annotate(self, code):
4264 self.key_expr.annotate(code)
4265 self.value_expr.annotate(code)
4268 class GeneratorExpressionNode(ScopedExprNode):
4269 # A generator expression, e.g. (i for i in range(10))
4271 # Result is a generator.
4273 # loop ForStatNode the for-loop, containing a YieldExprNode
4275 child_attrs = ["loop"]
4277 type = py_object_type
4279 def analyse_declarations(self, env):
4280 self.init_scope(env)
4281 self.loop.analyse_declarations(self.expr_scope)
4283 def init_scope(self, outer_scope, expr_scope=None):
4284 if expr_scope is not None:
4285 self.expr_scope = expr_scope
4287 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4289 def analyse_types(self, env):
4292 def analyse_scoped_expressions(self, env):
4293 self.loop.analyse_expressions(env)
4295 def may_be_none(self):
4298 def annotate(self, code):
4299 self.loop.annotate(code)
4302 class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
4303 # An inlined generator expression for which the result is
4304 # calculated inside of the loop. This will only be created by
4305 # transforms when replacing builtin calls on generator
4308 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4309 # result_node ResultRefNode the reference to the result value temp
4310 # orig_func String the name of the builtin function this node replaces
4312 child_attrs = ["loop"]
4314 def analyse_types(self, env):
4315 self.type = self.result_node.type
4318 def coerce_to(self, dst_type, env):
4319 if self.orig_func == 'sum' and dst_type.is_numeric:
4320 # we can optimise by dropping the aggregation variable into C
4321 self.result_node.type = self.type = dst_type
4323 return GeneratorExpressionNode.coerce_to(self, dst_type, env)
4325 def generate_result_code(self, code):
4326 self.result_node.result_code = self.result()
4327 self.loop.generate_execution_code(code)
4330 class SetNode(ExprNode):
4337 gil_message = "Constructing Python set"
4339 def analyse_types(self, env):
4340 for i in range(len(self.args)):
4342 arg.analyse_types(env)
4343 self.args[i] = arg.coerce_to_pyobject(env)
4344 self.type = set_type
4347 def may_be_none(self):
4350 def calculate_constant_result(self):
4351 self.constant_result = set([
4352 arg.constant_result for arg in self.args])
4354 def compile_time_value(self, denv):
4355 values = [arg.compile_time_value(denv) for arg in self.args]
4358 except Exception, e:
4359 self.compile_time_value_error(e)
4361 def generate_evaluation_code(self, code):
4362 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4363 self.allocate_temp_result(code)
4365 "%s = PySet_New(0); %s" % (
4367 code.error_goto_if_null(self.result(), self.pos)))
4368 code.put_gotref(self.py_result())
4369 for arg in self.args:
4370 arg.generate_evaluation_code(code)
4372 code.error_goto_if_neg(
4373 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4375 arg.generate_disposal_code(code)
4376 arg.free_temps(code)
4379 class DictNode(ExprNode):
4380 # Dictionary constructor.
4382 # key_value_pairs [DictItemNode]
4384 # obj_conversion_errors [PyrexError] used internally
4386 subexprs = ['key_value_pairs']
4390 obj_conversion_errors = []
4392 def calculate_constant_result(self):
4393 self.constant_result = dict([
4394 item.constant_result for item in self.key_value_pairs])
4396 def compile_time_value(self, denv):
4397 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4398 for item in self.key_value_pairs]
4401 except Exception, e:
4402 self.compile_time_value_error(e)
4404 def type_dependencies(self, env):
4407 def infer_type(self, env):
4408 # TOOD: Infer struct constructors.
4411 def analyse_types(self, env):
4413 for item in self.key_value_pairs:
4414 item.analyse_types(env)
4415 self.obj_conversion_errors = held_errors()
4416 release_errors(ignore=True)
4418 def may_be_none(self):
4421 def coerce_to(self, dst_type, env):
4422 if dst_type.is_pyobject:
4423 self.release_errors()
4424 if not self.type.subtype_of(dst_type):
4425 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4426 elif dst_type.is_struct_or_union:
4427 self.type = dst_type
4428 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4429 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4430 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4431 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4432 for item in self.key_value_pairs:
4433 if isinstance(item.key, CoerceToPyTypeNode):
4434 item.key = item.key.arg
4435 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4436 error(item.key.pos, "Invalid struct field identifier")
4437 item.key = StringNode(item.key.pos, value="<error>")
4439 key = str(item.key.value) # converts string literals to unicode in Py3
4440 member = dst_type.scope.lookup_here(key)
4442 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4445 if isinstance(value, CoerceToPyTypeNode):
4447 item.value = value.coerce_to(member.type, env)
4449 self.type = error_type
4450 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4453 def release_errors(self):
4454 for err in self.obj_conversion_errors:
4456 self.obj_conversion_errors = []
4458 gil_message = "Constructing Python dict"
4460 def generate_evaluation_code(self, code):
4461 # Custom method used here because key-value
4462 # pairs are evaluated and used one at a time.
4463 code.mark_pos(self.pos)
4464 self.allocate_temp_result(code)
4465 if self.type.is_pyobject:
4466 self.release_errors()
4468 "%s = PyDict_New(); %s" % (
4470 code.error_goto_if_null(self.result(), self.pos)))
4471 code.put_gotref(self.py_result())
4472 for item in self.key_value_pairs:
4473 item.generate_evaluation_code(code)
4474 if self.type.is_pyobject:
4475 code.put_error_if_neg(self.pos,
4476 "PyDict_SetItem(%s, %s, %s)" % (
4478 item.key.py_result(),
4479 item.value.py_result()))
4481 code.putln("%s.%s = %s;" % (
4484 item.value.result()))
4485 item.generate_disposal_code(code)
4486 item.free_temps(code)
4488 def annotate(self, code):
4489 for item in self.key_value_pairs:
4492 class DictItemNode(ExprNode):
4493 # Represents a single item in a DictNode
4497 subexprs = ['key', 'value']
4499 nogil_check = None # Parent DictNode takes care of it
4501 def calculate_constant_result(self):
4502 self.constant_result = (
4503 self.key.constant_result, self.value.constant_result)
4505 def analyse_types(self, env):
4506 self.key.analyse_types(env)
4507 self.value.analyse_types(env)
4508 self.key = self.key.coerce_to_pyobject(env)
4509 self.value = self.value.coerce_to_pyobject(env)
4511 def generate_evaluation_code(self, code):
4512 self.key.generate_evaluation_code(code)
4513 self.value.generate_evaluation_code(code)
4515 def generate_disposal_code(self, code):
4516 self.key.generate_disposal_code(code)
4517 self.value.generate_disposal_code(code)
4519 def free_temps(self, code):
4520 self.key.free_temps(code)
4521 self.value.free_temps(code)
4524 return iter([self.key, self.value])
4526 class ModuleNameMixin(object):
4527 def set_mod_name(self, env):
4528 self.module_name = env.global_scope().qualified_name
4530 def get_py_mod_name(self, code):
4531 return code.get_py_string_const(
4532 self.module_name, identifier=True)
4534 class ClassNode(ExprNode, ModuleNameMixin):
4535 # Helper class used in the implementation of Python
4536 # class definitions. Constructs a class object given
4537 # a name, tuple of bases and class dictionary.
4539 # name EncodedString Name of the class
4540 # bases ExprNode Base class tuple
4541 # dict ExprNode Class dict (not owned by this node)
4542 # doc ExprNode or None Doc string
4543 # module_name EncodedString Name of defining module
4545 subexprs = ['bases', 'doc']
4547 def analyse_types(self, env):
4548 self.bases.analyse_types(env)
4550 self.doc.analyse_types(env)
4551 self.doc = self.doc.coerce_to_pyobject(env)
4552 self.type = py_object_type
4554 env.use_utility_code(create_class_utility_code);
4555 #TODO(craig,haoyu) This should be moved to a better place
4556 self.set_mod_name(env)
4558 def may_be_none(self):
4561 gil_message = "Constructing Python class"
4563 def generate_result_code(self, code):
4564 cname = code.intern_identifier(self.name)
4567 code.put_error_if_neg(self.pos,
4568 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4569 self.dict.py_result(),
4570 self.doc.py_result()))
4571 py_mod_name = self.get_py_mod_name(code)
4573 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4575 self.bases.py_result(),
4576 self.dict.py_result(),
4579 code.error_goto_if_null(self.result(), self.pos)))
4580 code.put_gotref(self.py_result())
4583 class Py3ClassNode(ExprNode):
4584 # Helper class used in the implementation of Python3+
4585 # class definitions. Constructs a class object given
4586 # a name, tuple of bases and class dictionary.
4588 # name EncodedString Name of the class
4589 # dict ExprNode Class dict (not owned by this node)
4590 # module_name EncodedString Name of defining module
4594 def analyse_types(self, env):
4595 self.type = py_object_type
4598 def may_be_none(self):
4601 gil_message = "Constructing Python class"
4603 def generate_result_code(self, code):
4604 code.globalstate.use_utility_code(create_py3class_utility_code)
4605 cname = code.intern_identifier(self.name)
4607 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4609 self.metaclass.result(),
4611 self.bases.py_result(),
4612 self.dict.py_result(),
4613 self.mkw.py_result(),
4614 code.error_goto_if_null(self.result(), self.pos)))
4615 code.put_gotref(self.py_result())
4617 class KeywordArgsNode(ExprNode):
4618 # Helper class for keyword arguments
4620 # keyword_args ExprNode or None Keyword arguments
4621 # starstar_arg ExprNode or None Extra arguments
4623 subexprs = ['keyword_args', 'starstar_arg']
4625 def analyse_types(self, env):
4626 if self.keyword_args:
4627 self.keyword_args.analyse_types(env)
4628 if self.starstar_arg:
4629 self.starstar_arg.analyse_types(env)
4630 # make sure we have a Python object as **kwargs mapping
4631 self.starstar_arg = \
4632 self.starstar_arg.coerce_to_pyobject(env)
4633 self.type = py_object_type
4636 gil_message = "Constructing Keyword Args"
4638 def generate_result_code(self, code):
4639 if self.keyword_args and self.starstar_arg:
4640 code.put_error_if_neg(self.pos,
4641 "PyDict_Update(%s, %s)" % (
4642 self.keyword_args.py_result(),
4643 self.starstar_arg.py_result()))
4644 if self.keyword_args:
4645 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4646 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4647 elif self.starstar_arg:
4649 "%s = PyDict_Copy(%s); %s" % (
4651 self.starstar_arg.py_result(),
4652 code.error_goto_if_null(self.result(), self.pos)))
4653 code.put_gotref(self.py_result())
4656 "%s = PyDict_New(); %s" % (
4658 code.error_goto_if_null(self.result(), self.pos)))
4659 code.put_gotref(self.py_result())
4661 class PyClassMetaclassNode(ExprNode):
4662 # Helper class holds Python3 metaclass object
4664 # bases ExprNode Base class tuple (not owned by this node)
4665 # mkw ExprNode Class keyword arguments (not owned by this node)
4669 def analyse_types(self, env):
4670 self.type = py_object_type
4673 def may_be_none(self):
4676 def generate_result_code(self, code):
4678 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4680 self.bases.result(),
4682 code.error_goto_if_null(self.result(), self.pos)))
4683 code.put_gotref(self.py_result())
4685 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4686 # Helper class holds Python3 namespace object
4688 # All this are not owned by this node
4689 # metaclass ExprNode Metaclass object
4690 # bases ExprNode Base class tuple
4691 # mkw ExprNode Class keyword arguments
4692 # doc ExprNode or None Doc string (owned)
4696 def analyse_types(self, env):
4697 self.bases.analyse_types(env)
4699 self.doc.analyse_types(env)
4700 self.doc = self.doc.coerce_to_pyobject(env)
4701 self.type = py_object_type
4703 #TODO(craig,haoyu) This should be moved to a better place
4704 self.set_mod_name(env)
4706 def may_be_none(self):
4709 def generate_result_code(self, code):
4710 cname = code.intern_identifier(self.name)
4711 py_mod_name = self.get_py_mod_name(code)
4713 doc_code = self.doc.result()
4715 doc_code = '(PyObject *) NULL'
4717 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4719 self.metaclass.result(),
4720 self.bases.result(),
4725 code.error_goto_if_null(self.result(), self.pos)))
4726 code.put_gotref(self.py_result())
4728 class BoundMethodNode(ExprNode):
4729 # Helper class used in the implementation of Python
4730 # class definitions. Constructs an bound method
4731 # object from a class and a function.
4733 # function ExprNode Function object
4734 # self_object ExprNode self object
4736 subexprs = ['function']
4738 def analyse_types(self, env):
4739 self.function.analyse_types(env)
4740 self.type = py_object_type
4743 gil_message = "Constructing an bound method"
4745 def generate_result_code(self, code):
4747 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4749 self.function.py_result(),
4750 self.self_object.py_result(),
4751 self.self_object.py_result(),
4752 code.error_goto_if_null(self.result(), self.pos)))
4753 code.put_gotref(self.py_result())
4755 class UnboundMethodNode(ExprNode):
4756 # Helper class used in the implementation of Python
4757 # class definitions. Constructs an unbound method
4758 # object from a class and a function.
4760 # function ExprNode Function object
4762 type = py_object_type
4765 subexprs = ['function']
4767 def analyse_types(self, env):
4768 self.function.analyse_types(env)
4770 def may_be_none(self):
4773 gil_message = "Constructing an unbound method"
4775 def generate_result_code(self, code):
4776 class_cname = code.pyclass_stack[-1].classobj.result()
4778 "%s = PyMethod_New(%s, 0, %s); %s" % (
4780 self.function.py_result(),
4782 code.error_goto_if_null(self.result(), self.pos)))
4783 code.put_gotref(self.py_result())
4786 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4787 # Helper class used in the implementation of Python
4788 # class definitions. Constructs a PyCFunction object
4789 # from a PyMethodDef struct.
4791 # pymethdef_cname string PyMethodDef structure
4792 # self_object ExprNode or None
4794 # module_name EncodedString Name of defining module
4800 type = py_object_type
4803 def analyse_types(self, env):
4805 env.use_utility_code(binding_cfunc_utility_code)
4807 #TODO(craig,haoyu) This should be moved to a better place
4808 self.set_mod_name(env)
4810 def may_be_none(self):
4813 gil_message = "Constructing Python function"
4815 def self_result_code(self):
4816 if self.self_object is None:
4817 self_result = "NULL"
4819 self_result = self.self_object.py_result()
4822 def generate_result_code(self, code):
4824 constructor = "%s_NewEx" % Naming.binding_cfunc
4826 constructor = "PyCFunction_NewEx"
4827 py_mod_name = self.get_py_mod_name(code)
4829 '%s = %s(&%s, %s, %s); %s' % (
4832 self.pymethdef_cname,
4833 self.self_result_code(),
4835 code.error_goto_if_null(self.result(), self.pos)))
4836 code.put_gotref(self.py_result())
4838 class InnerFunctionNode(PyCFunctionNode):
4839 # Special PyCFunctionNode that depends on a closure class
4843 def self_result_code(self):
4844 return "((PyObject*)%s)" % Naming.cur_scope_cname
4846 class LambdaNode(InnerFunctionNode):
4847 # Lambda expression node (only used as a function reference)
4849 # args [CArgDeclNode] formal arguments
4850 # star_arg PyArgDeclNode or None * argument
4851 # starstar_arg PyArgDeclNode or None ** argument
4852 # lambda_name string a module-globally unique lambda name
4853 # result_expr ExprNode
4854 # def_node DefNode the underlying function 'def' node
4856 child_attrs = ['def_node']
4859 name = StringEncoding.EncodedString('<lambda>')
4861 def analyse_declarations(self, env):
4862 #self.def_node.needs_closure = self.needs_closure
4863 self.def_node.analyse_declarations(env)
4864 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
4865 env.add_lambda_def(self.def_node)
4867 class YieldExprNode(ExprNode):
4868 # Yield expression node
4870 # arg ExprNode the value to return from the generator
4871 # label_name string name of the C label used for this yield
4874 type = py_object_type
4876 def analyse_types(self, env):
4878 if self.arg is not None:
4879 self.arg.analyse_types(env)
4880 if not self.arg.type.is_pyobject:
4881 self.arg = self.arg.coerce_to_pyobject(env)
4882 error(self.pos, "Generators are not supported")
4884 def generate_result_code(self, code):
4885 self.label_name = code.new_label('resume_from_yield')
4886 code.use_label(self.label_name)
4887 code.putln("/* FIXME: save temporary variables */")
4888 code.putln("/* FIXME: return from function, yielding value */")
4889 code.put_label(self.label_name)
4890 code.putln("/* FIXME: restore temporary variables and */")
4891 code.putln("/* FIXME: extract sent value from closure */")
4894 #-------------------------------------------------------------------
4896 # Unary operator nodes
4898 #-------------------------------------------------------------------
4900 compile_time_unary_operators = {
4901 'not': operator.not_,
4907 class UnopNode(ExprNode):
4911 # Processing during analyse_expressions phase:
4913 # analyse_c_operation
4914 # Called when the operand is not a pyobject.
4915 # - Check operand type and coerce if needed.
4916 # - Determine result type and result code fragment.
4917 # - Allocate temporary for result if needed.
4919 subexprs = ['operand']
4922 def calculate_constant_result(self):
4923 func = compile_time_unary_operators[self.operator]
4924 self.constant_result = func(self.operand.constant_result)
4926 def compile_time_value(self, denv):
4927 func = compile_time_unary_operators.get(self.operator)
4930 "Unary '%s' not supported in compile-time expression"
4932 operand = self.operand.compile_time_value(denv)
4934 return func(operand)
4935 except Exception, e:
4936 self.compile_time_value_error(e)
4938 def infer_type(self, env):
4939 operand_type = self.operand.infer_type(env)
4940 if operand_type.is_pyobject:
4941 return py_object_type
4945 def analyse_types(self, env):
4946 self.operand.analyse_types(env)
4947 if self.is_py_operation():
4948 self.coerce_operand_to_pyobject(env)
4949 self.type = py_object_type
4951 elif self.is_cpp_operation():
4952 self.analyse_cpp_operation(env)
4954 self.analyse_c_operation(env)
4956 def check_const(self):
4957 return self.operand.check_const()
4959 def is_py_operation(self):
4960 return self.operand.type.is_pyobject
4962 def nogil_check(self, env):
4963 if self.is_py_operation():
4966 def is_cpp_operation(self):
4967 type = self.operand.type
4968 return type.is_cpp_class
4970 def coerce_operand_to_pyobject(self, env):
4971 self.operand = self.operand.coerce_to_pyobject(env)
4973 def generate_result_code(self, code):
4974 if self.operand.type.is_pyobject:
4975 self.generate_py_operation_code(code)
4977 def generate_py_operation_code(self, code):
4978 function = self.py_operation_function()
4980 "%s = %s(%s); %s" % (
4983 self.operand.py_result(),
4984 code.error_goto_if_null(self.result(), self.pos)))
4985 code.put_gotref(self.py_result())
4987 def type_error(self):
4988 if not self.operand.type.is_error:
4989 error(self.pos, "Invalid operand type for '%s' (%s)" %
4990 (self.operator, self.operand.type))
4991 self.type = PyrexTypes.error_type
4993 def analyse_cpp_operation(self, env):
4994 type = self.operand.type
4996 type = type.base_type
4997 function = type.scope.lookup("operator%s" % self.operator)
4999 error(self.pos, "'%s' operator not defined for %s"
5000 % (self.operator, type))
5003 func_type = function.type
5004 if func_type.is_ptr:
5005 func_type = func_type.base_type
5006 self.type = func_type.return_type
5009 class NotNode(ExprNode):
5014 type = PyrexTypes.c_bint_type
5016 subexprs = ['operand']
5018 def calculate_constant_result(self):
5019 self.constant_result = not self.operand.constant_result
5021 def compile_time_value(self, denv):
5022 operand = self.operand.compile_time_value(denv)
5025 except Exception, e:
5026 self.compile_time_value_error(e)
5028 def infer_type(self, env):
5029 return PyrexTypes.c_bint_type
5031 def analyse_types(self, env):
5032 self.operand.analyse_types(env)
5033 self.operand = self.operand.coerce_to_boolean(env)
5035 def calculate_result_code(self):
5036 return "(!%s)" % self.operand.result()
5038 def generate_result_code(self, code):
5042 class UnaryPlusNode(UnopNode):
5043 # unary '+' operator
5047 def analyse_c_operation(self, env):
5048 self.type = self.operand.type
5050 def py_operation_function(self):
5051 return "PyNumber_Positive"
5053 def calculate_result_code(self):
5054 if self.is_cpp_operation():
5055 return "(+%s)" % self.operand.result()
5057 return self.operand.result()
5060 class UnaryMinusNode(UnopNode):
5061 # unary '-' operator
5065 def analyse_c_operation(self, env):
5066 if self.operand.type.is_numeric:
5067 self.type = self.operand.type
5070 if self.type.is_complex:
5073 def py_operation_function(self):
5074 return "PyNumber_Negative"
5076 def calculate_result_code(self):
5078 return "(-%s)" % self.operand.result()
5080 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5082 def get_constant_c_result_code(self):
5083 value = self.operand.get_constant_c_result_code()
5085 return "(-%s)" % (value)
5087 class TildeNode(UnopNode):
5088 # unary '~' operator
5090 def analyse_c_operation(self, env):
5091 if self.operand.type.is_int:
5092 self.type = self.operand.type
5096 def py_operation_function(self):
5097 return "PyNumber_Invert"
5099 def calculate_result_code(self):
5100 return "(~%s)" % self.operand.result()
5103 class CUnopNode(UnopNode):
5105 def is_py_operation(self):
5108 class DereferenceNode(CUnopNode):
5113 def analyse_c_operation(self, env):
5114 if self.operand.type.is_ptr:
5115 self.type = self.operand.type.base_type
5119 def calculate_result_code(self):
5120 return "(*%s)" % self.operand.result()
5123 class DecrementIncrementNode(CUnopNode):
5124 # unary ++/-- operator
5126 def analyse_c_operation(self, env):
5127 if self.operand.type.is_ptr or self.operand.type.is_numeric:
5128 self.type = self.operand.type
5132 def calculate_result_code(self):
5134 return "(%s%s)" % (self.operator, self.operand.result())
5136 return "(%s%s)" % (self.operand.result(), self.operator)
5138 def inc_dec_constructor(is_prefix, operator):
5139 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5142 class AmpersandNode(ExprNode):
5143 # The C address-of operator.
5147 subexprs = ['operand']
5149 def infer_type(self, env):
5150 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5152 def analyse_types(self, env):
5153 self.operand.analyse_types(env)
5154 argtype = self.operand.type
5155 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5156 self.error("Taking address of non-lvalue")
5158 if argtype.is_pyobject:
5159 self.error("Cannot take address of Python variable")
5161 self.type = PyrexTypes.c_ptr_type(argtype)
5163 def check_const(self):
5164 return self.operand.check_const_addr()
5166 def error(self, mess):
5167 error(self.pos, mess)
5168 self.type = PyrexTypes.error_type
5169 self.result_code = "<error>"
5171 def calculate_result_code(self):
5172 return "(&%s)" % self.operand.result()
5174 def generate_result_code(self, code):
5178 unop_node_classes = {
5180 "-": UnaryMinusNode,
5184 def unop_node(pos, operator, operand):
5185 # Construct unnop node of appropriate class for
5187 if isinstance(operand, IntNode) and operator == '-':
5188 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5189 elif isinstance(operand, UnopNode) and operand.operator == operator:
5190 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5191 return unop_node_classes[operator](pos,
5192 operator = operator,
5196 class TypecastNode(ExprNode):
5200 # base_type CBaseTypeNode
5201 # declarator CDeclaratorNode
5203 # If used from a transform, one can if wanted specify the attribute
5204 # "type" directly and leave base_type and declarator to None
5206 subexprs = ['operand']
5207 base_type = declarator = type = None
5209 def type_dependencies(self, env):
5212 def infer_type(self, env):
5213 if self.type is None:
5214 base_type = self.base_type.analyse(env)
5215 _, self.type = self.declarator.analyse(base_type, env)
5218 def analyse_types(self, env):
5219 if self.type is None:
5220 base_type = self.base_type.analyse(env)
5221 _, self.type = self.declarator.analyse(base_type, env)
5222 if self.type.is_cfunction:
5224 "Cannot cast to a function type")
5225 self.type = PyrexTypes.error_type
5226 self.operand.analyse_types(env)
5227 to_py = self.type.is_pyobject
5228 from_py = self.operand.type.is_pyobject
5229 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5230 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5231 if to_py and not from_py:
5232 if self.type is bytes_type and self.operand.type.is_int:
5233 # FIXME: the type cast node isn't needed in this case
5234 # and can be dropped once analyse_types() can return a
5236 self.operand = CoerceIntToBytesNode(self.operand, env)
5237 elif self.operand.type.can_coerce_to_pyobject(env):
5238 self.result_ctype = py_object_type
5239 self.operand = self.operand.coerce_to_pyobject(env)
5241 if self.operand.type.is_ptr:
5242 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5243 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5245 # Should this be an error?
5246 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5247 self.operand = self.operand.coerce_to_simple(env)
5248 elif from_py and not to_py:
5249 if self.type.create_from_py_utility_code(env):
5250 self.operand = self.operand.coerce_to(self.type, env)
5251 elif self.type.is_ptr:
5252 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5253 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5255 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5256 elif from_py and to_py:
5257 if self.typecheck and self.type.is_extension_type:
5258 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5259 elif self.type.is_complex and self.operand.type.is_complex:
5260 self.operand = self.operand.coerce_to_simple(env)
5262 def nogil_check(self, env):
5263 if self.type and self.type.is_pyobject and self.is_temp:
5266 def check_const(self):
5267 return self.operand.check_const()
5269 def calculate_constant_result(self):
5270 # we usually do not know the result of a type cast at code
5274 def calculate_result_code(self):
5275 if self.type.is_complex:
5276 operand_result = self.operand.result()
5277 if self.operand.type.is_complex:
5278 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5279 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5281 real_part = self.type.real_type.cast_code(operand_result)
5283 return "%s(%s, %s)" % (
5284 self.type.from_parts,
5288 return self.type.cast_code(self.operand.result())
5290 def get_constant_c_result_code(self):
5291 operand_result = self.operand.get_constant_c_result_code()
5293 return self.type.cast_code(operand_result)
5295 def result_as(self, type):
5296 if self.type.is_pyobject and not self.is_temp:
5297 # Optimise away some unnecessary casting
5298 return self.operand.result_as(type)
5300 return ExprNode.result_as(self, type)
5302 def generate_result_code(self, code):
5305 "%s = (PyObject *)%s;" % (
5307 self.operand.result()))
5308 code.put_incref(self.result(), self.ctype())
5311 class SizeofNode(ExprNode):
5312 # Abstract base class for sizeof(x) expression nodes.
5314 type = PyrexTypes.c_size_t_type
5316 def check_const(self):
5319 def generate_result_code(self, code):
5323 class SizeofTypeNode(SizeofNode):
5324 # C sizeof function applied to a type
5326 # base_type CBaseTypeNode
5327 # declarator CDeclaratorNode
5332 def analyse_types(self, env):
5333 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5334 # this could be better handled by more uniformly treating types as runtime-available objects
5335 if 0 and self.base_type.module_path:
5336 path = self.base_type.module_path
5337 obj = env.lookup(path[0])
5338 if obj.as_module is None:
5339 operand = NameNode(pos=self.pos, name=path[0])
5340 for attr in path[1:]:
5341 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5342 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5343 self.operand = operand
5344 self.__class__ = SizeofVarNode
5345 self.analyse_types(env)
5347 if self.arg_type is None:
5348 base_type = self.base_type.analyse(env)
5349 _, arg_type = self.declarator.analyse(base_type, env)
5350 self.arg_type = arg_type
5353 def check_type(self):
5354 arg_type = self.arg_type
5355 if arg_type.is_pyobject and not arg_type.is_extension_type:
5356 error(self.pos, "Cannot take sizeof Python object")
5357 elif arg_type.is_void:
5358 error(self.pos, "Cannot take sizeof void")
5359 elif not arg_type.is_complete():
5360 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5362 def calculate_result_code(self):
5363 if self.arg_type.is_extension_type:
5364 # the size of the pointer is boring
5365 # we want the size of the actual struct
5366 arg_code = self.arg_type.declaration_code("", deref=1)
5368 arg_code = self.arg_type.declaration_code("")
5369 return "(sizeof(%s))" % arg_code
5372 class SizeofVarNode(SizeofNode):
5373 # C sizeof function applied to a variable
5377 subexprs = ['operand']
5379 def analyse_types(self, env):
5380 # We may actually be looking at a type rather than a variable...
5381 # If we are, traditional analysis would fail...
5382 operand_as_type = self.operand.analyse_as_type(env)
5384 self.arg_type = operand_as_type
5385 self.__class__ = SizeofTypeNode
5388 self.operand.analyse_types(env)
5390 def calculate_result_code(self):
5391 return "(sizeof(%s))" % self.operand.result()
5393 def generate_result_code(self, code):
5396 class TypeofNode(ExprNode):
5397 # Compile-time type of an expression, as a string.
5400 # literal StringNode # internal
5403 type = py_object_type
5405 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5407 def analyse_types(self, env):
5408 self.operand.analyse_types(env)
5409 self.literal = StringNode(
5410 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5411 self.literal.analyse_types(env)
5412 self.literal = self.literal.coerce_to_pyobject(env)
5414 def may_be_none(self):
5417 def generate_evaluation_code(self, code):
5418 self.literal.generate_evaluation_code(code)
5420 def calculate_result_code(self):
5421 return self.literal.calculate_result_code()
5423 #-------------------------------------------------------------------
5425 # Binary operator nodes
5427 #-------------------------------------------------------------------
5429 def _not_in(x, seq):
5432 compile_time_binary_operators = {
5440 'is_not': operator.is_not,
5443 '/': operator.truediv,
5444 '//': operator.floordiv,
5445 '<<': operator.lshift,
5450 '>>': operator.rshift,
5453 'in': operator.contains,
5457 def get_compile_time_binop(node):
5458 func = compile_time_binary_operators.get(node.operator)
5461 "Binary '%s' not supported in compile-time expression"
5465 class BinopNode(ExprNode):
5470 # Processing during analyse_expressions phase:
5472 # analyse_c_operation
5473 # Called when neither operand is a pyobject.
5474 # - Check operand types and coerce if needed.
5475 # - Determine result type and result code fragment.
5476 # - Allocate temporary for result if needed.
5478 subexprs = ['operand1', 'operand2']
5481 def calculate_constant_result(self):
5482 func = compile_time_binary_operators[self.operator]
5483 self.constant_result = func(
5484 self.operand1.constant_result,
5485 self.operand2.constant_result)
5487 def compile_time_value(self, denv):
5488 func = get_compile_time_binop(self)
5489 operand1 = self.operand1.compile_time_value(denv)
5490 operand2 = self.operand2.compile_time_value(denv)
5492 return func(operand1, operand2)
5493 except Exception, e:
5494 self.compile_time_value_error(e)
5496 def infer_type(self, env):
5497 return self.result_type(self.operand1.infer_type(env),
5498 self.operand2.infer_type(env))
5500 def analyse_types(self, env):
5501 self.operand1.analyse_types(env)
5502 self.operand2.analyse_types(env)
5503 self.analyse_operation(env)
5505 def analyse_operation(self, env):
5506 if self.is_py_operation():
5507 self.coerce_operands_to_pyobjects(env)
5508 self.type = self.result_type(self.operand1.type,
5510 assert self.type.is_pyobject
5512 elif self.is_cpp_operation():
5513 self.analyse_cpp_operation(env)
5515 self.analyse_c_operation(env)
5517 def is_py_operation(self):
5518 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5520 def is_py_operation_types(self, type1, type2):
5521 return type1.is_pyobject or type2.is_pyobject
5523 def is_cpp_operation(self):
5524 return (self.operand1.type.is_cpp_class
5525 or self.operand2.type.is_cpp_class)
5527 def analyse_cpp_operation(self, env):
5528 type1 = self.operand1.type
5529 type2 = self.operand2.type
5530 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5534 func_type = entry.type
5535 if func_type.is_ptr:
5536 func_type = func_type.base_type
5537 if len(func_type.args) == 1:
5538 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5540 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5541 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5542 self.type = func_type.return_type
5544 def result_type(self, type1, type2):
5545 if self.is_py_operation_types(type1, type2):
5547 type2 = Builtin.bytes_type
5549 type1 = Builtin.bytes_type
5550 elif self.operator == '%' \
5551 and type1 in (Builtin.str_type, Builtin.unicode_type):
5552 # note that b'%s' % b'abc' doesn't work in Py3
5554 if type1.is_builtin_type:
5556 if self.operator in '**%+|&^':
5557 # FIXME: at least these operators should be safe - others?
5559 elif self.operator == '*':
5560 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5562 # multiplication of containers/numbers with an
5563 # integer value always (?) returns the same type
5566 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5567 # multiplication of containers/numbers with an
5568 # integer value always (?) returns the same type
5570 return py_object_type
5572 return self.compute_c_result_type(type1, type2)
5574 def nogil_check(self, env):
5575 if self.is_py_operation():
5578 def coerce_operands_to_pyobjects(self, env):
5579 self.operand1 = self.operand1.coerce_to_pyobject(env)
5580 self.operand2 = self.operand2.coerce_to_pyobject(env)
5582 def check_const(self):
5583 return self.operand1.check_const() and self.operand2.check_const()
5585 def generate_result_code(self, code):
5586 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5587 if self.operand1.type.is_pyobject:
5588 function = self.py_operation_function()
5589 if self.operator == '**':
5590 extra_args = ", Py_None"
5594 "%s = %s(%s, %s%s); %s" % (
5597 self.operand1.py_result(),
5598 self.operand2.py_result(),
5600 code.error_goto_if_null(self.result(), self.pos)))
5601 code.put_gotref(self.py_result())
5603 def type_error(self):
5604 if not (self.operand1.type.is_error
5605 or self.operand2.type.is_error):
5606 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5607 (self.operator, self.operand1.type,
5608 self.operand2.type))
5609 self.type = PyrexTypes.error_type
5612 class CBinopNode(BinopNode):
5614 def analyse_types(self, env):
5615 BinopNode.analyse_types(self, env)
5616 if self.is_py_operation():
5617 self.type = PyrexTypes.error_type
5619 def py_operation_function():
5622 def calculate_result_code(self):
5623 return "(%s %s %s)" % (
5624 self.operand1.result(),
5626 self.operand2.result())
5629 def c_binop_constructor(operator):
5630 def make_binop_node(pos, **operands):
5631 return CBinopNode(pos, operator=operator, **operands)
5632 return make_binop_node
5634 class NumBinopNode(BinopNode):
5635 # Binary operation taking numeric arguments.
5639 def analyse_c_operation(self, env):
5640 type1 = self.operand1.type
5641 type2 = self.operand2.type
5642 self.type = self.compute_c_result_type(type1, type2)
5646 if self.type.is_complex:
5648 if not self.infix or (type1.is_numeric and type2.is_numeric):
5649 self.operand1 = self.operand1.coerce_to(self.type, env)
5650 self.operand2 = self.operand2.coerce_to(self.type, env)
5652 def compute_c_result_type(self, type1, type2):
5653 if self.c_types_okay(type1, type2):
5654 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5655 if widest_type is PyrexTypes.c_bint_type:
5656 if self.operator not in '|^&':
5657 # False + False == 0 # not False!
5658 widest_type = PyrexTypes.c_int_type
5663 def get_constant_c_result_code(self):
5664 value1 = self.operand1.get_constant_c_result_code()
5665 value2 = self.operand2.get_constant_c_result_code()
5666 if value1 and value2:
5667 return "(%s %s %s)" % (value1, self.operator, value2)
5671 def c_types_okay(self, type1, type2):
5672 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5673 return (type1.is_numeric or type1.is_enum) \
5674 and (type2.is_numeric or type2.is_enum)
5676 def calculate_result_code(self):
5678 return "(%s %s %s)" % (
5679 self.operand1.result(),
5681 self.operand2.result())
5683 func = self.type.binary_op(self.operator)
5685 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5686 return "%s(%s, %s)" % (
5688 self.operand1.result(),
5689 self.operand2.result())
5691 def is_py_operation_types(self, type1, type2):
5692 return (type1 is PyrexTypes.c_py_unicode_type or
5693 type2 is PyrexTypes.c_py_unicode_type or
5694 BinopNode.is_py_operation_types(self, type1, type2))
5696 def py_operation_function(self):
5697 fuction = self.py_functions[self.operator]
5699 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
5704 "^": "PyNumber_Xor",
5705 "&": "PyNumber_And",
5706 "<<": "PyNumber_Lshift",
5707 ">>": "PyNumber_Rshift",
5708 "+": "PyNumber_Add",
5709 "-": "PyNumber_Subtract",
5710 "*": "PyNumber_Multiply",
5711 "/": "__Pyx_PyNumber_Divide",
5712 "//": "PyNumber_FloorDivide",
5713 "%": "PyNumber_Remainder",
5714 "**": "PyNumber_Power"
5717 class IntBinopNode(NumBinopNode):
5718 # Binary operation taking integer arguments.
5720 def c_types_okay(self, type1, type2):
5721 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5722 return (type1.is_int or type1.is_enum) \
5723 and (type2.is_int or type2.is_enum)
5726 class AddNode(NumBinopNode):
5729 def is_py_operation_types(self, type1, type2):
5730 if type1.is_string and type2.is_string:
5733 return NumBinopNode.is_py_operation_types(self, type1, type2)
5735 def compute_c_result_type(self, type1, type2):
5736 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5737 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5739 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5742 return NumBinopNode.compute_c_result_type(
5746 class SubNode(NumBinopNode):
5749 def compute_c_result_type(self, type1, type2):
5750 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5752 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5753 return PyrexTypes.c_int_type
5755 return NumBinopNode.compute_c_result_type(
5759 class MulNode(NumBinopNode):
5762 def is_py_operation_types(self, type1, type2):
5763 if (type1.is_string and type2.is_int) \
5764 or (type2.is_string and type1.is_int):
5767 return NumBinopNode.is_py_operation_types(self, type1, type2)
5770 class DivNode(NumBinopNode):
5771 # '/' or '//' operator.
5774 truedivision = None # == "unknown" if operator == '/'
5775 ctruedivision = False
5776 cdivision_warnings = False
5777 zerodivision_check = None
5779 def find_compile_time_binary_operator(self, op1, op2):
5780 func = compile_time_binary_operators[self.operator]
5781 if self.operator == '/' and self.truedivision is None:
5782 # => true div for floats, floor div for integers
5783 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5784 func = compile_time_binary_operators['//']
5787 def calculate_constant_result(self):
5788 op1 = self.operand1.constant_result
5789 op2 = self.operand2.constant_result
5790 func = self.find_compile_time_binary_operator(op1, op2)
5791 self.constant_result = func(
5792 self.operand1.constant_result,
5793 self.operand2.constant_result)
5795 def compile_time_value(self, denv):
5796 operand1 = self.operand1.compile_time_value(denv)
5797 operand2 = self.operand2.compile_time_value(denv)
5799 func = self.find_compile_time_binary_operator(
5800 self, operand1, operand2)
5801 return func(operand1, operand2)
5802 except Exception, e:
5803 self.compile_time_value_error(e)
5805 def analyse_operation(self, env):
5806 if self.cdivision or env.directives['cdivision']:
5807 self.ctruedivision = False
5809 self.ctruedivision = self.truedivision
5810 NumBinopNode.analyse_operation(self, env)
5811 if self.is_cpp_operation():
5812 self.cdivision = True
5813 if not self.type.is_pyobject:
5814 self.zerodivision_check = (
5815 self.cdivision is None and not env.directives['cdivision']
5816 and (not self.operand2.has_constant_result() or
5817 self.operand2.constant_result == 0))
5818 if self.zerodivision_check or env.directives['cdivision_warnings']:
5819 # Need to check ahead of time to warn or raise zero division error
5820 self.operand1 = self.operand1.coerce_to_simple(env)
5821 self.operand2 = self.operand2.coerce_to_simple(env)
5823 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5825 def compute_c_result_type(self, type1, type2):
5826 if self.operator == '/' and self.ctruedivision:
5827 if not type1.is_float and not type2.is_float:
5828 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5829 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5831 return NumBinopNode.compute_c_result_type(self, type1, type2)
5833 def zero_division_message(self):
5834 if self.type.is_int:
5835 return "integer division or modulo by zero"
5837 return "float division"
5839 def generate_evaluation_code(self, code):
5840 if not self.type.is_pyobject and not self.type.is_complex:
5841 if self.cdivision is None:
5842 self.cdivision = (code.globalstate.directives['cdivision']
5843 or not self.type.signed
5844 or self.type.is_float)
5845 if not self.cdivision:
5846 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5847 NumBinopNode.generate_evaluation_code(self, code)
5848 self.generate_div_warning_code(code)
5850 def generate_div_warning_code(self, code):
5851 if not self.type.is_pyobject:
5852 if self.zerodivision_check:
5854 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5856 zero_test = "%s == 0" % self.operand2.result()
5857 code.putln("if (unlikely(%s)) {" % zero_test)
5858 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
5859 code.putln(code.error_goto(self.pos))
5861 if self.type.is_int and self.type.signed and self.operator != '%':
5862 code.globalstate.use_utility_code(division_overflow_test_code)
5863 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
5864 self.type.declaration_code(''),
5865 self.operand2.result(),
5866 self.operand1.result()))
5867 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
5868 code.putln(code.error_goto(self.pos))
5870 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
5871 code.globalstate.use_utility_code(cdivision_warning_utility_code)
5872 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
5873 self.operand1.result(),
5874 self.operand2.result()))
5875 code.putln(code.set_error_info(self.pos));
5876 code.put("if (__Pyx_cdivision_warning()) ")
5877 code.put_goto(code.error_label)
5880 def calculate_result_code(self):
5881 if self.type.is_complex:
5882 return NumBinopNode.calculate_result_code(self)
5883 elif self.type.is_float and self.operator == '//':
5884 return "floor(%s / %s)" % (
5885 self.operand1.result(),
5886 self.operand2.result())
5887 elif self.truedivision or self.cdivision:
5888 op1 = self.operand1.result()
5889 op2 = self.operand2.result()
5890 if self.truedivision:
5891 if self.type != self.operand1.type:
5892 op1 = self.type.cast_code(op1)
5893 if self.type != self.operand2.type:
5894 op2 = self.type.cast_code(op2)
5895 return "(%s / %s)" % (op1, op2)
5897 return "__Pyx_div_%s(%s, %s)" % (
5898 self.type.specialization_name(),
5899 self.operand1.result(),
5900 self.operand2.result())
5903 class ModNode(DivNode):
5906 def is_py_operation_types(self, type1, type2):
5907 return (type1.is_string
5909 or NumBinopNode.is_py_operation_types(self, type1, type2))
5911 def zero_division_message(self):
5912 if self.type.is_int:
5913 return "integer division or modulo by zero"
5915 return "float divmod()"
5917 def generate_evaluation_code(self, code):
5918 if not self.type.is_pyobject:
5919 if self.cdivision is None:
5920 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
5921 if not self.cdivision:
5922 if self.type.is_int:
5923 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
5925 code.globalstate.use_utility_code(
5926 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
5927 NumBinopNode.generate_evaluation_code(self, code)
5928 self.generate_div_warning_code(code)
5930 def calculate_result_code(self):
5932 if self.type.is_float:
5933 return "fmod%s(%s, %s)" % (
5934 self.type.math_h_modifier,
5935 self.operand1.result(),
5936 self.operand2.result())
5938 return "(%s %% %s)" % (
5939 self.operand1.result(),
5940 self.operand2.result())
5942 return "__Pyx_mod_%s(%s, %s)" % (
5943 self.type.specialization_name(),
5944 self.operand1.result(),
5945 self.operand2.result())
5947 class PowNode(NumBinopNode):
5950 def analyse_c_operation(self, env):
5951 NumBinopNode.analyse_c_operation(self, env)
5952 if self.type.is_complex:
5953 if self.type.real_type.is_float:
5954 self.operand1 = self.operand1.coerce_to(self.type, env)
5955 self.operand2 = self.operand2.coerce_to(self.type, env)
5956 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
5958 error(self.pos, "complex int powers not supported")
5959 self.pow_func = "<error>"
5960 elif self.type.is_float:
5961 self.pow_func = "pow" + self.type.math_h_modifier
5963 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
5964 env.use_utility_code(
5965 int_pow_utility_code.specialize(func_name=self.pow_func,
5966 type=self.type.declaration_code('')))
5968 def calculate_result_code(self):
5969 # Work around MSVC overloading ambiguity.
5970 def typecast(operand):
5971 if self.type == operand.type:
5972 return operand.result()
5974 return self.type.cast_code(operand.result())
5975 return "%s(%s, %s)" % (
5977 typecast(self.operand1),
5978 typecast(self.operand2))
5981 # Note: This class is temporarily "shut down" into an ineffective temp
5984 # More sophisticated temp reuse was going on before, one could have a
5985 # look at adding this again after /all/ classes are converted to the
5986 # new temp scheme. (The temp juggling cannot work otherwise).
5987 class BoolBinopNode(ExprNode):
5988 # Short-circuiting boolean operation.
5994 subexprs = ['operand1', 'operand2']
5996 def infer_type(self, env):
5997 type1 = self.operand1.infer_type(env)
5998 type2 = self.operand2.infer_type(env)
5999 return PyrexTypes.independent_spanning_type(type1, type2)
6001 def may_be_none(self):
6002 if self.operator == 'or':
6003 return self.operand2.may_be_none()
6005 return self.operand1.may_be_none() or self.operand2.may_be_none()
6007 def calculate_constant_result(self):
6008 if self.operator == 'and':
6009 self.constant_result = \
6010 self.operand1.constant_result and \
6011 self.operand2.constant_result
6013 self.constant_result = \
6014 self.operand1.constant_result or \
6015 self.operand2.constant_result
6017 def compile_time_value(self, denv):
6018 if self.operator == 'and':
6019 return self.operand1.compile_time_value(denv) \
6020 and self.operand2.compile_time_value(denv)
6022 return self.operand1.compile_time_value(denv) \
6023 or self.operand2.compile_time_value(denv)
6025 def coerce_to_boolean(self, env):
6026 return BoolBinopNode(
6028 operator = self.operator,
6029 operand1 = self.operand1.coerce_to_boolean(env),
6030 operand2 = self.operand2.coerce_to_boolean(env),
6031 type = PyrexTypes.c_bint_type,
6032 is_temp = self.is_temp)
6034 def analyse_types(self, env):
6035 self.operand1.analyse_types(env)
6036 self.operand2.analyse_types(env)
6037 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6038 self.operand1 = self.operand1.coerce_to(self.type, env)
6039 self.operand2 = self.operand2.coerce_to(self.type, env)
6041 # For what we're about to do, it's vital that
6042 # both operands be temp nodes.
6043 self.operand1 = self.operand1.coerce_to_simple(env)
6044 self.operand2 = self.operand2.coerce_to_simple(env)
6047 gil_message = "Truth-testing Python object"
6049 def check_const(self):
6050 return self.operand1.check_const() and self.operand2.check_const()
6052 def generate_evaluation_code(self, code):
6053 code.mark_pos(self.pos)
6054 self.operand1.generate_evaluation_code(code)
6055 test_result, uses_temp = self.generate_operand1_test(code)
6056 if self.operator == 'and':
6065 code.funcstate.release_temp(test_result)
6066 self.operand1.generate_disposal_code(code)
6067 self.operand2.generate_evaluation_code(code)
6068 self.allocate_temp_result(code)
6069 self.operand2.make_owned_reference(code)
6070 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6071 self.operand2.generate_post_assignment_code(code)
6072 self.operand2.free_temps(code)
6073 code.putln("} else {")
6074 self.operand1.make_owned_reference(code)
6075 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6076 self.operand1.generate_post_assignment_code(code)
6077 self.operand1.free_temps(code)
6080 def generate_operand1_test(self, code):
6081 # Generate code to test the truth of the first operand.
6082 if self.type.is_pyobject:
6083 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6086 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6088 self.operand1.py_result(),
6089 code.error_goto_if_neg(test_result, self.pos)))
6091 test_result = self.operand1.result()
6092 return (test_result, self.type.is_pyobject)
6095 class CondExprNode(ExprNode):
6096 # Short-circuiting conditional expression.
6100 # false_val ExprNode
6105 subexprs = ['test', 'true_val', 'false_val']
6107 def type_dependencies(self, env):
6108 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6110 def infer_type(self, env):
6111 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6112 self.false_val.infer_type(env))
6114 def calculate_constant_result(self):
6115 if self.test.constant_result:
6116 self.constant_result = self.true_val.constant_result
6118 self.constant_result = self.false_val.constant_result
6120 def analyse_types(self, env):
6121 self.test.analyse_types(env)
6122 self.test = self.test.coerce_to_boolean(env)
6123 self.true_val.analyse_types(env)
6124 self.false_val.analyse_types(env)
6125 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6126 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6127 self.true_val = self.true_val.coerce_to(self.type, env)
6128 self.false_val = self.false_val.coerce_to(self.type, env)
6130 if self.type == PyrexTypes.error_type:
6133 def type_error(self):
6134 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6135 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6136 (self.true_val.type, self.false_val.type))
6137 self.type = PyrexTypes.error_type
6139 def check_const(self):
6140 return (self.test.check_const()
6141 and self.true_val.check_const()
6142 and self.false_val.check_const())
6144 def generate_evaluation_code(self, code):
6145 # Because subexprs may not be evaluated we can use a more optimal
6146 # subexpr allocation strategy than the default, so override evaluation_code.
6148 code.mark_pos(self.pos)
6149 self.allocate_temp_result(code)
6150 self.test.generate_evaluation_code(code)
6151 code.putln("if (%s) {" % self.test.result() )
6152 self.eval_and_get(code, self.true_val)
6153 code.putln("} else {")
6154 self.eval_and_get(code, self.false_val)
6156 self.test.generate_disposal_code(code)
6157 self.test.free_temps(code)
6159 def eval_and_get(self, code, expr):
6160 expr.generate_evaluation_code(code)
6161 expr.make_owned_reference(code)
6162 code.putln("%s = %s;" % (self.result(), expr.result()))
6163 expr.generate_post_assignment_code(code)
6164 expr.free_temps(code)
6166 richcmp_constants = {
6176 class CmpNode(object):
6177 # Mixin class containing code common to PrimaryCmpNodes
6178 # and CascadedCmpNodes.
6180 special_bool_cmp_function = None
6182 def infer_type(self, env):
6183 # TODO: Actually implement this (after merging with -unstable).
6184 return py_object_type
6186 def calculate_cascaded_constant_result(self, operand1_result):
6187 func = compile_time_binary_operators[self.operator]
6188 operand2_result = self.operand2.constant_result
6189 result = func(operand1_result, operand2_result)
6191 self.cascade.calculate_cascaded_constant_result(operand2_result)
6192 if self.cascade.constant_result:
6193 self.constant_result = result and self.cascade.constant_result
6195 self.constant_result = result
6197 def cascaded_compile_time_value(self, operand1, denv):
6198 func = get_compile_time_binop(self)
6199 operand2 = self.operand2.compile_time_value(denv)
6201 result = func(operand1, operand2)
6202 except Exception, e:
6203 self.compile_time_value_error(e)
6206 cascade = self.cascade
6208 # FIXME: I bet this must call cascaded_compile_time_value()
6209 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6212 def is_cpp_comparison(self):
6213 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6215 def find_common_int_type(self, env, op, operand1, operand2):
6216 # type1 != type2 and at least one of the types is not a C int
6217 type1 = operand1.type
6218 type2 = operand2.type
6219 type1_can_be_int = False
6220 type2_can_be_int = False
6222 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6223 and operand1.can_coerce_to_char_literal():
6224 type1_can_be_int = True
6225 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6226 and operand2.can_coerce_to_char_literal():
6227 type2_can_be_int = True
6230 if type2_can_be_int:
6233 if type1_can_be_int:
6235 elif type1_can_be_int:
6236 if type2_can_be_int:
6237 return PyrexTypes.c_uchar_type
6241 def find_common_type(self, env, op, operand1, common_type=None):
6242 operand2 = self.operand2
6243 type1 = operand1.type
6244 type2 = operand2.type
6246 new_common_type = None
6248 # catch general errors
6249 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6250 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6251 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6252 new_common_type = error_type
6254 # try to use numeric comparisons where possible
6255 elif type1.is_complex or type2.is_complex:
6256 if op not in ('==', '!='):
6257 error(self.pos, "complex types are unordered")
6258 new_common_type = error_type
6259 if type1.is_pyobject:
6260 new_common_type = type1
6261 elif type2.is_pyobject:
6262 new_common_type = type2
6264 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6265 elif type1.is_numeric and type2.is_numeric:
6266 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6267 elif common_type is None or not common_type.is_pyobject:
6268 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6270 if new_common_type is None:
6271 # fall back to generic type compatibility tests
6273 new_common_type = type1
6274 elif type1.is_pyobject or type2.is_pyobject:
6275 if type2.is_numeric or type2.is_string:
6276 if operand2.check_for_coercion_error(type1):
6277 new_common_type = error_type
6279 new_common_type = py_object_type
6280 elif type1.is_numeric or type1.is_string:
6281 if operand1.check_for_coercion_error(type2):
6282 new_common_type = error_type
6284 new_common_type = py_object_type
6285 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6286 new_common_type = py_object_type
6288 # one Python type and one non-Python type, not assignable
6289 self.invalid_types_error(operand1, op, operand2)
6290 new_common_type = error_type
6291 elif type1.assignable_from(type2):
6292 new_common_type = type1
6293 elif type2.assignable_from(type1):
6294 new_common_type = type2
6296 # C types that we couldn't handle up to here are an error
6297 self.invalid_types_error(operand1, op, operand2)
6298 new_common_type = error_type
6300 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6301 isinstance(operand2, BytesNode)):
6302 # special case when comparing char* to bytes literal: must
6303 # compare string values!
6304 new_common_type = bytes_type
6306 # recursively merge types
6307 if common_type is None or new_common_type.is_error:
6308 common_type = new_common_type
6310 # we could do a lot better by splitting the comparison
6311 # into a non-Python part and a Python part, but this is
6313 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6316 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6320 def invalid_types_error(self, operand1, op, operand2):
6321 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6322 (op, operand1.type, operand2.type))
6324 def is_python_comparison(self):
6325 return (not self.is_ptr_contains()
6326 and not self.is_c_string_contains()
6327 and (self.has_python_operands()
6328 or (self.cascade and self.cascade.is_python_comparison())
6329 or self.operator in ('in', 'not_in')))
6331 def coerce_operands_to(self, dst_type, env):
6332 operand2 = self.operand2
6333 if operand2.type != dst_type:
6334 self.operand2 = operand2.coerce_to(dst_type, env)
6336 self.cascade.coerce_operands_to(dst_type, env)
6338 def is_python_result(self):
6339 return ((self.has_python_operands() and
6340 self.special_bool_cmp_function is None and
6341 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6342 not self.is_c_string_contains() and
6343 not self.is_ptr_contains())
6344 or (self.cascade and self.cascade.is_python_result()))
6346 def is_c_string_contains(self):
6347 return self.operator in ('in', 'not_in') and \
6348 ((self.operand1.type.is_int
6349 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6350 (self.operand1.type is PyrexTypes.c_py_unicode_type
6351 and self.operand2.type is unicode_type))
6353 def is_ptr_contains(self):
6354 if self.operator in ('in', 'not_in'):
6355 container_type = self.operand2.type
6356 return (container_type.is_ptr or container_type.is_array) \
6357 and not container_type.is_string
6359 def find_special_bool_compare_function(self, env):
6360 if self.operator in ('==', '!='):
6361 type1, type2 = self.operand1.type, self.operand2.type
6362 if type1.is_pyobject and type2.is_pyobject:
6363 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6364 env.use_utility_code(pyunicode_equals_utility_code)
6365 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6369 def generate_operation_code(self, code, result_code,
6370 operand1, op , operand2):
6371 if self.type.is_pyobject:
6372 coerce_result = "__Pyx_PyBool_FromLong"
6379 if self.special_bool_cmp_function:
6380 if operand1.type.is_pyobject:
6381 result1 = operand1.py_result()
6383 result1 = operand1.result()
6384 if operand2.type.is_pyobject:
6385 result2 = operand2.py_result()
6387 result2 = operand2.result()
6388 code.putln("%s = %s(%s, %s, %s); %s" % (
6390 self.special_bool_cmp_function,
6393 richcmp_constants[op],
6394 code.error_goto_if_neg(result_code, self.pos)))
6395 elif op == 'in' or op == 'not_in':
6396 code.globalstate.use_utility_code(contains_utility_code)
6397 if self.type.is_pyobject:
6398 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6400 negation = "__Pyx_NegateNonNeg"
6401 if operand2.type is dict_type:
6402 method = "PyDict_Contains"
6404 method = "PySequence_Contains"
6405 if self.type.is_pyobject:
6406 error_clause = code.error_goto_if_null
6407 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6409 error_clause = code.error_goto_if_neg
6412 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6417 operand2.py_result(),
6418 operand1.py_result(),
6420 error_clause(result_code, self.pos)))
6421 elif (operand1.type.is_pyobject
6422 and op not in ('is', 'is_not')):
6423 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6425 operand1.py_result(),
6426 operand2.py_result(),
6427 richcmp_constants[op],
6428 code.error_goto_if_null(result_code, self.pos)))
6429 code.put_gotref(result_code)
6430 elif operand1.type.is_complex:
6435 code.putln("%s = %s(%s%s(%s, %s));" % (
6439 operand1.type.unary_op('eq'),
6443 type1 = operand1.type
6444 type2 = operand2.type
6445 if (type1.is_extension_type or type2.is_extension_type) \
6446 and not type1.same_as(type2):
6447 common_type = py_object_type
6448 elif type1.is_numeric:
6449 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6452 code1 = operand1.result_as(common_type)
6453 code2 = operand2.result_as(common_type)
6454 code.putln("%s = %s(%s %s %s);" % (
6458 self.c_operator(op),
6461 def c_operator(self, op):
6464 elif op == 'is_not':
6469 contains_utility_code = UtilityCode(
6471 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6472 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6473 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6477 char_in_bytes_utility_code = UtilityCode(
6479 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6482 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6483 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6484 char* char_start = PyBytes_AS_STRING(bytes);
6486 for (pos=char_start; pos < char_start+length; pos++) {
6487 if (character == pos[0]) return 1;
6493 pyunicode_in_unicode_utility_code = UtilityCode(
6495 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6498 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6499 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6500 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6502 for (pos=char_start; pos < char_start+length; pos++) {
6503 if (character == pos[0]) return 1;
6509 pyunicode_equals_utility_code = UtilityCode(
6511 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6514 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6515 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6516 return (equals == Py_EQ);
6517 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6518 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6519 return (equals == Py_NE);
6520 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6521 if (equals == Py_EQ)
6522 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6524 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6526 int result = PyUnicode_Compare(s1, s2);
6527 if ((result == -1) && unlikely(PyErr_Occurred()))
6529 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6531 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6532 return (equals == Py_EQ);
6533 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6534 return (equals == Py_NE);
6535 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6536 return (equals == Py_NE);
6539 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6542 result = __Pyx_PyObject_IsTrue(py_result);
6543 Py_DECREF(py_result);
6550 class PrimaryCmpNode(ExprNode, CmpNode):
6551 # Non-cascaded comparison or first comparison of
6552 # a cascaded sequence.
6557 # cascade CascadedCmpNode
6559 # We don't use the subexprs mechanism, because
6560 # things here are too complicated for it to handle.
6561 # Instead, we override all the framework methods
6564 child_attrs = ['operand1', 'operand2', 'cascade']
6568 def infer_type(self, env):
6569 # TODO: Actually implement this (after merging with -unstable).
6570 return py_object_type
6572 def type_dependencies(self, env):
6575 def calculate_constant_result(self):
6576 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6578 def compile_time_value(self, denv):
6579 operand1 = self.operand1.compile_time_value(denv)
6580 return self.cascaded_compile_time_value(operand1, denv)
6582 def analyse_types(self, env):
6583 self.operand1.analyse_types(env)
6584 self.operand2.analyse_types(env)
6585 if self.is_cpp_comparison():
6586 self.analyse_cpp_comparison(env)
6588 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6591 self.cascade.analyse_types(env)
6593 if self.operator in ('in', 'not_in'):
6594 if self.is_c_string_contains():
6595 self.is_pycmp = False
6598 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6600 if self.operand2.type is unicode_type:
6601 env.use_utility_code(pyunicode_in_unicode_utility_code)
6603 if self.operand1.type is PyrexTypes.c_uchar_type:
6604 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6605 if self.operand2.type is not bytes_type:
6606 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6607 env.use_utility_code(char_in_bytes_utility_code)
6608 self.operand2 = self.operand2.as_none_safe_node(
6609 "argument of type 'NoneType' is not iterable")
6610 elif self.is_ptr_contains():
6612 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6613 self.type = PyrexTypes.c_bint_type
6614 # Will be transformed by IterationTransform
6617 if self.operand2.type is dict_type:
6618 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6619 common_type = py_object_type
6620 self.is_pycmp = True
6621 elif self.find_special_bool_compare_function(env):
6622 common_type = None # if coercion needed, the method call above has already done it
6623 self.is_pycmp = False # result is bint
6624 self.is_temp = True # must check for error return
6626 common_type = self.find_common_type(env, self.operator, self.operand1)
6627 self.is_pycmp = common_type.is_pyobject
6629 if common_type is not None and not common_type.is_error:
6630 if self.operand1.type != common_type:
6631 self.operand1 = self.operand1.coerce_to(common_type, env)
6632 self.coerce_operands_to(common_type, env)
6635 self.operand2 = self.operand2.coerce_to_simple(env)
6636 self.cascade.coerce_cascaded_operands_to_temp(env)
6637 if self.is_python_result():
6638 self.type = PyrexTypes.py_object_type
6640 self.type = PyrexTypes.c_bint_type
6643 cdr.type = self.type
6645 if self.is_pycmp or self.cascade:
6648 def analyse_cpp_comparison(self, env):
6649 type1 = self.operand1.type
6650 type2 = self.operand2.type
6651 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6653 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6654 (self.operator, type1, type2))
6655 self.type = PyrexTypes.error_type
6656 self.result_code = "<error>"
6658 func_type = entry.type
6659 if func_type.is_ptr:
6660 func_type = func_type.base_type
6661 if len(func_type.args) == 1:
6662 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6664 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6665 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6666 self.type = func_type.return_type
6668 def has_python_operands(self):
6669 return (self.operand1.type.is_pyobject
6670 or self.operand2.type.is_pyobject)
6672 def check_const(self):
6677 return self.operand1.check_const() and self.operand2.check_const()
6679 def calculate_result_code(self):
6680 if self.operand1.type.is_complex:
6681 if self.operator == "!=":
6685 return "(%s%s(%s, %s))" % (
6687 self.operand1.type.binary_op('=='),
6688 self.operand1.result(),
6689 self.operand2.result())
6690 elif self.is_c_string_contains():
6691 if self.operand2.type is bytes_type:
6692 method = "__Pyx_BytesContains"
6694 method = "__Pyx_UnicodeContains"
6695 if self.operator == "not_in":
6699 return "(%s%s(%s, %s))" % (
6702 self.operand2.result(),
6703 self.operand1.result())
6705 return "(%s %s %s)" % (
6706 self.operand1.result(),
6707 self.c_operator(self.operator),
6708 self.operand2.result())
6710 def generate_evaluation_code(self, code):
6711 self.operand1.generate_evaluation_code(code)
6712 self.operand2.generate_evaluation_code(code)
6714 self.allocate_temp_result(code)
6715 self.generate_operation_code(code, self.result(),
6716 self.operand1, self.operator, self.operand2)
6718 self.cascade.generate_evaluation_code(code,
6719 self.result(), self.operand2)
6720 self.operand1.generate_disposal_code(code)
6721 self.operand1.free_temps(code)
6722 self.operand2.generate_disposal_code(code)
6723 self.operand2.free_temps(code)
6725 def generate_subexpr_disposal_code(self, code):
6726 # If this is called, it is a non-cascaded cmp,
6727 # so only need to dispose of the two main operands.
6728 self.operand1.generate_disposal_code(code)
6729 self.operand2.generate_disposal_code(code)
6731 def free_subexpr_temps(self, code):
6732 # If this is called, it is a non-cascaded cmp,
6733 # so only need to dispose of the two main operands.
6734 self.operand1.free_temps(code)
6735 self.operand2.free_temps(code)
6737 def annotate(self, code):
6738 self.operand1.annotate(code)
6739 self.operand2.annotate(code)
6741 self.cascade.annotate(code)
6744 class CascadedCmpNode(Node, CmpNode):
6745 # A CascadedCmpNode is not a complete expression node. It
6746 # hangs off the side of another comparison node, shares
6747 # its left operand with that node, and shares its result
6748 # with the PrimaryCmpNode at the head of the chain.
6752 # cascade CascadedCmpNode
6754 child_attrs = ['operand2', 'cascade']
6757 constant_result = constant_value_not_set # FIXME: where to calculate this?
6759 def infer_type(self, env):
6760 # TODO: Actually implement this (after merging with -unstable).
6761 return py_object_type
6763 def type_dependencies(self, env):
6766 def has_constant_result(self):
6767 return self.constant_result is not constant_value_not_set and \
6768 self.constant_result is not not_a_constant
6770 def analyse_types(self, env):
6771 self.operand2.analyse_types(env)
6773 self.cascade.analyse_types(env)
6775 def has_python_operands(self):
6776 return self.operand2.type.is_pyobject
6778 def coerce_operands_to_pyobjects(self, env):
6779 self.operand2 = self.operand2.coerce_to_pyobject(env)
6780 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
6781 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6783 self.cascade.coerce_operands_to_pyobjects(env)
6785 def coerce_cascaded_operands_to_temp(self, env):
6787 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6788 self.operand2 = self.operand2.coerce_to_simple(env)
6789 self.cascade.coerce_cascaded_operands_to_temp(env)
6791 def generate_evaluation_code(self, code, result, operand1):
6792 if self.type.is_pyobject:
6793 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
6794 code.put_decref(result, self.type)
6796 code.putln("if (%s) {" % result)
6797 self.operand2.generate_evaluation_code(code)
6798 self.generate_operation_code(code, result,
6799 operand1, self.operator, self.operand2)
6801 self.cascade.generate_evaluation_code(
6802 code, result, self.operand2)
6803 # Cascaded cmp result is always temp
6804 self.operand2.generate_disposal_code(code)
6805 self.operand2.free_temps(code)
6808 def annotate(self, code):
6809 self.operand2.annotate(code)
6811 self.cascade.annotate(code)
6814 binop_node_classes = {
6815 "or": BoolBinopNode,
6816 "and": BoolBinopNode,
6831 def binop_node(pos, operator, operand1, operand2, inplace=False):
6832 # Construct binop node of appropriate class for
6834 return binop_node_classes[operator](pos,
6835 operator = operator,
6836 operand1 = operand1,
6837 operand2 = operand2,
6840 #-------------------------------------------------------------------
6844 # Coercion nodes are special in that they are created during
6845 # the analyse_types phase of parse tree processing.
6846 # Their __init__ methods consequently incorporate some aspects
6849 #-------------------------------------------------------------------
6851 class CoercionNode(ExprNode):
6852 # Abstract base class for coercion nodes.
6854 # arg ExprNode node being coerced
6857 constant_result = not_a_constant
6859 def __init__(self, arg):
6863 print("%s Coercing %s" % (self, self.arg))
6865 def calculate_constant_result(self):
6866 # constant folding can break type coercion, so this is disabled
6869 def annotate(self, code):
6870 self.arg.annotate(code)
6871 if self.arg.type != self.type:
6872 file, line, col = self.pos
6873 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
6876 class CastNode(CoercionNode):
6877 # Wrap a node in a C type cast.
6879 def __init__(self, arg, new_type):
6880 CoercionNode.__init__(self, arg)
6881 self.type = new_type
6883 def may_be_none(self):
6884 return self.arg.may_be_none()
6886 def calculate_result_code(self):
6887 return self.arg.result_as(self.type)
6889 def generate_result_code(self, code):
6890 self.arg.generate_result_code(code)
6893 class PyTypeTestNode(CoercionNode):
6894 # This node is used to check that a generic Python
6895 # object is an instance of a particular extension type.
6896 # This node borrows the result of its argument node.
6898 def __init__(self, arg, dst_type, env, notnone=False):
6899 # The arg is know to be a Python object, and
6900 # the dst_type is known to be an extension type.
6901 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
6902 CoercionNode.__init__(self, arg)
6903 self.type = dst_type
6904 self.result_ctype = arg.ctype()
6905 self.notnone = notnone
6907 nogil_check = Node.gil_error
6908 gil_message = "Python type test"
6910 def analyse_types(self, env):
6913 def may_be_none(self):
6916 return self.arg.may_be_none()
6918 def result_in_temp(self):
6919 return self.arg.result_in_temp()
6921 def is_ephemeral(self):
6922 return self.arg.is_ephemeral()
6924 def calculate_constant_result(self):
6928 def calculate_result_code(self):
6929 return self.arg.result()
6931 def generate_result_code(self, code):
6932 if self.type.typeobj_is_available():
6933 if not self.type.is_builtin_type:
6934 code.globalstate.use_utility_code(type_test_utility_code)
6937 self.type.type_test_code(self.arg.py_result(), self.notnone),
6938 code.error_goto(self.pos)))
6940 error(self.pos, "Cannot test type of extern C class "
6941 "without type object name specification")
6943 def generate_post_assignment_code(self, code):
6944 self.arg.generate_post_assignment_code(code)
6946 def free_temps(self, code):
6947 self.arg.free_temps(code)
6950 class NoneCheckNode(CoercionNode):
6951 # This node is used to check that a Python object is not None and
6952 # raises an appropriate exception (as specified by the creating
6955 def __init__(self, arg, exception_type_cname, exception_message):
6956 CoercionNode.__init__(self, arg)
6957 self.type = arg.type
6958 self.result_ctype = arg.ctype()
6959 self.exception_type_cname = exception_type_cname
6960 self.exception_message = exception_message
6962 def analyse_types(self, env):
6965 def may_be_none(self):
6968 def result_in_temp(self):
6969 return self.arg.result_in_temp()
6971 def calculate_result_code(self):
6972 return self.arg.result()
6974 def generate_result_code(self, code):
6976 "if (unlikely(%s == Py_None)) {" % self.arg.result())
6977 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
6978 self.exception_type_cname,
6979 StringEncoding.escape_byte_string(
6980 self.exception_message.encode('UTF-8')),
6981 code.error_goto(self.pos)))
6984 def generate_post_assignment_code(self, code):
6985 self.arg.generate_post_assignment_code(code)
6987 def free_temps(self, code):
6988 self.arg.free_temps(code)
6991 class CoerceToPyTypeNode(CoercionNode):
6992 # This node is used to convert a C data type
6993 # to a Python object.
6995 type = py_object_type
6998 def __init__(self, arg, env, type=py_object_type):
6999 CoercionNode.__init__(self, arg)
7000 if not arg.type.create_to_py_utility_code(env):
7002 "Cannot convert '%s' to Python object" % arg.type)
7003 if type is not py_object_type:
7004 self.type = py_object_type
7005 elif arg.type.is_string:
7006 self.type = bytes_type
7007 elif arg.type is PyrexTypes.c_py_unicode_type:
7008 self.type = unicode_type
7010 gil_message = "Converting to Python object"
7012 def may_be_none(self):
7013 # FIXME: is this always safe?
7016 def coerce_to_boolean(self, env):
7017 arg_type = self.arg.type
7018 if (arg_type == PyrexTypes.c_bint_type or
7019 (arg_type.is_pyobject and arg_type.name == 'bool')):
7020 return self.arg.coerce_to_temp(env)
7022 return CoerceToBooleanNode(self, env)
7024 def coerce_to_integer(self, env):
7025 # If not already some C integer type, coerce to longint.
7026 if self.arg.type.is_int:
7029 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7031 def analyse_types(self, env):
7032 # The arg is always already analysed
7035 def generate_result_code(self, code):
7036 function = self.arg.type.to_py_function
7037 code.putln('%s = %s(%s); %s' % (
7041 code.error_goto_if_null(self.result(), self.pos)))
7042 code.put_gotref(self.py_result())
7045 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7046 # This node is used to convert a C int type to a Python bytes
7051 def __init__(self, arg, env):
7052 arg = arg.coerce_to_simple(env)
7053 CoercionNode.__init__(self, arg)
7054 self.type = Builtin.bytes_type
7056 def generate_result_code(self, code):
7058 arg_result = arg.result()
7059 if arg.type not in (PyrexTypes.c_char_type,
7060 PyrexTypes.c_uchar_type,
7061 PyrexTypes.c_schar_type):
7063 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7064 arg_result, arg_result))
7066 code.putln("if (%s > 255) {" % arg_result)
7067 code.putln('PyErr_Format(PyExc_OverflowError, '
7068 '"value too large to pack into a byte"); %s' % (
7069 code.error_goto(self.pos)))
7072 if arg.type is not PyrexTypes.c_char_type:
7073 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7074 code.putln("%s = (char)%s;" % (temp, arg_result))
7076 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7079 code.error_goto_if_null(self.result(), self.pos)))
7080 if temp is not None:
7081 code.funcstate.release_temp(temp)
7082 code.put_gotref(self.py_result())
7085 class CoerceFromPyTypeNode(CoercionNode):
7086 # This node is used to convert a Python object
7089 def __init__(self, result_type, arg, env):
7090 CoercionNode.__init__(self, arg)
7091 self.type = result_type
7093 if not result_type.create_from_py_utility_code(env):
7095 "Cannot convert Python object to '%s'" % result_type)
7096 if self.type.is_string and self.arg.is_ephemeral():
7098 "Obtaining char * from temporary Python value")
7100 def analyse_types(self, env):
7101 # The arg is always already analysed
7104 def generate_result_code(self, code):
7105 function = self.type.from_py_function
7106 operand = self.arg.py_result()
7107 rhs = "%s(%s)" % (function, operand)
7108 if self.type.is_enum:
7109 rhs = typecast(self.type, c_long_type, rhs)
7110 code.putln('%s = %s; %s' % (
7113 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7114 if self.type.is_pyobject:
7115 code.put_gotref(self.py_result())
7118 class CoerceToBooleanNode(CoercionNode):
7119 # This node is used when a result needs to be used
7120 # in a boolean context.
7122 type = PyrexTypes.c_bint_type
7124 _special_builtins = {
7125 Builtin.list_type : 'PyList_GET_SIZE',
7126 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7127 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7128 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7131 def __init__(self, arg, env):
7132 CoercionNode.__init__(self, arg)
7133 if arg.type.is_pyobject:
7136 def nogil_check(self, env):
7137 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7140 gil_message = "Truth-testing Python object"
7142 def check_const(self):
7146 return self.arg.check_const()
7148 def calculate_result_code(self):
7149 return "(%s != 0)" % self.arg.result()
7151 def generate_result_code(self, code):
7152 if not self.is_temp:
7154 test_func = self._special_builtins.get(self.arg.type)
7155 if test_func is not None:
7156 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7158 self.arg.py_result(),
7160 self.arg.py_result()))
7163 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7165 self.arg.py_result(),
7166 code.error_goto_if_neg(self.result(), self.pos)))
7168 class CoerceToComplexNode(CoercionNode):
7170 def __init__(self, arg, dst_type, env):
7171 if arg.type.is_complex:
7172 arg = arg.coerce_to_simple(env)
7173 self.type = dst_type
7174 CoercionNode.__init__(self, arg)
7175 dst_type.create_declaration_utility_code(env)
7177 def calculate_result_code(self):
7178 if self.arg.type.is_complex:
7179 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7180 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7182 real_part = self.arg.result()
7184 return "%s(%s, %s)" % (
7185 self.type.from_parts,
7189 def generate_result_code(self, code):
7192 class CoerceToTempNode(CoercionNode):
7193 # This node is used to force the result of another node
7194 # to be stored in a temporary. It is only used if the
7195 # argument node's result is not already in a temporary.
7197 def __init__(self, arg, env):
7198 CoercionNode.__init__(self, arg)
7199 self.type = self.arg.type
7200 self.constant_result = self.arg.constant_result
7202 if self.type.is_pyobject:
7203 self.result_ctype = py_object_type
7205 gil_message = "Creating temporary Python reference"
7207 def analyse_types(self, env):
7208 # The arg is always already analysed
7211 def coerce_to_boolean(self, env):
7212 self.arg = self.arg.coerce_to_boolean(env)
7213 if self.arg.is_simple():
7215 self.type = self.arg.type
7216 self.result_ctype = self.type
7219 def generate_result_code(self, code):
7220 #self.arg.generate_evaluation_code(code) # Already done
7221 # by generic generate_subexpr_evaluation_code!
7222 code.putln("%s = %s;" % (
7223 self.result(), self.arg.result_as(self.ctype())))
7224 if self.type.is_pyobject and self.use_managed_ref:
7225 code.put_incref(self.result(), self.ctype())
7228 class CloneNode(CoercionNode):
7229 # This node is employed when the result of another node needs
7230 # to be used multiple times. The argument node's result must
7231 # be in a temporary. This node "borrows" the result from the
7232 # argument node, and does not generate any evaluation or
7233 # disposal code for it. The original owner of the argument
7234 # node is responsible for doing those things.
7236 subexprs = [] # Arg is not considered a subexpr
7239 def __init__(self, arg):
7240 CoercionNode.__init__(self, arg)
7241 if hasattr(arg, 'type'):
7242 self.type = arg.type
7243 self.result_ctype = arg.result_ctype
7244 if hasattr(arg, 'entry'):
7245 self.entry = arg.entry
7248 return self.arg.result()
7250 def type_dependencies(self, env):
7251 return self.arg.type_dependencies(env)
7253 def infer_type(self, env):
7254 return self.arg.infer_type(env)
7256 def analyse_types(self, env):
7257 self.type = self.arg.type
7258 self.result_ctype = self.arg.result_ctype
7260 if hasattr(self.arg, 'entry'):
7261 self.entry = self.arg.entry
7263 def generate_evaluation_code(self, code):
7266 def generate_result_code(self, code):
7269 def generate_disposal_code(self, code):
7272 def free_temps(self, code):
7276 class ModuleRefNode(ExprNode):
7277 # Simple returns the module object
7279 type = py_object_type
7283 def analyse_types(self, env):
7286 def may_be_none(self):
7289 def calculate_result_code(self):
7290 return Naming.module_cname
7292 def generate_result_code(self, code):
7295 class DocstringRefNode(ExprNode):
7296 # Extracts the docstring of the body element
7299 type = py_object_type
7302 def __init__(self, pos, body):
7303 ExprNode.__init__(self, pos)
7304 assert body.type.is_pyobject
7307 def analyse_types(self, env):
7310 def generate_result_code(self, code):
7311 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7312 self.result(), self.body.result(),
7313 code.error_goto_if_null(self.result(), self.pos)))
7314 code.put_gotref(self.result())
7318 #------------------------------------------------------------------------------------
7320 # Runtime support code
7322 #------------------------------------------------------------------------------------
7324 get_name_interned_utility_code = UtilityCode(
7326 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7329 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7331 result = PyObject_GetAttr(dict, name);
7333 PyErr_SetObject(PyExc_NameError, name);
7338 #------------------------------------------------------------------------------------
7340 import_utility_code = UtilityCode(
7342 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7345 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7346 PyObject *py_import = 0;
7347 PyObject *empty_list = 0;
7348 PyObject *module = 0;
7349 PyObject *global_dict = 0;
7350 PyObject *empty_dict = 0;
7352 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7358 empty_list = PyList_New(0);
7363 global_dict = PyModule_GetDict(%(GLOBALS)s);
7366 empty_dict = PyDict_New();
7369 module = PyObject_CallFunctionObjArgs(py_import,
7370 name, global_dict, empty_dict, list, NULL);
7372 Py_XDECREF(empty_list);
7373 Py_XDECREF(py_import);
7374 Py_XDECREF(empty_dict);
7378 "BUILTINS": Naming.builtins_cname,
7379 "GLOBALS": Naming.module_cname,
7382 #------------------------------------------------------------------------------------
7384 get_exception_utility_code = UtilityCode(
7386 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7389 static PyObject *__Pyx_GetExcValue(void) {
7390 PyObject *type = 0, *value = 0, *tb = 0;
7391 PyObject *tmp_type, *tmp_value, *tmp_tb;
7392 PyObject *result = 0;
7393 PyThreadState *tstate = PyThreadState_Get();
7394 PyErr_Fetch(&type, &value, &tb);
7395 PyErr_NormalizeException(&type, &value, &tb);
7396 if (PyErr_Occurred())
7402 tmp_type = tstate->exc_type;
7403 tmp_value = tstate->exc_value;
7404 tmp_tb = tstate->exc_traceback;
7405 tstate->exc_type = type;
7406 tstate->exc_value = value;
7407 tstate->exc_traceback = tb;
7408 /* Make sure tstate is in a consistent state when we XDECREF
7409 these objects (XDECREF may run arbitrary code). */
7410 Py_XDECREF(tmp_type);
7411 Py_XDECREF(tmp_value);
7426 #------------------------------------------------------------------------------------
7428 type_test_utility_code = UtilityCode(
7430 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7433 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7434 if (unlikely(!type)) {
7435 PyErr_Format(PyExc_SystemError, "Missing type object");
7438 if (likely(PyObject_TypeCheck(obj, type)))
7440 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7441 Py_TYPE(obj)->tp_name, type->tp_name);
7446 #------------------------------------------------------------------------------------
7448 find_py2_metaclass_utility_code = UtilityCode(
7450 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7453 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7454 PyObject *metaclass;
7455 /* Default metaclass */
7456 #if PY_MAJOR_VERSION < 3
7457 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7458 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7459 metaclass = PyObject_GetAttrString(base, "__class__");
7462 metaclass = (PyObject*) Py_TYPE(base);
7465 metaclass = (PyObject *) &PyClass_Type;
7468 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7469 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7470 metaclass = (PyObject*) Py_TYPE(base);
7472 metaclass = (PyObject *) &PyType_Type;
7475 Py_INCREF(metaclass);
7480 create_class_utility_code = UtilityCode(
7482 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7483 PyObject *modname); /*proto*/
7486 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7487 PyObject *modname) {
7489 PyObject *metaclass;
7491 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7494 /* Python2 __metaclass__ */
7495 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7497 Py_INCREF(metaclass);
7499 metaclass = __Pyx_FindPy2Metaclass(bases);
7501 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7502 Py_DECREF(metaclass);
7506 requires = [find_py2_metaclass_utility_code])
7508 #------------------------------------------------------------------------------------
7510 create_py3class_utility_code = UtilityCode(
7512 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7513 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7514 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7517 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7518 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7520 Py_INCREF(metaclass);
7521 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7522 Py_DECREF(metaclass);
7527 return __Pyx_FindPy2Metaclass(bases);
7530 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7531 PyObject *modname, PyObject *doc) {
7537 prep = PyObject_GetAttrString(metaclass, "__prepare__");
7539 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7542 return PyDict_New();
7544 pargs = PyTuple_New(2);
7552 PyTuple_SET_ITEM(pargs, 0, name);
7553 PyTuple_SET_ITEM(pargs, 1, bases);
7555 ns = PyObject_Call(prep, pargs, mkw);
7563 /* Required here to emulate assignment order */
7564 /* XXX: use consts here */
7565 #if PY_MAJOR_VERSION >= 3
7566 str = PyUnicode_FromString("__module__");
7568 str = PyString_FromString("__module__");
7575 if (PyObject_SetItem(ns, str, modname) < 0) {
7582 #if PY_MAJOR_VERSION >= 3
7583 str = PyUnicode_FromString("__doc__");
7585 str = PyString_FromString("__doc__");
7591 if (PyObject_SetItem(ns, str, doc) < 0) {
7601 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7603 PyObject *margs = PyTuple_New(3);
7609 PyTuple_SET_ITEM(margs, 0, name);
7610 PyTuple_SET_ITEM(margs, 1, bases);
7611 PyTuple_SET_ITEM(margs, 2, dict);
7612 result = PyObject_Call(metaclass, margs, mkw);
7617 requires = [find_py2_metaclass_utility_code])
7619 #------------------------------------------------------------------------------------
7621 cpp_exception_utility_code = UtilityCode(
7623 #ifndef __Pyx_CppExn2PyErr
7624 static void __Pyx_CppExn2PyErr() {
7626 if (PyErr_Occurred())
7627 ; // let the latest Python exn pass through and ignore the current one
7630 } catch (const std::invalid_argument& exn) {
7631 // Catch a handful of different errors here and turn them into the
7632 // equivalent Python errors.
7633 // Change invalid_argument to ValueError
7634 PyErr_SetString(PyExc_ValueError, exn.what());
7635 } catch (const std::out_of_range& exn) {
7636 // Change out_of_range to IndexError
7637 PyErr_SetString(PyExc_IndexError, exn.what());
7638 } catch (const std::exception& exn) {
7639 PyErr_SetString(PyExc_RuntimeError, exn.what());
7643 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7651 pyerr_occurred_withgil_utility_code= UtilityCode(
7653 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7656 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7659 PyGILState_STATE _save = PyGILState_Ensure();
7661 err = !!PyErr_Occurred();
7663 PyGILState_Release(_save);
7670 #------------------------------------------------------------------------------------
7672 raise_noneattr_error_utility_code = UtilityCode(
7674 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7677 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7678 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7682 raise_noneindex_error_utility_code = UtilityCode(
7684 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7687 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7688 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7692 raise_none_iter_error_utility_code = UtilityCode(
7694 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7697 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7698 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7702 #------------------------------------------------------------------------------------
7704 getitem_dict_utility_code = UtilityCode(
7706 #if PY_MAJOR_VERSION >= 3
7707 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7709 if (unlikely(d == Py_None)) {
7710 __Pyx_RaiseNoneIndexingError();
7713 value = PyDict_GetItemWithError(d, key);
7714 if (unlikely(!value)) {
7715 if (!PyErr_Occurred())
7716 PyErr_SetObject(PyExc_KeyError, key);
7723 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7726 requires = [raise_noneindex_error_utility_code])
7728 #------------------------------------------------------------------------------------
7730 getitem_int_pyunicode_utility_code = UtilityCode(
7732 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7733 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7734 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7736 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7737 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7738 return PyUnicode_AS_UNICODE(ustring)[i];
7739 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7740 i += PyUnicode_GET_SIZE(ustring);
7741 return PyUnicode_AS_UNICODE(ustring)[i];
7743 PyErr_SetString(PyExc_IndexError, "string index out of range");
7744 return (Py_UNICODE)-1;
7748 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7750 PyObject *uchar_string;
7751 if (!j) return (Py_UNICODE)-1;
7752 uchar_string = PyObject_GetItem(ustring, j);
7754 if (!uchar_string) return (Py_UNICODE)-1;
7755 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7756 Py_DECREF(uchar_string);
7761 getitem_int_utility_code = UtilityCode(
7764 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7766 if (!j) return NULL;
7767 r = PyObject_GetItem(o, j);
7774 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7775 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7776 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7778 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
7779 if (likely(o != Py_None)) {
7780 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
7781 PyObject *r = Py%(type)s_GET_ITEM(o, i);
7785 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
7786 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
7791 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7793 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
7796 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7797 __Pyx_GetItemInt_Fast(o, i) : \\
7798 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7800 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
7802 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7803 r = PyList_GET_ITEM(o, i);
7806 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
7807 r = PyTuple_GET_ITEM(o, i);
7810 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
7811 r = PySequence_GetItem(o, i);
7814 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7824 #------------------------------------------------------------------------------------
7826 setitem_int_utility_code = UtilityCode(
7828 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7829 __Pyx_SetItemInt_Fast(o, i, v) : \\
7830 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
7832 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
7835 r = PyObject_SetItem(o, j, v);
7840 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
7841 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7843 Py_DECREF(PyList_GET_ITEM(o, i));
7844 PyList_SET_ITEM(o, i, v);
7847 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
7848 return PySequence_SetItem(o, i, v);
7850 PyObject *j = PyInt_FromSsize_t(i);
7851 return __Pyx_SetItemInt_Generic(o, j, v);
7858 #------------------------------------------------------------------------------------
7860 delitem_int_utility_code = UtilityCode(
7862 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7863 __Pyx_DelItemInt_Fast(o, i) : \\
7864 __Pyx_DelItem_Generic(o, to_py_func(i)))
7866 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
7869 r = PyObject_DelItem(o, j);
7874 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
7875 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
7876 return PySequence_DelItem(o, i);
7878 PyObject *j = PyInt_FromSsize_t(i);
7879 return __Pyx_DelItem_Generic(o, j);
7886 #------------------------------------------------------------------------------------
7888 raise_too_many_values_to_unpack = UtilityCode(
7890 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
7893 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
7894 PyErr_Format(PyExc_ValueError,
7895 #if PY_VERSION_HEX < 0x02050000
7896 "too many values to unpack (expected %d)", (int)expected);
7898 "too many values to unpack (expected %zd)", expected);
7903 raise_need_more_values_to_unpack = UtilityCode(
7905 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
7908 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
7909 PyErr_Format(PyExc_ValueError,
7910 #if PY_VERSION_HEX < 0x02050000
7911 "need more than %d value%s to unpack", (int)index,
7913 "need more than %zd value%s to unpack", index,
7915 (index == 1) ? "" : "s");
7919 #------------------------------------------------------------------------------------
7921 tuple_unpacking_error_code = UtilityCode(
7923 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
7926 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
7928 __Pyx_RaiseNoneNotIterableError();
7929 } else if (PyTuple_GET_SIZE(t) < index) {
7930 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
7932 __Pyx_RaiseTooManyValuesError(index);
7936 requires = [raise_none_iter_error_utility_code,
7937 raise_need_more_values_to_unpack,
7938 raise_too_many_values_to_unpack]
7941 unpacking_utility_code = UtilityCode(
7943 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
7944 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
7947 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
7949 if (!(item = PyIter_Next(iter))) {
7950 if (!PyErr_Occurred()) {
7951 __Pyx_RaiseNeedMoreValuesError(index);
7957 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
7959 if ((item = PyIter_Next(iter))) {
7961 __Pyx_RaiseTooManyValuesError(expected);
7964 else if (!PyErr_Occurred())
7970 requires = [raise_need_more_values_to_unpack,
7971 raise_too_many_values_to_unpack]
7974 #------------------------------------------------------------------------------------
7976 # CPython supports calling functions with non-dict kwargs by
7977 # converting them to a dict first
7979 kwargs_call_utility_code = UtilityCode(
7981 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
7984 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
7986 if (likely(PyDict_Check(kwargs))) {
7987 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
7989 PyObject* real_dict;
7990 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
7991 if (unlikely(!real_dict))
7993 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
7994 Py_DECREF(real_dict);
7995 return result; /* may be NULL */
8002 #------------------------------------------------------------------------------------
8004 int_pow_utility_code = UtilityCode(
8006 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8009 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8021 if (unlikely(e<0)) return 0;
8024 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8032 # ------------------------------ Division ------------------------------------
8034 div_int_utility_code = UtilityCode(
8036 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8039 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8041 %(type)s r = a - q*b;
8042 q -= ((r != 0) & ((r ^ b) < 0));
8047 mod_int_utility_code = UtilityCode(
8049 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8052 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8053 %(type)s r = a %% b;
8054 r += ((r != 0) & ((r ^ b) < 0)) * b;
8059 mod_float_utility_code = UtilityCode(
8061 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8064 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8065 %(type)s r = fmod%(math_h_modifier)s(a, b);
8066 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8071 cdivision_warning_utility_code = UtilityCode(
8073 static int __Pyx_cdivision_warning(void); /* proto */
8076 static int __Pyx_cdivision_warning(void) {
8077 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8078 "division with oppositely signed operands, C and Python semantics differ",
8085 'FILENAME': Naming.filename_cname,
8086 'LINENO': Naming.lineno_cname,
8090 division_overflow_test_code = UtilityCode(
8092 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8093 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8097 binding_cfunc_utility_code = UtilityCode(
8099 #define %(binding_cfunc)s_USED 1
8102 PyCFunctionObject func;
8103 } %(binding_cfunc)s_object;
8105 PyTypeObject %(binding_cfunc)s_type;
8106 PyTypeObject *%(binding_cfunc)s = NULL;
8108 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8109 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8111 int %(binding_cfunc)s_init(void); /* proto */
8112 """ % Naming.__dict__,
8115 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8116 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8121 op->func.m_self = self;
8123 op->func.m_module = module;
8124 PyObject_GC_Track(op);
8125 return (PyObject *)op;
8128 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8129 PyObject_GC_UnTrack(m);
8130 Py_XDECREF(m->func.m_self);
8131 Py_XDECREF(m->func.m_module);
8135 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8138 return PyMethod_New(func, obj, type);
8141 int %(binding_cfunc)s_init(void) {
8142 %(binding_cfunc)s_type = PyCFunction_Type;
8143 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8144 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8145 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8146 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8149 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8153 """ % Naming.__dict__)