2 # Pyrex - Parse tree nodes for expressions
7 from Errors import error, warning, warn_once, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Code import UtilityCode
13 from Nodes import Node
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
17 from Builtin import list_type, tuple_type, set_type, dict_type, \
18 unicode_type, str_type, bytes_type, type_type
22 from Cython import Utils
23 from Annotate import AnnotationItem
24 from Cython import Utils
26 from Cython.Debugging import print_call_chain
27 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
33 from sets import Set as set
35 class NotConstant(object):
37 return "<NOT CONSTANT>"
39 not_a_constant = NotConstant()
40 constant_value_not_set = object()
42 # error messages when coercing from key[0] to key[1]
43 find_coercion_error = {
44 # string related errors
45 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
46 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
47 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
48 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
49 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
50 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
51 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
52 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
53 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
54 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
59 # subexprs [string] Class var holding names of subexpr node attrs
60 # type PyrexType Type of the result
61 # result_code string Code fragment
62 # result_ctype string C type of result_code if different from type
63 # is_temp boolean Result is in a temporary variable
64 # is_sequence_constructor
65 # boolean Is a list or tuple constructor expression
66 # is_starred boolean Is a starred expression (e.g. '*a')
68 # [ExprNode or [ExprNode or None] or None]
69 # Cached result of subexpr_nodes()
70 # use_managed_ref boolean use ref-counted temps/assignments/etc.
75 old_temp = None # error checker for multiple frees etc.
76 use_managed_ref = True # can be set by optimisation transforms
78 # The Analyse Expressions phase for expressions is split
79 # into two sub-phases:
82 # Determines the result type of the expression based
83 # on the types of its sub-expressions, and inserts
84 # coercion nodes into the expression tree where needed.
85 # Marks nodes which will need to have temporary variables
89 # Allocates temporary variables where needed, and fills
90 # in the result_code field of each node.
92 # ExprNode provides some convenience routines which
93 # perform both of the above phases. These should only
94 # be called from statement nodes, and only when no
95 # coercion nodes need to be added around the expression
96 # being analysed. In that case, the above two phases
97 # should be invoked separately.
99 # Framework code in ExprNode provides much of the common
100 # processing for the various phases. It makes use of the
101 # 'subexprs' class attribute of ExprNodes, which should
102 # contain a list of the names of attributes which can
103 # hold sub-nodes or sequences of sub-nodes.
105 # The framework makes use of a number of abstract methods.
106 # Their responsibilities are as follows.
108 # Declaration Analysis phase
110 # analyse_target_declaration
111 # Called during the Analyse Declarations phase to analyse
112 # the LHS of an assignment or argument of a del statement.
113 # Nodes which cannot be the LHS of an assignment need not
116 # Expression Analysis phase
119 # - Call analyse_types on all sub-expressions.
120 # - Check operand types, and wrap coercion nodes around
121 # sub-expressions where needed.
122 # - Set the type of this node.
123 # - If a temporary variable will be required for the
124 # result, set the is_temp flag of this node.
126 # analyse_target_types
127 # Called during the Analyse Types phase to analyse
128 # the LHS of an assignment or argument of a del
129 # statement. Similar responsibilities to analyse_types.
132 # Called by the default implementation of allocate_target_temps.
133 # Should return a C lvalue for assigning to the node. The default
134 # implementation calls calculate_result_code.
137 # - Check that this node and its subnodes form a
138 # legal constant expression. If so, do nothing,
139 # otherwise call not_const.
141 # The default implementation of check_const
142 # assumes that the expression is not constant.
145 # - Same as check_const, except check that the
146 # expression is a C lvalue whose address is
147 # constant. Otherwise, call addr_not_const.
149 # The default implementation of calc_const_addr
150 # assumes that the expression is not a constant
153 # Code Generation phase
155 # generate_evaluation_code
156 # - Call generate_evaluation_code for sub-expressions.
157 # - Perform the functions of generate_result_code
159 # - If result is temporary, call generate_disposal_code
160 # on all sub-expressions.
162 # A default implementation of generate_evaluation_code
163 # is provided which uses the following abstract methods:
165 # generate_result_code
166 # - Generate any C statements necessary to calculate
167 # the result of this node from the results of its
170 # calculate_result_code
171 # - Should return a C code fragment evaluating to the
172 # result. This is only called when the result is not
175 # generate_assignment_code
176 # Called on the LHS of an assignment.
177 # - Call generate_evaluation_code for sub-expressions.
178 # - Generate code to perform the assignment.
179 # - If the assignment absorbed a reference, call
180 # generate_post_assignment_code on the RHS,
181 # otherwise call generate_disposal_code on it.
183 # generate_deletion_code
184 # Called on an argument of a del statement.
185 # - Call generate_evaluation_code for sub-expressions.
186 # - Generate code to perform the deletion.
187 # - Call generate_disposal_code on all sub-expressions.
191 is_sequence_constructor = 0
194 saved_subexpr_nodes = None
199 constant_result = constant_value_not_set
202 _get_child_attrs = operator.attrgetter('subexprs')
203 except AttributeError:
205 def _get_child_attrs(self):
207 child_attrs = property(fget=_get_child_attrs)
209 def not_implemented(self, method_name):
210 print_call_chain(method_name, "not implemented") ###
212 "%s.%s not implemented" %
213 (self.__class__.__name__, method_name))
218 def is_ephemeral(self):
219 # An ephemeral node is one whose result is in
220 # a Python temporary and we suspect there are no
221 # other references to it. Certain operations are
222 # disallowed on such values, since they are
223 # likely to result in a dangling pointer.
224 return self.type.is_pyobject and self.is_temp
226 def subexpr_nodes(self):
227 # Extract a list of subexpression nodes based
228 # on the contents of the subexprs class attribute.
230 for name in self.subexprs:
231 item = getattr(self, name)
233 if type(item) is list:
241 return self.temp_code
243 return self.calculate_result_code()
245 def result_as(self, type = None):
246 # Return the result code cast to the specified C type.
247 return typecast(type, self.ctype(), self.result())
250 # Return the result code cast to PyObject *.
251 return self.result_as(py_object_type)
254 # Return the native C type of the result (i.e. the
255 # C type of the result_code expression).
256 return self.result_ctype or self.type
258 def get_constant_c_result_code(self):
259 # Return the constant value of this node as a result code
260 # string, or None if the node is not constant. This method
261 # can be called when the constant result code is required
262 # before the code generation phase.
264 # The return value is a string that can represent a simple C
265 # value, a constant C name or a constant C expression. If the
266 # node type depends on Python code, this must return None.
269 def calculate_constant_result(self):
270 # Calculate the constant compile time result value of this
271 # expression and store it in ``self.constant_result``. Does
272 # nothing by default, thus leaving ``self.constant_result``
273 # unknown. If valid, the result can be an arbitrary Python
276 # This must only be called when it is assured that all
277 # sub-expressions have a valid constant_result value. The
278 # ConstantFolding transform will do this.
281 def has_constant_result(self):
282 return self.constant_result is not constant_value_not_set and \
283 self.constant_result is not not_a_constant
285 def compile_time_value(self, denv):
286 # Return value of compile-time expression, or report error.
287 error(self.pos, "Invalid compile-time expression")
289 def compile_time_value_error(self, e):
290 error(self.pos, "Error in compile-time expression: %s: %s" % (
291 e.__class__.__name__, e))
293 # ------------- Declaration Analysis ----------------
295 def analyse_target_declaration(self, env):
296 error(self.pos, "Cannot assign to or delete this")
298 # ------------- Expression Analysis ----------------
300 def analyse_const_expression(self, env):
301 # Called during the analyse_declarations phase of a
302 # constant expression. Analyses the expression's type,
303 # checks whether it is a legal const expression,
304 # and determines its value.
305 self.analyse_types(env)
306 return self.check_const()
308 def analyse_expressions(self, env):
309 # Convenience routine performing both the Type
310 # Analysis and Temp Allocation phases for a whole
312 self.analyse_types(env)
314 def analyse_target_expression(self, env, rhs):
315 # Convenience routine performing both the Type
316 # Analysis and Temp Allocation phases for the LHS of
318 self.analyse_target_types(env)
320 def analyse_boolean_expression(self, env):
321 # Analyse expression and coerce to a boolean.
322 self.analyse_types(env)
323 bool = self.coerce_to_boolean(env)
326 def analyse_temp_boolean_expression(self, env):
327 # Analyse boolean expression and coerce result into
328 # a temporary. This is used when a branch is to be
329 # performed on the result and we won't have an
330 # opportunity to ensure disposal code is executed
331 # afterwards. By forcing the result into a temporary,
332 # we ensure that all disposal has been done by the
333 # time we get the result.
334 self.analyse_types(env)
335 return self.coerce_to_boolean(env).coerce_to_simple(env)
337 # --------------- Type Inference -----------------
339 def type_dependencies(self, env):
340 # Returns the list of entries whose types must be determined
341 # before the type of self can be infered.
342 if hasattr(self, 'type') and self.type is not None:
344 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
346 def infer_type(self, env):
347 # Attempt to deduce the type of self.
348 # Differs from analyse_types as it avoids unnecessary
349 # analysis of subexpressions, but can assume everything
350 # in self.type_dependencies() has been resolved.
351 if hasattr(self, 'type') and self.type is not None:
353 elif hasattr(self, 'entry') and self.entry is not None:
354 return self.entry.type
356 self.not_implemented("infer_type")
358 # --------------- Type Analysis ------------------
360 def analyse_as_module(self, env):
361 # If this node can be interpreted as a reference to a
362 # cimported module, return its scope, else None.
365 def analyse_as_type(self, env):
366 # If this node can be interpreted as a reference to a
367 # type, return that type, else None.
370 def analyse_as_extension_type(self, env):
371 # If this node can be interpreted as a reference to an
372 # extension type, return its type, else None.
375 def analyse_types(self, env):
376 self.not_implemented("analyse_types")
378 def analyse_target_types(self, env):
379 self.analyse_types(env)
381 def nogil_check(self, env):
382 # By default, any expression based on Python objects is
383 # prevented in nogil environments. Subtypes must override
384 # this if they can work without the GIL.
385 if self.type.is_pyobject:
388 def gil_assignment_check(self, env):
389 if env.nogil and self.type.is_pyobject:
390 error(self.pos, "Assignment of Python object not allowed without gil")
392 def check_const(self):
397 error(self.pos, "Not allowed in a constant expression")
399 def check_const_addr(self):
400 self.addr_not_const()
403 def addr_not_const(self):
404 error(self.pos, "Address is not constant")
406 # ----------------- Result Allocation -----------------
408 def result_in_temp(self):
409 # Return true if result is in a temporary owned by
410 # this node or one of its subexpressions. Overridden
411 # by certain nodes which can share the result of
415 def target_code(self):
416 # Return code fragment for use as LHS of a C assignment.
417 return self.calculate_result_code()
419 def calculate_result_code(self):
420 self.not_implemented("calculate_result_code")
422 # def release_target_temp(self, env):
423 # # Release temporaries used by LHS of an assignment.
424 # self.release_subexpr_temps(env)
426 def allocate_temp_result(self, code):
428 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
432 type = PyrexTypes.py_object_type
433 self.temp_code = code.funcstate.allocate_temp(
434 type, manage_ref=self.use_managed_ref)
436 self.temp_code = None
438 def release_temp_result(self, code):
439 if not self.temp_code:
441 raise RuntimeError("temp %s released multiple times in %s" % (
442 self.old_temp, self.__class__.__name__))
444 raise RuntimeError("no temp, but release requested in %s" % (
445 self.__class__.__name__))
446 code.funcstate.release_temp(self.temp_code)
447 self.old_temp = self.temp_code
448 self.temp_code = None
450 # ---------------- Code Generation -----------------
452 def make_owned_reference(self, code):
453 # If result is a pyobject, make sure we own
455 if self.type.is_pyobject and not self.result_in_temp():
456 code.put_incref(self.result(), self.ctype())
458 def generate_evaluation_code(self, code):
459 code.mark_pos(self.pos)
461 # Generate code to evaluate this node and
462 # its sub-expressions, and dispose of any
463 # temporary results of its sub-expressions.
464 self.generate_subexpr_evaluation_code(code)
467 self.allocate_temp_result(code)
469 self.generate_result_code(code)
471 # If we are temp we do not need to wait until this node is disposed
472 # before disposing children.
473 self.generate_subexpr_disposal_code(code)
474 self.free_subexpr_temps(code)
476 def generate_subexpr_evaluation_code(self, code):
477 for node in self.subexpr_nodes():
478 node.generate_evaluation_code(code)
480 def generate_result_code(self, code):
481 self.not_implemented("generate_result_code")
483 def generate_disposal_code(self, code):
485 if self.type.is_pyobject:
486 code.put_decref_clear(self.result(), self.ctype())
488 # Already done if self.is_temp
489 self.generate_subexpr_disposal_code(code)
491 def generate_subexpr_disposal_code(self, code):
492 # Generate code to dispose of temporary results
493 # of all sub-expressions.
494 for node in self.subexpr_nodes():
495 node.generate_disposal_code(code)
497 def generate_post_assignment_code(self, code):
499 if self.type.is_pyobject:
500 code.putln("%s = 0;" % self.result())
502 self.generate_subexpr_disposal_code(code)
504 def generate_assignment_code(self, rhs, code):
505 # Stub method for nodes which are not legal as
506 # the LHS of an assignment. An error will have
507 # been reported earlier.
510 def generate_deletion_code(self, code):
511 # Stub method for nodes that are not legal as
512 # the argument of a del statement. An error
513 # will have been reported earlier.
516 def free_temps(self, code):
518 if not self.type.is_void:
519 self.release_temp_result(code)
521 self.free_subexpr_temps(code)
523 def free_subexpr_temps(self, code):
524 for sub in self.subexpr_nodes():
527 def generate_function_definitions(self, env, code):
530 # ---------------- Annotation ---------------------
532 def annotate(self, code):
533 for node in self.subexpr_nodes():
536 # ----------------- Coercion ----------------------
538 def coerce_to(self, dst_type, env):
539 # Coerce the result so that it can be assigned to
540 # something of type dst_type. If processing is necessary,
541 # wraps this node in a coercion node and returns that.
542 # Otherwise, returns this node unchanged.
544 # This method is called during the analyse_expressions
545 # phase of the src_node's processing.
547 # Note that subclasses that override this (especially
548 # ConstNodes) must not (re-)set their own .type attribute
549 # here. Since expression nodes may turn up in different
550 # places in the tree (e.g. inside of CloneNodes in cascaded
551 # assignments), this method must return a new node instance
552 # if it changes the type.
556 src_is_py_type = src_type.is_pyobject
557 dst_is_py_type = dst_type.is_pyobject
559 if self.check_for_coercion_error(dst_type):
562 if dst_type.is_pyobject:
563 if not src.type.is_pyobject:
564 if dst_type is bytes_type and src.type.is_int:
565 src = CoerceIntToBytesNode(src, env)
567 src = CoerceToPyTypeNode(src, env)
568 if not src.type.subtype_of(dst_type):
569 if not isinstance(src, NoneNode):
570 src = PyTypeTestNode(src, dst_type, env)
571 elif src.type.is_pyobject:
572 src = CoerceFromPyTypeNode(dst_type, src, env)
573 elif (dst_type.is_complex
574 and src_type != dst_type
575 and dst_type.assignable_from(src_type)):
576 src = CoerceToComplexNode(src, dst_type, env)
577 else: # neither src nor dst are py types
578 # Added the string comparison, since for c types that
579 # is enough, but Cython gets confused when the types are
580 # in different pxi files.
581 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
582 self.fail_assignment(dst_type)
585 def fail_assignment(self, dst_type):
586 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
588 def check_for_coercion_error(self, dst_type, fail=False, default=None):
589 if fail and not default:
590 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
591 message = find_coercion_error((self.type, dst_type), default)
592 if message is not None:
593 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
596 self.fail_assignment(dst_type)
600 def coerce_to_pyobject(self, env):
601 return self.coerce_to(PyrexTypes.py_object_type, env)
603 def coerce_to_boolean(self, env):
604 # Coerce result to something acceptable as
607 # if it's constant, calculate the result now
608 if self.has_constant_result():
609 bool_value = bool(self.constant_result)
610 return BoolNode(self.pos, value=bool_value,
611 constant_result=bool_value)
614 if type.is_pyobject or type.is_ptr or type.is_float:
615 return CoerceToBooleanNode(self, env)
617 if not (type.is_int or type.is_enum or type.is_error):
619 "Type '%s' not acceptable as a boolean" % type)
622 def coerce_to_integer(self, env):
623 # If not already some C integer type, coerce to longint.
627 return self.coerce_to(PyrexTypes.c_long_type, env)
629 def coerce_to_temp(self, env):
630 # Ensure that the result is in a temporary.
631 if self.result_in_temp():
634 return CoerceToTempNode(self, env)
636 def coerce_to_simple(self, env):
637 # Ensure that the result is simple (see is_simple).
641 return self.coerce_to_temp(env)
644 # A node is simple if its result is something that can
645 # be referred to without performing any operations, e.g.
646 # a constant, local var, C global var, struct member
647 # reference, or temporary.
648 return self.result_in_temp()
650 def may_be_none(self):
651 return self.type.is_pyobject
653 def as_cython_attribute(self):
656 def as_none_safe_node(self, message, error="PyExc_TypeError"):
657 # Wraps the node in a NoneCheckNode if it is not known to be
658 # not-None (e.g. because it is a Python literal).
659 if self.may_be_none():
660 return NoneCheckNode(self, error, message)
665 class AtomicExprNode(ExprNode):
666 # Abstract base class for expression nodes which have
667 # no sub-expressions.
671 # Override to optimize -- we know we have no children
672 def generate_subexpr_evaluation_code(self, code):
674 def generate_subexpr_disposal_code(self, code):
677 class PyConstNode(AtomicExprNode):
678 # Abstract base class for constant Python values.
681 type = py_object_type
686 def may_be_none(self):
689 def analyse_types(self, env):
692 def calculate_result_code(self):
695 def generate_result_code(self, code):
699 class NoneNode(PyConstNode):
700 # The constant value None
704 constant_result = None
708 def compile_time_value(self, denv):
711 def may_be_none(self):
715 class EllipsisNode(PyConstNode):
716 # '...' in a subscript list.
718 value = "Py_Ellipsis"
720 constant_result = Ellipsis
722 def compile_time_value(self, denv):
726 class ConstNode(AtomicExprNode):
727 # Abstract base type for literal constant nodes.
729 # value string C code fragment
737 def may_be_none(self):
740 def analyse_types(self, env):
741 pass # Types are held in class variables
743 def check_const(self):
746 def get_constant_c_result_code(self):
747 return self.calculate_result_code()
749 def calculate_result_code(self):
750 return str(self.value)
752 def generate_result_code(self, code):
756 class BoolNode(ConstNode):
757 type = PyrexTypes.c_bint_type
758 # The constant value True or False
760 def calculate_constant_result(self):
761 self.constant_result = self.value
763 def compile_time_value(self, denv):
766 def calculate_result_code(self):
767 return str(int(self.value))
770 class NullNode(ConstNode):
771 type = PyrexTypes.c_null_ptr_type
775 def get_constant_c_result_code(self):
779 class CharNode(ConstNode):
780 type = PyrexTypes.c_char_type
782 def calculate_constant_result(self):
783 self.constant_result = ord(self.value)
785 def compile_time_value(self, denv):
786 return ord(self.value)
788 def calculate_result_code(self):
789 return "'%s'" % StringEncoding.escape_char(self.value)
792 class IntNode(ConstNode):
795 # longness "" or "L" or "LL"
800 def __init__(self, pos, **kwds):
801 ExprNode.__init__(self, pos, **kwds)
802 if 'type' not in kwds:
803 rank = max(1, len(self.longness))
804 sign = not self.unsigned
805 self.type = PyrexTypes.modifiers_and_name_to_type[sign, rank, "int"]
807 def coerce_to(self, dst_type, env):
808 if self.type is dst_type:
810 elif dst_type.is_float:
811 float_value = float(self.value)
812 return FloatNode(self.pos, value=repr(float_value), constant_result=float_value)
813 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
814 unsigned=self.unsigned, longness=self.longness)
815 if dst_type.is_numeric and not dst_type.is_complex:
817 if dst_type.is_pyobject:
818 node.type = PyrexTypes.py_object_type
819 # We still need to perform normal coerce_to processing on the
820 # result, because we might be coercing to an extension type,
821 # in which case a type test node will be needed.
822 return ConstNode.coerce_to(node, dst_type, env)
824 def coerce_to_boolean(self, env):
826 self.pos, value=self.value,
827 type = PyrexTypes.c_bint_type,
828 unsigned=self.unsigned, longness=self.longness)
830 def generate_evaluation_code(self, code):
831 if self.type.is_pyobject:
832 # pre-allocate a Python version of the number
833 self.result_code = code.get_py_num(self.value, self.longness)
835 self.result_code = self.get_constant_c_result_code()
837 def get_constant_c_result_code(self):
839 if isinstance(value, basestring) and len(value) > 2:
840 # must convert C-incompatible Py3 oct/bin notations
842 value = value[0] + value[2:] # '0o123' => '0123'
843 elif value[1] in 'bB':
844 value = int(value[2:], 2)
845 return str(value) + self.unsigned + self.longness
847 def calculate_result_code(self):
848 return self.result_code
850 def calculate_constant_result(self):
851 self.constant_result = Utils.str_to_number(self.value)
853 def compile_time_value(self, denv):
854 return Utils.str_to_number(self.value)
857 class FloatNode(ConstNode):
858 type = PyrexTypes.c_double_type
860 def calculate_constant_result(self):
861 self.constant_result = float(self.value)
863 def compile_time_value(self, denv):
864 return float(self.value)
866 def calculate_result_code(self):
868 assert isinstance(strval, (str, unicode))
869 cmpval = repr(float(strval))
871 return "(Py_HUGE_VAL * 0)"
872 elif cmpval == 'inf':
874 elif cmpval == '-inf':
875 return "(-Py_HUGE_VAL)"
880 class BytesNode(ConstNode):
881 # A char* or bytes literal
885 type = PyrexTypes.c_char_ptr_type
887 def compile_time_value(self, denv):
890 def analyse_as_type(self, env):
891 type = PyrexTypes.parse_basic_type(self.value)
894 from TreeFragment import TreeFragment
895 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
896 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
897 sizeof_node = declaration.root.stats[0].expr
898 sizeof_node.analyse_types(env)
899 if isinstance(sizeof_node, SizeofTypeNode):
900 return sizeof_node.arg_type
902 def can_coerce_to_char_literal(self):
903 return len(self.value) == 1
905 def coerce_to_boolean(self, env):
906 # This is special because we start off as a C char*. Testing
907 # that for truth directly would yield the wrong result.
908 return BoolNode(self.pos, value=bool(self.value))
910 def coerce_to(self, dst_type, env):
912 if not self.can_coerce_to_char_literal():
913 error(self.pos, "Only single-character string literals can be coerced into ints.")
915 if dst_type is PyrexTypes.c_py_unicode_type:
916 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.")
918 return CharNode(self.pos, value=self.value)
920 node = BytesNode(self.pos, value=self.value)
921 if dst_type == PyrexTypes.c_char_ptr_type:
922 node.type = PyrexTypes.c_char_ptr_type
924 elif dst_type == PyrexTypes.c_uchar_ptr_type:
925 node.type = PyrexTypes.c_char_ptr_type
926 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
928 if not self.type.is_pyobject:
929 if dst_type in (py_object_type, Builtin.bytes_type):
930 node.type = Builtin.bytes_type
931 elif dst_type.is_pyobject:
932 self.fail_assignment(dst_type)
934 elif dst_type.is_pyobject and dst_type is not py_object_type:
935 self.check_for_coercion_error(dst_type, fail=True)
938 # We still need to perform normal coerce_to processing on the
939 # result, because we might be coercing to an extension type,
940 # in which case a type test node will be needed.
941 return ConstNode.coerce_to(node, dst_type, env)
943 def as_py_string_node(self, env):
944 # Return a new BytesNode with the same value as this node
945 # but whose type is a Python type instead of a C type.
946 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
948 def generate_evaluation_code(self, code):
949 if self.type.is_pyobject:
950 self.result_code = code.get_py_string_const(self.value)
952 self.result_code = code.get_string_const(self.value)
954 def get_constant_c_result_code(self):
957 def calculate_result_code(self):
958 return self.result_code
961 class UnicodeNode(PyConstNode):
962 # A Python unicode object
964 # value EncodedString
965 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
970 def coerce_to(self, dst_type, env):
971 if dst_type is self.type:
973 elif dst_type is PyrexTypes.c_py_unicode_type:
974 if not self.can_coerce_to_char_literal():
975 error(self.pos, "Only single-character Unicode string literals can be coerced into Py_UNICODE.")
977 int_value = ord(self.value)
978 return IntNode(self.pos, value=int_value, constant_result=int_value)
979 elif not dst_type.is_pyobject:
980 if dst_type.is_string and self.bytes_value is not None:
981 # special case: '-3' enforced unicode literal used in a C char* context
982 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
983 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE.")
984 elif dst_type is not py_object_type:
985 if not self.check_for_coercion_error(dst_type):
986 self.fail_assignment(dst_type)
989 def can_coerce_to_char_literal(self):
990 return len(self.value) == 1
992 def contains_surrogates(self):
993 # Check if the unicode string contains surrogate code points
994 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
995 # Unicode, i.e. characters that would be spelled as two
996 # separate code units on a narrow platform.
997 for c in map(ord, self.value):
998 if c > 65535: # can only happen on wide platforms
1000 # We only look for the first code unit (D800-DBFF) of a
1001 # surrogate pair - if we find one, the other one
1002 # (DC00-DFFF) is likely there, too. If we don't find it,
1003 # any second code unit cannot make for a surrogate pair by
1005 if c >= 0xD800 and c <= 0xDBFF:
1009 def generate_evaluation_code(self, code):
1010 self.result_code = code.get_py_string_const(self.value)
1012 def calculate_result_code(self):
1013 return self.result_code
1015 def compile_time_value(self, env):
1019 class StringNode(PyConstNode):
1020 # A Python str object, i.e. a byte string in Python 2.x and a
1021 # unicode string in Python 3.x
1023 # value BytesLiteral
1024 # unicode_value EncodedString
1025 # is_identifier boolean
1028 is_identifier = None
1029 unicode_value = None
1031 def coerce_to(self, dst_type, env):
1032 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1033 # if dst_type is Builtin.bytes_type:
1034 # # special case: bytes = 'str literal'
1035 # return BytesNode(self.pos, value=self.value)
1036 if not dst_type.is_pyobject:
1037 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1038 self.check_for_coercion_error(dst_type, fail=True)
1040 # this will be a unicode string in Py3, so make sure we can decode it
1041 if self.value.encoding:
1042 encoding = self.value.encoding
1044 self.value.decode(encoding)
1045 except UnicodeDecodeError:
1046 error(self.pos, "String decoding as '%s' failed. Consider using a byte string or unicode string explicitly, or adjust the source code encoding." % encoding)
1050 def can_coerce_to_char_literal(self):
1051 return not self.is_identifier and len(self.value) == 1
1053 def generate_evaluation_code(self, code):
1054 self.result_code = code.get_py_string_const(
1055 self.value, identifier=self.is_identifier, is_str=True)
1057 def get_constant_c_result_code(self):
1060 def calculate_result_code(self):
1061 return self.result_code
1063 def compile_time_value(self, env):
1067 class IdentifierStringNode(StringNode):
1068 # A special str value that represents an identifier (bytes in Py2,
1070 is_identifier = True
1073 class LongNode(AtomicExprNode):
1074 # Python long integer literal
1078 type = py_object_type
1080 def calculate_constant_result(self):
1081 self.constant_result = Utils.str_to_number(self.value)
1083 def compile_time_value(self, denv):
1084 return Utils.str_to_number(self.value)
1086 def analyse_types(self, env):
1089 def may_be_none(self):
1092 gil_message = "Constructing Python long int"
1094 def generate_result_code(self, code):
1096 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1099 code.error_goto_if_null(self.result(), self.pos)))
1100 code.put_gotref(self.py_result())
1103 class ImagNode(AtomicExprNode):
1104 # Imaginary number literal
1106 # value float imaginary part
1108 type = PyrexTypes.c_double_complex_type
1110 def calculate_constant_result(self):
1111 self.constant_result = complex(0.0, self.value)
1113 def compile_time_value(self, denv):
1114 return complex(0.0, self.value)
1116 def analyse_types(self, env):
1117 self.type.create_declaration_utility_code(env)
1119 def may_be_none(self):
1122 def coerce_to(self, dst_type, env):
1123 if self.type is dst_type:
1125 node = ImagNode(self.pos, value=self.value)
1126 if dst_type.is_pyobject:
1128 node.type = PyrexTypes.py_object_type
1129 # We still need to perform normal coerce_to processing on the
1130 # result, because we might be coercing to an extension type,
1131 # in which case a type test node will be needed.
1132 return AtomicExprNode.coerce_to(node, dst_type, env)
1134 gil_message = "Constructing complex number"
1136 def calculate_result_code(self):
1137 if self.type.is_pyobject:
1138 return self.result()
1140 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1142 def generate_result_code(self, code):
1143 if self.type.is_pyobject:
1145 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1148 code.error_goto_if_null(self.result(), self.pos)))
1149 code.put_gotref(self.py_result())
1152 class NewExprNode(AtomicExprNode):
1156 # cppclass node c++ class to create
1160 def infer_type(self, env):
1161 type = self.cppclass.analyse_as_type(env)
1162 if type is None or not type.is_cpp_class:
1163 error(self.pos, "new operator can only be applied to a C++ class")
1164 self.type = error_type
1167 constructor = type.scope.lookup(u'<init>')
1168 if constructor is None:
1169 return_type = PyrexTypes.CFuncType(type, [])
1170 return_type = PyrexTypes.CPtrType(return_type)
1171 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1172 constructor = type.scope.lookup(u'<init>')
1173 self.class_type = type
1174 self.entry = constructor
1175 self.type = constructor.type
1178 def analyse_types(self, env):
1179 if self.type is None:
1180 self.infer_type(env)
1182 def may_be_none(self):
1185 def generate_result_code(self, code):
1188 def calculate_result_code(self):
1189 return "new " + self.class_type.declaration_code("")
1192 class NameNode(AtomicExprNode):
1193 # Reference to a local or global variable name.
1195 # name string Python name of the variable
1196 # entry Entry Symbol table entry
1197 # type_entry Entry For extension type names, the original type entry
1200 is_cython_module = False
1201 cython_attribute = None
1202 lhs_of_first_assignment = False
1203 is_used_as_rvalue = 0
1207 def create_analysed_rvalue(pos, env, entry):
1208 node = NameNode(pos)
1209 node.analyse_types(env, entry=entry)
1212 def as_cython_attribute(self):
1213 return self.cython_attribute
1215 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1217 def type_dependencies(self, env):
1218 if self.entry is None:
1219 self.entry = env.lookup(self.name)
1220 if self.entry is not None and self.entry.type.is_unspecified:
1221 return (self.entry,)
1225 def infer_type(self, env):
1226 if self.entry is None:
1227 self.entry = env.lookup(self.name)
1228 if self.entry is None:
1229 return py_object_type
1230 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1231 self.name == self.entry.type.name:
1232 # Unfortunately the type attribute of type objects
1233 # is used for the pointer to the type they represent.
1236 return self.entry.type
1238 def compile_time_value(self, denv):
1240 return denv.lookup(self.name)
1242 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1244 def get_constant_c_result_code(self):
1245 if not self.entry or self.entry.type.is_pyobject:
1247 return self.entry.cname
1249 def coerce_to(self, dst_type, env):
1250 # If coercing to a generic pyobject and this is a builtin
1251 # C function with a Python equivalent, manufacture a NameNode
1252 # referring to the Python builtin.
1253 #print "NameNode.coerce_to:", self.name, dst_type ###
1254 if dst_type is py_object_type:
1256 if entry and entry.is_cfunction:
1257 var_entry = entry.as_variable
1259 if var_entry.is_builtin and Options.cache_builtins:
1260 var_entry = env.declare_builtin(var_entry.name, self.pos)
1261 node = NameNode(self.pos, name = self.name)
1262 node.entry = var_entry
1263 node.analyse_rvalue_entry(env)
1265 return super(NameNode, self).coerce_to(dst_type, env)
1267 def analyse_as_module(self, env):
1268 # Try to interpret this as a reference to a cimported module.
1269 # Returns the module scope, or None.
1272 entry = env.lookup(self.name)
1273 if entry and entry.as_module:
1274 return entry.as_module
1277 def analyse_as_type(self, env):
1278 if self.cython_attribute:
1279 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1281 type = PyrexTypes.parse_basic_type(self.name)
1286 entry = env.lookup(self.name)
1287 if entry and entry.is_type:
1292 def analyse_as_extension_type(self, env):
1293 # Try to interpret this as a reference to an extension type.
1294 # Returns the extension type, or None.
1297 entry = env.lookup(self.name)
1298 if entry and entry.is_type and entry.type.is_extension_type:
1303 def analyse_target_declaration(self, env):
1305 self.entry = env.lookup_here(self.name)
1307 if env.directives['warn.undeclared']:
1308 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1309 if env.directives['infer_types'] != False:
1310 type = unspecified_type
1312 type = py_object_type
1313 self.entry = env.declare_var(self.name, type, self.pos)
1314 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1315 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1316 if self.entry.is_declared_generic:
1317 self.result_ctype = py_object_type
1319 def analyse_types(self, env):
1320 if self.entry is None:
1321 self.entry = env.lookup(self.name)
1323 self.entry = env.declare_builtin(self.name, self.pos)
1325 self.type = PyrexTypes.error_type
1330 if entry.type.is_buffer:
1332 Buffer.used_buffer_aux_vars(entry)
1333 if entry.utility_code:
1334 env.use_utility_code(entry.utility_code)
1335 self.analyse_rvalue_entry(env)
1337 def analyse_target_types(self, env):
1338 self.analyse_entry(env)
1339 if not self.is_lvalue():
1340 error(self.pos, "Assignment to non-lvalue '%s'"
1342 self.type = PyrexTypes.error_type
1344 if self.entry.type.is_buffer:
1346 Buffer.used_buffer_aux_vars(self.entry)
1348 def analyse_rvalue_entry(self, env):
1349 #print "NameNode.analyse_rvalue_entry:", self.name ###
1350 #print "Entry:", self.entry.__dict__ ###
1351 self.analyse_entry(env)
1353 if entry.is_declared_generic:
1354 self.result_ctype = py_object_type
1355 if entry.is_pyglobal or entry.is_builtin:
1356 if Options.cache_builtins and entry.is_builtin:
1360 env.use_utility_code(get_name_interned_utility_code)
1361 self.is_used_as_rvalue = 1
1363 def nogil_check(self, env):
1364 if self.is_used_as_rvalue:
1366 if entry.is_builtin:
1367 # if not Options.cache_builtins: # cached builtins are ok
1369 elif entry.is_pyglobal:
1372 gil_message = "Accessing Python global or builtin"
1374 def analyse_entry(self, env):
1375 #print "NameNode.analyse_entry:", self.name ###
1376 self.check_identifier_kind()
1381 def check_identifier_kind(self):
1382 # Check that this is an appropriate kind of name for use in an
1383 # expression. Also finds the variable entry associated with
1384 # an extension type.
1386 if entry.is_type and entry.type.is_extension_type:
1387 self.type_entry = entry
1388 if not (entry.is_const or entry.is_variable
1389 or entry.is_builtin or entry.is_cfunction
1390 or entry.is_cpp_class):
1391 if self.entry.as_variable:
1392 self.entry = self.entry.as_variable
1395 "'%s' is not a constant, variable or function identifier" % self.name)
1397 def is_simple(self):
1398 # If it's not a C variable, it'll be in a temp.
1401 def calculate_target_results(self, env):
1404 def check_const(self):
1406 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1411 def check_const_addr(self):
1413 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1414 self.addr_not_const()
1418 def is_lvalue(self):
1419 return self.entry.is_variable and \
1420 not self.entry.type.is_array and \
1421 not self.entry.is_readonly
1423 def is_ephemeral(self):
1424 # Name nodes are never ephemeral, even if the
1425 # result is in a temporary.
1428 def calculate_result_code(self):
1431 return "<error>" # There was an error earlier
1434 def generate_result_code(self, code):
1435 assert hasattr(self, 'entry')
1438 return # There was an error earlier
1439 if entry.is_builtin and Options.cache_builtins:
1440 return # Lookup already cached
1441 elif entry.is_pyglobal or entry.is_builtin:
1442 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1443 interned_cname = code.intern_identifier(self.entry.name)
1444 if entry.is_builtin:
1445 namespace = Naming.builtins_cname
1446 else: # entry.is_pyglobal
1447 namespace = entry.scope.namespace_cname
1448 code.globalstate.use_utility_code(get_name_interned_utility_code)
1450 '%s = __Pyx_GetName(%s, %s); %s' % (
1454 code.error_goto_if_null(self.result(), self.pos)))
1455 code.put_gotref(self.py_result())
1457 elif entry.is_local and False:
1458 # control flow not good enough yet
1459 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1460 if assigned is False:
1461 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1462 elif not Options.init_local_none and assigned is None:
1463 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1464 (entry.cname, entry.name, code.error_goto(self.pos)))
1465 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1467 def generate_assignment_code(self, rhs, code):
1468 #print "NameNode.generate_assignment_code:", self.name ###
1471 return # There was an error earlier
1473 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1474 and not self.lhs_of_first_assignment):
1475 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1477 # is_pyglobal seems to be True for module level-globals only.
1478 # We use this to access class->tp_dict if necessary.
1479 if entry.is_pyglobal:
1480 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1481 interned_cname = code.intern_identifier(self.entry.name)
1482 namespace = self.entry.scope.namespace_cname
1484 # if the entry is a member we have to cheat: SetAttr does not work
1485 # on types, so we create a descriptor which is then added to tp_dict
1486 code.put_error_if_neg(self.pos,
1487 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1491 rhs.generate_disposal_code(code)
1492 rhs.free_temps(code)
1493 # in Py2.6+, we need to invalidate the method cache
1494 code.putln("PyType_Modified(%s);" %
1495 entry.scope.parent_type.typeptr_cname)
1497 code.put_error_if_neg(self.pos,
1498 'PyObject_SetAttr(%s, %s, %s)' % (
1502 if debug_disposal_code:
1503 print("NameNode.generate_assignment_code:")
1504 print("...generating disposal code for %s" % rhs)
1505 rhs.generate_disposal_code(code)
1506 rhs.free_temps(code)
1508 if self.type.is_buffer:
1509 # Generate code for doing the buffer release/acquisition.
1510 # This might raise an exception in which case the assignment (done
1511 # below) will not happen.
1513 # The reason this is not in a typetest-like node is because the
1514 # variables that the acquired buffer info is stored to is allocated
1515 # per entry and coupled with it.
1516 self.generate_acquire_buffer(rhs, code)
1518 if self.type.is_pyobject:
1519 #print "NameNode.generate_assignment_code: to", self.name ###
1520 #print "...from", rhs ###
1521 #print "...LHS type", self.type, "ctype", self.ctype() ###
1522 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1523 if self.use_managed_ref:
1524 rhs.make_owned_reference(code)
1525 if entry.is_cglobal:
1526 code.put_gotref(self.py_result())
1527 if not self.lhs_of_first_assignment:
1528 if entry.is_local and not Options.init_local_none:
1529 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1530 if initialized is True:
1531 code.put_decref(self.result(), self.ctype())
1532 elif initialized is None:
1533 code.put_xdecref(self.result(), self.ctype())
1535 code.put_decref(self.result(), self.ctype())
1536 if entry.is_cglobal:
1537 code.put_giveref(rhs.py_result())
1539 code.putln('%s = %s;' % (self.result(),
1540 rhs.result_as(self.ctype())))
1541 if debug_disposal_code:
1542 print("NameNode.generate_assignment_code:")
1543 print("...generating post-assignment code for %s" % rhs)
1544 rhs.generate_post_assignment_code(code)
1545 rhs.free_temps(code)
1547 def generate_acquire_buffer(self, rhs, code):
1548 # rhstmp is only used in case the rhs is a complicated expression leading to
1549 # the object, to avoid repeating the same C expression for every reference
1550 # to the rhs. It does NOT hold a reference.
1551 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1553 rhstmp = rhs.result_as(self.ctype())
1555 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1556 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1558 buffer_aux = self.entry.buffer_aux
1559 bufstruct = buffer_aux.buffer_info_var.cname
1561 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1562 is_initialized=not self.lhs_of_first_assignment,
1563 pos=self.pos, code=code)
1566 code.putln("%s = 0;" % rhstmp)
1567 code.funcstate.release_temp(rhstmp)
1569 def generate_deletion_code(self, code):
1570 if self.entry is None:
1571 return # There was an error earlier
1572 if not self.entry.is_pyglobal:
1573 error(self.pos, "Deletion of local or C global name not supported")
1575 code.put_error_if_neg(self.pos,
1576 '__Pyx_DelAttrString(%s, "%s")' % (
1577 Naming.module_cname,
1580 def annotate(self, code):
1581 if hasattr(self, 'is_called') and self.is_called:
1582 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1583 if self.type.is_pyobject:
1584 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1586 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1588 class BackquoteNode(ExprNode):
1593 type = py_object_type
1597 def analyse_types(self, env):
1598 self.arg.analyse_types(env)
1599 self.arg = self.arg.coerce_to_pyobject(env)
1602 gil_message = "Backquote expression"
1604 def calculate_constant_result(self):
1605 self.constant_result = repr(self.arg.constant_result)
1607 def generate_result_code(self, code):
1609 "%s = PyObject_Repr(%s); %s" % (
1611 self.arg.py_result(),
1612 code.error_goto_if_null(self.result(), self.pos)))
1613 code.put_gotref(self.py_result())
1617 class ImportNode(ExprNode):
1618 # Used as part of import statement implementation.
1619 # Implements result =
1620 # __import__(module_name, globals(), None, name_list)
1622 # module_name StringNode dotted name of module
1623 # name_list ListNode or None list of names to be imported
1625 type = py_object_type
1627 subexprs = ['module_name', 'name_list']
1629 def analyse_types(self, env):
1630 self.module_name.analyse_types(env)
1631 self.module_name = self.module_name.coerce_to_pyobject(env)
1633 self.name_list.analyse_types(env)
1634 self.name_list.coerce_to_pyobject(env)
1636 env.use_utility_code(import_utility_code)
1638 gil_message = "Python import"
1640 def generate_result_code(self, code):
1642 name_list_code = self.name_list.py_result()
1644 name_list_code = "0"
1646 "%s = __Pyx_Import(%s, %s); %s" % (
1648 self.module_name.py_result(),
1650 code.error_goto_if_null(self.result(), self.pos)))
1651 code.put_gotref(self.py_result())
1654 class IteratorNode(ExprNode):
1655 # Used as part of for statement implementation.
1657 # allocate_counter_temp/release_counter_temp needs to be called
1658 # by parent (ForInStatNode)
1660 # Implements result = iter(sequence)
1664 type = py_object_type
1666 subexprs = ['sequence']
1668 def analyse_types(self, env):
1669 self.sequence.analyse_types(env)
1670 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1671 not self.sequence.type.is_string:
1672 # C array iteration will be transformed later on
1673 self.type = self.sequence.type
1675 self.sequence = self.sequence.coerce_to_pyobject(env)
1678 gil_message = "Iterating over Python object"
1680 def allocate_counter_temp(self, code):
1681 self.counter_cname = code.funcstate.allocate_temp(
1682 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1684 def release_counter_temp(self, code):
1685 code.funcstate.release_temp(self.counter_cname)
1687 def generate_result_code(self, code):
1688 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1689 raise InternalError("for in carray slice not transformed")
1690 is_builtin_sequence = self.sequence.type is list_type or \
1691 self.sequence.type is tuple_type
1692 may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1693 if is_builtin_sequence:
1695 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1696 elif may_be_a_sequence:
1698 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1699 self.sequence.py_result(),
1700 self.sequence.py_result()))
1701 if may_be_a_sequence:
1703 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1706 self.sequence.py_result(),
1708 code.putln("} else {")
1709 if is_builtin_sequence:
1711 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1712 code.error_goto(self.pos))
1714 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1717 self.sequence.py_result(),
1718 code.error_goto_if_null(self.result(), self.pos)))
1719 code.put_gotref(self.py_result())
1720 if may_be_a_sequence:
1724 class NextNode(AtomicExprNode):
1725 # Used as part of for statement implementation.
1726 # Implements result = iterator.next()
1727 # Created during analyse_types phase.
1728 # The iterator is not owned by this node.
1732 type = py_object_type
1734 def __init__(self, iterator, env):
1735 self.pos = iterator.pos
1736 self.iterator = iterator
1737 if iterator.type.is_ptr or iterator.type.is_array:
1738 self.type = iterator.type.base_type
1741 def generate_result_code(self, code):
1742 sequence_type = self.iterator.sequence.type
1743 if sequence_type is list_type:
1744 type_checks = [(list_type, "List")]
1745 elif sequence_type is tuple_type:
1746 type_checks = [(tuple_type, "Tuple")]
1747 elif not sequence_type.is_builtin_type:
1748 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1752 for py_type, prefix in type_checks:
1753 if len(type_checks) > 1:
1755 "if (likely(Py%s_CheckExact(%s))) {" % (
1756 prefix, self.iterator.py_result()))
1758 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1759 self.iterator.counter_cname,
1761 self.iterator.py_result()))
1763 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1766 self.iterator.py_result(),
1767 self.iterator.counter_cname,
1769 self.iterator.counter_cname))
1770 if len(type_checks) > 1:
1772 if len(type_checks) == 1:
1776 "%s = PyIter_Next(%s);" % (
1778 self.iterator.py_result()))
1782 code.putln(code.error_goto_if_PyErr(self.pos))
1783 code.putln("break;")
1785 code.put_gotref(self.py_result())
1789 class ExcValueNode(AtomicExprNode):
1790 # Node created during analyse_types phase
1791 # of an ExceptClauseNode to fetch the current
1794 type = py_object_type
1796 def __init__(self, pos, env):
1797 ExprNode.__init__(self, pos)
1799 def set_var(self, var):
1802 def calculate_result_code(self):
1805 def generate_result_code(self, code):
1808 def analyse_types(self, env):
1812 class TempNode(ExprNode):
1813 # Node created during analyse_types phase
1814 # of some nodes to hold a temporary value.
1816 # Note: One must call "allocate" and "release" on
1817 # the node during code generation to get/release the temp.
1818 # This is because the temp result is often used outside of
1819 # the regular cycle.
1823 def __init__(self, pos, type, env):
1824 ExprNode.__init__(self, pos)
1826 if type.is_pyobject:
1827 self.result_ctype = py_object_type
1830 def analyse_types(self, env):
1833 def generate_result_code(self, code):
1836 def allocate(self, code):
1837 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1839 def release(self, code):
1840 code.funcstate.release_temp(self.temp_cname)
1841 self.temp_cname = None
1845 return self.temp_cname
1847 assert False, "Remember to call allocate/release on TempNode"
1850 # Do not participate in normal temp alloc/dealloc:
1851 def allocate_temp_result(self, code):
1854 def release_temp_result(self, code):
1857 class PyTempNode(TempNode):
1858 # TempNode holding a Python value.
1860 def __init__(self, pos, env):
1861 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1863 class RawCNameExprNode(ExprNode):
1866 def __init__(self, pos, type=None):
1870 def analyse_types(self, env):
1873 def set_cname(self, cname):
1879 def generate_result_code(self, code):
1883 #-------------------------------------------------------------------
1887 #-------------------------------------------------------------------
1889 class IndexNode(ExprNode):
1890 # Sequence indexing.
1894 # indices [ExprNode]
1895 # is_buffer_access boolean Whether this is a buffer access.
1897 # indices is used on buffer access, index on non-buffer access.
1898 # The former contains a clean list of index parameters, the
1899 # latter whatever Python object is needed for index access.
1901 subexprs = ['base', 'index', 'indices']
1904 def __init__(self, pos, index, *args, **kw):
1905 ExprNode.__init__(self, pos, index=index, *args, **kw)
1908 def calculate_constant_result(self):
1909 self.constant_result = \
1910 self.base.constant_result[self.index.constant_result]
1912 def compile_time_value(self, denv):
1913 base = self.base.compile_time_value(denv)
1914 index = self.index.compile_time_value(denv)
1917 except Exception, e:
1918 self.compile_time_value_error(e)
1920 def is_ephemeral(self):
1921 return self.base.is_ephemeral()
1923 def analyse_target_declaration(self, env):
1926 def analyse_as_type(self, env):
1927 base_type = self.base.analyse_as_type(env)
1928 if base_type and not base_type.is_pyobject:
1929 if base_type.is_cpp_class:
1930 if isinstance(self.index, TupleNode):
1931 template_values = self.index.args
1933 template_values = [self.index]
1935 type_node = Nodes.TemplatedTypeNode(
1937 positional_args = template_values,
1938 keyword_args = None)
1939 return type_node.analyse(env, base_type = base_type)
1941 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1944 def type_dependencies(self, env):
1945 return self.base.type_dependencies(env)
1947 def infer_type(self, env):
1948 base_type = self.base.infer_type(env)
1949 if isinstance(self.index, SliceNode):
1951 if base_type.is_string:
1952 # sliced C strings must coerce to Python
1954 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
1955 # slicing these returns the same type
1958 # TODO: Handle buffers (hopefully without too much redundancy).
1959 return py_object_type
1961 index_type = self.index.infer_type(env)
1962 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
1964 if base_type is unicode_type:
1965 # Py_UNICODE will automatically coerce to a unicode string
1966 # if required, so this is safe. We only infer Py_UNICODE
1967 # when the index is a C integer type. Otherwise, we may
1968 # need to use normal Python item access, in which case
1969 # it's faster to return the one-char unicode string than
1970 # to receive it, throw it away, and potentially rebuild it
1971 # on a subsequent PyObject coercion.
1972 return PyrexTypes.c_py_unicode_type
1973 elif isinstance(self.base, BytesNode):
1974 #if env.global_scope().context.language_level >= 3:
1975 # # infering 'char' can be made to work in Python 3 mode
1976 # return PyrexTypes.c_char_type
1977 # Py2/3 return different types on indexing bytes objects
1978 return py_object_type
1979 elif base_type.is_ptr or base_type.is_array:
1980 return base_type.base_type
1982 # may be slicing or indexing, we don't know
1983 if base_type is unicode_type:
1984 # this type always returns its own type on Python indexing/slicing
1987 # TODO: Handle buffers (hopefully without too much redundancy).
1988 return py_object_type
1990 def analyse_types(self, env):
1991 self.analyse_base_and_index_types(env, getting = 1)
1993 def analyse_target_types(self, env):
1994 self.analyse_base_and_index_types(env, setting = 1)
1996 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
1997 # Note: This might be cleaned up by having IndexNode
1998 # parsed in a saner way and only construct the tuple if
2001 # Note that this function must leave IndexNode in a cloneable state.
2002 # For buffers, self.index is packed out on the initial analysis, and
2003 # when cloning self.indices is copied.
2004 self.is_buffer_access = False
2006 self.base.analyse_types(env)
2007 if self.base.type.is_error:
2008 # Do not visit child tree if base is undeclared to avoid confusing
2010 self.type = PyrexTypes.error_type
2013 is_slice = isinstance(self.index, SliceNode)
2014 # Potentially overflowing index value.
2015 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2016 self.index = self.index.coerce_to_pyobject(env)
2018 # Handle the case where base is a literal char* (and we expect a string, not an int)
2019 if isinstance(self.base, BytesNode) or is_slice:
2020 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2021 self.base = self.base.coerce_to_pyobject(env)
2023 skip_child_analysis = False
2024 buffer_access = False
2025 if self.base.type.is_buffer:
2026 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2028 indices = self.indices
2030 if isinstance(self.index, TupleNode):
2031 indices = self.index.args
2033 indices = [self.index]
2034 if len(indices) == self.base.type.ndim:
2035 buffer_access = True
2036 skip_child_analysis = True
2038 x.analyse_types(env)
2039 if not x.type.is_int:
2040 buffer_access = False
2042 # On cloning, indices is cloned. Otherwise, unpack index into indices
2043 assert not (buffer_access and isinstance(self.index, CloneNode))
2046 self.indices = indices
2048 self.type = self.base.type.dtype
2049 self.is_buffer_access = True
2050 self.buffer_type = self.base.entry.type
2052 if getting and self.type.is_pyobject:
2055 if not self.base.entry.type.writable:
2056 error(self.pos, "Writing to readonly buffer")
2058 self.base.entry.buffer_aux.writable_needed = True
2060 base_type = self.base.type
2061 if isinstance(self.index, TupleNode):
2062 self.index.analyse_types(env, skip_children=skip_child_analysis)
2063 elif not skip_child_analysis:
2064 self.index.analyse_types(env)
2065 self.original_index_type = self.index.type
2066 if base_type is PyrexTypes.c_py_unicode_type:
2067 # we infer Py_UNICODE for unicode strings in some
2068 # cases, but indexing must still work for them
2069 if self.index.constant_result in (0, -1):
2070 # FIXME: we know that this node is redundant -
2071 # currently, this needs to get handled in Optimize.py
2073 self.base = self.base.coerce_to_pyobject(env)
2074 base_type = self.base.type
2075 if base_type.is_pyobject:
2076 if self.index.type.is_int:
2078 and (base_type in (list_type, tuple_type, unicode_type))
2079 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2080 and not env.directives['boundscheck']):
2084 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2086 self.index = self.index.coerce_to_pyobject(env)
2088 if self.index.type.is_int and base_type is unicode_type:
2089 # Py_UNICODE will automatically coerce to a unicode string
2090 # if required, so this is fast and safe
2091 self.type = PyrexTypes.c_py_unicode_type
2092 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2093 self.type = base_type
2095 self.type = py_object_type
2097 if base_type.is_ptr or base_type.is_array:
2098 self.type = base_type.base_type
2100 self.type = base_type
2101 elif self.index.type.is_pyobject:
2102 self.index = self.index.coerce_to(
2103 PyrexTypes.c_py_ssize_t_type, env)
2104 elif not self.index.type.is_int:
2106 "Invalid index type '%s'" %
2108 elif base_type.is_cpp_class:
2109 function = env.lookup_operator("[]", [self.base, self.index])
2110 if function is None:
2111 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2112 self.type = PyrexTypes.error_type
2113 self.result_code = "<error>"
2115 func_type = function.type
2116 if func_type.is_ptr:
2117 func_type = func_type.base_type
2118 self.index = self.index.coerce_to(func_type.args[0].type, env)
2119 self.type = func_type.return_type
2120 if setting and not func_type.return_type.is_reference:
2121 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2124 "Attempting to index non-array type '%s'" %
2126 self.type = PyrexTypes.error_type
2128 gil_message = "Indexing Python object"
2130 def nogil_check(self, env):
2131 if self.is_buffer_access:
2132 if env.directives['boundscheck']:
2133 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2135 elif self.type.is_pyobject:
2136 error(self.pos, "Cannot access buffer with object dtype without gil")
2138 super(IndexNode, self).nogil_check(env)
2141 def check_const_addr(self):
2142 return self.base.check_const_addr() and self.index.check_const()
2144 def is_lvalue(self):
2147 def calculate_result_code(self):
2148 if self.is_buffer_access:
2149 return "(*%s)" % self.buffer_ptr_code
2150 elif self.base.type is list_type:
2151 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2152 elif self.base.type is tuple_type:
2153 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2154 elif self.base.type is unicode_type and self.type is PyrexTypes.c_py_unicode_type:
2155 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2156 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2157 error(self.pos, "Invalid use of pointer slice")
2159 return "(%s[%s])" % (
2160 self.base.result(), self.index.result())
2162 def extra_index_params(self):
2163 if self.index.type.is_int:
2164 if self.original_index_type.signed:
2165 size_adjustment = ""
2167 size_adjustment = "+1"
2168 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2172 def generate_subexpr_evaluation_code(self, code):
2173 self.base.generate_evaluation_code(code)
2174 if not self.indices:
2175 self.index.generate_evaluation_code(code)
2177 for i in self.indices:
2178 i.generate_evaluation_code(code)
2180 def generate_subexpr_disposal_code(self, code):
2181 self.base.generate_disposal_code(code)
2182 if not self.indices:
2183 self.index.generate_disposal_code(code)
2185 for i in self.indices:
2186 i.generate_disposal_code(code)
2188 def free_subexpr_temps(self, code):
2189 self.base.free_temps(code)
2190 if not self.indices:
2191 self.index.free_temps(code)
2193 for i in self.indices:
2196 def generate_result_code(self, code):
2197 if self.is_buffer_access:
2198 if code.globalstate.directives['nonecheck']:
2199 self.put_nonecheck(code)
2200 self.buffer_ptr_code = self.buffer_lookup_code(code)
2201 if self.type.is_pyobject:
2202 # is_temp is True, so must pull out value and incref it.
2203 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2204 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2206 if self.type.is_pyobject:
2207 if self.index.type.is_int:
2208 index_code = self.index.result()
2209 if self.base.type is list_type:
2210 function = "__Pyx_GetItemInt_List"
2211 elif self.base.type is tuple_type:
2212 function = "__Pyx_GetItemInt_Tuple"
2214 function = "__Pyx_GetItemInt"
2215 code.globalstate.use_utility_code(getitem_int_utility_code)
2217 index_code = self.index.py_result()
2218 if self.base.type is dict_type:
2219 function = "__Pyx_PyDict_GetItem"
2220 code.globalstate.use_utility_code(getitem_dict_utility_code)
2222 function = "PyObject_GetItem"
2224 "%s = %s(%s, %s%s); if (!%s) %s" % (
2227 self.base.py_result(),
2229 self.extra_index_params(),
2231 code.error_goto(self.pos)))
2232 code.put_gotref(self.py_result())
2233 elif self.type is PyrexTypes.c_py_unicode_type and self.base.type is unicode_type:
2234 assert self.index.type.is_int
2235 index_code = self.index.result()
2236 function = "__Pyx_GetItemInt_Unicode"
2237 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2239 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2242 self.base.py_result(),
2244 self.extra_index_params(),
2246 code.error_goto(self.pos)))
2248 def generate_setitem_code(self, value_code, code):
2249 if self.index.type.is_int:
2250 function = "__Pyx_SetItemInt"
2251 index_code = self.index.result()
2252 code.globalstate.use_utility_code(setitem_int_utility_code)
2254 index_code = self.index.py_result()
2255 if self.base.type is dict_type:
2256 function = "PyDict_SetItem"
2257 # It would seem that we could specialized lists/tuples, but that
2258 # shouldn't happen here.
2259 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2260 # not a PyObject*, and bad conversion here would give the wrong
2261 # exception. Also, tuples are supposed to be immutable, and raise
2262 # TypeErrors when trying to set their entries (PyTuple_SetItem
2263 # is for creating new tuples from).
2265 function = "PyObject_SetItem"
2267 "if (%s(%s, %s, %s%s) < 0) %s" % (
2269 self.base.py_result(),
2272 self.extra_index_params(),
2273 code.error_goto(self.pos)))
2275 def generate_buffer_setitem_code(self, rhs, code, op=""):
2276 # Used from generate_assignment_code and InPlaceAssignmentNode
2277 if code.globalstate.directives['nonecheck']:
2278 self.put_nonecheck(code)
2279 ptrexpr = self.buffer_lookup_code(code)
2280 if self.buffer_type.dtype.is_pyobject:
2281 # Must manage refcounts. Decref what is already there
2282 # and incref what we put in.
2283 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2284 rhs_code = rhs.result()
2285 code.putln("%s = %s;" % (ptr, ptrexpr))
2286 code.put_gotref("*%s" % ptr)
2287 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2290 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2291 code.put_giveref("*%s" % ptr)
2292 code.funcstate.release_temp(ptr)
2295 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2297 def generate_assignment_code(self, rhs, code):
2298 self.generate_subexpr_evaluation_code(code)
2299 if self.is_buffer_access:
2300 self.generate_buffer_setitem_code(rhs, code)
2301 elif self.type.is_pyobject:
2302 self.generate_setitem_code(rhs.py_result(), code)
2306 self.result(), rhs.result()))
2307 self.generate_subexpr_disposal_code(code)
2308 self.free_subexpr_temps(code)
2309 rhs.generate_disposal_code(code)
2310 rhs.free_temps(code)
2312 def generate_deletion_code(self, code):
2313 self.generate_subexpr_evaluation_code(code)
2314 #if self.type.is_pyobject:
2315 if self.index.type.is_int:
2316 function = "__Pyx_DelItemInt"
2317 index_code = self.index.result()
2318 code.globalstate.use_utility_code(delitem_int_utility_code)
2320 index_code = self.index.py_result()
2321 if self.base.type is dict_type:
2322 function = "PyDict_DelItem"
2324 function = "PyObject_DelItem"
2326 "if (%s(%s, %s%s) < 0) %s" % (
2328 self.base.py_result(),
2330 self.extra_index_params(),
2331 code.error_goto(self.pos)))
2332 self.generate_subexpr_disposal_code(code)
2333 self.free_subexpr_temps(code)
2335 def buffer_lookup_code(self, code):
2336 # Assign indices to temps
2337 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2338 for temp, index in zip(index_temps, self.indices):
2339 code.putln("%s = %s;" % (temp, index.result()))
2340 # Generate buffer access code using these temps
2342 # The above could happen because child_attrs is wrong somewhere so that
2343 # options are not propagated.
2344 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2345 index_signeds=[i.type.signed for i in self.indices],
2346 index_cnames=index_temps,
2347 directives=code.globalstate.directives,
2348 pos=self.pos, code=code)
2350 def put_nonecheck(self, code):
2351 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2352 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2353 code.putln("__Pyx_RaiseNoneIndexingError();")
2354 code.putln(code.error_goto(self.pos))
2357 class SliceIndexNode(ExprNode):
2358 # 2-element slice indexing
2361 # start ExprNode or None
2362 # stop ExprNode or None
2364 subexprs = ['base', 'start', 'stop']
2366 def infer_type(self, env):
2367 base_type = self.base.infer_type(env)
2368 if base_type.is_string:
2370 elif base_type in (bytes_type, str_type, unicode_type,
2371 list_type, tuple_type):
2373 return py_object_type
2375 def calculate_constant_result(self):
2376 self.constant_result = self.base.constant_result[
2377 self.start.constant_result : self.stop.constant_result]
2379 def compile_time_value(self, denv):
2380 base = self.base.compile_time_value(denv)
2381 if self.start is None:
2384 start = self.start.compile_time_value(denv)
2385 if self.stop is None:
2388 stop = self.stop.compile_time_value(denv)
2390 return base[start:stop]
2391 except Exception, e:
2392 self.compile_time_value_error(e)
2394 def analyse_target_declaration(self, env):
2397 def analyse_target_types(self, env):
2398 self.analyse_types(env)
2399 # when assigning, we must accept any Python type
2400 if self.type.is_pyobject:
2401 self.type = py_object_type
2403 def analyse_types(self, env):
2404 self.base.analyse_types(env)
2406 self.start.analyse_types(env)
2408 self.stop.analyse_types(env)
2409 base_type = self.base.type
2410 if base_type.is_string:
2411 self.type = bytes_type
2412 elif base_type.is_ptr:
2413 self.type = base_type
2414 elif base_type.is_array:
2415 # we need a ptr type here instead of an array type, as
2416 # array types can result in invalid type casts in the C
2418 self.type = PyrexTypes.CPtrType(base_type.base_type)
2420 self.base = self.base.coerce_to_pyobject(env)
2421 self.type = py_object_type
2422 if base_type.is_builtin_type:
2423 # slicing builtin types returns something of the same type
2424 self.type = base_type
2425 c_int = PyrexTypes.c_py_ssize_t_type
2427 self.start = self.start.coerce_to(c_int, env)
2429 self.stop = self.stop.coerce_to(c_int, env)
2432 nogil_check = Node.gil_error
2433 gil_message = "Slicing Python object"
2435 def generate_result_code(self, code):
2436 if not self.type.is_pyobject:
2438 "Slicing is not currently supported for '%s'." % self.type)
2440 if self.base.type.is_string:
2441 if self.stop is None:
2443 "%s = PyBytes_FromString(%s + %s); %s" % (
2447 code.error_goto_if_null(self.result(), self.pos)))
2450 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2456 code.error_goto_if_null(self.result(), self.pos)))
2459 "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
2461 self.base.py_result(),
2464 code.error_goto_if_null(self.result(), self.pos)))
2465 code.put_gotref(self.py_result())
2467 def generate_assignment_code(self, rhs, code):
2468 self.generate_subexpr_evaluation_code(code)
2469 if self.type.is_pyobject:
2470 code.put_error_if_neg(self.pos,
2471 "PySequence_SetSlice(%s, %s, %s, %s)" % (
2472 self.base.py_result(),
2479 start_offset = self.start_code()
2480 if start_offset == '0':
2484 if rhs.type.is_array:
2485 array_length = rhs.type.size
2486 self.generate_slice_guard_code(code, array_length)
2489 "Slice assignments from pointers are not yet supported.")
2490 # FIXME: fix the array size according to start/stop
2491 array_length = self.base.type.size
2492 for i in range(array_length):
2493 code.putln("%s[%s%s] = %s[%d];" % (
2494 self.base.result(), start_offset, i,
2496 self.generate_subexpr_disposal_code(code)
2497 self.free_subexpr_temps(code)
2498 rhs.generate_disposal_code(code)
2499 rhs.free_temps(code)
2501 def generate_deletion_code(self, code):
2502 if not self.base.type.is_pyobject:
2504 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2506 self.generate_subexpr_evaluation_code(code)
2507 code.put_error_if_neg(self.pos,
2508 "PySequence_DelSlice(%s, %s, %s)" % (
2509 self.base.py_result(),
2512 self.generate_subexpr_disposal_code(code)
2514 def generate_slice_guard_code(self, code, target_size):
2515 if not self.base.type.is_array:
2517 slice_size = self.base.type.size
2520 stop = self.stop.result()
2524 slice_size = self.base.type.size + stop
2531 start = self.start.result()
2535 start = self.base.type.size + start
2543 error(self.pos, "Assignment to empty slice.")
2544 elif start is None and stop is None:
2545 # we know the exact slice length
2546 if target_size != slice_size:
2547 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2548 slice_size, target_size))
2549 elif start is not None:
2552 check = "(%s)-(%s)" % (stop, start)
2553 else: # stop is not None:
2556 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2557 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));' % (
2558 target_size, check))
2559 code.putln(code.error_goto(self.pos))
2562 def start_code(self):
2564 return self.start.result()
2568 def stop_code(self):
2570 return self.stop.result()
2571 elif self.base.type.is_array:
2572 return self.base.type.size
2574 return "PY_SSIZE_T_MAX"
2576 def calculate_result_code(self):
2577 # self.result() is not used, but this method must exist
2581 class SliceNode(ExprNode):
2582 # start:stop:step in subscript list
2588 type = py_object_type
2591 def calculate_constant_result(self):
2592 self.constant_result = self.base.constant_result[
2593 self.start.constant_result : \
2594 self.stop.constant_result : \
2595 self.step.constant_result]
2597 def compile_time_value(self, denv):
2598 start = self.start.compile_time_value(denv)
2599 if self.stop is None:
2602 stop = self.stop.compile_time_value(denv)
2603 if self.step is None:
2606 step = self.step.compile_time_value(denv)
2608 return slice(start, stop, step)
2609 except Exception, e:
2610 self.compile_time_value_error(e)
2612 subexprs = ['start', 'stop', 'step']
2614 def analyse_types(self, env):
2615 self.start.analyse_types(env)
2616 self.stop.analyse_types(env)
2617 self.step.analyse_types(env)
2618 self.start = self.start.coerce_to_pyobject(env)
2619 self.stop = self.stop.coerce_to_pyobject(env)
2620 self.step = self.step.coerce_to_pyobject(env)
2622 gil_message = "Constructing Python slice object"
2624 def generate_result_code(self, code):
2626 "%s = PySlice_New(%s, %s, %s); %s" % (
2628 self.start.py_result(),
2629 self.stop.py_result(),
2630 self.step.py_result(),
2631 code.error_goto_if_null(self.result(), self.pos)))
2632 code.put_gotref(self.py_result())
2635 class CallNode(ExprNode):
2637 # allow overriding the default 'may_be_none' behaviour
2638 may_return_none = None
2640 def may_be_none(self):
2641 if self.may_return_none is not None:
2642 return self.may_return_none
2643 return ExprNode.may_be_none(self)
2645 def analyse_as_type_constructor(self, env):
2646 type = self.function.analyse_as_type(env)
2647 if type and type.is_struct_or_union:
2648 args, kwds = self.explicit_args_kwds()
2650 for arg, member in zip(args, type.scope.var_entries):
2651 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2653 items += kwds.key_value_pairs
2654 self.key_value_pairs = items
2655 self.__class__ = DictNode
2656 self.analyse_types(env)
2657 self.coerce_to(type, env)
2659 elif type and type.is_cpp_class:
2660 for arg in self.args:
2661 arg.analyse_types(env)
2662 constructor = type.scope.lookup("<init>")
2663 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2664 self.function.entry = constructor
2665 self.function.set_cname(type.declaration_code(""))
2666 self.analyse_c_function_call(env)
2669 def is_lvalue(self):
2670 return self.type.is_reference
2672 def nogil_check(self, env):
2673 func_type = self.function_type()
2674 if func_type.is_pyobject:
2676 elif not getattr(func_type, 'nogil', False):
2679 gil_message = "Calling gil-requiring function"
2682 class SimpleCallNode(CallNode):
2683 # Function call without keyword, * or ** args.
2687 # arg_tuple ExprNode or None used internally
2688 # self ExprNode or None used internally
2689 # coerced_self ExprNode or None used internally
2690 # wrapper_call bool used internally
2691 # has_optional_args bool used internally
2693 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2698 wrapper_call = False
2699 has_optional_args = False
2701 def compile_time_value(self, denv):
2702 function = self.function.compile_time_value(denv)
2703 args = [arg.compile_time_value(denv) for arg in self.args]
2705 return function(*args)
2706 except Exception, e:
2707 self.compile_time_value_error(e)
2709 def type_dependencies(self, env):
2710 # TODO: Update when Danilo's C++ code merged in to handle the
2711 # the case of function overloading.
2712 return self.function.type_dependencies(env)
2714 def infer_type(self, env):
2715 function = self.function
2716 func_type = function.infer_type(env)
2717 if isinstance(self.function, NewExprNode):
2718 return PyrexTypes.CPtrType(self.function.class_type)
2719 if func_type.is_ptr:
2720 func_type = func_type.base_type
2721 if func_type.is_cfunction:
2722 return func_type.return_type
2723 elif func_type is type_type:
2724 if function.is_name and function.entry and function.entry.type:
2725 result_type = function.entry.type
2726 if result_type.is_extension_type:
2728 elif result_type.is_builtin_type:
2729 if function.entry.name == 'float':
2730 return PyrexTypes.c_double_type
2731 elif function.entry.name in Builtin.types_that_construct_their_instance:
2733 return py_object_type
2735 def analyse_as_type(self, env):
2736 attr = self.function.as_cython_attribute()
2737 if attr == 'pointer':
2738 if len(self.args) != 1:
2739 error(self.args.pos, "only one type allowed.")
2741 type = self.args[0].analyse_as_type(env)
2743 error(self.args[0].pos, "Unknown type")
2745 return PyrexTypes.CPtrType(type)
2747 def explicit_args_kwds(self):
2748 return self.args, None
2750 def analyse_types(self, env):
2751 if self.analyse_as_type_constructor(env):
2753 function = self.function
2754 function.is_called = 1
2755 self.function.analyse_types(env)
2756 if function.is_attribute and function.entry and function.entry.is_cmethod:
2757 # Take ownership of the object from which the attribute
2758 # was obtained, because we need to pass it as 'self'.
2759 self.self = function.obj
2760 function.obj = CloneNode(self.self)
2761 func_type = self.function_type()
2762 if func_type.is_pyobject:
2763 self.arg_tuple = TupleNode(self.pos, args = self.args)
2764 self.arg_tuple.analyse_types(env)
2766 if func_type is Builtin.type_type and function.is_name and \
2767 function.entry and \
2768 function.entry.is_builtin and \
2769 function.entry.name in Builtin.types_that_construct_their_instance:
2770 # calling a builtin type that returns a specific object type
2771 if function.entry.name == 'float':
2772 # the following will come true later on in a transform
2773 self.type = PyrexTypes.c_double_type
2774 self.result_ctype = PyrexTypes.c_double_type
2776 self.type = Builtin.builtin_types[function.entry.name]
2777 self.result_ctype = py_object_type
2778 self.may_return_none = False
2779 elif function.is_name and function.type_entry:
2780 # We are calling an extension type constructor. As
2781 # long as we do not support __new__(), the result type
2783 self.type = function.type_entry.type
2784 self.result_ctype = py_object_type
2785 self.may_return_none = False
2787 self.type = py_object_type
2790 for arg in self.args:
2791 arg.analyse_types(env)
2792 if self.self and func_type.args:
2793 # Coerce 'self' to the type expected by the method.
2794 expected_type = func_type.args[0].type
2795 self.coerced_self = CloneNode(self.self).coerce_to(
2797 # Insert coerced 'self' argument into argument list.
2798 self.args.insert(0, self.coerced_self)
2799 self.analyse_c_function_call(env)
2801 def function_type(self):
2802 # Return the type of the function being called, coercing a function
2803 # pointer to a function if necessary.
2804 func_type = self.function.type
2805 if func_type.is_ptr:
2806 func_type = func_type.base_type
2809 def analyse_c_function_call(self, env):
2810 if self.function.type is error_type:
2811 self.type = error_type
2813 if self.function.type.is_cpp_class:
2814 overloaded_entry = self.function.type.scope.lookup("operator()")
2815 if overloaded_entry is None:
2816 self.type = PyrexTypes.error_type
2817 self.result_code = "<error>"
2819 elif hasattr(self.function, 'entry'):
2820 overloaded_entry = self.function.entry
2822 overloaded_entry = None
2823 if overloaded_entry:
2824 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2826 self.type = PyrexTypes.error_type
2827 self.result_code = "<error>"
2829 self.function.entry = entry
2830 self.function.type = entry.type
2831 func_type = self.function_type()
2833 func_type = self.function_type()
2834 if not func_type.is_cfunction:
2835 error(self.pos, "Calling non-function type '%s'" % func_type)
2836 self.type = PyrexTypes.error_type
2837 self.result_code = "<error>"
2840 max_nargs = len(func_type.args)
2841 expected_nargs = max_nargs - func_type.optional_arg_count
2842 actual_nargs = len(self.args)
2843 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2844 self.has_optional_args = 1
2847 for i in range(min(max_nargs, actual_nargs)):
2848 formal_type = func_type.args[i].type
2849 self.args[i] = self.args[i].coerce_to(formal_type, env)
2850 for i in range(max_nargs, actual_nargs):
2851 if self.args[i].type.is_pyobject:
2852 error(self.args[i].pos,
2853 "Python object cannot be passed as a varargs parameter")
2854 # Calc result type and code fragment
2855 if isinstance(self.function, NewExprNode):
2856 self.type = PyrexTypes.CPtrType(self.function.class_type)
2858 self.type = func_type.return_type
2859 if self.type.is_pyobject:
2860 self.result_ctype = py_object_type
2862 elif func_type.exception_value is not None \
2863 or func_type.exception_check:
2865 # C++ exception handler
2866 if func_type.exception_check == '+':
2867 if func_type.exception_value is None:
2868 env.use_utility_code(cpp_exception_utility_code)
2870 def calculate_result_code(self):
2871 return self.c_call_code()
2873 def c_call_code(self):
2874 func_type = self.function_type()
2875 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2877 formal_args = func_type.args
2879 args = zip(formal_args, self.args)
2880 max_nargs = len(func_type.args)
2881 expected_nargs = max_nargs - func_type.optional_arg_count
2882 actual_nargs = len(self.args)
2883 for formal_arg, actual_arg in args[:expected_nargs]:
2884 arg_code = actual_arg.result_as(formal_arg.type)
2885 arg_list_code.append(arg_code)
2887 if func_type.is_overridable:
2888 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2890 if func_type.optional_arg_count:
2891 if expected_nargs == actual_nargs:
2892 optional_args = 'NULL'
2894 optional_args = "&%s" % self.opt_arg_struct
2895 arg_list_code.append(optional_args)
2897 for actual_arg in self.args[len(formal_args):]:
2898 arg_list_code.append(actual_arg.result())
2899 result = "%s(%s)" % (self.function.result(),
2900 ', '.join(arg_list_code))
2903 def generate_result_code(self, code):
2904 func_type = self.function_type()
2905 if func_type.is_pyobject:
2906 arg_code = self.arg_tuple.py_result()
2908 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2910 self.function.py_result(),
2912 code.error_goto_if_null(self.result(), self.pos)))
2913 code.put_gotref(self.py_result())
2914 elif func_type.is_cfunction:
2915 if self.has_optional_args:
2916 actual_nargs = len(self.args)
2917 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2918 self.opt_arg_struct = code.funcstate.allocate_temp(
2919 func_type.op_arg_struct.base_type, manage_ref=True)
2920 code.putln("%s.%s = %s;" % (
2921 self.opt_arg_struct,
2922 Naming.pyrex_prefix + "n",
2923 len(self.args) - expected_nargs))
2924 args = zip(func_type.args, self.args)
2925 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2926 code.putln("%s.%s = %s;" % (
2927 self.opt_arg_struct,
2928 func_type.opt_arg_cname(formal_arg.name),
2929 actual_arg.result_as(formal_arg.type)))
2931 if self.type.is_pyobject and self.is_temp:
2932 exc_checks.append("!%s" % self.result())
2934 exc_val = func_type.exception_value
2935 exc_check = func_type.exception_check
2936 if exc_val is not None:
2937 exc_checks.append("%s == %s" % (self.result(), exc_val))
2939 exc_checks.append("PyErr_Occurred()")
2940 if self.is_temp or exc_checks:
2941 rhs = self.c_call_code()
2943 lhs = "%s = " % self.result()
2944 if self.is_temp and self.type.is_pyobject:
2945 #return_type = self.type # func_type.return_type
2946 #print "SimpleCallNode.generate_result_code: casting", rhs, \
2947 # "from", return_type, "to pyobject" ###
2948 rhs = typecast(py_object_type, self.type, rhs)
2951 if func_type.exception_check == '+':
2952 if func_type.exception_value is None:
2953 raise_py_exception = "__Pyx_CppExn2PyErr()"
2954 elif func_type.exception_value.type.is_pyobject:
2955 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
2956 func_type.exception_value.entry.cname,
2957 func_type.exception_value.entry.cname)
2959 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
2961 "try {%s%s;} catch(...) {%s; %s}" % (
2965 code.error_goto(self.pos)))
2968 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
2971 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
2972 if self.type.is_pyobject and self.result():
2973 code.put_gotref(self.py_result())
2974 if self.has_optional_args:
2975 code.funcstate.release_temp(self.opt_arg_struct)
2978 class PythonCapiFunctionNode(ExprNode):
2980 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
2984 self.type = func_type
2985 self.utility_code = utility_code
2987 def analyse_types(self, env):
2990 def generate_result_code(self, code):
2991 if self.utility_code:
2992 code.globalstate.use_utility_code(self.utility_code)
2994 def calculate_result_code(self):
2997 class PythonCapiCallNode(SimpleCallNode):
2998 # Python C-API Function call (only created in transforms)
3000 # By default, we assume that the call never returns None, as this
3001 # is true for most C-API functions in CPython. If this does not
3002 # apply to a call, set the following to True (or None to inherit
3003 # the default behaviour).
3004 may_return_none = False
3006 def __init__(self, pos, function_name, func_type,
3007 utility_code = None, py_name=None, **kwargs):
3008 self.type = func_type.return_type
3009 self.result_ctype = self.type
3010 self.function = PythonCapiFunctionNode(
3011 pos, py_name, function_name, func_type,
3012 utility_code = utility_code)
3013 # call this last so that we can override the constructed
3014 # attributes above with explicit keyword arguments if required
3015 SimpleCallNode.__init__(self, pos, **kwargs)
3018 class GeneralCallNode(CallNode):
3019 # General Python function call, including keyword,
3020 # * and ** arguments.
3023 # positional_args ExprNode Tuple of positional arguments
3024 # keyword_args ExprNode or None Dict of keyword arguments
3025 # starstar_arg ExprNode or None Dict of extra keyword args
3027 type = py_object_type
3029 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3031 nogil_check = Node.gil_error
3033 def compile_time_value(self, denv):
3034 function = self.function.compile_time_value(denv)
3035 positional_args = self.positional_args.compile_time_value(denv)
3036 keyword_args = self.keyword_args.compile_time_value(denv)
3037 starstar_arg = self.starstar_arg.compile_time_value(denv)
3039 keyword_args.update(starstar_arg)
3040 return function(*positional_args, **keyword_args)
3041 except Exception, e:
3042 self.compile_time_value_error(e)
3044 def explicit_args_kwds(self):
3045 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3046 raise PostParseError(self.pos,
3047 'Compile-time keyword arguments must be explicit.')
3048 return self.positional_args.args, self.keyword_args
3050 def analyse_types(self, env):
3051 if self.analyse_as_type_constructor(env):
3053 self.function.analyse_types(env)
3054 self.positional_args.analyse_types(env)
3055 if self.keyword_args:
3056 self.keyword_args.analyse_types(env)
3057 if self.starstar_arg:
3058 self.starstar_arg.analyse_types(env)
3059 if not self.function.type.is_pyobject:
3060 if self.function.type.is_error:
3061 self.type = error_type
3063 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3064 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3066 self.function = self.function.coerce_to_pyobject(env)
3067 self.positional_args = \
3068 self.positional_args.coerce_to_pyobject(env)
3069 if self.starstar_arg:
3070 self.starstar_arg = \
3071 self.starstar_arg.coerce_to_pyobject(env)
3072 function = self.function
3073 if function.is_name and function.type_entry:
3074 # We are calling an extension type constructor. As long
3075 # as we do not support __new__(), the result type is clear
3076 self.type = function.type_entry.type
3077 self.result_ctype = py_object_type
3078 self.may_return_none = False
3080 self.type = py_object_type
3083 def generate_result_code(self, code):
3084 if self.type.is_error: return
3085 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3086 if self.keyword_args and self.starstar_arg:
3087 code.put_error_if_neg(self.pos,
3088 "PyDict_Update(%s, %s)" % (
3089 self.keyword_args.py_result(),
3090 self.starstar_arg.py_result()))
3091 keyword_code = self.keyword_args.py_result()
3092 elif self.keyword_args:
3093 keyword_code = self.keyword_args.py_result()
3094 elif self.starstar_arg:
3095 keyword_code = self.starstar_arg.py_result()
3096 if self.starstar_arg.type is not Builtin.dict_type:
3097 # CPython supports calling functions with non-dicts, so do we
3098 code.globalstate.use_utility_code(kwargs_call_utility_code)
3099 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3102 if not keyword_code:
3103 call_code = "PyObject_Call(%s, %s, NULL)" % (
3104 self.function.py_result(),
3105 self.positional_args.py_result())
3107 call_code = "%s(%s, %s, %s)" % (
3108 kwargs_call_function,
3109 self.function.py_result(),
3110 self.positional_args.py_result(),
3116 code.error_goto_if_null(self.result(), self.pos)))
3117 code.put_gotref(self.py_result())
3120 class AsTupleNode(ExprNode):
3121 # Convert argument to tuple. Used for normalising
3122 # the * argument of a function call.
3128 def calculate_constant_result(self):
3129 self.constant_result = tuple(self.base.constant_result)
3131 def compile_time_value(self, denv):
3132 arg = self.arg.compile_time_value(denv)
3135 except Exception, e:
3136 self.compile_time_value_error(e)
3138 def analyse_types(self, env):
3139 self.arg.analyse_types(env)
3140 self.arg = self.arg.coerce_to_pyobject(env)
3141 self.type = tuple_type
3144 def may_be_none(self):
3147 nogil_check = Node.gil_error
3148 gil_message = "Constructing Python tuple"
3150 def generate_result_code(self, code):
3152 "%s = PySequence_Tuple(%s); %s" % (
3154 self.arg.py_result(),
3155 code.error_goto_if_null(self.result(), self.pos)))
3156 code.put_gotref(self.py_result())
3159 class AttributeNode(ExprNode):
3164 # needs_none_check boolean Used if obj is an extension type.
3165 # If set to True, it is known that the type is not None.
3169 # is_py_attr boolean Is a Python getattr operation
3170 # member string C name of struct member
3171 # is_called boolean Function call is being done on result
3172 # entry Entry Symbol table entry of attribute
3177 type = PyrexTypes.error_type
3180 needs_none_check = True
3182 def as_cython_attribute(self):
3183 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3184 return self.attribute
3185 cy = self.obj.as_cython_attribute()
3187 return "%s.%s" % (cy, self.attribute)
3189 def coerce_to(self, dst_type, env):
3190 # If coercing to a generic pyobject and this is a cpdef function
3191 # we can create the corresponding attribute
3192 if dst_type is py_object_type:
3194 if entry and entry.is_cfunction and entry.as_variable:
3195 # must be a cpdef function
3197 self.entry = entry.as_variable
3198 self.analyse_as_python_attribute(env)
3200 return ExprNode.coerce_to(self, dst_type, env)
3202 def calculate_constant_result(self):
3203 attr = self.attribute
3204 if attr.startswith("__") and attr.endswith("__"):
3206 self.constant_result = getattr(self.obj.constant_result, attr)
3208 def compile_time_value(self, denv):
3209 attr = self.attribute
3210 if attr.startswith("__") and attr.endswith("__"):
3212 "Invalid attribute name '%s' in compile-time expression" % attr)
3214 obj = self.obj.compile_time_value(denv)
3216 return getattr(obj, attr)
3217 except Exception, e:
3218 self.compile_time_value_error(e)
3220 def type_dependencies(self, env):
3221 return self.obj.type_dependencies(env)
3223 def infer_type(self, env):
3224 if self.analyse_as_cimported_attribute(env, 0):
3225 return self.entry.type
3226 elif self.analyse_as_unbound_cmethod(env):
3227 return self.entry.type
3229 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3232 def analyse_target_declaration(self, env):
3235 def analyse_target_types(self, env):
3236 self.analyse_types(env, target = 1)
3238 def analyse_types(self, env, target = 0):
3239 if self.analyse_as_cimported_attribute(env, target):
3241 if not target and self.analyse_as_unbound_cmethod(env):
3243 self.analyse_as_ordinary_attribute(env, target)
3245 def analyse_as_cimported_attribute(self, env, target):
3246 # Try to interpret this as a reference to an imported
3247 # C const, type, var or function. If successful, mutates
3248 # this node into a NameNode and returns 1, otherwise
3250 module_scope = self.obj.analyse_as_module(env)
3252 entry = module_scope.lookup_here(self.attribute)
3254 entry.is_cglobal or entry.is_cfunction
3255 or entry.is_type or entry.is_const):
3256 self.mutate_into_name_node(env, entry, target)
3260 def analyse_as_unbound_cmethod(self, env):
3261 # Try to interpret this as a reference to an unbound
3262 # C method of an extension type. If successful, mutates
3263 # this node into a NameNode and returns 1, otherwise
3265 type = self.obj.analyse_as_extension_type(env)
3267 entry = type.scope.lookup_here(self.attribute)
3268 if entry and entry.is_cmethod:
3269 # Create a temporary entry describing the C method
3270 # as an ordinary function.
3271 ubcm_entry = Symtab.Entry(entry.name,
3272 "%s->%s" % (type.vtabptr_cname, entry.cname),
3274 ubcm_entry.is_cfunction = 1
3275 ubcm_entry.func_cname = entry.func_cname
3276 ubcm_entry.is_unbound_cmethod = 1
3277 self.mutate_into_name_node(env, ubcm_entry, None)
3281 def analyse_as_type(self, env):
3282 module_scope = self.obj.analyse_as_module(env)
3284 return module_scope.lookup_type(self.attribute)
3285 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3286 base_type = self.obj.analyse_as_type(env)
3287 if base_type and hasattr(base_type, 'scope'):
3288 return base_type.scope.lookup_type(self.attribute)
3291 def analyse_as_extension_type(self, env):
3292 # Try to interpret this as a reference to an extension type
3293 # in a cimported module. Returns the extension type, or None.
3294 module_scope = self.obj.analyse_as_module(env)
3296 entry = module_scope.lookup_here(self.attribute)
3297 if entry and entry.is_type and entry.type.is_extension_type:
3301 def analyse_as_module(self, env):
3302 # Try to interpret this as a reference to a cimported module
3303 # in another cimported module. Returns the module scope, or None.
3304 module_scope = self.obj.analyse_as_module(env)
3306 entry = module_scope.lookup_here(self.attribute)
3307 if entry and entry.as_module:
3308 return entry.as_module
3311 def mutate_into_name_node(self, env, entry, target):
3312 # Mutate this node into a NameNode and complete the
3313 # analyse_types phase.
3314 self.__class__ = NameNode
3315 self.name = self.attribute
3320 NameNode.analyse_target_types(self, env)
3322 NameNode.analyse_rvalue_entry(self, env)
3324 def analyse_as_ordinary_attribute(self, env, target):
3325 self.obj.analyse_types(env)
3326 self.analyse_attribute(env)
3327 if self.entry and self.entry.is_cmethod and not self.is_called:
3328 # error(self.pos, "C method can only be called")
3330 ## Reference to C array turns into pointer to first element.
3331 #while self.type.is_array:
3332 # self.type = self.type.element_ptr_type()
3336 self.result_ctype = py_object_type
3338 def analyse_attribute(self, env, obj_type = None):
3339 # Look up attribute and set self.type and self.member.
3341 self.member = self.attribute
3342 if obj_type is None:
3343 if self.obj.type.is_string:
3344 self.obj = self.obj.coerce_to_pyobject(env)
3345 obj_type = self.obj.type
3347 if obj_type.is_string:
3348 obj_type = py_object_type
3349 if obj_type.is_ptr or obj_type.is_array:
3350 obj_type = obj_type.base_type
3352 elif obj_type.is_extension_type:
3356 if obj_type.has_attributes:
3358 if obj_type.attributes_known():
3359 entry = obj_type.scope.lookup_here(self.attribute)
3360 if entry and entry.is_member:
3364 "Cannot select attribute of incomplete type '%s'"
3366 self.type = PyrexTypes.error_type
3370 if obj_type.is_extension_type and entry.name == "__weakref__":
3371 error(self.pos, "Illegal use of special attribute __weakref__")
3372 # methods need the normal attribute lookup
3373 # because they do not have struct entries
3374 if entry.is_variable or entry.is_cmethod:
3375 self.type = entry.type
3376 self.member = entry.cname
3379 # If it's not a variable or C method, it must be a Python
3380 # method of an extension type, so we treat it like a Python
3383 # If we get here, the base object is not a struct/union/extension
3384 # type, or it is an extension type and the attribute is either not
3385 # declared or is declared as a Python method. Treat it as a Python
3386 # attribute reference.
3387 self.analyse_as_python_attribute(env, obj_type)
3389 def analyse_as_python_attribute(self, env, obj_type = None):
3390 if obj_type is None:
3391 obj_type = self.obj.type
3392 self.member = self.attribute
3393 self.type = py_object_type
3395 if not obj_type.is_pyobject and not obj_type.is_error:
3396 if obj_type.can_coerce_to_pyobject(env):
3397 self.obj = self.obj.coerce_to_pyobject(env)
3400 "Object of type '%s' has no attribute '%s'" %
3401 (obj_type, self.attribute))
3403 def nogil_check(self, env):
3407 gil_message = "Accessing Python attribute"
3409 def is_simple(self):
3411 return self.result_in_temp() or self.obj.is_simple()
3413 return NameNode.is_simple(self)
3415 def is_lvalue(self):
3419 return NameNode.is_lvalue(self)
3421 def is_ephemeral(self):
3423 return self.obj.is_ephemeral()
3425 return NameNode.is_ephemeral(self)
3427 def calculate_result_code(self):
3428 #print "AttributeNode.calculate_result_code:", self.member ###
3429 #print "...obj node =", self.obj, "code", self.obj.result() ###
3430 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3432 obj_code = obj.result_as(obj.type)
3433 #print "...obj_code =", obj_code ###
3434 if self.entry and self.entry.is_cmethod:
3435 if obj.type.is_extension_type:
3436 return "((struct %s *)%s%s%s)->%s" % (
3437 obj.type.vtabstruct_cname, obj_code, self.op,
3438 obj.type.vtabslot_cname, self.member)
3441 elif obj.type.is_complex:
3442 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3444 return "%s%s%s" % (obj_code, self.op, self.member)
3446 def generate_result_code(self, code):
3447 interned_attr_cname = code.intern_identifier(self.attribute)
3450 '%s = PyObject_GetAttr(%s, %s); %s' % (
3452 self.obj.py_result(),
3453 interned_attr_cname,
3454 code.error_goto_if_null(self.result(), self.pos)))
3455 code.put_gotref(self.py_result())
3457 # result_code contains what is needed, but we may need to insert
3458 # a check and raise an exception
3459 if (self.obj.type.is_extension_type
3460 and self.needs_none_check
3461 and code.globalstate.directives['nonecheck']):
3462 self.put_nonecheck(code)
3464 def generate_assignment_code(self, rhs, code):
3465 interned_attr_cname = code.intern_identifier(self.attribute)
3466 self.obj.generate_evaluation_code(code)
3468 code.put_error_if_neg(self.pos,
3469 'PyObject_SetAttr(%s, %s, %s)' % (
3470 self.obj.py_result(),
3471 interned_attr_cname,
3473 rhs.generate_disposal_code(code)
3474 rhs.free_temps(code)
3475 elif self.obj.type.is_complex:
3476 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3477 self.member.upper(),
3478 self.obj.result_as(self.obj.type),
3479 rhs.result_as(self.ctype())))
3481 if (self.obj.type.is_extension_type
3482 and self.needs_none_check
3483 and code.globalstate.directives['nonecheck']):
3484 self.put_nonecheck(code)
3486 select_code = self.result()
3487 if self.type.is_pyobject and self.use_managed_ref:
3488 rhs.make_owned_reference(code)
3489 code.put_giveref(rhs.py_result())
3490 code.put_gotref(select_code)
3491 code.put_decref(select_code, self.ctype())
3495 rhs.result_as(self.ctype())))
3497 rhs.generate_post_assignment_code(code)
3498 rhs.free_temps(code)
3499 self.obj.generate_disposal_code(code)
3500 self.obj.free_temps(code)
3502 def generate_deletion_code(self, code):
3503 interned_attr_cname = code.intern_identifier(self.attribute)
3504 self.obj.generate_evaluation_code(code)
3505 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3506 and self.entry.scope.entries.has_key(u'__del__')):
3507 code.put_error_if_neg(self.pos,
3508 'PyObject_DelAttr(%s, %s)' % (
3509 self.obj.py_result(),
3510 interned_attr_cname))
3512 error(self.pos, "Cannot delete C attribute of extension type")
3513 self.obj.generate_disposal_code(code)
3514 self.obj.free_temps(code)
3516 def annotate(self, code):
3518 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3520 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3522 def put_nonecheck(self, code):
3523 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3524 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3525 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3526 code.putln(code.error_goto(self.pos))
3530 #-------------------------------------------------------------------
3534 #-------------------------------------------------------------------
3536 class StarredTargetNode(ExprNode):
3537 # A starred expression like "*a"
3539 # This is only allowed in sequence assignment targets such as
3541 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3543 # and will be removed during type analysis (or generate an error
3544 # if it's found at unexpected places).
3548 subexprs = ['target']
3550 type = py_object_type
3553 def __init__(self, pos, target):
3555 self.target = target
3557 def analyse_declarations(self, env):
3558 error(self.pos, "can use starred expression only as assignment target")
3559 self.target.analyse_declarations(env)
3561 def analyse_types(self, env):
3562 error(self.pos, "can use starred expression only as assignment target")
3563 self.target.analyse_types(env)
3564 self.type = self.target.type
3566 def analyse_target_declaration(self, env):
3567 self.target.analyse_target_declaration(env)
3569 def analyse_target_types(self, env):
3570 self.target.analyse_target_types(env)
3571 self.type = self.target.type
3573 def calculate_result_code(self):
3576 def generate_result_code(self, code):
3580 class SequenceNode(ExprNode):
3581 # Base class for list and tuple constructor nodes.
3582 # Contains common code for performing sequence unpacking.
3586 # unpacked_items [ExprNode] or None
3587 # coerced_unpacked_items [ExprNode] or None
3591 is_sequence_constructor = 1
3592 unpacked_items = None
3594 def compile_time_value_list(self, denv):
3595 return [arg.compile_time_value(denv) for arg in self.args]
3597 def replace_starred_target_node(self):
3598 # replace a starred node in the targets by the contained expression
3599 self.starred_assignment = False
3601 for arg in self.args:
3603 if self.starred_assignment:
3604 error(arg.pos, "more than 1 starred expression in assignment")
3605 self.starred_assignment = True
3607 arg.is_starred = True
3611 def analyse_target_declaration(self, env):
3612 self.replace_starred_target_node()
3613 for arg in self.args:
3614 arg.analyse_target_declaration(env)
3616 def analyse_types(self, env, skip_children=False):
3617 for i in range(len(self.args)):
3619 if not skip_children: arg.analyse_types(env)
3620 self.args[i] = arg.coerce_to_pyobject(env)
3621 self.type = py_object_type
3624 def may_be_none(self):
3627 def analyse_target_types(self, env):
3628 self.iterator = PyTempNode(self.pos, env)
3629 self.unpacked_items = []
3630 self.coerced_unpacked_items = []
3631 for arg in self.args:
3632 arg.analyse_target_types(env)
3634 if not arg.type.assignable_from(Builtin.list_type):
3636 "starred target must have Python object (list) type")
3637 if arg.type is py_object_type:
3638 arg.type = Builtin.list_type
3639 unpacked_item = PyTempNode(self.pos, env)
3640 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3641 self.unpacked_items.append(unpacked_item)
3642 self.coerced_unpacked_items.append(coerced_unpacked_item)
3643 self.type = py_object_type
3645 def generate_result_code(self, code):
3646 self.generate_operation_code(code)
3648 def generate_assignment_code(self, rhs, code):
3649 if self.starred_assignment:
3650 self.generate_starred_assignment_code(rhs, code)
3652 self.generate_parallel_assignment_code(rhs, code)
3654 for item in self.unpacked_items:
3656 rhs.free_temps(code)
3658 def generate_parallel_assignment_code(self, rhs, code):
3659 # Need to work around the fact that generate_evaluation_code
3660 # allocates the temps in a rather hacky way -- the assignment
3661 # is evaluated twice, within each if-block.
3663 if rhs.type is tuple_type:
3664 tuple_check = "likely(%s != Py_None)"
3666 tuple_check = "PyTuple_CheckExact(%s)"
3668 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3669 tuple_check % rhs.py_result(),
3672 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3673 for item in self.unpacked_items:
3675 for i in range(len(self.args)):
3676 item = self.unpacked_items[i]
3678 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3681 code.put_incref(item.result(), item.ctype())
3682 value_node = self.coerced_unpacked_items[i]
3683 value_node.generate_evaluation_code(code)
3684 rhs.generate_disposal_code(code)
3686 for i in range(len(self.args)):
3687 self.args[i].generate_assignment_code(
3688 self.coerced_unpacked_items[i], code)
3690 code.putln("} else {")
3692 if rhs.type is tuple_type:
3693 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3694 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3695 rhs.py_result(), len(self.args)))
3696 code.putln(code.error_goto(self.pos))
3698 code.globalstate.use_utility_code(unpacking_utility_code)
3700 self.iterator.allocate(code)
3702 "%s = PyObject_GetIter(%s); %s" % (
3703 self.iterator.result(),
3705 code.error_goto_if_null(self.iterator.result(), self.pos)))
3706 code.put_gotref(self.iterator.py_result())
3707 rhs.generate_disposal_code(code)
3708 for i in range(len(self.args)):
3709 item = self.unpacked_items[i]
3710 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3711 self.iterator.py_result(), i)
3715 typecast(item.ctype(), py_object_type, unpack_code),
3716 code.error_goto_if_null(item.result(), self.pos)))
3717 code.put_gotref(item.py_result())
3718 value_node = self.coerced_unpacked_items[i]
3719 value_node.generate_evaluation_code(code)
3720 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3721 self.iterator.py_result(),
3723 if debug_disposal_code:
3724 print("UnpackNode.generate_assignment_code:")
3725 print("...generating disposal code for %s" % self.iterator)
3726 self.iterator.generate_disposal_code(code)
3727 self.iterator.free_temps(code)
3728 self.iterator.release(code)
3730 for i in range(len(self.args)):
3731 self.args[i].generate_assignment_code(
3732 self.coerced_unpacked_items[i], code)
3736 def generate_starred_assignment_code(self, rhs, code):
3737 code.globalstate.use_utility_code(unpacking_utility_code)
3739 for i, arg in enumerate(self.args):
3741 starred_target = self.unpacked_items[i]
3742 fixed_args_left = self.args[:i]
3743 fixed_args_right = self.args[i+1:]
3746 self.iterator.allocate(code)
3748 "%s = PyObject_GetIter(%s); %s" % (
3749 self.iterator.result(),
3751 code.error_goto_if_null(self.iterator.result(), self.pos)))
3752 code.put_gotref(self.iterator.py_result())
3753 rhs.generate_disposal_code(code)
3755 for item in self.unpacked_items:
3757 for i in range(len(fixed_args_left)):
3758 item = self.unpacked_items[i]
3759 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3760 self.iterator.py_result(), i)
3764 typecast(item.ctype(), py_object_type, unpack_code),
3765 code.error_goto_if_null(item.result(), self.pos)))
3766 code.put_gotref(item.py_result())
3767 value_node = self.coerced_unpacked_items[i]
3768 value_node.generate_evaluation_code(code)
3770 target_list = starred_target.result()
3771 code.putln("%s = PySequence_List(%s); %s" % (
3772 target_list, self.iterator.py_result(),
3773 code.error_goto_if_null(target_list, self.pos)))
3774 code.put_gotref(target_list)
3775 if fixed_args_right:
3776 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3777 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3778 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3779 (target_list, len(unpacked_right_args))))
3780 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3781 len(fixed_args_left), target_list,
3782 code.error_goto(self.pos)))
3784 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3785 self.coerced_unpacked_items[::-1])):
3787 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3789 target_list, target_list))
3790 # resize the list the hard way
3791 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3792 code.put_gotref(arg.py_result())
3793 coerced_arg.generate_evaluation_code(code)
3795 self.iterator.generate_disposal_code(code)
3796 self.iterator.free_temps(code)
3797 self.iterator.release(code)
3799 for i in range(len(self.args)):
3800 self.args[i].generate_assignment_code(
3801 self.coerced_unpacked_items[i], code)
3803 def annotate(self, code):
3804 for arg in self.args:
3806 if self.unpacked_items:
3807 for arg in self.unpacked_items:
3809 for arg in self.coerced_unpacked_items:
3813 class TupleNode(SequenceNode):
3814 # Tuple constructor.
3818 gil_message = "Constructing Python tuple"
3820 def analyse_types(self, env, skip_children=False):
3821 if len(self.args) == 0:
3825 SequenceNode.analyse_types(self, env, skip_children)
3827 def calculate_result_code(self):
3828 if len(self.args) > 0:
3829 error(self.pos, "Positive length tuples must be constructed.")
3831 return Naming.empty_tuple
3833 def calculate_constant_result(self):
3834 self.constant_result = tuple([
3835 arg.constant_result for arg in self.args])
3837 def compile_time_value(self, denv):
3838 values = self.compile_time_value_list(denv)
3840 return tuple(values)
3841 except Exception, e:
3842 self.compile_time_value_error(e)
3844 def generate_operation_code(self, code):
3845 if len(self.args) == 0:
3846 # result_code is Naming.empty_tuple
3849 "%s = PyTuple_New(%s); %s" % (
3852 code.error_goto_if_null(self.result(), self.pos)))
3853 code.put_gotref(self.py_result())
3854 for i in range(len(self.args)):
3856 if not arg.result_in_temp():
3857 code.put_incref(arg.result(), arg.ctype())
3859 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3863 code.put_giveref(arg.py_result())
3865 def generate_subexpr_disposal_code(self, code):
3866 # We call generate_post_assignment_code here instead
3867 # of generate_disposal_code, because values were stored
3868 # in the tuple using a reference-stealing operation.
3869 for arg in self.args:
3870 arg.generate_post_assignment_code(code)
3871 # Should NOT call free_temps -- this is invoked by the default
3872 # generate_evaluation_code which will do that.
3875 class ListNode(SequenceNode):
3878 # obj_conversion_errors [PyrexError] used internally
3879 # orignial_args [ExprNode] used internally
3881 obj_conversion_errors = []
3883 gil_message = "Constructing Python list"
3885 def type_dependencies(self, env):
3888 def infer_type(self, env):
3889 # TOOD: Infer non-object list arrays.
3892 def analyse_expressions(self, env):
3893 SequenceNode.analyse_expressions(self, env)
3894 self.coerce_to_pyobject(env)
3896 def analyse_types(self, env):
3898 self.original_args = list(self.args)
3899 SequenceNode.analyse_types(self, env)
3900 self.type = list_type
3901 self.obj_conversion_errors = held_errors()
3902 release_errors(ignore=True)
3904 def coerce_to(self, dst_type, env):
3905 if dst_type.is_pyobject:
3906 for err in self.obj_conversion_errors:
3908 self.obj_conversion_errors = []
3909 if not self.type.subtype_of(dst_type):
3910 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3911 elif dst_type.is_ptr:
3912 base_type = dst_type.base_type
3913 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3914 for i in range(len(self.original_args)):
3916 if isinstance(arg, CoerceToPyTypeNode):
3918 self.args[i] = arg.coerce_to(base_type, env)
3919 elif dst_type.is_struct:
3920 if len(self.args) > len(dst_type.scope.var_entries):
3921 error(self.pos, "Too may members for '%s'" % dst_type)
3923 if len(self.args) < len(dst_type.scope.var_entries):
3924 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3925 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3926 if isinstance(arg, CoerceToPyTypeNode):
3928 self.args[i] = arg.coerce_to(member.type, env)
3929 self.type = dst_type
3931 self.type = error_type
3932 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3935 def release_temp(self, env):
3936 if self.type.is_array:
3937 # To be valid C++, we must allocate the memory on the stack
3938 # manually and be sure not to reuse it for something else.
3941 SequenceNode.release_temp(self, env)
3943 def calculate_constant_result(self):
3944 self.constant_result = [
3945 arg.constant_result for arg in self.args]
3947 def compile_time_value(self, denv):
3948 return self.compile_time_value_list(denv)
3950 def generate_operation_code(self, code):
3951 if self.type.is_pyobject:
3952 for err in self.obj_conversion_errors:
3954 code.putln("%s = PyList_New(%s); %s" %
3957 code.error_goto_if_null(self.result(), self.pos)))
3958 code.put_gotref(self.py_result())
3959 for i in range(len(self.args)):
3961 #if not arg.is_temp:
3962 if not arg.result_in_temp():
3963 code.put_incref(arg.result(), arg.ctype())
3964 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
3968 code.put_giveref(arg.py_result())
3969 elif self.type.is_array:
3970 for i, arg in enumerate(self.args):
3971 code.putln("%s[%s] = %s;" % (
3975 elif self.type.is_struct:
3976 for arg, member in zip(self.args, self.type.scope.var_entries):
3977 code.putln("%s.%s = %s;" % (
3982 raise InternalError("List type never specified")
3984 def generate_subexpr_disposal_code(self, code):
3985 # We call generate_post_assignment_code here instead
3986 # of generate_disposal_code, because values were stored
3987 # in the list using a reference-stealing operation.
3988 for arg in self.args:
3989 arg.generate_post_assignment_code(code)
3990 # Should NOT call free_temps -- this is invoked by the default
3991 # generate_evaluation_code which will do that.
3994 class ScopedExprNode(ExprNode):
3995 # Abstract base class for ExprNodes that have their own local
3996 # scope, such as generator expressions.
3998 # expr_scope Scope the inner scope of the expression
4003 def analyse_types(self, env):
4004 # nothing to do here, the children will be analysed separately
4007 def analyse_expressions(self, env):
4008 # nothing to do here, the children will be analysed separately
4011 def analyse_scoped_expressions(self, env):
4012 # this is called with the expr_scope as env
4015 def init_scope(self, outer_scope, expr_scope=None):
4016 self.expr_scope = expr_scope
4019 class ComprehensionNode(ScopedExprNode):
4020 subexprs = ["target"]
4021 child_attrs = ["loop", "append"]
4023 # leak loop variables or not? non-leaking Py3 behaviour is
4024 # default, except for list comprehensions where the behaviour
4025 # differs in Py2 and Py3 (see Parsing.py)
4026 has_local_scope = True
4028 def infer_type(self, env):
4029 return self.target.infer_type(env)
4031 def analyse_declarations(self, env):
4032 self.append.target = self # this is used in the PyList_Append of the inner loop
4033 self.init_scope(env)
4034 if self.expr_scope is not None:
4035 self.loop.analyse_declarations(self.expr_scope)
4037 self.loop.analyse_declarations(env)
4039 def init_scope(self, outer_scope, expr_scope=None):
4040 if expr_scope is not None:
4041 self.expr_scope = expr_scope
4042 elif self.has_local_scope:
4043 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4045 self.expr_scope = None
4047 def analyse_types(self, env):
4048 self.target.analyse_expressions(env)
4049 self.type = self.target.type
4050 if not self.has_local_scope:
4051 self.loop.analyse_expressions(env)
4053 def analyse_expressions(self, env):
4054 self.analyse_types(env)
4056 def analyse_scoped_expressions(self, env):
4057 if self.has_local_scope:
4058 self.loop.analyse_expressions(env)
4060 def may_be_none(self):
4063 def calculate_result_code(self):
4064 return self.target.result()
4066 def generate_result_code(self, code):
4067 self.generate_operation_code(code)
4069 def generate_operation_code(self, code):
4070 self.loop.generate_execution_code(code)
4072 def annotate(self, code):
4073 self.loop.annotate(code)
4076 class ComprehensionAppendNode(Node):
4077 # Need to be careful to avoid infinite recursion:
4078 # target must not be in child_attrs/subexprs
4080 child_attrs = ['expr']
4082 type = PyrexTypes.c_int_type
4084 def analyse_expressions(self, env):
4085 self.expr.analyse_expressions(env)
4086 if not self.expr.type.is_pyobject:
4087 self.expr = self.expr.coerce_to_pyobject(env)
4089 def generate_execution_code(self, code):
4090 if self.target.type is list_type:
4091 function = "PyList_Append"
4092 elif self.target.type is set_type:
4093 function = "PySet_Add"
4095 raise InternalError(
4096 "Invalid type for comprehension node: %s" % self.target.type)
4098 self.expr.generate_evaluation_code(code)
4099 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4101 self.target.result(),
4104 self.expr.generate_disposal_code(code)
4105 self.expr.free_temps(code)
4107 def generate_function_definitions(self, env, code):
4108 self.expr.generate_function_definitions(env, code)
4110 def annotate(self, code):
4111 self.expr.annotate(code)
4113 class DictComprehensionAppendNode(ComprehensionAppendNode):
4114 child_attrs = ['key_expr', 'value_expr']
4116 def analyse_expressions(self, env):
4117 self.key_expr.analyse_expressions(env)
4118 if not self.key_expr.type.is_pyobject:
4119 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4120 self.value_expr.analyse_expressions(env)
4121 if not self.value_expr.type.is_pyobject:
4122 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4124 def generate_execution_code(self, code):
4125 self.key_expr.generate_evaluation_code(code)
4126 self.value_expr.generate_evaluation_code(code)
4127 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4128 self.target.result(),
4129 self.key_expr.result(),
4130 self.value_expr.result()
4132 self.key_expr.generate_disposal_code(code)
4133 self.key_expr.free_temps(code)
4134 self.value_expr.generate_disposal_code(code)
4135 self.value_expr.free_temps(code)
4137 def generate_function_definitions(self, env, code):
4138 self.key_expr.generate_function_definitions(env, code)
4139 self.value_expr.generate_function_definitions(env, code)
4141 def annotate(self, code):
4142 self.key_expr.annotate(code)
4143 self.value_expr.annotate(code)
4146 class GeneratorExpressionNode(ScopedExprNode):
4147 # A generator expression, e.g. (i for i in range(10))
4149 # Result is a generator.
4151 # loop ForStatNode the for-loop, containing a YieldExprNode
4153 child_attrs = ["loop"]
4155 type = py_object_type
4157 def analyse_declarations(self, env):
4158 self.init_scope(env)
4159 self.loop.analyse_declarations(self.expr_scope)
4161 def init_scope(self, outer_scope, expr_scope=None):
4162 if expr_scope is not None:
4163 self.expr_scope = expr_scope
4165 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4167 def analyse_types(self, env):
4170 def analyse_scoped_expressions(self, env):
4171 self.loop.analyse_expressions(env)
4173 def may_be_none(self):
4176 def annotate(self, code):
4177 self.loop.annotate(code)
4180 class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
4181 # An inlined generator expression for which the result is
4182 # calculated inside of the loop. This will only be created by
4183 # transforms when replacing builtin calls on generator
4186 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4187 # result_node ResultRefNode the reference to the result value temp
4188 # orig_func String the name of the builtin function this node replaces
4190 child_attrs = ["loop"]
4192 def analyse_types(self, env):
4193 self.type = self.result_node.type
4196 def coerce_to(self, dst_type, env):
4197 if self.orig_func == 'sum' and dst_type.is_numeric:
4198 # we can optimise by dropping the aggregation variable into C
4199 self.result_node.type = self.type = dst_type
4201 return GeneratorExpressionNode.coerce_to(self, dst_type, env)
4203 def generate_result_code(self, code):
4204 self.result_node.result_code = self.result()
4205 self.loop.generate_execution_code(code)
4208 class SetNode(ExprNode):
4215 gil_message = "Constructing Python set"
4217 def analyse_types(self, env):
4218 for i in range(len(self.args)):
4220 arg.analyse_types(env)
4221 self.args[i] = arg.coerce_to_pyobject(env)
4222 self.type = set_type
4225 def may_be_none(self):
4228 def calculate_constant_result(self):
4229 self.constant_result = set([
4230 arg.constant_result for arg in self.args])
4232 def compile_time_value(self, denv):
4233 values = [arg.compile_time_value(denv) for arg in self.args]
4236 except Exception, e:
4237 self.compile_time_value_error(e)
4239 def generate_evaluation_code(self, code):
4240 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4241 self.allocate_temp_result(code)
4243 "%s = PySet_New(0); %s" % (
4245 code.error_goto_if_null(self.result(), self.pos)))
4246 code.put_gotref(self.py_result())
4247 for arg in self.args:
4248 arg.generate_evaluation_code(code)
4250 code.error_goto_if_neg(
4251 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4253 arg.generate_disposal_code(code)
4254 arg.free_temps(code)
4257 class DictNode(ExprNode):
4258 # Dictionary constructor.
4260 # key_value_pairs [DictItemNode]
4262 # obj_conversion_errors [PyrexError] used internally
4264 subexprs = ['key_value_pairs']
4268 obj_conversion_errors = []
4270 def calculate_constant_result(self):
4271 self.constant_result = dict([
4272 item.constant_result for item in self.key_value_pairs])
4274 def compile_time_value(self, denv):
4275 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4276 for item in self.key_value_pairs]
4279 except Exception, e:
4280 self.compile_time_value_error(e)
4282 def type_dependencies(self, env):
4285 def infer_type(self, env):
4286 # TOOD: Infer struct constructors.
4289 def analyse_types(self, env):
4291 for item in self.key_value_pairs:
4292 item.analyse_types(env)
4293 self.obj_conversion_errors = held_errors()
4294 release_errors(ignore=True)
4296 def may_be_none(self):
4299 def coerce_to(self, dst_type, env):
4300 if dst_type.is_pyobject:
4301 self.release_errors()
4302 if not self.type.subtype_of(dst_type):
4303 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4304 elif dst_type.is_struct_or_union:
4305 self.type = dst_type
4306 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4307 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4308 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4309 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4310 for item in self.key_value_pairs:
4311 if isinstance(item.key, CoerceToPyTypeNode):
4312 item.key = item.key.arg
4313 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4314 error(item.key.pos, "Invalid struct field identifier")
4315 item.key = StringNode(item.key.pos, value="<error>")
4317 key = str(item.key.value) # converts string literals to unicode in Py3
4318 member = dst_type.scope.lookup_here(key)
4320 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4323 if isinstance(value, CoerceToPyTypeNode):
4325 item.value = value.coerce_to(member.type, env)
4327 self.type = error_type
4328 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4331 def release_errors(self):
4332 for err in self.obj_conversion_errors:
4334 self.obj_conversion_errors = []
4336 gil_message = "Constructing Python dict"
4338 def generate_evaluation_code(self, code):
4339 # Custom method used here because key-value
4340 # pairs are evaluated and used one at a time.
4341 code.mark_pos(self.pos)
4342 self.allocate_temp_result(code)
4343 if self.type.is_pyobject:
4344 self.release_errors()
4346 "%s = PyDict_New(); %s" % (
4348 code.error_goto_if_null(self.result(), self.pos)))
4349 code.put_gotref(self.py_result())
4350 for item in self.key_value_pairs:
4351 item.generate_evaluation_code(code)
4352 if self.type.is_pyobject:
4353 code.put_error_if_neg(self.pos,
4354 "PyDict_SetItem(%s, %s, %s)" % (
4356 item.key.py_result(),
4357 item.value.py_result()))
4359 code.putln("%s.%s = %s;" % (
4362 item.value.result()))
4363 item.generate_disposal_code(code)
4364 item.free_temps(code)
4366 def annotate(self, code):
4367 for item in self.key_value_pairs:
4370 class DictItemNode(ExprNode):
4371 # Represents a single item in a DictNode
4375 subexprs = ['key', 'value']
4377 nogil_check = None # Parent DictNode takes care of it
4379 def calculate_constant_result(self):
4380 self.constant_result = (
4381 self.key.constant_result, self.value.constant_result)
4383 def analyse_types(self, env):
4384 self.key.analyse_types(env)
4385 self.value.analyse_types(env)
4386 self.key = self.key.coerce_to_pyobject(env)
4387 self.value = self.value.coerce_to_pyobject(env)
4389 def generate_evaluation_code(self, code):
4390 self.key.generate_evaluation_code(code)
4391 self.value.generate_evaluation_code(code)
4393 def generate_disposal_code(self, code):
4394 self.key.generate_disposal_code(code)
4395 self.value.generate_disposal_code(code)
4397 def free_temps(self, code):
4398 self.key.free_temps(code)
4399 self.value.free_temps(code)
4402 return iter([self.key, self.value])
4405 class ClassNode(ExprNode):
4406 # Helper class used in the implementation of Python
4407 # class definitions. Constructs a class object given
4408 # a name, tuple of bases and class dictionary.
4410 # name EncodedString Name of the class
4411 # bases ExprNode Base class tuple
4412 # dict ExprNode Class dict (not owned by this node)
4413 # doc ExprNode or None Doc string
4414 # module_name string Name of defining module
4416 subexprs = ['bases', 'doc']
4418 def analyse_types(self, env):
4419 self.bases.analyse_types(env)
4421 self.doc.analyse_types(env)
4422 self.doc = self.doc.coerce_to_pyobject(env)
4423 self.module_name = env.global_scope().qualified_name
4424 self.type = py_object_type
4426 env.use_utility_code(create_class_utility_code);
4428 def may_be_none(self):
4431 gil_message = "Constructing Python class"
4433 def generate_result_code(self, code):
4434 cname = code.intern_identifier(self.name)
4436 code.put_error_if_neg(self.pos,
4437 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4438 self.dict.py_result(),
4439 self.doc.py_result()))
4441 '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % (
4443 self.bases.py_result(),
4444 self.dict.py_result(),
4447 code.error_goto_if_null(self.result(), self.pos)))
4448 code.put_gotref(self.py_result())
4450 class BoundMethodNode(ExprNode):
4451 # Helper class used in the implementation of Python
4452 # class definitions. Constructs an bound method
4453 # object from a class and a function.
4455 # function ExprNode Function object
4456 # self_object ExprNode self object
4458 subexprs = ['function']
4460 def analyse_types(self, env):
4461 self.function.analyse_types(env)
4462 self.type = py_object_type
4465 gil_message = "Constructing an bound method"
4467 def generate_result_code(self, code):
4469 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4471 self.function.py_result(),
4472 self.self_object.py_result(),
4473 self.self_object.py_result(),
4474 code.error_goto_if_null(self.result(), self.pos)))
4475 code.put_gotref(self.py_result())
4477 class UnboundMethodNode(ExprNode):
4478 # Helper class used in the implementation of Python
4479 # class definitions. Constructs an unbound method
4480 # object from a class and a function.
4482 # function ExprNode Function object
4484 type = py_object_type
4487 subexprs = ['function']
4489 def analyse_types(self, env):
4490 self.function.analyse_types(env)
4492 def may_be_none(self):
4495 gil_message = "Constructing an unbound method"
4497 def generate_result_code(self, code):
4498 class_cname = code.pyclass_stack[-1].classobj.result()
4500 "%s = PyMethod_New(%s, 0, %s); %s" % (
4502 self.function.py_result(),
4504 code.error_goto_if_null(self.result(), self.pos)))
4505 code.put_gotref(self.py_result())
4508 class PyCFunctionNode(ExprNode):
4509 # Helper class used in the implementation of Python
4510 # class definitions. Constructs a PyCFunction object
4511 # from a PyMethodDef struct.
4513 # pymethdef_cname string PyMethodDef structure
4514 # self_object ExprNode or None
4521 type = py_object_type
4524 def analyse_types(self, env):
4526 env.use_utility_code(binding_cfunc_utility_code)
4528 def may_be_none(self):
4531 gil_message = "Constructing Python function"
4533 def self_result_code(self):
4534 if self.self_object is None:
4535 self_result = "NULL"
4537 self_result = self.self_object.py_result()
4540 def generate_result_code(self, code):
4542 constructor = "%s_New" % Naming.binding_cfunc
4544 constructor = "PyCFunction_New"
4546 "%s = %s(&%s, %s); %s" % (
4549 self.pymethdef_cname,
4550 self.self_result_code(),
4551 code.error_goto_if_null(self.result(), self.pos)))
4552 code.put_gotref(self.py_result())
4554 class InnerFunctionNode(PyCFunctionNode):
4555 # Special PyCFunctionNode that depends on a closure class
4559 def self_result_code(self):
4560 return "((PyObject*)%s)" % Naming.cur_scope_cname
4562 class LambdaNode(InnerFunctionNode):
4563 # Lambda expression node (only used as a function reference)
4565 # args [CArgDeclNode] formal arguments
4566 # star_arg PyArgDeclNode or None * argument
4567 # starstar_arg PyArgDeclNode or None ** argument
4568 # lambda_name string a module-globally unique lambda name
4569 # result_expr ExprNode
4570 # def_node DefNode the underlying function 'def' node
4572 child_attrs = ['def_node']
4575 name = StringEncoding.EncodedString('<lambda>')
4577 def analyse_declarations(self, env):
4578 #self.def_node.needs_closure = self.needs_closure
4579 self.def_node.analyse_declarations(env)
4580 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
4581 env.add_lambda_def(self.def_node)
4583 class YieldExprNode(ExprNode):
4584 # Yield expression node
4586 # arg ExprNode the value to return from the generator
4587 # label_name string name of the C label used for this yield
4590 type = py_object_type
4592 def analyse_types(self, env):
4594 if self.arg is not None:
4595 self.arg.analyse_types(env)
4596 if not self.arg.type.is_pyobject:
4597 self.arg = self.arg.coerce_to_pyobject(env)
4598 error(self.pos, "Generators are not supported")
4600 def generate_result_code(self, code):
4601 self.label_name = code.new_label('resume_from_yield')
4602 code.use_label(self.label_name)
4603 code.putln("/* FIXME: save temporary variables */")
4604 code.putln("/* FIXME: return from function, yielding value */")
4605 code.put_label(self.label_name)
4606 code.putln("/* FIXME: restore temporary variables and */")
4607 code.putln("/* FIXME: extract sent value from closure */")
4610 #-------------------------------------------------------------------
4612 # Unary operator nodes
4614 #-------------------------------------------------------------------
4616 compile_time_unary_operators = {
4617 'not': operator.not_,
4623 class UnopNode(ExprNode):
4627 # Processing during analyse_expressions phase:
4629 # analyse_c_operation
4630 # Called when the operand is not a pyobject.
4631 # - Check operand type and coerce if needed.
4632 # - Determine result type and result code fragment.
4633 # - Allocate temporary for result if needed.
4635 subexprs = ['operand']
4638 def calculate_constant_result(self):
4639 func = compile_time_unary_operators[self.operator]
4640 self.constant_result = func(self.operand.constant_result)
4642 def compile_time_value(self, denv):
4643 func = compile_time_unary_operators.get(self.operator)
4646 "Unary '%s' not supported in compile-time expression"
4648 operand = self.operand.compile_time_value(denv)
4650 return func(operand)
4651 except Exception, e:
4652 self.compile_time_value_error(e)
4654 def infer_type(self, env):
4655 operand_type = self.operand.infer_type(env)
4656 if operand_type.is_pyobject:
4657 return py_object_type
4661 def analyse_types(self, env):
4662 self.operand.analyse_types(env)
4663 if self.is_py_operation():
4664 self.coerce_operand_to_pyobject(env)
4665 self.type = py_object_type
4667 elif self.is_cpp_operation():
4668 self.analyse_cpp_operation(env)
4670 self.analyse_c_operation(env)
4672 def check_const(self):
4673 return self.operand.check_const()
4675 def is_py_operation(self):
4676 return self.operand.type.is_pyobject
4678 def nogil_check(self, env):
4679 if self.is_py_operation():
4682 def is_cpp_operation(self):
4683 type = self.operand.type
4684 return type.is_cpp_class
4686 def coerce_operand_to_pyobject(self, env):
4687 self.operand = self.operand.coerce_to_pyobject(env)
4689 def generate_result_code(self, code):
4690 if self.operand.type.is_pyobject:
4691 self.generate_py_operation_code(code)
4693 def generate_py_operation_code(self, code):
4694 function = self.py_operation_function()
4696 "%s = %s(%s); %s" % (
4699 self.operand.py_result(),
4700 code.error_goto_if_null(self.result(), self.pos)))
4701 code.put_gotref(self.py_result())
4703 def type_error(self):
4704 if not self.operand.type.is_error:
4705 error(self.pos, "Invalid operand type for '%s' (%s)" %
4706 (self.operator, self.operand.type))
4707 self.type = PyrexTypes.error_type
4709 def analyse_cpp_operation(self, env):
4710 type = self.operand.type
4712 type = type.base_type
4713 function = type.scope.lookup("operator%s" % self.operator)
4715 error(self.pos, "'%s' operator not defined for %s"
4716 % (self.operator, type))
4719 func_type = function.type
4720 if func_type.is_ptr:
4721 func_type = func_type.base_type
4722 self.type = func_type.return_type
4725 class NotNode(ExprNode):
4730 type = PyrexTypes.c_bint_type
4732 subexprs = ['operand']
4734 def calculate_constant_result(self):
4735 self.constant_result = not self.operand.constant_result
4737 def compile_time_value(self, denv):
4738 operand = self.operand.compile_time_value(denv)
4741 except Exception, e:
4742 self.compile_time_value_error(e)
4744 def infer_type(self, env):
4745 return PyrexTypes.c_bint_type
4747 def analyse_types(self, env):
4748 self.operand.analyse_types(env)
4749 self.operand = self.operand.coerce_to_boolean(env)
4751 def calculate_result_code(self):
4752 return "(!%s)" % self.operand.result()
4754 def generate_result_code(self, code):
4758 class UnaryPlusNode(UnopNode):
4759 # unary '+' operator
4763 def analyse_c_operation(self, env):
4764 self.type = self.operand.type
4766 def py_operation_function(self):
4767 return "PyNumber_Positive"
4769 def calculate_result_code(self):
4770 if self.is_cpp_operation():
4771 return "(+%s)" % self.operand.result()
4773 return self.operand.result()
4776 class UnaryMinusNode(UnopNode):
4777 # unary '-' operator
4781 def analyse_c_operation(self, env):
4782 if self.operand.type.is_numeric:
4783 self.type = self.operand.type
4786 if self.type.is_complex:
4789 def py_operation_function(self):
4790 return "PyNumber_Negative"
4792 def calculate_result_code(self):
4794 return "(-%s)" % self.operand.result()
4796 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
4798 def get_constant_c_result_code(self):
4799 value = self.operand.get_constant_c_result_code()
4801 return "(-%s)" % (value)
4803 class TildeNode(UnopNode):
4804 # unary '~' operator
4806 def analyse_c_operation(self, env):
4807 if self.operand.type.is_int:
4808 self.type = self.operand.type
4812 def py_operation_function(self):
4813 return "PyNumber_Invert"
4815 def calculate_result_code(self):
4816 return "(~%s)" % self.operand.result()
4819 class CUnopNode(UnopNode):
4821 def is_py_operation(self):
4824 class DereferenceNode(CUnopNode):
4829 def analyse_c_operation(self, env):
4830 if self.operand.type.is_ptr:
4831 self.type = self.operand.type.base_type
4835 def calculate_result_code(self):
4836 return "(*%s)" % self.operand.result()
4839 class DecrementIncrementNode(CUnopNode):
4840 # unary ++/-- operator
4842 def analyse_c_operation(self, env):
4843 if self.operand.type.is_ptr or self.operand.type.is_numeric:
4844 self.type = self.operand.type
4848 def calculate_result_code(self):
4850 return "(%s%s)" % (self.operator, self.operand.result())
4852 return "(%s%s)" % (self.operand.result(), self.operator)
4854 def inc_dec_constructor(is_prefix, operator):
4855 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
4858 class AmpersandNode(ExprNode):
4859 # The C address-of operator.
4863 subexprs = ['operand']
4865 def infer_type(self, env):
4866 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
4868 def analyse_types(self, env):
4869 self.operand.analyse_types(env)
4870 argtype = self.operand.type
4871 if not (argtype.is_cfunction or self.operand.is_lvalue()):
4872 self.error("Taking address of non-lvalue")
4874 if argtype.is_pyobject:
4875 self.error("Cannot take address of Python variable")
4877 self.type = PyrexTypes.c_ptr_type(argtype)
4879 def check_const(self):
4880 return self.operand.check_const_addr()
4882 def error(self, mess):
4883 error(self.pos, mess)
4884 self.type = PyrexTypes.error_type
4885 self.result_code = "<error>"
4887 def calculate_result_code(self):
4888 return "(&%s)" % self.operand.result()
4890 def generate_result_code(self, code):
4894 unop_node_classes = {
4896 "-": UnaryMinusNode,
4900 def unop_node(pos, operator, operand):
4901 # Construct unnop node of appropriate class for
4903 if isinstance(operand, IntNode) and operator == '-':
4904 return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
4905 elif isinstance(operand, UnopNode) and operand.operator == operator:
4906 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
4907 return unop_node_classes[operator](pos,
4908 operator = operator,
4912 class TypecastNode(ExprNode):
4916 # base_type CBaseTypeNode
4917 # declarator CDeclaratorNode
4919 # If used from a transform, one can if wanted specify the attribute
4920 # "type" directly and leave base_type and declarator to None
4922 subexprs = ['operand']
4923 base_type = declarator = type = None
4925 def type_dependencies(self, env):
4928 def infer_type(self, env):
4929 if self.type is None:
4930 base_type = self.base_type.analyse(env)
4931 _, self.type = self.declarator.analyse(base_type, env)
4934 def analyse_types(self, env):
4935 if self.type is None:
4936 base_type = self.base_type.analyse(env)
4937 _, self.type = self.declarator.analyse(base_type, env)
4938 if self.type.is_cfunction:
4940 "Cannot cast to a function type")
4941 self.type = PyrexTypes.error_type
4942 self.operand.analyse_types(env)
4943 to_py = self.type.is_pyobject
4944 from_py = self.operand.type.is_pyobject
4945 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
4946 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
4947 if to_py and not from_py:
4948 if self.type is bytes_type and self.operand.type.is_int:
4949 # FIXME: the type cast node isn't needed in this case
4950 # and can be dropped once analyse_types() can return a
4952 self.operand = CoerceIntToBytesNode(self.operand, env)
4953 elif self.operand.type.can_coerce_to_pyobject(env):
4954 self.result_ctype = py_object_type
4955 self.operand = self.operand.coerce_to_pyobject(env)
4957 if self.operand.type.is_ptr:
4958 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
4959 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
4961 # Should this be an error?
4962 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
4963 self.operand = self.operand.coerce_to_simple(env)
4964 elif from_py and not to_py:
4965 if self.type.create_from_py_utility_code(env):
4966 self.operand = self.operand.coerce_to(self.type, env)
4967 elif self.type.is_ptr:
4968 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
4969 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
4971 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
4972 elif from_py and to_py:
4973 if self.typecheck and self.type.is_extension_type:
4974 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
4975 elif self.type.is_complex and self.operand.type.is_complex:
4976 self.operand = self.operand.coerce_to_simple(env)
4978 def nogil_check(self, env):
4979 if self.type and self.type.is_pyobject and self.is_temp:
4982 def check_const(self):
4983 return self.operand.check_const()
4985 def calculate_constant_result(self):
4986 # we usually do not know the result of a type cast at code
4990 def calculate_result_code(self):
4991 if self.type.is_complex:
4992 operand_result = self.operand.result()
4993 if self.operand.type.is_complex:
4994 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
4995 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
4997 real_part = self.type.real_type.cast_code(operand_result)
4999 return "%s(%s, %s)" % (
5000 self.type.from_parts,
5004 return self.type.cast_code(self.operand.result())
5006 def get_constant_c_result_code(self):
5007 operand_result = self.operand.get_constant_c_result_code()
5009 return self.type.cast_code(operand_result)
5011 def result_as(self, type):
5012 if self.type.is_pyobject and not self.is_temp:
5013 # Optimise away some unnecessary casting
5014 return self.operand.result_as(type)
5016 return ExprNode.result_as(self, type)
5018 def generate_result_code(self, code):
5021 "%s = (PyObject *)%s;" % (
5023 self.operand.result()))
5024 code.put_incref(self.result(), self.ctype())
5027 class SizeofNode(ExprNode):
5028 # Abstract base class for sizeof(x) expression nodes.
5030 type = PyrexTypes.c_size_t_type
5032 def check_const(self):
5035 def generate_result_code(self, code):
5039 class SizeofTypeNode(SizeofNode):
5040 # C sizeof function applied to a type
5042 # base_type CBaseTypeNode
5043 # declarator CDeclaratorNode
5048 def analyse_types(self, env):
5049 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5050 # this could be better handled by more uniformly treating types as runtime-available objects
5051 if 0 and self.base_type.module_path:
5052 path = self.base_type.module_path
5053 obj = env.lookup(path[0])
5054 if obj.as_module is None:
5055 operand = NameNode(pos=self.pos, name=path[0])
5056 for attr in path[1:]:
5057 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5058 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5059 self.operand = operand
5060 self.__class__ = SizeofVarNode
5061 self.analyse_types(env)
5063 if self.arg_type is None:
5064 base_type = self.base_type.analyse(env)
5065 _, arg_type = self.declarator.analyse(base_type, env)
5066 self.arg_type = arg_type
5069 def check_type(self):
5070 arg_type = self.arg_type
5071 if arg_type.is_pyobject and not arg_type.is_extension_type:
5072 error(self.pos, "Cannot take sizeof Python object")
5073 elif arg_type.is_void:
5074 error(self.pos, "Cannot take sizeof void")
5075 elif not arg_type.is_complete():
5076 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5078 def calculate_result_code(self):
5079 if self.arg_type.is_extension_type:
5080 # the size of the pointer is boring
5081 # we want the size of the actual struct
5082 arg_code = self.arg_type.declaration_code("", deref=1)
5084 arg_code = self.arg_type.declaration_code("")
5085 return "(sizeof(%s))" % arg_code
5088 class SizeofVarNode(SizeofNode):
5089 # C sizeof function applied to a variable
5093 subexprs = ['operand']
5095 def analyse_types(self, env):
5096 # We may actually be looking at a type rather than a variable...
5097 # If we are, traditional analysis would fail...
5098 operand_as_type = self.operand.analyse_as_type(env)
5100 self.arg_type = operand_as_type
5101 self.__class__ = SizeofTypeNode
5104 self.operand.analyse_types(env)
5106 def calculate_result_code(self):
5107 return "(sizeof(%s))" % self.operand.result()
5109 def generate_result_code(self, code):
5112 class TypeofNode(ExprNode):
5113 # Compile-time type of an expression, as a string.
5116 # literal StringNode # internal
5119 type = py_object_type
5121 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5123 def analyse_types(self, env):
5124 self.operand.analyse_types(env)
5125 self.literal = StringNode(
5126 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5127 self.literal.analyse_types(env)
5128 self.literal = self.literal.coerce_to_pyobject(env)
5130 def may_be_none(self):
5133 def generate_evaluation_code(self, code):
5134 self.literal.generate_evaluation_code(code)
5136 def calculate_result_code(self):
5137 return self.literal.calculate_result_code()
5139 #-------------------------------------------------------------------
5141 # Binary operator nodes
5143 #-------------------------------------------------------------------
5145 def _not_in(x, seq):
5148 compile_time_binary_operators = {
5156 'is_not': operator.is_not,
5159 '/': operator.truediv,
5160 '//': operator.floordiv,
5161 '<<': operator.lshift,
5166 '>>': operator.rshift,
5169 'in': operator.contains,
5173 def get_compile_time_binop(node):
5174 func = compile_time_binary_operators.get(node.operator)
5177 "Binary '%s' not supported in compile-time expression"
5181 class BinopNode(ExprNode):
5186 # Processing during analyse_expressions phase:
5188 # analyse_c_operation
5189 # Called when neither operand is a pyobject.
5190 # - Check operand types and coerce if needed.
5191 # - Determine result type and result code fragment.
5192 # - Allocate temporary for result if needed.
5194 subexprs = ['operand1', 'operand2']
5196 def calculate_constant_result(self):
5197 func = compile_time_binary_operators[self.operator]
5198 self.constant_result = func(
5199 self.operand1.constant_result,
5200 self.operand2.constant_result)
5202 def compile_time_value(self, denv):
5203 func = get_compile_time_binop(self)
5204 operand1 = self.operand1.compile_time_value(denv)
5205 operand2 = self.operand2.compile_time_value(denv)
5207 return func(operand1, operand2)
5208 except Exception, e:
5209 self.compile_time_value_error(e)
5211 def infer_type(self, env):
5212 return self.result_type(self.operand1.infer_type(env),
5213 self.operand2.infer_type(env))
5215 def analyse_types(self, env):
5216 self.operand1.analyse_types(env)
5217 self.operand2.analyse_types(env)
5218 if self.is_py_operation():
5219 self.coerce_operands_to_pyobjects(env)
5220 self.type = self.result_type(self.operand1.type,
5222 assert self.type.is_pyobject
5224 elif self.is_cpp_operation():
5225 self.analyse_cpp_operation(env)
5227 self.analyse_c_operation(env)
5229 def is_py_operation(self):
5230 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5232 def is_py_operation_types(self, type1, type2):
5233 return type1.is_pyobject or type2.is_pyobject
5235 def is_cpp_operation(self):
5236 return (self.operand1.type.is_cpp_class
5237 or self.operand2.type.is_cpp_class)
5239 def analyse_cpp_operation(self, env):
5240 type1 = self.operand1.type
5241 type2 = self.operand2.type
5242 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5246 func_type = entry.type
5247 if func_type.is_ptr:
5248 func_type = func_type.base_type
5249 if len(func_type.args) == 1:
5250 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5252 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5253 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5254 self.type = func_type.return_type
5256 def result_type(self, type1, type2):
5257 if self.is_py_operation_types(type1, type2):
5259 type2 = Builtin.bytes_type
5261 type1 = Builtin.bytes_type
5262 elif self.operator == '%' \
5263 and type1 in (Builtin.str_type, Builtin.unicode_type):
5264 # note that b'%s' % b'abc' doesn't work in Py3
5266 if type1.is_builtin_type:
5268 if self.operator in '**%+|&^':
5269 # FIXME: at least these operators should be safe - others?
5271 elif self.operator == '*':
5272 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5274 # multiplication of containers/numbers with an
5275 # integer value always (?) returns the same type
5278 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5279 # multiplication of containers/numbers with an
5280 # integer value always (?) returns the same type
5282 return py_object_type
5284 return self.compute_c_result_type(type1, type2)
5286 def nogil_check(self, env):
5287 if self.is_py_operation():
5290 def coerce_operands_to_pyobjects(self, env):
5291 self.operand1 = self.operand1.coerce_to_pyobject(env)
5292 self.operand2 = self.operand2.coerce_to_pyobject(env)
5294 def check_const(self):
5295 return self.operand1.check_const() and self.operand2.check_const()
5297 def generate_result_code(self, code):
5298 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5299 if self.operand1.type.is_pyobject:
5300 function = self.py_operation_function()
5301 if function == "PyNumber_Power":
5302 extra_args = ", Py_None"
5306 "%s = %s(%s, %s%s); %s" % (
5309 self.operand1.py_result(),
5310 self.operand2.py_result(),
5312 code.error_goto_if_null(self.result(), self.pos)))
5313 code.put_gotref(self.py_result())
5315 def type_error(self):
5316 if not (self.operand1.type.is_error
5317 or self.operand2.type.is_error):
5318 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5319 (self.operator, self.operand1.type,
5320 self.operand2.type))
5321 self.type = PyrexTypes.error_type
5324 class CBinopNode(BinopNode):
5326 def analyse_types(self, env):
5327 BinopNode.analyse_types(self, env)
5328 if self.is_py_operation():
5329 self.type = PyrexTypes.error_type
5331 def py_operation_function():
5334 def calculate_result_code(self):
5335 return "(%s %s %s)" % (
5336 self.operand1.result(),
5338 self.operand2.result())
5341 def c_binop_constructor(operator):
5342 def make_binop_node(pos, **operands):
5343 return CBinopNode(pos, operator=operator, **operands)
5344 return make_binop_node
5346 class NumBinopNode(BinopNode):
5347 # Binary operation taking numeric arguments.
5351 def analyse_c_operation(self, env):
5352 type1 = self.operand1.type
5353 type2 = self.operand2.type
5354 self.type = self.compute_c_result_type(type1, type2)
5358 if self.type.is_complex:
5360 if not self.infix or (type1.is_numeric and type2.is_numeric):
5361 self.operand1 = self.operand1.coerce_to(self.type, env)
5362 self.operand2 = self.operand2.coerce_to(self.type, env)
5364 def compute_c_result_type(self, type1, type2):
5365 if self.c_types_okay(type1, type2):
5366 return PyrexTypes.widest_numeric_type(type1, type2)
5370 def get_constant_c_result_code(self):
5371 value1 = self.operand1.get_constant_c_result_code()
5372 value2 = self.operand2.get_constant_c_result_code()
5373 if value1 and value2:
5374 return "(%s %s %s)" % (value1, self.operator, value2)
5378 def c_types_okay(self, type1, type2):
5379 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5380 return (type1.is_numeric or type1.is_enum) \
5381 and (type2.is_numeric or type2.is_enum)
5383 def calculate_result_code(self):
5385 return "(%s %s %s)" % (
5386 self.operand1.result(),
5388 self.operand2.result())
5390 func = self.type.binary_op(self.operator)
5392 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5393 return "%s(%s, %s)" % (
5395 self.operand1.result(),
5396 self.operand2.result())
5398 def is_py_operation_types(self, type1, type2):
5399 return (type1 is PyrexTypes.c_py_unicode_type or
5400 type2 is PyrexTypes.c_py_unicode_type or
5401 BinopNode.is_py_operation_types(self, type1, type2))
5403 def py_operation_function(self):
5404 return self.py_functions[self.operator]
5408 "^": "PyNumber_Xor",
5409 "&": "PyNumber_And",
5410 "<<": "PyNumber_Lshift",
5411 ">>": "PyNumber_Rshift",
5412 "+": "PyNumber_Add",
5413 "-": "PyNumber_Subtract",
5414 "*": "PyNumber_Multiply",
5415 "/": "__Pyx_PyNumber_Divide",
5416 "//": "PyNumber_FloorDivide",
5417 "%": "PyNumber_Remainder",
5418 "**": "PyNumber_Power"
5422 class IntBinopNode(NumBinopNode):
5423 # Binary operation taking integer arguments.
5425 def c_types_okay(self, type1, type2):
5426 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5427 return (type1.is_int or type1.is_enum) \
5428 and (type2.is_int or type2.is_enum)
5431 class AddNode(NumBinopNode):
5434 def is_py_operation_types(self, type1, type2):
5435 if type1.is_string and type2.is_string:
5438 return NumBinopNode.is_py_operation_types(self, type1, type2)
5440 def compute_c_result_type(self, type1, type2):
5441 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5442 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5444 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5447 return NumBinopNode.compute_c_result_type(
5451 class SubNode(NumBinopNode):
5454 def compute_c_result_type(self, type1, type2):
5455 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5457 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5458 return PyrexTypes.c_int_type
5460 return NumBinopNode.compute_c_result_type(
5464 class MulNode(NumBinopNode):
5467 def is_py_operation_types(self, type1, type2):
5468 if (type1.is_string and type2.is_int) \
5469 or (type2.is_string and type1.is_int):
5472 return NumBinopNode.is_py_operation_types(self, type1, type2)
5475 class DivNode(NumBinopNode):
5476 # '/' or '//' operator.
5479 truedivision = None # == "unknown" if operator == '/'
5480 ctruedivision = False
5481 cdivision_warnings = False
5482 zerodivision_check = None
5484 def find_compile_time_binary_operator(self, op1, op2):
5485 func = compile_time_binary_operators[self.operator]
5486 if self.operator == '/' and self.truedivision is None:
5487 # => true div for floats, floor div for integers
5488 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5489 func = compile_time_binary_operators['//']
5492 def calculate_constant_result(self):
5493 op1 = self.operand1.constant_result
5494 op2 = self.operand2.constant_result
5495 func = self.find_compile_time_binary_operator(op1, op2)
5496 self.constant_result = func(
5497 self.operand1.constant_result,
5498 self.operand2.constant_result)
5500 def compile_time_value(self, denv):
5501 operand1 = self.operand1.compile_time_value(denv)
5502 operand2 = self.operand2.compile_time_value(denv)
5504 func = self.find_compile_time_binary_operator(
5505 self, operand1, operand2)
5506 return func(operand1, operand2)
5507 except Exception, e:
5508 self.compile_time_value_error(e)
5510 def analyse_types(self, env):
5511 if self.cdivision or env.directives['cdivision']:
5512 self.ctruedivision = False
5514 self.ctruedivision = self.truedivision
5515 NumBinopNode.analyse_types(self, env)
5516 if self.is_cpp_operation():
5517 self.cdivision = True
5518 if not self.type.is_pyobject:
5519 self.zerodivision_check = (
5520 self.cdivision is None and not env.directives['cdivision']
5521 and (not self.operand2.has_constant_result() or
5522 self.operand2.constant_result == 0))
5523 if self.zerodivision_check or env.directives['cdivision_warnings']:
5524 # Need to check ahead of time to warn or raise zero division error
5525 self.operand1 = self.operand1.coerce_to_simple(env)
5526 self.operand2 = self.operand2.coerce_to_simple(env)
5528 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5530 def compute_c_result_type(self, type1, type2):
5531 if self.operator == '/' and self.ctruedivision:
5532 if not type1.is_float and not type2.is_float:
5533 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5534 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5536 return NumBinopNode.compute_c_result_type(self, type1, type2)
5538 def zero_division_message(self):
5539 if self.type.is_int:
5540 return "integer division or modulo by zero"
5542 return "float division"
5544 def generate_evaluation_code(self, code):
5545 if not self.type.is_pyobject and not self.type.is_complex:
5546 if self.cdivision is None:
5547 self.cdivision = (code.globalstate.directives['cdivision']
5548 or not self.type.signed
5549 or self.type.is_float)
5550 if not self.cdivision:
5551 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5552 NumBinopNode.generate_evaluation_code(self, code)
5553 self.generate_div_warning_code(code)
5555 def generate_div_warning_code(self, code):
5556 if not self.type.is_pyobject:
5557 if self.zerodivision_check:
5559 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5561 zero_test = "%s == 0" % self.operand2.result()
5562 code.putln("if (unlikely(%s)) {" % zero_test)
5563 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
5564 code.putln(code.error_goto(self.pos))
5566 if self.type.is_int and self.type.signed and self.operator != '%':
5567 code.globalstate.use_utility_code(division_overflow_test_code)
5568 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
5569 self.type.declaration_code(''),
5570 self.operand2.result(),
5571 self.operand1.result()))
5572 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
5573 code.putln(code.error_goto(self.pos))
5575 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
5576 code.globalstate.use_utility_code(cdivision_warning_utility_code)
5577 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
5578 self.operand1.result(),
5579 self.operand2.result()))
5580 code.putln(code.set_error_info(self.pos));
5581 code.put("if (__Pyx_cdivision_warning()) ")
5582 code.put_goto(code.error_label)
5585 def calculate_result_code(self):
5586 if self.type.is_complex:
5587 return NumBinopNode.calculate_result_code(self)
5588 elif self.type.is_float and self.operator == '//':
5589 return "floor(%s / %s)" % (
5590 self.operand1.result(),
5591 self.operand2.result())
5592 elif self.truedivision or self.cdivision:
5593 op1 = self.operand1.result()
5594 op2 = self.operand2.result()
5595 if self.truedivision:
5596 if self.type != self.operand1.type:
5597 op1 = self.type.cast_code(op1)
5598 if self.type != self.operand2.type:
5599 op2 = self.type.cast_code(op2)
5600 return "(%s / %s)" % (op1, op2)
5602 return "__Pyx_div_%s(%s, %s)" % (
5603 self.type.specialization_name(),
5604 self.operand1.result(),
5605 self.operand2.result())
5608 class ModNode(DivNode):
5611 def is_py_operation_types(self, type1, type2):
5612 return (type1.is_string
5614 or NumBinopNode.is_py_operation_types(self, type1, type2))
5616 def zero_division_message(self):
5617 if self.type.is_int:
5618 return "integer division or modulo by zero"
5620 return "float divmod()"
5622 def generate_evaluation_code(self, code):
5623 if not self.type.is_pyobject:
5624 if self.cdivision is None:
5625 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
5626 if not self.cdivision:
5627 if self.type.is_int:
5628 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
5630 code.globalstate.use_utility_code(
5631 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
5632 NumBinopNode.generate_evaluation_code(self, code)
5633 self.generate_div_warning_code(code)
5635 def calculate_result_code(self):
5637 if self.type.is_float:
5638 return "fmod%s(%s, %s)" % (
5639 self.type.math_h_modifier,
5640 self.operand1.result(),
5641 self.operand2.result())
5643 return "(%s %% %s)" % (
5644 self.operand1.result(),
5645 self.operand2.result())
5647 return "__Pyx_mod_%s(%s, %s)" % (
5648 self.type.specialization_name(),
5649 self.operand1.result(),
5650 self.operand2.result())
5652 class PowNode(NumBinopNode):
5655 def analyse_c_operation(self, env):
5656 NumBinopNode.analyse_c_operation(self, env)
5657 if self.type.is_complex:
5658 error(self.pos, "complex powers not yet supported")
5659 self.pow_func = "<error>"
5660 elif self.type.is_float:
5661 self.pow_func = "pow" + self.type.math_h_modifier
5663 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
5664 env.use_utility_code(
5665 int_pow_utility_code.specialize(func_name=self.pow_func,
5666 type=self.type.declaration_code('')))
5668 def calculate_result_code(self):
5669 # Work around MSVC overloading ambiguity.
5670 def typecast(operand):
5671 if self.type == operand.type:
5672 return operand.result()
5674 return self.type.cast_code(operand.result())
5675 return "%s(%s, %s)" % (
5677 typecast(self.operand1),
5678 typecast(self.operand2))
5681 # Note: This class is temporarily "shut down" into an ineffective temp
5684 # More sophisticated temp reuse was going on before, one could have a
5685 # look at adding this again after /all/ classes are converted to the
5686 # new temp scheme. (The temp juggling cannot work otherwise).
5687 class BoolBinopNode(ExprNode):
5688 # Short-circuiting boolean operation.
5694 subexprs = ['operand1', 'operand2']
5696 def infer_type(self, env):
5697 type1 = self.operand1.infer_type(env)
5698 type2 = self.operand2.infer_type(env)
5699 return PyrexTypes.independent_spanning_type(type1, type2)
5701 def may_be_none(self):
5702 if self.operator == 'or':
5703 return self.operand2.may_be_none()
5705 return self.operand1.may_be_none() or self.operand2.may_be_none()
5707 def calculate_constant_result(self):
5708 if self.operator == 'and':
5709 self.constant_result = \
5710 self.operand1.constant_result and \
5711 self.operand2.constant_result
5713 self.constant_result = \
5714 self.operand1.constant_result or \
5715 self.operand2.constant_result
5717 def compile_time_value(self, denv):
5718 if self.operator == 'and':
5719 return self.operand1.compile_time_value(denv) \
5720 and self.operand2.compile_time_value(denv)
5722 return self.operand1.compile_time_value(denv) \
5723 or self.operand2.compile_time_value(denv)
5725 def coerce_to_boolean(self, env):
5726 return BoolBinopNode(
5728 operator = self.operator,
5729 operand1 = self.operand1.coerce_to_boolean(env),
5730 operand2 = self.operand2.coerce_to_boolean(env),
5731 type = PyrexTypes.c_bint_type,
5732 is_temp = self.is_temp)
5734 def analyse_types(self, env):
5735 self.operand1.analyse_types(env)
5736 self.operand2.analyse_types(env)
5737 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
5738 self.operand1 = self.operand1.coerce_to(self.type, env)
5739 self.operand2 = self.operand2.coerce_to(self.type, env)
5741 # For what we're about to do, it's vital that
5742 # both operands be temp nodes.
5743 self.operand1 = self.operand1.coerce_to_simple(env)
5744 self.operand2 = self.operand2.coerce_to_simple(env)
5747 gil_message = "Truth-testing Python object"
5749 def check_const(self):
5750 return self.operand1.check_const() and self.operand2.check_const()
5752 def generate_evaluation_code(self, code):
5753 code.mark_pos(self.pos)
5754 self.operand1.generate_evaluation_code(code)
5755 test_result, uses_temp = self.generate_operand1_test(code)
5756 if self.operator == 'and':
5765 code.funcstate.release_temp(test_result)
5766 self.operand1.generate_disposal_code(code)
5767 self.operand2.generate_evaluation_code(code)
5768 self.allocate_temp_result(code)
5769 self.operand2.make_owned_reference(code)
5770 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
5771 self.operand2.generate_post_assignment_code(code)
5772 self.operand2.free_temps(code)
5773 code.putln("} else {")
5774 self.operand1.make_owned_reference(code)
5775 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
5776 self.operand1.generate_post_assignment_code(code)
5777 self.operand1.free_temps(code)
5780 def generate_operand1_test(self, code):
5781 # Generate code to test the truth of the first operand.
5782 if self.type.is_pyobject:
5783 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
5786 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5788 self.operand1.py_result(),
5789 code.error_goto_if_neg(test_result, self.pos)))
5791 test_result = self.operand1.result()
5792 return (test_result, self.type.is_pyobject)
5795 class CondExprNode(ExprNode):
5796 # Short-circuiting conditional expression.
5800 # false_val ExprNode
5805 subexprs = ['test', 'true_val', 'false_val']
5807 def type_dependencies(self, env):
5808 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
5810 def infer_type(self, env):
5811 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
5812 self.false_val.infer_type(env))
5814 def calculate_constant_result(self):
5815 if self.test.constant_result:
5816 self.constant_result = self.true_val.constant_result
5818 self.constant_result = self.false_val.constant_result
5820 def analyse_types(self, env):
5821 self.test.analyse_types(env)
5822 self.test = self.test.coerce_to_boolean(env)
5823 self.true_val.analyse_types(env)
5824 self.false_val.analyse_types(env)
5825 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
5826 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
5827 self.true_val = self.true_val.coerce_to(self.type, env)
5828 self.false_val = self.false_val.coerce_to(self.type, env)
5830 if self.type == PyrexTypes.error_type:
5833 def type_error(self):
5834 if not (self.true_val.type.is_error or self.false_val.type.is_error):
5835 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
5836 (self.true_val.type, self.false_val.type))
5837 self.type = PyrexTypes.error_type
5839 def check_const(self):
5840 return (self.test.check_const()
5841 and self.true_val.check_const()
5842 and self.false_val.check_const())
5844 def generate_evaluation_code(self, code):
5845 # Because subexprs may not be evaluated we can use a more optimal
5846 # subexpr allocation strategy than the default, so override evaluation_code.
5848 code.mark_pos(self.pos)
5849 self.allocate_temp_result(code)
5850 self.test.generate_evaluation_code(code)
5851 code.putln("if (%s) {" % self.test.result() )
5852 self.eval_and_get(code, self.true_val)
5853 code.putln("} else {")
5854 self.eval_and_get(code, self.false_val)
5856 self.test.generate_disposal_code(code)
5857 self.test.free_temps(code)
5859 def eval_and_get(self, code, expr):
5860 expr.generate_evaluation_code(code)
5861 expr.make_owned_reference(code)
5862 code.putln("%s = %s;" % (self.result(), expr.result()))
5863 expr.generate_post_assignment_code(code)
5864 expr.free_temps(code)
5866 richcmp_constants = {
5876 class CmpNode(object):
5877 # Mixin class containing code common to PrimaryCmpNodes
5878 # and CascadedCmpNodes.
5880 def infer_type(self, env):
5881 # TODO: Actually implement this (after merging with -unstable).
5882 return py_object_type
5884 def calculate_cascaded_constant_result(self, operand1_result):
5885 func = compile_time_binary_operators[self.operator]
5886 operand2_result = self.operand2.constant_result
5887 result = func(operand1_result, operand2_result)
5889 self.cascade.calculate_cascaded_constant_result(operand2_result)
5890 if self.cascade.constant_result:
5891 self.constant_result = result and self.cascade.constant_result
5893 self.constant_result = result
5895 def cascaded_compile_time_value(self, operand1, denv):
5896 func = get_compile_time_binop(self)
5897 operand2 = self.operand2.compile_time_value(denv)
5899 result = func(operand1, operand2)
5900 except Exception, e:
5901 self.compile_time_value_error(e)
5904 cascade = self.cascade
5906 # FIXME: I bet this must call cascaded_compile_time_value()
5907 result = result and cascade.cascaded_compile_time_value(operand2, denv)
5910 def is_cpp_comparison(self):
5911 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
5913 def find_common_int_type(self, env, op, operand1, operand2):
5914 # type1 != type2 and at least one of the types is not a C int
5915 type1 = operand1.type
5916 type2 = operand2.type
5917 type1_can_be_int = False
5918 type2_can_be_int = False
5920 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
5921 and operand1.can_coerce_to_char_literal():
5922 type1_can_be_int = True
5923 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
5924 and operand2.can_coerce_to_char_literal():
5925 type2_can_be_int = True
5928 if type2_can_be_int:
5931 if type1_can_be_int:
5933 elif type1_can_be_int:
5934 if type2_can_be_int:
5935 return PyrexTypes.c_uchar_type
5939 def find_common_type(self, env, op, operand1, common_type=None):
5940 operand2 = self.operand2
5941 type1 = operand1.type
5942 type2 = operand2.type
5944 new_common_type = None
5946 # catch general errors
5947 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
5948 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
5949 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
5950 new_common_type = error_type
5952 # try to use numeric comparisons where possible
5953 elif type1.is_complex or type2.is_complex:
5954 if op not in ('==', '!='):
5955 error(self.pos, "complex types are unordered")
5956 new_common_type = error_type
5957 if type1.is_pyobject:
5958 new_common_type = type1
5959 elif type2.is_pyobject:
5960 new_common_type = type2
5962 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5963 elif type1.is_numeric and type2.is_numeric:
5964 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5965 elif common_type is None or not common_type.is_pyobject:
5966 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
5968 if new_common_type is None:
5969 # fall back to generic type compatibility tests
5971 new_common_type = type1
5972 elif type1.is_pyobject or type2.is_pyobject:
5973 if type2.is_numeric or type2.is_string:
5974 if operand2.check_for_coercion_error(type1):
5975 new_common_type = error_type
5977 new_common_type = py_object_type
5978 elif type1.is_numeric or type1.is_string:
5979 if operand1.check_for_coercion_error(type2):
5980 new_common_type = error_type
5982 new_common_type = py_object_type
5983 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
5984 new_common_type = py_object_type
5986 # one Python type and one non-Python type, not assignable
5987 self.invalid_types_error(operand1, op, operand2)
5988 new_common_type = error_type
5989 elif type1.assignable_from(type2):
5990 new_common_type = type1
5991 elif type2.assignable_from(type1):
5992 new_common_type = type2
5994 # C types that we couldn't handle up to here are an error
5995 self.invalid_types_error(operand1, op, operand2)
5996 new_common_type = error_type
5998 # recursively merge types
5999 if common_type is None or new_common_type.is_error:
6000 common_type = new_common_type
6002 # we could do a lot better by splitting the comparison
6003 # into a non-Python part and a Python part, but this is
6005 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6008 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6012 def invalid_types_error(self, operand1, op, operand2):
6013 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6014 (op, operand1.type, operand2.type))
6016 def is_python_comparison(self):
6017 return (not self.is_ptr_contains()
6018 and not self.is_c_string_contains()
6019 and (self.has_python_operands()
6020 or (self.cascade and self.cascade.is_python_comparison())
6021 or self.operator in ('in', 'not_in')))
6023 def coerce_operands_to(self, dst_type, env):
6024 operand2 = self.operand2
6025 if operand2.type != dst_type:
6026 self.operand2 = operand2.coerce_to(dst_type, env)
6028 self.cascade.coerce_operands_to(dst_type, env)
6030 def is_python_result(self):
6031 return ((self.has_python_operands() and
6032 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6033 not self.is_c_string_contains() and
6034 not self.is_ptr_contains())
6035 or (self.cascade and self.cascade.is_python_result()))
6037 def is_c_string_contains(self):
6038 return self.operator in ('in', 'not_in') and \
6039 ((self.operand1.type.is_int
6040 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6041 (self.operand1.type is PyrexTypes.c_py_unicode_type
6042 and self.operand2.type is unicode_type))
6044 def is_ptr_contains(self):
6045 if self.operator in ('in', 'not_in'):
6046 container_type = self.operand2.type
6047 return (container_type.is_ptr or container_type.is_array) \
6048 and not container_type.is_string
6050 def generate_operation_code(self, code, result_code,
6051 operand1, op , operand2):
6052 if self.type.is_pyobject:
6053 coerce_result = "__Pyx_PyBool_FromLong"
6060 if op == 'in' or op == 'not_in':
6061 code.globalstate.use_utility_code(contains_utility_code)
6062 if self.type.is_pyobject:
6063 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6065 negation = "__Pyx_NegateNonNeg"
6066 if operand2.type is dict_type:
6067 code.globalstate.use_utility_code(
6068 raise_none_iter_error_utility_code)
6069 code.putln("if (unlikely(%s == Py_None)) {" % operand2.py_result())
6070 code.putln("__Pyx_RaiseNoneNotIterableError(); %s" %
6071 code.error_goto(self.pos))
6072 code.putln("} else {")
6073 method = "PyDict_Contains"
6075 method = "PySequence_Contains"
6076 if self.type.is_pyobject:
6077 error_clause = code.error_goto_if_null
6078 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6080 error_clause = code.error_goto_if_neg
6083 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6088 operand2.py_result(),
6089 operand1.py_result(),
6091 error_clause(result_code, self.pos)))
6092 if operand2.type is dict_type:
6095 elif (operand1.type.is_pyobject
6096 and op not in ('is', 'is_not')):
6097 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6099 operand1.py_result(),
6100 operand2.py_result(),
6101 richcmp_constants[op],
6102 code.error_goto_if_null(result_code, self.pos)))
6103 code.put_gotref(result_code)
6104 elif operand1.type.is_complex:
6109 code.putln("%s = %s(%s%s(%s, %s));" % (
6113 operand1.type.unary_op('eq'),
6117 type1 = operand1.type
6118 type2 = operand2.type
6119 if (type1.is_extension_type or type2.is_extension_type) \
6120 and not type1.same_as(type2):
6121 common_type = py_object_type
6122 elif type1.is_numeric:
6123 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6126 code1 = operand1.result_as(common_type)
6127 code2 = operand2.result_as(common_type)
6128 code.putln("%s = %s(%s %s %s);" % (
6132 self.c_operator(op),
6135 def c_operator(self, op):
6138 elif op == 'is_not':
6143 contains_utility_code = UtilityCode(
6145 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6146 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6147 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6151 char_in_bytes_utility_code = UtilityCode(
6153 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6156 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6157 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6158 char* char_start = PyBytes_AS_STRING(bytes);
6160 for (pos=char_start; pos < char_start+length; pos++) {
6161 if (character == pos[0]) return 1;
6167 pyunicode_in_unicode_utility_code = UtilityCode(
6169 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6172 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6173 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6174 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6176 for (pos=char_start; pos < char_start+length; pos++) {
6177 if (character == pos[0]) return 1;
6184 class PrimaryCmpNode(ExprNode, CmpNode):
6185 # Non-cascaded comparison or first comparison of
6186 # a cascaded sequence.
6191 # cascade CascadedCmpNode
6193 # We don't use the subexprs mechanism, because
6194 # things here are too complicated for it to handle.
6195 # Instead, we override all the framework methods
6198 child_attrs = ['operand1', 'operand2', 'cascade']
6202 def infer_type(self, env):
6203 # TODO: Actually implement this (after merging with -unstable).
6204 return py_object_type
6206 def type_dependencies(self, env):
6209 def calculate_constant_result(self):
6210 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6212 def compile_time_value(self, denv):
6213 operand1 = self.operand1.compile_time_value(denv)
6214 return self.cascaded_compile_time_value(operand1, denv)
6216 def analyse_types(self, env):
6217 self.operand1.analyse_types(env)
6218 self.operand2.analyse_types(env)
6219 if self.is_cpp_comparison():
6220 self.analyse_cpp_comparison(env)
6222 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6225 self.cascade.analyse_types(env)
6227 if self.operator in ('in', 'not_in'):
6228 if self.is_c_string_contains():
6229 self.is_pycmp = False
6232 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6234 if self.operand2.type is unicode_type:
6235 env.use_utility_code(pyunicode_in_unicode_utility_code)
6237 if self.operand1.type is PyrexTypes.c_uchar_type:
6238 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6239 if self.operand2.type is not bytes_type:
6240 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6241 env.use_utility_code(char_in_bytes_utility_code)
6242 self.operand2 = self.operand2.as_none_safe_node(
6243 "argument of type 'NoneType' is not iterable")
6244 elif self.is_ptr_contains():
6246 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6247 self.type = PyrexTypes.c_bint_type
6248 # Will be transformed by IterationTransform
6251 common_type = py_object_type
6252 self.is_pycmp = True
6254 common_type = self.find_common_type(env, self.operator, self.operand1)
6255 self.is_pycmp = common_type.is_pyobject
6257 if common_type is not None and not common_type.is_error:
6258 if self.operand1.type != common_type:
6259 self.operand1 = self.operand1.coerce_to(common_type, env)
6260 self.coerce_operands_to(common_type, env)
6263 self.operand2 = self.operand2.coerce_to_simple(env)
6264 self.cascade.coerce_cascaded_operands_to_temp(env)
6265 if self.is_python_result():
6266 self.type = PyrexTypes.py_object_type
6268 self.type = PyrexTypes.c_bint_type
6271 cdr.type = self.type
6273 if self.is_pycmp or self.cascade:
6276 def analyse_cpp_comparison(self, env):
6277 type1 = self.operand1.type
6278 type2 = self.operand2.type
6279 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6281 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6282 (self.operator, type1, type2))
6283 self.type = PyrexTypes.error_type
6284 self.result_code = "<error>"
6286 func_type = entry.type
6287 if func_type.is_ptr:
6288 func_type = func_type.base_type
6289 if len(func_type.args) == 1:
6290 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6292 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6293 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6294 self.type = func_type.return_type
6296 def has_python_operands(self):
6297 return (self.operand1.type.is_pyobject
6298 or self.operand2.type.is_pyobject)
6300 def check_const(self):
6305 return self.operand1.check_const() and self.operand2.check_const()
6307 def calculate_result_code(self):
6308 if self.operand1.type.is_complex:
6309 if self.operator == "!=":
6313 return "(%s%s(%s, %s))" % (
6315 self.operand1.type.binary_op('=='),
6316 self.operand1.result(),
6317 self.operand2.result())
6318 elif self.is_c_string_contains():
6319 if self.operand2.type is bytes_type:
6320 method = "__Pyx_BytesContains"
6322 method = "__Pyx_UnicodeContains"
6323 if self.operator == "not_in":
6327 return "(%s%s(%s, %s))" % (
6330 self.operand2.result(),
6331 self.operand1.result())
6333 return "(%s %s %s)" % (
6334 self.operand1.result(),
6335 self.c_operator(self.operator),
6336 self.operand2.result())
6338 def generate_evaluation_code(self, code):
6339 self.operand1.generate_evaluation_code(code)
6340 self.operand2.generate_evaluation_code(code)
6342 self.allocate_temp_result(code)
6343 self.generate_operation_code(code, self.result(),
6344 self.operand1, self.operator, self.operand2)
6346 self.cascade.generate_evaluation_code(code,
6347 self.result(), self.operand2)
6348 self.operand1.generate_disposal_code(code)
6349 self.operand1.free_temps(code)
6350 self.operand2.generate_disposal_code(code)
6351 self.operand2.free_temps(code)
6353 def generate_subexpr_disposal_code(self, code):
6354 # If this is called, it is a non-cascaded cmp,
6355 # so only need to dispose of the two main operands.
6356 self.operand1.generate_disposal_code(code)
6357 self.operand2.generate_disposal_code(code)
6359 def free_subexpr_temps(self, code):
6360 # If this is called, it is a non-cascaded cmp,
6361 # so only need to dispose of the two main operands.
6362 self.operand1.free_temps(code)
6363 self.operand2.free_temps(code)
6365 def annotate(self, code):
6366 self.operand1.annotate(code)
6367 self.operand2.annotate(code)
6369 self.cascade.annotate(code)
6372 class CascadedCmpNode(Node, CmpNode):
6373 # A CascadedCmpNode is not a complete expression node. It
6374 # hangs off the side of another comparison node, shares
6375 # its left operand with that node, and shares its result
6376 # with the PrimaryCmpNode at the head of the chain.
6380 # cascade CascadedCmpNode
6382 child_attrs = ['operand2', 'cascade']
6385 constant_result = constant_value_not_set # FIXME: where to calculate this?
6387 def infer_type(self, env):
6388 # TODO: Actually implement this (after merging with -unstable).
6389 return py_object_type
6391 def type_dependencies(self, env):
6394 def has_constant_result(self):
6395 return self.constant_result is not constant_value_not_set and \
6396 self.constant_result is not not_a_constant
6398 def analyse_types(self, env):
6399 self.operand2.analyse_types(env)
6401 self.cascade.analyse_types(env)
6403 def has_python_operands(self):
6404 return self.operand2.type.is_pyobject
6406 def coerce_operands_to_pyobjects(self, env):
6407 self.operand2 = self.operand2.coerce_to_pyobject(env)
6409 self.cascade.coerce_operands_to_pyobjects(env)
6411 def coerce_cascaded_operands_to_temp(self, env):
6413 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6414 self.operand2 = self.operand2.coerce_to_simple(env)
6415 self.cascade.coerce_cascaded_operands_to_temp(env)
6417 def generate_evaluation_code(self, code, result, operand1):
6418 if self.type.is_pyobject:
6419 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
6420 code.put_decref(result, self.type)
6422 code.putln("if (%s) {" % result)
6423 self.operand2.generate_evaluation_code(code)
6424 self.generate_operation_code(code, result,
6425 operand1, self.operator, self.operand2)
6427 self.cascade.generate_evaluation_code(
6428 code, result, self.operand2)
6429 # Cascaded cmp result is always temp
6430 self.operand2.generate_disposal_code(code)
6431 self.operand2.free_temps(code)
6434 def annotate(self, code):
6435 self.operand2.annotate(code)
6437 self.cascade.annotate(code)
6440 binop_node_classes = {
6441 "or": BoolBinopNode,
6442 "and": BoolBinopNode,
6457 def binop_node(pos, operator, operand1, operand2):
6458 # Construct binop node of appropriate class for
6460 return binop_node_classes[operator](pos,
6461 operator = operator,
6462 operand1 = operand1,
6463 operand2 = operand2)
6465 #-------------------------------------------------------------------
6469 # Coercion nodes are special in that they are created during
6470 # the analyse_types phase of parse tree processing.
6471 # Their __init__ methods consequently incorporate some aspects
6474 #-------------------------------------------------------------------
6476 class CoercionNode(ExprNode):
6477 # Abstract base class for coercion nodes.
6479 # arg ExprNode node being coerced
6482 constant_result = not_a_constant
6484 def __init__(self, arg):
6488 print("%s Coercing %s" % (self, self.arg))
6490 def calculate_constant_result(self):
6491 # constant folding can break type coercion, so this is disabled
6494 def annotate(self, code):
6495 self.arg.annotate(code)
6496 if self.arg.type != self.type:
6497 file, line, col = self.pos
6498 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
6501 class CastNode(CoercionNode):
6502 # Wrap a node in a C type cast.
6504 def __init__(self, arg, new_type):
6505 CoercionNode.__init__(self, arg)
6506 self.type = new_type
6508 def may_be_none(self):
6509 return self.arg.may_be_none()
6511 def calculate_result_code(self):
6512 return self.arg.result_as(self.type)
6514 def generate_result_code(self, code):
6515 self.arg.generate_result_code(code)
6518 class PyTypeTestNode(CoercionNode):
6519 # This node is used to check that a generic Python
6520 # object is an instance of a particular extension type.
6521 # This node borrows the result of its argument node.
6523 def __init__(self, arg, dst_type, env, notnone=False):
6524 # The arg is know to be a Python object, and
6525 # the dst_type is known to be an extension type.
6526 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
6527 CoercionNode.__init__(self, arg)
6528 self.type = dst_type
6529 self.result_ctype = arg.ctype()
6530 self.notnone = notnone
6532 nogil_check = Node.gil_error
6533 gil_message = "Python type test"
6535 def analyse_types(self, env):
6538 def may_be_none(self):
6541 return self.arg.may_be_none()
6543 def result_in_temp(self):
6544 return self.arg.result_in_temp()
6546 def is_ephemeral(self):
6547 return self.arg.is_ephemeral()
6549 def calculate_constant_result(self):
6553 def calculate_result_code(self):
6554 return self.arg.result()
6556 def generate_result_code(self, code):
6557 if self.type.typeobj_is_available():
6558 if not self.type.is_builtin_type:
6559 code.globalstate.use_utility_code(type_test_utility_code)
6562 self.type.type_test_code(self.arg.py_result(), self.notnone),
6563 code.error_goto(self.pos)))
6565 error(self.pos, "Cannot test type of extern C class "
6566 "without type object name specification")
6568 def generate_post_assignment_code(self, code):
6569 self.arg.generate_post_assignment_code(code)
6571 def free_temps(self, code):
6572 self.arg.free_temps(code)
6575 class NoneCheckNode(CoercionNode):
6576 # This node is used to check that a Python object is not None and
6577 # raises an appropriate exception (as specified by the creating
6580 def __init__(self, arg, exception_type_cname, exception_message):
6581 CoercionNode.__init__(self, arg)
6582 self.type = arg.type
6583 self.result_ctype = arg.ctype()
6584 self.exception_type_cname = exception_type_cname
6585 self.exception_message = exception_message
6587 def analyse_types(self, env):
6590 def may_be_none(self):
6593 def result_in_temp(self):
6594 return self.arg.result_in_temp()
6596 def calculate_result_code(self):
6597 return self.arg.result()
6599 def generate_result_code(self, code):
6601 "if (unlikely(%s == Py_None)) {" % self.arg.result())
6602 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
6603 self.exception_type_cname,
6604 StringEncoding.escape_byte_string(
6605 self.exception_message.encode('UTF-8')),
6606 code.error_goto(self.pos)))
6609 def generate_post_assignment_code(self, code):
6610 self.arg.generate_post_assignment_code(code)
6612 def free_temps(self, code):
6613 self.arg.free_temps(code)
6616 class CoerceToPyTypeNode(CoercionNode):
6617 # This node is used to convert a C data type
6618 # to a Python object.
6620 type = py_object_type
6623 def __init__(self, arg, env, type=py_object_type):
6624 CoercionNode.__init__(self, arg)
6625 if not arg.type.create_to_py_utility_code(env):
6627 "Cannot convert '%s' to Python object" % arg.type)
6628 if type is not py_object_type:
6629 self.type = py_object_type
6630 elif arg.type.is_string:
6631 self.type = bytes_type
6632 elif arg.type is PyrexTypes.c_py_unicode_type:
6633 self.type = unicode_type
6635 gil_message = "Converting to Python object"
6637 def may_be_none(self):
6638 # FIXME: is this always safe?
6641 def coerce_to_boolean(self, env):
6642 arg_type = self.arg.type
6643 if (arg_type == PyrexTypes.c_bint_type or
6644 (arg_type.is_pyobject and arg_type.name == 'bool')):
6645 return self.arg.coerce_to_temp(env)
6647 return CoerceToBooleanNode(self, env)
6649 def coerce_to_integer(self, env):
6650 # If not already some C integer type, coerce to longint.
6651 if self.arg.type.is_int:
6654 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
6656 def analyse_types(self, env):
6657 # The arg is always already analysed
6660 def generate_result_code(self, code):
6661 function = self.arg.type.to_py_function
6662 code.putln('%s = %s(%s); %s' % (
6666 code.error_goto_if_null(self.result(), self.pos)))
6667 code.put_gotref(self.py_result())
6670 class CoerceIntToBytesNode(CoerceToPyTypeNode):
6671 # This node is used to convert a C int type to a Python bytes
6676 def __init__(self, arg, env):
6677 arg = arg.coerce_to_simple(env)
6678 CoercionNode.__init__(self, arg)
6679 self.type = Builtin.bytes_type
6681 def generate_result_code(self, code):
6683 arg_result = arg.result()
6684 if arg.type not in (PyrexTypes.c_char_type,
6685 PyrexTypes.c_uchar_type,
6686 PyrexTypes.c_schar_type):
6688 code.putln("if ((%s < 0) || (%s > 255)) {" % (
6689 arg_result, arg_result))
6691 code.putln("if (%s > 255) {" % arg_result)
6692 code.putln('PyErr_Format(PyExc_OverflowError, '
6693 '"value too large to pack into a byte"); %s' % (
6694 code.error_goto(self.pos)))
6697 if arg.type is not PyrexTypes.c_char_type:
6698 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
6699 code.putln("%s = (char)%s;" % (temp, arg_result))
6701 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
6704 code.error_goto_if_null(self.result(), self.pos)))
6705 if temp is not None:
6706 code.funcstate.release_temp(temp)
6707 code.put_gotref(self.py_result())
6710 class CoerceFromPyTypeNode(CoercionNode):
6711 # This node is used to convert a Python object
6714 def __init__(self, result_type, arg, env):
6715 CoercionNode.__init__(self, arg)
6716 self.type = result_type
6718 if not result_type.create_from_py_utility_code(env):
6720 "Cannot convert Python object to '%s'" % result_type)
6721 if self.type.is_string and self.arg.is_ephemeral():
6723 "Obtaining char * from temporary Python value")
6725 def analyse_types(self, env):
6726 # The arg is always already analysed
6729 def generate_result_code(self, code):
6730 function = self.type.from_py_function
6731 operand = self.arg.py_result()
6732 rhs = "%s(%s)" % (function, operand)
6733 if self.type.is_enum:
6734 rhs = typecast(self.type, c_long_type, rhs)
6735 code.putln('%s = %s; %s' % (
6738 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
6739 if self.type.is_pyobject:
6740 code.put_gotref(self.py_result())
6743 class CoerceToBooleanNode(CoercionNode):
6744 # This node is used when a result needs to be used
6745 # in a boolean context.
6747 type = PyrexTypes.c_bint_type
6749 _special_builtins = {
6750 Builtin.list_type : 'PyList_GET_SIZE',
6751 Builtin.tuple_type : 'PyTuple_GET_SIZE',
6752 Builtin.bytes_type : 'PyBytes_GET_SIZE',
6753 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
6756 def __init__(self, arg, env):
6757 CoercionNode.__init__(self, arg)
6758 if arg.type.is_pyobject:
6761 def nogil_check(self, env):
6762 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
6765 gil_message = "Truth-testing Python object"
6767 def check_const(self):
6771 return self.arg.check_const()
6773 def calculate_result_code(self):
6774 return "(%s != 0)" % self.arg.result()
6776 def generate_result_code(self, code):
6777 if not self.is_temp:
6779 test_func = self._special_builtins.get(self.arg.type)
6780 if test_func is not None:
6781 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
6783 self.arg.py_result(),
6785 self.arg.py_result()))
6788 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6790 self.arg.py_result(),
6791 code.error_goto_if_neg(self.result(), self.pos)))
6793 class CoerceToComplexNode(CoercionNode):
6795 def __init__(self, arg, dst_type, env):
6796 if arg.type.is_complex:
6797 arg = arg.coerce_to_simple(env)
6798 self.type = dst_type
6799 CoercionNode.__init__(self, arg)
6800 dst_type.create_declaration_utility_code(env)
6802 def calculate_result_code(self):
6803 if self.arg.type.is_complex:
6804 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
6805 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
6807 real_part = self.arg.result()
6809 return "%s(%s, %s)" % (
6810 self.type.from_parts,
6814 def generate_result_code(self, code):
6817 class CoerceToTempNode(CoercionNode):
6818 # This node is used to force the result of another node
6819 # to be stored in a temporary. It is only used if the
6820 # argument node's result is not already in a temporary.
6822 def __init__(self, arg, env):
6823 CoercionNode.__init__(self, arg)
6824 self.type = self.arg.type
6825 self.constant_result = self.arg.constant_result
6827 if self.type.is_pyobject:
6828 self.result_ctype = py_object_type
6830 gil_message = "Creating temporary Python reference"
6832 def analyse_types(self, env):
6833 # The arg is always already analysed
6836 def coerce_to_boolean(self, env):
6837 self.arg = self.arg.coerce_to_boolean(env)
6838 if self.arg.is_simple():
6840 self.type = self.arg.type
6841 self.result_ctype = self.type
6844 def generate_result_code(self, code):
6845 #self.arg.generate_evaluation_code(code) # Already done
6846 # by generic generate_subexpr_evaluation_code!
6847 code.putln("%s = %s;" % (
6848 self.result(), self.arg.result_as(self.ctype())))
6849 if self.type.is_pyobject and self.use_managed_ref:
6850 code.put_incref(self.result(), self.ctype())
6853 class CloneNode(CoercionNode):
6854 # This node is employed when the result of another node needs
6855 # to be used multiple times. The argument node's result must
6856 # be in a temporary. This node "borrows" the result from the
6857 # argument node, and does not generate any evaluation or
6858 # disposal code for it. The original owner of the argument
6859 # node is responsible for doing those things.
6861 subexprs = [] # Arg is not considered a subexpr
6864 def __init__(self, arg):
6865 CoercionNode.__init__(self, arg)
6866 if hasattr(arg, 'type'):
6867 self.type = arg.type
6868 self.result_ctype = arg.result_ctype
6869 if hasattr(arg, 'entry'):
6870 self.entry = arg.entry
6873 return self.arg.result()
6875 def type_dependencies(self, env):
6876 return self.arg.type_dependencies(env)
6878 def infer_type(self, env):
6879 return self.arg.infer_type(env)
6881 def analyse_types(self, env):
6882 self.type = self.arg.type
6883 self.result_ctype = self.arg.result_ctype
6885 if hasattr(self.arg, 'entry'):
6886 self.entry = self.arg.entry
6888 def generate_evaluation_code(self, code):
6891 def generate_result_code(self, code):
6894 def generate_disposal_code(self, code):
6897 def free_temps(self, code):
6901 class ModuleRefNode(ExprNode):
6902 # Simple returns the module object
6904 type = py_object_type
6908 def analyse_types(self, env):
6911 def may_be_none(self):
6914 def calculate_result_code(self):
6915 return Naming.module_cname
6917 def generate_result_code(self, code):
6920 class DocstringRefNode(ExprNode):
6921 # Extracts the docstring of the body element
6924 type = py_object_type
6927 def __init__(self, pos, body):
6928 ExprNode.__init__(self, pos)
6929 assert body.type.is_pyobject
6932 def analyse_types(self, env):
6935 def generate_result_code(self, code):
6936 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
6937 self.result(), self.body.result(),
6938 code.error_goto_if_null(self.result(), self.pos)))
6939 code.put_gotref(self.result())
6943 #------------------------------------------------------------------------------------
6945 # Runtime support code
6947 #------------------------------------------------------------------------------------
6949 get_name_interned_utility_code = UtilityCode(
6951 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
6954 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
6956 result = PyObject_GetAttr(dict, name);
6958 PyErr_SetObject(PyExc_NameError, name);
6963 #------------------------------------------------------------------------------------
6965 import_utility_code = UtilityCode(
6967 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
6970 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
6971 PyObject *py_import = 0;
6972 PyObject *empty_list = 0;
6973 PyObject *module = 0;
6974 PyObject *global_dict = 0;
6975 PyObject *empty_dict = 0;
6977 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
6983 empty_list = PyList_New(0);
6988 global_dict = PyModule_GetDict(%(GLOBALS)s);
6991 empty_dict = PyDict_New();
6994 module = PyObject_CallFunctionObjArgs(py_import,
6995 name, global_dict, empty_dict, list, NULL);
6997 Py_XDECREF(empty_list);
6998 Py_XDECREF(py_import);
6999 Py_XDECREF(empty_dict);
7003 "BUILTINS": Naming.builtins_cname,
7004 "GLOBALS": Naming.module_cname,
7007 #------------------------------------------------------------------------------------
7009 get_exception_utility_code = UtilityCode(
7011 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7014 static PyObject *__Pyx_GetExcValue(void) {
7015 PyObject *type = 0, *value = 0, *tb = 0;
7016 PyObject *tmp_type, *tmp_value, *tmp_tb;
7017 PyObject *result = 0;
7018 PyThreadState *tstate = PyThreadState_Get();
7019 PyErr_Fetch(&type, &value, &tb);
7020 PyErr_NormalizeException(&type, &value, &tb);
7021 if (PyErr_Occurred())
7027 tmp_type = tstate->exc_type;
7028 tmp_value = tstate->exc_value;
7029 tmp_tb = tstate->exc_traceback;
7030 tstate->exc_type = type;
7031 tstate->exc_value = value;
7032 tstate->exc_traceback = tb;
7033 /* Make sure tstate is in a consistent state when we XDECREF
7034 these objects (XDECREF may run arbitrary code). */
7035 Py_XDECREF(tmp_type);
7036 Py_XDECREF(tmp_value);
7051 #------------------------------------------------------------------------------------
7053 type_test_utility_code = UtilityCode(
7055 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7058 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7059 if (unlikely(!type)) {
7060 PyErr_Format(PyExc_SystemError, "Missing type object");
7063 if (likely(PyObject_TypeCheck(obj, type)))
7065 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7066 Py_TYPE(obj)->tp_name, type->tp_name);
7071 #------------------------------------------------------------------------------------
7073 create_class_utility_code = UtilityCode(
7075 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/
7078 static PyObject *__Pyx_CreateClass(
7079 PyObject *bases, PyObject *dict, PyObject *name, const char *modname)
7081 PyObject *py_modname;
7082 PyObject *result = 0;
7084 #if PY_MAJOR_VERSION < 3
7085 py_modname = PyString_FromString(modname);
7087 py_modname = PyUnicode_FromString(modname);
7091 if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
7093 #if PY_MAJOR_VERSION < 3
7094 result = PyClass_New(bases, dict, name);
7096 result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
7099 Py_XDECREF(py_modname);
7104 #------------------------------------------------------------------------------------
7106 cpp_exception_utility_code = UtilityCode(
7108 #ifndef __Pyx_CppExn2PyErr
7109 static void __Pyx_CppExn2PyErr() {
7111 if (PyErr_Occurred())
7112 ; // let the latest Python exn pass through and ignore the current one
7115 } catch (const std::invalid_argument& exn) {
7116 // Catch a handful of different errors here and turn them into the
7117 // equivalent Python errors.
7118 // Change invalid_argument to ValueError
7119 PyErr_SetString(PyExc_ValueError, exn.what());
7120 } catch (const std::out_of_range& exn) {
7121 // Change out_of_range to IndexError
7122 PyErr_SetString(PyExc_IndexError, exn.what());
7123 } catch (const std::exception& exn) {
7124 PyErr_SetString(PyExc_RuntimeError, exn.what());
7128 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7136 #------------------------------------------------------------------------------------
7138 raise_noneattr_error_utility_code = UtilityCode(
7140 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7143 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7144 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7148 raise_noneindex_error_utility_code = UtilityCode(
7150 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7153 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7154 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7158 raise_none_iter_error_utility_code = UtilityCode(
7160 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7163 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7164 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7168 #------------------------------------------------------------------------------------
7170 getitem_dict_utility_code = UtilityCode(
7173 #if PY_MAJOR_VERSION >= 3
7174 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7176 if (unlikely(d == Py_None)) {
7177 __Pyx_RaiseNoneIndexingError();
7180 value = PyDict_GetItemWithError(d, key);
7181 if (unlikely(!value)) {
7182 if (!PyErr_Occurred())
7183 PyErr_SetObject(PyExc_KeyError, key);
7190 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7193 requires = [raise_noneindex_error_utility_code])
7195 #------------------------------------------------------------------------------------
7197 getitem_int_pyunicode_utility_code = UtilityCode(
7199 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7200 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7201 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7203 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7204 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7205 return PyUnicode_AS_UNICODE(ustring)[i];
7206 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7207 i += PyUnicode_GET_SIZE(ustring);
7208 return PyUnicode_AS_UNICODE(ustring)[i];
7210 PyErr_SetString(PyExc_IndexError, "string index out of range");
7211 return (Py_UNICODE)-1;
7215 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7217 PyObject *uchar_string;
7218 if (!j) return (Py_UNICODE)-1;
7219 uchar_string = PyObject_GetItem(ustring, j);
7221 if (!uchar_string) return (Py_UNICODE)-1;
7222 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7223 Py_DECREF(uchar_string);
7228 getitem_int_utility_code = UtilityCode(
7231 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7233 if (!j) return NULL;
7234 r = PyObject_GetItem(o, j);
7241 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7242 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7243 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7245 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
7246 if (likely(o != Py_None)) {
7247 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
7248 PyObject *r = Py%(type)s_GET_ITEM(o, i);
7252 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
7253 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
7258 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7260 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
7263 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7264 __Pyx_GetItemInt_Fast(o, i) : \\
7265 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7267 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
7269 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7270 r = PyList_GET_ITEM(o, i);
7273 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
7274 r = PyTuple_GET_ITEM(o, i);
7277 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
7278 r = PySequence_GetItem(o, i);
7281 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7291 #------------------------------------------------------------------------------------
7293 setitem_int_utility_code = UtilityCode(
7295 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7296 __Pyx_SetItemInt_Fast(o, i, v) : \\
7297 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
7299 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
7302 r = PyObject_SetItem(o, j, v);
7307 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
7308 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7310 Py_DECREF(PyList_GET_ITEM(o, i));
7311 PyList_SET_ITEM(o, i, v);
7314 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
7315 return PySequence_SetItem(o, i, v);
7317 PyObject *j = PyInt_FromSsize_t(i);
7318 return __Pyx_SetItemInt_Generic(o, j, v);
7325 #------------------------------------------------------------------------------------
7327 delitem_int_utility_code = UtilityCode(
7329 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7330 __Pyx_DelItemInt_Fast(o, i) : \\
7331 __Pyx_DelItem_Generic(o, to_py_func(i)))
7333 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
7336 r = PyObject_DelItem(o, j);
7341 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
7342 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
7343 return PySequence_DelItem(o, i);
7345 PyObject *j = PyInt_FromSsize_t(i);
7346 return __Pyx_DelItem_Generic(o, j);
7353 #------------------------------------------------------------------------------------
7355 raise_too_many_values_to_unpack = UtilityCode(
7357 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
7360 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
7361 PyErr_Format(PyExc_ValueError,
7362 #if PY_VERSION_HEX < 0x02050000
7363 "too many values to unpack (expected %d)", (int)expected);
7365 "too many values to unpack (expected %zd)", expected);
7370 raise_need_more_values_to_unpack = UtilityCode(
7372 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
7375 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
7376 PyErr_Format(PyExc_ValueError,
7377 #if PY_VERSION_HEX < 0x02050000
7378 "need more than %d value%s to unpack", (int)index,
7380 "need more than %zd value%s to unpack", index,
7382 (index == 1) ? "" : "s");
7386 #------------------------------------------------------------------------------------
7388 tuple_unpacking_error_code = UtilityCode(
7390 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
7393 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
7395 __Pyx_RaiseNoneNotIterableError();
7396 } else if (PyTuple_GET_SIZE(t) < index) {
7397 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
7399 __Pyx_RaiseTooManyValuesError(index);
7403 requires = [raise_none_iter_error_utility_code,
7404 raise_need_more_values_to_unpack,
7405 raise_too_many_values_to_unpack]
7408 unpacking_utility_code = UtilityCode(
7410 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
7411 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
7414 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
7416 if (!(item = PyIter_Next(iter))) {
7417 if (!PyErr_Occurred()) {
7418 __Pyx_RaiseNeedMoreValuesError(index);
7424 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
7426 if ((item = PyIter_Next(iter))) {
7428 __Pyx_RaiseTooManyValuesError(expected);
7431 else if (!PyErr_Occurred())
7437 requires = [raise_need_more_values_to_unpack,
7438 raise_too_many_values_to_unpack]
7441 #------------------------------------------------------------------------------------
7443 # CPython supports calling functions with non-dict kwargs by
7444 # converting them to a dict first
7446 kwargs_call_utility_code = UtilityCode(
7448 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
7451 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
7453 if (likely(PyDict_Check(kwargs))) {
7454 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
7456 PyObject* real_dict;
7457 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
7458 if (unlikely(!real_dict))
7460 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
7461 Py_DECREF(real_dict);
7462 return result; /* may be NULL */
7469 #------------------------------------------------------------------------------------
7471 int_pow_utility_code = UtilityCode(
7473 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
7476 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
7488 if (unlikely(e<0)) return 0;
7491 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
7499 # ------------------------------ Division ------------------------------------
7501 div_int_utility_code = UtilityCode(
7503 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
7506 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
7508 %(type)s r = a - q*b;
7509 q -= ((r != 0) & ((r ^ b) < 0));
7514 mod_int_utility_code = UtilityCode(
7516 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
7519 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
7520 %(type)s r = a %% b;
7521 r += ((r != 0) & ((r ^ b) < 0)) * b;
7526 mod_float_utility_code = UtilityCode(
7528 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
7531 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
7532 %(type)s r = fmod%(math_h_modifier)s(a, b);
7533 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
7538 cdivision_warning_utility_code = UtilityCode(
7540 static int __Pyx_cdivision_warning(void); /* proto */
7543 static int __Pyx_cdivision_warning(void) {
7544 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
7545 "division with oppositely signed operands, C and Python semantics differ",
7552 'FILENAME': Naming.filename_cname,
7553 'LINENO': Naming.lineno_cname,
7557 division_overflow_test_code = UtilityCode(
7559 #define UNARY_NEG_WOULD_OVERFLOW(x) \
7560 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
7564 binding_cfunc_utility_code = UtilityCode(
7566 #define %(binding_cfunc)s_USED 1
7569 PyCFunctionObject func;
7570 } %(binding_cfunc)s_object;
7572 PyTypeObject %(binding_cfunc)s_type;
7573 PyTypeObject *%(binding_cfunc)s = NULL;
7575 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
7576 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
7578 int %(binding_cfunc)s_init(void); /* proto */
7579 """ % Naming.__dict__,
7582 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
7583 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
7588 op->func.m_self = self;
7590 op->func.m_module = module;
7591 PyObject_GC_Track(op);
7592 return (PyObject *)op;
7595 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
7596 PyObject_GC_UnTrack(m);
7597 Py_XDECREF(m->func.m_self);
7598 Py_XDECREF(m->func.m_module);
7602 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
7605 return PyMethod_New(func, obj, type);
7608 int %(binding_cfunc)s_init(void) {
7609 %(binding_cfunc)s_type = PyCFunction_Type;
7610 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
7611 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
7612 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
7613 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
7616 %(binding_cfunc)s = &%(binding_cfunc)s_type;
7620 """ % Naming.__dict__)