2 # Pyrex - Parse tree nodes for expressions
7 from Errors import error, warning, warn_once, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Code import UtilityCode
13 from Nodes import Node
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
17 from Builtin import list_type, tuple_type, set_type, dict_type, \
18 unicode_type, str_type, bytes_type, type_type
22 from Cython import Utils
23 from Annotate import AnnotationItem
24 from Cython import Utils
26 from Cython.Debugging import print_call_chain
27 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
33 from sets import Set as set
35 class NotConstant(object):
37 return "<NOT CONSTANT>"
39 not_a_constant = NotConstant()
40 constant_value_not_set = object()
42 # error messages when coercing from key[0] to key[1]
43 find_coercion_error = {
44 # string related errors
45 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
46 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
47 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
48 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
49 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
50 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
51 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
52 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
53 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
54 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
59 # subexprs [string] Class var holding names of subexpr node attrs
60 # type PyrexType Type of the result
61 # result_code string Code fragment
62 # result_ctype string C type of result_code if different from type
63 # is_temp boolean Result is in a temporary variable
64 # is_sequence_constructor
65 # boolean Is a list or tuple constructor expression
66 # is_starred boolean Is a starred expression (e.g. '*a')
68 # [ExprNode or [ExprNode or None] or None]
69 # Cached result of subexpr_nodes()
70 # use_managed_ref boolean use ref-counted temps/assignments/etc.
75 old_temp = None # error checker for multiple frees etc.
76 use_managed_ref = True # can be set by optimisation transforms
78 # The Analyse Expressions phase for expressions is split
79 # into two sub-phases:
82 # Determines the result type of the expression based
83 # on the types of its sub-expressions, and inserts
84 # coercion nodes into the expression tree where needed.
85 # Marks nodes which will need to have temporary variables
89 # Allocates temporary variables where needed, and fills
90 # in the result_code field of each node.
92 # ExprNode provides some convenience routines which
93 # perform both of the above phases. These should only
94 # be called from statement nodes, and only when no
95 # coercion nodes need to be added around the expression
96 # being analysed. In that case, the above two phases
97 # should be invoked separately.
99 # Framework code in ExprNode provides much of the common
100 # processing for the various phases. It makes use of the
101 # 'subexprs' class attribute of ExprNodes, which should
102 # contain a list of the names of attributes which can
103 # hold sub-nodes or sequences of sub-nodes.
105 # The framework makes use of a number of abstract methods.
106 # Their responsibilities are as follows.
108 # Declaration Analysis phase
110 # analyse_target_declaration
111 # Called during the Analyse Declarations phase to analyse
112 # the LHS of an assignment or argument of a del statement.
113 # Nodes which cannot be the LHS of an assignment need not
116 # Expression Analysis phase
119 # - Call analyse_types on all sub-expressions.
120 # - Check operand types, and wrap coercion nodes around
121 # sub-expressions where needed.
122 # - Set the type of this node.
123 # - If a temporary variable will be required for the
124 # result, set the is_temp flag of this node.
126 # analyse_target_types
127 # Called during the Analyse Types phase to analyse
128 # the LHS of an assignment or argument of a del
129 # statement. Similar responsibilities to analyse_types.
132 # Called by the default implementation of allocate_target_temps.
133 # Should return a C lvalue for assigning to the node. The default
134 # implementation calls calculate_result_code.
137 # - Check that this node and its subnodes form a
138 # legal constant expression. If so, do nothing,
139 # otherwise call not_const.
141 # The default implementation of check_const
142 # assumes that the expression is not constant.
145 # - Same as check_const, except check that the
146 # expression is a C lvalue whose address is
147 # constant. Otherwise, call addr_not_const.
149 # The default implementation of calc_const_addr
150 # assumes that the expression is not a constant
153 # Code Generation phase
155 # generate_evaluation_code
156 # - Call generate_evaluation_code for sub-expressions.
157 # - Perform the functions of generate_result_code
159 # - If result is temporary, call generate_disposal_code
160 # on all sub-expressions.
162 # A default implementation of generate_evaluation_code
163 # is provided which uses the following abstract methods:
165 # generate_result_code
166 # - Generate any C statements necessary to calculate
167 # the result of this node from the results of its
170 # calculate_result_code
171 # - Should return a C code fragment evaluating to the
172 # result. This is only called when the result is not
175 # generate_assignment_code
176 # Called on the LHS of an assignment.
177 # - Call generate_evaluation_code for sub-expressions.
178 # - Generate code to perform the assignment.
179 # - If the assignment absorbed a reference, call
180 # generate_post_assignment_code on the RHS,
181 # otherwise call generate_disposal_code on it.
183 # generate_deletion_code
184 # Called on an argument of a del statement.
185 # - Call generate_evaluation_code for sub-expressions.
186 # - Generate code to perform the deletion.
187 # - Call generate_disposal_code on all sub-expressions.
191 is_sequence_constructor = 0
194 saved_subexpr_nodes = None
199 constant_result = constant_value_not_set
202 _get_child_attrs = operator.attrgetter('subexprs')
203 except AttributeError:
205 def _get_child_attrs(self):
207 child_attrs = property(fget=_get_child_attrs)
209 def not_implemented(self, method_name):
210 print_call_chain(method_name, "not implemented") ###
212 "%s.%s not implemented" %
213 (self.__class__.__name__, method_name))
218 def is_ephemeral(self):
219 # An ephemeral node is one whose result is in
220 # a Python temporary and we suspect there are no
221 # other references to it. Certain operations are
222 # disallowed on such values, since they are
223 # likely to result in a dangling pointer.
224 return self.type.is_pyobject and self.is_temp
226 def subexpr_nodes(self):
227 # Extract a list of subexpression nodes based
228 # on the contents of the subexprs class attribute.
230 for name in self.subexprs:
231 item = getattr(self, name)
233 if type(item) is list:
241 return self.temp_code
243 return self.calculate_result_code()
245 def result_as(self, type = None):
246 # Return the result code cast to the specified C type.
247 return typecast(type, self.ctype(), self.result())
250 # Return the result code cast to PyObject *.
251 return self.result_as(py_object_type)
254 # Return the native C type of the result (i.e. the
255 # C type of the result_code expression).
256 return self.result_ctype or self.type
258 def get_constant_c_result_code(self):
259 # Return the constant value of this node as a result code
260 # string, or None if the node is not constant. This method
261 # can be called when the constant result code is required
262 # before the code generation phase.
264 # The return value is a string that can represent a simple C
265 # value, a constant C name or a constant C expression. If the
266 # node type depends on Python code, this must return None.
269 def calculate_constant_result(self):
270 # Calculate the constant compile time result value of this
271 # expression and store it in ``self.constant_result``. Does
272 # nothing by default, thus leaving ``self.constant_result``
273 # unknown. If valid, the result can be an arbitrary Python
276 # This must only be called when it is assured that all
277 # sub-expressions have a valid constant_result value. The
278 # ConstantFolding transform will do this.
281 def has_constant_result(self):
282 return self.constant_result is not constant_value_not_set and \
283 self.constant_result is not not_a_constant
285 def compile_time_value(self, denv):
286 # Return value of compile-time expression, or report error.
287 error(self.pos, "Invalid compile-time expression")
289 def compile_time_value_error(self, e):
290 error(self.pos, "Error in compile-time expression: %s: %s" % (
291 e.__class__.__name__, e))
293 # ------------- Declaration Analysis ----------------
295 def analyse_target_declaration(self, env):
296 error(self.pos, "Cannot assign to or delete this")
298 # ------------- Expression Analysis ----------------
300 def analyse_const_expression(self, env):
301 # Called during the analyse_declarations phase of a
302 # constant expression. Analyses the expression's type,
303 # checks whether it is a legal const expression,
304 # and determines its value.
305 self.analyse_types(env)
306 return self.check_const()
308 def analyse_expressions(self, env):
309 # Convenience routine performing both the Type
310 # Analysis and Temp Allocation phases for a whole
312 self.analyse_types(env)
314 def analyse_target_expression(self, env, rhs):
315 # Convenience routine performing both the Type
316 # Analysis and Temp Allocation phases for the LHS of
318 self.analyse_target_types(env)
320 def analyse_boolean_expression(self, env):
321 # Analyse expression and coerce to a boolean.
322 self.analyse_types(env)
323 bool = self.coerce_to_boolean(env)
326 def analyse_temp_boolean_expression(self, env):
327 # Analyse boolean expression and coerce result into
328 # a temporary. This is used when a branch is to be
329 # performed on the result and we won't have an
330 # opportunity to ensure disposal code is executed
331 # afterwards. By forcing the result into a temporary,
332 # we ensure that all disposal has been done by the
333 # time we get the result.
334 self.analyse_types(env)
335 return self.coerce_to_boolean(env).coerce_to_simple(env)
337 # --------------- Type Inference -----------------
339 def type_dependencies(self, env):
340 # Returns the list of entries whose types must be determined
341 # before the type of self can be infered.
342 if hasattr(self, 'type') and self.type is not None:
344 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
346 def infer_type(self, env):
347 # Attempt to deduce the type of self.
348 # Differs from analyse_types as it avoids unnecessary
349 # analysis of subexpressions, but can assume everything
350 # in self.type_dependencies() has been resolved.
351 if hasattr(self, 'type') and self.type is not None:
353 elif hasattr(self, 'entry') and self.entry is not None:
354 return self.entry.type
356 self.not_implemented("infer_type")
358 # --------------- Type Analysis ------------------
360 def analyse_as_module(self, env):
361 # If this node can be interpreted as a reference to a
362 # cimported module, return its scope, else None.
365 def analyse_as_type(self, env):
366 # If this node can be interpreted as a reference to a
367 # type, return that type, else None.
370 def analyse_as_extension_type(self, env):
371 # If this node can be interpreted as a reference to an
372 # extension type, return its type, else None.
375 def analyse_types(self, env):
376 self.not_implemented("analyse_types")
378 def analyse_target_types(self, env):
379 self.analyse_types(env)
381 def nogil_check(self, env):
382 # By default, any expression based on Python objects is
383 # prevented in nogil environments. Subtypes must override
384 # this if they can work without the GIL.
385 if self.type.is_pyobject:
388 def gil_assignment_check(self, env):
389 if env.nogil and self.type.is_pyobject:
390 error(self.pos, "Assignment of Python object not allowed without gil")
392 def check_const(self):
397 error(self.pos, "Not allowed in a constant expression")
399 def check_const_addr(self):
400 self.addr_not_const()
403 def addr_not_const(self):
404 error(self.pos, "Address is not constant")
406 # ----------------- Result Allocation -----------------
408 def result_in_temp(self):
409 # Return true if result is in a temporary owned by
410 # this node or one of its subexpressions. Overridden
411 # by certain nodes which can share the result of
415 def target_code(self):
416 # Return code fragment for use as LHS of a C assignment.
417 return self.calculate_result_code()
419 def calculate_result_code(self):
420 self.not_implemented("calculate_result_code")
422 # def release_target_temp(self, env):
423 # # Release temporaries used by LHS of an assignment.
424 # self.release_subexpr_temps(env)
426 def allocate_temp_result(self, code):
428 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
432 type = PyrexTypes.py_object_type
433 self.temp_code = code.funcstate.allocate_temp(
434 type, manage_ref=self.use_managed_ref)
436 self.temp_code = None
438 def release_temp_result(self, code):
439 if not self.temp_code:
441 raise RuntimeError("temp %s released multiple times in %s" % (
442 self.old_temp, self.__class__.__name__))
444 raise RuntimeError("no temp, but release requested in %s" % (
445 self.__class__.__name__))
446 code.funcstate.release_temp(self.temp_code)
447 self.old_temp = self.temp_code
448 self.temp_code = None
450 # ---------------- Code Generation -----------------
452 def make_owned_reference(self, code):
453 # If result is a pyobject, make sure we own
455 if self.type.is_pyobject and not self.result_in_temp():
456 code.put_incref(self.result(), self.ctype())
458 def generate_evaluation_code(self, code):
459 code.mark_pos(self.pos)
461 # Generate code to evaluate this node and
462 # its sub-expressions, and dispose of any
463 # temporary results of its sub-expressions.
464 self.generate_subexpr_evaluation_code(code)
467 self.allocate_temp_result(code)
469 self.generate_result_code(code)
471 # If we are temp we do not need to wait until this node is disposed
472 # before disposing children.
473 self.generate_subexpr_disposal_code(code)
474 self.free_subexpr_temps(code)
476 def generate_subexpr_evaluation_code(self, code):
477 for node in self.subexpr_nodes():
478 node.generate_evaluation_code(code)
480 def generate_result_code(self, code):
481 self.not_implemented("generate_result_code")
483 def generate_disposal_code(self, code):
485 if self.type.is_pyobject:
486 code.put_decref_clear(self.result(), self.ctype())
488 # Already done if self.is_temp
489 self.generate_subexpr_disposal_code(code)
491 def generate_subexpr_disposal_code(self, code):
492 # Generate code to dispose of temporary results
493 # of all sub-expressions.
494 for node in self.subexpr_nodes():
495 node.generate_disposal_code(code)
497 def generate_post_assignment_code(self, code):
499 if self.type.is_pyobject:
500 code.putln("%s = 0;" % self.result())
502 self.generate_subexpr_disposal_code(code)
504 def generate_assignment_code(self, rhs, code):
505 # Stub method for nodes which are not legal as
506 # the LHS of an assignment. An error will have
507 # been reported earlier.
510 def generate_deletion_code(self, code):
511 # Stub method for nodes that are not legal as
512 # the argument of a del statement. An error
513 # will have been reported earlier.
516 def free_temps(self, code):
518 if not self.type.is_void:
519 self.release_temp_result(code)
521 self.free_subexpr_temps(code)
523 def free_subexpr_temps(self, code):
524 for sub in self.subexpr_nodes():
527 def generate_function_definitions(self, env, code):
530 # ---------------- Annotation ---------------------
532 def annotate(self, code):
533 for node in self.subexpr_nodes():
536 # ----------------- Coercion ----------------------
538 def coerce_to(self, dst_type, env):
539 # Coerce the result so that it can be assigned to
540 # something of type dst_type. If processing is necessary,
541 # wraps this node in a coercion node and returns that.
542 # Otherwise, returns this node unchanged.
544 # This method is called during the analyse_expressions
545 # phase of the src_node's processing.
547 # Note that subclasses that override this (especially
548 # ConstNodes) must not (re-)set their own .type attribute
549 # here. Since expression nodes may turn up in different
550 # places in the tree (e.g. inside of CloneNodes in cascaded
551 # assignments), this method must return a new node instance
552 # if it changes the type.
556 src_is_py_type = src_type.is_pyobject
557 dst_is_py_type = dst_type.is_pyobject
559 if self.check_for_coercion_error(dst_type):
562 if dst_type.is_reference:
563 dst_type = dst_type.ref_base_type
565 if dst_type.is_pyobject:
566 if not src.type.is_pyobject:
567 if dst_type is bytes_type and src.type.is_int:
568 src = CoerceIntToBytesNode(src, env)
570 src = CoerceToPyTypeNode(src, env)
571 if not src.type.subtype_of(dst_type):
572 if not isinstance(src, NoneNode):
573 src = PyTypeTestNode(src, dst_type, env)
574 elif src.type.is_pyobject:
575 src = CoerceFromPyTypeNode(dst_type, src, env)
576 elif (dst_type.is_complex
577 and src_type != dst_type
578 and dst_type.assignable_from(src_type)):
579 src = CoerceToComplexNode(src, dst_type, env)
580 else: # neither src nor dst are py types
581 # Added the string comparison, since for c types that
582 # is enough, but Cython gets confused when the types are
583 # in different pxi files.
584 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
585 self.fail_assignment(dst_type)
588 def fail_assignment(self, dst_type):
589 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
591 def check_for_coercion_error(self, dst_type, fail=False, default=None):
592 if fail and not default:
593 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
594 message = find_coercion_error((self.type, dst_type), default)
595 if message is not None:
596 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
599 self.fail_assignment(dst_type)
603 def coerce_to_pyobject(self, env):
604 return self.coerce_to(PyrexTypes.py_object_type, env)
606 def coerce_to_boolean(self, env):
607 # Coerce result to something acceptable as
610 # if it's constant, calculate the result now
611 if self.has_constant_result():
612 bool_value = bool(self.constant_result)
613 return BoolNode(self.pos, value=bool_value,
614 constant_result=bool_value)
617 if type.is_pyobject or type.is_ptr or type.is_float:
618 return CoerceToBooleanNode(self, env)
620 if not (type.is_int or type.is_enum or type.is_error):
622 "Type '%s' not acceptable as a boolean" % type)
625 def coerce_to_integer(self, env):
626 # If not already some C integer type, coerce to longint.
630 return self.coerce_to(PyrexTypes.c_long_type, env)
632 def coerce_to_temp(self, env):
633 # Ensure that the result is in a temporary.
634 if self.result_in_temp():
637 return CoerceToTempNode(self, env)
639 def coerce_to_simple(self, env):
640 # Ensure that the result is simple (see is_simple).
644 return self.coerce_to_temp(env)
647 # A node is simple if its result is something that can
648 # be referred to without performing any operations, e.g.
649 # a constant, local var, C global var, struct member
650 # reference, or temporary.
651 return self.result_in_temp()
653 def may_be_none(self):
654 return self.type.is_pyobject
656 def as_cython_attribute(self):
659 def as_none_safe_node(self, message, error="PyExc_TypeError"):
660 # Wraps the node in a NoneCheckNode if it is not known to be
661 # not-None (e.g. because it is a Python literal).
662 if self.may_be_none():
663 return NoneCheckNode(self, error, message)
668 class AtomicExprNode(ExprNode):
669 # Abstract base class for expression nodes which have
670 # no sub-expressions.
674 # Override to optimize -- we know we have no children
675 def generate_subexpr_evaluation_code(self, code):
677 def generate_subexpr_disposal_code(self, code):
680 class PyConstNode(AtomicExprNode):
681 # Abstract base class for constant Python values.
684 type = py_object_type
689 def may_be_none(self):
692 def analyse_types(self, env):
695 def calculate_result_code(self):
698 def generate_result_code(self, code):
702 class NoneNode(PyConstNode):
703 # The constant value None
707 constant_result = None
711 def compile_time_value(self, denv):
714 def may_be_none(self):
718 class EllipsisNode(PyConstNode):
719 # '...' in a subscript list.
721 value = "Py_Ellipsis"
723 constant_result = Ellipsis
725 def compile_time_value(self, denv):
729 class ConstNode(AtomicExprNode):
730 # Abstract base type for literal constant nodes.
732 # value string C code fragment
740 def may_be_none(self):
743 def analyse_types(self, env):
744 pass # Types are held in class variables
746 def check_const(self):
749 def get_constant_c_result_code(self):
750 return self.calculate_result_code()
752 def calculate_result_code(self):
753 return str(self.value)
755 def generate_result_code(self, code):
759 class BoolNode(ConstNode):
760 type = PyrexTypes.c_bint_type
761 # The constant value True or False
763 def calculate_constant_result(self):
764 self.constant_result = self.value
766 def compile_time_value(self, denv):
769 def calculate_result_code(self):
770 return str(int(self.value))
773 class NullNode(ConstNode):
774 type = PyrexTypes.c_null_ptr_type
778 def get_constant_c_result_code(self):
782 class CharNode(ConstNode):
783 type = PyrexTypes.c_char_type
785 def calculate_constant_result(self):
786 self.constant_result = ord(self.value)
788 def compile_time_value(self, denv):
789 return ord(self.value)
791 def calculate_result_code(self):
792 return "'%s'" % StringEncoding.escape_char(self.value)
795 class IntNode(ConstNode):
798 # longness "" or "L" or "LL"
803 def __init__(self, pos, **kwds):
804 ExprNode.__init__(self, pos, **kwds)
805 if 'type' not in kwds:
806 rank = max(1, len(self.longness))
807 sign = not self.unsigned
808 self.type = PyrexTypes.modifiers_and_name_to_type[sign, rank, "int"]
810 def coerce_to(self, dst_type, env):
811 if self.type is dst_type:
813 elif dst_type.is_float:
814 float_value = float(self.value)
815 return FloatNode(self.pos, value=repr(float_value), constant_result=float_value)
816 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
817 unsigned=self.unsigned, longness=self.longness)
818 if dst_type.is_numeric and not dst_type.is_complex:
820 if dst_type.is_pyobject:
821 node.type = PyrexTypes.py_object_type
822 # We still need to perform normal coerce_to processing on the
823 # result, because we might be coercing to an extension type,
824 # in which case a type test node will be needed.
825 return ConstNode.coerce_to(node, dst_type, env)
827 def coerce_to_boolean(self, env):
829 self.pos, value=self.value,
830 type = PyrexTypes.c_bint_type,
831 unsigned=self.unsigned, longness=self.longness)
833 def generate_evaluation_code(self, code):
834 if self.type.is_pyobject:
835 # pre-allocate a Python version of the number
836 self.result_code = code.get_py_num(self.value, self.longness)
838 self.result_code = self.get_constant_c_result_code()
840 def get_constant_c_result_code(self):
842 if isinstance(value, basestring) and len(value) > 2:
843 # must convert C-incompatible Py3 oct/bin notations
845 value = value[0] + value[2:] # '0o123' => '0123'
846 elif value[1] in 'bB':
847 value = int(value[2:], 2)
848 return str(value) + self.unsigned + self.longness
850 def calculate_result_code(self):
851 return self.result_code
853 def calculate_constant_result(self):
854 self.constant_result = Utils.str_to_number(self.value)
856 def compile_time_value(self, denv):
857 return Utils.str_to_number(self.value)
860 class FloatNode(ConstNode):
861 type = PyrexTypes.c_double_type
863 def calculate_constant_result(self):
864 self.constant_result = float(self.value)
866 def compile_time_value(self, denv):
867 return float(self.value)
869 def calculate_result_code(self):
871 assert isinstance(strval, (str, unicode))
872 cmpval = repr(float(strval))
874 return "(Py_HUGE_VAL * 0)"
875 elif cmpval == 'inf':
877 elif cmpval == '-inf':
878 return "(-Py_HUGE_VAL)"
883 class BytesNode(ConstNode):
884 # A char* or bytes literal
888 type = PyrexTypes.c_char_ptr_type
890 def compile_time_value(self, denv):
893 def analyse_as_type(self, env):
894 type = PyrexTypes.parse_basic_type(self.value)
897 from TreeFragment import TreeFragment
898 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
899 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
900 sizeof_node = declaration.root.stats[0].expr
901 sizeof_node.analyse_types(env)
902 if isinstance(sizeof_node, SizeofTypeNode):
903 return sizeof_node.arg_type
905 def can_coerce_to_char_literal(self):
906 return len(self.value) == 1
908 def coerce_to_boolean(self, env):
909 # This is special because we start off as a C char*. Testing
910 # that for truth directly would yield the wrong result.
911 return BoolNode(self.pos, value=bool(self.value))
913 def coerce_to(self, dst_type, env):
915 if not self.can_coerce_to_char_literal():
916 error(self.pos, "Only single-character string literals can be coerced into ints.")
918 if dst_type is PyrexTypes.c_py_unicode_type:
919 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.")
921 return CharNode(self.pos, value=self.value)
923 node = BytesNode(self.pos, value=self.value)
924 if dst_type == PyrexTypes.c_char_ptr_type:
925 node.type = PyrexTypes.c_char_ptr_type
927 elif dst_type == PyrexTypes.c_uchar_ptr_type:
928 node.type = PyrexTypes.c_char_ptr_type
929 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
931 if not self.type.is_pyobject:
932 if dst_type in (py_object_type, Builtin.bytes_type):
933 node.type = Builtin.bytes_type
934 elif dst_type.is_pyobject:
935 self.fail_assignment(dst_type)
937 elif dst_type.is_pyobject and dst_type is not py_object_type:
938 self.check_for_coercion_error(dst_type, fail=True)
941 # We still need to perform normal coerce_to processing on the
942 # result, because we might be coercing to an extension type,
943 # in which case a type test node will be needed.
944 return ConstNode.coerce_to(node, dst_type, env)
946 def as_py_string_node(self, env):
947 # Return a new BytesNode with the same value as this node
948 # but whose type is a Python type instead of a C type.
949 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
951 def generate_evaluation_code(self, code):
952 if self.type.is_pyobject:
953 self.result_code = code.get_py_string_const(self.value)
955 self.result_code = code.get_string_const(self.value)
957 def get_constant_c_result_code(self):
960 def calculate_result_code(self):
961 return self.result_code
964 class UnicodeNode(PyConstNode):
965 # A Python unicode object
967 # value EncodedString
968 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
973 def coerce_to(self, dst_type, env):
974 if dst_type is self.type:
976 elif dst_type is PyrexTypes.c_py_unicode_type:
977 if not self.can_coerce_to_char_literal():
978 error(self.pos, "Only single-character Unicode string literals can be coerced into Py_UNICODE.")
980 int_value = ord(self.value)
981 return IntNode(self.pos, value=int_value, constant_result=int_value)
982 elif not dst_type.is_pyobject:
983 if dst_type.is_string and self.bytes_value is not None:
984 # special case: '-3' enforced unicode literal used in a C char* context
985 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
986 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE.")
987 elif dst_type is not py_object_type:
988 if not self.check_for_coercion_error(dst_type):
989 self.fail_assignment(dst_type)
992 def can_coerce_to_char_literal(self):
993 return len(self.value) == 1
995 def contains_surrogates(self):
996 # Check if the unicode string contains surrogate code points
997 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
998 # Unicode, i.e. characters that would be spelled as two
999 # separate code units on a narrow platform.
1000 for c in map(ord, self.value):
1001 if c > 65535: # can only happen on wide platforms
1003 # We only look for the first code unit (D800-DBFF) of a
1004 # surrogate pair - if we find one, the other one
1005 # (DC00-DFFF) is likely there, too. If we don't find it,
1006 # any second code unit cannot make for a surrogate pair by
1008 if c >= 0xD800 and c <= 0xDBFF:
1012 def generate_evaluation_code(self, code):
1013 self.result_code = code.get_py_string_const(self.value)
1015 def calculate_result_code(self):
1016 return self.result_code
1018 def compile_time_value(self, env):
1022 class StringNode(PyConstNode):
1023 # A Python str object, i.e. a byte string in Python 2.x and a
1024 # unicode string in Python 3.x
1026 # value BytesLiteral
1027 # unicode_value EncodedString
1028 # is_identifier boolean
1031 is_identifier = None
1032 unicode_value = None
1034 def coerce_to(self, dst_type, env):
1035 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1036 # if dst_type is Builtin.bytes_type:
1037 # # special case: bytes = 'str literal'
1038 # return BytesNode(self.pos, value=self.value)
1039 if not dst_type.is_pyobject:
1040 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1041 self.check_for_coercion_error(dst_type, fail=True)
1043 # this will be a unicode string in Py3, so make sure we can decode it
1044 if self.value.encoding:
1045 encoding = self.value.encoding
1047 self.value.decode(encoding)
1048 except UnicodeDecodeError:
1049 error(self.pos, "String decoding as '%s' failed. Consider using a byte string or unicode string explicitly, or adjust the source code encoding." % encoding)
1053 def can_coerce_to_char_literal(self):
1054 return not self.is_identifier and len(self.value) == 1
1056 def generate_evaluation_code(self, code):
1057 self.result_code = code.get_py_string_const(
1058 self.value, identifier=self.is_identifier, is_str=True)
1060 def get_constant_c_result_code(self):
1063 def calculate_result_code(self):
1064 return self.result_code
1066 def compile_time_value(self, env):
1070 class IdentifierStringNode(StringNode):
1071 # A special str value that represents an identifier (bytes in Py2,
1073 is_identifier = True
1076 class LongNode(AtomicExprNode):
1077 # Python long integer literal
1081 type = py_object_type
1083 def calculate_constant_result(self):
1084 self.constant_result = Utils.str_to_number(self.value)
1086 def compile_time_value(self, denv):
1087 return Utils.str_to_number(self.value)
1089 def analyse_types(self, env):
1092 def may_be_none(self):
1095 gil_message = "Constructing Python long int"
1097 def generate_result_code(self, code):
1099 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1102 code.error_goto_if_null(self.result(), self.pos)))
1103 code.put_gotref(self.py_result())
1106 class ImagNode(AtomicExprNode):
1107 # Imaginary number literal
1109 # value float imaginary part
1111 type = PyrexTypes.c_double_complex_type
1113 def calculate_constant_result(self):
1114 self.constant_result = complex(0.0, self.value)
1116 def compile_time_value(self, denv):
1117 return complex(0.0, self.value)
1119 def analyse_types(self, env):
1120 self.type.create_declaration_utility_code(env)
1122 def may_be_none(self):
1125 def coerce_to(self, dst_type, env):
1126 if self.type is dst_type:
1128 node = ImagNode(self.pos, value=self.value)
1129 if dst_type.is_pyobject:
1131 node.type = PyrexTypes.py_object_type
1132 # We still need to perform normal coerce_to processing on the
1133 # result, because we might be coercing to an extension type,
1134 # in which case a type test node will be needed.
1135 return AtomicExprNode.coerce_to(node, dst_type, env)
1137 gil_message = "Constructing complex number"
1139 def calculate_result_code(self):
1140 if self.type.is_pyobject:
1141 return self.result()
1143 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1145 def generate_result_code(self, code):
1146 if self.type.is_pyobject:
1148 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1151 code.error_goto_if_null(self.result(), self.pos)))
1152 code.put_gotref(self.py_result())
1155 class NewExprNode(AtomicExprNode):
1159 # cppclass node c++ class to create
1163 def infer_type(self, env):
1164 type = self.cppclass.analyse_as_type(env)
1165 if type is None or not type.is_cpp_class:
1166 error(self.pos, "new operator can only be applied to a C++ class")
1167 self.type = error_type
1170 constructor = type.scope.lookup(u'<init>')
1171 if constructor is None:
1172 return_type = PyrexTypes.CFuncType(type, [])
1173 return_type = PyrexTypes.CPtrType(return_type)
1174 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1175 constructor = type.scope.lookup(u'<init>')
1176 self.class_type = type
1177 self.entry = constructor
1178 self.type = constructor.type
1181 def analyse_types(self, env):
1182 if self.type is None:
1183 self.infer_type(env)
1185 def may_be_none(self):
1188 def generate_result_code(self, code):
1191 def calculate_result_code(self):
1192 return "new " + self.class_type.declaration_code("")
1195 class NameNode(AtomicExprNode):
1196 # Reference to a local or global variable name.
1198 # name string Python name of the variable
1199 # entry Entry Symbol table entry
1200 # type_entry Entry For extension type names, the original type entry
1203 is_cython_module = False
1204 cython_attribute = None
1205 lhs_of_first_assignment = False
1206 is_used_as_rvalue = 0
1210 def create_analysed_rvalue(pos, env, entry):
1211 node = NameNode(pos)
1212 node.analyse_types(env, entry=entry)
1215 def as_cython_attribute(self):
1216 return self.cython_attribute
1218 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1220 def type_dependencies(self, env):
1221 if self.entry is None:
1222 self.entry = env.lookup(self.name)
1223 if self.entry is not None and self.entry.type.is_unspecified:
1224 return (self.entry,)
1228 def infer_type(self, env):
1229 if self.entry is None:
1230 self.entry = env.lookup(self.name)
1231 if self.entry is None:
1232 return py_object_type
1233 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1234 self.name == self.entry.type.name:
1235 # Unfortunately the type attribute of type objects
1236 # is used for the pointer to the type they represent.
1239 return self.entry.type
1241 def compile_time_value(self, denv):
1243 return denv.lookup(self.name)
1245 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1247 def get_constant_c_result_code(self):
1248 if not self.entry or self.entry.type.is_pyobject:
1250 return self.entry.cname
1252 def coerce_to(self, dst_type, env):
1253 # If coercing to a generic pyobject and this is a builtin
1254 # C function with a Python equivalent, manufacture a NameNode
1255 # referring to the Python builtin.
1256 #print "NameNode.coerce_to:", self.name, dst_type ###
1257 if dst_type is py_object_type:
1259 if entry and entry.is_cfunction:
1260 var_entry = entry.as_variable
1262 if var_entry.is_builtin and Options.cache_builtins:
1263 var_entry = env.declare_builtin(var_entry.name, self.pos)
1264 node = NameNode(self.pos, name = self.name)
1265 node.entry = var_entry
1266 node.analyse_rvalue_entry(env)
1268 return super(NameNode, self).coerce_to(dst_type, env)
1270 def analyse_as_module(self, env):
1271 # Try to interpret this as a reference to a cimported module.
1272 # Returns the module scope, or None.
1275 entry = env.lookup(self.name)
1276 if entry and entry.as_module:
1277 return entry.as_module
1280 def analyse_as_type(self, env):
1281 if self.cython_attribute:
1282 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1284 type = PyrexTypes.parse_basic_type(self.name)
1289 entry = env.lookup(self.name)
1290 if entry and entry.is_type:
1295 def analyse_as_extension_type(self, env):
1296 # Try to interpret this as a reference to an extension type.
1297 # Returns the extension type, or None.
1300 entry = env.lookup(self.name)
1301 if entry and entry.is_type and entry.type.is_extension_type:
1306 def analyse_target_declaration(self, env):
1308 self.entry = env.lookup_here(self.name)
1310 if env.directives['warn.undeclared']:
1311 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1312 if env.directives['infer_types'] != False:
1313 type = unspecified_type
1315 type = py_object_type
1316 self.entry = env.declare_var(self.name, type, self.pos)
1317 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1318 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1319 if self.entry.is_declared_generic:
1320 self.result_ctype = py_object_type
1322 def analyse_types(self, env):
1323 if self.entry is None:
1324 self.entry = env.lookup(self.name)
1326 self.entry = env.declare_builtin(self.name, self.pos)
1328 self.type = PyrexTypes.error_type
1333 if entry.type.is_buffer:
1335 Buffer.used_buffer_aux_vars(entry)
1336 if entry.utility_code:
1337 env.use_utility_code(entry.utility_code)
1338 self.analyse_rvalue_entry(env)
1340 def analyse_target_types(self, env):
1341 self.analyse_entry(env)
1342 if not self.is_lvalue():
1343 error(self.pos, "Assignment to non-lvalue '%s'"
1345 self.type = PyrexTypes.error_type
1347 if self.entry.type.is_buffer:
1349 Buffer.used_buffer_aux_vars(self.entry)
1351 def analyse_rvalue_entry(self, env):
1352 #print "NameNode.analyse_rvalue_entry:", self.name ###
1353 #print "Entry:", self.entry.__dict__ ###
1354 self.analyse_entry(env)
1356 if entry.is_declared_generic:
1357 self.result_ctype = py_object_type
1358 if entry.is_pyglobal or entry.is_builtin:
1359 if Options.cache_builtins and entry.is_builtin:
1363 env.use_utility_code(get_name_interned_utility_code)
1364 self.is_used_as_rvalue = 1
1366 def nogil_check(self, env):
1367 if self.is_used_as_rvalue:
1369 if entry.is_builtin:
1370 # if not Options.cache_builtins: # cached builtins are ok
1372 elif entry.is_pyglobal:
1375 gil_message = "Accessing Python global or builtin"
1377 def analyse_entry(self, env):
1378 #print "NameNode.analyse_entry:", self.name ###
1379 self.check_identifier_kind()
1384 def check_identifier_kind(self):
1385 # Check that this is an appropriate kind of name for use in an
1386 # expression. Also finds the variable entry associated with
1387 # an extension type.
1389 if entry.is_type and entry.type.is_extension_type:
1390 self.type_entry = entry
1391 if not (entry.is_const or entry.is_variable
1392 or entry.is_builtin or entry.is_cfunction
1393 or entry.is_cpp_class):
1394 if self.entry.as_variable:
1395 self.entry = self.entry.as_variable
1398 "'%s' is not a constant, variable or function identifier" % self.name)
1400 def is_simple(self):
1401 # If it's not a C variable, it'll be in a temp.
1404 def calculate_target_results(self, env):
1407 def check_const(self):
1409 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1414 def check_const_addr(self):
1416 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1417 self.addr_not_const()
1421 def is_lvalue(self):
1422 return self.entry.is_variable and \
1423 not self.entry.type.is_array and \
1424 not self.entry.is_readonly
1426 def is_ephemeral(self):
1427 # Name nodes are never ephemeral, even if the
1428 # result is in a temporary.
1431 def calculate_result_code(self):
1434 return "<error>" # There was an error earlier
1437 def generate_result_code(self, code):
1438 assert hasattr(self, 'entry')
1441 return # There was an error earlier
1442 if entry.is_builtin and Options.cache_builtins:
1443 return # Lookup already cached
1444 elif entry.is_pyglobal or entry.is_builtin:
1445 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1446 interned_cname = code.intern_identifier(self.entry.name)
1447 if entry.is_builtin:
1448 namespace = Naming.builtins_cname
1449 else: # entry.is_pyglobal
1450 namespace = entry.scope.namespace_cname
1451 code.globalstate.use_utility_code(get_name_interned_utility_code)
1453 '%s = __Pyx_GetName(%s, %s); %s' % (
1457 code.error_goto_if_null(self.result(), self.pos)))
1458 code.put_gotref(self.py_result())
1460 elif entry.is_local and False:
1461 # control flow not good enough yet
1462 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1463 if assigned is False:
1464 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1465 elif not Options.init_local_none and assigned is None:
1466 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1467 (entry.cname, entry.name, code.error_goto(self.pos)))
1468 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1470 def generate_assignment_code(self, rhs, code):
1471 #print "NameNode.generate_assignment_code:", self.name ###
1474 return # There was an error earlier
1476 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1477 and not self.lhs_of_first_assignment):
1478 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1480 # is_pyglobal seems to be True for module level-globals only.
1481 # We use this to access class->tp_dict if necessary.
1482 if entry.is_pyglobal:
1483 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1484 interned_cname = code.intern_identifier(self.entry.name)
1485 namespace = self.entry.scope.namespace_cname
1487 # if the entry is a member we have to cheat: SetAttr does not work
1488 # on types, so we create a descriptor which is then added to tp_dict
1489 code.put_error_if_neg(self.pos,
1490 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1494 rhs.generate_disposal_code(code)
1495 rhs.free_temps(code)
1496 # in Py2.6+, we need to invalidate the method cache
1497 code.putln("PyType_Modified(%s);" %
1498 entry.scope.parent_type.typeptr_cname)
1500 code.put_error_if_neg(self.pos,
1501 'PyObject_SetAttr(%s, %s, %s)' % (
1505 if debug_disposal_code:
1506 print("NameNode.generate_assignment_code:")
1507 print("...generating disposal code for %s" % rhs)
1508 rhs.generate_disposal_code(code)
1509 rhs.free_temps(code)
1511 if self.type.is_buffer:
1512 # Generate code for doing the buffer release/acquisition.
1513 # This might raise an exception in which case the assignment (done
1514 # below) will not happen.
1516 # The reason this is not in a typetest-like node is because the
1517 # variables that the acquired buffer info is stored to is allocated
1518 # per entry and coupled with it.
1519 self.generate_acquire_buffer(rhs, code)
1521 if self.type.is_pyobject:
1522 #print "NameNode.generate_assignment_code: to", self.name ###
1523 #print "...from", rhs ###
1524 #print "...LHS type", self.type, "ctype", self.ctype() ###
1525 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1526 if self.use_managed_ref:
1527 rhs.make_owned_reference(code)
1528 if entry.is_cglobal:
1529 code.put_gotref(self.py_result())
1530 if not self.lhs_of_first_assignment:
1531 if entry.is_local and not Options.init_local_none:
1532 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1533 if initialized is True:
1534 code.put_decref(self.result(), self.ctype())
1535 elif initialized is None:
1536 code.put_xdecref(self.result(), self.ctype())
1538 code.put_decref(self.result(), self.ctype())
1539 if entry.is_cglobal:
1540 code.put_giveref(rhs.py_result())
1542 code.putln('%s = %s;' % (self.result(),
1543 rhs.result_as(self.ctype())))
1544 if debug_disposal_code:
1545 print("NameNode.generate_assignment_code:")
1546 print("...generating post-assignment code for %s" % rhs)
1547 rhs.generate_post_assignment_code(code)
1548 rhs.free_temps(code)
1550 def generate_acquire_buffer(self, rhs, code):
1551 # rhstmp is only used in case the rhs is a complicated expression leading to
1552 # the object, to avoid repeating the same C expression for every reference
1553 # to the rhs. It does NOT hold a reference.
1554 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1556 rhstmp = rhs.result_as(self.ctype())
1558 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1559 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1561 buffer_aux = self.entry.buffer_aux
1562 bufstruct = buffer_aux.buffer_info_var.cname
1564 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1565 is_initialized=not self.lhs_of_first_assignment,
1566 pos=self.pos, code=code)
1569 code.putln("%s = 0;" % rhstmp)
1570 code.funcstate.release_temp(rhstmp)
1572 def generate_deletion_code(self, code):
1573 if self.entry is None:
1574 return # There was an error earlier
1575 if not self.entry.is_pyglobal:
1576 error(self.pos, "Deletion of local or C global name not supported")
1578 code.put_error_if_neg(self.pos,
1579 '__Pyx_DelAttrString(%s, "%s")' % (
1580 Naming.module_cname,
1583 def annotate(self, code):
1584 if hasattr(self, 'is_called') and self.is_called:
1585 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1586 if self.type.is_pyobject:
1587 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1589 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1591 class BackquoteNode(ExprNode):
1596 type = py_object_type
1600 def analyse_types(self, env):
1601 self.arg.analyse_types(env)
1602 self.arg = self.arg.coerce_to_pyobject(env)
1605 gil_message = "Backquote expression"
1607 def calculate_constant_result(self):
1608 self.constant_result = repr(self.arg.constant_result)
1610 def generate_result_code(self, code):
1612 "%s = PyObject_Repr(%s); %s" % (
1614 self.arg.py_result(),
1615 code.error_goto_if_null(self.result(), self.pos)))
1616 code.put_gotref(self.py_result())
1620 class ImportNode(ExprNode):
1621 # Used as part of import statement implementation.
1622 # Implements result =
1623 # __import__(module_name, globals(), None, name_list)
1625 # module_name StringNode dotted name of module
1626 # name_list ListNode or None list of names to be imported
1628 type = py_object_type
1630 subexprs = ['module_name', 'name_list']
1632 def analyse_types(self, env):
1633 self.module_name.analyse_types(env)
1634 self.module_name = self.module_name.coerce_to_pyobject(env)
1636 self.name_list.analyse_types(env)
1637 self.name_list.coerce_to_pyobject(env)
1639 env.use_utility_code(import_utility_code)
1641 gil_message = "Python import"
1643 def generate_result_code(self, code):
1645 name_list_code = self.name_list.py_result()
1647 name_list_code = "0"
1649 "%s = __Pyx_Import(%s, %s); %s" % (
1651 self.module_name.py_result(),
1653 code.error_goto_if_null(self.result(), self.pos)))
1654 code.put_gotref(self.py_result())
1657 class IteratorNode(ExprNode):
1658 # Used as part of for statement implementation.
1660 # allocate_counter_temp/release_counter_temp needs to be called
1661 # by parent (ForInStatNode)
1663 # Implements result = iter(sequence)
1667 type = py_object_type
1669 subexprs = ['sequence']
1671 def analyse_types(self, env):
1672 self.sequence.analyse_types(env)
1673 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1674 not self.sequence.type.is_string:
1675 # C array iteration will be transformed later on
1676 self.type = self.sequence.type
1678 self.sequence = self.sequence.coerce_to_pyobject(env)
1681 gil_message = "Iterating over Python object"
1683 def allocate_counter_temp(self, code):
1684 self.counter_cname = code.funcstate.allocate_temp(
1685 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1687 def release_counter_temp(self, code):
1688 code.funcstate.release_temp(self.counter_cname)
1690 def generate_result_code(self, code):
1691 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1692 raise InternalError("for in carray slice not transformed")
1693 is_builtin_sequence = self.sequence.type is list_type or \
1694 self.sequence.type is tuple_type
1695 may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1696 if is_builtin_sequence:
1698 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1699 elif may_be_a_sequence:
1701 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1702 self.sequence.py_result(),
1703 self.sequence.py_result()))
1704 if may_be_a_sequence:
1706 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1709 self.sequence.py_result(),
1711 code.putln("} else {")
1712 if is_builtin_sequence:
1714 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1715 code.error_goto(self.pos))
1717 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1720 self.sequence.py_result(),
1721 code.error_goto_if_null(self.result(), self.pos)))
1722 code.put_gotref(self.py_result())
1723 if may_be_a_sequence:
1727 class NextNode(AtomicExprNode):
1728 # Used as part of for statement implementation.
1729 # Implements result = iterator.next()
1730 # Created during analyse_types phase.
1731 # The iterator is not owned by this node.
1735 type = py_object_type
1737 def __init__(self, iterator, env):
1738 self.pos = iterator.pos
1739 self.iterator = iterator
1740 if iterator.type.is_ptr or iterator.type.is_array:
1741 self.type = iterator.type.base_type
1744 def generate_result_code(self, code):
1745 sequence_type = self.iterator.sequence.type
1746 if sequence_type is list_type:
1747 type_checks = [(list_type, "List")]
1748 elif sequence_type is tuple_type:
1749 type_checks = [(tuple_type, "Tuple")]
1750 elif not sequence_type.is_builtin_type:
1751 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1755 for py_type, prefix in type_checks:
1756 if len(type_checks) > 1:
1758 "if (likely(Py%s_CheckExact(%s))) {" % (
1759 prefix, self.iterator.py_result()))
1761 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1762 self.iterator.counter_cname,
1764 self.iterator.py_result()))
1766 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1769 self.iterator.py_result(),
1770 self.iterator.counter_cname,
1772 self.iterator.counter_cname))
1773 if len(type_checks) > 1:
1775 if len(type_checks) == 1:
1779 "%s = PyIter_Next(%s);" % (
1781 self.iterator.py_result()))
1785 code.putln(code.error_goto_if_PyErr(self.pos))
1786 code.putln("break;")
1788 code.put_gotref(self.py_result())
1792 class ExcValueNode(AtomicExprNode):
1793 # Node created during analyse_types phase
1794 # of an ExceptClauseNode to fetch the current
1797 type = py_object_type
1799 def __init__(self, pos, env):
1800 ExprNode.__init__(self, pos)
1802 def set_var(self, var):
1805 def calculate_result_code(self):
1808 def generate_result_code(self, code):
1811 def analyse_types(self, env):
1815 class TempNode(ExprNode):
1816 # Node created during analyse_types phase
1817 # of some nodes to hold a temporary value.
1819 # Note: One must call "allocate" and "release" on
1820 # the node during code generation to get/release the temp.
1821 # This is because the temp result is often used outside of
1822 # the regular cycle.
1826 def __init__(self, pos, type, env):
1827 ExprNode.__init__(self, pos)
1829 if type.is_pyobject:
1830 self.result_ctype = py_object_type
1833 def analyse_types(self, env):
1836 def generate_result_code(self, code):
1839 def allocate(self, code):
1840 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1842 def release(self, code):
1843 code.funcstate.release_temp(self.temp_cname)
1844 self.temp_cname = None
1848 return self.temp_cname
1850 assert False, "Remember to call allocate/release on TempNode"
1853 # Do not participate in normal temp alloc/dealloc:
1854 def allocate_temp_result(self, code):
1857 def release_temp_result(self, code):
1860 class PyTempNode(TempNode):
1861 # TempNode holding a Python value.
1863 def __init__(self, pos, env):
1864 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1866 class RawCNameExprNode(ExprNode):
1869 def __init__(self, pos, type=None):
1873 def analyse_types(self, env):
1876 def set_cname(self, cname):
1882 def generate_result_code(self, code):
1886 #-------------------------------------------------------------------
1890 #-------------------------------------------------------------------
1892 class IndexNode(ExprNode):
1893 # Sequence indexing.
1897 # indices [ExprNode]
1898 # is_buffer_access boolean Whether this is a buffer access.
1900 # indices is used on buffer access, index on non-buffer access.
1901 # The former contains a clean list of index parameters, the
1902 # latter whatever Python object is needed for index access.
1904 subexprs = ['base', 'index', 'indices']
1907 def __init__(self, pos, index, *args, **kw):
1908 ExprNode.__init__(self, pos, index=index, *args, **kw)
1911 def calculate_constant_result(self):
1912 self.constant_result = \
1913 self.base.constant_result[self.index.constant_result]
1915 def compile_time_value(self, denv):
1916 base = self.base.compile_time_value(denv)
1917 index = self.index.compile_time_value(denv)
1920 except Exception, e:
1921 self.compile_time_value_error(e)
1923 def is_ephemeral(self):
1924 return self.base.is_ephemeral()
1926 def analyse_target_declaration(self, env):
1929 def analyse_as_type(self, env):
1930 base_type = self.base.analyse_as_type(env)
1931 if base_type and not base_type.is_pyobject:
1932 if base_type.is_cpp_class:
1933 if isinstance(self.index, TupleNode):
1934 template_values = self.index.args
1936 template_values = [self.index]
1938 type_node = Nodes.TemplatedTypeNode(
1940 positional_args = template_values,
1941 keyword_args = None)
1942 return type_node.analyse(env, base_type = base_type)
1944 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1947 def type_dependencies(self, env):
1948 return self.base.type_dependencies(env)
1950 def infer_type(self, env):
1951 base_type = self.base.infer_type(env)
1952 if isinstance(self.index, SliceNode):
1954 if base_type.is_string:
1955 # sliced C strings must coerce to Python
1957 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
1958 # slicing these returns the same type
1961 # TODO: Handle buffers (hopefully without too much redundancy).
1962 return py_object_type
1964 index_type = self.index.infer_type(env)
1965 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
1967 if base_type is unicode_type:
1968 # Py_UNICODE will automatically coerce to a unicode string
1969 # if required, so this is safe. We only infer Py_UNICODE
1970 # when the index is a C integer type. Otherwise, we may
1971 # need to use normal Python item access, in which case
1972 # it's faster to return the one-char unicode string than
1973 # to receive it, throw it away, and potentially rebuild it
1974 # on a subsequent PyObject coercion.
1975 return PyrexTypes.c_py_unicode_type
1976 elif isinstance(self.base, BytesNode):
1977 #if env.global_scope().context.language_level >= 3:
1978 # # infering 'char' can be made to work in Python 3 mode
1979 # return PyrexTypes.c_char_type
1980 # Py2/3 return different types on indexing bytes objects
1981 return py_object_type
1982 elif base_type.is_ptr or base_type.is_array:
1983 return base_type.base_type
1985 # may be slicing or indexing, we don't know
1986 if base_type is unicode_type:
1987 # this type always returns its own type on Python indexing/slicing
1990 # TODO: Handle buffers (hopefully without too much redundancy).
1991 return py_object_type
1993 def analyse_types(self, env):
1994 self.analyse_base_and_index_types(env, getting = 1)
1996 def analyse_target_types(self, env):
1997 self.analyse_base_and_index_types(env, setting = 1)
1999 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2000 # Note: This might be cleaned up by having IndexNode
2001 # parsed in a saner way and only construct the tuple if
2004 # Note that this function must leave IndexNode in a cloneable state.
2005 # For buffers, self.index is packed out on the initial analysis, and
2006 # when cloning self.indices is copied.
2007 self.is_buffer_access = False
2009 self.base.analyse_types(env)
2010 if self.base.type.is_error:
2011 # Do not visit child tree if base is undeclared to avoid confusing
2013 self.type = PyrexTypes.error_type
2016 is_slice = isinstance(self.index, SliceNode)
2017 # Potentially overflowing index value.
2018 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2019 self.index = self.index.coerce_to_pyobject(env)
2021 # Handle the case where base is a literal char* (and we expect a string, not an int)
2022 if isinstance(self.base, BytesNode) or is_slice:
2023 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2024 self.base = self.base.coerce_to_pyobject(env)
2026 skip_child_analysis = False
2027 buffer_access = False
2028 if self.base.type.is_buffer:
2029 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2031 indices = self.indices
2033 if isinstance(self.index, TupleNode):
2034 indices = self.index.args
2036 indices = [self.index]
2037 if len(indices) == self.base.type.ndim:
2038 buffer_access = True
2039 skip_child_analysis = True
2041 x.analyse_types(env)
2042 if not x.type.is_int:
2043 buffer_access = False
2045 # On cloning, indices is cloned. Otherwise, unpack index into indices
2046 assert not (buffer_access and isinstance(self.index, CloneNode))
2049 self.indices = indices
2051 self.type = self.base.type.dtype
2052 self.is_buffer_access = True
2053 self.buffer_type = self.base.entry.type
2055 if getting and self.type.is_pyobject:
2058 if not self.base.entry.type.writable:
2059 error(self.pos, "Writing to readonly buffer")
2061 self.base.entry.buffer_aux.writable_needed = True
2063 base_type = self.base.type
2064 if isinstance(self.index, TupleNode):
2065 self.index.analyse_types(env, skip_children=skip_child_analysis)
2066 elif not skip_child_analysis:
2067 self.index.analyse_types(env)
2068 self.original_index_type = self.index.type
2069 if base_type is PyrexTypes.c_py_unicode_type:
2070 # we infer Py_UNICODE for unicode strings in some
2071 # cases, but indexing must still work for them
2072 if self.index.constant_result in (0, -1):
2073 # FIXME: we know that this node is redundant -
2074 # currently, this needs to get handled in Optimize.py
2076 self.base = self.base.coerce_to_pyobject(env)
2077 base_type = self.base.type
2078 if base_type.is_pyobject:
2079 if self.index.type.is_int:
2081 and (base_type in (list_type, tuple_type, unicode_type))
2082 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2083 and not env.directives['boundscheck']):
2087 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2089 self.index = self.index.coerce_to_pyobject(env)
2091 if self.index.type.is_int and base_type is unicode_type:
2092 # Py_UNICODE will automatically coerce to a unicode string
2093 # if required, so this is fast and safe
2094 self.type = PyrexTypes.c_py_unicode_type
2095 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2096 self.type = base_type
2098 self.type = py_object_type
2100 if base_type.is_ptr or base_type.is_array:
2101 self.type = base_type.base_type
2103 self.type = base_type
2104 elif self.index.type.is_pyobject:
2105 self.index = self.index.coerce_to(
2106 PyrexTypes.c_py_ssize_t_type, env)
2107 elif not self.index.type.is_int:
2109 "Invalid index type '%s'" %
2111 elif base_type.is_cpp_class:
2112 function = env.lookup_operator("[]", [self.base, self.index])
2113 if function is None:
2114 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2115 self.type = PyrexTypes.error_type
2116 self.result_code = "<error>"
2118 func_type = function.type
2119 if func_type.is_ptr:
2120 func_type = func_type.base_type
2121 self.index = self.index.coerce_to(func_type.args[0].type, env)
2122 self.type = func_type.return_type
2123 if setting and not func_type.return_type.is_reference:
2124 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2127 "Attempting to index non-array type '%s'" %
2129 self.type = PyrexTypes.error_type
2131 gil_message = "Indexing Python object"
2133 def nogil_check(self, env):
2134 if self.is_buffer_access:
2135 if env.directives['boundscheck']:
2136 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2138 elif self.type.is_pyobject:
2139 error(self.pos, "Cannot access buffer with object dtype without gil")
2141 super(IndexNode, self).nogil_check(env)
2144 def check_const_addr(self):
2145 return self.base.check_const_addr() and self.index.check_const()
2147 def is_lvalue(self):
2150 def calculate_result_code(self):
2151 if self.is_buffer_access:
2152 return "(*%s)" % self.buffer_ptr_code
2153 elif self.base.type is list_type:
2154 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2155 elif self.base.type is tuple_type:
2156 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2157 elif self.base.type is unicode_type and self.type is PyrexTypes.c_py_unicode_type:
2158 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2159 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2160 error(self.pos, "Invalid use of pointer slice")
2162 return "(%s[%s])" % (
2163 self.base.result(), self.index.result())
2165 def extra_index_params(self):
2166 if self.index.type.is_int:
2167 if self.original_index_type.signed:
2168 size_adjustment = ""
2170 size_adjustment = "+1"
2171 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2175 def generate_subexpr_evaluation_code(self, code):
2176 self.base.generate_evaluation_code(code)
2177 if not self.indices:
2178 self.index.generate_evaluation_code(code)
2180 for i in self.indices:
2181 i.generate_evaluation_code(code)
2183 def generate_subexpr_disposal_code(self, code):
2184 self.base.generate_disposal_code(code)
2185 if not self.indices:
2186 self.index.generate_disposal_code(code)
2188 for i in self.indices:
2189 i.generate_disposal_code(code)
2191 def free_subexpr_temps(self, code):
2192 self.base.free_temps(code)
2193 if not self.indices:
2194 self.index.free_temps(code)
2196 for i in self.indices:
2199 def generate_result_code(self, code):
2200 if self.is_buffer_access:
2201 if code.globalstate.directives['nonecheck']:
2202 self.put_nonecheck(code)
2203 self.buffer_ptr_code = self.buffer_lookup_code(code)
2204 if self.type.is_pyobject:
2205 # is_temp is True, so must pull out value and incref it.
2206 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2207 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2209 if self.type.is_pyobject:
2210 if self.index.type.is_int:
2211 index_code = self.index.result()
2212 if self.base.type is list_type:
2213 function = "__Pyx_GetItemInt_List"
2214 elif self.base.type is tuple_type:
2215 function = "__Pyx_GetItemInt_Tuple"
2217 function = "__Pyx_GetItemInt"
2218 code.globalstate.use_utility_code(getitem_int_utility_code)
2220 index_code = self.index.py_result()
2221 if self.base.type is dict_type:
2222 function = "__Pyx_PyDict_GetItem"
2223 code.globalstate.use_utility_code(getitem_dict_utility_code)
2225 function = "PyObject_GetItem"
2227 "%s = %s(%s, %s%s); if (!%s) %s" % (
2230 self.base.py_result(),
2232 self.extra_index_params(),
2234 code.error_goto(self.pos)))
2235 code.put_gotref(self.py_result())
2236 elif self.type is PyrexTypes.c_py_unicode_type and self.base.type is unicode_type:
2237 assert self.index.type.is_int
2238 index_code = self.index.result()
2239 function = "__Pyx_GetItemInt_Unicode"
2240 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2242 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2245 self.base.py_result(),
2247 self.extra_index_params(),
2249 code.error_goto(self.pos)))
2251 def generate_setitem_code(self, value_code, code):
2252 if self.index.type.is_int:
2253 function = "__Pyx_SetItemInt"
2254 index_code = self.index.result()
2255 code.globalstate.use_utility_code(setitem_int_utility_code)
2257 index_code = self.index.py_result()
2258 if self.base.type is dict_type:
2259 function = "PyDict_SetItem"
2260 # It would seem that we could specialized lists/tuples, but that
2261 # shouldn't happen here.
2262 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2263 # not a PyObject*, and bad conversion here would give the wrong
2264 # exception. Also, tuples are supposed to be immutable, and raise
2265 # TypeErrors when trying to set their entries (PyTuple_SetItem
2266 # is for creating new tuples from).
2268 function = "PyObject_SetItem"
2270 "if (%s(%s, %s, %s%s) < 0) %s" % (
2272 self.base.py_result(),
2275 self.extra_index_params(),
2276 code.error_goto(self.pos)))
2278 def generate_buffer_setitem_code(self, rhs, code, op=""):
2279 # Used from generate_assignment_code and InPlaceAssignmentNode
2280 if code.globalstate.directives['nonecheck']:
2281 self.put_nonecheck(code)
2282 ptrexpr = self.buffer_lookup_code(code)
2283 if self.buffer_type.dtype.is_pyobject:
2284 # Must manage refcounts. Decref what is already there
2285 # and incref what we put in.
2286 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2287 rhs_code = rhs.result()
2288 code.putln("%s = %s;" % (ptr, ptrexpr))
2289 code.put_gotref("*%s" % ptr)
2290 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2293 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2294 code.put_giveref("*%s" % ptr)
2295 code.funcstate.release_temp(ptr)
2298 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2300 def generate_assignment_code(self, rhs, code):
2301 self.generate_subexpr_evaluation_code(code)
2302 if self.is_buffer_access:
2303 self.generate_buffer_setitem_code(rhs, code)
2304 elif self.type.is_pyobject:
2305 self.generate_setitem_code(rhs.py_result(), code)
2309 self.result(), rhs.result()))
2310 self.generate_subexpr_disposal_code(code)
2311 self.free_subexpr_temps(code)
2312 rhs.generate_disposal_code(code)
2313 rhs.free_temps(code)
2315 def generate_deletion_code(self, code):
2316 self.generate_subexpr_evaluation_code(code)
2317 #if self.type.is_pyobject:
2318 if self.index.type.is_int:
2319 function = "__Pyx_DelItemInt"
2320 index_code = self.index.result()
2321 code.globalstate.use_utility_code(delitem_int_utility_code)
2323 index_code = self.index.py_result()
2324 if self.base.type is dict_type:
2325 function = "PyDict_DelItem"
2327 function = "PyObject_DelItem"
2329 "if (%s(%s, %s%s) < 0) %s" % (
2331 self.base.py_result(),
2333 self.extra_index_params(),
2334 code.error_goto(self.pos)))
2335 self.generate_subexpr_disposal_code(code)
2336 self.free_subexpr_temps(code)
2338 def buffer_lookup_code(self, code):
2339 # Assign indices to temps
2340 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2341 for temp, index in zip(index_temps, self.indices):
2342 code.putln("%s = %s;" % (temp, index.result()))
2343 # Generate buffer access code using these temps
2345 # The above could happen because child_attrs is wrong somewhere so that
2346 # options are not propagated.
2347 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2348 index_signeds=[i.type.signed for i in self.indices],
2349 index_cnames=index_temps,
2350 directives=code.globalstate.directives,
2351 pos=self.pos, code=code)
2353 def put_nonecheck(self, code):
2354 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2355 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2356 code.putln("__Pyx_RaiseNoneIndexingError();")
2357 code.putln(code.error_goto(self.pos))
2360 class SliceIndexNode(ExprNode):
2361 # 2-element slice indexing
2364 # start ExprNode or None
2365 # stop ExprNode or None
2367 subexprs = ['base', 'start', 'stop']
2369 def infer_type(self, env):
2370 base_type = self.base.infer_type(env)
2371 if base_type.is_string:
2373 elif base_type in (bytes_type, str_type, unicode_type,
2374 list_type, tuple_type):
2376 return py_object_type
2378 def calculate_constant_result(self):
2379 self.constant_result = self.base.constant_result[
2380 self.start.constant_result : self.stop.constant_result]
2382 def compile_time_value(self, denv):
2383 base = self.base.compile_time_value(denv)
2384 if self.start is None:
2387 start = self.start.compile_time_value(denv)
2388 if self.stop is None:
2391 stop = self.stop.compile_time_value(denv)
2393 return base[start:stop]
2394 except Exception, e:
2395 self.compile_time_value_error(e)
2397 def analyse_target_declaration(self, env):
2400 def analyse_target_types(self, env):
2401 self.analyse_types(env)
2402 # when assigning, we must accept any Python type
2403 if self.type.is_pyobject:
2404 self.type = py_object_type
2406 def analyse_types(self, env):
2407 self.base.analyse_types(env)
2409 self.start.analyse_types(env)
2411 self.stop.analyse_types(env)
2412 base_type = self.base.type
2413 if base_type.is_string:
2414 self.type = bytes_type
2415 elif base_type.is_ptr:
2416 self.type = base_type
2417 elif base_type.is_array:
2418 # we need a ptr type here instead of an array type, as
2419 # array types can result in invalid type casts in the C
2421 self.type = PyrexTypes.CPtrType(base_type.base_type)
2423 self.base = self.base.coerce_to_pyobject(env)
2424 self.type = py_object_type
2425 if base_type.is_builtin_type:
2426 # slicing builtin types returns something of the same type
2427 self.type = base_type
2428 c_int = PyrexTypes.c_py_ssize_t_type
2430 self.start = self.start.coerce_to(c_int, env)
2432 self.stop = self.stop.coerce_to(c_int, env)
2435 nogil_check = Node.gil_error
2436 gil_message = "Slicing Python object"
2438 def generate_result_code(self, code):
2439 if not self.type.is_pyobject:
2441 "Slicing is not currently supported for '%s'." % self.type)
2443 if self.base.type.is_string:
2444 if self.stop is None:
2446 "%s = PyBytes_FromString(%s + %s); %s" % (
2450 code.error_goto_if_null(self.result(), self.pos)))
2453 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2459 code.error_goto_if_null(self.result(), self.pos)))
2462 "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
2464 self.base.py_result(),
2467 code.error_goto_if_null(self.result(), self.pos)))
2468 code.put_gotref(self.py_result())
2470 def generate_assignment_code(self, rhs, code):
2471 self.generate_subexpr_evaluation_code(code)
2472 if self.type.is_pyobject:
2473 code.put_error_if_neg(self.pos,
2474 "PySequence_SetSlice(%s, %s, %s, %s)" % (
2475 self.base.py_result(),
2482 start_offset = self.start_code()
2483 if start_offset == '0':
2487 if rhs.type.is_array:
2488 array_length = rhs.type.size
2489 self.generate_slice_guard_code(code, array_length)
2492 "Slice assignments from pointers are not yet supported.")
2493 # FIXME: fix the array size according to start/stop
2494 array_length = self.base.type.size
2495 for i in range(array_length):
2496 code.putln("%s[%s%s] = %s[%d];" % (
2497 self.base.result(), start_offset, i,
2499 self.generate_subexpr_disposal_code(code)
2500 self.free_subexpr_temps(code)
2501 rhs.generate_disposal_code(code)
2502 rhs.free_temps(code)
2504 def generate_deletion_code(self, code):
2505 if not self.base.type.is_pyobject:
2507 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2509 self.generate_subexpr_evaluation_code(code)
2510 code.put_error_if_neg(self.pos,
2511 "PySequence_DelSlice(%s, %s, %s)" % (
2512 self.base.py_result(),
2515 self.generate_subexpr_disposal_code(code)
2517 def generate_slice_guard_code(self, code, target_size):
2518 if not self.base.type.is_array:
2520 slice_size = self.base.type.size
2523 stop = self.stop.result()
2527 slice_size = self.base.type.size + stop
2534 start = self.start.result()
2538 start = self.base.type.size + start
2546 error(self.pos, "Assignment to empty slice.")
2547 elif start is None and stop is None:
2548 # we know the exact slice length
2549 if target_size != slice_size:
2550 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2551 slice_size, target_size))
2552 elif start is not None:
2555 check = "(%s)-(%s)" % (stop, start)
2556 else: # stop is not None:
2559 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2560 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));' % (
2561 target_size, check))
2562 code.putln(code.error_goto(self.pos))
2565 def start_code(self):
2567 return self.start.result()
2571 def stop_code(self):
2573 return self.stop.result()
2574 elif self.base.type.is_array:
2575 return self.base.type.size
2577 return "PY_SSIZE_T_MAX"
2579 def calculate_result_code(self):
2580 # self.result() is not used, but this method must exist
2584 class SliceNode(ExprNode):
2585 # start:stop:step in subscript list
2591 type = py_object_type
2594 def calculate_constant_result(self):
2595 self.constant_result = self.base.constant_result[
2596 self.start.constant_result : \
2597 self.stop.constant_result : \
2598 self.step.constant_result]
2600 def compile_time_value(self, denv):
2601 start = self.start.compile_time_value(denv)
2602 if self.stop is None:
2605 stop = self.stop.compile_time_value(denv)
2606 if self.step is None:
2609 step = self.step.compile_time_value(denv)
2611 return slice(start, stop, step)
2612 except Exception, e:
2613 self.compile_time_value_error(e)
2615 subexprs = ['start', 'stop', 'step']
2617 def analyse_types(self, env):
2618 self.start.analyse_types(env)
2619 self.stop.analyse_types(env)
2620 self.step.analyse_types(env)
2621 self.start = self.start.coerce_to_pyobject(env)
2622 self.stop = self.stop.coerce_to_pyobject(env)
2623 self.step = self.step.coerce_to_pyobject(env)
2625 gil_message = "Constructing Python slice object"
2627 def generate_result_code(self, code):
2629 "%s = PySlice_New(%s, %s, %s); %s" % (
2631 self.start.py_result(),
2632 self.stop.py_result(),
2633 self.step.py_result(),
2634 code.error_goto_if_null(self.result(), self.pos)))
2635 code.put_gotref(self.py_result())
2638 class CallNode(ExprNode):
2640 # allow overriding the default 'may_be_none' behaviour
2641 may_return_none = None
2643 def may_be_none(self):
2644 if self.may_return_none is not None:
2645 return self.may_return_none
2646 return ExprNode.may_be_none(self)
2648 def analyse_as_type_constructor(self, env):
2649 type = self.function.analyse_as_type(env)
2650 if type and type.is_struct_or_union:
2651 args, kwds = self.explicit_args_kwds()
2653 for arg, member in zip(args, type.scope.var_entries):
2654 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2656 items += kwds.key_value_pairs
2657 self.key_value_pairs = items
2658 self.__class__ = DictNode
2659 self.analyse_types(env)
2660 self.coerce_to(type, env)
2662 elif type and type.is_cpp_class:
2663 for arg in self.args:
2664 arg.analyse_types(env)
2665 constructor = type.scope.lookup("<init>")
2666 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2667 self.function.entry = constructor
2668 self.function.set_cname(type.declaration_code(""))
2669 self.analyse_c_function_call(env)
2672 def is_lvalue(self):
2673 return self.type.is_reference
2675 def nogil_check(self, env):
2676 func_type = self.function_type()
2677 if func_type.is_pyobject:
2679 elif not getattr(func_type, 'nogil', False):
2682 gil_message = "Calling gil-requiring function"
2685 class SimpleCallNode(CallNode):
2686 # Function call without keyword, * or ** args.
2690 # arg_tuple ExprNode or None used internally
2691 # self ExprNode or None used internally
2692 # coerced_self ExprNode or None used internally
2693 # wrapper_call bool used internally
2694 # has_optional_args bool used internally
2695 # nogil bool used internally
2697 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2702 wrapper_call = False
2703 has_optional_args = False
2706 def compile_time_value(self, denv):
2707 function = self.function.compile_time_value(denv)
2708 args = [arg.compile_time_value(denv) for arg in self.args]
2710 return function(*args)
2711 except Exception, e:
2712 self.compile_time_value_error(e)
2714 def type_dependencies(self, env):
2715 # TODO: Update when Danilo's C++ code merged in to handle the
2716 # the case of function overloading.
2717 return self.function.type_dependencies(env)
2719 def infer_type(self, env):
2720 function = self.function
2721 func_type = function.infer_type(env)
2722 if isinstance(self.function, NewExprNode):
2723 return PyrexTypes.CPtrType(self.function.class_type)
2724 if func_type.is_ptr:
2725 func_type = func_type.base_type
2726 if func_type.is_cfunction:
2727 return func_type.return_type
2728 elif func_type is type_type:
2729 if function.is_name and function.entry and function.entry.type:
2730 result_type = function.entry.type
2731 if result_type.is_extension_type:
2733 elif result_type.is_builtin_type:
2734 if function.entry.name == 'float':
2735 return PyrexTypes.c_double_type
2736 elif function.entry.name in Builtin.types_that_construct_their_instance:
2738 return py_object_type
2740 def analyse_as_type(self, env):
2741 attr = self.function.as_cython_attribute()
2742 if attr == 'pointer':
2743 if len(self.args) != 1:
2744 error(self.args.pos, "only one type allowed.")
2746 type = self.args[0].analyse_as_type(env)
2748 error(self.args[0].pos, "Unknown type")
2750 return PyrexTypes.CPtrType(type)
2752 def explicit_args_kwds(self):
2753 return self.args, None
2755 def analyse_types(self, env):
2756 if self.analyse_as_type_constructor(env):
2758 function = self.function
2759 function.is_called = 1
2760 self.function.analyse_types(env)
2761 if function.is_attribute and function.entry and function.entry.is_cmethod:
2762 # Take ownership of the object from which the attribute
2763 # was obtained, because we need to pass it as 'self'.
2764 self.self = function.obj
2765 function.obj = CloneNode(self.self)
2766 func_type = self.function_type()
2767 if func_type.is_pyobject:
2768 self.arg_tuple = TupleNode(self.pos, args = self.args)
2769 self.arg_tuple.analyse_types(env)
2771 if func_type is Builtin.type_type and function.is_name and \
2772 function.entry and \
2773 function.entry.is_builtin and \
2774 function.entry.name in Builtin.types_that_construct_their_instance:
2775 # calling a builtin type that returns a specific object type
2776 if function.entry.name == 'float':
2777 # the following will come true later on in a transform
2778 self.type = PyrexTypes.c_double_type
2779 self.result_ctype = PyrexTypes.c_double_type
2781 self.type = Builtin.builtin_types[function.entry.name]
2782 self.result_ctype = py_object_type
2783 self.may_return_none = False
2784 elif function.is_name and function.type_entry:
2785 # We are calling an extension type constructor. As
2786 # long as we do not support __new__(), the result type
2788 self.type = function.type_entry.type
2789 self.result_ctype = py_object_type
2790 self.may_return_none = False
2792 self.type = py_object_type
2795 for arg in self.args:
2796 arg.analyse_types(env)
2797 if self.self and func_type.args:
2798 # Coerce 'self' to the type expected by the method.
2799 expected_type = func_type.args[0].type
2800 self.coerced_self = CloneNode(self.self).coerce_to(
2802 # Insert coerced 'self' argument into argument list.
2803 self.args.insert(0, self.coerced_self)
2804 self.analyse_c_function_call(env)
2806 def function_type(self):
2807 # Return the type of the function being called, coercing a function
2808 # pointer to a function if necessary.
2809 func_type = self.function.type
2810 if func_type.is_ptr:
2811 func_type = func_type.base_type
2814 def analyse_c_function_call(self, env):
2815 if self.function.type is error_type:
2816 self.type = error_type
2818 if self.function.type.is_cpp_class:
2819 overloaded_entry = self.function.type.scope.lookup("operator()")
2820 if overloaded_entry is None:
2821 self.type = PyrexTypes.error_type
2822 self.result_code = "<error>"
2824 elif hasattr(self.function, 'entry'):
2825 overloaded_entry = self.function.entry
2827 overloaded_entry = None
2828 if overloaded_entry:
2829 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2831 self.type = PyrexTypes.error_type
2832 self.result_code = "<error>"
2834 self.function.entry = entry
2835 self.function.type = entry.type
2836 func_type = self.function_type()
2838 func_type = self.function_type()
2839 if not func_type.is_cfunction:
2840 error(self.pos, "Calling non-function type '%s'" % func_type)
2841 self.type = PyrexTypes.error_type
2842 self.result_code = "<error>"
2845 max_nargs = len(func_type.args)
2846 expected_nargs = max_nargs - func_type.optional_arg_count
2847 actual_nargs = len(self.args)
2848 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2849 self.has_optional_args = 1
2852 for i in range(min(max_nargs, actual_nargs)):
2853 formal_type = func_type.args[i].type
2854 self.args[i] = self.args[i].coerce_to(formal_type, env)
2855 for i in range(max_nargs, actual_nargs):
2856 if self.args[i].type.is_pyobject:
2857 error(self.args[i].pos,
2858 "Python object cannot be passed as a varargs parameter")
2859 # Calc result type and code fragment
2860 if isinstance(self.function, NewExprNode):
2861 self.type = PyrexTypes.CPtrType(self.function.class_type)
2863 self.type = func_type.return_type
2864 if self.type.is_pyobject:
2865 self.result_ctype = py_object_type
2867 elif func_type.exception_value is not None \
2868 or func_type.exception_check:
2870 # Called in 'nogil' context?
2871 self.nogil = env.nogil
2873 func_type.exception_check and
2874 func_type.exception_check != '+'):
2875 env.use_utility_code(pyerr_occurred_withgil_utility_code)
2876 # C++ exception handler
2877 if func_type.exception_check == '+':
2878 if func_type.exception_value is None:
2879 env.use_utility_code(cpp_exception_utility_code)
2881 def calculate_result_code(self):
2882 return self.c_call_code()
2884 def c_call_code(self):
2885 func_type = self.function_type()
2886 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2888 formal_args = func_type.args
2890 args = zip(formal_args, self.args)
2891 max_nargs = len(func_type.args)
2892 expected_nargs = max_nargs - func_type.optional_arg_count
2893 actual_nargs = len(self.args)
2894 for formal_arg, actual_arg in args[:expected_nargs]:
2895 arg_code = actual_arg.result_as(formal_arg.type)
2896 arg_list_code.append(arg_code)
2898 if func_type.is_overridable:
2899 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2901 if func_type.optional_arg_count:
2902 if expected_nargs == actual_nargs:
2903 optional_args = 'NULL'
2905 optional_args = "&%s" % self.opt_arg_struct
2906 arg_list_code.append(optional_args)
2908 for actual_arg in self.args[len(formal_args):]:
2909 arg_list_code.append(actual_arg.result())
2910 result = "%s(%s)" % (self.function.result(),
2911 ', '.join(arg_list_code))
2914 def generate_result_code(self, code):
2915 func_type = self.function_type()
2916 if func_type.is_pyobject:
2917 arg_code = self.arg_tuple.py_result()
2919 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2921 self.function.py_result(),
2923 code.error_goto_if_null(self.result(), self.pos)))
2924 code.put_gotref(self.py_result())
2925 elif func_type.is_cfunction:
2926 if self.has_optional_args:
2927 actual_nargs = len(self.args)
2928 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2929 self.opt_arg_struct = code.funcstate.allocate_temp(
2930 func_type.op_arg_struct.base_type, manage_ref=True)
2931 code.putln("%s.%s = %s;" % (
2932 self.opt_arg_struct,
2933 Naming.pyrex_prefix + "n",
2934 len(self.args) - expected_nargs))
2935 args = zip(func_type.args, self.args)
2936 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2937 code.putln("%s.%s = %s;" % (
2938 self.opt_arg_struct,
2939 func_type.opt_arg_cname(formal_arg.name),
2940 actual_arg.result_as(formal_arg.type)))
2942 if self.type.is_pyobject and self.is_temp:
2943 exc_checks.append("!%s" % self.result())
2945 exc_val = func_type.exception_value
2946 exc_check = func_type.exception_check
2947 if exc_val is not None:
2948 exc_checks.append("%s == %s" % (self.result(), exc_val))
2951 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
2953 exc_checks.append("PyErr_Occurred()")
2954 if self.is_temp or exc_checks:
2955 rhs = self.c_call_code()
2957 lhs = "%s = " % self.result()
2958 if self.is_temp and self.type.is_pyobject:
2959 #return_type = self.type # func_type.return_type
2960 #print "SimpleCallNode.generate_result_code: casting", rhs, \
2961 # "from", return_type, "to pyobject" ###
2962 rhs = typecast(py_object_type, self.type, rhs)
2965 if func_type.exception_check == '+':
2966 if func_type.exception_value is None:
2967 raise_py_exception = "__Pyx_CppExn2PyErr()"
2968 elif func_type.exception_value.type.is_pyobject:
2969 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
2970 func_type.exception_value.entry.cname,
2971 func_type.exception_value.entry.cname)
2973 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
2975 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
2977 "try {%s%s;} catch(...) {%s; %s}" % (
2981 code.error_goto(self.pos)))
2984 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
2987 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
2988 if self.type.is_pyobject and self.result():
2989 code.put_gotref(self.py_result())
2990 if self.has_optional_args:
2991 code.funcstate.release_temp(self.opt_arg_struct)
2994 class PythonCapiFunctionNode(ExprNode):
2996 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3000 self.type = func_type
3001 self.utility_code = utility_code
3003 def analyse_types(self, env):
3006 def generate_result_code(self, code):
3007 if self.utility_code:
3008 code.globalstate.use_utility_code(self.utility_code)
3010 def calculate_result_code(self):
3013 class PythonCapiCallNode(SimpleCallNode):
3014 # Python C-API Function call (only created in transforms)
3016 # By default, we assume that the call never returns None, as this
3017 # is true for most C-API functions in CPython. If this does not
3018 # apply to a call, set the following to True (or None to inherit
3019 # the default behaviour).
3020 may_return_none = False
3022 def __init__(self, pos, function_name, func_type,
3023 utility_code = None, py_name=None, **kwargs):
3024 self.type = func_type.return_type
3025 self.result_ctype = self.type
3026 self.function = PythonCapiFunctionNode(
3027 pos, py_name, function_name, func_type,
3028 utility_code = utility_code)
3029 # call this last so that we can override the constructed
3030 # attributes above with explicit keyword arguments if required
3031 SimpleCallNode.__init__(self, pos, **kwargs)
3034 class GeneralCallNode(CallNode):
3035 # General Python function call, including keyword,
3036 # * and ** arguments.
3039 # positional_args ExprNode Tuple of positional arguments
3040 # keyword_args ExprNode or None Dict of keyword arguments
3041 # starstar_arg ExprNode or None Dict of extra keyword args
3043 type = py_object_type
3045 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3047 nogil_check = Node.gil_error
3049 def compile_time_value(self, denv):
3050 function = self.function.compile_time_value(denv)
3051 positional_args = self.positional_args.compile_time_value(denv)
3052 keyword_args = self.keyword_args.compile_time_value(denv)
3053 starstar_arg = self.starstar_arg.compile_time_value(denv)
3055 keyword_args.update(starstar_arg)
3056 return function(*positional_args, **keyword_args)
3057 except Exception, e:
3058 self.compile_time_value_error(e)
3060 def explicit_args_kwds(self):
3061 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3062 raise PostParseError(self.pos,
3063 'Compile-time keyword arguments must be explicit.')
3064 return self.positional_args.args, self.keyword_args
3066 def analyse_types(self, env):
3067 if self.analyse_as_type_constructor(env):
3069 self.function.analyse_types(env)
3070 self.positional_args.analyse_types(env)
3071 if self.keyword_args:
3072 self.keyword_args.analyse_types(env)
3073 if self.starstar_arg:
3074 self.starstar_arg.analyse_types(env)
3075 if not self.function.type.is_pyobject:
3076 if self.function.type.is_error:
3077 self.type = error_type
3079 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3080 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3082 self.function = self.function.coerce_to_pyobject(env)
3083 self.positional_args = \
3084 self.positional_args.coerce_to_pyobject(env)
3085 if self.starstar_arg:
3086 self.starstar_arg = \
3087 self.starstar_arg.coerce_to_pyobject(env)
3088 function = self.function
3089 if function.is_name and function.type_entry:
3090 # We are calling an extension type constructor. As long
3091 # as we do not support __new__(), the result type is clear
3092 self.type = function.type_entry.type
3093 self.result_ctype = py_object_type
3094 self.may_return_none = False
3096 self.type = py_object_type
3099 def generate_result_code(self, code):
3100 if self.type.is_error: return
3101 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3102 if self.keyword_args and self.starstar_arg:
3103 code.put_error_if_neg(self.pos,
3104 "PyDict_Update(%s, %s)" % (
3105 self.keyword_args.py_result(),
3106 self.starstar_arg.py_result()))
3107 keyword_code = self.keyword_args.py_result()
3108 elif self.keyword_args:
3109 keyword_code = self.keyword_args.py_result()
3110 elif self.starstar_arg:
3111 keyword_code = self.starstar_arg.py_result()
3112 if self.starstar_arg.type is not Builtin.dict_type:
3113 # CPython supports calling functions with non-dicts, so do we
3114 code.globalstate.use_utility_code(kwargs_call_utility_code)
3115 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3118 if not keyword_code:
3119 call_code = "PyObject_Call(%s, %s, NULL)" % (
3120 self.function.py_result(),
3121 self.positional_args.py_result())
3123 call_code = "%s(%s, %s, %s)" % (
3124 kwargs_call_function,
3125 self.function.py_result(),
3126 self.positional_args.py_result(),
3132 code.error_goto_if_null(self.result(), self.pos)))
3133 code.put_gotref(self.py_result())
3136 class AsTupleNode(ExprNode):
3137 # Convert argument to tuple. Used for normalising
3138 # the * argument of a function call.
3144 def calculate_constant_result(self):
3145 self.constant_result = tuple(self.base.constant_result)
3147 def compile_time_value(self, denv):
3148 arg = self.arg.compile_time_value(denv)
3151 except Exception, e:
3152 self.compile_time_value_error(e)
3154 def analyse_types(self, env):
3155 self.arg.analyse_types(env)
3156 self.arg = self.arg.coerce_to_pyobject(env)
3157 self.type = tuple_type
3160 def may_be_none(self):
3163 nogil_check = Node.gil_error
3164 gil_message = "Constructing Python tuple"
3166 def generate_result_code(self, code):
3168 "%s = PySequence_Tuple(%s); %s" % (
3170 self.arg.py_result(),
3171 code.error_goto_if_null(self.result(), self.pos)))
3172 code.put_gotref(self.py_result())
3175 class AttributeNode(ExprNode):
3180 # needs_none_check boolean Used if obj is an extension type.
3181 # If set to True, it is known that the type is not None.
3185 # is_py_attr boolean Is a Python getattr operation
3186 # member string C name of struct member
3187 # is_called boolean Function call is being done on result
3188 # entry Entry Symbol table entry of attribute
3193 type = PyrexTypes.error_type
3196 needs_none_check = True
3198 def as_cython_attribute(self):
3199 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3200 return self.attribute
3201 cy = self.obj.as_cython_attribute()
3203 return "%s.%s" % (cy, self.attribute)
3205 def coerce_to(self, dst_type, env):
3206 # If coercing to a generic pyobject and this is a cpdef function
3207 # we can create the corresponding attribute
3208 if dst_type is py_object_type:
3210 if entry and entry.is_cfunction and entry.as_variable:
3211 # must be a cpdef function
3213 self.entry = entry.as_variable
3214 self.analyse_as_python_attribute(env)
3216 return ExprNode.coerce_to(self, dst_type, env)
3218 def calculate_constant_result(self):
3219 attr = self.attribute
3220 if attr.startswith("__") and attr.endswith("__"):
3222 self.constant_result = getattr(self.obj.constant_result, attr)
3224 def compile_time_value(self, denv):
3225 attr = self.attribute
3226 if attr.startswith("__") and attr.endswith("__"):
3228 "Invalid attribute name '%s' in compile-time expression" % attr)
3230 obj = self.obj.compile_time_value(denv)
3232 return getattr(obj, attr)
3233 except Exception, e:
3234 self.compile_time_value_error(e)
3236 def type_dependencies(self, env):
3237 return self.obj.type_dependencies(env)
3239 def infer_type(self, env):
3240 if self.analyse_as_cimported_attribute(env, 0):
3241 return self.entry.type
3242 elif self.analyse_as_unbound_cmethod(env):
3243 return self.entry.type
3245 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3248 def analyse_target_declaration(self, env):
3251 def analyse_target_types(self, env):
3252 self.analyse_types(env, target = 1)
3254 def analyse_types(self, env, target = 0):
3255 if self.analyse_as_cimported_attribute(env, target):
3257 if not target and self.analyse_as_unbound_cmethod(env):
3259 self.analyse_as_ordinary_attribute(env, target)
3261 def analyse_as_cimported_attribute(self, env, target):
3262 # Try to interpret this as a reference to an imported
3263 # C const, type, var or function. If successful, mutates
3264 # this node into a NameNode and returns 1, otherwise
3266 module_scope = self.obj.analyse_as_module(env)
3268 entry = module_scope.lookup_here(self.attribute)
3270 entry.is_cglobal or entry.is_cfunction
3271 or entry.is_type or entry.is_const):
3272 self.mutate_into_name_node(env, entry, target)
3276 def analyse_as_unbound_cmethod(self, env):
3277 # Try to interpret this as a reference to an unbound
3278 # C method of an extension type. If successful, mutates
3279 # this node into a NameNode and returns 1, otherwise
3281 type = self.obj.analyse_as_extension_type(env)
3283 entry = type.scope.lookup_here(self.attribute)
3284 if entry and entry.is_cmethod:
3285 # Create a temporary entry describing the C method
3286 # as an ordinary function.
3287 ubcm_entry = Symtab.Entry(entry.name,
3288 "%s->%s" % (type.vtabptr_cname, entry.cname),
3290 ubcm_entry.is_cfunction = 1
3291 ubcm_entry.func_cname = entry.func_cname
3292 ubcm_entry.is_unbound_cmethod = 1
3293 self.mutate_into_name_node(env, ubcm_entry, None)
3297 def analyse_as_type(self, env):
3298 module_scope = self.obj.analyse_as_module(env)
3300 return module_scope.lookup_type(self.attribute)
3301 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3302 base_type = self.obj.analyse_as_type(env)
3303 if base_type and hasattr(base_type, 'scope'):
3304 return base_type.scope.lookup_type(self.attribute)
3307 def analyse_as_extension_type(self, env):
3308 # Try to interpret this as a reference to an extension type
3309 # in a cimported module. Returns the extension type, or None.
3310 module_scope = self.obj.analyse_as_module(env)
3312 entry = module_scope.lookup_here(self.attribute)
3313 if entry and entry.is_type and entry.type.is_extension_type:
3317 def analyse_as_module(self, env):
3318 # Try to interpret this as a reference to a cimported module
3319 # in another cimported module. Returns the module scope, or None.
3320 module_scope = self.obj.analyse_as_module(env)
3322 entry = module_scope.lookup_here(self.attribute)
3323 if entry and entry.as_module:
3324 return entry.as_module
3327 def mutate_into_name_node(self, env, entry, target):
3328 # Mutate this node into a NameNode and complete the
3329 # analyse_types phase.
3330 self.__class__ = NameNode
3331 self.name = self.attribute
3336 NameNode.analyse_target_types(self, env)
3338 NameNode.analyse_rvalue_entry(self, env)
3340 def analyse_as_ordinary_attribute(self, env, target):
3341 self.obj.analyse_types(env)
3342 self.analyse_attribute(env)
3343 if self.entry and self.entry.is_cmethod and not self.is_called:
3344 # error(self.pos, "C method can only be called")
3346 ## Reference to C array turns into pointer to first element.
3347 #while self.type.is_array:
3348 # self.type = self.type.element_ptr_type()
3352 self.result_ctype = py_object_type
3354 def analyse_attribute(self, env, obj_type = None):
3355 # Look up attribute and set self.type and self.member.
3357 self.member = self.attribute
3358 if obj_type is None:
3359 if self.obj.type.is_string:
3360 self.obj = self.obj.coerce_to_pyobject(env)
3361 obj_type = self.obj.type
3363 if obj_type.is_string:
3364 obj_type = py_object_type
3365 if obj_type.is_ptr or obj_type.is_array:
3366 obj_type = obj_type.base_type
3368 elif obj_type.is_extension_type:
3372 if obj_type.has_attributes:
3374 if obj_type.attributes_known():
3375 entry = obj_type.scope.lookup_here(self.attribute)
3376 if entry and entry.is_member:
3380 "Cannot select attribute of incomplete type '%s'"
3382 self.type = PyrexTypes.error_type
3386 if obj_type.is_extension_type and entry.name == "__weakref__":
3387 error(self.pos, "Illegal use of special attribute __weakref__")
3388 # methods need the normal attribute lookup
3389 # because they do not have struct entries
3390 if entry.is_variable or entry.is_cmethod:
3391 self.type = entry.type
3392 self.member = entry.cname
3395 # If it's not a variable or C method, it must be a Python
3396 # method of an extension type, so we treat it like a Python
3399 # If we get here, the base object is not a struct/union/extension
3400 # type, or it is an extension type and the attribute is either not
3401 # declared or is declared as a Python method. Treat it as a Python
3402 # attribute reference.
3403 self.analyse_as_python_attribute(env, obj_type)
3405 def analyse_as_python_attribute(self, env, obj_type = None):
3406 if obj_type is None:
3407 obj_type = self.obj.type
3408 self.member = self.attribute
3409 self.type = py_object_type
3411 if not obj_type.is_pyobject and not obj_type.is_error:
3412 if obj_type.can_coerce_to_pyobject(env):
3413 self.obj = self.obj.coerce_to_pyobject(env)
3416 "Object of type '%s' has no attribute '%s'" %
3417 (obj_type, self.attribute))
3419 def nogil_check(self, env):
3423 gil_message = "Accessing Python attribute"
3425 def is_simple(self):
3427 return self.result_in_temp() or self.obj.is_simple()
3429 return NameNode.is_simple(self)
3431 def is_lvalue(self):
3435 return NameNode.is_lvalue(self)
3437 def is_ephemeral(self):
3439 return self.obj.is_ephemeral()
3441 return NameNode.is_ephemeral(self)
3443 def calculate_result_code(self):
3444 #print "AttributeNode.calculate_result_code:", self.member ###
3445 #print "...obj node =", self.obj, "code", self.obj.result() ###
3446 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3448 obj_code = obj.result_as(obj.type)
3449 #print "...obj_code =", obj_code ###
3450 if self.entry and self.entry.is_cmethod:
3451 if obj.type.is_extension_type:
3452 return "((struct %s *)%s%s%s)->%s" % (
3453 obj.type.vtabstruct_cname, obj_code, self.op,
3454 obj.type.vtabslot_cname, self.member)
3457 elif obj.type.is_complex:
3458 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3460 return "%s%s%s" % (obj_code, self.op, self.member)
3462 def generate_result_code(self, code):
3463 interned_attr_cname = code.intern_identifier(self.attribute)
3466 '%s = PyObject_GetAttr(%s, %s); %s' % (
3468 self.obj.py_result(),
3469 interned_attr_cname,
3470 code.error_goto_if_null(self.result(), self.pos)))
3471 code.put_gotref(self.py_result())
3473 # result_code contains what is needed, but we may need to insert
3474 # a check and raise an exception
3475 if (self.obj.type.is_extension_type
3476 and self.needs_none_check
3477 and code.globalstate.directives['nonecheck']):
3478 self.put_nonecheck(code)
3480 def generate_assignment_code(self, rhs, code):
3481 interned_attr_cname = code.intern_identifier(self.attribute)
3482 self.obj.generate_evaluation_code(code)
3484 code.put_error_if_neg(self.pos,
3485 'PyObject_SetAttr(%s, %s, %s)' % (
3486 self.obj.py_result(),
3487 interned_attr_cname,
3489 rhs.generate_disposal_code(code)
3490 rhs.free_temps(code)
3491 elif self.obj.type.is_complex:
3492 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3493 self.member.upper(),
3494 self.obj.result_as(self.obj.type),
3495 rhs.result_as(self.ctype())))
3497 if (self.obj.type.is_extension_type
3498 and self.needs_none_check
3499 and code.globalstate.directives['nonecheck']):
3500 self.put_nonecheck(code)
3502 select_code = self.result()
3503 if self.type.is_pyobject and self.use_managed_ref:
3504 rhs.make_owned_reference(code)
3505 code.put_giveref(rhs.py_result())
3506 code.put_gotref(select_code)
3507 code.put_decref(select_code, self.ctype())
3511 rhs.result_as(self.ctype())))
3513 rhs.generate_post_assignment_code(code)
3514 rhs.free_temps(code)
3515 self.obj.generate_disposal_code(code)
3516 self.obj.free_temps(code)
3518 def generate_deletion_code(self, code):
3519 interned_attr_cname = code.intern_identifier(self.attribute)
3520 self.obj.generate_evaluation_code(code)
3521 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3522 and self.entry.scope.entries.has_key(u'__del__')):
3523 code.put_error_if_neg(self.pos,
3524 'PyObject_DelAttr(%s, %s)' % (
3525 self.obj.py_result(),
3526 interned_attr_cname))
3528 error(self.pos, "Cannot delete C attribute of extension type")
3529 self.obj.generate_disposal_code(code)
3530 self.obj.free_temps(code)
3532 def annotate(self, code):
3534 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3536 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3538 def put_nonecheck(self, code):
3539 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3540 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3541 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3542 code.putln(code.error_goto(self.pos))
3546 #-------------------------------------------------------------------
3550 #-------------------------------------------------------------------
3552 class StarredTargetNode(ExprNode):
3553 # A starred expression like "*a"
3555 # This is only allowed in sequence assignment targets such as
3557 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3559 # and will be removed during type analysis (or generate an error
3560 # if it's found at unexpected places).
3564 subexprs = ['target']
3566 type = py_object_type
3569 def __init__(self, pos, target):
3571 self.target = target
3573 def analyse_declarations(self, env):
3574 error(self.pos, "can use starred expression only as assignment target")
3575 self.target.analyse_declarations(env)
3577 def analyse_types(self, env):
3578 error(self.pos, "can use starred expression only as assignment target")
3579 self.target.analyse_types(env)
3580 self.type = self.target.type
3582 def analyse_target_declaration(self, env):
3583 self.target.analyse_target_declaration(env)
3585 def analyse_target_types(self, env):
3586 self.target.analyse_target_types(env)
3587 self.type = self.target.type
3589 def calculate_result_code(self):
3592 def generate_result_code(self, code):
3596 class SequenceNode(ExprNode):
3597 # Base class for list and tuple constructor nodes.
3598 # Contains common code for performing sequence unpacking.
3602 # unpacked_items [ExprNode] or None
3603 # coerced_unpacked_items [ExprNode] or None
3607 is_sequence_constructor = 1
3608 unpacked_items = None
3610 def compile_time_value_list(self, denv):
3611 return [arg.compile_time_value(denv) for arg in self.args]
3613 def replace_starred_target_node(self):
3614 # replace a starred node in the targets by the contained expression
3615 self.starred_assignment = False
3617 for arg in self.args:
3619 if self.starred_assignment:
3620 error(arg.pos, "more than 1 starred expression in assignment")
3621 self.starred_assignment = True
3623 arg.is_starred = True
3627 def analyse_target_declaration(self, env):
3628 self.replace_starred_target_node()
3629 for arg in self.args:
3630 arg.analyse_target_declaration(env)
3632 def analyse_types(self, env, skip_children=False):
3633 for i in range(len(self.args)):
3635 if not skip_children: arg.analyse_types(env)
3636 self.args[i] = arg.coerce_to_pyobject(env)
3637 self.type = py_object_type
3640 def may_be_none(self):
3643 def analyse_target_types(self, env):
3644 self.iterator = PyTempNode(self.pos, env)
3645 self.unpacked_items = []
3646 self.coerced_unpacked_items = []
3647 for arg in self.args:
3648 arg.analyse_target_types(env)
3650 if not arg.type.assignable_from(Builtin.list_type):
3652 "starred target must have Python object (list) type")
3653 if arg.type is py_object_type:
3654 arg.type = Builtin.list_type
3655 unpacked_item = PyTempNode(self.pos, env)
3656 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3657 self.unpacked_items.append(unpacked_item)
3658 self.coerced_unpacked_items.append(coerced_unpacked_item)
3659 self.type = py_object_type
3661 def generate_result_code(self, code):
3662 self.generate_operation_code(code)
3664 def generate_assignment_code(self, rhs, code):
3665 if self.starred_assignment:
3666 self.generate_starred_assignment_code(rhs, code)
3668 self.generate_parallel_assignment_code(rhs, code)
3670 for item in self.unpacked_items:
3672 rhs.free_temps(code)
3674 def generate_parallel_assignment_code(self, rhs, code):
3675 # Need to work around the fact that generate_evaluation_code
3676 # allocates the temps in a rather hacky way -- the assignment
3677 # is evaluated twice, within each if-block.
3679 if rhs.type is tuple_type:
3680 tuple_check = "likely(%s != Py_None)"
3682 tuple_check = "PyTuple_CheckExact(%s)"
3684 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3685 tuple_check % rhs.py_result(),
3688 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3689 for item in self.unpacked_items:
3691 for i in range(len(self.args)):
3692 item = self.unpacked_items[i]
3694 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3697 code.put_incref(item.result(), item.ctype())
3698 value_node = self.coerced_unpacked_items[i]
3699 value_node.generate_evaluation_code(code)
3700 rhs.generate_disposal_code(code)
3702 for i in range(len(self.args)):
3703 self.args[i].generate_assignment_code(
3704 self.coerced_unpacked_items[i], code)
3706 code.putln("} else {")
3708 if rhs.type is tuple_type:
3709 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3710 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3711 rhs.py_result(), len(self.args)))
3712 code.putln(code.error_goto(self.pos))
3714 code.globalstate.use_utility_code(unpacking_utility_code)
3716 self.iterator.allocate(code)
3718 "%s = PyObject_GetIter(%s); %s" % (
3719 self.iterator.result(),
3721 code.error_goto_if_null(self.iterator.result(), self.pos)))
3722 code.put_gotref(self.iterator.py_result())
3723 rhs.generate_disposal_code(code)
3724 for i in range(len(self.args)):
3725 item = self.unpacked_items[i]
3726 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3727 self.iterator.py_result(), i)
3731 typecast(item.ctype(), py_object_type, unpack_code),
3732 code.error_goto_if_null(item.result(), self.pos)))
3733 code.put_gotref(item.py_result())
3734 value_node = self.coerced_unpacked_items[i]
3735 value_node.generate_evaluation_code(code)
3736 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3737 self.iterator.py_result(),
3739 if debug_disposal_code:
3740 print("UnpackNode.generate_assignment_code:")
3741 print("...generating disposal code for %s" % self.iterator)
3742 self.iterator.generate_disposal_code(code)
3743 self.iterator.free_temps(code)
3744 self.iterator.release(code)
3746 for i in range(len(self.args)):
3747 self.args[i].generate_assignment_code(
3748 self.coerced_unpacked_items[i], code)
3752 def generate_starred_assignment_code(self, rhs, code):
3753 code.globalstate.use_utility_code(unpacking_utility_code)
3755 for i, arg in enumerate(self.args):
3757 starred_target = self.unpacked_items[i]
3758 fixed_args_left = self.args[:i]
3759 fixed_args_right = self.args[i+1:]
3762 self.iterator.allocate(code)
3764 "%s = PyObject_GetIter(%s); %s" % (
3765 self.iterator.result(),
3767 code.error_goto_if_null(self.iterator.result(), self.pos)))
3768 code.put_gotref(self.iterator.py_result())
3769 rhs.generate_disposal_code(code)
3771 for item in self.unpacked_items:
3773 for i in range(len(fixed_args_left)):
3774 item = self.unpacked_items[i]
3775 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3776 self.iterator.py_result(), i)
3780 typecast(item.ctype(), py_object_type, unpack_code),
3781 code.error_goto_if_null(item.result(), self.pos)))
3782 code.put_gotref(item.py_result())
3783 value_node = self.coerced_unpacked_items[i]
3784 value_node.generate_evaluation_code(code)
3786 target_list = starred_target.result()
3787 code.putln("%s = PySequence_List(%s); %s" % (
3788 target_list, self.iterator.py_result(),
3789 code.error_goto_if_null(target_list, self.pos)))
3790 code.put_gotref(target_list)
3791 if fixed_args_right:
3792 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3793 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3794 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3795 (target_list, len(unpacked_right_args))))
3796 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3797 len(fixed_args_left), target_list,
3798 code.error_goto(self.pos)))
3800 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3801 self.coerced_unpacked_items[::-1])):
3803 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3805 target_list, target_list))
3806 # resize the list the hard way
3807 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3808 code.put_gotref(arg.py_result())
3809 coerced_arg.generate_evaluation_code(code)
3811 self.iterator.generate_disposal_code(code)
3812 self.iterator.free_temps(code)
3813 self.iterator.release(code)
3815 for i in range(len(self.args)):
3816 self.args[i].generate_assignment_code(
3817 self.coerced_unpacked_items[i], code)
3819 def annotate(self, code):
3820 for arg in self.args:
3822 if self.unpacked_items:
3823 for arg in self.unpacked_items:
3825 for arg in self.coerced_unpacked_items:
3829 class TupleNode(SequenceNode):
3830 # Tuple constructor.
3834 gil_message = "Constructing Python tuple"
3836 def analyse_types(self, env, skip_children=False):
3837 if len(self.args) == 0:
3841 SequenceNode.analyse_types(self, env, skip_children)
3843 def calculate_result_code(self):
3844 if len(self.args) > 0:
3845 error(self.pos, "Positive length tuples must be constructed.")
3847 return Naming.empty_tuple
3849 def calculate_constant_result(self):
3850 self.constant_result = tuple([
3851 arg.constant_result for arg in self.args])
3853 def compile_time_value(self, denv):
3854 values = self.compile_time_value_list(denv)
3856 return tuple(values)
3857 except Exception, e:
3858 self.compile_time_value_error(e)
3860 def generate_operation_code(self, code):
3861 if len(self.args) == 0:
3862 # result_code is Naming.empty_tuple
3865 "%s = PyTuple_New(%s); %s" % (
3868 code.error_goto_if_null(self.result(), self.pos)))
3869 code.put_gotref(self.py_result())
3870 for i in range(len(self.args)):
3872 if not arg.result_in_temp():
3873 code.put_incref(arg.result(), arg.ctype())
3875 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3879 code.put_giveref(arg.py_result())
3881 def generate_subexpr_disposal_code(self, code):
3882 # We call generate_post_assignment_code here instead
3883 # of generate_disposal_code, because values were stored
3884 # in the tuple using a reference-stealing operation.
3885 for arg in self.args:
3886 arg.generate_post_assignment_code(code)
3887 # Should NOT call free_temps -- this is invoked by the default
3888 # generate_evaluation_code which will do that.
3891 class ListNode(SequenceNode):
3894 # obj_conversion_errors [PyrexError] used internally
3895 # orignial_args [ExprNode] used internally
3897 obj_conversion_errors = []
3899 gil_message = "Constructing Python list"
3901 def type_dependencies(self, env):
3904 def infer_type(self, env):
3905 # TOOD: Infer non-object list arrays.
3908 def analyse_expressions(self, env):
3909 SequenceNode.analyse_expressions(self, env)
3910 self.coerce_to_pyobject(env)
3912 def analyse_types(self, env):
3914 self.original_args = list(self.args)
3915 SequenceNode.analyse_types(self, env)
3916 self.type = list_type
3917 self.obj_conversion_errors = held_errors()
3918 release_errors(ignore=True)
3920 def coerce_to(self, dst_type, env):
3921 if dst_type.is_pyobject:
3922 for err in self.obj_conversion_errors:
3924 self.obj_conversion_errors = []
3925 if not self.type.subtype_of(dst_type):
3926 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3927 elif dst_type.is_ptr:
3928 base_type = dst_type.base_type
3929 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3930 for i in range(len(self.original_args)):
3932 if isinstance(arg, CoerceToPyTypeNode):
3934 self.args[i] = arg.coerce_to(base_type, env)
3935 elif dst_type.is_struct:
3936 if len(self.args) > len(dst_type.scope.var_entries):
3937 error(self.pos, "Too may members for '%s'" % dst_type)
3939 if len(self.args) < len(dst_type.scope.var_entries):
3940 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3941 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3942 if isinstance(arg, CoerceToPyTypeNode):
3944 self.args[i] = arg.coerce_to(member.type, env)
3945 self.type = dst_type
3947 self.type = error_type
3948 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3951 def release_temp(self, env):
3952 if self.type.is_array:
3953 # To be valid C++, we must allocate the memory on the stack
3954 # manually and be sure not to reuse it for something else.
3957 SequenceNode.release_temp(self, env)
3959 def calculate_constant_result(self):
3960 self.constant_result = [
3961 arg.constant_result for arg in self.args]
3963 def compile_time_value(self, denv):
3964 return self.compile_time_value_list(denv)
3966 def generate_operation_code(self, code):
3967 if self.type.is_pyobject:
3968 for err in self.obj_conversion_errors:
3970 code.putln("%s = PyList_New(%s); %s" %
3973 code.error_goto_if_null(self.result(), self.pos)))
3974 code.put_gotref(self.py_result())
3975 for i in range(len(self.args)):
3977 #if not arg.is_temp:
3978 if not arg.result_in_temp():
3979 code.put_incref(arg.result(), arg.ctype())
3980 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
3984 code.put_giveref(arg.py_result())
3985 elif self.type.is_array:
3986 for i, arg in enumerate(self.args):
3987 code.putln("%s[%s] = %s;" % (
3991 elif self.type.is_struct:
3992 for arg, member in zip(self.args, self.type.scope.var_entries):
3993 code.putln("%s.%s = %s;" % (
3998 raise InternalError("List type never specified")
4000 def generate_subexpr_disposal_code(self, code):
4001 # We call generate_post_assignment_code here instead
4002 # of generate_disposal_code, because values were stored
4003 # in the list using a reference-stealing operation.
4004 for arg in self.args:
4005 arg.generate_post_assignment_code(code)
4006 # Should NOT call free_temps -- this is invoked by the default
4007 # generate_evaluation_code which will do that.
4010 class ScopedExprNode(ExprNode):
4011 # Abstract base class for ExprNodes that have their own local
4012 # scope, such as generator expressions.
4014 # expr_scope Scope the inner scope of the expression
4019 def analyse_types(self, env):
4020 # nothing to do here, the children will be analysed separately
4023 def analyse_expressions(self, env):
4024 # nothing to do here, the children will be analysed separately
4027 def analyse_scoped_expressions(self, env):
4028 # this is called with the expr_scope as env
4031 def init_scope(self, outer_scope, expr_scope=None):
4032 self.expr_scope = expr_scope
4035 class ComprehensionNode(ScopedExprNode):
4036 subexprs = ["target"]
4037 child_attrs = ["loop", "append"]
4039 # leak loop variables or not? non-leaking Py3 behaviour is
4040 # default, except for list comprehensions where the behaviour
4041 # differs in Py2 and Py3 (see Parsing.py)
4042 has_local_scope = True
4044 def infer_type(self, env):
4045 return self.target.infer_type(env)
4047 def analyse_declarations(self, env):
4048 self.append.target = self # this is used in the PyList_Append of the inner loop
4049 self.init_scope(env)
4050 if self.expr_scope is not None:
4051 self.loop.analyse_declarations(self.expr_scope)
4053 self.loop.analyse_declarations(env)
4055 def init_scope(self, outer_scope, expr_scope=None):
4056 if expr_scope is not None:
4057 self.expr_scope = expr_scope
4058 elif self.has_local_scope:
4059 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4061 self.expr_scope = None
4063 def analyse_types(self, env):
4064 self.target.analyse_expressions(env)
4065 self.type = self.target.type
4066 if not self.has_local_scope:
4067 self.loop.analyse_expressions(env)
4069 def analyse_expressions(self, env):
4070 self.analyse_types(env)
4072 def analyse_scoped_expressions(self, env):
4073 if self.has_local_scope:
4074 self.loop.analyse_expressions(env)
4076 def may_be_none(self):
4079 def calculate_result_code(self):
4080 return self.target.result()
4082 def generate_result_code(self, code):
4083 self.generate_operation_code(code)
4085 def generate_operation_code(self, code):
4086 self.loop.generate_execution_code(code)
4088 def annotate(self, code):
4089 self.loop.annotate(code)
4092 class ComprehensionAppendNode(Node):
4093 # Need to be careful to avoid infinite recursion:
4094 # target must not be in child_attrs/subexprs
4096 child_attrs = ['expr']
4098 type = PyrexTypes.c_int_type
4100 def analyse_expressions(self, env):
4101 self.expr.analyse_expressions(env)
4102 if not self.expr.type.is_pyobject:
4103 self.expr = self.expr.coerce_to_pyobject(env)
4105 def generate_execution_code(self, code):
4106 if self.target.type is list_type:
4107 function = "PyList_Append"
4108 elif self.target.type is set_type:
4109 function = "PySet_Add"
4111 raise InternalError(
4112 "Invalid type for comprehension node: %s" % self.target.type)
4114 self.expr.generate_evaluation_code(code)
4115 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4117 self.target.result(),
4120 self.expr.generate_disposal_code(code)
4121 self.expr.free_temps(code)
4123 def generate_function_definitions(self, env, code):
4124 self.expr.generate_function_definitions(env, code)
4126 def annotate(self, code):
4127 self.expr.annotate(code)
4129 class DictComprehensionAppendNode(ComprehensionAppendNode):
4130 child_attrs = ['key_expr', 'value_expr']
4132 def analyse_expressions(self, env):
4133 self.key_expr.analyse_expressions(env)
4134 if not self.key_expr.type.is_pyobject:
4135 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4136 self.value_expr.analyse_expressions(env)
4137 if not self.value_expr.type.is_pyobject:
4138 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4140 def generate_execution_code(self, code):
4141 self.key_expr.generate_evaluation_code(code)
4142 self.value_expr.generate_evaluation_code(code)
4143 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4144 self.target.result(),
4145 self.key_expr.result(),
4146 self.value_expr.result()
4148 self.key_expr.generate_disposal_code(code)
4149 self.key_expr.free_temps(code)
4150 self.value_expr.generate_disposal_code(code)
4151 self.value_expr.free_temps(code)
4153 def generate_function_definitions(self, env, code):
4154 self.key_expr.generate_function_definitions(env, code)
4155 self.value_expr.generate_function_definitions(env, code)
4157 def annotate(self, code):
4158 self.key_expr.annotate(code)
4159 self.value_expr.annotate(code)
4162 class GeneratorExpressionNode(ScopedExprNode):
4163 # A generator expression, e.g. (i for i in range(10))
4165 # Result is a generator.
4167 # loop ForStatNode the for-loop, containing a YieldExprNode
4169 child_attrs = ["loop"]
4171 type = py_object_type
4173 def analyse_declarations(self, env):
4174 self.init_scope(env)
4175 self.loop.analyse_declarations(self.expr_scope)
4177 def init_scope(self, outer_scope, expr_scope=None):
4178 if expr_scope is not None:
4179 self.expr_scope = expr_scope
4181 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4183 def analyse_types(self, env):
4186 def analyse_scoped_expressions(self, env):
4187 self.loop.analyse_expressions(env)
4189 def may_be_none(self):
4192 def annotate(self, code):
4193 self.loop.annotate(code)
4196 class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
4197 # An inlined generator expression for which the result is
4198 # calculated inside of the loop. This will only be created by
4199 # transforms when replacing builtin calls on generator
4202 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4203 # result_node ResultRefNode the reference to the result value temp
4204 # orig_func String the name of the builtin function this node replaces
4206 child_attrs = ["loop"]
4208 def analyse_types(self, env):
4209 self.type = self.result_node.type
4212 def coerce_to(self, dst_type, env):
4213 if self.orig_func == 'sum' and dst_type.is_numeric:
4214 # we can optimise by dropping the aggregation variable into C
4215 self.result_node.type = self.type = dst_type
4217 return GeneratorExpressionNode.coerce_to(self, dst_type, env)
4219 def generate_result_code(self, code):
4220 self.result_node.result_code = self.result()
4221 self.loop.generate_execution_code(code)
4224 class SetNode(ExprNode):
4231 gil_message = "Constructing Python set"
4233 def analyse_types(self, env):
4234 for i in range(len(self.args)):
4236 arg.analyse_types(env)
4237 self.args[i] = arg.coerce_to_pyobject(env)
4238 self.type = set_type
4241 def may_be_none(self):
4244 def calculate_constant_result(self):
4245 self.constant_result = set([
4246 arg.constant_result for arg in self.args])
4248 def compile_time_value(self, denv):
4249 values = [arg.compile_time_value(denv) for arg in self.args]
4252 except Exception, e:
4253 self.compile_time_value_error(e)
4255 def generate_evaluation_code(self, code):
4256 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4257 self.allocate_temp_result(code)
4259 "%s = PySet_New(0); %s" % (
4261 code.error_goto_if_null(self.result(), self.pos)))
4262 code.put_gotref(self.py_result())
4263 for arg in self.args:
4264 arg.generate_evaluation_code(code)
4266 code.error_goto_if_neg(
4267 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4269 arg.generate_disposal_code(code)
4270 arg.free_temps(code)
4273 class DictNode(ExprNode):
4274 # Dictionary constructor.
4276 # key_value_pairs [DictItemNode]
4278 # obj_conversion_errors [PyrexError] used internally
4280 subexprs = ['key_value_pairs']
4284 obj_conversion_errors = []
4286 def calculate_constant_result(self):
4287 self.constant_result = dict([
4288 item.constant_result for item in self.key_value_pairs])
4290 def compile_time_value(self, denv):
4291 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4292 for item in self.key_value_pairs]
4295 except Exception, e:
4296 self.compile_time_value_error(e)
4298 def type_dependencies(self, env):
4301 def infer_type(self, env):
4302 # TOOD: Infer struct constructors.
4305 def analyse_types(self, env):
4307 for item in self.key_value_pairs:
4308 item.analyse_types(env)
4309 self.obj_conversion_errors = held_errors()
4310 release_errors(ignore=True)
4312 def may_be_none(self):
4315 def coerce_to(self, dst_type, env):
4316 if dst_type.is_pyobject:
4317 self.release_errors()
4318 if not self.type.subtype_of(dst_type):
4319 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4320 elif dst_type.is_struct_or_union:
4321 self.type = dst_type
4322 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4323 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4324 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4325 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4326 for item in self.key_value_pairs:
4327 if isinstance(item.key, CoerceToPyTypeNode):
4328 item.key = item.key.arg
4329 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4330 error(item.key.pos, "Invalid struct field identifier")
4331 item.key = StringNode(item.key.pos, value="<error>")
4333 key = str(item.key.value) # converts string literals to unicode in Py3
4334 member = dst_type.scope.lookup_here(key)
4336 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4339 if isinstance(value, CoerceToPyTypeNode):
4341 item.value = value.coerce_to(member.type, env)
4343 self.type = error_type
4344 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4347 def release_errors(self):
4348 for err in self.obj_conversion_errors:
4350 self.obj_conversion_errors = []
4352 gil_message = "Constructing Python dict"
4354 def generate_evaluation_code(self, code):
4355 # Custom method used here because key-value
4356 # pairs are evaluated and used one at a time.
4357 code.mark_pos(self.pos)
4358 self.allocate_temp_result(code)
4359 if self.type.is_pyobject:
4360 self.release_errors()
4362 "%s = PyDict_New(); %s" % (
4364 code.error_goto_if_null(self.result(), self.pos)))
4365 code.put_gotref(self.py_result())
4366 for item in self.key_value_pairs:
4367 item.generate_evaluation_code(code)
4368 if self.type.is_pyobject:
4369 code.put_error_if_neg(self.pos,
4370 "PyDict_SetItem(%s, %s, %s)" % (
4372 item.key.py_result(),
4373 item.value.py_result()))
4375 code.putln("%s.%s = %s;" % (
4378 item.value.result()))
4379 item.generate_disposal_code(code)
4380 item.free_temps(code)
4382 def annotate(self, code):
4383 for item in self.key_value_pairs:
4386 class DictItemNode(ExprNode):
4387 # Represents a single item in a DictNode
4391 subexprs = ['key', 'value']
4393 nogil_check = None # Parent DictNode takes care of it
4395 def calculate_constant_result(self):
4396 self.constant_result = (
4397 self.key.constant_result, self.value.constant_result)
4399 def analyse_types(self, env):
4400 self.key.analyse_types(env)
4401 self.value.analyse_types(env)
4402 self.key = self.key.coerce_to_pyobject(env)
4403 self.value = self.value.coerce_to_pyobject(env)
4405 def generate_evaluation_code(self, code):
4406 self.key.generate_evaluation_code(code)
4407 self.value.generate_evaluation_code(code)
4409 def generate_disposal_code(self, code):
4410 self.key.generate_disposal_code(code)
4411 self.value.generate_disposal_code(code)
4413 def free_temps(self, code):
4414 self.key.free_temps(code)
4415 self.value.free_temps(code)
4418 return iter([self.key, self.value])
4420 class ModuleNameMixin(object):
4421 def set_mod_name(self, env):
4422 self.module_name = env.global_scope().qualified_name
4424 def get_py_mod_name(self, code):
4425 return code.get_py_string_const(
4426 self.module_name, identifier=True)
4428 class ClassNode(ExprNode, ModuleNameMixin):
4429 # Helper class used in the implementation of Python
4430 # class definitions. Constructs a class object given
4431 # a name, tuple of bases and class dictionary.
4433 # name EncodedString Name of the class
4434 # bases ExprNode Base class tuple
4435 # dict ExprNode Class dict (not owned by this node)
4436 # doc ExprNode or None Doc string
4437 # module_name EncodedString Name of defining module
4439 subexprs = ['bases', 'doc']
4441 def analyse_types(self, env):
4442 self.bases.analyse_types(env)
4444 self.doc.analyse_types(env)
4445 self.doc = self.doc.coerce_to_pyobject(env)
4446 self.type = py_object_type
4448 env.use_utility_code(create_class_utility_code);
4449 #TODO(craig,haoyu) This should be moved to a better place
4450 self.set_mod_name(env)
4452 def may_be_none(self):
4455 gil_message = "Constructing Python class"
4457 def generate_result_code(self, code):
4458 cname = code.intern_identifier(self.name)
4460 code.put_error_if_neg(self.pos,
4461 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4462 self.dict.py_result(),
4463 self.doc.py_result()))
4464 py_mod_name = self.get_py_mod_name(code)
4466 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4468 self.bases.py_result(),
4469 self.dict.py_result(),
4472 code.error_goto_if_null(self.result(), self.pos)))
4473 code.put_gotref(self.py_result())
4475 class BoundMethodNode(ExprNode):
4476 # Helper class used in the implementation of Python
4477 # class definitions. Constructs an bound method
4478 # object from a class and a function.
4480 # function ExprNode Function object
4481 # self_object ExprNode self object
4483 subexprs = ['function']
4485 def analyse_types(self, env):
4486 self.function.analyse_types(env)
4487 self.type = py_object_type
4490 gil_message = "Constructing an bound method"
4492 def generate_result_code(self, code):
4494 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4496 self.function.py_result(),
4497 self.self_object.py_result(),
4498 self.self_object.py_result(),
4499 code.error_goto_if_null(self.result(), self.pos)))
4500 code.put_gotref(self.py_result())
4502 class UnboundMethodNode(ExprNode):
4503 # Helper class used in the implementation of Python
4504 # class definitions. Constructs an unbound method
4505 # object from a class and a function.
4507 # function ExprNode Function object
4509 type = py_object_type
4512 subexprs = ['function']
4514 def analyse_types(self, env):
4515 self.function.analyse_types(env)
4517 def may_be_none(self):
4520 gil_message = "Constructing an unbound method"
4522 def generate_result_code(self, code):
4523 class_cname = code.pyclass_stack[-1].classobj.result()
4525 "%s = PyMethod_New(%s, 0, %s); %s" % (
4527 self.function.py_result(),
4529 code.error_goto_if_null(self.result(), self.pos)))
4530 code.put_gotref(self.py_result())
4533 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4534 # Helper class used in the implementation of Python
4535 # class definitions. Constructs a PyCFunction object
4536 # from a PyMethodDef struct.
4538 # pymethdef_cname string PyMethodDef structure
4539 # self_object ExprNode or None
4541 # module_name EncodedString Name of defining module
4547 type = py_object_type
4550 def analyse_types(self, env):
4552 env.use_utility_code(binding_cfunc_utility_code)
4554 #TODO(craig,haoyu) This should be moved to a better place
4555 self.set_mod_name(env)
4557 def may_be_none(self):
4560 gil_message = "Constructing Python function"
4562 def self_result_code(self):
4563 if self.self_object is None:
4564 self_result = "NULL"
4566 self_result = self.self_object.py_result()
4569 def generate_result_code(self, code):
4571 constructor = "%s_NewEx" % Naming.binding_cfunc
4573 constructor = "PyCFunction_NewEx"
4574 py_mod_name = self.get_py_mod_name(code)
4576 '%s = %s(&%s, %s, %s); %s' % (
4579 self.pymethdef_cname,
4580 self.self_result_code(),
4582 code.error_goto_if_null(self.result(), self.pos)))
4583 code.put_gotref(self.py_result())
4585 class InnerFunctionNode(PyCFunctionNode):
4586 # Special PyCFunctionNode that depends on a closure class
4590 def self_result_code(self):
4591 return "((PyObject*)%s)" % Naming.cur_scope_cname
4593 class LambdaNode(InnerFunctionNode):
4594 # Lambda expression node (only used as a function reference)
4596 # args [CArgDeclNode] formal arguments
4597 # star_arg PyArgDeclNode or None * argument
4598 # starstar_arg PyArgDeclNode or None ** argument
4599 # lambda_name string a module-globally unique lambda name
4600 # result_expr ExprNode
4601 # def_node DefNode the underlying function 'def' node
4603 child_attrs = ['def_node']
4606 name = StringEncoding.EncodedString('<lambda>')
4608 def analyse_declarations(self, env):
4609 #self.def_node.needs_closure = self.needs_closure
4610 self.def_node.analyse_declarations(env)
4611 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
4612 env.add_lambda_def(self.def_node)
4614 class YieldExprNode(ExprNode):
4615 # Yield expression node
4617 # arg ExprNode the value to return from the generator
4618 # label_name string name of the C label used for this yield
4621 type = py_object_type
4623 def analyse_types(self, env):
4625 if self.arg is not None:
4626 self.arg.analyse_types(env)
4627 if not self.arg.type.is_pyobject:
4628 self.arg = self.arg.coerce_to_pyobject(env)
4629 error(self.pos, "Generators are not supported")
4631 def generate_result_code(self, code):
4632 self.label_name = code.new_label('resume_from_yield')
4633 code.use_label(self.label_name)
4634 code.putln("/* FIXME: save temporary variables */")
4635 code.putln("/* FIXME: return from function, yielding value */")
4636 code.put_label(self.label_name)
4637 code.putln("/* FIXME: restore temporary variables and */")
4638 code.putln("/* FIXME: extract sent value from closure */")
4641 #-------------------------------------------------------------------
4643 # Unary operator nodes
4645 #-------------------------------------------------------------------
4647 compile_time_unary_operators = {
4648 'not': operator.not_,
4654 class UnopNode(ExprNode):
4658 # Processing during analyse_expressions phase:
4660 # analyse_c_operation
4661 # Called when the operand is not a pyobject.
4662 # - Check operand type and coerce if needed.
4663 # - Determine result type and result code fragment.
4664 # - Allocate temporary for result if needed.
4666 subexprs = ['operand']
4669 def calculate_constant_result(self):
4670 func = compile_time_unary_operators[self.operator]
4671 self.constant_result = func(self.operand.constant_result)
4673 def compile_time_value(self, denv):
4674 func = compile_time_unary_operators.get(self.operator)
4677 "Unary '%s' not supported in compile-time expression"
4679 operand = self.operand.compile_time_value(denv)
4681 return func(operand)
4682 except Exception, e:
4683 self.compile_time_value_error(e)
4685 def infer_type(self, env):
4686 operand_type = self.operand.infer_type(env)
4687 if operand_type.is_pyobject:
4688 return py_object_type
4692 def analyse_types(self, env):
4693 self.operand.analyse_types(env)
4694 if self.is_py_operation():
4695 self.coerce_operand_to_pyobject(env)
4696 self.type = py_object_type
4698 elif self.is_cpp_operation():
4699 self.analyse_cpp_operation(env)
4701 self.analyse_c_operation(env)
4703 def check_const(self):
4704 return self.operand.check_const()
4706 def is_py_operation(self):
4707 return self.operand.type.is_pyobject
4709 def nogil_check(self, env):
4710 if self.is_py_operation():
4713 def is_cpp_operation(self):
4714 type = self.operand.type
4715 return type.is_cpp_class
4717 def coerce_operand_to_pyobject(self, env):
4718 self.operand = self.operand.coerce_to_pyobject(env)
4720 def generate_result_code(self, code):
4721 if self.operand.type.is_pyobject:
4722 self.generate_py_operation_code(code)
4724 def generate_py_operation_code(self, code):
4725 function = self.py_operation_function()
4727 "%s = %s(%s); %s" % (
4730 self.operand.py_result(),
4731 code.error_goto_if_null(self.result(), self.pos)))
4732 code.put_gotref(self.py_result())
4734 def type_error(self):
4735 if not self.operand.type.is_error:
4736 error(self.pos, "Invalid operand type for '%s' (%s)" %
4737 (self.operator, self.operand.type))
4738 self.type = PyrexTypes.error_type
4740 def analyse_cpp_operation(self, env):
4741 type = self.operand.type
4743 type = type.base_type
4744 function = type.scope.lookup("operator%s" % self.operator)
4746 error(self.pos, "'%s' operator not defined for %s"
4747 % (self.operator, type))
4750 func_type = function.type
4751 if func_type.is_ptr:
4752 func_type = func_type.base_type
4753 self.type = func_type.return_type
4756 class NotNode(ExprNode):
4761 type = PyrexTypes.c_bint_type
4763 subexprs = ['operand']
4765 def calculate_constant_result(self):
4766 self.constant_result = not self.operand.constant_result
4768 def compile_time_value(self, denv):
4769 operand = self.operand.compile_time_value(denv)
4772 except Exception, e:
4773 self.compile_time_value_error(e)
4775 def infer_type(self, env):
4776 return PyrexTypes.c_bint_type
4778 def analyse_types(self, env):
4779 self.operand.analyse_types(env)
4780 self.operand = self.operand.coerce_to_boolean(env)
4782 def calculate_result_code(self):
4783 return "(!%s)" % self.operand.result()
4785 def generate_result_code(self, code):
4789 class UnaryPlusNode(UnopNode):
4790 # unary '+' operator
4794 def analyse_c_operation(self, env):
4795 self.type = self.operand.type
4797 def py_operation_function(self):
4798 return "PyNumber_Positive"
4800 def calculate_result_code(self):
4801 if self.is_cpp_operation():
4802 return "(+%s)" % self.operand.result()
4804 return self.operand.result()
4807 class UnaryMinusNode(UnopNode):
4808 # unary '-' operator
4812 def analyse_c_operation(self, env):
4813 if self.operand.type.is_numeric:
4814 self.type = self.operand.type
4817 if self.type.is_complex:
4820 def py_operation_function(self):
4821 return "PyNumber_Negative"
4823 def calculate_result_code(self):
4825 return "(-%s)" % self.operand.result()
4827 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
4829 def get_constant_c_result_code(self):
4830 value = self.operand.get_constant_c_result_code()
4832 return "(-%s)" % (value)
4834 class TildeNode(UnopNode):
4835 # unary '~' operator
4837 def analyse_c_operation(self, env):
4838 if self.operand.type.is_int:
4839 self.type = self.operand.type
4843 def py_operation_function(self):
4844 return "PyNumber_Invert"
4846 def calculate_result_code(self):
4847 return "(~%s)" % self.operand.result()
4850 class CUnopNode(UnopNode):
4852 def is_py_operation(self):
4855 class DereferenceNode(CUnopNode):
4860 def analyse_c_operation(self, env):
4861 if self.operand.type.is_ptr:
4862 self.type = self.operand.type.base_type
4866 def calculate_result_code(self):
4867 return "(*%s)" % self.operand.result()
4870 class DecrementIncrementNode(CUnopNode):
4871 # unary ++/-- operator
4873 def analyse_c_operation(self, env):
4874 if self.operand.type.is_ptr or self.operand.type.is_numeric:
4875 self.type = self.operand.type
4879 def calculate_result_code(self):
4881 return "(%s%s)" % (self.operator, self.operand.result())
4883 return "(%s%s)" % (self.operand.result(), self.operator)
4885 def inc_dec_constructor(is_prefix, operator):
4886 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
4889 class AmpersandNode(ExprNode):
4890 # The C address-of operator.
4894 subexprs = ['operand']
4896 def infer_type(self, env):
4897 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
4899 def analyse_types(self, env):
4900 self.operand.analyse_types(env)
4901 argtype = self.operand.type
4902 if not (argtype.is_cfunction or self.operand.is_lvalue()):
4903 self.error("Taking address of non-lvalue")
4905 if argtype.is_pyobject:
4906 self.error("Cannot take address of Python variable")
4908 self.type = PyrexTypes.c_ptr_type(argtype)
4910 def check_const(self):
4911 return self.operand.check_const_addr()
4913 def error(self, mess):
4914 error(self.pos, mess)
4915 self.type = PyrexTypes.error_type
4916 self.result_code = "<error>"
4918 def calculate_result_code(self):
4919 return "(&%s)" % self.operand.result()
4921 def generate_result_code(self, code):
4925 unop_node_classes = {
4927 "-": UnaryMinusNode,
4931 def unop_node(pos, operator, operand):
4932 # Construct unnop node of appropriate class for
4934 if isinstance(operand, IntNode) and operator == '-':
4935 return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
4936 elif isinstance(operand, UnopNode) and operand.operator == operator:
4937 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
4938 return unop_node_classes[operator](pos,
4939 operator = operator,
4943 class TypecastNode(ExprNode):
4947 # base_type CBaseTypeNode
4948 # declarator CDeclaratorNode
4950 # If used from a transform, one can if wanted specify the attribute
4951 # "type" directly and leave base_type and declarator to None
4953 subexprs = ['operand']
4954 base_type = declarator = type = None
4956 def type_dependencies(self, env):
4959 def infer_type(self, env):
4960 if self.type is None:
4961 base_type = self.base_type.analyse(env)
4962 _, self.type = self.declarator.analyse(base_type, env)
4965 def analyse_types(self, env):
4966 if self.type is None:
4967 base_type = self.base_type.analyse(env)
4968 _, self.type = self.declarator.analyse(base_type, env)
4969 if self.type.is_cfunction:
4971 "Cannot cast to a function type")
4972 self.type = PyrexTypes.error_type
4973 self.operand.analyse_types(env)
4974 to_py = self.type.is_pyobject
4975 from_py = self.operand.type.is_pyobject
4976 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
4977 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
4978 if to_py and not from_py:
4979 if self.type is bytes_type and self.operand.type.is_int:
4980 # FIXME: the type cast node isn't needed in this case
4981 # and can be dropped once analyse_types() can return a
4983 self.operand = CoerceIntToBytesNode(self.operand, env)
4984 elif self.operand.type.can_coerce_to_pyobject(env):
4985 self.result_ctype = py_object_type
4986 self.operand = self.operand.coerce_to_pyobject(env)
4988 if self.operand.type.is_ptr:
4989 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
4990 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
4992 # Should this be an error?
4993 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
4994 self.operand = self.operand.coerce_to_simple(env)
4995 elif from_py and not to_py:
4996 if self.type.create_from_py_utility_code(env):
4997 self.operand = self.operand.coerce_to(self.type, env)
4998 elif self.type.is_ptr:
4999 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5000 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5002 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5003 elif from_py and to_py:
5004 if self.typecheck and self.type.is_extension_type:
5005 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5006 elif self.type.is_complex and self.operand.type.is_complex:
5007 self.operand = self.operand.coerce_to_simple(env)
5009 def nogil_check(self, env):
5010 if self.type and self.type.is_pyobject and self.is_temp:
5013 def check_const(self):
5014 return self.operand.check_const()
5016 def calculate_constant_result(self):
5017 # we usually do not know the result of a type cast at code
5021 def calculate_result_code(self):
5022 if self.type.is_complex:
5023 operand_result = self.operand.result()
5024 if self.operand.type.is_complex:
5025 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5026 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5028 real_part = self.type.real_type.cast_code(operand_result)
5030 return "%s(%s, %s)" % (
5031 self.type.from_parts,
5035 return self.type.cast_code(self.operand.result())
5037 def get_constant_c_result_code(self):
5038 operand_result = self.operand.get_constant_c_result_code()
5040 return self.type.cast_code(operand_result)
5042 def result_as(self, type):
5043 if self.type.is_pyobject and not self.is_temp:
5044 # Optimise away some unnecessary casting
5045 return self.operand.result_as(type)
5047 return ExprNode.result_as(self, type)
5049 def generate_result_code(self, code):
5052 "%s = (PyObject *)%s;" % (
5054 self.operand.result()))
5055 code.put_incref(self.result(), self.ctype())
5058 class SizeofNode(ExprNode):
5059 # Abstract base class for sizeof(x) expression nodes.
5061 type = PyrexTypes.c_size_t_type
5063 def check_const(self):
5066 def generate_result_code(self, code):
5070 class SizeofTypeNode(SizeofNode):
5071 # C sizeof function applied to a type
5073 # base_type CBaseTypeNode
5074 # declarator CDeclaratorNode
5079 def analyse_types(self, env):
5080 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5081 # this could be better handled by more uniformly treating types as runtime-available objects
5082 if 0 and self.base_type.module_path:
5083 path = self.base_type.module_path
5084 obj = env.lookup(path[0])
5085 if obj.as_module is None:
5086 operand = NameNode(pos=self.pos, name=path[0])
5087 for attr in path[1:]:
5088 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5089 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5090 self.operand = operand
5091 self.__class__ = SizeofVarNode
5092 self.analyse_types(env)
5094 if self.arg_type is None:
5095 base_type = self.base_type.analyse(env)
5096 _, arg_type = self.declarator.analyse(base_type, env)
5097 self.arg_type = arg_type
5100 def check_type(self):
5101 arg_type = self.arg_type
5102 if arg_type.is_pyobject and not arg_type.is_extension_type:
5103 error(self.pos, "Cannot take sizeof Python object")
5104 elif arg_type.is_void:
5105 error(self.pos, "Cannot take sizeof void")
5106 elif not arg_type.is_complete():
5107 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5109 def calculate_result_code(self):
5110 if self.arg_type.is_extension_type:
5111 # the size of the pointer is boring
5112 # we want the size of the actual struct
5113 arg_code = self.arg_type.declaration_code("", deref=1)
5115 arg_code = self.arg_type.declaration_code("")
5116 return "(sizeof(%s))" % arg_code
5119 class SizeofVarNode(SizeofNode):
5120 # C sizeof function applied to a variable
5124 subexprs = ['operand']
5126 def analyse_types(self, env):
5127 # We may actually be looking at a type rather than a variable...
5128 # If we are, traditional analysis would fail...
5129 operand_as_type = self.operand.analyse_as_type(env)
5131 self.arg_type = operand_as_type
5132 self.__class__ = SizeofTypeNode
5135 self.operand.analyse_types(env)
5137 def calculate_result_code(self):
5138 return "(sizeof(%s))" % self.operand.result()
5140 def generate_result_code(self, code):
5143 class TypeofNode(ExprNode):
5144 # Compile-time type of an expression, as a string.
5147 # literal StringNode # internal
5150 type = py_object_type
5152 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5154 def analyse_types(self, env):
5155 self.operand.analyse_types(env)
5156 self.literal = StringNode(
5157 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5158 self.literal.analyse_types(env)
5159 self.literal = self.literal.coerce_to_pyobject(env)
5161 def may_be_none(self):
5164 def generate_evaluation_code(self, code):
5165 self.literal.generate_evaluation_code(code)
5167 def calculate_result_code(self):
5168 return self.literal.calculate_result_code()
5170 #-------------------------------------------------------------------
5172 # Binary operator nodes
5174 #-------------------------------------------------------------------
5176 def _not_in(x, seq):
5179 compile_time_binary_operators = {
5187 'is_not': operator.is_not,
5190 '/': operator.truediv,
5191 '//': operator.floordiv,
5192 '<<': operator.lshift,
5197 '>>': operator.rshift,
5200 'in': operator.contains,
5204 def get_compile_time_binop(node):
5205 func = compile_time_binary_operators.get(node.operator)
5208 "Binary '%s' not supported in compile-time expression"
5212 class BinopNode(ExprNode):
5217 # Processing during analyse_expressions phase:
5219 # analyse_c_operation
5220 # Called when neither operand is a pyobject.
5221 # - Check operand types and coerce if needed.
5222 # - Determine result type and result code fragment.
5223 # - Allocate temporary for result if needed.
5225 subexprs = ['operand1', 'operand2']
5227 def calculate_constant_result(self):
5228 func = compile_time_binary_operators[self.operator]
5229 self.constant_result = func(
5230 self.operand1.constant_result,
5231 self.operand2.constant_result)
5233 def compile_time_value(self, denv):
5234 func = get_compile_time_binop(self)
5235 operand1 = self.operand1.compile_time_value(denv)
5236 operand2 = self.operand2.compile_time_value(denv)
5238 return func(operand1, operand2)
5239 except Exception, e:
5240 self.compile_time_value_error(e)
5242 def infer_type(self, env):
5243 return self.result_type(self.operand1.infer_type(env),
5244 self.operand2.infer_type(env))
5246 def analyse_types(self, env):
5247 self.operand1.analyse_types(env)
5248 self.operand2.analyse_types(env)
5249 if self.is_py_operation():
5250 self.coerce_operands_to_pyobjects(env)
5251 self.type = self.result_type(self.operand1.type,
5253 assert self.type.is_pyobject
5255 elif self.is_cpp_operation():
5256 self.analyse_cpp_operation(env)
5258 self.analyse_c_operation(env)
5260 def is_py_operation(self):
5261 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5263 def is_py_operation_types(self, type1, type2):
5264 return type1.is_pyobject or type2.is_pyobject
5266 def is_cpp_operation(self):
5267 return (self.operand1.type.is_cpp_class
5268 or self.operand2.type.is_cpp_class)
5270 def analyse_cpp_operation(self, env):
5271 type1 = self.operand1.type
5272 type2 = self.operand2.type
5273 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5277 func_type = entry.type
5278 if func_type.is_ptr:
5279 func_type = func_type.base_type
5280 if len(func_type.args) == 1:
5281 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5283 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5284 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5285 self.type = func_type.return_type
5287 def result_type(self, type1, type2):
5288 if self.is_py_operation_types(type1, type2):
5290 type2 = Builtin.bytes_type
5292 type1 = Builtin.bytes_type
5293 elif self.operator == '%' \
5294 and type1 in (Builtin.str_type, Builtin.unicode_type):
5295 # note that b'%s' % b'abc' doesn't work in Py3
5297 if type1.is_builtin_type:
5299 if self.operator in '**%+|&^':
5300 # FIXME: at least these operators should be safe - others?
5302 elif self.operator == '*':
5303 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5305 # multiplication of containers/numbers with an
5306 # integer value always (?) returns the same type
5309 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5310 # multiplication of containers/numbers with an
5311 # integer value always (?) returns the same type
5313 return py_object_type
5315 return self.compute_c_result_type(type1, type2)
5317 def nogil_check(self, env):
5318 if self.is_py_operation():
5321 def coerce_operands_to_pyobjects(self, env):
5322 self.operand1 = self.operand1.coerce_to_pyobject(env)
5323 self.operand2 = self.operand2.coerce_to_pyobject(env)
5325 def check_const(self):
5326 return self.operand1.check_const() and self.operand2.check_const()
5328 def generate_result_code(self, code):
5329 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5330 if self.operand1.type.is_pyobject:
5331 function = self.py_operation_function()
5332 if function == "PyNumber_Power":
5333 extra_args = ", Py_None"
5337 "%s = %s(%s, %s%s); %s" % (
5340 self.operand1.py_result(),
5341 self.operand2.py_result(),
5343 code.error_goto_if_null(self.result(), self.pos)))
5344 code.put_gotref(self.py_result())
5346 def type_error(self):
5347 if not (self.operand1.type.is_error
5348 or self.operand2.type.is_error):
5349 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5350 (self.operator, self.operand1.type,
5351 self.operand2.type))
5352 self.type = PyrexTypes.error_type
5355 class CBinopNode(BinopNode):
5357 def analyse_types(self, env):
5358 BinopNode.analyse_types(self, env)
5359 if self.is_py_operation():
5360 self.type = PyrexTypes.error_type
5362 def py_operation_function():
5365 def calculate_result_code(self):
5366 return "(%s %s %s)" % (
5367 self.operand1.result(),
5369 self.operand2.result())
5372 def c_binop_constructor(operator):
5373 def make_binop_node(pos, **operands):
5374 return CBinopNode(pos, operator=operator, **operands)
5375 return make_binop_node
5377 class NumBinopNode(BinopNode):
5378 # Binary operation taking numeric arguments.
5382 def analyse_c_operation(self, env):
5383 type1 = self.operand1.type
5384 type2 = self.operand2.type
5385 self.type = self.compute_c_result_type(type1, type2)
5389 if self.type.is_complex:
5391 if not self.infix or (type1.is_numeric and type2.is_numeric):
5392 self.operand1 = self.operand1.coerce_to(self.type, env)
5393 self.operand2 = self.operand2.coerce_to(self.type, env)
5395 def compute_c_result_type(self, type1, type2):
5396 if self.c_types_okay(type1, type2):
5397 return PyrexTypes.widest_numeric_type(type1, type2)
5401 def get_constant_c_result_code(self):
5402 value1 = self.operand1.get_constant_c_result_code()
5403 value2 = self.operand2.get_constant_c_result_code()
5404 if value1 and value2:
5405 return "(%s %s %s)" % (value1, self.operator, value2)
5409 def c_types_okay(self, type1, type2):
5410 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5411 return (type1.is_numeric or type1.is_enum) \
5412 and (type2.is_numeric or type2.is_enum)
5414 def calculate_result_code(self):
5416 return "(%s %s %s)" % (
5417 self.operand1.result(),
5419 self.operand2.result())
5421 func = self.type.binary_op(self.operator)
5423 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5424 return "%s(%s, %s)" % (
5426 self.operand1.result(),
5427 self.operand2.result())
5429 def is_py_operation_types(self, type1, type2):
5430 return (type1 is PyrexTypes.c_py_unicode_type or
5431 type2 is PyrexTypes.c_py_unicode_type or
5432 BinopNode.is_py_operation_types(self, type1, type2))
5434 def py_operation_function(self):
5435 return self.py_functions[self.operator]
5439 "^": "PyNumber_Xor",
5440 "&": "PyNumber_And",
5441 "<<": "PyNumber_Lshift",
5442 ">>": "PyNumber_Rshift",
5443 "+": "PyNumber_Add",
5444 "-": "PyNumber_Subtract",
5445 "*": "PyNumber_Multiply",
5446 "/": "__Pyx_PyNumber_Divide",
5447 "//": "PyNumber_FloorDivide",
5448 "%": "PyNumber_Remainder",
5449 "**": "PyNumber_Power"
5453 class IntBinopNode(NumBinopNode):
5454 # Binary operation taking integer arguments.
5456 def c_types_okay(self, type1, type2):
5457 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5458 return (type1.is_int or type1.is_enum) \
5459 and (type2.is_int or type2.is_enum)
5462 class AddNode(NumBinopNode):
5465 def is_py_operation_types(self, type1, type2):
5466 if type1.is_string and type2.is_string:
5469 return NumBinopNode.is_py_operation_types(self, type1, type2)
5471 def compute_c_result_type(self, type1, type2):
5472 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5473 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5475 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5478 return NumBinopNode.compute_c_result_type(
5482 class SubNode(NumBinopNode):
5485 def compute_c_result_type(self, type1, type2):
5486 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5488 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5489 return PyrexTypes.c_int_type
5491 return NumBinopNode.compute_c_result_type(
5495 class MulNode(NumBinopNode):
5498 def is_py_operation_types(self, type1, type2):
5499 if (type1.is_string and type2.is_int) \
5500 or (type2.is_string and type1.is_int):
5503 return NumBinopNode.is_py_operation_types(self, type1, type2)
5506 class DivNode(NumBinopNode):
5507 # '/' or '//' operator.
5510 truedivision = None # == "unknown" if operator == '/'
5511 ctruedivision = False
5512 cdivision_warnings = False
5513 zerodivision_check = None
5515 def find_compile_time_binary_operator(self, op1, op2):
5516 func = compile_time_binary_operators[self.operator]
5517 if self.operator == '/' and self.truedivision is None:
5518 # => true div for floats, floor div for integers
5519 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5520 func = compile_time_binary_operators['//']
5523 def calculate_constant_result(self):
5524 op1 = self.operand1.constant_result
5525 op2 = self.operand2.constant_result
5526 func = self.find_compile_time_binary_operator(op1, op2)
5527 self.constant_result = func(
5528 self.operand1.constant_result,
5529 self.operand2.constant_result)
5531 def compile_time_value(self, denv):
5532 operand1 = self.operand1.compile_time_value(denv)
5533 operand2 = self.operand2.compile_time_value(denv)
5535 func = self.find_compile_time_binary_operator(
5536 self, operand1, operand2)
5537 return func(operand1, operand2)
5538 except Exception, e:
5539 self.compile_time_value_error(e)
5541 def analyse_types(self, env):
5542 if self.cdivision or env.directives['cdivision']:
5543 self.ctruedivision = False
5545 self.ctruedivision = self.truedivision
5546 NumBinopNode.analyse_types(self, env)
5547 if self.is_cpp_operation():
5548 self.cdivision = True
5549 if not self.type.is_pyobject:
5550 self.zerodivision_check = (
5551 self.cdivision is None and not env.directives['cdivision']
5552 and (not self.operand2.has_constant_result() or
5553 self.operand2.constant_result == 0))
5554 if self.zerodivision_check or env.directives['cdivision_warnings']:
5555 # Need to check ahead of time to warn or raise zero division error
5556 self.operand1 = self.operand1.coerce_to_simple(env)
5557 self.operand2 = self.operand2.coerce_to_simple(env)
5559 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5561 def compute_c_result_type(self, type1, type2):
5562 if self.operator == '/' and self.ctruedivision:
5563 if not type1.is_float and not type2.is_float:
5564 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5565 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5567 return NumBinopNode.compute_c_result_type(self, type1, type2)
5569 def zero_division_message(self):
5570 if self.type.is_int:
5571 return "integer division or modulo by zero"
5573 return "float division"
5575 def generate_evaluation_code(self, code):
5576 if not self.type.is_pyobject and not self.type.is_complex:
5577 if self.cdivision is None:
5578 self.cdivision = (code.globalstate.directives['cdivision']
5579 or not self.type.signed
5580 or self.type.is_float)
5581 if not self.cdivision:
5582 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5583 NumBinopNode.generate_evaluation_code(self, code)
5584 self.generate_div_warning_code(code)
5586 def generate_div_warning_code(self, code):
5587 if not self.type.is_pyobject:
5588 if self.zerodivision_check:
5590 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5592 zero_test = "%s == 0" % self.operand2.result()
5593 code.putln("if (unlikely(%s)) {" % zero_test)
5594 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
5595 code.putln(code.error_goto(self.pos))
5597 if self.type.is_int and self.type.signed and self.operator != '%':
5598 code.globalstate.use_utility_code(division_overflow_test_code)
5599 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
5600 self.type.declaration_code(''),
5601 self.operand2.result(),
5602 self.operand1.result()))
5603 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
5604 code.putln(code.error_goto(self.pos))
5606 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
5607 code.globalstate.use_utility_code(cdivision_warning_utility_code)
5608 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
5609 self.operand1.result(),
5610 self.operand2.result()))
5611 code.putln(code.set_error_info(self.pos));
5612 code.put("if (__Pyx_cdivision_warning()) ")
5613 code.put_goto(code.error_label)
5616 def calculate_result_code(self):
5617 if self.type.is_complex:
5618 return NumBinopNode.calculate_result_code(self)
5619 elif self.type.is_float and self.operator == '//':
5620 return "floor(%s / %s)" % (
5621 self.operand1.result(),
5622 self.operand2.result())
5623 elif self.truedivision or self.cdivision:
5624 op1 = self.operand1.result()
5625 op2 = self.operand2.result()
5626 if self.truedivision:
5627 if self.type != self.operand1.type:
5628 op1 = self.type.cast_code(op1)
5629 if self.type != self.operand2.type:
5630 op2 = self.type.cast_code(op2)
5631 return "(%s / %s)" % (op1, op2)
5633 return "__Pyx_div_%s(%s, %s)" % (
5634 self.type.specialization_name(),
5635 self.operand1.result(),
5636 self.operand2.result())
5639 class ModNode(DivNode):
5642 def is_py_operation_types(self, type1, type2):
5643 return (type1.is_string
5645 or NumBinopNode.is_py_operation_types(self, type1, type2))
5647 def zero_division_message(self):
5648 if self.type.is_int:
5649 return "integer division or modulo by zero"
5651 return "float divmod()"
5653 def generate_evaluation_code(self, code):
5654 if not self.type.is_pyobject:
5655 if self.cdivision is None:
5656 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
5657 if not self.cdivision:
5658 if self.type.is_int:
5659 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
5661 code.globalstate.use_utility_code(
5662 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
5663 NumBinopNode.generate_evaluation_code(self, code)
5664 self.generate_div_warning_code(code)
5666 def calculate_result_code(self):
5668 if self.type.is_float:
5669 return "fmod%s(%s, %s)" % (
5670 self.type.math_h_modifier,
5671 self.operand1.result(),
5672 self.operand2.result())
5674 return "(%s %% %s)" % (
5675 self.operand1.result(),
5676 self.operand2.result())
5678 return "__Pyx_mod_%s(%s, %s)" % (
5679 self.type.specialization_name(),
5680 self.operand1.result(),
5681 self.operand2.result())
5683 class PowNode(NumBinopNode):
5686 def analyse_c_operation(self, env):
5687 NumBinopNode.analyse_c_operation(self, env)
5688 if self.type.is_complex:
5689 if self.type.real_type.is_float:
5690 self.operand1 = self.operand1.coerce_to(self.type, env)
5691 self.operand2 = self.operand2.coerce_to(self.type, env)
5692 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
5694 error(self.pos, "complex int powers not supported")
5695 self.pow_func = "<error>"
5696 elif self.type.is_float:
5697 self.pow_func = "pow" + self.type.math_h_modifier
5699 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
5700 env.use_utility_code(
5701 int_pow_utility_code.specialize(func_name=self.pow_func,
5702 type=self.type.declaration_code('')))
5704 def calculate_result_code(self):
5705 # Work around MSVC overloading ambiguity.
5706 def typecast(operand):
5707 if self.type == operand.type:
5708 return operand.result()
5710 return self.type.cast_code(operand.result())
5711 return "%s(%s, %s)" % (
5713 typecast(self.operand1),
5714 typecast(self.operand2))
5717 # Note: This class is temporarily "shut down" into an ineffective temp
5720 # More sophisticated temp reuse was going on before, one could have a
5721 # look at adding this again after /all/ classes are converted to the
5722 # new temp scheme. (The temp juggling cannot work otherwise).
5723 class BoolBinopNode(ExprNode):
5724 # Short-circuiting boolean operation.
5730 subexprs = ['operand1', 'operand2']
5732 def infer_type(self, env):
5733 type1 = self.operand1.infer_type(env)
5734 type2 = self.operand2.infer_type(env)
5735 return PyrexTypes.independent_spanning_type(type1, type2)
5737 def may_be_none(self):
5738 if self.operator == 'or':
5739 return self.operand2.may_be_none()
5741 return self.operand1.may_be_none() or self.operand2.may_be_none()
5743 def calculate_constant_result(self):
5744 if self.operator == 'and':
5745 self.constant_result = \
5746 self.operand1.constant_result and \
5747 self.operand2.constant_result
5749 self.constant_result = \
5750 self.operand1.constant_result or \
5751 self.operand2.constant_result
5753 def compile_time_value(self, denv):
5754 if self.operator == 'and':
5755 return self.operand1.compile_time_value(denv) \
5756 and self.operand2.compile_time_value(denv)
5758 return self.operand1.compile_time_value(denv) \
5759 or self.operand2.compile_time_value(denv)
5761 def coerce_to_boolean(self, env):
5762 return BoolBinopNode(
5764 operator = self.operator,
5765 operand1 = self.operand1.coerce_to_boolean(env),
5766 operand2 = self.operand2.coerce_to_boolean(env),
5767 type = PyrexTypes.c_bint_type,
5768 is_temp = self.is_temp)
5770 def analyse_types(self, env):
5771 self.operand1.analyse_types(env)
5772 self.operand2.analyse_types(env)
5773 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
5774 self.operand1 = self.operand1.coerce_to(self.type, env)
5775 self.operand2 = self.operand2.coerce_to(self.type, env)
5777 # For what we're about to do, it's vital that
5778 # both operands be temp nodes.
5779 self.operand1 = self.operand1.coerce_to_simple(env)
5780 self.operand2 = self.operand2.coerce_to_simple(env)
5783 gil_message = "Truth-testing Python object"
5785 def check_const(self):
5786 return self.operand1.check_const() and self.operand2.check_const()
5788 def generate_evaluation_code(self, code):
5789 code.mark_pos(self.pos)
5790 self.operand1.generate_evaluation_code(code)
5791 test_result, uses_temp = self.generate_operand1_test(code)
5792 if self.operator == 'and':
5801 code.funcstate.release_temp(test_result)
5802 self.operand1.generate_disposal_code(code)
5803 self.operand2.generate_evaluation_code(code)
5804 self.allocate_temp_result(code)
5805 self.operand2.make_owned_reference(code)
5806 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
5807 self.operand2.generate_post_assignment_code(code)
5808 self.operand2.free_temps(code)
5809 code.putln("} else {")
5810 self.operand1.make_owned_reference(code)
5811 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
5812 self.operand1.generate_post_assignment_code(code)
5813 self.operand1.free_temps(code)
5816 def generate_operand1_test(self, code):
5817 # Generate code to test the truth of the first operand.
5818 if self.type.is_pyobject:
5819 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
5822 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5824 self.operand1.py_result(),
5825 code.error_goto_if_neg(test_result, self.pos)))
5827 test_result = self.operand1.result()
5828 return (test_result, self.type.is_pyobject)
5831 class CondExprNode(ExprNode):
5832 # Short-circuiting conditional expression.
5836 # false_val ExprNode
5841 subexprs = ['test', 'true_val', 'false_val']
5843 def type_dependencies(self, env):
5844 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
5846 def infer_type(self, env):
5847 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
5848 self.false_val.infer_type(env))
5850 def calculate_constant_result(self):
5851 if self.test.constant_result:
5852 self.constant_result = self.true_val.constant_result
5854 self.constant_result = self.false_val.constant_result
5856 def analyse_types(self, env):
5857 self.test.analyse_types(env)
5858 self.test = self.test.coerce_to_boolean(env)
5859 self.true_val.analyse_types(env)
5860 self.false_val.analyse_types(env)
5861 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
5862 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
5863 self.true_val = self.true_val.coerce_to(self.type, env)
5864 self.false_val = self.false_val.coerce_to(self.type, env)
5866 if self.type == PyrexTypes.error_type:
5869 def type_error(self):
5870 if not (self.true_val.type.is_error or self.false_val.type.is_error):
5871 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
5872 (self.true_val.type, self.false_val.type))
5873 self.type = PyrexTypes.error_type
5875 def check_const(self):
5876 return (self.test.check_const()
5877 and self.true_val.check_const()
5878 and self.false_val.check_const())
5880 def generate_evaluation_code(self, code):
5881 # Because subexprs may not be evaluated we can use a more optimal
5882 # subexpr allocation strategy than the default, so override evaluation_code.
5884 code.mark_pos(self.pos)
5885 self.allocate_temp_result(code)
5886 self.test.generate_evaluation_code(code)
5887 code.putln("if (%s) {" % self.test.result() )
5888 self.eval_and_get(code, self.true_val)
5889 code.putln("} else {")
5890 self.eval_and_get(code, self.false_val)
5892 self.test.generate_disposal_code(code)
5893 self.test.free_temps(code)
5895 def eval_and_get(self, code, expr):
5896 expr.generate_evaluation_code(code)
5897 expr.make_owned_reference(code)
5898 code.putln("%s = %s;" % (self.result(), expr.result()))
5899 expr.generate_post_assignment_code(code)
5900 expr.free_temps(code)
5902 richcmp_constants = {
5912 class CmpNode(object):
5913 # Mixin class containing code common to PrimaryCmpNodes
5914 # and CascadedCmpNodes.
5916 def infer_type(self, env):
5917 # TODO: Actually implement this (after merging with -unstable).
5918 return py_object_type
5920 def calculate_cascaded_constant_result(self, operand1_result):
5921 func = compile_time_binary_operators[self.operator]
5922 operand2_result = self.operand2.constant_result
5923 result = func(operand1_result, operand2_result)
5925 self.cascade.calculate_cascaded_constant_result(operand2_result)
5926 if self.cascade.constant_result:
5927 self.constant_result = result and self.cascade.constant_result
5929 self.constant_result = result
5931 def cascaded_compile_time_value(self, operand1, denv):
5932 func = get_compile_time_binop(self)
5933 operand2 = self.operand2.compile_time_value(denv)
5935 result = func(operand1, operand2)
5936 except Exception, e:
5937 self.compile_time_value_error(e)
5940 cascade = self.cascade
5942 # FIXME: I bet this must call cascaded_compile_time_value()
5943 result = result and cascade.cascaded_compile_time_value(operand2, denv)
5946 def is_cpp_comparison(self):
5947 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
5949 def find_common_int_type(self, env, op, operand1, operand2):
5950 # type1 != type2 and at least one of the types is not a C int
5951 type1 = operand1.type
5952 type2 = operand2.type
5953 type1_can_be_int = False
5954 type2_can_be_int = False
5956 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
5957 and operand1.can_coerce_to_char_literal():
5958 type1_can_be_int = True
5959 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
5960 and operand2.can_coerce_to_char_literal():
5961 type2_can_be_int = True
5964 if type2_can_be_int:
5967 if type1_can_be_int:
5969 elif type1_can_be_int:
5970 if type2_can_be_int:
5971 return PyrexTypes.c_uchar_type
5975 def find_common_type(self, env, op, operand1, common_type=None):
5976 operand2 = self.operand2
5977 type1 = operand1.type
5978 type2 = operand2.type
5980 new_common_type = None
5982 # catch general errors
5983 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
5984 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
5985 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
5986 new_common_type = error_type
5988 # try to use numeric comparisons where possible
5989 elif type1.is_complex or type2.is_complex:
5990 if op not in ('==', '!='):
5991 error(self.pos, "complex types are unordered")
5992 new_common_type = error_type
5993 if type1.is_pyobject:
5994 new_common_type = type1
5995 elif type2.is_pyobject:
5996 new_common_type = type2
5998 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
5999 elif type1.is_numeric and type2.is_numeric:
6000 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6001 elif common_type is None or not common_type.is_pyobject:
6002 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6004 if new_common_type is None:
6005 # fall back to generic type compatibility tests
6007 new_common_type = type1
6008 elif type1.is_pyobject or type2.is_pyobject:
6009 if type2.is_numeric or type2.is_string:
6010 if operand2.check_for_coercion_error(type1):
6011 new_common_type = error_type
6013 new_common_type = py_object_type
6014 elif type1.is_numeric or type1.is_string:
6015 if operand1.check_for_coercion_error(type2):
6016 new_common_type = error_type
6018 new_common_type = py_object_type
6019 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6020 new_common_type = py_object_type
6022 # one Python type and one non-Python type, not assignable
6023 self.invalid_types_error(operand1, op, operand2)
6024 new_common_type = error_type
6025 elif type1.assignable_from(type2):
6026 new_common_type = type1
6027 elif type2.assignable_from(type1):
6028 new_common_type = type2
6030 # C types that we couldn't handle up to here are an error
6031 self.invalid_types_error(operand1, op, operand2)
6032 new_common_type = error_type
6034 # recursively merge types
6035 if common_type is None or new_common_type.is_error:
6036 common_type = new_common_type
6038 # we could do a lot better by splitting the comparison
6039 # into a non-Python part and a Python part, but this is
6041 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6044 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6048 def invalid_types_error(self, operand1, op, operand2):
6049 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6050 (op, operand1.type, operand2.type))
6052 def is_python_comparison(self):
6053 return (not self.is_ptr_contains()
6054 and not self.is_c_string_contains()
6055 and (self.has_python_operands()
6056 or (self.cascade and self.cascade.is_python_comparison())
6057 or self.operator in ('in', 'not_in')))
6059 def coerce_operands_to(self, dst_type, env):
6060 operand2 = self.operand2
6061 if operand2.type != dst_type:
6062 self.operand2 = operand2.coerce_to(dst_type, env)
6064 self.cascade.coerce_operands_to(dst_type, env)
6066 def is_python_result(self):
6067 return ((self.has_python_operands() and
6068 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6069 not self.is_c_string_contains() and
6070 not self.is_ptr_contains())
6071 or (self.cascade and self.cascade.is_python_result()))
6073 def is_c_string_contains(self):
6074 return self.operator in ('in', 'not_in') and \
6075 ((self.operand1.type.is_int
6076 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6077 (self.operand1.type is PyrexTypes.c_py_unicode_type
6078 and self.operand2.type is unicode_type))
6080 def is_ptr_contains(self):
6081 if self.operator in ('in', 'not_in'):
6082 container_type = self.operand2.type
6083 return (container_type.is_ptr or container_type.is_array) \
6084 and not container_type.is_string
6086 def generate_operation_code(self, code, result_code,
6087 operand1, op , operand2):
6088 if self.type.is_pyobject:
6089 coerce_result = "__Pyx_PyBool_FromLong"
6096 if op == 'in' or op == 'not_in':
6097 code.globalstate.use_utility_code(contains_utility_code)
6098 if self.type.is_pyobject:
6099 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6101 negation = "__Pyx_NegateNonNeg"
6102 if operand2.type is dict_type:
6103 code.globalstate.use_utility_code(
6104 raise_none_iter_error_utility_code)
6105 code.putln("if (unlikely(%s == Py_None)) {" % operand2.py_result())
6106 code.putln("__Pyx_RaiseNoneNotIterableError(); %s" %
6107 code.error_goto(self.pos))
6108 code.putln("} else {")
6109 method = "PyDict_Contains"
6111 method = "PySequence_Contains"
6112 if self.type.is_pyobject:
6113 error_clause = code.error_goto_if_null
6114 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6116 error_clause = code.error_goto_if_neg
6119 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6124 operand2.py_result(),
6125 operand1.py_result(),
6127 error_clause(result_code, self.pos)))
6128 if operand2.type is dict_type:
6131 elif (operand1.type.is_pyobject
6132 and op not in ('is', 'is_not')):
6133 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6135 operand1.py_result(),
6136 operand2.py_result(),
6137 richcmp_constants[op],
6138 code.error_goto_if_null(result_code, self.pos)))
6139 code.put_gotref(result_code)
6140 elif operand1.type.is_complex:
6145 code.putln("%s = %s(%s%s(%s, %s));" % (
6149 operand1.type.unary_op('eq'),
6153 type1 = operand1.type
6154 type2 = operand2.type
6155 if (type1.is_extension_type or type2.is_extension_type) \
6156 and not type1.same_as(type2):
6157 common_type = py_object_type
6158 elif type1.is_numeric:
6159 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6162 code1 = operand1.result_as(common_type)
6163 code2 = operand2.result_as(common_type)
6164 code.putln("%s = %s(%s %s %s);" % (
6168 self.c_operator(op),
6171 def c_operator(self, op):
6174 elif op == 'is_not':
6179 contains_utility_code = UtilityCode(
6181 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6182 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6183 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6187 char_in_bytes_utility_code = UtilityCode(
6189 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6192 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6193 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6194 char* char_start = PyBytes_AS_STRING(bytes);
6196 for (pos=char_start; pos < char_start+length; pos++) {
6197 if (character == pos[0]) return 1;
6203 pyunicode_in_unicode_utility_code = UtilityCode(
6205 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6208 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6209 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6210 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6212 for (pos=char_start; pos < char_start+length; pos++) {
6213 if (character == pos[0]) return 1;
6220 class PrimaryCmpNode(ExprNode, CmpNode):
6221 # Non-cascaded comparison or first comparison of
6222 # a cascaded sequence.
6227 # cascade CascadedCmpNode
6229 # We don't use the subexprs mechanism, because
6230 # things here are too complicated for it to handle.
6231 # Instead, we override all the framework methods
6234 child_attrs = ['operand1', 'operand2', 'cascade']
6238 def infer_type(self, env):
6239 # TODO: Actually implement this (after merging with -unstable).
6240 return py_object_type
6242 def type_dependencies(self, env):
6245 def calculate_constant_result(self):
6246 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6248 def compile_time_value(self, denv):
6249 operand1 = self.operand1.compile_time_value(denv)
6250 return self.cascaded_compile_time_value(operand1, denv)
6252 def analyse_types(self, env):
6253 self.operand1.analyse_types(env)
6254 self.operand2.analyse_types(env)
6255 if self.is_cpp_comparison():
6256 self.analyse_cpp_comparison(env)
6258 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6261 self.cascade.analyse_types(env)
6263 if self.operator in ('in', 'not_in'):
6264 if self.is_c_string_contains():
6265 self.is_pycmp = False
6268 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6270 if self.operand2.type is unicode_type:
6271 env.use_utility_code(pyunicode_in_unicode_utility_code)
6273 if self.operand1.type is PyrexTypes.c_uchar_type:
6274 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6275 if self.operand2.type is not bytes_type:
6276 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6277 env.use_utility_code(char_in_bytes_utility_code)
6278 self.operand2 = self.operand2.as_none_safe_node(
6279 "argument of type 'NoneType' is not iterable")
6280 elif self.is_ptr_contains():
6282 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6283 self.type = PyrexTypes.c_bint_type
6284 # Will be transformed by IterationTransform
6287 common_type = py_object_type
6288 self.is_pycmp = True
6290 common_type = self.find_common_type(env, self.operator, self.operand1)
6291 self.is_pycmp = common_type.is_pyobject
6293 if common_type is not None and not common_type.is_error:
6294 if self.operand1.type != common_type:
6295 self.operand1 = self.operand1.coerce_to(common_type, env)
6296 self.coerce_operands_to(common_type, env)
6299 self.operand2 = self.operand2.coerce_to_simple(env)
6300 self.cascade.coerce_cascaded_operands_to_temp(env)
6301 if self.is_python_result():
6302 self.type = PyrexTypes.py_object_type
6304 self.type = PyrexTypes.c_bint_type
6307 cdr.type = self.type
6309 if self.is_pycmp or self.cascade:
6312 def analyse_cpp_comparison(self, env):
6313 type1 = self.operand1.type
6314 type2 = self.operand2.type
6315 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6317 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6318 (self.operator, type1, type2))
6319 self.type = PyrexTypes.error_type
6320 self.result_code = "<error>"
6322 func_type = entry.type
6323 if func_type.is_ptr:
6324 func_type = func_type.base_type
6325 if len(func_type.args) == 1:
6326 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6328 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6329 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6330 self.type = func_type.return_type
6332 def has_python_operands(self):
6333 return (self.operand1.type.is_pyobject
6334 or self.operand2.type.is_pyobject)
6336 def check_const(self):
6341 return self.operand1.check_const() and self.operand2.check_const()
6343 def calculate_result_code(self):
6344 if self.operand1.type.is_complex:
6345 if self.operator == "!=":
6349 return "(%s%s(%s, %s))" % (
6351 self.operand1.type.binary_op('=='),
6352 self.operand1.result(),
6353 self.operand2.result())
6354 elif self.is_c_string_contains():
6355 if self.operand2.type is bytes_type:
6356 method = "__Pyx_BytesContains"
6358 method = "__Pyx_UnicodeContains"
6359 if self.operator == "not_in":
6363 return "(%s%s(%s, %s))" % (
6366 self.operand2.result(),
6367 self.operand1.result())
6369 return "(%s %s %s)" % (
6370 self.operand1.result(),
6371 self.c_operator(self.operator),
6372 self.operand2.result())
6374 def generate_evaluation_code(self, code):
6375 self.operand1.generate_evaluation_code(code)
6376 self.operand2.generate_evaluation_code(code)
6378 self.allocate_temp_result(code)
6379 self.generate_operation_code(code, self.result(),
6380 self.operand1, self.operator, self.operand2)
6382 self.cascade.generate_evaluation_code(code,
6383 self.result(), self.operand2)
6384 self.operand1.generate_disposal_code(code)
6385 self.operand1.free_temps(code)
6386 self.operand2.generate_disposal_code(code)
6387 self.operand2.free_temps(code)
6389 def generate_subexpr_disposal_code(self, code):
6390 # If this is called, it is a non-cascaded cmp,
6391 # so only need to dispose of the two main operands.
6392 self.operand1.generate_disposal_code(code)
6393 self.operand2.generate_disposal_code(code)
6395 def free_subexpr_temps(self, code):
6396 # If this is called, it is a non-cascaded cmp,
6397 # so only need to dispose of the two main operands.
6398 self.operand1.free_temps(code)
6399 self.operand2.free_temps(code)
6401 def annotate(self, code):
6402 self.operand1.annotate(code)
6403 self.operand2.annotate(code)
6405 self.cascade.annotate(code)
6408 class CascadedCmpNode(Node, CmpNode):
6409 # A CascadedCmpNode is not a complete expression node. It
6410 # hangs off the side of another comparison node, shares
6411 # its left operand with that node, and shares its result
6412 # with the PrimaryCmpNode at the head of the chain.
6416 # cascade CascadedCmpNode
6418 child_attrs = ['operand2', 'cascade']
6421 constant_result = constant_value_not_set # FIXME: where to calculate this?
6423 def infer_type(self, env):
6424 # TODO: Actually implement this (after merging with -unstable).
6425 return py_object_type
6427 def type_dependencies(self, env):
6430 def has_constant_result(self):
6431 return self.constant_result is not constant_value_not_set and \
6432 self.constant_result is not not_a_constant
6434 def analyse_types(self, env):
6435 self.operand2.analyse_types(env)
6437 self.cascade.analyse_types(env)
6439 def has_python_operands(self):
6440 return self.operand2.type.is_pyobject
6442 def coerce_operands_to_pyobjects(self, env):
6443 self.operand2 = self.operand2.coerce_to_pyobject(env)
6445 self.cascade.coerce_operands_to_pyobjects(env)
6447 def coerce_cascaded_operands_to_temp(self, env):
6449 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6450 self.operand2 = self.operand2.coerce_to_simple(env)
6451 self.cascade.coerce_cascaded_operands_to_temp(env)
6453 def generate_evaluation_code(self, code, result, operand1):
6454 if self.type.is_pyobject:
6455 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
6456 code.put_decref(result, self.type)
6458 code.putln("if (%s) {" % result)
6459 self.operand2.generate_evaluation_code(code)
6460 self.generate_operation_code(code, result,
6461 operand1, self.operator, self.operand2)
6463 self.cascade.generate_evaluation_code(
6464 code, result, self.operand2)
6465 # Cascaded cmp result is always temp
6466 self.operand2.generate_disposal_code(code)
6467 self.operand2.free_temps(code)
6470 def annotate(self, code):
6471 self.operand2.annotate(code)
6473 self.cascade.annotate(code)
6476 binop_node_classes = {
6477 "or": BoolBinopNode,
6478 "and": BoolBinopNode,
6493 def binop_node(pos, operator, operand1, operand2):
6494 # Construct binop node of appropriate class for
6496 return binop_node_classes[operator](pos,
6497 operator = operator,
6498 operand1 = operand1,
6499 operand2 = operand2)
6501 #-------------------------------------------------------------------
6505 # Coercion nodes are special in that they are created during
6506 # the analyse_types phase of parse tree processing.
6507 # Their __init__ methods consequently incorporate some aspects
6510 #-------------------------------------------------------------------
6512 class CoercionNode(ExprNode):
6513 # Abstract base class for coercion nodes.
6515 # arg ExprNode node being coerced
6518 constant_result = not_a_constant
6520 def __init__(self, arg):
6524 print("%s Coercing %s" % (self, self.arg))
6526 def calculate_constant_result(self):
6527 # constant folding can break type coercion, so this is disabled
6530 def annotate(self, code):
6531 self.arg.annotate(code)
6532 if self.arg.type != self.type:
6533 file, line, col = self.pos
6534 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
6537 class CastNode(CoercionNode):
6538 # Wrap a node in a C type cast.
6540 def __init__(self, arg, new_type):
6541 CoercionNode.__init__(self, arg)
6542 self.type = new_type
6544 def may_be_none(self):
6545 return self.arg.may_be_none()
6547 def calculate_result_code(self):
6548 return self.arg.result_as(self.type)
6550 def generate_result_code(self, code):
6551 self.arg.generate_result_code(code)
6554 class PyTypeTestNode(CoercionNode):
6555 # This node is used to check that a generic Python
6556 # object is an instance of a particular extension type.
6557 # This node borrows the result of its argument node.
6559 def __init__(self, arg, dst_type, env, notnone=False):
6560 # The arg is know to be a Python object, and
6561 # the dst_type is known to be an extension type.
6562 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
6563 CoercionNode.__init__(self, arg)
6564 self.type = dst_type
6565 self.result_ctype = arg.ctype()
6566 self.notnone = notnone
6568 nogil_check = Node.gil_error
6569 gil_message = "Python type test"
6571 def analyse_types(self, env):
6574 def may_be_none(self):
6577 return self.arg.may_be_none()
6579 def result_in_temp(self):
6580 return self.arg.result_in_temp()
6582 def is_ephemeral(self):
6583 return self.arg.is_ephemeral()
6585 def calculate_constant_result(self):
6589 def calculate_result_code(self):
6590 return self.arg.result()
6592 def generate_result_code(self, code):
6593 if self.type.typeobj_is_available():
6594 if not self.type.is_builtin_type:
6595 code.globalstate.use_utility_code(type_test_utility_code)
6598 self.type.type_test_code(self.arg.py_result(), self.notnone),
6599 code.error_goto(self.pos)))
6601 error(self.pos, "Cannot test type of extern C class "
6602 "without type object name specification")
6604 def generate_post_assignment_code(self, code):
6605 self.arg.generate_post_assignment_code(code)
6607 def free_temps(self, code):
6608 self.arg.free_temps(code)
6611 class NoneCheckNode(CoercionNode):
6612 # This node is used to check that a Python object is not None and
6613 # raises an appropriate exception (as specified by the creating
6616 def __init__(self, arg, exception_type_cname, exception_message):
6617 CoercionNode.__init__(self, arg)
6618 self.type = arg.type
6619 self.result_ctype = arg.ctype()
6620 self.exception_type_cname = exception_type_cname
6621 self.exception_message = exception_message
6623 def analyse_types(self, env):
6626 def may_be_none(self):
6629 def result_in_temp(self):
6630 return self.arg.result_in_temp()
6632 def calculate_result_code(self):
6633 return self.arg.result()
6635 def generate_result_code(self, code):
6637 "if (unlikely(%s == Py_None)) {" % self.arg.result())
6638 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
6639 self.exception_type_cname,
6640 StringEncoding.escape_byte_string(
6641 self.exception_message.encode('UTF-8')),
6642 code.error_goto(self.pos)))
6645 def generate_post_assignment_code(self, code):
6646 self.arg.generate_post_assignment_code(code)
6648 def free_temps(self, code):
6649 self.arg.free_temps(code)
6652 class CoerceToPyTypeNode(CoercionNode):
6653 # This node is used to convert a C data type
6654 # to a Python object.
6656 type = py_object_type
6659 def __init__(self, arg, env, type=py_object_type):
6660 CoercionNode.__init__(self, arg)
6661 if not arg.type.create_to_py_utility_code(env):
6663 "Cannot convert '%s' to Python object" % arg.type)
6664 if type is not py_object_type:
6665 self.type = py_object_type
6666 elif arg.type.is_string:
6667 self.type = bytes_type
6668 elif arg.type is PyrexTypes.c_py_unicode_type:
6669 self.type = unicode_type
6671 gil_message = "Converting to Python object"
6673 def may_be_none(self):
6674 # FIXME: is this always safe?
6677 def coerce_to_boolean(self, env):
6678 arg_type = self.arg.type
6679 if (arg_type == PyrexTypes.c_bint_type or
6680 (arg_type.is_pyobject and arg_type.name == 'bool')):
6681 return self.arg.coerce_to_temp(env)
6683 return CoerceToBooleanNode(self, env)
6685 def coerce_to_integer(self, env):
6686 # If not already some C integer type, coerce to longint.
6687 if self.arg.type.is_int:
6690 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
6692 def analyse_types(self, env):
6693 # The arg is always already analysed
6696 def generate_result_code(self, code):
6697 function = self.arg.type.to_py_function
6698 code.putln('%s = %s(%s); %s' % (
6702 code.error_goto_if_null(self.result(), self.pos)))
6703 code.put_gotref(self.py_result())
6706 class CoerceIntToBytesNode(CoerceToPyTypeNode):
6707 # This node is used to convert a C int type to a Python bytes
6712 def __init__(self, arg, env):
6713 arg = arg.coerce_to_simple(env)
6714 CoercionNode.__init__(self, arg)
6715 self.type = Builtin.bytes_type
6717 def generate_result_code(self, code):
6719 arg_result = arg.result()
6720 if arg.type not in (PyrexTypes.c_char_type,
6721 PyrexTypes.c_uchar_type,
6722 PyrexTypes.c_schar_type):
6724 code.putln("if ((%s < 0) || (%s > 255)) {" % (
6725 arg_result, arg_result))
6727 code.putln("if (%s > 255) {" % arg_result)
6728 code.putln('PyErr_Format(PyExc_OverflowError, '
6729 '"value too large to pack into a byte"); %s' % (
6730 code.error_goto(self.pos)))
6733 if arg.type is not PyrexTypes.c_char_type:
6734 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
6735 code.putln("%s = (char)%s;" % (temp, arg_result))
6737 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
6740 code.error_goto_if_null(self.result(), self.pos)))
6741 if temp is not None:
6742 code.funcstate.release_temp(temp)
6743 code.put_gotref(self.py_result())
6746 class CoerceFromPyTypeNode(CoercionNode):
6747 # This node is used to convert a Python object
6750 def __init__(self, result_type, arg, env):
6751 CoercionNode.__init__(self, arg)
6752 self.type = result_type
6754 if not result_type.create_from_py_utility_code(env):
6756 "Cannot convert Python object to '%s'" % result_type)
6757 if self.type.is_string and self.arg.is_ephemeral():
6759 "Obtaining char * from temporary Python value")
6761 def analyse_types(self, env):
6762 # The arg is always already analysed
6765 def generate_result_code(self, code):
6766 function = self.type.from_py_function
6767 operand = self.arg.py_result()
6768 rhs = "%s(%s)" % (function, operand)
6769 if self.type.is_enum:
6770 rhs = typecast(self.type, c_long_type, rhs)
6771 code.putln('%s = %s; %s' % (
6774 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
6775 if self.type.is_pyobject:
6776 code.put_gotref(self.py_result())
6779 class CoerceToBooleanNode(CoercionNode):
6780 # This node is used when a result needs to be used
6781 # in a boolean context.
6783 type = PyrexTypes.c_bint_type
6785 _special_builtins = {
6786 Builtin.list_type : 'PyList_GET_SIZE',
6787 Builtin.tuple_type : 'PyTuple_GET_SIZE',
6788 Builtin.bytes_type : 'PyBytes_GET_SIZE',
6789 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
6792 def __init__(self, arg, env):
6793 CoercionNode.__init__(self, arg)
6794 if arg.type.is_pyobject:
6797 def nogil_check(self, env):
6798 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
6801 gil_message = "Truth-testing Python object"
6803 def check_const(self):
6807 return self.arg.check_const()
6809 def calculate_result_code(self):
6810 return "(%s != 0)" % self.arg.result()
6812 def generate_result_code(self, code):
6813 if not self.is_temp:
6815 test_func = self._special_builtins.get(self.arg.type)
6816 if test_func is not None:
6817 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
6819 self.arg.py_result(),
6821 self.arg.py_result()))
6824 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6826 self.arg.py_result(),
6827 code.error_goto_if_neg(self.result(), self.pos)))
6829 class CoerceToComplexNode(CoercionNode):
6831 def __init__(self, arg, dst_type, env):
6832 if arg.type.is_complex:
6833 arg = arg.coerce_to_simple(env)
6834 self.type = dst_type
6835 CoercionNode.__init__(self, arg)
6836 dst_type.create_declaration_utility_code(env)
6838 def calculate_result_code(self):
6839 if self.arg.type.is_complex:
6840 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
6841 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
6843 real_part = self.arg.result()
6845 return "%s(%s, %s)" % (
6846 self.type.from_parts,
6850 def generate_result_code(self, code):
6853 class CoerceToTempNode(CoercionNode):
6854 # This node is used to force the result of another node
6855 # to be stored in a temporary. It is only used if the
6856 # argument node's result is not already in a temporary.
6858 def __init__(self, arg, env):
6859 CoercionNode.__init__(self, arg)
6860 self.type = self.arg.type
6861 self.constant_result = self.arg.constant_result
6863 if self.type.is_pyobject:
6864 self.result_ctype = py_object_type
6866 gil_message = "Creating temporary Python reference"
6868 def analyse_types(self, env):
6869 # The arg is always already analysed
6872 def coerce_to_boolean(self, env):
6873 self.arg = self.arg.coerce_to_boolean(env)
6874 if self.arg.is_simple():
6876 self.type = self.arg.type
6877 self.result_ctype = self.type
6880 def generate_result_code(self, code):
6881 #self.arg.generate_evaluation_code(code) # Already done
6882 # by generic generate_subexpr_evaluation_code!
6883 code.putln("%s = %s;" % (
6884 self.result(), self.arg.result_as(self.ctype())))
6885 if self.type.is_pyobject and self.use_managed_ref:
6886 code.put_incref(self.result(), self.ctype())
6889 class CloneNode(CoercionNode):
6890 # This node is employed when the result of another node needs
6891 # to be used multiple times. The argument node's result must
6892 # be in a temporary. This node "borrows" the result from the
6893 # argument node, and does not generate any evaluation or
6894 # disposal code for it. The original owner of the argument
6895 # node is responsible for doing those things.
6897 subexprs = [] # Arg is not considered a subexpr
6900 def __init__(self, arg):
6901 CoercionNode.__init__(self, arg)
6902 if hasattr(arg, 'type'):
6903 self.type = arg.type
6904 self.result_ctype = arg.result_ctype
6905 if hasattr(arg, 'entry'):
6906 self.entry = arg.entry
6909 return self.arg.result()
6911 def type_dependencies(self, env):
6912 return self.arg.type_dependencies(env)
6914 def infer_type(self, env):
6915 return self.arg.infer_type(env)
6917 def analyse_types(self, env):
6918 self.type = self.arg.type
6919 self.result_ctype = self.arg.result_ctype
6921 if hasattr(self.arg, 'entry'):
6922 self.entry = self.arg.entry
6924 def generate_evaluation_code(self, code):
6927 def generate_result_code(self, code):
6930 def generate_disposal_code(self, code):
6933 def free_temps(self, code):
6937 class ModuleRefNode(ExprNode):
6938 # Simple returns the module object
6940 type = py_object_type
6944 def analyse_types(self, env):
6947 def may_be_none(self):
6950 def calculate_result_code(self):
6951 return Naming.module_cname
6953 def generate_result_code(self, code):
6956 class DocstringRefNode(ExprNode):
6957 # Extracts the docstring of the body element
6960 type = py_object_type
6963 def __init__(self, pos, body):
6964 ExprNode.__init__(self, pos)
6965 assert body.type.is_pyobject
6968 def analyse_types(self, env):
6971 def generate_result_code(self, code):
6972 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
6973 self.result(), self.body.result(),
6974 code.error_goto_if_null(self.result(), self.pos)))
6975 code.put_gotref(self.result())
6979 #------------------------------------------------------------------------------------
6981 # Runtime support code
6983 #------------------------------------------------------------------------------------
6985 get_name_interned_utility_code = UtilityCode(
6987 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
6990 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
6992 result = PyObject_GetAttr(dict, name);
6994 PyErr_SetObject(PyExc_NameError, name);
6999 #------------------------------------------------------------------------------------
7001 import_utility_code = UtilityCode(
7003 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7006 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7007 PyObject *py_import = 0;
7008 PyObject *empty_list = 0;
7009 PyObject *module = 0;
7010 PyObject *global_dict = 0;
7011 PyObject *empty_dict = 0;
7013 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7019 empty_list = PyList_New(0);
7024 global_dict = PyModule_GetDict(%(GLOBALS)s);
7027 empty_dict = PyDict_New();
7030 module = PyObject_CallFunctionObjArgs(py_import,
7031 name, global_dict, empty_dict, list, NULL);
7033 Py_XDECREF(empty_list);
7034 Py_XDECREF(py_import);
7035 Py_XDECREF(empty_dict);
7039 "BUILTINS": Naming.builtins_cname,
7040 "GLOBALS": Naming.module_cname,
7043 #------------------------------------------------------------------------------------
7045 get_exception_utility_code = UtilityCode(
7047 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7050 static PyObject *__Pyx_GetExcValue(void) {
7051 PyObject *type = 0, *value = 0, *tb = 0;
7052 PyObject *tmp_type, *tmp_value, *tmp_tb;
7053 PyObject *result = 0;
7054 PyThreadState *tstate = PyThreadState_Get();
7055 PyErr_Fetch(&type, &value, &tb);
7056 PyErr_NormalizeException(&type, &value, &tb);
7057 if (PyErr_Occurred())
7063 tmp_type = tstate->exc_type;
7064 tmp_value = tstate->exc_value;
7065 tmp_tb = tstate->exc_traceback;
7066 tstate->exc_type = type;
7067 tstate->exc_value = value;
7068 tstate->exc_traceback = tb;
7069 /* Make sure tstate is in a consistent state when we XDECREF
7070 these objects (XDECREF may run arbitrary code). */
7071 Py_XDECREF(tmp_type);
7072 Py_XDECREF(tmp_value);
7087 #------------------------------------------------------------------------------------
7089 type_test_utility_code = UtilityCode(
7091 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7094 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7095 if (unlikely(!type)) {
7096 PyErr_Format(PyExc_SystemError, "Missing type object");
7099 if (likely(PyObject_TypeCheck(obj, type)))
7101 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7102 Py_TYPE(obj)->tp_name, type->tp_name);
7107 #------------------------------------------------------------------------------------
7109 create_class_utility_code = UtilityCode(
7111 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, PyObject *modname); /*proto*/
7114 static PyObject *__Pyx_CreateClass(
7115 PyObject *bases, PyObject *dict, PyObject *name, PyObject *modname)
7117 PyObject *result = 0;
7119 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7121 #if PY_MAJOR_VERSION < 3
7122 result = PyClass_New(bases, dict, name);
7124 result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
7131 #------------------------------------------------------------------------------------
7133 cpp_exception_utility_code = UtilityCode(
7135 #ifndef __Pyx_CppExn2PyErr
7136 static void __Pyx_CppExn2PyErr() {
7138 if (PyErr_Occurred())
7139 ; // let the latest Python exn pass through and ignore the current one
7142 } catch (const std::invalid_argument& exn) {
7143 // Catch a handful of different errors here and turn them into the
7144 // equivalent Python errors.
7145 // Change invalid_argument to ValueError
7146 PyErr_SetString(PyExc_ValueError, exn.what());
7147 } catch (const std::out_of_range& exn) {
7148 // Change out_of_range to IndexError
7149 PyErr_SetString(PyExc_IndexError, exn.what());
7150 } catch (const std::exception& exn) {
7151 PyErr_SetString(PyExc_RuntimeError, exn.what());
7155 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7163 pyerr_occurred_withgil_utility_code= UtilityCode(
7165 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7168 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7171 PyGILState_STATE _save = PyGILState_Ensure();
7173 err = !!PyErr_Occurred();
7175 PyGILState_Release(_save);
7182 #------------------------------------------------------------------------------------
7184 raise_noneattr_error_utility_code = UtilityCode(
7186 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7189 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7190 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7194 raise_noneindex_error_utility_code = UtilityCode(
7196 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7199 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7200 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7204 raise_none_iter_error_utility_code = UtilityCode(
7206 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7209 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7210 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7214 #------------------------------------------------------------------------------------
7216 getitem_dict_utility_code = UtilityCode(
7219 #if PY_MAJOR_VERSION >= 3
7220 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7222 if (unlikely(d == Py_None)) {
7223 __Pyx_RaiseNoneIndexingError();
7226 value = PyDict_GetItemWithError(d, key);
7227 if (unlikely(!value)) {
7228 if (!PyErr_Occurred())
7229 PyErr_SetObject(PyExc_KeyError, key);
7236 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7239 requires = [raise_noneindex_error_utility_code])
7241 #------------------------------------------------------------------------------------
7243 getitem_int_pyunicode_utility_code = UtilityCode(
7245 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7246 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7247 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7249 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7250 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7251 return PyUnicode_AS_UNICODE(ustring)[i];
7252 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7253 i += PyUnicode_GET_SIZE(ustring);
7254 return PyUnicode_AS_UNICODE(ustring)[i];
7256 PyErr_SetString(PyExc_IndexError, "string index out of range");
7257 return (Py_UNICODE)-1;
7261 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7263 PyObject *uchar_string;
7264 if (!j) return (Py_UNICODE)-1;
7265 uchar_string = PyObject_GetItem(ustring, j);
7267 if (!uchar_string) return (Py_UNICODE)-1;
7268 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7269 Py_DECREF(uchar_string);
7274 getitem_int_utility_code = UtilityCode(
7277 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7279 if (!j) return NULL;
7280 r = PyObject_GetItem(o, j);
7287 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7288 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7289 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7291 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
7292 if (likely(o != Py_None)) {
7293 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
7294 PyObject *r = Py%(type)s_GET_ITEM(o, i);
7298 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
7299 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
7304 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7306 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
7309 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7310 __Pyx_GetItemInt_Fast(o, i) : \\
7311 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7313 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
7315 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7316 r = PyList_GET_ITEM(o, i);
7319 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
7320 r = PyTuple_GET_ITEM(o, i);
7323 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
7324 r = PySequence_GetItem(o, i);
7327 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7337 #------------------------------------------------------------------------------------
7339 setitem_int_utility_code = UtilityCode(
7341 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7342 __Pyx_SetItemInt_Fast(o, i, v) : \\
7343 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
7345 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
7348 r = PyObject_SetItem(o, j, v);
7353 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
7354 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7356 Py_DECREF(PyList_GET_ITEM(o, i));
7357 PyList_SET_ITEM(o, i, v);
7360 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
7361 return PySequence_SetItem(o, i, v);
7363 PyObject *j = PyInt_FromSsize_t(i);
7364 return __Pyx_SetItemInt_Generic(o, j, v);
7371 #------------------------------------------------------------------------------------
7373 delitem_int_utility_code = UtilityCode(
7375 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7376 __Pyx_DelItemInt_Fast(o, i) : \\
7377 __Pyx_DelItem_Generic(o, to_py_func(i)))
7379 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
7382 r = PyObject_DelItem(o, j);
7387 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
7388 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
7389 return PySequence_DelItem(o, i);
7391 PyObject *j = PyInt_FromSsize_t(i);
7392 return __Pyx_DelItem_Generic(o, j);
7399 #------------------------------------------------------------------------------------
7401 raise_too_many_values_to_unpack = UtilityCode(
7403 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
7406 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
7407 PyErr_Format(PyExc_ValueError,
7408 #if PY_VERSION_HEX < 0x02050000
7409 "too many values to unpack (expected %d)", (int)expected);
7411 "too many values to unpack (expected %zd)", expected);
7416 raise_need_more_values_to_unpack = UtilityCode(
7418 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
7421 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
7422 PyErr_Format(PyExc_ValueError,
7423 #if PY_VERSION_HEX < 0x02050000
7424 "need more than %d value%s to unpack", (int)index,
7426 "need more than %zd value%s to unpack", index,
7428 (index == 1) ? "" : "s");
7432 #------------------------------------------------------------------------------------
7434 tuple_unpacking_error_code = UtilityCode(
7436 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
7439 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
7441 __Pyx_RaiseNoneNotIterableError();
7442 } else if (PyTuple_GET_SIZE(t) < index) {
7443 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
7445 __Pyx_RaiseTooManyValuesError(index);
7449 requires = [raise_none_iter_error_utility_code,
7450 raise_need_more_values_to_unpack,
7451 raise_too_many_values_to_unpack]
7454 unpacking_utility_code = UtilityCode(
7456 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
7457 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
7460 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
7462 if (!(item = PyIter_Next(iter))) {
7463 if (!PyErr_Occurred()) {
7464 __Pyx_RaiseNeedMoreValuesError(index);
7470 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
7472 if ((item = PyIter_Next(iter))) {
7474 __Pyx_RaiseTooManyValuesError(expected);
7477 else if (!PyErr_Occurred())
7483 requires = [raise_need_more_values_to_unpack,
7484 raise_too_many_values_to_unpack]
7487 #------------------------------------------------------------------------------------
7489 # CPython supports calling functions with non-dict kwargs by
7490 # converting them to a dict first
7492 kwargs_call_utility_code = UtilityCode(
7494 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
7497 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
7499 if (likely(PyDict_Check(kwargs))) {
7500 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
7502 PyObject* real_dict;
7503 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
7504 if (unlikely(!real_dict))
7506 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
7507 Py_DECREF(real_dict);
7508 return result; /* may be NULL */
7515 #------------------------------------------------------------------------------------
7517 int_pow_utility_code = UtilityCode(
7519 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
7522 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
7534 if (unlikely(e<0)) return 0;
7537 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
7545 # ------------------------------ Division ------------------------------------
7547 div_int_utility_code = UtilityCode(
7549 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
7552 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
7554 %(type)s r = a - q*b;
7555 q -= ((r != 0) & ((r ^ b) < 0));
7560 mod_int_utility_code = UtilityCode(
7562 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
7565 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
7566 %(type)s r = a %% b;
7567 r += ((r != 0) & ((r ^ b) < 0)) * b;
7572 mod_float_utility_code = UtilityCode(
7574 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
7577 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
7578 %(type)s r = fmod%(math_h_modifier)s(a, b);
7579 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
7584 cdivision_warning_utility_code = UtilityCode(
7586 static int __Pyx_cdivision_warning(void); /* proto */
7589 static int __Pyx_cdivision_warning(void) {
7590 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
7591 "division with oppositely signed operands, C and Python semantics differ",
7598 'FILENAME': Naming.filename_cname,
7599 'LINENO': Naming.lineno_cname,
7603 division_overflow_test_code = UtilityCode(
7605 #define UNARY_NEG_WOULD_OVERFLOW(x) \
7606 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
7610 binding_cfunc_utility_code = UtilityCode(
7612 #define %(binding_cfunc)s_USED 1
7615 PyCFunctionObject func;
7616 } %(binding_cfunc)s_object;
7618 PyTypeObject %(binding_cfunc)s_type;
7619 PyTypeObject *%(binding_cfunc)s = NULL;
7621 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
7622 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
7624 int %(binding_cfunc)s_init(void); /* proto */
7625 """ % Naming.__dict__,
7628 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
7629 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
7634 op->func.m_self = self;
7636 op->func.m_module = module;
7637 PyObject_GC_Track(op);
7638 return (PyObject *)op;
7641 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
7642 PyObject_GC_UnTrack(m);
7643 Py_XDECREF(m->func.m_self);
7644 Py_XDECREF(m->func.m_module);
7648 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
7651 return PyMethod_New(func, obj, type);
7654 int %(binding_cfunc)s_init(void) {
7655 %(binding_cfunc)s_type = PyCFunction_Type;
7656 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
7657 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
7658 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
7659 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
7662 %(binding_cfunc)s = &%(binding_cfunc)s_type;
7666 """ % Naming.__dict__)