2 # Pyrex - Parse tree nodes for expressions
7 cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
8 CompileError=object, UtilityCode=object, StringEncoding=object, operator=object,
9 Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
10 list_type=object, tuple_type=object, set_type=object, dict_type=object, \
11 unicode_type=object, str_type=object, bytes_type=object, type_type=object,
12 Builtin=object, Symtab=object, Utils=object, find_coercion_error=object,
13 debug_disposal_code=object, debug_temp_alloc=object, debug_coercion=object)
17 from Errors import error, warning, warn_once, InternalError, CompileError
18 from Errors import hold_errors, release_errors, held_errors, report_error
19 from Code import UtilityCode
23 from Nodes import Node
25 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
27 from Builtin import list_type, tuple_type, set_type, dict_type, \
28 unicode_type, str_type, bytes_type, type_type
32 from Cython import Utils
33 from Annotate import AnnotationItem
35 from Cython.Debugging import print_call_chain
36 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
40 from __builtin__ import basestring
42 basestring = str # Python 3
44 class NotConstant(object):
46 return "<NOT CONSTANT>"
48 not_a_constant = NotConstant()
49 constant_value_not_set = object()
51 # error messages when coercing from key[0] to key[1]
52 find_coercion_error = {
53 # string related errors
54 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
55 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
56 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
57 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
58 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
59 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
60 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
61 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
62 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
63 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
68 # subexprs [string] Class var holding names of subexpr node attrs
69 # type PyrexType Type of the result
70 # result_code string Code fragment
71 # result_ctype string C type of result_code if different from type
72 # is_temp boolean Result is in a temporary variable
73 # is_sequence_constructor
74 # boolean Is a list or tuple constructor expression
75 # is_starred boolean Is a starred expression (e.g. '*a')
77 # [ExprNode or [ExprNode or None] or None]
78 # Cached result of subexpr_nodes()
79 # use_managed_ref boolean use ref-counted temps/assignments/etc.
84 old_temp = None # error checker for multiple frees etc.
85 use_managed_ref = True # can be set by optimisation transforms
87 # The Analyse Expressions phase for expressions is split
88 # into two sub-phases:
91 # Determines the result type of the expression based
92 # on the types of its sub-expressions, and inserts
93 # coercion nodes into the expression tree where needed.
94 # Marks nodes which will need to have temporary variables
98 # Allocates temporary variables where needed, and fills
99 # in the result_code field of each node.
101 # ExprNode provides some convenience routines which
102 # perform both of the above phases. These should only
103 # be called from statement nodes, and only when no
104 # coercion nodes need to be added around the expression
105 # being analysed. In that case, the above two phases
106 # should be invoked separately.
108 # Framework code in ExprNode provides much of the common
109 # processing for the various phases. It makes use of the
110 # 'subexprs' class attribute of ExprNodes, which should
111 # contain a list of the names of attributes which can
112 # hold sub-nodes or sequences of sub-nodes.
114 # The framework makes use of a number of abstract methods.
115 # Their responsibilities are as follows.
117 # Declaration Analysis phase
119 # analyse_target_declaration
120 # Called during the Analyse Declarations phase to analyse
121 # the LHS of an assignment or argument of a del statement.
122 # Nodes which cannot be the LHS of an assignment need not
125 # Expression Analysis phase
128 # - Call analyse_types on all sub-expressions.
129 # - Check operand types, and wrap coercion nodes around
130 # sub-expressions where needed.
131 # - Set the type of this node.
132 # - If a temporary variable will be required for the
133 # result, set the is_temp flag of this node.
135 # analyse_target_types
136 # Called during the Analyse Types phase to analyse
137 # the LHS of an assignment or argument of a del
138 # statement. Similar responsibilities to analyse_types.
141 # Called by the default implementation of allocate_target_temps.
142 # Should return a C lvalue for assigning to the node. The default
143 # implementation calls calculate_result_code.
146 # - Check that this node and its subnodes form a
147 # legal constant expression. If so, do nothing,
148 # otherwise call not_const.
150 # The default implementation of check_const
151 # assumes that the expression is not constant.
154 # - Same as check_const, except check that the
155 # expression is a C lvalue whose address is
156 # constant. Otherwise, call addr_not_const.
158 # The default implementation of calc_const_addr
159 # assumes that the expression is not a constant
162 # Code Generation phase
164 # generate_evaluation_code
165 # - Call generate_evaluation_code for sub-expressions.
166 # - Perform the functions of generate_result_code
168 # - If result is temporary, call generate_disposal_code
169 # on all sub-expressions.
171 # A default implementation of generate_evaluation_code
172 # is provided which uses the following abstract methods:
174 # generate_result_code
175 # - Generate any C statements necessary to calculate
176 # the result of this node from the results of its
179 # calculate_result_code
180 # - Should return a C code fragment evaluating to the
181 # result. This is only called when the result is not
184 # generate_assignment_code
185 # Called on the LHS of an assignment.
186 # - Call generate_evaluation_code for sub-expressions.
187 # - Generate code to perform the assignment.
188 # - If the assignment absorbed a reference, call
189 # generate_post_assignment_code on the RHS,
190 # otherwise call generate_disposal_code on it.
192 # generate_deletion_code
193 # Called on an argument of a del statement.
194 # - Call generate_evaluation_code for sub-expressions.
195 # - Generate code to perform the deletion.
196 # - Call generate_disposal_code on all sub-expressions.
200 is_sequence_constructor = 0
203 saved_subexpr_nodes = None
208 constant_result = constant_value_not_set
211 _get_child_attrs = operator.attrgetter('subexprs')
212 except AttributeError:
214 def __get_child_attrs(self):
216 _get_child_attrs = __get_child_attrs
217 child_attrs = property(fget=_get_child_attrs)
219 def not_implemented(self, method_name):
220 print_call_chain(method_name, "not implemented") ###
222 "%s.%s not implemented" %
223 (self.__class__.__name__, method_name))
228 def is_ephemeral(self):
229 # An ephemeral node is one whose result is in
230 # a Python temporary and we suspect there are no
231 # other references to it. Certain operations are
232 # disallowed on such values, since they are
233 # likely to result in a dangling pointer.
234 return self.type.is_pyobject and self.is_temp
236 def subexpr_nodes(self):
237 # Extract a list of subexpression nodes based
238 # on the contents of the subexprs class attribute.
240 for name in self.subexprs:
241 item = getattr(self, name)
243 if type(item) is list:
251 return self.temp_code
253 return self.calculate_result_code()
255 def result_as(self, type = None):
256 # Return the result code cast to the specified C type.
257 return typecast(type, self.ctype(), self.result())
260 # Return the result code cast to PyObject *.
261 return self.result_as(py_object_type)
264 # Return the native C type of the result (i.e. the
265 # C type of the result_code expression).
266 return self.result_ctype or self.type
268 def get_constant_c_result_code(self):
269 # Return the constant value of this node as a result code
270 # string, or None if the node is not constant. This method
271 # can be called when the constant result code is required
272 # before the code generation phase.
274 # The return value is a string that can represent a simple C
275 # value, a constant C name or a constant C expression. If the
276 # node type depends on Python code, this must return None.
279 def calculate_constant_result(self):
280 # Calculate the constant compile time result value of this
281 # expression and store it in ``self.constant_result``. Does
282 # nothing by default, thus leaving ``self.constant_result``
283 # unknown. If valid, the result can be an arbitrary Python
286 # This must only be called when it is assured that all
287 # sub-expressions have a valid constant_result value. The
288 # ConstantFolding transform will do this.
291 def has_constant_result(self):
292 return self.constant_result is not constant_value_not_set and \
293 self.constant_result is not not_a_constant
295 def compile_time_value(self, denv):
296 # Return value of compile-time expression, or report error.
297 error(self.pos, "Invalid compile-time expression")
299 def compile_time_value_error(self, e):
300 error(self.pos, "Error in compile-time expression: %s: %s" % (
301 e.__class__.__name__, e))
303 # ------------- Declaration Analysis ----------------
305 def analyse_target_declaration(self, env):
306 error(self.pos, "Cannot assign to or delete this")
308 # ------------- Expression Analysis ----------------
310 def analyse_const_expression(self, env):
311 # Called during the analyse_declarations phase of a
312 # constant expression. Analyses the expression's type,
313 # checks whether it is a legal const expression,
314 # and determines its value.
315 self.analyse_types(env)
316 return self.check_const()
318 def analyse_expressions(self, env):
319 # Convenience routine performing both the Type
320 # Analysis and Temp Allocation phases for a whole
322 self.analyse_types(env)
324 def analyse_target_expression(self, env, rhs):
325 # Convenience routine performing both the Type
326 # Analysis and Temp Allocation phases for the LHS of
328 self.analyse_target_types(env)
330 def analyse_boolean_expression(self, env):
331 # Analyse expression and coerce to a boolean.
332 self.analyse_types(env)
333 bool = self.coerce_to_boolean(env)
336 def analyse_temp_boolean_expression(self, env):
337 # Analyse boolean expression and coerce result into
338 # a temporary. This is used when a branch is to be
339 # performed on the result and we won't have an
340 # opportunity to ensure disposal code is executed
341 # afterwards. By forcing the result into a temporary,
342 # we ensure that all disposal has been done by the
343 # time we get the result.
344 self.analyse_types(env)
345 return self.coerce_to_boolean(env).coerce_to_simple(env)
347 # --------------- Type Inference -----------------
349 def type_dependencies(self, env):
350 # Returns the list of entries whose types must be determined
351 # before the type of self can be infered.
352 if hasattr(self, 'type') and self.type is not None:
354 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
356 def infer_type(self, env):
357 # Attempt to deduce the type of self.
358 # Differs from analyse_types as it avoids unnecessary
359 # analysis of subexpressions, but can assume everything
360 # in self.type_dependencies() has been resolved.
361 if hasattr(self, 'type') and self.type is not None:
363 elif hasattr(self, 'entry') and self.entry is not None:
364 return self.entry.type
366 self.not_implemented("infer_type")
368 # --------------- Type Analysis ------------------
370 def analyse_as_module(self, env):
371 # If this node can be interpreted as a reference to a
372 # cimported module, return its scope, else None.
375 def analyse_as_type(self, env):
376 # If this node can be interpreted as a reference to a
377 # type, return that type, else None.
380 def analyse_as_extension_type(self, env):
381 # If this node can be interpreted as a reference to an
382 # extension type, return its type, else None.
385 def analyse_types(self, env):
386 self.not_implemented("analyse_types")
388 def analyse_target_types(self, env):
389 self.analyse_types(env)
391 def nogil_check(self, env):
392 # By default, any expression based on Python objects is
393 # prevented in nogil environments. Subtypes must override
394 # this if they can work without the GIL.
395 if self.type.is_pyobject:
398 def gil_assignment_check(self, env):
399 if env.nogil and self.type.is_pyobject:
400 error(self.pos, "Assignment of Python object not allowed without gil")
402 def check_const(self):
407 error(self.pos, "Not allowed in a constant expression")
409 def check_const_addr(self):
410 self.addr_not_const()
413 def addr_not_const(self):
414 error(self.pos, "Address is not constant")
416 # ----------------- Result Allocation -----------------
418 def result_in_temp(self):
419 # Return true if result is in a temporary owned by
420 # this node or one of its subexpressions. Overridden
421 # by certain nodes which can share the result of
425 def target_code(self):
426 # Return code fragment for use as LHS of a C assignment.
427 return self.calculate_result_code()
429 def calculate_result_code(self):
430 self.not_implemented("calculate_result_code")
432 # def release_target_temp(self, env):
433 # # Release temporaries used by LHS of an assignment.
434 # self.release_subexpr_temps(env)
436 def allocate_temp_result(self, code):
438 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
442 type = PyrexTypes.py_object_type
443 self.temp_code = code.funcstate.allocate_temp(
444 type, manage_ref=self.use_managed_ref)
446 self.temp_code = None
448 def release_temp_result(self, code):
449 if not self.temp_code:
451 raise RuntimeError("temp %s released multiple times in %s" % (
452 self.old_temp, self.__class__.__name__))
454 raise RuntimeError("no temp, but release requested in %s" % (
455 self.__class__.__name__))
456 code.funcstate.release_temp(self.temp_code)
457 self.old_temp = self.temp_code
458 self.temp_code = None
460 # ---------------- Code Generation -----------------
462 def make_owned_reference(self, code):
463 # If result is a pyobject, make sure we own
465 if self.type.is_pyobject and not self.result_in_temp():
466 code.put_incref(self.result(), self.ctype())
468 def generate_evaluation_code(self, code):
469 code.mark_pos(self.pos)
471 # Generate code to evaluate this node and
472 # its sub-expressions, and dispose of any
473 # temporary results of its sub-expressions.
474 self.generate_subexpr_evaluation_code(code)
477 self.allocate_temp_result(code)
479 self.generate_result_code(code)
481 # If we are temp we do not need to wait until this node is disposed
482 # before disposing children.
483 self.generate_subexpr_disposal_code(code)
484 self.free_subexpr_temps(code)
486 def generate_subexpr_evaluation_code(self, code):
487 for node in self.subexpr_nodes():
488 node.generate_evaluation_code(code)
490 def generate_result_code(self, code):
491 self.not_implemented("generate_result_code")
493 def generate_disposal_code(self, code):
495 if self.type.is_pyobject:
496 code.put_decref_clear(self.result(), self.ctype())
498 # Already done if self.is_temp
499 self.generate_subexpr_disposal_code(code)
501 def generate_subexpr_disposal_code(self, code):
502 # Generate code to dispose of temporary results
503 # of all sub-expressions.
504 for node in self.subexpr_nodes():
505 node.generate_disposal_code(code)
507 def generate_post_assignment_code(self, code):
509 if self.type.is_pyobject:
510 code.putln("%s = 0;" % self.result())
512 self.generate_subexpr_disposal_code(code)
514 def generate_assignment_code(self, rhs, code):
515 # Stub method for nodes which are not legal as
516 # the LHS of an assignment. An error will have
517 # been reported earlier.
520 def generate_deletion_code(self, code):
521 # Stub method for nodes that are not legal as
522 # the argument of a del statement. An error
523 # will have been reported earlier.
526 def free_temps(self, code):
528 if not self.type.is_void:
529 self.release_temp_result(code)
531 self.free_subexpr_temps(code)
533 def free_subexpr_temps(self, code):
534 for sub in self.subexpr_nodes():
537 def generate_function_definitions(self, env, code):
540 # ---------------- Annotation ---------------------
542 def annotate(self, code):
543 for node in self.subexpr_nodes():
546 # ----------------- Coercion ----------------------
548 def coerce_to(self, dst_type, env):
549 # Coerce the result so that it can be assigned to
550 # something of type dst_type. If processing is necessary,
551 # wraps this node in a coercion node and returns that.
552 # Otherwise, returns this node unchanged.
554 # This method is called during the analyse_expressions
555 # phase of the src_node's processing.
557 # Note that subclasses that override this (especially
558 # ConstNodes) must not (re-)set their own .type attribute
559 # here. Since expression nodes may turn up in different
560 # places in the tree (e.g. inside of CloneNodes in cascaded
561 # assignments), this method must return a new node instance
562 # if it changes the type.
566 src_is_py_type = src_type.is_pyobject
567 dst_is_py_type = dst_type.is_pyobject
569 if self.check_for_coercion_error(dst_type):
572 if dst_type.is_reference:
573 dst_type = dst_type.ref_base_type
575 if dst_type.is_pyobject:
576 if not src.type.is_pyobject:
577 if dst_type is bytes_type and src.type.is_int:
578 src = CoerceIntToBytesNode(src, env)
580 src = CoerceToPyTypeNode(src, env)
581 if not src.type.subtype_of(dst_type):
582 if not isinstance(src, NoneNode):
583 src = PyTypeTestNode(src, dst_type, env)
584 elif src.type.is_pyobject:
585 src = CoerceFromPyTypeNode(dst_type, src, env)
586 elif (dst_type.is_complex
587 and src_type != dst_type
588 and dst_type.assignable_from(src_type)):
589 src = CoerceToComplexNode(src, dst_type, env)
590 else: # neither src nor dst are py types
591 # Added the string comparison, since for c types that
592 # is enough, but Cython gets confused when the types are
593 # in different pxi files.
594 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
595 self.fail_assignment(dst_type)
598 def fail_assignment(self, dst_type):
599 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
601 def check_for_coercion_error(self, dst_type, fail=False, default=None):
602 if fail and not default:
603 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
604 message = find_coercion_error((self.type, dst_type), default)
605 if message is not None:
606 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
609 self.fail_assignment(dst_type)
613 def coerce_to_pyobject(self, env):
614 return self.coerce_to(PyrexTypes.py_object_type, env)
616 def coerce_to_boolean(self, env):
617 # Coerce result to something acceptable as
620 # if it's constant, calculate the result now
621 if self.has_constant_result():
622 bool_value = bool(self.constant_result)
623 return BoolNode(self.pos, value=bool_value,
624 constant_result=bool_value)
627 if type.is_pyobject or type.is_ptr or type.is_float:
628 return CoerceToBooleanNode(self, env)
630 if not (type.is_int or type.is_enum or type.is_error):
632 "Type '%s' not acceptable as a boolean" % type)
635 def coerce_to_integer(self, env):
636 # If not already some C integer type, coerce to longint.
640 return self.coerce_to(PyrexTypes.c_long_type, env)
642 def coerce_to_temp(self, env):
643 # Ensure that the result is in a temporary.
644 if self.result_in_temp():
647 return CoerceToTempNode(self, env)
649 def coerce_to_simple(self, env):
650 # Ensure that the result is simple (see is_simple).
654 return self.coerce_to_temp(env)
657 # A node is simple if its result is something that can
658 # be referred to without performing any operations, e.g.
659 # a constant, local var, C global var, struct member
660 # reference, or temporary.
661 return self.result_in_temp()
663 def may_be_none(self):
664 if not self.type.is_pyobject:
666 if self.constant_result not in (not_a_constant, constant_value_not_set):
667 return self.constant_result is not None
670 def as_cython_attribute(self):
673 def as_none_safe_node(self, message, error="PyExc_TypeError"):
674 # Wraps the node in a NoneCheckNode if it is not known to be
675 # not-None (e.g. because it is a Python literal).
676 if self.may_be_none():
677 return NoneCheckNode(self, error, message)
682 class AtomicExprNode(ExprNode):
683 # Abstract base class for expression nodes which have
684 # no sub-expressions.
688 # Override to optimize -- we know we have no children
689 def generate_subexpr_evaluation_code(self, code):
691 def generate_subexpr_disposal_code(self, code):
694 class PyConstNode(AtomicExprNode):
695 # Abstract base class for constant Python values.
698 type = py_object_type
703 def may_be_none(self):
706 def analyse_types(self, env):
709 def calculate_result_code(self):
712 def generate_result_code(self, code):
716 class NoneNode(PyConstNode):
717 # The constant value None
721 constant_result = None
725 def compile_time_value(self, denv):
728 def may_be_none(self):
732 class EllipsisNode(PyConstNode):
733 # '...' in a subscript list.
735 value = "Py_Ellipsis"
737 constant_result = Ellipsis
739 def compile_time_value(self, denv):
743 class ConstNode(AtomicExprNode):
744 # Abstract base type for literal constant nodes.
746 # value string C code fragment
754 def may_be_none(self):
757 def analyse_types(self, env):
758 pass # Types are held in class variables
760 def check_const(self):
763 def get_constant_c_result_code(self):
764 return self.calculate_result_code()
766 def calculate_result_code(self):
767 return str(self.value)
769 def generate_result_code(self, code):
773 class BoolNode(ConstNode):
774 type = PyrexTypes.c_bint_type
775 # The constant value True or False
777 def calculate_constant_result(self):
778 self.constant_result = self.value
780 def compile_time_value(self, denv):
783 def calculate_result_code(self):
784 return str(int(self.value))
787 class NullNode(ConstNode):
788 type = PyrexTypes.c_null_ptr_type
792 def get_constant_c_result_code(self):
796 class CharNode(ConstNode):
797 type = PyrexTypes.c_char_type
799 def calculate_constant_result(self):
800 self.constant_result = ord(self.value)
802 def compile_time_value(self, denv):
803 return ord(self.value)
805 def calculate_result_code(self):
806 return "'%s'" % StringEncoding.escape_char(self.value)
809 class IntNode(ConstNode):
812 # longness "" or "L" or "LL"
813 # is_c_literal True/False/None creator considers this a C integer literal
817 is_c_literal = None # unknown
819 def __init__(self, pos, **kwds):
820 ExprNode.__init__(self, pos, **kwds)
821 if 'type' not in kwds:
822 self.type = self.find_suitable_type_for_value()
824 def find_suitable_type_for_value(self):
825 if self.constant_result is constant_value_not_set:
827 self.calculate_constant_result()
830 # we ignore 'is_c_literal = True' and instead map signed 32bit
831 # integers as C long values
832 if self.is_c_literal or \
833 self.constant_result in (constant_value_not_set, not_a_constant) or \
834 self.unsigned or self.longness == 'LL':
835 # clearly a C literal
836 rank = (self.longness == 'LL') and 2 or 1
837 suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
839 suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
841 # C literal or Python literal - split at 32bit boundary
842 if self.constant_result >= -2**31 and self.constant_result < 2**31:
843 if self.type and self.type.is_int:
844 suitable_type = self.type
846 suitable_type = PyrexTypes.c_long_type
848 suitable_type = PyrexTypes.py_object_type
851 def coerce_to(self, dst_type, env):
852 if self.type is dst_type:
854 elif dst_type.is_float:
855 if self.constant_result is not not_a_constant:
856 float_value = float(self.constant_result)
857 return FloatNode(self.pos, value=repr(float_value), type=dst_type,
858 constant_result=float_value)
860 return FloatNode(self.pos, value=self.value, type=dst_type,
861 constant_result=not_a_constant)
862 if dst_type.is_numeric and not dst_type.is_complex:
863 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
864 type = dst_type, is_c_literal = True,
865 unsigned=self.unsigned, longness=self.longness)
867 elif dst_type.is_pyobject:
868 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
869 type = PyrexTypes.py_object_type, is_c_literal = False,
870 unsigned=self.unsigned, longness=self.longness)
872 # FIXME: not setting the type here to keep it working with
873 # complex numbers. Should they be special cased?
874 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
875 unsigned=self.unsigned, longness=self.longness)
876 # We still need to perform normal coerce_to processing on the
877 # result, because we might be coercing to an extension type,
878 # in which case a type test node will be needed.
879 return ConstNode.coerce_to(node, dst_type, env)
881 def coerce_to_boolean(self, env):
883 self.pos, value=self.value,
884 type = PyrexTypes.c_bint_type,
885 unsigned=self.unsigned, longness=self.longness)
887 def generate_evaluation_code(self, code):
888 if self.type.is_pyobject:
889 # pre-allocate a Python version of the number
890 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
891 self.result_code = code.get_py_num(plain_integer_string, self.longness)
893 self.result_code = self.get_constant_c_result_code()
895 def get_constant_c_result_code(self):
896 return self.value_as_c_integer_string() + self.unsigned + self.longness
898 def value_as_c_integer_string(self, plain_digits=False):
900 if isinstance(value, basestring) and len(value) > 2:
901 # must convert C-incompatible Py3 oct/bin notations
904 value = int(value[2:], 8)
906 value = value[0] + value[2:] # '0o123' => '0123'
907 elif value[1] in 'bB':
908 value = int(value[2:], 2)
909 elif plain_digits and value[1] in 'xX':
910 value = int(value[2:], 16)
913 def calculate_result_code(self):
914 return self.result_code
916 def calculate_constant_result(self):
917 self.constant_result = Utils.str_to_number(self.value)
919 def compile_time_value(self, denv):
920 return Utils.str_to_number(self.value)
923 class FloatNode(ConstNode):
924 type = PyrexTypes.c_double_type
926 def calculate_constant_result(self):
927 self.constant_result = float(self.value)
929 def compile_time_value(self, denv):
930 return float(self.value)
932 def calculate_result_code(self):
934 assert isinstance(strval, (str, unicode))
935 cmpval = repr(float(strval))
937 return "(Py_HUGE_VAL * 0)"
938 elif cmpval == 'inf':
940 elif cmpval == '-inf':
941 return "(-Py_HUGE_VAL)"
946 class BytesNode(ConstNode):
947 # A char* or bytes literal
951 # start off as Python 'bytes' to support len() in O(1)
954 def compile_time_value(self, denv):
957 def analyse_as_type(self, env):
958 type = PyrexTypes.parse_basic_type(self.value)
961 from TreeFragment import TreeFragment
962 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
963 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
964 sizeof_node = declaration.root.stats[0].expr
965 sizeof_node.analyse_types(env)
966 if isinstance(sizeof_node, SizeofTypeNode):
967 return sizeof_node.arg_type
969 def can_coerce_to_char_literal(self):
970 return len(self.value) == 1
972 def coerce_to_boolean(self, env):
973 # This is special because testing a C char* for truth directly
974 # would yield the wrong result.
975 return BoolNode(self.pos, value=bool(self.value))
977 def coerce_to(self, dst_type, env):
978 if self.type == dst_type:
981 if not self.can_coerce_to_char_literal():
982 error(self.pos, "Only single-character string literals can be coerced into ints.")
984 if dst_type.is_unicode_char:
985 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
987 return CharNode(self.pos, value=self.value)
989 node = BytesNode(self.pos, value=self.value)
990 if dst_type.is_pyobject:
991 if dst_type in (py_object_type, Builtin.bytes_type):
992 node.type = Builtin.bytes_type
994 self.check_for_coercion_error(dst_type, fail=True)
996 elif dst_type == PyrexTypes.c_char_ptr_type:
999 elif dst_type == PyrexTypes.c_uchar_ptr_type:
1000 node.type = PyrexTypes.c_char_ptr_type
1001 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
1002 elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
1003 node.type = dst_type
1006 # We still need to perform normal coerce_to processing on the
1007 # result, because we might be coercing to an extension type,
1008 # in which case a type test node will be needed.
1009 return ConstNode.coerce_to(node, dst_type, env)
1011 def generate_evaluation_code(self, code):
1012 if self.type.is_pyobject:
1013 self.result_code = code.get_py_string_const(self.value)
1015 self.result_code = code.get_string_const(self.value)
1017 def get_constant_c_result_code(self):
1020 def calculate_result_code(self):
1021 return self.result_code
1024 class UnicodeNode(PyConstNode):
1025 # A Python unicode object
1027 # value EncodedString
1028 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
1033 def coerce_to(self, dst_type, env):
1034 if dst_type is self.type:
1036 elif dst_type.is_unicode_char:
1037 if not self.can_coerce_to_char_literal():
1038 error(self.pos, "Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
1040 int_value = ord(self.value)
1041 return IntNode(self.pos, type=dst_type, value=str(int_value), constant_result=int_value)
1042 elif not dst_type.is_pyobject:
1043 if dst_type.is_string and self.bytes_value is not None:
1044 # special case: '-3' enforced unicode literal used in a C char* context
1045 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
1046 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE or Py_UCS4.")
1047 elif dst_type is not py_object_type:
1048 if not self.check_for_coercion_error(dst_type):
1049 self.fail_assignment(dst_type)
1052 def can_coerce_to_char_literal(self):
1053 return len(self.value) == 1
1054 ## or (len(self.value) == 2
1055 ## and (0xD800 <= self.value[0] <= 0xDBFF)
1056 ## and (0xDC00 <= self.value[1] <= 0xDFFF))
1058 def contains_surrogates(self):
1059 # Check if the unicode string contains surrogate code points
1060 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1061 # Unicode, i.e. characters that would be spelled as two
1062 # separate code units on a narrow platform.
1063 for c in map(ord, self.value):
1064 if c > 65535: # can only happen on wide platforms
1066 # We only look for the first code unit (D800-DBFF) of a
1067 # surrogate pair - if we find one, the other one
1068 # (DC00-DFFF) is likely there, too. If we don't find it,
1069 # any second code unit cannot make for a surrogate pair by
1071 if c >= 0xD800 and c <= 0xDBFF:
1075 def generate_evaluation_code(self, code):
1076 self.result_code = code.get_py_string_const(self.value)
1078 def calculate_result_code(self):
1079 return self.result_code
1081 def compile_time_value(self, env):
1085 class StringNode(PyConstNode):
1086 # A Python str object, i.e. a byte string in Python 2.x and a
1087 # unicode string in Python 3.x
1089 # value BytesLiteral (or EncodedString with ASCII content)
1090 # unicode_value EncodedString or None
1091 # is_identifier boolean
1094 is_identifier = None
1095 unicode_value = None
1097 def coerce_to(self, dst_type, env):
1098 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1099 # if dst_type is Builtin.bytes_type:
1100 # # special case: bytes = 'str literal'
1101 # return BytesNode(self.pos, value=self.value)
1102 if not dst_type.is_pyobject:
1103 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1104 self.check_for_coercion_error(dst_type, fail=True)
1106 # this will be a unicode string in Py3, so make sure we can decode it
1107 if self.value.encoding and isinstance(self.value, StringEncoding.BytesLiteral):
1109 self.value.decode(self.value.encoding)
1110 except UnicodeDecodeError:
1111 error(self.pos, ("Decoding unprefixed string literal from '%s' failed. Consider using"
1112 "a byte string or unicode string explicitly, "
1113 "or adjust the source code encoding.") % self.value.encoding)
1117 def can_coerce_to_char_literal(self):
1118 return not self.is_identifier and len(self.value) == 1
1120 def generate_evaluation_code(self, code):
1121 self.result_code = code.get_py_string_const(
1122 self.value, identifier=self.is_identifier, is_str=True)
1124 def get_constant_c_result_code(self):
1127 def calculate_result_code(self):
1128 return self.result_code
1130 def compile_time_value(self, env):
1134 class IdentifierStringNode(StringNode):
1135 # A special str value that represents an identifier (bytes in Py2,
1137 is_identifier = True
1140 class LongNode(AtomicExprNode):
1141 # Python long integer literal
1145 type = py_object_type
1147 def calculate_constant_result(self):
1148 self.constant_result = Utils.str_to_number(self.value)
1150 def compile_time_value(self, denv):
1151 return Utils.str_to_number(self.value)
1153 def analyse_types(self, env):
1156 def may_be_none(self):
1159 gil_message = "Constructing Python long int"
1161 def generate_result_code(self, code):
1163 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1166 code.error_goto_if_null(self.result(), self.pos)))
1167 code.put_gotref(self.py_result())
1170 class ImagNode(AtomicExprNode):
1171 # Imaginary number literal
1173 # value float imaginary part
1175 type = PyrexTypes.c_double_complex_type
1177 def calculate_constant_result(self):
1178 self.constant_result = complex(0.0, self.value)
1180 def compile_time_value(self, denv):
1181 return complex(0.0, self.value)
1183 def analyse_types(self, env):
1184 self.type.create_declaration_utility_code(env)
1186 def may_be_none(self):
1189 def coerce_to(self, dst_type, env):
1190 if self.type is dst_type:
1192 node = ImagNode(self.pos, value=self.value)
1193 if dst_type.is_pyobject:
1195 node.type = PyrexTypes.py_object_type
1196 # We still need to perform normal coerce_to processing on the
1197 # result, because we might be coercing to an extension type,
1198 # in which case a type test node will be needed.
1199 return AtomicExprNode.coerce_to(node, dst_type, env)
1201 gil_message = "Constructing complex number"
1203 def calculate_result_code(self):
1204 if self.type.is_pyobject:
1205 return self.result()
1207 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1209 def generate_result_code(self, code):
1210 if self.type.is_pyobject:
1212 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1215 code.error_goto_if_null(self.result(), self.pos)))
1216 code.put_gotref(self.py_result())
1219 class NewExprNode(AtomicExprNode):
1223 # cppclass node c++ class to create
1227 def infer_type(self, env):
1228 type = self.cppclass.analyse_as_type(env)
1229 if type is None or not type.is_cpp_class:
1230 error(self.pos, "new operator can only be applied to a C++ class")
1231 self.type = error_type
1234 constructor = type.scope.lookup(u'<init>')
1235 if constructor is None:
1236 return_type = PyrexTypes.CFuncType(type, [])
1237 return_type = PyrexTypes.CPtrType(return_type)
1238 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1239 constructor = type.scope.lookup(u'<init>')
1240 self.class_type = type
1241 self.entry = constructor
1242 self.type = constructor.type
1245 def analyse_types(self, env):
1246 if self.type is None:
1247 self.infer_type(env)
1249 def may_be_none(self):
1252 def generate_result_code(self, code):
1255 def calculate_result_code(self):
1256 return "new " + self.class_type.declaration_code("")
1259 class NameNode(AtomicExprNode):
1260 # Reference to a local or global variable name.
1262 # name string Python name of the variable
1263 # entry Entry Symbol table entry
1264 # type_entry Entry For extension type names, the original type entry
1267 is_cython_module = False
1268 cython_attribute = None
1269 lhs_of_first_assignment = False
1270 is_used_as_rvalue = 0
1274 def create_analysed_rvalue(pos, env, entry):
1275 node = NameNode(pos)
1276 node.analyse_types(env, entry=entry)
1279 def as_cython_attribute(self):
1280 return self.cython_attribute
1282 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1284 def type_dependencies(self, env):
1285 if self.entry is None:
1286 self.entry = env.lookup(self.name)
1287 if self.entry is not None and self.entry.type.is_unspecified:
1288 return (self.entry,)
1292 def infer_type(self, env):
1293 if self.entry is None:
1294 self.entry = env.lookup(self.name)
1295 if self.entry is None:
1296 return py_object_type
1297 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1298 self.name == self.entry.type.name:
1299 # Unfortunately the type attribute of type objects
1300 # is used for the pointer to the type they represent.
1302 elif self.entry.type.is_cfunction:
1303 # special case: referring to a C function must return its pointer
1304 return PyrexTypes.CPtrType(self.entry.type)
1306 return self.entry.type
1308 def compile_time_value(self, denv):
1310 return denv.lookup(self.name)
1312 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1314 def get_constant_c_result_code(self):
1315 if not self.entry or self.entry.type.is_pyobject:
1317 return self.entry.cname
1319 def coerce_to(self, dst_type, env):
1320 # If coercing to a generic pyobject and this is a builtin
1321 # C function with a Python equivalent, manufacture a NameNode
1322 # referring to the Python builtin.
1323 #print "NameNode.coerce_to:", self.name, dst_type ###
1324 if dst_type is py_object_type:
1326 if entry and entry.is_cfunction:
1327 var_entry = entry.as_variable
1329 if var_entry.is_builtin and Options.cache_builtins:
1330 var_entry = env.declare_builtin(var_entry.name, self.pos)
1331 node = NameNode(self.pos, name = self.name)
1332 node.entry = var_entry
1333 node.analyse_rvalue_entry(env)
1335 return super(NameNode, self).coerce_to(dst_type, env)
1337 def analyse_as_module(self, env):
1338 # Try to interpret this as a reference to a cimported module.
1339 # Returns the module scope, or None.
1342 entry = env.lookup(self.name)
1343 if entry and entry.as_module:
1344 return entry.as_module
1347 def analyse_as_type(self, env):
1348 if self.cython_attribute:
1349 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1351 type = PyrexTypes.parse_basic_type(self.name)
1356 entry = env.lookup(self.name)
1357 if entry and entry.is_type:
1362 def analyse_as_extension_type(self, env):
1363 # Try to interpret this as a reference to an extension type.
1364 # Returns the extension type, or None.
1367 entry = env.lookup(self.name)
1368 if entry and entry.is_type and entry.type.is_extension_type:
1373 def analyse_target_declaration(self, env):
1375 self.entry = env.lookup_here(self.name)
1377 if env.directives['warn.undeclared']:
1378 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1379 if env.directives['infer_types'] != False:
1380 type = unspecified_type
1382 type = py_object_type
1383 self.entry = env.declare_var(self.name, type, self.pos)
1384 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1385 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1386 if self.entry.is_declared_generic:
1387 self.result_ctype = py_object_type
1389 def analyse_types(self, env):
1390 if self.entry is None:
1391 self.entry = env.lookup(self.name)
1393 self.entry = env.declare_builtin(self.name, self.pos)
1395 self.type = PyrexTypes.error_type
1400 if entry.type.is_buffer:
1402 Buffer.used_buffer_aux_vars(entry)
1403 if entry.utility_code:
1404 env.use_utility_code(entry.utility_code)
1405 self.analyse_rvalue_entry(env)
1407 def analyse_target_types(self, env):
1408 self.analyse_entry(env)
1409 if not self.is_lvalue():
1410 error(self.pos, "Assignment to non-lvalue '%s'"
1412 self.type = PyrexTypes.error_type
1414 if self.entry.type.is_buffer:
1416 Buffer.used_buffer_aux_vars(self.entry)
1418 def analyse_rvalue_entry(self, env):
1419 #print "NameNode.analyse_rvalue_entry:", self.name ###
1420 #print "Entry:", self.entry.__dict__ ###
1421 self.analyse_entry(env)
1423 if entry.is_declared_generic:
1424 self.result_ctype = py_object_type
1425 if entry.is_pyglobal or entry.is_builtin:
1426 if Options.cache_builtins and entry.is_builtin:
1430 env.use_utility_code(get_name_interned_utility_code)
1431 self.is_used_as_rvalue = 1
1433 def nogil_check(self, env):
1434 if self.is_used_as_rvalue:
1436 if entry.is_builtin:
1437 if not Options.cache_builtins: # cached builtins are ok
1439 elif entry.is_pyglobal:
1442 gil_message = "Accessing Python global or builtin"
1444 def analyse_entry(self, env):
1445 #print "NameNode.analyse_entry:", self.name ###
1446 self.check_identifier_kind()
1451 def check_identifier_kind(self):
1452 # Check that this is an appropriate kind of name for use in an
1453 # expression. Also finds the variable entry associated with
1454 # an extension type.
1456 if entry.is_type and entry.type.is_extension_type:
1457 self.type_entry = entry
1458 if not (entry.is_const or entry.is_variable
1459 or entry.is_builtin or entry.is_cfunction
1460 or entry.is_cpp_class):
1461 if self.entry.as_variable:
1462 self.entry = self.entry.as_variable
1465 "'%s' is not a constant, variable or function identifier" % self.name)
1467 def is_simple(self):
1468 # If it's not a C variable, it'll be in a temp.
1471 def calculate_target_results(self, env):
1474 def check_const(self):
1476 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1481 def check_const_addr(self):
1483 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1484 self.addr_not_const()
1488 def is_lvalue(self):
1489 return self.entry.is_variable and \
1490 not self.entry.type.is_array and \
1491 not self.entry.is_readonly
1493 def is_ephemeral(self):
1494 # Name nodes are never ephemeral, even if the
1495 # result is in a temporary.
1498 def calculate_result_code(self):
1501 return "<error>" # There was an error earlier
1504 def generate_result_code(self, code):
1505 assert hasattr(self, 'entry')
1508 return # There was an error earlier
1509 if entry.is_builtin and Options.cache_builtins:
1510 return # Lookup already cached
1511 elif entry.is_pyclass_attr:
1512 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1513 interned_cname = code.intern_identifier(self.entry.name)
1514 if entry.is_builtin:
1515 namespace = Naming.builtins_cname
1516 else: # entry.is_pyglobal
1517 namespace = entry.scope.namespace_cname
1519 '%s = PyObject_GetItem(%s, %s); %s' % (
1523 code.error_goto_if_null(self.result(), self.pos)))
1524 code.put_gotref(self.py_result())
1526 elif entry.is_pyglobal or entry.is_builtin:
1527 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1528 interned_cname = code.intern_identifier(self.entry.name)
1529 if entry.is_builtin:
1530 namespace = Naming.builtins_cname
1531 else: # entry.is_pyglobal
1532 namespace = entry.scope.namespace_cname
1533 code.globalstate.use_utility_code(get_name_interned_utility_code)
1535 '%s = __Pyx_GetName(%s, %s); %s' % (
1539 code.error_goto_if_null(self.result(), self.pos)))
1540 code.put_gotref(self.py_result())
1542 elif entry.is_local and False:
1543 # control flow not good enough yet
1544 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1545 if assigned is False:
1546 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1547 elif not Options.init_local_none and assigned is None:
1548 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1549 (entry.cname, entry.name, code.error_goto(self.pos)))
1550 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1552 def generate_assignment_code(self, rhs, code):
1553 #print "NameNode.generate_assignment_code:", self.name ###
1556 return # There was an error earlier
1558 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1559 and not self.lhs_of_first_assignment):
1560 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1562 # is_pyglobal seems to be True for module level-globals only.
1563 # We use this to access class->tp_dict if necessary.
1564 if entry.is_pyglobal:
1565 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1566 interned_cname = code.intern_identifier(self.entry.name)
1567 namespace = self.entry.scope.namespace_cname
1569 # if the entry is a member we have to cheat: SetAttr does not work
1570 # on types, so we create a descriptor which is then added to tp_dict
1571 code.put_error_if_neg(self.pos,
1572 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1576 rhs.generate_disposal_code(code)
1577 rhs.free_temps(code)
1578 # in Py2.6+, we need to invalidate the method cache
1579 code.putln("PyType_Modified(%s);" %
1580 entry.scope.parent_type.typeptr_cname)
1581 elif entry.is_pyclass_attr:
1582 code.put_error_if_neg(self.pos,
1583 'PyObject_SetItem(%s, %s, %s)' % (
1587 rhs.generate_disposal_code(code)
1588 rhs.free_temps(code)
1590 code.put_error_if_neg(self.pos,
1591 'PyObject_SetAttr(%s, %s, %s)' % (
1595 if debug_disposal_code:
1596 print("NameNode.generate_assignment_code:")
1597 print("...generating disposal code for %s" % rhs)
1598 rhs.generate_disposal_code(code)
1599 rhs.free_temps(code)
1601 if self.type.is_buffer:
1602 # Generate code for doing the buffer release/acquisition.
1603 # This might raise an exception in which case the assignment (done
1604 # below) will not happen.
1606 # The reason this is not in a typetest-like node is because the
1607 # variables that the acquired buffer info is stored to is allocated
1608 # per entry and coupled with it.
1609 self.generate_acquire_buffer(rhs, code)
1611 if self.type.is_pyobject:
1612 #print "NameNode.generate_assignment_code: to", self.name ###
1613 #print "...from", rhs ###
1614 #print "...LHS type", self.type, "ctype", self.ctype() ###
1615 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1616 if self.use_managed_ref:
1617 rhs.make_owned_reference(code)
1618 if entry.is_cglobal:
1619 code.put_gotref(self.py_result())
1620 if not self.lhs_of_first_assignment:
1621 if entry.is_local and not Options.init_local_none:
1622 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1623 if initialized is True:
1624 code.put_decref(self.result(), self.ctype())
1625 elif initialized is None:
1626 code.put_xdecref(self.result(), self.ctype())
1628 code.put_decref(self.result(), self.ctype())
1629 if entry.is_cglobal:
1630 code.put_giveref(rhs.py_result())
1632 code.putln('%s = %s;' % (self.result(),
1633 rhs.result_as(self.ctype())))
1634 if debug_disposal_code:
1635 print("NameNode.generate_assignment_code:")
1636 print("...generating post-assignment code for %s" % rhs)
1637 rhs.generate_post_assignment_code(code)
1638 rhs.free_temps(code)
1640 def generate_acquire_buffer(self, rhs, code):
1641 # rhstmp is only used in case the rhs is a complicated expression leading to
1642 # the object, to avoid repeating the same C expression for every reference
1643 # to the rhs. It does NOT hold a reference.
1644 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1646 rhstmp = rhs.result_as(self.ctype())
1648 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1649 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1651 buffer_aux = self.entry.buffer_aux
1652 bufstruct = buffer_aux.buffer_info_var.cname
1654 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1655 is_initialized=not self.lhs_of_first_assignment,
1656 pos=self.pos, code=code)
1659 code.putln("%s = 0;" % rhstmp)
1660 code.funcstate.release_temp(rhstmp)
1662 def generate_deletion_code(self, code):
1663 if self.entry is None:
1664 return # There was an error earlier
1665 if not self.entry.is_pyglobal:
1666 error(self.pos, "Deletion of local or C global name not supported")
1668 if self.entry.is_pyclass_attr:
1669 namespace = self.entry.scope.namespace_cname
1670 code.put_error_if_neg(self.pos,
1671 'PyMapping_DelItemString(%s, "%s")' % (
1675 code.put_error_if_neg(self.pos,
1676 '__Pyx_DelAttrString(%s, "%s")' % (
1677 Naming.module_cname,
1680 def annotate(self, code):
1681 if hasattr(self, 'is_called') and self.is_called:
1682 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1683 if self.type.is_pyobject:
1684 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1686 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1688 class BackquoteNode(ExprNode):
1693 type = py_object_type
1697 def analyse_types(self, env):
1698 self.arg.analyse_types(env)
1699 self.arg = self.arg.coerce_to_pyobject(env)
1702 gil_message = "Backquote expression"
1704 def calculate_constant_result(self):
1705 self.constant_result = repr(self.arg.constant_result)
1707 def generate_result_code(self, code):
1709 "%s = PyObject_Repr(%s); %s" % (
1711 self.arg.py_result(),
1712 code.error_goto_if_null(self.result(), self.pos)))
1713 code.put_gotref(self.py_result())
1717 class ImportNode(ExprNode):
1718 # Used as part of import statement implementation.
1719 # Implements result =
1720 # __import__(module_name, globals(), None, name_list)
1722 # module_name StringNode dotted name of module
1723 # name_list ListNode or None list of names to be imported
1725 type = py_object_type
1727 subexprs = ['module_name', 'name_list']
1729 def analyse_types(self, env):
1730 self.module_name.analyse_types(env)
1731 self.module_name = self.module_name.coerce_to_pyobject(env)
1733 self.name_list.analyse_types(env)
1734 self.name_list.coerce_to_pyobject(env)
1736 env.use_utility_code(import_utility_code)
1738 gil_message = "Python import"
1740 def generate_result_code(self, code):
1742 name_list_code = self.name_list.py_result()
1744 name_list_code = "0"
1746 "%s = __Pyx_Import(%s, %s); %s" % (
1748 self.module_name.py_result(),
1750 code.error_goto_if_null(self.result(), self.pos)))
1751 code.put_gotref(self.py_result())
1754 class IteratorNode(ExprNode):
1755 # Used as part of for statement implementation.
1757 # allocate_counter_temp/release_counter_temp needs to be called
1758 # by parent (ForInStatNode)
1760 # Implements result = iter(sequence)
1764 type = py_object_type
1766 subexprs = ['sequence']
1768 def analyse_types(self, env):
1769 self.sequence.analyse_types(env)
1770 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1771 not self.sequence.type.is_string:
1772 # C array iteration will be transformed later on
1773 self.type = self.sequence.type
1775 self.sequence = self.sequence.coerce_to_pyobject(env)
1776 if self.sequence.type is list_type or \
1777 self.sequence.type is tuple_type:
1778 self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
1781 gil_message = "Iterating over Python object"
1783 def allocate_counter_temp(self, code):
1784 self.counter_cname = code.funcstate.allocate_temp(
1785 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1787 def release_counter_temp(self, code):
1788 code.funcstate.release_temp(self.counter_cname)
1790 def generate_result_code(self, code):
1791 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1792 raise InternalError("for in carray slice not transformed")
1793 is_builtin_sequence = self.sequence.type is list_type or \
1794 self.sequence.type is tuple_type
1795 may_be_a_sequence = not self.sequence.type.is_builtin_type
1796 if may_be_a_sequence:
1798 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1799 self.sequence.py_result(),
1800 self.sequence.py_result()))
1801 if is_builtin_sequence or may_be_a_sequence:
1803 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1806 self.sequence.py_result(),
1808 if not is_builtin_sequence:
1809 if may_be_a_sequence:
1810 code.putln("} else {")
1811 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1814 self.sequence.py_result(),
1815 code.error_goto_if_null(self.result(), self.pos)))
1816 code.put_gotref(self.py_result())
1817 if may_be_a_sequence:
1821 class NextNode(AtomicExprNode):
1822 # Used as part of for statement implementation.
1823 # Implements result = iterator.next()
1824 # Created during analyse_types phase.
1825 # The iterator is not owned by this node.
1829 type = py_object_type
1831 def __init__(self, iterator, env):
1832 self.pos = iterator.pos
1833 self.iterator = iterator
1834 if iterator.type.is_ptr or iterator.type.is_array:
1835 self.type = iterator.type.base_type
1838 def generate_result_code(self, code):
1839 sequence_type = self.iterator.sequence.type
1840 if sequence_type is list_type:
1841 type_checks = [(list_type, "List")]
1842 elif sequence_type is tuple_type:
1843 type_checks = [(tuple_type, "Tuple")]
1844 elif not sequence_type.is_builtin_type:
1845 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1849 for py_type, prefix in type_checks:
1850 if len(type_checks) > 1:
1852 "if (likely(Py%s_CheckExact(%s))) {" % (
1853 prefix, self.iterator.py_result()))
1855 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1856 self.iterator.counter_cname,
1858 self.iterator.py_result()))
1860 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1863 self.iterator.py_result(),
1864 self.iterator.counter_cname,
1866 self.iterator.counter_cname))
1867 if len(type_checks) > 1:
1869 if len(type_checks) == 1:
1873 "%s = PyIter_Next(%s);" % (
1875 self.iterator.py_result()))
1879 code.putln(code.error_goto_if_PyErr(self.pos))
1880 code.putln("break;")
1882 code.put_gotref(self.py_result())
1886 class ExcValueNode(AtomicExprNode):
1887 # Node created during analyse_types phase
1888 # of an ExceptClauseNode to fetch the current
1891 type = py_object_type
1893 def __init__(self, pos, env):
1894 ExprNode.__init__(self, pos)
1896 def set_var(self, var):
1899 def calculate_result_code(self):
1902 def generate_result_code(self, code):
1905 def analyse_types(self, env):
1909 class TempNode(ExprNode):
1910 # Node created during analyse_types phase
1911 # of some nodes to hold a temporary value.
1913 # Note: One must call "allocate" and "release" on
1914 # the node during code generation to get/release the temp.
1915 # This is because the temp result is often used outside of
1916 # the regular cycle.
1920 def __init__(self, pos, type, env):
1921 ExprNode.__init__(self, pos)
1923 if type.is_pyobject:
1924 self.result_ctype = py_object_type
1927 def analyse_types(self, env):
1930 def generate_result_code(self, code):
1933 def allocate(self, code):
1934 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1936 def release(self, code):
1937 code.funcstate.release_temp(self.temp_cname)
1938 self.temp_cname = None
1942 return self.temp_cname
1944 assert False, "Remember to call allocate/release on TempNode"
1947 # Do not participate in normal temp alloc/dealloc:
1948 def allocate_temp_result(self, code):
1951 def release_temp_result(self, code):
1954 class PyTempNode(TempNode):
1955 # TempNode holding a Python value.
1957 def __init__(self, pos, env):
1958 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1960 class RawCNameExprNode(ExprNode):
1963 def __init__(self, pos, type=None):
1967 def analyse_types(self, env):
1970 def set_cname(self, cname):
1976 def generate_result_code(self, code):
1980 #-------------------------------------------------------------------
1984 #-------------------------------------------------------------------
1986 class IndexNode(ExprNode):
1987 # Sequence indexing.
1991 # indices [ExprNode]
1992 # is_buffer_access boolean Whether this is a buffer access.
1994 # indices is used on buffer access, index on non-buffer access.
1995 # The former contains a clean list of index parameters, the
1996 # latter whatever Python object is needed for index access.
1998 subexprs = ['base', 'index', 'indices']
2001 def __init__(self, pos, index, *args, **kw):
2002 ExprNode.__init__(self, pos, index=index, *args, **kw)
2005 def calculate_constant_result(self):
2006 self.constant_result = \
2007 self.base.constant_result[self.index.constant_result]
2009 def compile_time_value(self, denv):
2010 base = self.base.compile_time_value(denv)
2011 index = self.index.compile_time_value(denv)
2014 except Exception, e:
2015 self.compile_time_value_error(e)
2017 def is_ephemeral(self):
2018 return self.base.is_ephemeral()
2020 def is_simple(self):
2021 if self.is_buffer_access:
2024 return (base.is_simple() and self.index.is_simple()
2025 and base.type and (base.type.is_ptr or base.type.is_array))
2027 def analyse_target_declaration(self, env):
2030 def analyse_as_type(self, env):
2031 base_type = self.base.analyse_as_type(env)
2032 if base_type and not base_type.is_pyobject:
2033 if base_type.is_cpp_class:
2034 if isinstance(self.index, TupleNode):
2035 template_values = self.index.args
2037 template_values = [self.index]
2039 type_node = Nodes.TemplatedTypeNode(
2041 positional_args = template_values,
2042 keyword_args = None)
2043 return type_node.analyse(env, base_type = base_type)
2045 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2048 def type_dependencies(self, env):
2049 return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2051 def infer_type(self, env):
2052 base_type = self.base.infer_type(env)
2053 if isinstance(self.index, SliceNode):
2055 if base_type.is_string:
2056 # sliced C strings must coerce to Python
2058 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2059 # slicing these returns the same type
2062 # TODO: Handle buffers (hopefully without too much redundancy).
2063 return py_object_type
2065 index_type = self.index.infer_type(env)
2066 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2068 if base_type is unicode_type:
2069 # Py_UCS4 will automatically coerce to a unicode string
2070 # if required, so this is safe. We only infer Py_UCS4
2071 # when the index is a C integer type. Otherwise, we may
2072 # need to use normal Python item access, in which case
2073 # it's faster to return the one-char unicode string than
2074 # to receive it, throw it away, and potentially rebuild it
2075 # on a subsequent PyObject coercion.
2076 return PyrexTypes.c_py_ucs4_type
2077 elif base_type is str_type:
2078 # always returns str - Py2: bytes, Py3: unicode
2080 elif isinstance(self.base, BytesNode):
2081 #if env.global_scope().context.language_level >= 3:
2082 # # infering 'char' can be made to work in Python 3 mode
2083 # return PyrexTypes.c_char_type
2084 # Py2/3 return different types on indexing bytes objects
2085 return py_object_type
2086 elif base_type.is_ptr or base_type.is_array:
2087 return base_type.base_type
2089 # may be slicing or indexing, we don't know
2090 if base_type is unicode_type:
2091 # this type always returns its own type on Python indexing/slicing
2094 # TODO: Handle buffers (hopefully without too much redundancy).
2095 return py_object_type
2097 def analyse_types(self, env):
2098 self.analyse_base_and_index_types(env, getting = 1)
2100 def analyse_target_types(self, env):
2101 self.analyse_base_and_index_types(env, setting = 1)
2103 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2104 # Note: This might be cleaned up by having IndexNode
2105 # parsed in a saner way and only construct the tuple if
2108 # Note that this function must leave IndexNode in a cloneable state.
2109 # For buffers, self.index is packed out on the initial analysis, and
2110 # when cloning self.indices is copied.
2111 self.is_buffer_access = False
2113 self.base.analyse_types(env)
2114 if self.base.type.is_error:
2115 # Do not visit child tree if base is undeclared to avoid confusing
2117 self.type = PyrexTypes.error_type
2120 is_slice = isinstance(self.index, SliceNode)
2121 # Potentially overflowing index value.
2122 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2123 self.index = self.index.coerce_to_pyobject(env)
2125 # Handle the case where base is a literal char* (and we expect a string, not an int)
2126 if isinstance(self.base, BytesNode) or is_slice:
2127 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2128 self.base = self.base.coerce_to_pyobject(env)
2130 skip_child_analysis = False
2131 buffer_access = False
2132 if self.base.type.is_buffer:
2134 indices = self.indices
2136 if isinstance(self.index, TupleNode):
2137 indices = self.index.args
2139 indices = [self.index]
2140 if len(indices) == self.base.type.ndim:
2141 buffer_access = True
2142 skip_child_analysis = True
2144 x.analyse_types(env)
2145 if not x.type.is_int:
2146 buffer_access = False
2148 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2150 # On cloning, indices is cloned. Otherwise, unpack index into indices
2151 assert not (buffer_access and isinstance(self.index, CloneNode))
2154 self.indices = indices
2156 self.type = self.base.type.dtype
2157 self.is_buffer_access = True
2158 self.buffer_type = self.base.entry.type
2160 if getting and self.type.is_pyobject:
2163 if not self.base.entry.type.writable:
2164 error(self.pos, "Writing to readonly buffer")
2166 self.base.entry.buffer_aux.writable_needed = True
2168 base_type = self.base.type
2169 if isinstance(self.index, TupleNode):
2170 self.index.analyse_types(env, skip_children=skip_child_analysis)
2171 elif not skip_child_analysis:
2172 self.index.analyse_types(env)
2173 self.original_index_type = self.index.type
2174 if base_type.is_unicode_char:
2175 # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
2176 # cases, but indexing must still work for them
2177 if self.index.constant_result in (0, -1):
2178 # FIXME: we know that this node is redundant -
2179 # currently, this needs to get handled in Optimize.py
2181 self.base = self.base.coerce_to_pyobject(env)
2182 base_type = self.base.type
2183 if base_type.is_pyobject:
2184 if self.index.type.is_int:
2186 and (base_type in (list_type, tuple_type, unicode_type))
2187 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2188 and not env.directives['boundscheck']):
2192 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2194 self.index = self.index.coerce_to_pyobject(env)
2196 if self.index.type.is_int and base_type is unicode_type:
2197 # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
2198 # if required, so this is fast and safe
2199 self.type = PyrexTypes.c_py_ucs4_type
2200 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2201 self.type = base_type
2203 self.type = py_object_type
2205 if base_type.is_ptr or base_type.is_array:
2206 self.type = base_type.base_type
2208 self.type = base_type
2209 elif self.index.type.is_pyobject:
2210 self.index = self.index.coerce_to(
2211 PyrexTypes.c_py_ssize_t_type, env)
2212 elif not self.index.type.is_int:
2214 "Invalid index type '%s'" %
2216 elif base_type.is_cpp_class:
2217 function = env.lookup_operator("[]", [self.base, self.index])
2218 if function is None:
2219 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2220 self.type = PyrexTypes.error_type
2221 self.result_code = "<error>"
2223 func_type = function.type
2224 if func_type.is_ptr:
2225 func_type = func_type.base_type
2226 self.index = self.index.coerce_to(func_type.args[0].type, env)
2227 self.type = func_type.return_type
2228 if setting and not func_type.return_type.is_reference:
2229 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2232 "Attempting to index non-array type '%s'" %
2234 self.type = PyrexTypes.error_type
2236 gil_message = "Indexing Python object"
2238 def nogil_check(self, env):
2239 if self.is_buffer_access:
2240 if env.directives['boundscheck']:
2241 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2243 elif self.type.is_pyobject:
2244 error(self.pos, "Cannot access buffer with object dtype without gil")
2246 super(IndexNode, self).nogil_check(env)
2249 def check_const_addr(self):
2250 return self.base.check_const_addr() and self.index.check_const()
2252 def is_lvalue(self):
2255 def calculate_result_code(self):
2256 if self.is_buffer_access:
2257 return "(*%s)" % self.buffer_ptr_code
2258 elif self.base.type is list_type:
2259 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2260 elif self.base.type is tuple_type:
2261 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2262 elif self.base.type is unicode_type and self.type.is_unicode_char:
2263 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2264 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2265 error(self.pos, "Invalid use of pointer slice")
2267 return "(%s[%s])" % (
2268 self.base.result(), self.index.result())
2270 def extra_index_params(self):
2271 if self.index.type.is_int:
2272 if self.original_index_type.signed:
2273 size_adjustment = ""
2275 size_adjustment = "+1"
2276 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2280 def generate_subexpr_evaluation_code(self, code):
2281 self.base.generate_evaluation_code(code)
2282 if not self.indices:
2283 self.index.generate_evaluation_code(code)
2285 for i in self.indices:
2286 i.generate_evaluation_code(code)
2288 def generate_subexpr_disposal_code(self, code):
2289 self.base.generate_disposal_code(code)
2290 if not self.indices:
2291 self.index.generate_disposal_code(code)
2293 for i in self.indices:
2294 i.generate_disposal_code(code)
2296 def free_subexpr_temps(self, code):
2297 self.base.free_temps(code)
2298 if not self.indices:
2299 self.index.free_temps(code)
2301 for i in self.indices:
2304 def generate_result_code(self, code):
2305 if self.is_buffer_access:
2306 if code.globalstate.directives['nonecheck']:
2307 self.put_nonecheck(code)
2308 self.buffer_ptr_code = self.buffer_lookup_code(code)
2309 if self.type.is_pyobject:
2310 # is_temp is True, so must pull out value and incref it.
2311 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2312 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2314 if self.type.is_pyobject:
2315 if self.index.type.is_int:
2316 index_code = self.index.result()
2317 if self.base.type is list_type:
2318 function = "__Pyx_GetItemInt_List"
2319 elif self.base.type is tuple_type:
2320 function = "__Pyx_GetItemInt_Tuple"
2322 function = "__Pyx_GetItemInt"
2323 code.globalstate.use_utility_code(getitem_int_utility_code)
2325 index_code = self.index.py_result()
2326 if self.base.type is dict_type:
2327 function = "__Pyx_PyDict_GetItem"
2328 code.globalstate.use_utility_code(getitem_dict_utility_code)
2330 function = "PyObject_GetItem"
2332 "%s = %s(%s, %s%s); if (!%s) %s" % (
2335 self.base.py_result(),
2337 self.extra_index_params(),
2339 code.error_goto(self.pos)))
2340 code.put_gotref(self.py_result())
2341 elif self.type.is_unicode_char and self.base.type is unicode_type:
2342 assert self.index.type.is_int
2343 index_code = self.index.result()
2344 function = "__Pyx_GetItemInt_Unicode"
2345 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2347 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2350 self.base.py_result(),
2352 self.extra_index_params(),
2354 code.error_goto(self.pos)))
2356 def generate_setitem_code(self, value_code, code):
2357 if self.index.type.is_int:
2358 function = "__Pyx_SetItemInt"
2359 index_code = self.index.result()
2360 code.globalstate.use_utility_code(setitem_int_utility_code)
2362 index_code = self.index.py_result()
2363 if self.base.type is dict_type:
2364 function = "PyDict_SetItem"
2365 # It would seem that we could specialized lists/tuples, but that
2366 # shouldn't happen here.
2367 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2368 # not a PyObject*, and bad conversion here would give the wrong
2369 # exception. Also, tuples are supposed to be immutable, and raise
2370 # TypeErrors when trying to set their entries (PyTuple_SetItem
2371 # is for creating new tuples from).
2373 function = "PyObject_SetItem"
2375 "if (%s(%s, %s, %s%s) < 0) %s" % (
2377 self.base.py_result(),
2380 self.extra_index_params(),
2381 code.error_goto(self.pos)))
2383 def generate_buffer_setitem_code(self, rhs, code, op=""):
2384 # Used from generate_assignment_code and InPlaceAssignmentNode
2385 if code.globalstate.directives['nonecheck']:
2386 self.put_nonecheck(code)
2387 ptrexpr = self.buffer_lookup_code(code)
2388 if self.buffer_type.dtype.is_pyobject:
2389 # Must manage refcounts. Decref what is already there
2390 # and incref what we put in.
2391 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2392 rhs_code = rhs.result()
2393 code.putln("%s = %s;" % (ptr, ptrexpr))
2394 code.put_gotref("*%s" % ptr)
2395 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2398 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2399 code.put_giveref("*%s" % ptr)
2400 code.funcstate.release_temp(ptr)
2403 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2405 def generate_assignment_code(self, rhs, code):
2406 self.generate_subexpr_evaluation_code(code)
2407 if self.is_buffer_access:
2408 self.generate_buffer_setitem_code(rhs, code)
2409 elif self.type.is_pyobject:
2410 self.generate_setitem_code(rhs.py_result(), code)
2414 self.result(), rhs.result()))
2415 self.generate_subexpr_disposal_code(code)
2416 self.free_subexpr_temps(code)
2417 rhs.generate_disposal_code(code)
2418 rhs.free_temps(code)
2420 def generate_deletion_code(self, code):
2421 self.generate_subexpr_evaluation_code(code)
2422 #if self.type.is_pyobject:
2423 if self.index.type.is_int:
2424 function = "__Pyx_DelItemInt"
2425 index_code = self.index.result()
2426 code.globalstate.use_utility_code(delitem_int_utility_code)
2428 index_code = self.index.py_result()
2429 if self.base.type is dict_type:
2430 function = "PyDict_DelItem"
2432 function = "PyObject_DelItem"
2434 "if (%s(%s, %s%s) < 0) %s" % (
2436 self.base.py_result(),
2438 self.extra_index_params(),
2439 code.error_goto(self.pos)))
2440 self.generate_subexpr_disposal_code(code)
2441 self.free_subexpr_temps(code)
2443 def buffer_lookup_code(self, code):
2444 # Assign indices to temps
2445 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2446 for temp, index in zip(index_temps, self.indices):
2447 code.putln("%s = %s;" % (temp, index.result()))
2448 # Generate buffer access code using these temps
2450 # The above could happen because child_attrs is wrong somewhere so that
2451 # options are not propagated.
2452 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2453 index_signeds=[i.type.signed for i in self.indices],
2454 index_cnames=index_temps,
2455 directives=code.globalstate.directives,
2456 pos=self.pos, code=code)
2458 def put_nonecheck(self, code):
2459 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2460 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2461 code.putln("__Pyx_RaiseNoneIndexingError();")
2462 code.putln(code.error_goto(self.pos))
2465 class SliceIndexNode(ExprNode):
2466 # 2-element slice indexing
2469 # start ExprNode or None
2470 # stop ExprNode or None
2472 subexprs = ['base', 'start', 'stop']
2474 def infer_type(self, env):
2475 base_type = self.base.infer_type(env)
2476 if base_type.is_string:
2478 elif base_type in (bytes_type, str_type, unicode_type,
2479 list_type, tuple_type):
2481 return py_object_type
2483 def calculate_constant_result(self):
2484 self.constant_result = self.base.constant_result[
2485 self.start.constant_result : self.stop.constant_result]
2487 def compile_time_value(self, denv):
2488 base = self.base.compile_time_value(denv)
2489 if self.start is None:
2492 start = self.start.compile_time_value(denv)
2493 if self.stop is None:
2496 stop = self.stop.compile_time_value(denv)
2498 return base[start:stop]
2499 except Exception, e:
2500 self.compile_time_value_error(e)
2502 def analyse_target_declaration(self, env):
2505 def analyse_target_types(self, env):
2506 self.analyse_types(env)
2507 # when assigning, we must accept any Python type
2508 if self.type.is_pyobject:
2509 self.type = py_object_type
2511 def analyse_types(self, env):
2512 self.base.analyse_types(env)
2514 self.start.analyse_types(env)
2516 self.stop.analyse_types(env)
2517 base_type = self.base.type
2518 if base_type.is_string:
2519 self.type = bytes_type
2520 elif base_type.is_ptr:
2521 self.type = base_type
2522 elif base_type.is_array:
2523 # we need a ptr type here instead of an array type, as
2524 # array types can result in invalid type casts in the C
2526 self.type = PyrexTypes.CPtrType(base_type.base_type)
2528 self.base = self.base.coerce_to_pyobject(env)
2529 self.type = py_object_type
2530 if base_type.is_builtin_type:
2531 # slicing builtin types returns something of the same type
2532 self.type = base_type
2533 c_int = PyrexTypes.c_py_ssize_t_type
2535 self.start = self.start.coerce_to(c_int, env)
2537 self.stop = self.stop.coerce_to(c_int, env)
2540 nogil_check = Node.gil_error
2541 gil_message = "Slicing Python object"
2543 def generate_result_code(self, code):
2544 if not self.type.is_pyobject:
2546 "Slicing is not currently supported for '%s'." % self.type)
2548 if self.base.type.is_string:
2549 if self.stop is None:
2551 "%s = PyBytes_FromString(%s + %s); %s" % (
2555 code.error_goto_if_null(self.result(), self.pos)))
2558 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2564 code.error_goto_if_null(self.result(), self.pos)))
2567 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2569 self.base.py_result(),
2572 code.error_goto_if_null(self.result(), self.pos)))
2573 code.put_gotref(self.py_result())
2575 def generate_assignment_code(self, rhs, code):
2576 self.generate_subexpr_evaluation_code(code)
2577 if self.type.is_pyobject:
2578 code.put_error_if_neg(self.pos,
2579 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2580 self.base.py_result(),
2587 start_offset = self.start_code()
2588 if start_offset == '0':
2592 if rhs.type.is_array:
2593 array_length = rhs.type.size
2594 self.generate_slice_guard_code(code, array_length)
2597 "Slice assignments from pointers are not yet supported.")
2598 # FIXME: fix the array size according to start/stop
2599 array_length = self.base.type.size
2600 for i in range(array_length):
2601 code.putln("%s[%s%s] = %s[%d];" % (
2602 self.base.result(), start_offset, i,
2604 self.generate_subexpr_disposal_code(code)
2605 self.free_subexpr_temps(code)
2606 rhs.generate_disposal_code(code)
2607 rhs.free_temps(code)
2609 def generate_deletion_code(self, code):
2610 if not self.base.type.is_pyobject:
2612 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2614 self.generate_subexpr_evaluation_code(code)
2615 code.put_error_if_neg(self.pos,
2616 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2617 self.base.py_result(),
2620 self.generate_subexpr_disposal_code(code)
2621 self.free_subexpr_temps(code)
2623 def generate_slice_guard_code(self, code, target_size):
2624 if not self.base.type.is_array:
2626 slice_size = self.base.type.size
2629 stop = self.stop.result()
2633 slice_size = self.base.type.size + stop
2640 start = self.start.result()
2644 start = self.base.type.size + start
2652 error(self.pos, "Assignment to empty slice.")
2653 elif start is None and stop is None:
2654 # we know the exact slice length
2655 if target_size != slice_size:
2656 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2657 slice_size, target_size))
2658 elif start is not None:
2661 check = "(%s)-(%s)" % (stop, start)
2662 else: # stop is not None:
2665 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2666 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));' % (
2667 target_size, check))
2668 code.putln(code.error_goto(self.pos))
2671 def start_code(self):
2673 return self.start.result()
2677 def stop_code(self):
2679 return self.stop.result()
2680 elif self.base.type.is_array:
2681 return self.base.type.size
2683 return "PY_SSIZE_T_MAX"
2685 def calculate_result_code(self):
2686 # self.result() is not used, but this method must exist
2690 class SliceNode(ExprNode):
2691 # start:stop:step in subscript list
2697 subexprs = ['start', 'stop', 'step']
2699 type = py_object_type
2702 def calculate_constant_result(self):
2703 self.constant_result = slice(
2704 self.start.constant_result,
2705 self.stop.constant_result,
2706 self.step.constant_result)
2708 def compile_time_value(self, denv):
2709 start = self.start.compile_time_value(denv)
2710 stop = self.stop.compile_time_value(denv)
2711 step = self.step.compile_time_value(denv)
2713 return slice(start, stop, step)
2714 except Exception, e:
2715 self.compile_time_value_error(e)
2717 def analyse_types(self, env):
2718 self.start.analyse_types(env)
2719 self.stop.analyse_types(env)
2720 self.step.analyse_types(env)
2721 self.start = self.start.coerce_to_pyobject(env)
2722 self.stop = self.stop.coerce_to_pyobject(env)
2723 self.step = self.step.coerce_to_pyobject(env)
2724 if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
2725 self.is_literal = True
2726 self.is_temp = False
2728 gil_message = "Constructing Python slice object"
2730 def calculate_result_code(self):
2731 return self.result_code
2733 def generate_result_code(self, code):
2735 self.result_code = code.get_py_const(py_object_type, 'slice_', cleanup_level=2)
2736 code = code.get_cached_constants_writer()
2737 code.mark_pos(self.pos)
2740 "%s = PySlice_New(%s, %s, %s); %s" % (
2742 self.start.py_result(),
2743 self.stop.py_result(),
2744 self.step.py_result(),
2745 code.error_goto_if_null(self.result(), self.pos)))
2746 code.put_gotref(self.py_result())
2748 code.put_giveref(self.py_result())
2751 class CallNode(ExprNode):
2753 # allow overriding the default 'may_be_none' behaviour
2754 may_return_none = None
2756 def may_be_none(self):
2757 if self.may_return_none is not None:
2758 return self.may_return_none
2759 return ExprNode.may_be_none(self)
2761 def analyse_as_type_constructor(self, env):
2762 type = self.function.analyse_as_type(env)
2763 if type and type.is_struct_or_union:
2764 args, kwds = self.explicit_args_kwds()
2766 for arg, member in zip(args, type.scope.var_entries):
2767 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2769 items += kwds.key_value_pairs
2770 self.key_value_pairs = items
2771 self.__class__ = DictNode
2772 self.analyse_types(env)
2773 self.coerce_to(type, env)
2775 elif type and type.is_cpp_class:
2776 for arg in self.args:
2777 arg.analyse_types(env)
2778 constructor = type.scope.lookup("<init>")
2779 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2780 self.function.entry = constructor
2781 self.function.set_cname(type.declaration_code(""))
2782 self.analyse_c_function_call(env)
2785 def is_lvalue(self):
2786 return self.type.is_reference
2788 def nogil_check(self, env):
2789 func_type = self.function_type()
2790 if func_type.is_pyobject:
2792 elif not getattr(func_type, 'nogil', False):
2795 gil_message = "Calling gil-requiring function"
2798 class SimpleCallNode(CallNode):
2799 # Function call without keyword, * or ** args.
2803 # arg_tuple ExprNode or None used internally
2804 # self ExprNode or None used internally
2805 # coerced_self ExprNode or None used internally
2806 # wrapper_call bool used internally
2807 # has_optional_args bool used internally
2808 # nogil bool used internally
2810 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2815 wrapper_call = False
2816 has_optional_args = False
2820 def compile_time_value(self, denv):
2821 function = self.function.compile_time_value(denv)
2822 args = [arg.compile_time_value(denv) for arg in self.args]
2824 return function(*args)
2825 except Exception, e:
2826 self.compile_time_value_error(e)
2828 def type_dependencies(self, env):
2829 # TODO: Update when Danilo's C++ code merged in to handle the
2830 # the case of function overloading.
2831 return self.function.type_dependencies(env)
2833 def infer_type(self, env):
2834 function = self.function
2835 func_type = function.infer_type(env)
2836 if isinstance(self.function, NewExprNode):
2837 return PyrexTypes.CPtrType(self.function.class_type)
2838 if func_type.is_ptr:
2839 func_type = func_type.base_type
2840 if func_type.is_cfunction:
2841 return func_type.return_type
2842 elif func_type is type_type:
2843 if function.is_name and function.entry and function.entry.type:
2844 result_type = function.entry.type
2845 if result_type.is_extension_type:
2847 elif result_type.is_builtin_type:
2848 if function.entry.name == 'float':
2849 return PyrexTypes.c_double_type
2850 elif function.entry.name in Builtin.types_that_construct_their_instance:
2852 return py_object_type
2854 def analyse_as_type(self, env):
2855 attr = self.function.as_cython_attribute()
2856 if attr == 'pointer':
2857 if len(self.args) != 1:
2858 error(self.args.pos, "only one type allowed.")
2860 type = self.args[0].analyse_as_type(env)
2862 error(self.args[0].pos, "Unknown type")
2864 return PyrexTypes.CPtrType(type)
2866 def explicit_args_kwds(self):
2867 return self.args, None
2869 def analyse_types(self, env):
2870 if self.analyse_as_type_constructor(env):
2874 self.analysed = True
2875 function = self.function
2876 function.is_called = 1
2877 self.function.analyse_types(env)
2878 if function.is_attribute and function.entry and function.entry.is_cmethod:
2879 # Take ownership of the object from which the attribute
2880 # was obtained, because we need to pass it as 'self'.
2881 self.self = function.obj
2882 function.obj = CloneNode(self.self)
2883 func_type = self.function_type()
2884 if func_type.is_pyobject:
2885 self.arg_tuple = TupleNode(self.pos, args = self.args)
2886 self.arg_tuple.analyse_types(env)
2888 if func_type is Builtin.type_type and function.is_name and \
2889 function.entry and \
2890 function.entry.is_builtin and \
2891 function.entry.name in Builtin.types_that_construct_their_instance:
2892 # calling a builtin type that returns a specific object type
2893 if function.entry.name == 'float':
2894 # the following will come true later on in a transform
2895 self.type = PyrexTypes.c_double_type
2896 self.result_ctype = PyrexTypes.c_double_type
2898 self.type = Builtin.builtin_types[function.entry.name]
2899 self.result_ctype = py_object_type
2900 self.may_return_none = False
2901 elif function.is_name and function.type_entry:
2902 # We are calling an extension type constructor. As
2903 # long as we do not support __new__(), the result type
2905 self.type = function.type_entry.type
2906 self.result_ctype = py_object_type
2907 self.may_return_none = False
2909 self.type = py_object_type
2912 for arg in self.args:
2913 arg.analyse_types(env)
2914 if self.self and func_type.args:
2915 # Coerce 'self' to the type expected by the method.
2916 self_arg = func_type.args[0]
2917 if self_arg.not_none: # C methods must do the None test for self at *call* time
2918 self.self = self.self.as_none_safe_node(
2919 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2920 'PyExc_AttributeError')
2921 expected_type = self_arg.type
2922 self.coerced_self = CloneNode(self.self).coerce_to(
2924 # Insert coerced 'self' argument into argument list.
2925 self.args.insert(0, self.coerced_self)
2926 self.analyse_c_function_call(env)
2928 def function_type(self):
2929 # Return the type of the function being called, coercing a function
2930 # pointer to a function if necessary.
2931 func_type = self.function.type
2932 if func_type.is_ptr:
2933 func_type = func_type.base_type
2936 def is_simple(self):
2937 # C function calls could be considered simple, but they may
2938 # have side-effects that may hit when multiple operations must
2939 # be effected in order, e.g. when constructing the argument
2940 # sequence for a function call or comparing values.
2943 def analyse_c_function_call(self, env):
2944 if self.function.type is error_type:
2945 self.type = error_type
2947 if self.function.type.is_cpp_class:
2948 overloaded_entry = self.function.type.scope.lookup("operator()")
2949 if overloaded_entry is None:
2950 self.type = PyrexTypes.error_type
2951 self.result_code = "<error>"
2953 elif hasattr(self.function, 'entry'):
2954 overloaded_entry = self.function.entry
2956 overloaded_entry = None
2957 if overloaded_entry:
2958 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2960 self.type = PyrexTypes.error_type
2961 self.result_code = "<error>"
2963 self.function.entry = entry
2964 self.function.type = entry.type
2965 func_type = self.function_type()
2967 func_type = self.function_type()
2968 if not func_type.is_cfunction:
2969 error(self.pos, "Calling non-function type '%s'" % func_type)
2970 self.type = PyrexTypes.error_type
2971 self.result_code = "<error>"
2974 max_nargs = len(func_type.args)
2975 expected_nargs = max_nargs - func_type.optional_arg_count
2976 actual_nargs = len(self.args)
2977 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2978 self.has_optional_args = 1
2981 some_args_in_temps = False
2982 for i in xrange(min(max_nargs, actual_nargs)):
2983 formal_type = func_type.args[i].type
2984 arg = self.args[i].coerce_to(formal_type, env)
2987 # first argument in temp doesn't impact subsequent arguments
2988 some_args_in_temps = True
2989 elif arg.type.is_pyobject and not env.nogil:
2990 if i == 0 and self.self is not None:
2991 # a method's cloned "self" argument is ok
2993 elif arg.is_name and arg.entry and arg.entry.is_local and not arg.entry.in_closure:
2994 # plain local variables are ok
2997 # we do not safely own the argument's reference,
2998 # but we must make sure it cannot be collected
2999 # before we return from the function, so we create
3000 # an owned temp reference to it
3001 if i > 0: # first argument doesn't matter
3002 some_args_in_temps = True
3003 arg = arg.coerce_to_temp(env)
3005 # handle additional varargs parameters
3006 for i in xrange(max_nargs, actual_nargs):
3008 if arg.type.is_pyobject:
3009 arg_ctype = arg.type.default_coerced_ctype()
3010 if arg_ctype is None:
3011 error(self.args[i].pos,
3012 "Python object cannot be passed as a varargs parameter")
3014 self.args[i] = arg = arg.coerce_to(arg_ctype, env)
3015 if arg.is_temp and i > 0:
3016 some_args_in_temps = True
3017 if some_args_in_temps:
3018 # if some args are temps and others are not, they may get
3019 # constructed in the wrong order (temps first) => make
3020 # sure they are either all temps or all not temps (except
3021 # for the last argument, which is evaluated last in any
3023 for i in xrange(actual_nargs-1):
3024 if i == 0 and self.self is not None:
3025 continue # self is ok
3027 if arg.is_name and arg.entry and (
3028 (arg.entry.is_local and not arg.entry.in_closure)
3029 or arg.entry.type.is_cfunction):
3030 # local variables and C functions are safe
3032 elif env.nogil and arg.type.is_pyobject:
3033 # can't copy a Python reference into a temp in nogil
3034 # env (this is safe: a construction would fail in
3038 self.args[i] = arg.coerce_to_temp(env)
3039 # Calc result type and code fragment
3040 if isinstance(self.function, NewExprNode):
3041 self.type = PyrexTypes.CPtrType(self.function.class_type)
3043 self.type = func_type.return_type
3044 if self.type.is_pyobject:
3045 self.result_ctype = py_object_type
3047 elif func_type.exception_value is not None \
3048 or func_type.exception_check:
3050 # Called in 'nogil' context?
3051 self.nogil = env.nogil
3053 func_type.exception_check and
3054 func_type.exception_check != '+'):
3055 env.use_utility_code(pyerr_occurred_withgil_utility_code)
3056 # C++ exception handler
3057 if func_type.exception_check == '+':
3058 if func_type.exception_value is None:
3059 env.use_utility_code(cpp_exception_utility_code)
3061 def calculate_result_code(self):
3062 return self.c_call_code()
3064 def c_call_code(self):
3065 func_type = self.function_type()
3066 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
3068 formal_args = func_type.args
3070 args = list(zip(formal_args, self.args))
3071 max_nargs = len(func_type.args)
3072 expected_nargs = max_nargs - func_type.optional_arg_count
3073 actual_nargs = len(self.args)
3074 for formal_arg, actual_arg in args[:expected_nargs]:
3075 arg_code = actual_arg.result_as(formal_arg.type)
3076 arg_list_code.append(arg_code)
3078 if func_type.is_overridable:
3079 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3081 if func_type.optional_arg_count:
3082 if expected_nargs == actual_nargs:
3083 optional_args = 'NULL'
3085 optional_args = "&%s" % self.opt_arg_struct
3086 arg_list_code.append(optional_args)
3088 for actual_arg in self.args[len(formal_args):]:
3089 arg_list_code.append(actual_arg.result())
3090 result = "%s(%s)" % (self.function.result(),
3091 ', '.join(arg_list_code))
3094 def generate_result_code(self, code):
3095 func_type = self.function_type()
3096 if func_type.is_pyobject:
3097 arg_code = self.arg_tuple.py_result()
3099 "%s = PyObject_Call(%s, %s, NULL); %s" % (
3101 self.function.py_result(),
3103 code.error_goto_if_null(self.result(), self.pos)))
3104 code.put_gotref(self.py_result())
3105 elif func_type.is_cfunction:
3106 if self.has_optional_args:
3107 actual_nargs = len(self.args)
3108 expected_nargs = len(func_type.args) - func_type.optional_arg_count
3109 self.opt_arg_struct = code.funcstate.allocate_temp(
3110 func_type.op_arg_struct.base_type, manage_ref=True)
3111 code.putln("%s.%s = %s;" % (
3112 self.opt_arg_struct,
3113 Naming.pyrex_prefix + "n",
3114 len(self.args) - expected_nargs))
3115 args = list(zip(func_type.args, self.args))
3116 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
3117 code.putln("%s.%s = %s;" % (
3118 self.opt_arg_struct,
3119 func_type.opt_arg_cname(formal_arg.name),
3120 actual_arg.result_as(formal_arg.type)))
3122 if self.type.is_pyobject and self.is_temp:
3123 exc_checks.append("!%s" % self.result())
3125 exc_val = func_type.exception_value
3126 exc_check = func_type.exception_check
3127 if exc_val is not None:
3128 exc_checks.append("%s == %s" % (self.result(), exc_val))
3131 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3133 exc_checks.append("PyErr_Occurred()")
3134 if self.is_temp or exc_checks:
3135 rhs = self.c_call_code()
3137 lhs = "%s = " % self.result()
3138 if self.is_temp and self.type.is_pyobject:
3139 #return_type = self.type # func_type.return_type
3140 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3141 # "from", return_type, "to pyobject" ###
3142 rhs = typecast(py_object_type, self.type, rhs)
3145 if func_type.exception_check == '+':
3146 if func_type.exception_value is None:
3147 raise_py_exception = "__Pyx_CppExn2PyErr()"
3148 elif func_type.exception_value.type.is_pyobject:
3149 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3150 func_type.exception_value.entry.cname,
3151 func_type.exception_value.entry.cname)
3153 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3155 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3157 "try {%s%s;} catch(...) {%s; %s}" % (
3161 code.error_goto(self.pos)))
3164 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3167 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3168 if self.type.is_pyobject and self.result():
3169 code.put_gotref(self.py_result())
3170 if self.has_optional_args:
3171 code.funcstate.release_temp(self.opt_arg_struct)
3174 class PythonCapiFunctionNode(ExprNode):
3176 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3180 self.type = func_type
3181 self.utility_code = utility_code
3183 def analyse_types(self, env):
3186 def generate_result_code(self, code):
3187 if self.utility_code:
3188 code.globalstate.use_utility_code(self.utility_code)
3190 def calculate_result_code(self):
3193 class PythonCapiCallNode(SimpleCallNode):
3194 # Python C-API Function call (only created in transforms)
3196 # By default, we assume that the call never returns None, as this
3197 # is true for most C-API functions in CPython. If this does not
3198 # apply to a call, set the following to True (or None to inherit
3199 # the default behaviour).
3200 may_return_none = False
3202 def __init__(self, pos, function_name, func_type,
3203 utility_code = None, py_name=None, **kwargs):
3204 self.type = func_type.return_type
3205 self.result_ctype = self.type
3206 self.function = PythonCapiFunctionNode(
3207 pos, py_name, function_name, func_type,
3208 utility_code = utility_code)
3209 # call this last so that we can override the constructed
3210 # attributes above with explicit keyword arguments if required
3211 SimpleCallNode.__init__(self, pos, **kwargs)
3214 class GeneralCallNode(CallNode):
3215 # General Python function call, including keyword,
3216 # * and ** arguments.
3219 # positional_args ExprNode Tuple of positional arguments
3220 # keyword_args ExprNode or None Dict of keyword arguments
3221 # starstar_arg ExprNode or None Dict of extra keyword args
3223 type = py_object_type
3225 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3227 nogil_check = Node.gil_error
3229 def compile_time_value(self, denv):
3230 function = self.function.compile_time_value(denv)
3231 positional_args = self.positional_args.compile_time_value(denv)
3232 keyword_args = self.keyword_args.compile_time_value(denv)
3233 starstar_arg = self.starstar_arg.compile_time_value(denv)
3235 keyword_args.update(starstar_arg)
3236 return function(*positional_args, **keyword_args)
3237 except Exception, e:
3238 self.compile_time_value_error(e)
3240 def explicit_args_kwds(self):
3241 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3242 raise CompileError(self.pos,
3243 'Compile-time keyword arguments must be explicit.')
3244 return self.positional_args.args, self.keyword_args
3246 def analyse_types(self, env):
3247 if self.analyse_as_type_constructor(env):
3249 self.function.analyse_types(env)
3250 self.positional_args.analyse_types(env)
3251 if self.keyword_args:
3252 self.keyword_args.analyse_types(env)
3253 if self.starstar_arg:
3254 self.starstar_arg.analyse_types(env)
3255 if not self.function.type.is_pyobject:
3256 if self.function.type.is_error:
3257 self.type = error_type
3259 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3260 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3262 self.function = self.function.coerce_to_pyobject(env)
3263 self.positional_args = \
3264 self.positional_args.coerce_to_pyobject(env)
3265 if self.starstar_arg:
3266 self.starstar_arg = \
3267 self.starstar_arg.coerce_to_pyobject(env)
3268 function = self.function
3269 if function.is_name and function.type_entry:
3270 # We are calling an extension type constructor. As long
3271 # as we do not support __new__(), the result type is clear
3272 self.type = function.type_entry.type
3273 self.result_ctype = py_object_type
3274 self.may_return_none = False
3276 self.type = py_object_type
3279 def generate_result_code(self, code):
3280 if self.type.is_error: return
3281 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3282 if self.keyword_args and self.starstar_arg:
3283 code.put_error_if_neg(self.pos,
3284 "PyDict_Update(%s, %s)" % (
3285 self.keyword_args.py_result(),
3286 self.starstar_arg.py_result()))
3287 keyword_code = self.keyword_args.py_result()
3288 elif self.keyword_args:
3289 keyword_code = self.keyword_args.py_result()
3290 elif self.starstar_arg:
3291 keyword_code = self.starstar_arg.py_result()
3292 if self.starstar_arg.type is not Builtin.dict_type:
3293 # CPython supports calling functions with non-dicts, so do we
3294 code.globalstate.use_utility_code(kwargs_call_utility_code)
3295 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3298 if not keyword_code:
3299 call_code = "PyObject_Call(%s, %s, NULL)" % (
3300 self.function.py_result(),
3301 self.positional_args.py_result())
3303 call_code = "%s(%s, %s, %s)" % (
3304 kwargs_call_function,
3305 self.function.py_result(),
3306 self.positional_args.py_result(),
3312 code.error_goto_if_null(self.result(), self.pos)))
3313 code.put_gotref(self.py_result())
3316 class AsTupleNode(ExprNode):
3317 # Convert argument to tuple. Used for normalising
3318 # the * argument of a function call.
3324 def calculate_constant_result(self):
3325 self.constant_result = tuple(self.base.constant_result)
3327 def compile_time_value(self, denv):
3328 arg = self.arg.compile_time_value(denv)
3331 except Exception, e:
3332 self.compile_time_value_error(e)
3334 def analyse_types(self, env):
3335 self.arg.analyse_types(env)
3336 self.arg = self.arg.coerce_to_pyobject(env)
3337 self.type = tuple_type
3340 def may_be_none(self):
3343 nogil_check = Node.gil_error
3344 gil_message = "Constructing Python tuple"
3346 def generate_result_code(self, code):
3348 "%s = PySequence_Tuple(%s); %s" % (
3350 self.arg.py_result(),
3351 code.error_goto_if_null(self.result(), self.pos)))
3352 code.put_gotref(self.py_result())
3355 class AttributeNode(ExprNode):
3360 # needs_none_check boolean Used if obj is an extension type.
3361 # If set to True, it is known that the type is not None.
3365 # is_py_attr boolean Is a Python getattr operation
3366 # member string C name of struct member
3367 # is_called boolean Function call is being done on result
3368 # entry Entry Symbol table entry of attribute
3373 type = PyrexTypes.error_type
3376 needs_none_check = True
3378 def as_cython_attribute(self):
3379 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3380 return self.attribute
3381 cy = self.obj.as_cython_attribute()
3383 return "%s.%s" % (cy, self.attribute)
3385 def coerce_to(self, dst_type, env):
3386 # If coercing to a generic pyobject and this is a cpdef function
3387 # we can create the corresponding attribute
3388 if dst_type is py_object_type:
3390 if entry and entry.is_cfunction and entry.as_variable:
3391 # must be a cpdef function
3393 self.entry = entry.as_variable
3394 self.analyse_as_python_attribute(env)
3396 return ExprNode.coerce_to(self, dst_type, env)
3398 def calculate_constant_result(self):
3399 attr = self.attribute
3400 if attr.startswith("__") and attr.endswith("__"):
3402 self.constant_result = getattr(self.obj.constant_result, attr)
3404 def compile_time_value(self, denv):
3405 attr = self.attribute
3406 if attr.startswith("__") and attr.endswith("__"):
3408 "Invalid attribute name '%s' in compile-time expression" % attr)
3410 obj = self.obj.compile_time_value(denv)
3412 return getattr(obj, attr)
3413 except Exception, e:
3414 self.compile_time_value_error(e)
3416 def type_dependencies(self, env):
3417 return self.obj.type_dependencies(env)
3419 def infer_type(self, env):
3420 if self.analyse_as_cimported_attribute(env, 0):
3421 return self.entry.type
3422 elif self.analyse_as_unbound_cmethod(env):
3423 return self.entry.type
3425 obj_type = self.obj.infer_type(env)
3426 self.analyse_attribute(env, obj_type = obj_type)
3427 if obj_type.is_builtin_type and self.type.is_cfunction:
3428 # special case: C-API replacements for C methods of
3429 # builtin types cannot be inferred as C functions as
3430 # that would prevent their use as bound methods
3431 self.type = py_object_type
3432 return py_object_type
3435 def analyse_target_declaration(self, env):
3438 def analyse_target_types(self, env):
3439 self.analyse_types(env, target = 1)
3441 def analyse_types(self, env, target = 0):
3442 if self.analyse_as_cimported_attribute(env, target):
3444 if not target and self.analyse_as_unbound_cmethod(env):
3446 self.analyse_as_ordinary_attribute(env, target)
3448 def analyse_as_cimported_attribute(self, env, target):
3449 # Try to interpret this as a reference to an imported
3450 # C const, type, var or function. If successful, mutates
3451 # this node into a NameNode and returns 1, otherwise
3453 module_scope = self.obj.analyse_as_module(env)
3455 entry = module_scope.lookup_here(self.attribute)
3457 entry.is_cglobal or entry.is_cfunction
3458 or entry.is_type or entry.is_const):
3459 self.mutate_into_name_node(env, entry, target)
3463 def analyse_as_unbound_cmethod(self, env):
3464 # Try to interpret this as a reference to an unbound
3465 # C method of an extension type. If successful, mutates
3466 # this node into a NameNode and returns 1, otherwise
3468 type = self.obj.analyse_as_extension_type(env)
3470 entry = type.scope.lookup_here(self.attribute)
3471 if entry and entry.is_cmethod:
3472 # Create a temporary entry describing the C method
3473 # as an ordinary function.
3474 ubcm_entry = Symtab.Entry(entry.name,
3475 "%s->%s" % (type.vtabptr_cname, entry.cname),
3477 ubcm_entry.is_cfunction = 1
3478 ubcm_entry.func_cname = entry.func_cname
3479 ubcm_entry.is_unbound_cmethod = 1
3480 self.mutate_into_name_node(env, ubcm_entry, None)
3484 def analyse_as_type(self, env):
3485 module_scope = self.obj.analyse_as_module(env)
3487 return module_scope.lookup_type(self.attribute)
3488 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3489 base_type = self.obj.analyse_as_type(env)
3490 if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
3491 return base_type.scope.lookup_type(self.attribute)
3494 def analyse_as_extension_type(self, env):
3495 # Try to interpret this as a reference to an extension type
3496 # in a cimported module. Returns the extension type, or None.
3497 module_scope = self.obj.analyse_as_module(env)
3499 entry = module_scope.lookup_here(self.attribute)
3500 if entry and entry.is_type and entry.type.is_extension_type:
3504 def analyse_as_module(self, env):
3505 # Try to interpret this as a reference to a cimported module
3506 # in another cimported module. Returns the module scope, or None.
3507 module_scope = self.obj.analyse_as_module(env)
3509 entry = module_scope.lookup_here(self.attribute)
3510 if entry and entry.as_module:
3511 return entry.as_module
3514 def mutate_into_name_node(self, env, entry, target):
3515 # Mutate this node into a NameNode and complete the
3516 # analyse_types phase.
3517 self.__class__ = NameNode
3518 self.name = self.attribute
3523 NameNode.analyse_target_types(self, env)
3525 NameNode.analyse_rvalue_entry(self, env)
3527 def analyse_as_ordinary_attribute(self, env, target):
3528 self.obj.analyse_types(env)
3529 self.analyse_attribute(env)
3530 if self.entry and self.entry.is_cmethod and not self.is_called:
3531 # error(self.pos, "C method can only be called")
3533 ## Reference to C array turns into pointer to first element.
3534 #while self.type.is_array:
3535 # self.type = self.type.element_ptr_type()
3539 self.result_ctype = py_object_type
3540 elif target and self.obj.type.is_builtin_type:
3541 error(self.pos, "Assignment to an immutable object field")
3543 def analyse_attribute(self, env, obj_type = None):
3544 # Look up attribute and set self.type and self.member.
3546 self.member = self.attribute
3547 if obj_type is None:
3548 if self.obj.type.is_string:
3549 self.obj = self.obj.coerce_to_pyobject(env)
3550 obj_type = self.obj.type
3552 if obj_type.is_string:
3553 obj_type = py_object_type
3554 if obj_type.is_ptr or obj_type.is_array:
3555 obj_type = obj_type.base_type
3557 elif obj_type.is_extension_type or obj_type.is_builtin_type:
3561 if obj_type.has_attributes:
3563 if obj_type.attributes_known():
3564 entry = obj_type.scope.lookup_here(self.attribute)
3565 if entry and entry.is_member:
3569 "Cannot select attribute of incomplete type '%s'"
3571 self.type = PyrexTypes.error_type
3575 if obj_type.is_extension_type and entry.name == "__weakref__":
3576 error(self.pos, "Illegal use of special attribute __weakref__")
3577 # methods need the normal attribute lookup
3578 # because they do not have struct entries
3579 if entry.is_variable or entry.is_cmethod:
3580 self.type = entry.type
3581 self.member = entry.cname
3584 # If it's not a variable or C method, it must be a Python
3585 # method of an extension type, so we treat it like a Python
3588 # If we get here, the base object is not a struct/union/extension
3589 # type, or it is an extension type and the attribute is either not
3590 # declared or is declared as a Python method. Treat it as a Python
3591 # attribute reference.
3592 self.analyse_as_python_attribute(env, obj_type)
3594 def analyse_as_python_attribute(self, env, obj_type = None):
3595 if obj_type is None:
3596 obj_type = self.obj.type
3597 self.member = self.attribute
3598 self.type = py_object_type
3600 if not obj_type.is_pyobject and not obj_type.is_error:
3601 if obj_type.can_coerce_to_pyobject(env):
3602 self.obj = self.obj.coerce_to_pyobject(env)
3605 "Object of type '%s' has no attribute '%s'" %
3606 (obj_type, self.attribute))
3608 def nogil_check(self, env):
3612 gil_message = "Accessing Python attribute"
3614 def is_simple(self):
3616 return self.result_in_temp() or self.obj.is_simple()
3618 return NameNode.is_simple(self)
3620 def is_lvalue(self):
3624 return NameNode.is_lvalue(self)
3626 def is_ephemeral(self):
3628 return self.obj.is_ephemeral()
3630 return NameNode.is_ephemeral(self)
3632 def calculate_result_code(self):
3633 #print "AttributeNode.calculate_result_code:", self.member ###
3634 #print "...obj node =", self.obj, "code", self.obj.result() ###
3635 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3637 obj_code = obj.result_as(obj.type)
3638 #print "...obj_code =", obj_code ###
3639 if self.entry and self.entry.is_cmethod:
3640 if obj.type.is_extension_type:
3641 return "((struct %s *)%s%s%s)->%s" % (
3642 obj.type.vtabstruct_cname, obj_code, self.op,
3643 obj.type.vtabslot_cname, self.member)
3646 elif obj.type.is_complex:
3647 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3649 if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
3650 # accessing a field of a builtin type, need to cast better than result_as() does
3651 obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
3652 return "%s%s%s" % (obj_code, self.op, self.member)
3654 def generate_result_code(self, code):
3655 interned_attr_cname = code.intern_identifier(self.attribute)
3658 '%s = PyObject_GetAttr(%s, %s); %s' % (
3660 self.obj.py_result(),
3661 interned_attr_cname,
3662 code.error_goto_if_null(self.result(), self.pos)))
3663 code.put_gotref(self.py_result())
3665 # result_code contains what is needed, but we may need to insert
3666 # a check and raise an exception
3667 if (self.obj.type.is_extension_type
3668 and self.needs_none_check
3669 and code.globalstate.directives['nonecheck']):
3670 self.put_nonecheck(code)
3672 def generate_assignment_code(self, rhs, code):
3673 interned_attr_cname = code.intern_identifier(self.attribute)
3674 self.obj.generate_evaluation_code(code)
3676 code.put_error_if_neg(self.pos,
3677 'PyObject_SetAttr(%s, %s, %s)' % (
3678 self.obj.py_result(),
3679 interned_attr_cname,
3681 rhs.generate_disposal_code(code)
3682 rhs.free_temps(code)
3683 elif self.obj.type.is_complex:
3684 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3685 self.member.upper(),
3686 self.obj.result_as(self.obj.type),
3687 rhs.result_as(self.ctype())))
3689 if (self.obj.type.is_extension_type
3690 and self.needs_none_check
3691 and code.globalstate.directives['nonecheck']):
3692 self.put_nonecheck(code)
3694 select_code = self.result()
3695 if self.type.is_pyobject and self.use_managed_ref:
3696 rhs.make_owned_reference(code)
3697 code.put_giveref(rhs.py_result())
3698 code.put_gotref(select_code)
3699 code.put_decref(select_code, self.ctype())
3703 rhs.result_as(self.ctype())))
3705 rhs.generate_post_assignment_code(code)
3706 rhs.free_temps(code)
3707 self.obj.generate_disposal_code(code)
3708 self.obj.free_temps(code)
3710 def generate_deletion_code(self, code):
3711 interned_attr_cname = code.intern_identifier(self.attribute)
3712 self.obj.generate_evaluation_code(code)
3713 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3714 and u'__del__' in self.entry.scope.entries):
3715 code.put_error_if_neg(self.pos,
3716 'PyObject_DelAttr(%s, %s)' % (
3717 self.obj.py_result(),
3718 interned_attr_cname))
3720 error(self.pos, "Cannot delete C attribute of extension type")
3721 self.obj.generate_disposal_code(code)
3722 self.obj.free_temps(code)
3724 def annotate(self, code):
3726 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3728 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3730 def put_nonecheck(self, code):
3731 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3732 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3733 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3734 code.putln(code.error_goto(self.pos))
3738 #-------------------------------------------------------------------
3742 #-------------------------------------------------------------------
3744 class StarredTargetNode(ExprNode):
3745 # A starred expression like "*a"
3747 # This is only allowed in sequence assignment targets such as
3749 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3751 # and will be removed during type analysis (or generate an error
3752 # if it's found at unexpected places).
3756 subexprs = ['target']
3758 type = py_object_type
3761 def __init__(self, pos, target):
3763 self.target = target
3765 def analyse_declarations(self, env):
3766 error(self.pos, "can use starred expression only as assignment target")
3767 self.target.analyse_declarations(env)
3769 def analyse_types(self, env):
3770 error(self.pos, "can use starred expression only as assignment target")
3771 self.target.analyse_types(env)
3772 self.type = self.target.type
3774 def analyse_target_declaration(self, env):
3775 self.target.analyse_target_declaration(env)
3777 def analyse_target_types(self, env):
3778 self.target.analyse_target_types(env)
3779 self.type = self.target.type
3781 def calculate_result_code(self):
3784 def generate_result_code(self, code):
3788 class SequenceNode(ExprNode):
3789 # Base class for list and tuple constructor nodes.
3790 # Contains common code for performing sequence unpacking.
3794 # unpacked_items [ExprNode] or None
3795 # coerced_unpacked_items [ExprNode] or None
3799 is_sequence_constructor = 1
3800 unpacked_items = None
3802 def compile_time_value_list(self, denv):
3803 return [arg.compile_time_value(denv) for arg in self.args]
3805 def replace_starred_target_node(self):
3806 # replace a starred node in the targets by the contained expression
3807 self.starred_assignment = False
3809 for arg in self.args:
3811 if self.starred_assignment:
3812 error(arg.pos, "more than 1 starred expression in assignment")
3813 self.starred_assignment = True
3815 arg.is_starred = True
3819 def analyse_target_declaration(self, env):
3820 self.replace_starred_target_node()
3821 for arg in self.args:
3822 arg.analyse_target_declaration(env)
3824 def analyse_types(self, env, skip_children=False):
3825 for i in range(len(self.args)):
3827 if not skip_children: arg.analyse_types(env)
3828 self.args[i] = arg.coerce_to_pyobject(env)
3830 # not setting self.type here, subtypes do this
3832 def may_be_none(self):
3835 def analyse_target_types(self, env):
3836 self.iterator = PyTempNode(self.pos, env)
3837 self.unpacked_items = []
3838 self.coerced_unpacked_items = []
3839 for arg in self.args:
3840 arg.analyse_target_types(env)
3842 if not arg.type.assignable_from(Builtin.list_type):
3844 "starred target must have Python object (list) type")
3845 if arg.type is py_object_type:
3846 arg.type = Builtin.list_type
3847 unpacked_item = PyTempNode(self.pos, env)
3848 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3849 self.unpacked_items.append(unpacked_item)
3850 self.coerced_unpacked_items.append(coerced_unpacked_item)
3851 self.type = py_object_type
3853 def generate_result_code(self, code):
3854 self.generate_operation_code(code)
3856 def generate_assignment_code(self, rhs, code):
3857 if self.starred_assignment:
3858 self.generate_starred_assignment_code(rhs, code)
3860 self.generate_parallel_assignment_code(rhs, code)
3862 for item in self.unpacked_items:
3864 rhs.free_temps(code)
3866 def generate_parallel_assignment_code(self, rhs, code):
3867 # Need to work around the fact that generate_evaluation_code
3868 # allocates the temps in a rather hacky way -- the assignment
3869 # is evaluated twice, within each if-block.
3871 if rhs.type is tuple_type:
3872 tuple_check = "likely(%s != Py_None)"
3874 tuple_check = "PyTuple_CheckExact(%s)"
3876 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3877 tuple_check % rhs.py_result(),
3880 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3881 for item in self.unpacked_items:
3883 for i in range(len(self.args)):
3884 item = self.unpacked_items[i]
3886 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3889 code.put_incref(item.result(), item.ctype())
3890 value_node = self.coerced_unpacked_items[i]
3891 value_node.generate_evaluation_code(code)
3892 rhs.generate_disposal_code(code)
3894 for i in range(len(self.args)):
3895 self.args[i].generate_assignment_code(
3896 self.coerced_unpacked_items[i], code)
3898 code.putln("} else {")
3900 if rhs.type is tuple_type:
3901 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3902 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3903 rhs.py_result(), len(self.args)))
3904 code.putln(code.error_goto(self.pos))
3906 code.globalstate.use_utility_code(unpacking_utility_code)
3908 self.iterator.allocate(code)
3910 "%s = PyObject_GetIter(%s); %s" % (
3911 self.iterator.result(),
3913 code.error_goto_if_null(self.iterator.result(), self.pos)))
3914 code.put_gotref(self.iterator.py_result())
3915 rhs.generate_disposal_code(code)
3916 for i in range(len(self.args)):
3917 item = self.unpacked_items[i]
3918 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3919 self.iterator.py_result(), i)
3923 typecast(item.ctype(), py_object_type, unpack_code),
3924 code.error_goto_if_null(item.result(), self.pos)))
3925 code.put_gotref(item.py_result())
3926 value_node = self.coerced_unpacked_items[i]
3927 value_node.generate_evaluation_code(code)
3928 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3929 self.iterator.py_result(),
3931 if debug_disposal_code:
3932 print("UnpackNode.generate_assignment_code:")
3933 print("...generating disposal code for %s" % self.iterator)
3934 self.iterator.generate_disposal_code(code)
3935 self.iterator.free_temps(code)
3936 self.iterator.release(code)
3938 for i in range(len(self.args)):
3939 self.args[i].generate_assignment_code(
3940 self.coerced_unpacked_items[i], code)
3944 def generate_starred_assignment_code(self, rhs, code):
3945 code.globalstate.use_utility_code(unpacking_utility_code)
3947 for i, arg in enumerate(self.args):
3949 starred_target = self.unpacked_items[i]
3950 fixed_args_left = self.args[:i]
3951 fixed_args_right = self.args[i+1:]
3954 self.iterator.allocate(code)
3956 "%s = PyObject_GetIter(%s); %s" % (
3957 self.iterator.result(),
3959 code.error_goto_if_null(self.iterator.result(), self.pos)))
3960 code.put_gotref(self.iterator.py_result())
3961 rhs.generate_disposal_code(code)
3963 for item in self.unpacked_items:
3965 for i in range(len(fixed_args_left)):
3966 item = self.unpacked_items[i]
3967 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3968 self.iterator.py_result(), i)
3972 typecast(item.ctype(), py_object_type, unpack_code),
3973 code.error_goto_if_null(item.result(), self.pos)))
3974 code.put_gotref(item.py_result())
3975 value_node = self.coerced_unpacked_items[i]
3976 value_node.generate_evaluation_code(code)
3978 target_list = starred_target.result()
3979 code.putln("%s = PySequence_List(%s); %s" % (
3980 target_list, self.iterator.py_result(),
3981 code.error_goto_if_null(target_list, self.pos)))
3982 code.put_gotref(target_list)
3983 if fixed_args_right:
3984 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3985 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3986 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3987 (target_list, len(unpacked_right_args))))
3988 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3989 len(fixed_args_left), target_list,
3990 code.error_goto(self.pos)))
3992 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3993 self.coerced_unpacked_items[::-1])):
3995 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3997 target_list, target_list))
3998 # resize the list the hard way
3999 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
4000 code.put_gotref(arg.py_result())
4001 coerced_arg.generate_evaluation_code(code)
4003 self.iterator.generate_disposal_code(code)
4004 self.iterator.free_temps(code)
4005 self.iterator.release(code)
4007 for i in range(len(self.args)):
4008 self.args[i].generate_assignment_code(
4009 self.coerced_unpacked_items[i], code)
4011 def annotate(self, code):
4012 for arg in self.args:
4014 if self.unpacked_items:
4015 for arg in self.unpacked_items:
4017 for arg in self.coerced_unpacked_items:
4021 class TupleNode(SequenceNode):
4022 # Tuple constructor.
4026 gil_message = "Constructing Python tuple"
4028 def analyse_types(self, env, skip_children=False):
4029 if len(self.args) == 0:
4033 SequenceNode.analyse_types(self, env, skip_children)
4034 for child in self.args:
4035 if not child.is_literal:
4041 def is_simple(self):
4042 # either temp or constant => always simple
4045 def calculate_result_code(self):
4046 if len(self.args) > 0:
4047 return self.result_code
4049 return Naming.empty_tuple
4051 def calculate_constant_result(self):
4052 self.constant_result = tuple([
4053 arg.constant_result for arg in self.args])
4055 def compile_time_value(self, denv):
4056 values = self.compile_time_value_list(denv)
4058 return tuple(values)
4059 except Exception, e:
4060 self.compile_time_value_error(e)
4062 def generate_operation_code(self, code):
4063 if len(self.args) == 0:
4064 # result_code is Naming.empty_tuple
4067 # non-empty cached tuple => result is global constant,
4068 # creation code goes into separate code writer
4069 self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
4070 code = code.get_cached_constants_writer()
4071 code.mark_pos(self.pos)
4074 "%s = PyTuple_New(%s); %s" % (
4077 code.error_goto_if_null(self.result(), self.pos)))
4078 code.put_gotref(self.py_result())
4079 for i in range(len(self.args)):
4081 if not arg.result_in_temp():
4082 code.put_incref(arg.result(), arg.ctype())
4084 "PyTuple_SET_ITEM(%s, %s, %s);" % (
4088 code.put_giveref(arg.py_result())
4090 code.put_giveref(self.py_result())
4092 def generate_subexpr_disposal_code(self, code):
4093 # We call generate_post_assignment_code here instead
4094 # of generate_disposal_code, because values were stored
4095 # in the tuple using a reference-stealing operation.
4096 for arg in self.args:
4097 arg.generate_post_assignment_code(code)
4098 # Should NOT call free_temps -- this is invoked by the default
4099 # generate_evaluation_code which will do that.
4102 class ListNode(SequenceNode):
4105 # obj_conversion_errors [PyrexError] used internally
4106 # orignial_args [ExprNode] used internally
4108 obj_conversion_errors = []
4111 gil_message = "Constructing Python list"
4113 def type_dependencies(self, env):
4116 def infer_type(self, env):
4117 # TOOD: Infer non-object list arrays.
4120 def analyse_expressions(self, env):
4121 SequenceNode.analyse_expressions(self, env)
4122 self.coerce_to_pyobject(env)
4124 def analyse_types(self, env):
4126 self.original_args = list(self.args)
4127 SequenceNode.analyse_types(self, env)
4128 self.obj_conversion_errors = held_errors()
4129 release_errors(ignore=True)
4131 def coerce_to(self, dst_type, env):
4132 if dst_type.is_pyobject:
4133 for err in self.obj_conversion_errors:
4135 self.obj_conversion_errors = []
4136 if not self.type.subtype_of(dst_type):
4137 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4138 elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
4139 base_type = dst_type.base_type
4140 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4141 for i in range(len(self.original_args)):
4143 if isinstance(arg, CoerceToPyTypeNode):
4145 self.args[i] = arg.coerce_to(base_type, env)
4146 elif dst_type.is_struct:
4147 if len(self.args) > len(dst_type.scope.var_entries):
4148 error(self.pos, "Too may members for '%s'" % dst_type)
4150 if len(self.args) < len(dst_type.scope.var_entries):
4151 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4152 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
4153 if isinstance(arg, CoerceToPyTypeNode):
4155 self.args[i] = arg.coerce_to(member.type, env)
4156 self.type = dst_type
4158 self.type = error_type
4159 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4162 def release_temp(self, env):
4163 if self.type.is_array:
4164 # To be valid C++, we must allocate the memory on the stack
4165 # manually and be sure not to reuse it for something else.
4168 SequenceNode.release_temp(self, env)
4170 def calculate_constant_result(self):
4171 self.constant_result = [
4172 arg.constant_result for arg in self.args]
4174 def compile_time_value(self, denv):
4175 return self.compile_time_value_list(denv)
4177 def generate_operation_code(self, code):
4178 if self.type.is_pyobject:
4179 for err in self.obj_conversion_errors:
4181 code.putln("%s = PyList_New(%s); %s" %
4184 code.error_goto_if_null(self.result(), self.pos)))
4185 code.put_gotref(self.py_result())
4186 for i in range(len(self.args)):
4188 #if not arg.is_temp:
4189 if not arg.result_in_temp():
4190 code.put_incref(arg.result(), arg.ctype())
4191 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4195 code.put_giveref(arg.py_result())
4196 elif self.type.is_array:
4197 for i, arg in enumerate(self.args):
4198 code.putln("%s[%s] = %s;" % (
4202 elif self.type.is_struct:
4203 for arg, member in zip(self.args, self.type.scope.var_entries):
4204 code.putln("%s.%s = %s;" % (
4209 raise InternalError("List type never specified")
4211 def generate_subexpr_disposal_code(self, code):
4212 # We call generate_post_assignment_code here instead
4213 # of generate_disposal_code, because values were stored
4214 # in the list using a reference-stealing operation.
4215 for arg in self.args:
4216 arg.generate_post_assignment_code(code)
4217 # Should NOT call free_temps -- this is invoked by the default
4218 # generate_evaluation_code which will do that.
4221 class ScopedExprNode(ExprNode):
4222 # Abstract base class for ExprNodes that have their own local
4223 # scope, such as generator expressions.
4225 # expr_scope Scope the inner scope of the expression
4230 # does this node really have a local scope, e.g. does it leak loop
4231 # variables or not? non-leaking Py3 behaviour is default, except
4232 # for list comprehensions where the behaviour differs in Py2 and
4233 # Py3 (set in Parsing.py based on parser context)
4234 has_local_scope = True
4236 def init_scope(self, outer_scope, expr_scope=None):
4237 if expr_scope is not None:
4238 self.expr_scope = expr_scope
4239 elif self.has_local_scope:
4240 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4242 self.expr_scope = None
4244 def analyse_declarations(self, env):
4245 self.init_scope(env)
4247 def analyse_scoped_declarations(self, env):
4248 # this is called with the expr_scope as env
4251 def analyse_types(self, env):
4252 # no recursion here, the children will be analysed separately below
4255 def analyse_scoped_expressions(self, env):
4256 # this is called with the expr_scope as env
4259 def generate_evaluation_code(self, code):
4260 # set up local variables and free their references on exit
4261 generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
4262 if not self.has_local_scope or not self.expr_scope.var_entries:
4263 # no local variables => delegate, done
4264 generate_inner_evaluation_code(code)
4267 code.putln('{ /* enter inner scope */')
4269 for entry in self.expr_scope.var_entries:
4270 if not entry.in_closure:
4271 code.put_var_declaration(entry)
4272 if entry.type.is_pyobject and entry.used:
4273 py_entries.append(entry)
4275 # no local Python references => no cleanup required
4276 generate_inner_evaluation_code(code)
4277 code.putln('} /* exit inner scope */')
4279 for entry in py_entries:
4280 code.put_init_var_to_py_none(entry)
4282 # must free all local Python references at each exit point
4283 old_loop_labels = tuple(code.new_loop_labels())
4284 old_error_label = code.new_error_label()
4286 generate_inner_evaluation_code(code)
4288 # normal (non-error) exit
4289 for entry in py_entries:
4290 code.put_var_decref(entry)
4292 # error/loop body exit points
4293 exit_scope = code.new_label('exit_scope')
4294 code.put_goto(exit_scope)
4295 for label, old_label in ([(code.error_label, old_error_label)] +
4296 list(zip(code.get_loop_labels(), old_loop_labels))):
4297 if code.label_used(label):
4298 code.put_label(label)
4299 for entry in py_entries:
4300 code.put_var_decref(entry)
4301 code.put_goto(old_label)
4302 code.put_label(exit_scope)
4303 code.putln('} /* exit inner scope */')
4305 code.set_loop_labels(old_loop_labels)
4306 code.error_label = old_error_label
4309 class ComprehensionNode(ScopedExprNode):
4310 subexprs = ["target"]
4311 child_attrs = ["loop", "append"]
4313 def infer_type(self, env):
4314 return self.target.infer_type(env)
4316 def analyse_declarations(self, env):
4317 self.append.target = self # this is used in the PyList_Append of the inner loop
4318 self.init_scope(env)
4320 def analyse_scoped_declarations(self, env):
4321 self.loop.analyse_declarations(env)
4323 def analyse_types(self, env):
4324 self.target.analyse_expressions(env)
4325 self.type = self.target.type
4326 if not self.has_local_scope:
4327 self.loop.analyse_expressions(env)
4329 def analyse_scoped_expressions(self, env):
4330 if self.has_local_scope:
4331 self.loop.analyse_expressions(env)
4333 def may_be_none(self):
4336 def calculate_result_code(self):
4337 return self.target.result()
4339 def generate_result_code(self, code):
4340 self.generate_operation_code(code)
4342 def generate_operation_code(self, code):
4343 self.loop.generate_execution_code(code)
4345 def annotate(self, code):
4346 self.loop.annotate(code)
4349 class ComprehensionAppendNode(Node):
4350 # Need to be careful to avoid infinite recursion:
4351 # target must not be in child_attrs/subexprs
4353 child_attrs = ['expr']
4355 type = PyrexTypes.c_int_type
4357 def analyse_expressions(self, env):
4358 self.expr.analyse_expressions(env)
4359 if not self.expr.type.is_pyobject:
4360 self.expr = self.expr.coerce_to_pyobject(env)
4362 def generate_execution_code(self, code):
4363 if self.target.type is list_type:
4364 function = "PyList_Append"
4365 elif self.target.type is set_type:
4366 function = "PySet_Add"
4368 raise InternalError(
4369 "Invalid type for comprehension node: %s" % self.target.type)
4371 self.expr.generate_evaluation_code(code)
4372 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4374 self.target.result(),
4377 self.expr.generate_disposal_code(code)
4378 self.expr.free_temps(code)
4380 def generate_function_definitions(self, env, code):
4381 self.expr.generate_function_definitions(env, code)
4383 def annotate(self, code):
4384 self.expr.annotate(code)
4386 class DictComprehensionAppendNode(ComprehensionAppendNode):
4387 child_attrs = ['key_expr', 'value_expr']
4389 def analyse_expressions(self, env):
4390 self.key_expr.analyse_expressions(env)
4391 if not self.key_expr.type.is_pyobject:
4392 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4393 self.value_expr.analyse_expressions(env)
4394 if not self.value_expr.type.is_pyobject:
4395 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4397 def generate_execution_code(self, code):
4398 self.key_expr.generate_evaluation_code(code)
4399 self.value_expr.generate_evaluation_code(code)
4400 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4401 self.target.result(),
4402 self.key_expr.result(),
4403 self.value_expr.result()
4405 self.key_expr.generate_disposal_code(code)
4406 self.key_expr.free_temps(code)
4407 self.value_expr.generate_disposal_code(code)
4408 self.value_expr.free_temps(code)
4410 def generate_function_definitions(self, env, code):
4411 self.key_expr.generate_function_definitions(env, code)
4412 self.value_expr.generate_function_definitions(env, code)
4414 def annotate(self, code):
4415 self.key_expr.annotate(code)
4416 self.value_expr.annotate(code)
4419 class GeneratorExpressionNode(ScopedExprNode):
4420 # A generator expression, e.g. (i for i in range(10))
4422 # Result is a generator.
4424 # loop ForStatNode the for-loop, containing a YieldExprNode
4426 child_attrs = ["loop"]
4428 type = py_object_type
4430 def analyse_scoped_declarations(self, env):
4431 self.loop.analyse_declarations(env)
4433 def analyse_types(self, env):
4434 if not self.has_local_scope:
4435 self.loop.analyse_expressions(env)
4438 def analyse_scoped_expressions(self, env):
4439 if self.has_local_scope:
4440 self.loop.analyse_expressions(env)
4442 def may_be_none(self):
4445 def annotate(self, code):
4446 self.loop.annotate(code)
4449 class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
4450 # An inlined generator expression for which the result is
4451 # calculated inside of the loop. This will only be created by
4452 # transforms when replacing builtin calls on generator
4455 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4456 # result_node ResultRefNode the reference to the result value temp
4457 # orig_func String the name of the builtin function this node replaces
4459 child_attrs = ["loop"]
4460 loop_analysed = False
4462 def infer_type(self, env):
4463 return self.result_node.infer_type(env)
4465 def analyse_types(self, env):
4466 if not self.has_local_scope:
4467 self.loop_analysed = True
4468 self.loop.analyse_expressions(env)
4469 self.type = self.result_node.type
4472 def analyse_scoped_expressions(self, env):
4473 self.loop_analysed = True
4474 GeneratorExpressionNode.analyse_scoped_expressions(self, env)
4476 def coerce_to(self, dst_type, env):
4477 if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
4478 # We can optimise by dropping the aggregation variable and
4479 # the add operations into C. This can only be done safely
4480 # before analysing the loop body, after that, the result
4481 # reference type will have infected expressions and
4483 self.result_node.type = self.type = dst_type
4485 return GeneratorExpressionNode.coerce_to(self, dst_type, env)
4487 def generate_result_code(self, code):
4488 self.result_node.result_code = self.result()
4489 self.loop.generate_execution_code(code)
4492 class SetNode(ExprNode):
4499 gil_message = "Constructing Python set"
4501 def analyse_types(self, env):
4502 for i in range(len(self.args)):
4504 arg.analyse_types(env)
4505 self.args[i] = arg.coerce_to_pyobject(env)
4506 self.type = set_type
4509 def may_be_none(self):
4512 def calculate_constant_result(self):
4513 self.constant_result = set([
4514 arg.constant_result for arg in self.args])
4516 def compile_time_value(self, denv):
4517 values = [arg.compile_time_value(denv) for arg in self.args]
4520 except Exception, e:
4521 self.compile_time_value_error(e)
4523 def generate_evaluation_code(self, code):
4524 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4525 self.allocate_temp_result(code)
4527 "%s = PySet_New(0); %s" % (
4529 code.error_goto_if_null(self.result(), self.pos)))
4530 code.put_gotref(self.py_result())
4531 for arg in self.args:
4532 arg.generate_evaluation_code(code)
4534 code.error_goto_if_neg(
4535 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4537 arg.generate_disposal_code(code)
4538 arg.free_temps(code)
4541 class DictNode(ExprNode):
4542 # Dictionary constructor.
4544 # key_value_pairs [DictItemNode]
4546 # obj_conversion_errors [PyrexError] used internally
4548 subexprs = ['key_value_pairs']
4552 obj_conversion_errors = []
4554 def calculate_constant_result(self):
4555 self.constant_result = dict([
4556 item.constant_result for item in self.key_value_pairs])
4558 def compile_time_value(self, denv):
4559 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4560 for item in self.key_value_pairs]
4563 except Exception, e:
4564 self.compile_time_value_error(e)
4566 def type_dependencies(self, env):
4569 def infer_type(self, env):
4570 # TOOD: Infer struct constructors.
4573 def analyse_types(self, env):
4575 for item in self.key_value_pairs:
4576 item.analyse_types(env)
4577 self.obj_conversion_errors = held_errors()
4578 release_errors(ignore=True)
4580 def may_be_none(self):
4583 def coerce_to(self, dst_type, env):
4584 if dst_type.is_pyobject:
4585 self.release_errors()
4586 if not self.type.subtype_of(dst_type):
4587 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4588 elif dst_type.is_struct_or_union:
4589 self.type = dst_type
4590 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4591 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4592 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4593 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4594 for item in self.key_value_pairs:
4595 if isinstance(item.key, CoerceToPyTypeNode):
4596 item.key = item.key.arg
4597 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4598 error(item.key.pos, "Invalid struct field identifier")
4599 item.key = StringNode(item.key.pos, value="<error>")
4601 key = str(item.key.value) # converts string literals to unicode in Py3
4602 member = dst_type.scope.lookup_here(key)
4604 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4607 if isinstance(value, CoerceToPyTypeNode):
4609 item.value = value.coerce_to(member.type, env)
4611 self.type = error_type
4612 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4615 def release_errors(self):
4616 for err in self.obj_conversion_errors:
4618 self.obj_conversion_errors = []
4620 gil_message = "Constructing Python dict"
4622 def generate_evaluation_code(self, code):
4623 # Custom method used here because key-value
4624 # pairs are evaluated and used one at a time.
4625 code.mark_pos(self.pos)
4626 self.allocate_temp_result(code)
4627 if self.type.is_pyobject:
4628 self.release_errors()
4630 "%s = PyDict_New(); %s" % (
4632 code.error_goto_if_null(self.result(), self.pos)))
4633 code.put_gotref(self.py_result())
4634 for item in self.key_value_pairs:
4635 item.generate_evaluation_code(code)
4636 if self.type.is_pyobject:
4637 code.put_error_if_neg(self.pos,
4638 "PyDict_SetItem(%s, %s, %s)" % (
4640 item.key.py_result(),
4641 item.value.py_result()))
4643 code.putln("%s.%s = %s;" % (
4646 item.value.result()))
4647 item.generate_disposal_code(code)
4648 item.free_temps(code)
4650 def annotate(self, code):
4651 for item in self.key_value_pairs:
4654 class DictItemNode(ExprNode):
4655 # Represents a single item in a DictNode
4659 subexprs = ['key', 'value']
4661 nogil_check = None # Parent DictNode takes care of it
4663 def calculate_constant_result(self):
4664 self.constant_result = (
4665 self.key.constant_result, self.value.constant_result)
4667 def analyse_types(self, env):
4668 self.key.analyse_types(env)
4669 self.value.analyse_types(env)
4670 self.key = self.key.coerce_to_pyobject(env)
4671 self.value = self.value.coerce_to_pyobject(env)
4673 def generate_evaluation_code(self, code):
4674 self.key.generate_evaluation_code(code)
4675 self.value.generate_evaluation_code(code)
4677 def generate_disposal_code(self, code):
4678 self.key.generate_disposal_code(code)
4679 self.value.generate_disposal_code(code)
4681 def free_temps(self, code):
4682 self.key.free_temps(code)
4683 self.value.free_temps(code)
4686 return iter([self.key, self.value])
4688 class ModuleNameMixin(object):
4689 def set_mod_name(self, env):
4690 self.module_name = env.global_scope().qualified_name
4692 def get_py_mod_name(self, code):
4693 return code.get_py_string_const(
4694 self.module_name, identifier=True)
4696 class ClassNode(ExprNode, ModuleNameMixin):
4697 # Helper class used in the implementation of Python
4698 # class definitions. Constructs a class object given
4699 # a name, tuple of bases and class dictionary.
4701 # name EncodedString Name of the class
4702 # bases ExprNode Base class tuple
4703 # dict ExprNode Class dict (not owned by this node)
4704 # doc ExprNode or None Doc string
4705 # module_name EncodedString Name of defining module
4707 subexprs = ['bases', 'doc']
4709 def analyse_types(self, env):
4710 self.bases.analyse_types(env)
4712 self.doc.analyse_types(env)
4713 self.doc = self.doc.coerce_to_pyobject(env)
4714 self.type = py_object_type
4716 env.use_utility_code(create_class_utility_code);
4717 #TODO(craig,haoyu) This should be moved to a better place
4718 self.set_mod_name(env)
4720 def may_be_none(self):
4723 gil_message = "Constructing Python class"
4725 def generate_result_code(self, code):
4726 cname = code.intern_identifier(self.name)
4729 code.put_error_if_neg(self.pos,
4730 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4731 self.dict.py_result(),
4732 self.doc.py_result()))
4733 py_mod_name = self.get_py_mod_name(code)
4735 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4737 self.bases.py_result(),
4738 self.dict.py_result(),
4741 code.error_goto_if_null(self.result(), self.pos)))
4742 code.put_gotref(self.py_result())
4745 class Py3ClassNode(ExprNode):
4746 # Helper class used in the implementation of Python3+
4747 # class definitions. Constructs a class object given
4748 # a name, tuple of bases and class dictionary.
4750 # name EncodedString Name of the class
4751 # dict ExprNode Class dict (not owned by this node)
4752 # module_name EncodedString Name of defining module
4756 def analyse_types(self, env):
4757 self.type = py_object_type
4760 def may_be_none(self):
4763 gil_message = "Constructing Python class"
4765 def generate_result_code(self, code):
4766 code.globalstate.use_utility_code(create_py3class_utility_code)
4767 cname = code.intern_identifier(self.name)
4769 '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
4771 self.metaclass.result(),
4773 self.bases.py_result(),
4774 self.dict.py_result(),
4775 self.mkw.py_result(),
4776 code.error_goto_if_null(self.result(), self.pos)))
4777 code.put_gotref(self.py_result())
4779 class KeywordArgsNode(ExprNode):
4780 # Helper class for keyword arguments
4782 # keyword_args ExprNode or None Keyword arguments
4783 # starstar_arg ExprNode or None Extra arguments
4785 subexprs = ['keyword_args', 'starstar_arg']
4787 def analyse_types(self, env):
4788 if self.keyword_args:
4789 self.keyword_args.analyse_types(env)
4790 if self.starstar_arg:
4791 self.starstar_arg.analyse_types(env)
4792 # make sure we have a Python object as **kwargs mapping
4793 self.starstar_arg = \
4794 self.starstar_arg.coerce_to_pyobject(env)
4795 self.type = py_object_type
4798 gil_message = "Constructing Keyword Args"
4800 def generate_result_code(self, code):
4801 if self.keyword_args and self.starstar_arg:
4802 code.put_error_if_neg(self.pos,
4803 "PyDict_Update(%s, %s)" % (
4804 self.keyword_args.py_result(),
4805 self.starstar_arg.py_result()))
4806 if self.keyword_args:
4807 code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
4808 code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
4809 elif self.starstar_arg:
4811 "%s = PyDict_Copy(%s); %s" % (
4813 self.starstar_arg.py_result(),
4814 code.error_goto_if_null(self.result(), self.pos)))
4815 code.put_gotref(self.py_result())
4818 "%s = PyDict_New(); %s" % (
4820 code.error_goto_if_null(self.result(), self.pos)))
4821 code.put_gotref(self.py_result())
4823 class PyClassMetaclassNode(ExprNode):
4824 # Helper class holds Python3 metaclass object
4826 # bases ExprNode Base class tuple (not owned by this node)
4827 # mkw ExprNode Class keyword arguments (not owned by this node)
4831 def analyse_types(self, env):
4832 self.type = py_object_type
4835 def may_be_none(self):
4838 def generate_result_code(self, code):
4840 "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
4842 self.bases.result(),
4844 code.error_goto_if_null(self.result(), self.pos)))
4845 code.put_gotref(self.py_result())
4847 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
4848 # Helper class holds Python3 namespace object
4850 # All this are not owned by this node
4851 # metaclass ExprNode Metaclass object
4852 # bases ExprNode Base class tuple
4853 # mkw ExprNode Class keyword arguments
4854 # doc ExprNode or None Doc string (owned)
4858 def analyse_types(self, env):
4859 self.bases.analyse_types(env)
4861 self.doc.analyse_types(env)
4862 self.doc = self.doc.coerce_to_pyobject(env)
4863 self.type = py_object_type
4865 #TODO(craig,haoyu) This should be moved to a better place
4866 self.set_mod_name(env)
4868 def may_be_none(self):
4871 def generate_result_code(self, code):
4872 cname = code.intern_identifier(self.name)
4873 py_mod_name = self.get_py_mod_name(code)
4875 doc_code = self.doc.result()
4877 doc_code = '(PyObject *) NULL'
4879 "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
4881 self.metaclass.result(),
4882 self.bases.result(),
4887 code.error_goto_if_null(self.result(), self.pos)))
4888 code.put_gotref(self.py_result())
4890 class BoundMethodNode(ExprNode):
4891 # Helper class used in the implementation of Python
4892 # class definitions. Constructs an bound method
4893 # object from a class and a function.
4895 # function ExprNode Function object
4896 # self_object ExprNode self object
4898 subexprs = ['function']
4900 def analyse_types(self, env):
4901 self.function.analyse_types(env)
4902 self.type = py_object_type
4905 gil_message = "Constructing an bound method"
4907 def generate_result_code(self, code):
4909 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4911 self.function.py_result(),
4912 self.self_object.py_result(),
4913 self.self_object.py_result(),
4914 code.error_goto_if_null(self.result(), self.pos)))
4915 code.put_gotref(self.py_result())
4917 class UnboundMethodNode(ExprNode):
4918 # Helper class used in the implementation of Python
4919 # class definitions. Constructs an unbound method
4920 # object from a class and a function.
4922 # function ExprNode Function object
4924 type = py_object_type
4927 subexprs = ['function']
4929 def analyse_types(self, env):
4930 self.function.analyse_types(env)
4932 def may_be_none(self):
4935 gil_message = "Constructing an unbound method"
4937 def generate_result_code(self, code):
4938 class_cname = code.pyclass_stack[-1].classobj.result()
4940 "%s = PyMethod_New(%s, 0, %s); %s" % (
4942 self.function.py_result(),
4944 code.error_goto_if_null(self.result(), self.pos)))
4945 code.put_gotref(self.py_result())
4948 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4949 # Helper class used in the implementation of Python
4950 # class definitions. Constructs a PyCFunction object
4951 # from a PyMethodDef struct.
4953 # pymethdef_cname string PyMethodDef structure
4954 # self_object ExprNode or None
4956 # module_name EncodedString Name of defining module
4962 type = py_object_type
4965 def analyse_types(self, env):
4967 env.use_utility_code(binding_cfunc_utility_code)
4969 #TODO(craig,haoyu) This should be moved to a better place
4970 self.set_mod_name(env)
4972 def may_be_none(self):
4975 gil_message = "Constructing Python function"
4977 def self_result_code(self):
4978 if self.self_object is None:
4979 self_result = "NULL"
4981 self_result = self.self_object.py_result()
4984 def generate_result_code(self, code):
4986 constructor = "%s_NewEx" % Naming.binding_cfunc
4988 constructor = "PyCFunction_NewEx"
4989 py_mod_name = self.get_py_mod_name(code)
4991 '%s = %s(&%s, %s, %s); %s' % (
4994 self.pymethdef_cname,
4995 self.self_result_code(),
4997 code.error_goto_if_null(self.result(), self.pos)))
4998 code.put_gotref(self.py_result())
5000 class InnerFunctionNode(PyCFunctionNode):
5001 # Special PyCFunctionNode that depends on a closure class
5005 needs_self_code = True
5007 def self_result_code(self):
5008 if self.needs_self_code:
5009 return "((PyObject*)%s)" % (Naming.cur_scope_cname)
5012 class LambdaNode(InnerFunctionNode):
5013 # Lambda expression node (only used as a function reference)
5015 # args [CArgDeclNode] formal arguments
5016 # star_arg PyArgDeclNode or None * argument
5017 # starstar_arg PyArgDeclNode or None ** argument
5018 # lambda_name string a module-globally unique lambda name
5019 # result_expr ExprNode
5020 # def_node DefNode the underlying function 'def' node
5022 child_attrs = ['def_node']
5025 name = StringEncoding.EncodedString('<lambda>')
5027 def analyse_declarations(self, env):
5028 self.def_node.analyse_declarations(env)
5029 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
5030 env.add_lambda_def(self.def_node)
5032 class YieldExprNode(ExprNode):
5033 # Yield expression node
5035 # arg ExprNode the value to return from the generator
5036 # label_name string name of the C label used for this yield
5039 type = py_object_type
5041 def analyse_types(self, env):
5043 if self.arg is not None:
5044 self.arg.analyse_types(env)
5045 if not self.arg.type.is_pyobject:
5046 self.arg = self.arg.coerce_to_pyobject(env)
5047 error(self.pos, "Generators are not supported")
5049 def generate_result_code(self, code):
5050 self.label_name = code.new_label('resume_from_yield')
5051 code.use_label(self.label_name)
5052 code.putln("/* FIXME: save temporary variables */")
5053 code.putln("/* FIXME: return from function, yielding value */")
5054 code.put_label(self.label_name)
5055 code.putln("/* FIXME: restore temporary variables and */")
5056 code.putln("/* FIXME: extract sent value from closure */")
5059 #-------------------------------------------------------------------
5061 # Unary operator nodes
5063 #-------------------------------------------------------------------
5065 compile_time_unary_operators = {
5066 'not': operator.not_,
5072 class UnopNode(ExprNode):
5076 # Processing during analyse_expressions phase:
5078 # analyse_c_operation
5079 # Called when the operand is not a pyobject.
5080 # - Check operand type and coerce if needed.
5081 # - Determine result type and result code fragment.
5082 # - Allocate temporary for result if needed.
5084 subexprs = ['operand']
5087 def calculate_constant_result(self):
5088 func = compile_time_unary_operators[self.operator]
5089 self.constant_result = func(self.operand.constant_result)
5091 def compile_time_value(self, denv):
5092 func = compile_time_unary_operators.get(self.operator)
5095 "Unary '%s' not supported in compile-time expression"
5097 operand = self.operand.compile_time_value(denv)
5099 return func(operand)
5100 except Exception, e:
5101 self.compile_time_value_error(e)
5103 def infer_type(self, env):
5104 operand_type = self.operand.infer_type(env)
5105 if operand_type.is_pyobject:
5106 return py_object_type
5110 def analyse_types(self, env):
5111 self.operand.analyse_types(env)
5112 if self.is_py_operation():
5113 self.coerce_operand_to_pyobject(env)
5114 self.type = py_object_type
5116 elif self.is_cpp_operation():
5117 self.analyse_cpp_operation(env)
5119 self.analyse_c_operation(env)
5121 def check_const(self):
5122 return self.operand.check_const()
5124 def is_py_operation(self):
5125 return self.operand.type.is_pyobject
5127 def nogil_check(self, env):
5128 if self.is_py_operation():
5131 def is_cpp_operation(self):
5132 type = self.operand.type
5133 return type.is_cpp_class
5135 def coerce_operand_to_pyobject(self, env):
5136 self.operand = self.operand.coerce_to_pyobject(env)
5138 def generate_result_code(self, code):
5139 if self.operand.type.is_pyobject:
5140 self.generate_py_operation_code(code)
5142 def generate_py_operation_code(self, code):
5143 function = self.py_operation_function()
5145 "%s = %s(%s); %s" % (
5148 self.operand.py_result(),
5149 code.error_goto_if_null(self.result(), self.pos)))
5150 code.put_gotref(self.py_result())
5152 def type_error(self):
5153 if not self.operand.type.is_error:
5154 error(self.pos, "Invalid operand type for '%s' (%s)" %
5155 (self.operator, self.operand.type))
5156 self.type = PyrexTypes.error_type
5158 def analyse_cpp_operation(self, env):
5159 type = self.operand.type
5161 type = type.base_type
5162 function = type.scope.lookup("operator%s" % self.operator)
5164 error(self.pos, "'%s' operator not defined for %s"
5165 % (self.operator, type))
5168 func_type = function.type
5169 if func_type.is_ptr:
5170 func_type = func_type.base_type
5171 self.type = func_type.return_type
5174 class NotNode(ExprNode):
5179 type = PyrexTypes.c_bint_type
5181 subexprs = ['operand']
5183 def calculate_constant_result(self):
5184 self.constant_result = not self.operand.constant_result
5186 def compile_time_value(self, denv):
5187 operand = self.operand.compile_time_value(denv)
5190 except Exception, e:
5191 self.compile_time_value_error(e)
5193 def infer_type(self, env):
5194 return PyrexTypes.c_bint_type
5196 def analyse_types(self, env):
5197 self.operand.analyse_types(env)
5198 self.operand = self.operand.coerce_to_boolean(env)
5200 def calculate_result_code(self):
5201 return "(!%s)" % self.operand.result()
5203 def generate_result_code(self, code):
5207 class UnaryPlusNode(UnopNode):
5208 # unary '+' operator
5212 def analyse_c_operation(self, env):
5213 self.type = self.operand.type
5215 def py_operation_function(self):
5216 return "PyNumber_Positive"
5218 def calculate_result_code(self):
5219 if self.is_cpp_operation():
5220 return "(+%s)" % self.operand.result()
5222 return self.operand.result()
5225 class UnaryMinusNode(UnopNode):
5226 # unary '-' operator
5230 def analyse_c_operation(self, env):
5231 if self.operand.type.is_numeric:
5232 self.type = self.operand.type
5235 if self.type.is_complex:
5238 def py_operation_function(self):
5239 return "PyNumber_Negative"
5241 def calculate_result_code(self):
5243 return "(-%s)" % self.operand.result()
5245 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
5247 def get_constant_c_result_code(self):
5248 value = self.operand.get_constant_c_result_code()
5250 return "(-%s)" % (value)
5252 class TildeNode(UnopNode):
5253 # unary '~' operator
5255 def analyse_c_operation(self, env):
5256 if self.operand.type.is_int:
5257 self.type = self.operand.type
5261 def py_operation_function(self):
5262 return "PyNumber_Invert"
5264 def calculate_result_code(self):
5265 return "(~%s)" % self.operand.result()
5268 class CUnopNode(UnopNode):
5270 def is_py_operation(self):
5273 class DereferenceNode(CUnopNode):
5278 def analyse_c_operation(self, env):
5279 if self.operand.type.is_ptr:
5280 self.type = self.operand.type.base_type
5284 def calculate_result_code(self):
5285 return "(*%s)" % self.operand.result()
5288 class DecrementIncrementNode(CUnopNode):
5289 # unary ++/-- operator
5291 def analyse_c_operation(self, env):
5292 if self.operand.type.is_ptr or self.operand.type.is_numeric:
5293 self.type = self.operand.type
5297 def calculate_result_code(self):
5299 return "(%s%s)" % (self.operator, self.operand.result())
5301 return "(%s%s)" % (self.operand.result(), self.operator)
5303 def inc_dec_constructor(is_prefix, operator):
5304 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
5307 class AmpersandNode(ExprNode):
5308 # The C address-of operator.
5312 subexprs = ['operand']
5314 def infer_type(self, env):
5315 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
5317 def analyse_types(self, env):
5318 self.operand.analyse_types(env)
5319 argtype = self.operand.type
5320 if not (argtype.is_cfunction or self.operand.is_lvalue()):
5321 self.error("Taking address of non-lvalue")
5323 if argtype.is_pyobject:
5324 self.error("Cannot take address of Python variable")
5326 self.type = PyrexTypes.c_ptr_type(argtype)
5328 def check_const(self):
5329 return self.operand.check_const_addr()
5331 def error(self, mess):
5332 error(self.pos, mess)
5333 self.type = PyrexTypes.error_type
5334 self.result_code = "<error>"
5336 def calculate_result_code(self):
5337 return "(&%s)" % self.operand.result()
5339 def generate_result_code(self, code):
5343 unop_node_classes = {
5345 "-": UnaryMinusNode,
5349 def unop_node(pos, operator, operand):
5350 # Construct unnop node of appropriate class for
5352 if isinstance(operand, IntNode) and operator == '-':
5353 return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
5354 elif isinstance(operand, UnopNode) and operand.operator == operator:
5355 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5356 return unop_node_classes[operator](pos,
5357 operator = operator,
5361 class TypecastNode(ExprNode):
5365 # base_type CBaseTypeNode
5366 # declarator CDeclaratorNode
5368 # If used from a transform, one can if wanted specify the attribute
5369 # "type" directly and leave base_type and declarator to None
5371 subexprs = ['operand']
5372 base_type = declarator = type = None
5374 def type_dependencies(self, env):
5377 def infer_type(self, env):
5378 if self.type is None:
5379 base_type = self.base_type.analyse(env)
5380 _, self.type = self.declarator.analyse(base_type, env)
5383 def analyse_types(self, env):
5384 if self.type is None:
5385 base_type = self.base_type.analyse(env)
5386 _, self.type = self.declarator.analyse(base_type, env)
5387 if self.type.is_cfunction:
5389 "Cannot cast to a function type")
5390 self.type = PyrexTypes.error_type
5391 self.operand.analyse_types(env)
5392 to_py = self.type.is_pyobject
5393 from_py = self.operand.type.is_pyobject
5394 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5395 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5396 if to_py and not from_py:
5397 if self.type is bytes_type and self.operand.type.is_int:
5398 # FIXME: the type cast node isn't needed in this case
5399 # and can be dropped once analyse_types() can return a
5401 self.operand = CoerceIntToBytesNode(self.operand, env)
5402 elif self.operand.type.can_coerce_to_pyobject(env):
5403 self.result_ctype = py_object_type
5404 self.operand = self.operand.coerce_to_pyobject(env)
5406 if self.operand.type.is_ptr:
5407 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5408 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5410 # Should this be an error?
5411 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5412 self.operand = self.operand.coerce_to_simple(env)
5413 elif from_py and not to_py:
5414 if self.type.create_from_py_utility_code(env):
5415 self.operand = self.operand.coerce_to(self.type, env)
5416 elif self.type.is_ptr:
5417 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5418 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5420 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5421 elif from_py and to_py:
5422 if self.typecheck and self.type.is_extension_type:
5423 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5424 elif self.type.is_complex and self.operand.type.is_complex:
5425 self.operand = self.operand.coerce_to_simple(env)
5427 def is_simple(self):
5428 # either temp or a C cast => no side effects
5431 def nogil_check(self, env):
5432 if self.type and self.type.is_pyobject and self.is_temp:
5435 def check_const(self):
5436 return self.operand.check_const()
5438 def calculate_constant_result(self):
5439 # we usually do not know the result of a type cast at code
5443 def calculate_result_code(self):
5444 if self.type.is_complex:
5445 operand_result = self.operand.result()
5446 if self.operand.type.is_complex:
5447 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5448 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5450 real_part = self.type.real_type.cast_code(operand_result)
5452 return "%s(%s, %s)" % (
5453 self.type.from_parts,
5457 return self.type.cast_code(self.operand.result())
5459 def get_constant_c_result_code(self):
5460 operand_result = self.operand.get_constant_c_result_code()
5462 return self.type.cast_code(operand_result)
5464 def result_as(self, type):
5465 if self.type.is_pyobject and not self.is_temp:
5466 # Optimise away some unnecessary casting
5467 return self.operand.result_as(type)
5469 return ExprNode.result_as(self, type)
5471 def generate_result_code(self, code):
5474 "%s = (PyObject *)%s;" % (
5476 self.operand.result()))
5477 code.put_incref(self.result(), self.ctype())
5480 class SizeofNode(ExprNode):
5481 # Abstract base class for sizeof(x) expression nodes.
5483 type = PyrexTypes.c_size_t_type
5485 def check_const(self):
5488 def generate_result_code(self, code):
5492 class SizeofTypeNode(SizeofNode):
5493 # C sizeof function applied to a type
5495 # base_type CBaseTypeNode
5496 # declarator CDeclaratorNode
5501 def analyse_types(self, env):
5502 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5503 # this could be better handled by more uniformly treating types as runtime-available objects
5504 if 0 and self.base_type.module_path:
5505 path = self.base_type.module_path
5506 obj = env.lookup(path[0])
5507 if obj.as_module is None:
5508 operand = NameNode(pos=self.pos, name=path[0])
5509 for attr in path[1:]:
5510 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5511 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5512 self.operand = operand
5513 self.__class__ = SizeofVarNode
5514 self.analyse_types(env)
5516 if self.arg_type is None:
5517 base_type = self.base_type.analyse(env)
5518 _, arg_type = self.declarator.analyse(base_type, env)
5519 self.arg_type = arg_type
5522 def check_type(self):
5523 arg_type = self.arg_type
5524 if arg_type.is_pyobject and not arg_type.is_extension_type:
5525 error(self.pos, "Cannot take sizeof Python object")
5526 elif arg_type.is_void:
5527 error(self.pos, "Cannot take sizeof void")
5528 elif not arg_type.is_complete():
5529 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5531 def calculate_result_code(self):
5532 if self.arg_type.is_extension_type:
5533 # the size of the pointer is boring
5534 # we want the size of the actual struct
5535 arg_code = self.arg_type.declaration_code("", deref=1)
5537 arg_code = self.arg_type.declaration_code("")
5538 return "(sizeof(%s))" % arg_code
5541 class SizeofVarNode(SizeofNode):
5542 # C sizeof function applied to a variable
5546 subexprs = ['operand']
5548 def analyse_types(self, env):
5549 # We may actually be looking at a type rather than a variable...
5550 # If we are, traditional analysis would fail...
5551 operand_as_type = self.operand.analyse_as_type(env)
5553 self.arg_type = operand_as_type
5554 self.__class__ = SizeofTypeNode
5557 self.operand.analyse_types(env)
5559 def calculate_result_code(self):
5560 return "(sizeof(%s))" % self.operand.result()
5562 def generate_result_code(self, code):
5565 class TypeofNode(ExprNode):
5566 # Compile-time type of an expression, as a string.
5569 # literal StringNode # internal
5572 type = py_object_type
5574 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5576 def analyse_types(self, env):
5577 self.operand.analyse_types(env)
5578 self.literal = StringNode(
5579 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5580 self.literal.analyse_types(env)
5581 self.literal = self.literal.coerce_to_pyobject(env)
5583 def may_be_none(self):
5586 def generate_evaluation_code(self, code):
5587 self.literal.generate_evaluation_code(code)
5589 def calculate_result_code(self):
5590 return self.literal.calculate_result_code()
5592 #-------------------------------------------------------------------
5594 # Binary operator nodes
5596 #-------------------------------------------------------------------
5598 def _not_in(x, seq):
5601 compile_time_binary_operators = {
5609 'is_not': operator.is_not,
5612 '/': operator.truediv,
5613 '//': operator.floordiv,
5614 '<<': operator.lshift,
5619 '>>': operator.rshift,
5622 'in': operator.contains,
5626 def get_compile_time_binop(node):
5627 func = compile_time_binary_operators.get(node.operator)
5630 "Binary '%s' not supported in compile-time expression"
5634 class BinopNode(ExprNode):
5639 # Processing during analyse_expressions phase:
5641 # analyse_c_operation
5642 # Called when neither operand is a pyobject.
5643 # - Check operand types and coerce if needed.
5644 # - Determine result type and result code fragment.
5645 # - Allocate temporary for result if needed.
5647 subexprs = ['operand1', 'operand2']
5650 def calculate_constant_result(self):
5651 func = compile_time_binary_operators[self.operator]
5652 self.constant_result = func(
5653 self.operand1.constant_result,
5654 self.operand2.constant_result)
5656 def compile_time_value(self, denv):
5657 func = get_compile_time_binop(self)
5658 operand1 = self.operand1.compile_time_value(denv)
5659 operand2 = self.operand2.compile_time_value(denv)
5661 return func(operand1, operand2)
5662 except Exception, e:
5663 self.compile_time_value_error(e)
5665 def infer_type(self, env):
5666 return self.result_type(self.operand1.infer_type(env),
5667 self.operand2.infer_type(env))
5669 def analyse_types(self, env):
5670 self.operand1.analyse_types(env)
5671 self.operand2.analyse_types(env)
5672 self.analyse_operation(env)
5674 def analyse_operation(self, env):
5675 if self.is_py_operation():
5676 self.coerce_operands_to_pyobjects(env)
5677 self.type = self.result_type(self.operand1.type,
5679 assert self.type.is_pyobject
5681 elif self.is_cpp_operation():
5682 self.analyse_cpp_operation(env)
5684 self.analyse_c_operation(env)
5686 def is_py_operation(self):
5687 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5689 def is_py_operation_types(self, type1, type2):
5690 return type1.is_pyobject or type2.is_pyobject
5692 def is_cpp_operation(self):
5693 return (self.operand1.type.is_cpp_class
5694 or self.operand2.type.is_cpp_class)
5696 def analyse_cpp_operation(self, env):
5697 type1 = self.operand1.type
5698 type2 = self.operand2.type
5699 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5703 func_type = entry.type
5704 if func_type.is_ptr:
5705 func_type = func_type.base_type
5706 if len(func_type.args) == 1:
5707 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5709 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5710 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5711 self.type = func_type.return_type
5713 def result_type(self, type1, type2):
5714 if self.is_py_operation_types(type1, type2):
5716 type2 = Builtin.bytes_type
5718 type1 = Builtin.bytes_type
5719 elif self.operator == '%' \
5720 and type1 in (Builtin.str_type, Builtin.unicode_type):
5721 # note that b'%s' % b'abc' doesn't work in Py3
5723 if type1.is_builtin_type:
5725 if self.operator in '**%+|&^':
5726 # FIXME: at least these operators should be safe - others?
5728 elif self.operator == '*':
5729 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5731 # multiplication of containers/numbers with an
5732 # integer value always (?) returns the same type
5735 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5736 # multiplication of containers/numbers with an
5737 # integer value always (?) returns the same type
5739 return py_object_type
5741 return self.compute_c_result_type(type1, type2)
5743 def nogil_check(self, env):
5744 if self.is_py_operation():
5747 def coerce_operands_to_pyobjects(self, env):
5748 self.operand1 = self.operand1.coerce_to_pyobject(env)
5749 self.operand2 = self.operand2.coerce_to_pyobject(env)
5751 def check_const(self):
5752 return self.operand1.check_const() and self.operand2.check_const()
5754 def generate_result_code(self, code):
5755 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5756 if self.operand1.type.is_pyobject:
5757 function = self.py_operation_function()
5758 if self.operator == '**':
5759 extra_args = ", Py_None"
5763 "%s = %s(%s, %s%s); %s" % (
5766 self.operand1.py_result(),
5767 self.operand2.py_result(),
5769 code.error_goto_if_null(self.result(), self.pos)))
5770 code.put_gotref(self.py_result())
5772 def type_error(self):
5773 if not (self.operand1.type.is_error
5774 or self.operand2.type.is_error):
5775 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5776 (self.operator, self.operand1.type,
5777 self.operand2.type))
5778 self.type = PyrexTypes.error_type
5781 class CBinopNode(BinopNode):
5783 def analyse_types(self, env):
5784 BinopNode.analyse_types(self, env)
5785 if self.is_py_operation():
5786 self.type = PyrexTypes.error_type
5788 def py_operation_function():
5791 def calculate_result_code(self):
5792 return "(%s %s %s)" % (
5793 self.operand1.result(),
5795 self.operand2.result())
5798 def c_binop_constructor(operator):
5799 def make_binop_node(pos, **operands):
5800 return CBinopNode(pos, operator=operator, **operands)
5801 return make_binop_node
5803 class NumBinopNode(BinopNode):
5804 # Binary operation taking numeric arguments.
5808 def analyse_c_operation(self, env):
5809 type1 = self.operand1.type
5810 type2 = self.operand2.type
5811 self.type = self.compute_c_result_type(type1, type2)
5815 if self.type.is_complex:
5817 if not self.infix or (type1.is_numeric and type2.is_numeric):
5818 self.operand1 = self.operand1.coerce_to(self.type, env)
5819 self.operand2 = self.operand2.coerce_to(self.type, env)
5821 def compute_c_result_type(self, type1, type2):
5822 if self.c_types_okay(type1, type2):
5823 widest_type = PyrexTypes.widest_numeric_type(type1, type2)
5824 if widest_type is PyrexTypes.c_bint_type:
5825 if self.operator not in '|^&':
5826 # False + False == 0 # not False!
5827 widest_type = PyrexTypes.c_int_type
5832 def get_constant_c_result_code(self):
5833 value1 = self.operand1.get_constant_c_result_code()
5834 value2 = self.operand2.get_constant_c_result_code()
5835 if value1 and value2:
5836 return "(%s %s %s)" % (value1, self.operator, value2)
5840 def c_types_okay(self, type1, type2):
5841 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5842 return (type1.is_numeric or type1.is_enum) \
5843 and (type2.is_numeric or type2.is_enum)
5845 def calculate_result_code(self):
5847 return "(%s %s %s)" % (
5848 self.operand1.result(),
5850 self.operand2.result())
5852 func = self.type.binary_op(self.operator)
5854 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5855 return "%s(%s, %s)" % (
5857 self.operand1.result(),
5858 self.operand2.result())
5860 def is_py_operation_types(self, type1, type2):
5861 return (type1.is_unicode_char or
5862 type2.is_unicode_char or
5863 BinopNode.is_py_operation_types(self, type1, type2))
5865 def py_operation_function(self):
5866 fuction = self.py_functions[self.operator]
5868 fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
5873 "^": "PyNumber_Xor",
5874 "&": "PyNumber_And",
5875 "<<": "PyNumber_Lshift",
5876 ">>": "PyNumber_Rshift",
5877 "+": "PyNumber_Add",
5878 "-": "PyNumber_Subtract",
5879 "*": "PyNumber_Multiply",
5880 "/": "__Pyx_PyNumber_Divide",
5881 "//": "PyNumber_FloorDivide",
5882 "%": "PyNumber_Remainder",
5883 "**": "PyNumber_Power"
5886 class IntBinopNode(NumBinopNode):
5887 # Binary operation taking integer arguments.
5889 def c_types_okay(self, type1, type2):
5890 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5891 return (type1.is_int or type1.is_enum) \
5892 and (type2.is_int or type2.is_enum)
5895 class AddNode(NumBinopNode):
5898 def is_py_operation_types(self, type1, type2):
5899 if type1.is_string and type2.is_string:
5902 return NumBinopNode.is_py_operation_types(self, type1, type2)
5904 def compute_c_result_type(self, type1, type2):
5905 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5906 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5908 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5911 return NumBinopNode.compute_c_result_type(
5915 class SubNode(NumBinopNode):
5918 def compute_c_result_type(self, type1, type2):
5919 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5921 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5922 return PyrexTypes.c_int_type
5924 return NumBinopNode.compute_c_result_type(
5928 class MulNode(NumBinopNode):
5931 def is_py_operation_types(self, type1, type2):
5932 if (type1.is_string and type2.is_int) \
5933 or (type2.is_string and type1.is_int):
5936 return NumBinopNode.is_py_operation_types(self, type1, type2)
5939 class DivNode(NumBinopNode):
5940 # '/' or '//' operator.
5943 truedivision = None # == "unknown" if operator == '/'
5944 ctruedivision = False
5945 cdivision_warnings = False
5946 zerodivision_check = None
5948 def find_compile_time_binary_operator(self, op1, op2):
5949 func = compile_time_binary_operators[self.operator]
5950 if self.operator == '/' and self.truedivision is None:
5951 # => true div for floats, floor div for integers
5952 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5953 func = compile_time_binary_operators['//']
5956 def calculate_constant_result(self):
5957 op1 = self.operand1.constant_result
5958 op2 = self.operand2.constant_result
5959 func = self.find_compile_time_binary_operator(op1, op2)
5960 self.constant_result = func(
5961 self.operand1.constant_result,
5962 self.operand2.constant_result)
5964 def compile_time_value(self, denv):
5965 operand1 = self.operand1.compile_time_value(denv)
5966 operand2 = self.operand2.compile_time_value(denv)
5968 func = self.find_compile_time_binary_operator(
5969 self, operand1, operand2)
5970 return func(operand1, operand2)
5971 except Exception, e:
5972 self.compile_time_value_error(e)
5974 def analyse_operation(self, env):
5975 if self.cdivision or env.directives['cdivision']:
5976 self.ctruedivision = False
5978 self.ctruedivision = self.truedivision
5979 NumBinopNode.analyse_operation(self, env)
5980 if self.is_cpp_operation():
5981 self.cdivision = True
5982 if not self.type.is_pyobject:
5983 self.zerodivision_check = (
5984 self.cdivision is None and not env.directives['cdivision']
5985 and (not self.operand2.has_constant_result() or
5986 self.operand2.constant_result == 0))
5987 if self.zerodivision_check or env.directives['cdivision_warnings']:
5988 # Need to check ahead of time to warn or raise zero division error
5989 self.operand1 = self.operand1.coerce_to_simple(env)
5990 self.operand2 = self.operand2.coerce_to_simple(env)
5992 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5994 def compute_c_result_type(self, type1, type2):
5995 if self.operator == '/' and self.ctruedivision:
5996 if not type1.is_float and not type2.is_float:
5997 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5998 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
6000 return NumBinopNode.compute_c_result_type(self, type1, type2)
6002 def zero_division_message(self):
6003 if self.type.is_int:
6004 return "integer division or modulo by zero"
6006 return "float division"
6008 def generate_evaluation_code(self, code):
6009 if not self.type.is_pyobject and not self.type.is_complex:
6010 if self.cdivision is None:
6011 self.cdivision = (code.globalstate.directives['cdivision']
6012 or not self.type.signed
6013 or self.type.is_float)
6014 if not self.cdivision:
6015 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
6016 NumBinopNode.generate_evaluation_code(self, code)
6017 self.generate_div_warning_code(code)
6019 def generate_div_warning_code(self, code):
6020 if not self.type.is_pyobject:
6021 if self.zerodivision_check:
6023 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
6025 zero_test = "%s == 0" % self.operand2.result()
6026 code.putln("if (unlikely(%s)) {" % zero_test)
6027 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
6028 code.putln(code.error_goto(self.pos))
6030 if self.type.is_int and self.type.signed and self.operator != '%':
6031 code.globalstate.use_utility_code(division_overflow_test_code)
6032 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6033 self.type.declaration_code(''),
6034 self.operand2.result(),
6035 self.operand1.result()))
6036 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
6037 code.putln(code.error_goto(self.pos))
6039 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6040 code.globalstate.use_utility_code(cdivision_warning_utility_code)
6041 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
6042 self.operand1.result(),
6043 self.operand2.result()))
6044 code.putln(code.set_error_info(self.pos));
6045 code.put("if (__Pyx_cdivision_warning()) ")
6046 code.put_goto(code.error_label)
6049 def calculate_result_code(self):
6050 if self.type.is_complex:
6051 return NumBinopNode.calculate_result_code(self)
6052 elif self.type.is_float and self.operator == '//':
6053 return "floor(%s / %s)" % (
6054 self.operand1.result(),
6055 self.operand2.result())
6056 elif self.truedivision or self.cdivision:
6057 op1 = self.operand1.result()
6058 op2 = self.operand2.result()
6059 if self.truedivision:
6060 if self.type != self.operand1.type:
6061 op1 = self.type.cast_code(op1)
6062 if self.type != self.operand2.type:
6063 op2 = self.type.cast_code(op2)
6064 return "(%s / %s)" % (op1, op2)
6066 return "__Pyx_div_%s(%s, %s)" % (
6067 self.type.specialization_name(),
6068 self.operand1.result(),
6069 self.operand2.result())
6072 class ModNode(DivNode):
6075 def is_py_operation_types(self, type1, type2):
6076 return (type1.is_string
6078 or NumBinopNode.is_py_operation_types(self, type1, type2))
6080 def zero_division_message(self):
6081 if self.type.is_int:
6082 return "integer division or modulo by zero"
6084 return "float divmod()"
6086 def generate_evaluation_code(self, code):
6087 if not self.type.is_pyobject:
6088 if self.cdivision is None:
6089 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
6090 if not self.cdivision:
6091 if self.type.is_int:
6092 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6094 code.globalstate.use_utility_code(
6095 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6096 NumBinopNode.generate_evaluation_code(self, code)
6097 self.generate_div_warning_code(code)
6099 def calculate_result_code(self):
6101 if self.type.is_float:
6102 return "fmod%s(%s, %s)" % (
6103 self.type.math_h_modifier,
6104 self.operand1.result(),
6105 self.operand2.result())
6107 return "(%s %% %s)" % (
6108 self.operand1.result(),
6109 self.operand2.result())
6111 return "__Pyx_mod_%s(%s, %s)" % (
6112 self.type.specialization_name(),
6113 self.operand1.result(),
6114 self.operand2.result())
6116 class PowNode(NumBinopNode):
6119 def analyse_c_operation(self, env):
6120 NumBinopNode.analyse_c_operation(self, env)
6121 if self.type.is_complex:
6122 if self.type.real_type.is_float:
6123 self.operand1 = self.operand1.coerce_to(self.type, env)
6124 self.operand2 = self.operand2.coerce_to(self.type, env)
6125 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
6127 error(self.pos, "complex int powers not supported")
6128 self.pow_func = "<error>"
6129 elif self.type.is_float:
6130 self.pow_func = "pow" + self.type.math_h_modifier
6132 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
6133 env.use_utility_code(
6134 int_pow_utility_code.specialize(func_name=self.pow_func,
6135 type=self.type.declaration_code('')))
6137 def calculate_result_code(self):
6138 # Work around MSVC overloading ambiguity.
6139 def typecast(operand):
6140 if self.type == operand.type:
6141 return operand.result()
6143 return self.type.cast_code(operand.result())
6144 return "%s(%s, %s)" % (
6146 typecast(self.operand1),
6147 typecast(self.operand2))
6150 # Note: This class is temporarily "shut down" into an ineffective temp
6153 # More sophisticated temp reuse was going on before, one could have a
6154 # look at adding this again after /all/ classes are converted to the
6155 # new temp scheme. (The temp juggling cannot work otherwise).
6156 class BoolBinopNode(ExprNode):
6157 # Short-circuiting boolean operation.
6163 subexprs = ['operand1', 'operand2']
6165 def infer_type(self, env):
6166 type1 = self.operand1.infer_type(env)
6167 type2 = self.operand2.infer_type(env)
6168 return PyrexTypes.independent_spanning_type(type1, type2)
6170 def may_be_none(self):
6171 if self.operator == 'or':
6172 return self.operand2.may_be_none()
6174 return self.operand1.may_be_none() or self.operand2.may_be_none()
6176 def calculate_constant_result(self):
6177 if self.operator == 'and':
6178 self.constant_result = \
6179 self.operand1.constant_result and \
6180 self.operand2.constant_result
6182 self.constant_result = \
6183 self.operand1.constant_result or \
6184 self.operand2.constant_result
6186 def compile_time_value(self, denv):
6187 if self.operator == 'and':
6188 return self.operand1.compile_time_value(denv) \
6189 and self.operand2.compile_time_value(denv)
6191 return self.operand1.compile_time_value(denv) \
6192 or self.operand2.compile_time_value(denv)
6194 def coerce_to_boolean(self, env):
6195 return BoolBinopNode(
6197 operator = self.operator,
6198 operand1 = self.operand1.coerce_to_boolean(env),
6199 operand2 = self.operand2.coerce_to_boolean(env),
6200 type = PyrexTypes.c_bint_type,
6201 is_temp = self.is_temp)
6203 def analyse_types(self, env):
6204 self.operand1.analyse_types(env)
6205 self.operand2.analyse_types(env)
6206 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6207 self.operand1 = self.operand1.coerce_to(self.type, env)
6208 self.operand2 = self.operand2.coerce_to(self.type, env)
6210 # For what we're about to do, it's vital that
6211 # both operands be temp nodes.
6212 self.operand1 = self.operand1.coerce_to_simple(env)
6213 self.operand2 = self.operand2.coerce_to_simple(env)
6216 gil_message = "Truth-testing Python object"
6218 def check_const(self):
6219 return self.operand1.check_const() and self.operand2.check_const()
6221 def generate_evaluation_code(self, code):
6222 code.mark_pos(self.pos)
6223 self.operand1.generate_evaluation_code(code)
6224 test_result, uses_temp = self.generate_operand1_test(code)
6225 if self.operator == 'and':
6234 code.funcstate.release_temp(test_result)
6235 self.operand1.generate_disposal_code(code)
6236 self.operand2.generate_evaluation_code(code)
6237 self.allocate_temp_result(code)
6238 self.operand2.make_owned_reference(code)
6239 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6240 self.operand2.generate_post_assignment_code(code)
6241 self.operand2.free_temps(code)
6242 code.putln("} else {")
6243 self.operand1.make_owned_reference(code)
6244 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6245 self.operand1.generate_post_assignment_code(code)
6246 self.operand1.free_temps(code)
6249 def generate_operand1_test(self, code):
6250 # Generate code to test the truth of the first operand.
6251 if self.type.is_pyobject:
6252 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
6255 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6257 self.operand1.py_result(),
6258 code.error_goto_if_neg(test_result, self.pos)))
6260 test_result = self.operand1.result()
6261 return (test_result, self.type.is_pyobject)
6264 class CondExprNode(ExprNode):
6265 # Short-circuiting conditional expression.
6269 # false_val ExprNode
6274 subexprs = ['test', 'true_val', 'false_val']
6276 def type_dependencies(self, env):
6277 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6279 def infer_type(self, env):
6280 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
6281 self.false_val.infer_type(env))
6283 def calculate_constant_result(self):
6284 if self.test.constant_result:
6285 self.constant_result = self.true_val.constant_result
6287 self.constant_result = self.false_val.constant_result
6289 def analyse_types(self, env):
6290 self.test.analyse_types(env)
6291 self.test = self.test.coerce_to_boolean(env)
6292 self.true_val.analyse_types(env)
6293 self.false_val.analyse_types(env)
6294 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6295 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
6296 self.true_val = self.true_val.coerce_to(self.type, env)
6297 self.false_val = self.false_val.coerce_to(self.type, env)
6299 if self.type == PyrexTypes.error_type:
6302 def type_error(self):
6303 if not (self.true_val.type.is_error or self.false_val.type.is_error):
6304 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
6305 (self.true_val.type, self.false_val.type))
6306 self.type = PyrexTypes.error_type
6308 def check_const(self):
6309 return (self.test.check_const()
6310 and self.true_val.check_const()
6311 and self.false_val.check_const())
6313 def generate_evaluation_code(self, code):
6314 # Because subexprs may not be evaluated we can use a more optimal
6315 # subexpr allocation strategy than the default, so override evaluation_code.
6317 code.mark_pos(self.pos)
6318 self.allocate_temp_result(code)
6319 self.test.generate_evaluation_code(code)
6320 code.putln("if (%s) {" % self.test.result() )
6321 self.eval_and_get(code, self.true_val)
6322 code.putln("} else {")
6323 self.eval_and_get(code, self.false_val)
6325 self.test.generate_disposal_code(code)
6326 self.test.free_temps(code)
6328 def eval_and_get(self, code, expr):
6329 expr.generate_evaluation_code(code)
6330 expr.make_owned_reference(code)
6331 code.putln("%s = %s;" % (self.result(), expr.result()))
6332 expr.generate_post_assignment_code(code)
6333 expr.free_temps(code)
6335 richcmp_constants = {
6345 class CmpNode(object):
6346 # Mixin class containing code common to PrimaryCmpNodes
6347 # and CascadedCmpNodes.
6349 special_bool_cmp_function = None
6351 def infer_type(self, env):
6352 # TODO: Actually implement this (after merging with -unstable).
6353 return py_object_type
6355 def calculate_cascaded_constant_result(self, operand1_result):
6356 func = compile_time_binary_operators[self.operator]
6357 operand2_result = self.operand2.constant_result
6358 result = func(operand1_result, operand2_result)
6360 self.cascade.calculate_cascaded_constant_result(operand2_result)
6361 if self.cascade.constant_result:
6362 self.constant_result = result and self.cascade.constant_result
6364 self.constant_result = result
6366 def cascaded_compile_time_value(self, operand1, denv):
6367 func = get_compile_time_binop(self)
6368 operand2 = self.operand2.compile_time_value(denv)
6370 result = func(operand1, operand2)
6371 except Exception, e:
6372 self.compile_time_value_error(e)
6375 cascade = self.cascade
6377 # FIXME: I bet this must call cascaded_compile_time_value()
6378 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6381 def is_cpp_comparison(self):
6382 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6384 def find_common_int_type(self, env, op, operand1, operand2):
6385 # type1 != type2 and at least one of the types is not a C int
6386 type1 = operand1.type
6387 type2 = operand2.type
6388 type1_can_be_int = False
6389 type2_can_be_int = False
6391 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6392 and operand1.can_coerce_to_char_literal():
6393 type1_can_be_int = True
6394 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6395 and operand2.can_coerce_to_char_literal():
6396 type2_can_be_int = True
6399 if type2_can_be_int:
6402 if type1_can_be_int:
6404 elif type1_can_be_int:
6405 if type2_can_be_int:
6406 return PyrexTypes.c_uchar_type
6410 def find_common_type(self, env, op, operand1, common_type=None):
6411 operand2 = self.operand2
6412 type1 = operand1.type
6413 type2 = operand2.type
6415 new_common_type = None
6417 # catch general errors
6418 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6419 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6420 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6421 new_common_type = error_type
6423 # try to use numeric comparisons where possible
6424 elif type1.is_complex or type2.is_complex:
6425 if op not in ('==', '!='):
6426 error(self.pos, "complex types are unordered")
6427 new_common_type = error_type
6428 if type1.is_pyobject:
6429 new_common_type = type1
6430 elif type2.is_pyobject:
6431 new_common_type = type2
6433 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6434 elif type1.is_numeric and type2.is_numeric:
6435 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6436 elif common_type is None or not common_type.is_pyobject:
6437 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6439 if new_common_type is None:
6440 # fall back to generic type compatibility tests
6442 new_common_type = type1
6443 elif type1.is_pyobject or type2.is_pyobject:
6444 if type2.is_numeric or type2.is_string:
6445 if operand2.check_for_coercion_error(type1):
6446 new_common_type = error_type
6448 new_common_type = py_object_type
6449 elif type1.is_numeric or type1.is_string:
6450 if operand1.check_for_coercion_error(type2):
6451 new_common_type = error_type
6453 new_common_type = py_object_type
6454 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6455 new_common_type = py_object_type
6457 # one Python type and one non-Python type, not assignable
6458 self.invalid_types_error(operand1, op, operand2)
6459 new_common_type = error_type
6460 elif type1.assignable_from(type2):
6461 new_common_type = type1
6462 elif type2.assignable_from(type1):
6463 new_common_type = type2
6465 # C types that we couldn't handle up to here are an error
6466 self.invalid_types_error(operand1, op, operand2)
6467 new_common_type = error_type
6469 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6470 isinstance(operand2, BytesNode)):
6471 # special case when comparing char* to bytes literal: must
6472 # compare string values!
6473 new_common_type = bytes_type
6475 # recursively merge types
6476 if common_type is None or new_common_type.is_error:
6477 common_type = new_common_type
6479 # we could do a lot better by splitting the comparison
6480 # into a non-Python part and a Python part, but this is
6482 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6485 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6489 def invalid_types_error(self, operand1, op, operand2):
6490 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6491 (op, operand1.type, operand2.type))
6493 def is_python_comparison(self):
6494 return (not self.is_ptr_contains()
6495 and not self.is_c_string_contains()
6496 and (self.has_python_operands()
6497 or (self.cascade and self.cascade.is_python_comparison())
6498 or self.operator in ('in', 'not_in')))
6500 def coerce_operands_to(self, dst_type, env):
6501 operand2 = self.operand2
6502 if operand2.type != dst_type:
6503 self.operand2 = operand2.coerce_to(dst_type, env)
6505 self.cascade.coerce_operands_to(dst_type, env)
6507 def is_python_result(self):
6508 return ((self.has_python_operands() and
6509 self.special_bool_cmp_function is None and
6510 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6511 not self.is_c_string_contains() and
6512 not self.is_ptr_contains())
6513 or (self.cascade and self.cascade.is_python_result()))
6515 def is_c_string_contains(self):
6516 return self.operator in ('in', 'not_in') and \
6517 ((self.operand1.type.is_int
6518 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6519 (self.operand1.type.is_unicode_char
6520 and self.operand2.type is unicode_type))
6522 def is_ptr_contains(self):
6523 if self.operator in ('in', 'not_in'):
6524 container_type = self.operand2.type
6525 return (container_type.is_ptr or container_type.is_array) \
6526 and not container_type.is_string
6528 def find_special_bool_compare_function(self, env):
6529 if self.operator in ('==', '!='):
6530 type1, type2 = self.operand1.type, self.operand2.type
6531 if type1.is_pyobject and type2.is_pyobject:
6532 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6533 env.use_utility_code(pyunicode_equals_utility_code)
6534 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6538 def generate_operation_code(self, code, result_code,
6539 operand1, op , operand2):
6540 if self.type.is_pyobject:
6541 coerce_result = "__Pyx_PyBool_FromLong"
6548 if self.special_bool_cmp_function:
6549 if operand1.type.is_pyobject:
6550 result1 = operand1.py_result()
6552 result1 = operand1.result()
6553 if operand2.type.is_pyobject:
6554 result2 = operand2.py_result()
6556 result2 = operand2.result()
6557 code.putln("%s = %s(%s, %s, %s); %s" % (
6559 self.special_bool_cmp_function,
6562 richcmp_constants[op],
6563 code.error_goto_if_neg(result_code, self.pos)))
6564 elif op == 'in' or op == 'not_in':
6565 code.globalstate.use_utility_code(contains_utility_code)
6566 if self.type.is_pyobject:
6567 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6569 negation = "__Pyx_NegateNonNeg"
6570 if operand2.type is dict_type:
6571 method = "PyDict_Contains"
6573 method = "PySequence_Contains"
6574 if self.type.is_pyobject:
6575 error_clause = code.error_goto_if_null
6576 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6578 error_clause = code.error_goto_if_neg
6581 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6586 operand2.py_result(),
6587 operand1.py_result(),
6589 error_clause(result_code, self.pos)))
6590 elif (operand1.type.is_pyobject
6591 and op not in ('is', 'is_not')):
6592 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6594 operand1.py_result(),
6595 operand2.py_result(),
6596 richcmp_constants[op],
6597 code.error_goto_if_null(result_code, self.pos)))
6598 code.put_gotref(result_code)
6599 elif operand1.type.is_complex:
6604 code.putln("%s = %s(%s%s(%s, %s));" % (
6608 operand1.type.unary_op('eq'),
6612 type1 = operand1.type
6613 type2 = operand2.type
6614 if (type1.is_extension_type or type2.is_extension_type) \
6615 and not type1.same_as(type2):
6616 common_type = py_object_type
6617 elif type1.is_numeric:
6618 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6621 code1 = operand1.result_as(common_type)
6622 code2 = operand2.result_as(common_type)
6623 code.putln("%s = %s(%s %s %s);" % (
6627 self.c_operator(op),
6630 def c_operator(self, op):
6633 elif op == 'is_not':
6638 contains_utility_code = UtilityCode(
6640 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6641 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6642 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6646 char_in_bytes_utility_code = UtilityCode(
6648 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6651 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6652 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6653 char* char_start = PyBytes_AS_STRING(bytes);
6655 for (pos=char_start; pos < char_start+length; pos++) {
6656 if (character == pos[0]) return 1;
6662 pyunicode_in_unicode_utility_code = UtilityCode(
6664 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6667 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6669 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6670 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6672 for (pos=char_start; pos < char_start+length; pos++) {
6673 if (unlikely(character == pos[0])) return 1;
6679 py_ucs4_in_unicode_utility_code = UtilityCode(
6681 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
6683 # additionally handles surrogate pairs in 16bit Unicode builds
6685 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
6688 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6689 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6691 #if Py_UNICODE_SIZE == 2
6692 if (unlikely(character > 65535)) {
6693 Py_UNICODE high_val, low_val;
6694 high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
6695 low_val = (Py_UNICODE) (0xDC00 | ( (character - 0x10000) & ((1<<10)-1)));
6696 for (pos=char_start; pos < char_start+length-1; pos++) {
6697 if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
6702 uchar = (Py_UNICODE) character;
6703 for (pos=char_start; pos < char_start+length; pos++) {
6704 if (unlikely(uchar == pos[0])) return 1;
6710 pyunicode_equals_utility_code = UtilityCode(
6712 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6715 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6716 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6717 return (equals == Py_EQ);
6718 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6719 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6720 return (equals == Py_NE);
6721 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6722 if (equals == Py_EQ)
6723 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6725 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6727 int result = PyUnicode_Compare(s1, s2);
6728 if ((result == -1) && unlikely(PyErr_Occurred()))
6730 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6732 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6733 return (equals == Py_EQ);
6734 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6735 return (equals == Py_NE);
6736 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6737 return (equals == Py_NE);
6740 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6743 result = __Pyx_PyObject_IsTrue(py_result);
6744 Py_DECREF(py_result);
6751 class PrimaryCmpNode(ExprNode, CmpNode):
6752 # Non-cascaded comparison or first comparison of
6753 # a cascaded sequence.
6758 # cascade CascadedCmpNode
6760 # We don't use the subexprs mechanism, because
6761 # things here are too complicated for it to handle.
6762 # Instead, we override all the framework methods
6765 child_attrs = ['operand1', 'operand2', 'cascade']
6769 def infer_type(self, env):
6770 # TODO: Actually implement this (after merging with -unstable).
6771 return py_object_type
6773 def type_dependencies(self, env):
6776 def calculate_constant_result(self):
6777 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6779 def compile_time_value(self, denv):
6780 operand1 = self.operand1.compile_time_value(denv)
6781 return self.cascaded_compile_time_value(operand1, denv)
6783 def analyse_types(self, env):
6784 self.operand1.analyse_types(env)
6785 self.operand2.analyse_types(env)
6786 if self.is_cpp_comparison():
6787 self.analyse_cpp_comparison(env)
6789 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6792 self.cascade.analyse_types(env)
6794 if self.operator in ('in', 'not_in'):
6795 if self.is_c_string_contains():
6796 self.is_pycmp = False
6799 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6801 if self.operand2.type is unicode_type:
6802 self.uchar_test_type = PyrexTypes.widest_numeric_type(
6803 self.operand1.type, PyrexTypes.c_py_unicode_type)
6804 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
6805 env.use_utility_code(pyunicode_in_unicode_utility_code)
6807 env.use_utility_code(py_ucs4_in_unicode_utility_code)
6809 if self.operand1.type is PyrexTypes.c_uchar_type:
6810 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6811 if self.operand2.type is not bytes_type:
6812 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6813 env.use_utility_code(char_in_bytes_utility_code)
6814 self.operand2 = self.operand2.as_none_safe_node(
6815 "argument of type 'NoneType' is not iterable")
6816 elif self.is_ptr_contains():
6818 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6819 self.type = PyrexTypes.c_bint_type
6820 # Will be transformed by IterationTransform
6823 if self.operand2.type is dict_type:
6824 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6825 common_type = py_object_type
6826 self.is_pycmp = True
6827 elif self.find_special_bool_compare_function(env):
6828 common_type = None # if coercion needed, the method call above has already done it
6829 self.is_pycmp = False # result is bint
6830 self.is_temp = True # must check for error return
6832 common_type = self.find_common_type(env, self.operator, self.operand1)
6833 self.is_pycmp = common_type.is_pyobject
6835 if common_type is not None and not common_type.is_error:
6836 if self.operand1.type != common_type:
6837 self.operand1 = self.operand1.coerce_to(common_type, env)
6838 self.coerce_operands_to(common_type, env)
6841 self.operand2 = self.operand2.coerce_to_simple(env)
6842 self.cascade.coerce_cascaded_operands_to_temp(env)
6843 if self.is_python_result():
6844 self.type = PyrexTypes.py_object_type
6846 self.type = PyrexTypes.c_bint_type
6849 cdr.type = self.type
6851 if self.is_pycmp or self.cascade:
6854 def analyse_cpp_comparison(self, env):
6855 type1 = self.operand1.type
6856 type2 = self.operand2.type
6857 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6859 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6860 (self.operator, type1, type2))
6861 self.type = PyrexTypes.error_type
6862 self.result_code = "<error>"
6864 func_type = entry.type
6865 if func_type.is_ptr:
6866 func_type = func_type.base_type
6867 if len(func_type.args) == 1:
6868 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6870 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6871 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6872 self.type = func_type.return_type
6874 def has_python_operands(self):
6875 return (self.operand1.type.is_pyobject
6876 or self.operand2.type.is_pyobject)
6878 def check_const(self):
6883 return self.operand1.check_const() and self.operand2.check_const()
6885 def calculate_result_code(self):
6886 if self.operand1.type.is_complex:
6887 if self.operator == "!=":
6891 return "(%s%s(%s, %s))" % (
6893 self.operand1.type.binary_op('=='),
6894 self.operand1.result(),
6895 self.operand2.result())
6896 elif self.is_c_string_contains():
6897 if self.operand2.type is unicode_type:
6898 if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
6899 method = "__Pyx_UnicodeContains"
6901 method = "__Pyx_UnicodeContainsUCS4"
6903 method = "__Pyx_BytesContains"
6904 if self.operator == "not_in":
6908 return "(%s%s(%s, %s))" % (
6911 self.operand2.result(),
6912 self.operand1.result())
6914 return "(%s %s %s)" % (
6915 self.operand1.result(),
6916 self.c_operator(self.operator),
6917 self.operand2.result())
6919 def generate_evaluation_code(self, code):
6920 self.operand1.generate_evaluation_code(code)
6921 self.operand2.generate_evaluation_code(code)
6923 self.allocate_temp_result(code)
6924 self.generate_operation_code(code, self.result(),
6925 self.operand1, self.operator, self.operand2)
6927 self.cascade.generate_evaluation_code(code,
6928 self.result(), self.operand2)
6929 self.operand1.generate_disposal_code(code)
6930 self.operand1.free_temps(code)
6931 self.operand2.generate_disposal_code(code)
6932 self.operand2.free_temps(code)
6934 def generate_subexpr_disposal_code(self, code):
6935 # If this is called, it is a non-cascaded cmp,
6936 # so only need to dispose of the two main operands.
6937 self.operand1.generate_disposal_code(code)
6938 self.operand2.generate_disposal_code(code)
6940 def free_subexpr_temps(self, code):
6941 # If this is called, it is a non-cascaded cmp,
6942 # so only need to dispose of the two main operands.
6943 self.operand1.free_temps(code)
6944 self.operand2.free_temps(code)
6946 def annotate(self, code):
6947 self.operand1.annotate(code)
6948 self.operand2.annotate(code)
6950 self.cascade.annotate(code)
6953 class CascadedCmpNode(Node, CmpNode):
6954 # A CascadedCmpNode is not a complete expression node. It
6955 # hangs off the side of another comparison node, shares
6956 # its left operand with that node, and shares its result
6957 # with the PrimaryCmpNode at the head of the chain.
6961 # cascade CascadedCmpNode
6963 child_attrs = ['operand2', 'cascade']
6966 constant_result = constant_value_not_set # FIXME: where to calculate this?
6968 def infer_type(self, env):
6969 # TODO: Actually implement this (after merging with -unstable).
6970 return py_object_type
6972 def type_dependencies(self, env):
6975 def has_constant_result(self):
6976 return self.constant_result is not constant_value_not_set and \
6977 self.constant_result is not not_a_constant
6979 def analyse_types(self, env):
6980 self.operand2.analyse_types(env)
6982 self.cascade.analyse_types(env)
6984 def has_python_operands(self):
6985 return self.operand2.type.is_pyobject
6987 def coerce_operands_to_pyobjects(self, env):
6988 self.operand2 = self.operand2.coerce_to_pyobject(env)
6989 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
6990 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6992 self.cascade.coerce_operands_to_pyobjects(env)
6994 def coerce_cascaded_operands_to_temp(self, env):
6996 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6997 self.operand2 = self.operand2.coerce_to_simple(env)
6998 self.cascade.coerce_cascaded_operands_to_temp(env)
7000 def generate_evaluation_code(self, code, result, operand1):
7001 if self.type.is_pyobject:
7002 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
7003 code.put_decref(result, self.type)
7005 code.putln("if (%s) {" % result)
7006 self.operand2.generate_evaluation_code(code)
7007 self.generate_operation_code(code, result,
7008 operand1, self.operator, self.operand2)
7010 self.cascade.generate_evaluation_code(
7011 code, result, self.operand2)
7012 # Cascaded cmp result is always temp
7013 self.operand2.generate_disposal_code(code)
7014 self.operand2.free_temps(code)
7017 def annotate(self, code):
7018 self.operand2.annotate(code)
7020 self.cascade.annotate(code)
7023 binop_node_classes = {
7024 "or": BoolBinopNode,
7025 "and": BoolBinopNode,
7040 def binop_node(pos, operator, operand1, operand2, inplace=False):
7041 # Construct binop node of appropriate class for
7043 return binop_node_classes[operator](pos,
7044 operator = operator,
7045 operand1 = operand1,
7046 operand2 = operand2,
7049 #-------------------------------------------------------------------
7053 # Coercion nodes are special in that they are created during
7054 # the analyse_types phase of parse tree processing.
7055 # Their __init__ methods consequently incorporate some aspects
7058 #-------------------------------------------------------------------
7060 class CoercionNode(ExprNode):
7061 # Abstract base class for coercion nodes.
7063 # arg ExprNode node being coerced
7066 constant_result = not_a_constant
7068 def __init__(self, arg):
7072 print("%s Coercing %s" % (self, self.arg))
7074 def calculate_constant_result(self):
7075 # constant folding can break type coercion, so this is disabled
7078 def annotate(self, code):
7079 self.arg.annotate(code)
7080 if self.arg.type != self.type:
7081 file, line, col = self.pos
7082 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
7085 class CastNode(CoercionNode):
7086 # Wrap a node in a C type cast.
7088 def __init__(self, arg, new_type):
7089 CoercionNode.__init__(self, arg)
7090 self.type = new_type
7092 def may_be_none(self):
7093 return self.arg.may_be_none()
7095 def calculate_result_code(self):
7096 return self.arg.result_as(self.type)
7098 def generate_result_code(self, code):
7099 self.arg.generate_result_code(code)
7102 class PyTypeTestNode(CoercionNode):
7103 # This node is used to check that a generic Python
7104 # object is an instance of a particular extension type.
7105 # This node borrows the result of its argument node.
7107 def __init__(self, arg, dst_type, env, notnone=False):
7108 # The arg is know to be a Python object, and
7109 # the dst_type is known to be an extension type.
7110 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
7111 CoercionNode.__init__(self, arg)
7112 self.type = dst_type
7113 self.result_ctype = arg.ctype()
7114 self.notnone = notnone
7116 nogil_check = Node.gil_error
7117 gil_message = "Python type test"
7119 def analyse_types(self, env):
7122 def may_be_none(self):
7125 return self.arg.may_be_none()
7127 def is_simple(self):
7128 return self.arg.is_simple()
7130 def result_in_temp(self):
7131 return self.arg.result_in_temp()
7133 def is_ephemeral(self):
7134 return self.arg.is_ephemeral()
7136 def calculate_constant_result(self):
7140 def calculate_result_code(self):
7141 return self.arg.result()
7143 def generate_result_code(self, code):
7144 if self.type.typeobj_is_available():
7145 if not self.type.is_builtin_type:
7146 code.globalstate.use_utility_code(type_test_utility_code)
7149 self.type.type_test_code(self.arg.py_result(), self.notnone),
7150 code.error_goto(self.pos)))
7152 error(self.pos, "Cannot test type of extern C class "
7153 "without type object name specification")
7155 def generate_post_assignment_code(self, code):
7156 self.arg.generate_post_assignment_code(code)
7158 def free_temps(self, code):
7159 self.arg.free_temps(code)
7162 class NoneCheckNode(CoercionNode):
7163 # This node is used to check that a Python object is not None and
7164 # raises an appropriate exception (as specified by the creating
7167 def __init__(self, arg, exception_type_cname, exception_message):
7168 CoercionNode.__init__(self, arg)
7169 self.type = arg.type
7170 self.result_ctype = arg.ctype()
7171 self.exception_type_cname = exception_type_cname
7172 self.exception_message = exception_message
7174 def analyse_types(self, env):
7177 def may_be_none(self):
7180 def is_simple(self):
7181 return self.arg.is_simple()
7183 def result_in_temp(self):
7184 return self.arg.result_in_temp()
7186 def calculate_result_code(self):
7187 return self.arg.result()
7189 def generate_result_code(self, code):
7191 "if (unlikely(%s == Py_None)) {" % self.arg.result())
7192 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
7193 self.exception_type_cname,
7194 StringEncoding.escape_byte_string(
7195 self.exception_message.encode('UTF-8')),
7196 code.error_goto(self.pos)))
7199 def generate_post_assignment_code(self, code):
7200 self.arg.generate_post_assignment_code(code)
7202 def free_temps(self, code):
7203 self.arg.free_temps(code)
7206 class CoerceToPyTypeNode(CoercionNode):
7207 # This node is used to convert a C data type
7208 # to a Python object.
7210 type = py_object_type
7213 def __init__(self, arg, env, type=py_object_type):
7214 CoercionNode.__init__(self, arg)
7215 if not arg.type.create_to_py_utility_code(env):
7217 "Cannot convert '%s' to Python object" % arg.type)
7218 if type is py_object_type:
7219 # be specific about some known types
7220 if arg.type.is_string:
7221 self.type = bytes_type
7222 elif arg.type.is_unicode_char:
7223 self.type = unicode_type
7224 elif arg.type.is_complex:
7225 self.type = Builtin.complex_type
7227 # FIXME: check that the target type and the resulting type are compatible
7230 gil_message = "Converting to Python object"
7232 def may_be_none(self):
7233 # FIXME: is this always safe?
7236 def coerce_to_boolean(self, env):
7237 arg_type = self.arg.type
7238 if (arg_type == PyrexTypes.c_bint_type or
7239 (arg_type.is_pyobject and arg_type.name == 'bool')):
7240 return self.arg.coerce_to_temp(env)
7242 return CoerceToBooleanNode(self, env)
7244 def coerce_to_integer(self, env):
7245 # If not already some C integer type, coerce to longint.
7246 if self.arg.type.is_int:
7249 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7251 def analyse_types(self, env):
7252 # The arg is always already analysed
7255 def generate_result_code(self, code):
7256 function = self.arg.type.to_py_function
7257 code.putln('%s = %s(%s); %s' % (
7261 code.error_goto_if_null(self.result(), self.pos)))
7262 code.put_gotref(self.py_result())
7265 class CoerceIntToBytesNode(CoerceToPyTypeNode):
7266 # This node is used to convert a C int type to a Python bytes
7271 def __init__(self, arg, env):
7272 arg = arg.coerce_to_simple(env)
7273 CoercionNode.__init__(self, arg)
7274 self.type = Builtin.bytes_type
7276 def generate_result_code(self, code):
7278 arg_result = arg.result()
7279 if arg.type not in (PyrexTypes.c_char_type,
7280 PyrexTypes.c_uchar_type,
7281 PyrexTypes.c_schar_type):
7283 code.putln("if ((%s < 0) || (%s > 255)) {" % (
7284 arg_result, arg_result))
7286 code.putln("if (%s > 255) {" % arg_result)
7287 code.putln('PyErr_Format(PyExc_OverflowError, '
7288 '"value too large to pack into a byte"); %s' % (
7289 code.error_goto(self.pos)))
7292 if arg.type is not PyrexTypes.c_char_type:
7293 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
7294 code.putln("%s = (char)%s;" % (temp, arg_result))
7296 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
7299 code.error_goto_if_null(self.result(), self.pos)))
7300 if temp is not None:
7301 code.funcstate.release_temp(temp)
7302 code.put_gotref(self.py_result())
7305 class CoerceFromPyTypeNode(CoercionNode):
7306 # This node is used to convert a Python object
7309 def __init__(self, result_type, arg, env):
7310 CoercionNode.__init__(self, arg)
7311 self.type = result_type
7313 if not result_type.create_from_py_utility_code(env):
7315 "Cannot convert Python object to '%s'" % result_type)
7316 if self.type.is_string and self.arg.is_ephemeral():
7318 "Obtaining char * from temporary Python value")
7320 def analyse_types(self, env):
7321 # The arg is always already analysed
7324 def generate_result_code(self, code):
7325 function = self.type.from_py_function
7326 operand = self.arg.py_result()
7327 rhs = "%s(%s)" % (function, operand)
7328 if self.type.is_enum:
7329 rhs = typecast(self.type, c_long_type, rhs)
7330 code.putln('%s = %s; %s' % (
7333 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7334 if self.type.is_pyobject:
7335 code.put_gotref(self.py_result())
7338 class CoerceToBooleanNode(CoercionNode):
7339 # This node is used when a result needs to be used
7340 # in a boolean context.
7342 type = PyrexTypes.c_bint_type
7344 _special_builtins = {
7345 Builtin.list_type : 'PyList_GET_SIZE',
7346 Builtin.tuple_type : 'PyTuple_GET_SIZE',
7347 Builtin.bytes_type : 'PyBytes_GET_SIZE',
7348 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
7351 def __init__(self, arg, env):
7352 CoercionNode.__init__(self, arg)
7353 if arg.type.is_pyobject:
7356 def nogil_check(self, env):
7357 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7360 gil_message = "Truth-testing Python object"
7362 def check_const(self):
7366 return self.arg.check_const()
7368 def calculate_result_code(self):
7369 return "(%s != 0)" % self.arg.result()
7371 def generate_result_code(self, code):
7372 if not self.is_temp:
7374 test_func = self._special_builtins.get(self.arg.type)
7375 if test_func is not None:
7376 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7378 self.arg.py_result(),
7380 self.arg.py_result()))
7383 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7385 self.arg.py_result(),
7386 code.error_goto_if_neg(self.result(), self.pos)))
7388 class CoerceToComplexNode(CoercionNode):
7390 def __init__(self, arg, dst_type, env):
7391 if arg.type.is_complex:
7392 arg = arg.coerce_to_simple(env)
7393 self.type = dst_type
7394 CoercionNode.__init__(self, arg)
7395 dst_type.create_declaration_utility_code(env)
7397 def calculate_result_code(self):
7398 if self.arg.type.is_complex:
7399 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
7400 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7402 real_part = self.arg.result()
7404 return "%s(%s, %s)" % (
7405 self.type.from_parts,
7409 def generate_result_code(self, code):
7412 class CoerceToTempNode(CoercionNode):
7413 # This node is used to force the result of another node
7414 # to be stored in a temporary. It is only used if the
7415 # argument node's result is not already in a temporary.
7417 def __init__(self, arg, env):
7418 CoercionNode.__init__(self, arg)
7419 self.type = self.arg.type
7420 self.constant_result = self.arg.constant_result
7422 if self.type.is_pyobject:
7423 self.result_ctype = py_object_type
7425 gil_message = "Creating temporary Python reference"
7427 def analyse_types(self, env):
7428 # The arg is always already analysed
7431 def coerce_to_boolean(self, env):
7432 self.arg = self.arg.coerce_to_boolean(env)
7433 if self.arg.is_simple():
7435 self.type = self.arg.type
7436 self.result_ctype = self.type
7439 def generate_result_code(self, code):
7440 #self.arg.generate_evaluation_code(code) # Already done
7441 # by generic generate_subexpr_evaluation_code!
7442 code.putln("%s = %s;" % (
7443 self.result(), self.arg.result_as(self.ctype())))
7444 if self.type.is_pyobject and self.use_managed_ref:
7445 code.put_incref(self.result(), self.ctype())
7448 class CloneNode(CoercionNode):
7449 # This node is employed when the result of another node needs
7450 # to be used multiple times. The argument node's result must
7451 # be in a temporary. This node "borrows" the result from the
7452 # argument node, and does not generate any evaluation or
7453 # disposal code for it. The original owner of the argument
7454 # node is responsible for doing those things.
7456 subexprs = [] # Arg is not considered a subexpr
7459 def __init__(self, arg):
7460 CoercionNode.__init__(self, arg)
7461 if hasattr(arg, 'type'):
7462 self.type = arg.type
7463 self.result_ctype = arg.result_ctype
7464 if hasattr(arg, 'entry'):
7465 self.entry = arg.entry
7468 return self.arg.result()
7470 def type_dependencies(self, env):
7471 return self.arg.type_dependencies(env)
7473 def infer_type(self, env):
7474 return self.arg.infer_type(env)
7476 def analyse_types(self, env):
7477 self.type = self.arg.type
7478 self.result_ctype = self.arg.result_ctype
7480 if hasattr(self.arg, 'entry'):
7481 self.entry = self.arg.entry
7483 def is_simple(self):
7484 return True # result is always in a temp (or a name)
7486 def generate_evaluation_code(self, code):
7489 def generate_result_code(self, code):
7492 def generate_disposal_code(self, code):
7495 def free_temps(self, code):
7499 class ModuleRefNode(ExprNode):
7500 # Simple returns the module object
7502 type = py_object_type
7506 def analyse_types(self, env):
7509 def may_be_none(self):
7512 def calculate_result_code(self):
7513 return Naming.module_cname
7515 def generate_result_code(self, code):
7518 class DocstringRefNode(ExprNode):
7519 # Extracts the docstring of the body element
7522 type = py_object_type
7525 def __init__(self, pos, body):
7526 ExprNode.__init__(self, pos)
7527 assert body.type.is_pyobject
7530 def analyse_types(self, env):
7533 def generate_result_code(self, code):
7534 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7535 self.result(), self.body.result(),
7536 code.error_goto_if_null(self.result(), self.pos)))
7537 code.put_gotref(self.result())
7541 #------------------------------------------------------------------------------------
7543 # Runtime support code
7545 #------------------------------------------------------------------------------------
7547 get_name_interned_utility_code = UtilityCode(
7549 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7552 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7554 result = PyObject_GetAttr(dict, name);
7556 PyErr_SetObject(PyExc_NameError, name);
7561 #------------------------------------------------------------------------------------
7563 import_utility_code = UtilityCode(
7565 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7568 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7569 PyObject *py_import = 0;
7570 PyObject *empty_list = 0;
7571 PyObject *module = 0;
7572 PyObject *global_dict = 0;
7573 PyObject *empty_dict = 0;
7575 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7581 empty_list = PyList_New(0);
7586 global_dict = PyModule_GetDict(%(GLOBALS)s);
7589 empty_dict = PyDict_New();
7592 module = PyObject_CallFunctionObjArgs(py_import,
7593 name, global_dict, empty_dict, list, NULL);
7595 Py_XDECREF(empty_list);
7596 Py_XDECREF(py_import);
7597 Py_XDECREF(empty_dict);
7601 "BUILTINS": Naming.builtins_cname,
7602 "GLOBALS": Naming.module_cname,
7605 #------------------------------------------------------------------------------------
7607 get_exception_utility_code = UtilityCode(
7609 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7612 static PyObject *__Pyx_GetExcValue(void) {
7613 PyObject *type = 0, *value = 0, *tb = 0;
7614 PyObject *tmp_type, *tmp_value, *tmp_tb;
7615 PyObject *result = 0;
7616 PyThreadState *tstate = PyThreadState_Get();
7617 PyErr_Fetch(&type, &value, &tb);
7618 PyErr_NormalizeException(&type, &value, &tb);
7619 if (PyErr_Occurred())
7625 tmp_type = tstate->exc_type;
7626 tmp_value = tstate->exc_value;
7627 tmp_tb = tstate->exc_traceback;
7628 tstate->exc_type = type;
7629 tstate->exc_value = value;
7630 tstate->exc_traceback = tb;
7631 /* Make sure tstate is in a consistent state when we XDECREF
7632 these objects (XDECREF may run arbitrary code). */
7633 Py_XDECREF(tmp_type);
7634 Py_XDECREF(tmp_value);
7649 #------------------------------------------------------------------------------------
7651 type_test_utility_code = UtilityCode(
7653 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7656 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7657 if (unlikely(!type)) {
7658 PyErr_Format(PyExc_SystemError, "Missing type object");
7661 if (likely(PyObject_TypeCheck(obj, type)))
7663 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7664 Py_TYPE(obj)->tp_name, type->tp_name);
7669 #------------------------------------------------------------------------------------
7671 find_py2_metaclass_utility_code = UtilityCode(
7673 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
7676 static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
7677 PyObject *metaclass;
7678 /* Default metaclass */
7679 #if PY_MAJOR_VERSION < 3
7680 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7681 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7682 metaclass = PyObject_GetAttrString(base, "__class__");
7685 metaclass = (PyObject*) Py_TYPE(base);
7688 metaclass = (PyObject *) &PyClass_Type;
7691 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7692 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7693 metaclass = (PyObject*) Py_TYPE(base);
7695 metaclass = (PyObject *) &PyType_Type;
7698 Py_INCREF(metaclass);
7703 create_class_utility_code = UtilityCode(
7705 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7706 PyObject *modname); /*proto*/
7709 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7710 PyObject *modname) {
7712 PyObject *metaclass;
7714 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7717 /* Python2 __metaclass__ */
7718 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7720 Py_INCREF(metaclass);
7722 metaclass = __Pyx_FindPy2Metaclass(bases);
7724 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7725 Py_DECREF(metaclass);
7729 requires = [find_py2_metaclass_utility_code])
7731 #------------------------------------------------------------------------------------
7733 create_py3class_utility_code = UtilityCode(
7735 static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
7736 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
7737 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7740 PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7741 PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7743 Py_INCREF(metaclass);
7744 if (PyDict_DelItemString(mkw, "metaclass") < 0) {
7745 Py_DECREF(metaclass);
7750 return __Pyx_FindPy2Metaclass(bases);
7753 PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
7754 PyObject *modname, PyObject *doc) {
7760 prep = PyObject_GetAttrString(metaclass, "__prepare__");
7762 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7765 return PyDict_New();
7767 pargs = PyTuple_New(2);
7775 PyTuple_SET_ITEM(pargs, 0, name);
7776 PyTuple_SET_ITEM(pargs, 1, bases);
7778 ns = PyObject_Call(prep, pargs, mkw);
7786 /* Required here to emulate assignment order */
7787 /* XXX: use consts here */
7788 #if PY_MAJOR_VERSION >= 3
7789 str = PyUnicode_FromString("__module__");
7791 str = PyString_FromString("__module__");
7798 if (PyObject_SetItem(ns, str, modname) < 0) {
7805 #if PY_MAJOR_VERSION >= 3
7806 str = PyUnicode_FromString("__doc__");
7808 str = PyString_FromString("__doc__");
7814 if (PyObject_SetItem(ns, str, doc) < 0) {
7824 PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7826 PyObject *margs = PyTuple_New(3);
7832 PyTuple_SET_ITEM(margs, 0, name);
7833 PyTuple_SET_ITEM(margs, 1, bases);
7834 PyTuple_SET_ITEM(margs, 2, dict);
7835 result = PyObject_Call(metaclass, margs, mkw);
7840 requires = [find_py2_metaclass_utility_code])
7842 #------------------------------------------------------------------------------------
7844 cpp_exception_utility_code = UtilityCode(
7846 #ifndef __Pyx_CppExn2PyErr
7847 static void __Pyx_CppExn2PyErr() {
7849 if (PyErr_Occurred())
7850 ; // let the latest Python exn pass through and ignore the current one
7853 } catch (const std::invalid_argument& exn) {
7854 // Catch a handful of different errors here and turn them into the
7855 // equivalent Python errors.
7856 // Change invalid_argument to ValueError
7857 PyErr_SetString(PyExc_ValueError, exn.what());
7858 } catch (const std::out_of_range& exn) {
7859 // Change out_of_range to IndexError
7860 PyErr_SetString(PyExc_IndexError, exn.what());
7861 } catch (const std::exception& exn) {
7862 PyErr_SetString(PyExc_RuntimeError, exn.what());
7866 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7874 pyerr_occurred_withgil_utility_code= UtilityCode(
7876 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7879 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7882 PyGILState_STATE _save = PyGILState_Ensure();
7884 err = !!PyErr_Occurred();
7886 PyGILState_Release(_save);
7893 #------------------------------------------------------------------------------------
7895 raise_noneattr_error_utility_code = UtilityCode(
7897 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7900 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7901 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7905 raise_noneindex_error_utility_code = UtilityCode(
7907 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7910 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7911 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7915 raise_none_iter_error_utility_code = UtilityCode(
7917 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7920 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7921 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7925 #------------------------------------------------------------------------------------
7927 getitem_dict_utility_code = UtilityCode(
7929 #if PY_MAJOR_VERSION >= 3
7930 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7932 if (unlikely(d == Py_None)) {
7933 __Pyx_RaiseNoneIndexingError();
7936 value = PyDict_GetItemWithError(d, key);
7937 if (unlikely(!value)) {
7938 if (!PyErr_Occurred())
7939 PyErr_SetObject(PyExc_KeyError, key);
7946 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7949 requires = [raise_noneindex_error_utility_code])
7951 #------------------------------------------------------------------------------------
7953 getitem_int_pyunicode_utility_code = UtilityCode(
7955 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7956 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7957 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7959 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7960 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7961 return PyUnicode_AS_UNICODE(ustring)[i];
7962 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7963 i += PyUnicode_GET_SIZE(ustring);
7964 return PyUnicode_AS_UNICODE(ustring)[i];
7966 PyErr_SetString(PyExc_IndexError, "string index out of range");
7967 return (Py_UNICODE)-1;
7971 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7973 PyObject *uchar_string;
7974 if (!j) return (Py_UNICODE)-1;
7975 uchar_string = PyObject_GetItem(ustring, j);
7977 if (!uchar_string) return (Py_UNICODE)-1;
7978 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7979 Py_DECREF(uchar_string);
7984 getitem_int_utility_code = UtilityCode(
7987 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7989 if (!j) return NULL;
7990 r = PyObject_GetItem(o, j);
7997 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7998 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7999 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8001 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
8002 if (likely(o != Py_None)) {
8003 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
8004 PyObject *r = Py%(type)s_GET_ITEM(o, i);
8008 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
8009 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
8014 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8016 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
8019 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8020 __Pyx_GetItemInt_Fast(o, i) : \\
8021 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
8023 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
8025 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8026 r = PyList_GET_ITEM(o, i);
8029 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
8030 r = PyTuple_GET_ITEM(o, i);
8033 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
8034 r = PySequence_GetItem(o, i);
8037 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8047 #------------------------------------------------------------------------------------
8049 setitem_int_utility_code = UtilityCode(
8051 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8052 __Pyx_SetItemInt_Fast(o, i, v) : \\
8053 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
8055 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
8058 r = PyObject_SetItem(o, j, v);
8063 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
8064 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
8066 Py_DECREF(PyList_GET_ITEM(o, i));
8067 PyList_SET_ITEM(o, i, v);
8070 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
8071 return PySequence_SetItem(o, i, v);
8073 PyObject *j = PyInt_FromSsize_t(i);
8074 return __Pyx_SetItemInt_Generic(o, j, v);
8081 #------------------------------------------------------------------------------------
8083 delitem_int_utility_code = UtilityCode(
8085 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
8086 __Pyx_DelItemInt_Fast(o, i) : \\
8087 __Pyx_DelItem_Generic(o, to_py_func(i)))
8089 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8092 r = PyObject_DelItem(o, j);
8097 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8098 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
8099 return PySequence_DelItem(o, i);
8101 PyObject *j = PyInt_FromSsize_t(i);
8102 return __Pyx_DelItem_Generic(o, j);
8109 #------------------------------------------------------------------------------------
8111 raise_too_many_values_to_unpack = UtilityCode(
8113 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8116 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
8117 PyErr_Format(PyExc_ValueError,
8118 #if PY_VERSION_HEX < 0x02050000
8119 "too many values to unpack (expected %d)", (int)expected);
8121 "too many values to unpack (expected %zd)", expected);
8126 raise_need_more_values_to_unpack = UtilityCode(
8128 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8131 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8132 PyErr_Format(PyExc_ValueError,
8133 #if PY_VERSION_HEX < 0x02050000
8134 "need more than %d value%s to unpack", (int)index,
8136 "need more than %zd value%s to unpack", index,
8138 (index == 1) ? "" : "s");
8142 #------------------------------------------------------------------------------------
8144 tuple_unpacking_error_code = UtilityCode(
8146 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8149 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
8151 __Pyx_RaiseNoneNotIterableError();
8152 } else if (PyTuple_GET_SIZE(t) < index) {
8153 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
8155 __Pyx_RaiseTooManyValuesError(index);
8159 requires = [raise_none_iter_error_utility_code,
8160 raise_need_more_values_to_unpack,
8161 raise_too_many_values_to_unpack]
8164 unpacking_utility_code = UtilityCode(
8166 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8167 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8170 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
8172 if (!(item = PyIter_Next(iter))) {
8173 if (!PyErr_Occurred()) {
8174 __Pyx_RaiseNeedMoreValuesError(index);
8180 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8182 if ((item = PyIter_Next(iter))) {
8184 __Pyx_RaiseTooManyValuesError(expected);
8187 else if (!PyErr_Occurred())
8193 requires = [raise_need_more_values_to_unpack,
8194 raise_too_many_values_to_unpack]
8197 #------------------------------------------------------------------------------------
8199 # CPython supports calling functions with non-dict kwargs by
8200 # converting them to a dict first
8202 kwargs_call_utility_code = UtilityCode(
8204 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
8207 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
8209 if (likely(PyDict_Check(kwargs))) {
8210 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
8212 PyObject* real_dict;
8213 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
8214 if (unlikely(!real_dict))
8216 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
8217 Py_DECREF(real_dict);
8218 return result; /* may be NULL */
8225 #------------------------------------------------------------------------------------
8227 int_pow_utility_code = UtilityCode(
8229 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
8232 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
8244 if (unlikely(e<0)) return 0;
8247 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
8255 # ------------------------------ Division ------------------------------------
8257 div_int_utility_code = UtilityCode(
8259 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8262 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8264 %(type)s r = a - q*b;
8265 q -= ((r != 0) & ((r ^ b) < 0));
8270 mod_int_utility_code = UtilityCode(
8272 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8275 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8276 %(type)s r = a %% b;
8277 r += ((r != 0) & ((r ^ b) < 0)) * b;
8282 mod_float_utility_code = UtilityCode(
8284 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8287 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8288 %(type)s r = fmod%(math_h_modifier)s(a, b);
8289 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
8294 cdivision_warning_utility_code = UtilityCode(
8296 static int __Pyx_cdivision_warning(void); /* proto */
8299 static int __Pyx_cdivision_warning(void) {
8300 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8301 "division with oppositely signed operands, C and Python semantics differ",
8308 'FILENAME': Naming.filename_cname,
8309 'LINENO': Naming.lineno_cname,
8313 division_overflow_test_code = UtilityCode(
8315 #define UNARY_NEG_WOULD_OVERFLOW(x) \
8316 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
8320 binding_cfunc_utility_code = UtilityCode(
8322 #define %(binding_cfunc)s_USED 1
8325 PyCFunctionObject func;
8326 } %(binding_cfunc)s_object;
8328 static PyTypeObject %(binding_cfunc)s_type;
8329 static PyTypeObject *%(binding_cfunc)s = NULL;
8331 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
8332 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
8334 static int %(binding_cfunc)s_init(void); /* proto */
8335 """ % Naming.__dict__,
8338 static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
8339 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
8344 op->func.m_self = self;
8346 op->func.m_module = module;
8347 PyObject_GC_Track(op);
8348 return (PyObject *)op;
8351 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8352 PyObject_GC_UnTrack(m);
8353 Py_XDECREF(m->func.m_self);
8354 Py_XDECREF(m->func.m_module);
8358 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
8361 return PyMethod_New(func, obj, type);
8364 static int %(binding_cfunc)s_init(void) {
8365 %(binding_cfunc)s_type = PyCFunction_Type;
8366 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
8367 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
8368 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
8369 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
8372 %(binding_cfunc)s = &%(binding_cfunc)s_type;
8376 """ % Naming.__dict__)