2 # Pyrex - Parse tree nodes for expressions
7 from Errors import error, warning, warn_once, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Code import UtilityCode
13 from Nodes import Node
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
17 from Builtin import list_type, tuple_type, set_type, dict_type, \
18 unicode_type, str_type, bytes_type, type_type
22 from Cython import Utils
23 from Annotate import AnnotationItem
24 from Cython import Utils
26 from Cython.Debugging import print_call_chain
27 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
33 from sets import Set as set
35 class NotConstant(object):
37 return "<NOT CONSTANT>"
39 not_a_constant = NotConstant()
40 constant_value_not_set = object()
42 # error messages when coercing from key[0] to key[1]
43 find_coercion_error = {
44 # string related errors
45 (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
46 (Builtin.unicode_type, Builtin.str_type) : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
47 (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
48 (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
49 (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
50 (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
51 (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
52 (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
53 (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
54 (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
59 # subexprs [string] Class var holding names of subexpr node attrs
60 # type PyrexType Type of the result
61 # result_code string Code fragment
62 # result_ctype string C type of result_code if different from type
63 # is_temp boolean Result is in a temporary variable
64 # is_sequence_constructor
65 # boolean Is a list or tuple constructor expression
66 # is_starred boolean Is a starred expression (e.g. '*a')
68 # [ExprNode or [ExprNode or None] or None]
69 # Cached result of subexpr_nodes()
70 # use_managed_ref boolean use ref-counted temps/assignments/etc.
75 old_temp = None # error checker for multiple frees etc.
76 use_managed_ref = True # can be set by optimisation transforms
78 # The Analyse Expressions phase for expressions is split
79 # into two sub-phases:
82 # Determines the result type of the expression based
83 # on the types of its sub-expressions, and inserts
84 # coercion nodes into the expression tree where needed.
85 # Marks nodes which will need to have temporary variables
89 # Allocates temporary variables where needed, and fills
90 # in the result_code field of each node.
92 # ExprNode provides some convenience routines which
93 # perform both of the above phases. These should only
94 # be called from statement nodes, and only when no
95 # coercion nodes need to be added around the expression
96 # being analysed. In that case, the above two phases
97 # should be invoked separately.
99 # Framework code in ExprNode provides much of the common
100 # processing for the various phases. It makes use of the
101 # 'subexprs' class attribute of ExprNodes, which should
102 # contain a list of the names of attributes which can
103 # hold sub-nodes or sequences of sub-nodes.
105 # The framework makes use of a number of abstract methods.
106 # Their responsibilities are as follows.
108 # Declaration Analysis phase
110 # analyse_target_declaration
111 # Called during the Analyse Declarations phase to analyse
112 # the LHS of an assignment or argument of a del statement.
113 # Nodes which cannot be the LHS of an assignment need not
116 # Expression Analysis phase
119 # - Call analyse_types on all sub-expressions.
120 # - Check operand types, and wrap coercion nodes around
121 # sub-expressions where needed.
122 # - Set the type of this node.
123 # - If a temporary variable will be required for the
124 # result, set the is_temp flag of this node.
126 # analyse_target_types
127 # Called during the Analyse Types phase to analyse
128 # the LHS of an assignment or argument of a del
129 # statement. Similar responsibilities to analyse_types.
132 # Called by the default implementation of allocate_target_temps.
133 # Should return a C lvalue for assigning to the node. The default
134 # implementation calls calculate_result_code.
137 # - Check that this node and its subnodes form a
138 # legal constant expression. If so, do nothing,
139 # otherwise call not_const.
141 # The default implementation of check_const
142 # assumes that the expression is not constant.
145 # - Same as check_const, except check that the
146 # expression is a C lvalue whose address is
147 # constant. Otherwise, call addr_not_const.
149 # The default implementation of calc_const_addr
150 # assumes that the expression is not a constant
153 # Code Generation phase
155 # generate_evaluation_code
156 # - Call generate_evaluation_code for sub-expressions.
157 # - Perform the functions of generate_result_code
159 # - If result is temporary, call generate_disposal_code
160 # on all sub-expressions.
162 # A default implementation of generate_evaluation_code
163 # is provided which uses the following abstract methods:
165 # generate_result_code
166 # - Generate any C statements necessary to calculate
167 # the result of this node from the results of its
170 # calculate_result_code
171 # - Should return a C code fragment evaluating to the
172 # result. This is only called when the result is not
175 # generate_assignment_code
176 # Called on the LHS of an assignment.
177 # - Call generate_evaluation_code for sub-expressions.
178 # - Generate code to perform the assignment.
179 # - If the assignment absorbed a reference, call
180 # generate_post_assignment_code on the RHS,
181 # otherwise call generate_disposal_code on it.
183 # generate_deletion_code
184 # Called on an argument of a del statement.
185 # - Call generate_evaluation_code for sub-expressions.
186 # - Generate code to perform the deletion.
187 # - Call generate_disposal_code on all sub-expressions.
191 is_sequence_constructor = 0
194 saved_subexpr_nodes = None
199 constant_result = constant_value_not_set
202 _get_child_attrs = operator.attrgetter('subexprs')
203 except AttributeError:
205 def _get_child_attrs(self):
207 child_attrs = property(fget=_get_child_attrs)
209 def not_implemented(self, method_name):
210 print_call_chain(method_name, "not implemented") ###
212 "%s.%s not implemented" %
213 (self.__class__.__name__, method_name))
218 def is_ephemeral(self):
219 # An ephemeral node is one whose result is in
220 # a Python temporary and we suspect there are no
221 # other references to it. Certain operations are
222 # disallowed on such values, since they are
223 # likely to result in a dangling pointer.
224 return self.type.is_pyobject and self.is_temp
226 def subexpr_nodes(self):
227 # Extract a list of subexpression nodes based
228 # on the contents of the subexprs class attribute.
230 for name in self.subexprs:
231 item = getattr(self, name)
233 if type(item) is list:
241 return self.temp_code
243 return self.calculate_result_code()
245 def result_as(self, type = None):
246 # Return the result code cast to the specified C type.
247 return typecast(type, self.ctype(), self.result())
250 # Return the result code cast to PyObject *.
251 return self.result_as(py_object_type)
254 # Return the native C type of the result (i.e. the
255 # C type of the result_code expression).
256 return self.result_ctype or self.type
258 def get_constant_c_result_code(self):
259 # Return the constant value of this node as a result code
260 # string, or None if the node is not constant. This method
261 # can be called when the constant result code is required
262 # before the code generation phase.
264 # The return value is a string that can represent a simple C
265 # value, a constant C name or a constant C expression. If the
266 # node type depends on Python code, this must return None.
269 def calculate_constant_result(self):
270 # Calculate the constant compile time result value of this
271 # expression and store it in ``self.constant_result``. Does
272 # nothing by default, thus leaving ``self.constant_result``
273 # unknown. If valid, the result can be an arbitrary Python
276 # This must only be called when it is assured that all
277 # sub-expressions have a valid constant_result value. The
278 # ConstantFolding transform will do this.
281 def has_constant_result(self):
282 return self.constant_result is not constant_value_not_set and \
283 self.constant_result is not not_a_constant
285 def compile_time_value(self, denv):
286 # Return value of compile-time expression, or report error.
287 error(self.pos, "Invalid compile-time expression")
289 def compile_time_value_error(self, e):
290 error(self.pos, "Error in compile-time expression: %s: %s" % (
291 e.__class__.__name__, e))
293 # ------------- Declaration Analysis ----------------
295 def analyse_target_declaration(self, env):
296 error(self.pos, "Cannot assign to or delete this")
298 # ------------- Expression Analysis ----------------
300 def analyse_const_expression(self, env):
301 # Called during the analyse_declarations phase of a
302 # constant expression. Analyses the expression's type,
303 # checks whether it is a legal const expression,
304 # and determines its value.
305 self.analyse_types(env)
306 return self.check_const()
308 def analyse_expressions(self, env):
309 # Convenience routine performing both the Type
310 # Analysis and Temp Allocation phases for a whole
312 self.analyse_types(env)
314 def analyse_target_expression(self, env, rhs):
315 # Convenience routine performing both the Type
316 # Analysis and Temp Allocation phases for the LHS of
318 self.analyse_target_types(env)
320 def analyse_boolean_expression(self, env):
321 # Analyse expression and coerce to a boolean.
322 self.analyse_types(env)
323 bool = self.coerce_to_boolean(env)
326 def analyse_temp_boolean_expression(self, env):
327 # Analyse boolean expression and coerce result into
328 # a temporary. This is used when a branch is to be
329 # performed on the result and we won't have an
330 # opportunity to ensure disposal code is executed
331 # afterwards. By forcing the result into a temporary,
332 # we ensure that all disposal has been done by the
333 # time we get the result.
334 self.analyse_types(env)
335 return self.coerce_to_boolean(env).coerce_to_simple(env)
337 # --------------- Type Inference -----------------
339 def type_dependencies(self, env):
340 # Returns the list of entries whose types must be determined
341 # before the type of self can be infered.
342 if hasattr(self, 'type') and self.type is not None:
344 return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
346 def infer_type(self, env):
347 # Attempt to deduce the type of self.
348 # Differs from analyse_types as it avoids unnecessary
349 # analysis of subexpressions, but can assume everything
350 # in self.type_dependencies() has been resolved.
351 if hasattr(self, 'type') and self.type is not None:
353 elif hasattr(self, 'entry') and self.entry is not None:
354 return self.entry.type
356 self.not_implemented("infer_type")
358 # --------------- Type Analysis ------------------
360 def analyse_as_module(self, env):
361 # If this node can be interpreted as a reference to a
362 # cimported module, return its scope, else None.
365 def analyse_as_type(self, env):
366 # If this node can be interpreted as a reference to a
367 # type, return that type, else None.
370 def analyse_as_extension_type(self, env):
371 # If this node can be interpreted as a reference to an
372 # extension type, return its type, else None.
375 def analyse_types(self, env):
376 self.not_implemented("analyse_types")
378 def analyse_target_types(self, env):
379 self.analyse_types(env)
381 def nogil_check(self, env):
382 # By default, any expression based on Python objects is
383 # prevented in nogil environments. Subtypes must override
384 # this if they can work without the GIL.
385 if self.type.is_pyobject:
388 def gil_assignment_check(self, env):
389 if env.nogil and self.type.is_pyobject:
390 error(self.pos, "Assignment of Python object not allowed without gil")
392 def check_const(self):
397 error(self.pos, "Not allowed in a constant expression")
399 def check_const_addr(self):
400 self.addr_not_const()
403 def addr_not_const(self):
404 error(self.pos, "Address is not constant")
406 # ----------------- Result Allocation -----------------
408 def result_in_temp(self):
409 # Return true if result is in a temporary owned by
410 # this node or one of its subexpressions. Overridden
411 # by certain nodes which can share the result of
415 def target_code(self):
416 # Return code fragment for use as LHS of a C assignment.
417 return self.calculate_result_code()
419 def calculate_result_code(self):
420 self.not_implemented("calculate_result_code")
422 # def release_target_temp(self, env):
423 # # Release temporaries used by LHS of an assignment.
424 # self.release_subexpr_temps(env)
426 def allocate_temp_result(self, code):
428 raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
432 type = PyrexTypes.py_object_type
433 self.temp_code = code.funcstate.allocate_temp(
434 type, manage_ref=self.use_managed_ref)
436 self.temp_code = None
438 def release_temp_result(self, code):
439 if not self.temp_code:
441 raise RuntimeError("temp %s released multiple times in %s" % (
442 self.old_temp, self.__class__.__name__))
444 raise RuntimeError("no temp, but release requested in %s" % (
445 self.__class__.__name__))
446 code.funcstate.release_temp(self.temp_code)
447 self.old_temp = self.temp_code
448 self.temp_code = None
450 # ---------------- Code Generation -----------------
452 def make_owned_reference(self, code):
453 # If result is a pyobject, make sure we own
455 if self.type.is_pyobject and not self.result_in_temp():
456 code.put_incref(self.result(), self.ctype())
458 def generate_evaluation_code(self, code):
459 code.mark_pos(self.pos)
461 # Generate code to evaluate this node and
462 # its sub-expressions, and dispose of any
463 # temporary results of its sub-expressions.
464 self.generate_subexpr_evaluation_code(code)
467 self.allocate_temp_result(code)
469 self.generate_result_code(code)
471 # If we are temp we do not need to wait until this node is disposed
472 # before disposing children.
473 self.generate_subexpr_disposal_code(code)
474 self.free_subexpr_temps(code)
476 def generate_subexpr_evaluation_code(self, code):
477 for node in self.subexpr_nodes():
478 node.generate_evaluation_code(code)
480 def generate_result_code(self, code):
481 self.not_implemented("generate_result_code")
483 def generate_disposal_code(self, code):
485 if self.type.is_pyobject:
486 code.put_decref_clear(self.result(), self.ctype())
488 # Already done if self.is_temp
489 self.generate_subexpr_disposal_code(code)
491 def generate_subexpr_disposal_code(self, code):
492 # Generate code to dispose of temporary results
493 # of all sub-expressions.
494 for node in self.subexpr_nodes():
495 node.generate_disposal_code(code)
497 def generate_post_assignment_code(self, code):
499 if self.type.is_pyobject:
500 code.putln("%s = 0;" % self.result())
502 self.generate_subexpr_disposal_code(code)
504 def generate_assignment_code(self, rhs, code):
505 # Stub method for nodes which are not legal as
506 # the LHS of an assignment. An error will have
507 # been reported earlier.
510 def generate_deletion_code(self, code):
511 # Stub method for nodes that are not legal as
512 # the argument of a del statement. An error
513 # will have been reported earlier.
516 def free_temps(self, code):
518 if not self.type.is_void:
519 self.release_temp_result(code)
521 self.free_subexpr_temps(code)
523 def free_subexpr_temps(self, code):
524 for sub in self.subexpr_nodes():
527 def generate_function_definitions(self, env, code):
530 # ---------------- Annotation ---------------------
532 def annotate(self, code):
533 for node in self.subexpr_nodes():
536 # ----------------- Coercion ----------------------
538 def coerce_to(self, dst_type, env):
539 # Coerce the result so that it can be assigned to
540 # something of type dst_type. If processing is necessary,
541 # wraps this node in a coercion node and returns that.
542 # Otherwise, returns this node unchanged.
544 # This method is called during the analyse_expressions
545 # phase of the src_node's processing.
547 # Note that subclasses that override this (especially
548 # ConstNodes) must not (re-)set their own .type attribute
549 # here. Since expression nodes may turn up in different
550 # places in the tree (e.g. inside of CloneNodes in cascaded
551 # assignments), this method must return a new node instance
552 # if it changes the type.
556 src_is_py_type = src_type.is_pyobject
557 dst_is_py_type = dst_type.is_pyobject
559 if self.check_for_coercion_error(dst_type):
562 if dst_type.is_reference:
563 dst_type = dst_type.ref_base_type
565 if dst_type.is_pyobject:
566 if not src.type.is_pyobject:
567 if dst_type is bytes_type and src.type.is_int:
568 src = CoerceIntToBytesNode(src, env)
570 src = CoerceToPyTypeNode(src, env)
571 if not src.type.subtype_of(dst_type):
572 if not isinstance(src, NoneNode):
573 src = PyTypeTestNode(src, dst_type, env)
574 elif src.type.is_pyobject:
575 src = CoerceFromPyTypeNode(dst_type, src, env)
576 elif (dst_type.is_complex
577 and src_type != dst_type
578 and dst_type.assignable_from(src_type)):
579 src = CoerceToComplexNode(src, dst_type, env)
580 else: # neither src nor dst are py types
581 # Added the string comparison, since for c types that
582 # is enough, but Cython gets confused when the types are
583 # in different pxi files.
584 if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
585 self.fail_assignment(dst_type)
588 def fail_assignment(self, dst_type):
589 error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
591 def check_for_coercion_error(self, dst_type, fail=False, default=None):
592 if fail and not default:
593 default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
594 message = find_coercion_error((self.type, dst_type), default)
595 if message is not None:
596 error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
599 self.fail_assignment(dst_type)
603 def coerce_to_pyobject(self, env):
604 return self.coerce_to(PyrexTypes.py_object_type, env)
606 def coerce_to_boolean(self, env):
607 # Coerce result to something acceptable as
610 # if it's constant, calculate the result now
611 if self.has_constant_result():
612 bool_value = bool(self.constant_result)
613 return BoolNode(self.pos, value=bool_value,
614 constant_result=bool_value)
617 if type.is_pyobject or type.is_ptr or type.is_float:
618 return CoerceToBooleanNode(self, env)
620 if not (type.is_int or type.is_enum or type.is_error):
622 "Type '%s' not acceptable as a boolean" % type)
625 def coerce_to_integer(self, env):
626 # If not already some C integer type, coerce to longint.
630 return self.coerce_to(PyrexTypes.c_long_type, env)
632 def coerce_to_temp(self, env):
633 # Ensure that the result is in a temporary.
634 if self.result_in_temp():
637 return CoerceToTempNode(self, env)
639 def coerce_to_simple(self, env):
640 # Ensure that the result is simple (see is_simple).
644 return self.coerce_to_temp(env)
647 # A node is simple if its result is something that can
648 # be referred to without performing any operations, e.g.
649 # a constant, local var, C global var, struct member
650 # reference, or temporary.
651 return self.result_in_temp()
653 def may_be_none(self):
654 if not self.type.is_pyobject:
656 if self.constant_result not in (not_a_constant, constant_value_not_set):
657 return self.constant_result is not None
660 def as_cython_attribute(self):
663 def as_none_safe_node(self, message, error="PyExc_TypeError"):
664 # Wraps the node in a NoneCheckNode if it is not known to be
665 # not-None (e.g. because it is a Python literal).
666 if self.may_be_none():
667 return NoneCheckNode(self, error, message)
672 class AtomicExprNode(ExprNode):
673 # Abstract base class for expression nodes which have
674 # no sub-expressions.
678 # Override to optimize -- we know we have no children
679 def generate_subexpr_evaluation_code(self, code):
681 def generate_subexpr_disposal_code(self, code):
684 class PyConstNode(AtomicExprNode):
685 # Abstract base class for constant Python values.
688 type = py_object_type
693 def may_be_none(self):
696 def analyse_types(self, env):
699 def calculate_result_code(self):
702 def generate_result_code(self, code):
706 class NoneNode(PyConstNode):
707 # The constant value None
711 constant_result = None
715 def compile_time_value(self, denv):
718 def may_be_none(self):
722 class EllipsisNode(PyConstNode):
723 # '...' in a subscript list.
725 value = "Py_Ellipsis"
727 constant_result = Ellipsis
729 def compile_time_value(self, denv):
733 class ConstNode(AtomicExprNode):
734 # Abstract base type for literal constant nodes.
736 # value string C code fragment
744 def may_be_none(self):
747 def analyse_types(self, env):
748 pass # Types are held in class variables
750 def check_const(self):
753 def get_constant_c_result_code(self):
754 return self.calculate_result_code()
756 def calculate_result_code(self):
757 return str(self.value)
759 def generate_result_code(self, code):
763 class BoolNode(ConstNode):
764 type = PyrexTypes.c_bint_type
765 # The constant value True or False
767 def calculate_constant_result(self):
768 self.constant_result = self.value
770 def compile_time_value(self, denv):
773 def calculate_result_code(self):
774 return str(int(self.value))
777 class NullNode(ConstNode):
778 type = PyrexTypes.c_null_ptr_type
782 def get_constant_c_result_code(self):
786 class CharNode(ConstNode):
787 type = PyrexTypes.c_char_type
789 def calculate_constant_result(self):
790 self.constant_result = ord(self.value)
792 def compile_time_value(self, denv):
793 return ord(self.value)
795 def calculate_result_code(self):
796 return "'%s'" % StringEncoding.escape_char(self.value)
799 class IntNode(ConstNode):
802 # longness "" or "L" or "LL"
807 def __init__(self, pos, **kwds):
808 ExprNode.__init__(self, pos, **kwds)
809 if 'type' not in kwds:
810 rank = max(1, len(self.longness))
811 sign = not self.unsigned
812 self.type = PyrexTypes.modifiers_and_name_to_type[sign, rank, "int"]
814 def coerce_to(self, dst_type, env):
815 if self.type is dst_type:
817 elif dst_type.is_float:
818 float_value = float(self.value)
819 return FloatNode(self.pos, value=repr(float_value), constant_result=float_value)
820 node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
821 unsigned=self.unsigned, longness=self.longness)
822 if dst_type.is_numeric and not dst_type.is_complex:
824 if dst_type.is_pyobject:
825 node.type = PyrexTypes.py_object_type
826 # We still need to perform normal coerce_to processing on the
827 # result, because we might be coercing to an extension type,
828 # in which case a type test node will be needed.
829 return ConstNode.coerce_to(node, dst_type, env)
831 def coerce_to_boolean(self, env):
833 self.pos, value=self.value,
834 type = PyrexTypes.c_bint_type,
835 unsigned=self.unsigned, longness=self.longness)
837 def generate_evaluation_code(self, code):
838 if self.type.is_pyobject:
839 # pre-allocate a Python version of the number
840 plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
841 self.result_code = code.get_py_num(plain_integer_string, self.longness)
843 self.result_code = self.get_constant_c_result_code()
845 def get_constant_c_result_code(self):
846 return self.value_as_c_integer_string() + self.unsigned + self.longness
848 def value_as_c_integer_string(self, plain_digits=False):
850 if isinstance(value, basestring) and len(value) > 2:
851 # must convert C-incompatible Py3 oct/bin notations
854 value = int(value[2:], 8)
856 value = value[0] + value[2:] # '0o123' => '0123'
857 elif value[1] in 'bB':
858 value = int(value[2:], 2)
859 elif plain_digits and value[1] in 'xX':
860 value = int(value[2:], 16)
863 def calculate_result_code(self):
864 return self.result_code
866 def calculate_constant_result(self):
867 self.constant_result = Utils.str_to_number(self.value)
869 def compile_time_value(self, denv):
870 return Utils.str_to_number(self.value)
873 class FloatNode(ConstNode):
874 type = PyrexTypes.c_double_type
876 def calculate_constant_result(self):
877 self.constant_result = float(self.value)
879 def compile_time_value(self, denv):
880 return float(self.value)
882 def calculate_result_code(self):
884 assert isinstance(strval, (str, unicode))
885 cmpval = repr(float(strval))
887 return "(Py_HUGE_VAL * 0)"
888 elif cmpval == 'inf':
890 elif cmpval == '-inf':
891 return "(-Py_HUGE_VAL)"
896 class BytesNode(ConstNode):
897 # A char* or bytes literal
901 type = PyrexTypes.c_char_ptr_type
903 def compile_time_value(self, denv):
906 def analyse_as_type(self, env):
907 type = PyrexTypes.parse_basic_type(self.value)
910 from TreeFragment import TreeFragment
911 pos = (self.pos[0], self.pos[1], self.pos[2]-7)
912 declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
913 sizeof_node = declaration.root.stats[0].expr
914 sizeof_node.analyse_types(env)
915 if isinstance(sizeof_node, SizeofTypeNode):
916 return sizeof_node.arg_type
918 def can_coerce_to_char_literal(self):
919 return len(self.value) == 1
921 def coerce_to_boolean(self, env):
922 # This is special because we start off as a C char*. Testing
923 # that for truth directly would yield the wrong result.
924 return BoolNode(self.pos, value=bool(self.value))
926 def coerce_to(self, dst_type, env):
928 if not self.can_coerce_to_char_literal():
929 error(self.pos, "Only single-character string literals can be coerced into ints.")
931 if dst_type is PyrexTypes.c_py_unicode_type:
932 error(self.pos, "Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.")
934 return CharNode(self.pos, value=self.value)
936 node = BytesNode(self.pos, value=self.value)
937 if dst_type == PyrexTypes.c_char_ptr_type:
938 node.type = PyrexTypes.c_char_ptr_type
940 elif dst_type == PyrexTypes.c_uchar_ptr_type:
941 node.type = PyrexTypes.c_char_ptr_type
942 return CastNode(node, PyrexTypes.c_uchar_ptr_type)
944 if not self.type.is_pyobject:
945 if dst_type in (py_object_type, Builtin.bytes_type):
946 node.type = Builtin.bytes_type
947 elif dst_type.is_pyobject:
948 self.fail_assignment(dst_type)
950 elif dst_type.is_pyobject and dst_type is not py_object_type:
951 self.check_for_coercion_error(dst_type, fail=True)
954 # We still need to perform normal coerce_to processing on the
955 # result, because we might be coercing to an extension type,
956 # in which case a type test node will be needed.
957 return ConstNode.coerce_to(node, dst_type, env)
959 def as_py_string_node(self, env):
960 # Return a new BytesNode with the same value as this node
961 # but whose type is a Python type instead of a C type.
962 return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
964 def generate_evaluation_code(self, code):
965 if self.type.is_pyobject:
966 self.result_code = code.get_py_string_const(self.value)
968 self.result_code = code.get_string_const(self.value)
970 def get_constant_c_result_code(self):
973 def calculate_result_code(self):
974 return self.result_code
977 class UnicodeNode(PyConstNode):
978 # A Python unicode object
980 # value EncodedString
981 # bytes_value BytesLiteral the literal parsed as bytes string ('-3' unicode literals only)
986 def coerce_to(self, dst_type, env):
987 if dst_type is self.type:
989 elif dst_type is PyrexTypes.c_py_unicode_type:
990 if not self.can_coerce_to_char_literal():
991 error(self.pos, "Only single-character Unicode string literals can be coerced into Py_UNICODE.")
993 int_value = ord(self.value)
994 return IntNode(self.pos, value=int_value, constant_result=int_value)
995 elif not dst_type.is_pyobject:
996 if dst_type.is_string and self.bytes_value is not None:
997 # special case: '-3' enforced unicode literal used in a C char* context
998 return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
999 error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE.")
1000 elif dst_type is not py_object_type:
1001 if not self.check_for_coercion_error(dst_type):
1002 self.fail_assignment(dst_type)
1005 def can_coerce_to_char_literal(self):
1006 return len(self.value) == 1
1008 def contains_surrogates(self):
1009 # Check if the unicode string contains surrogate code points
1010 # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
1011 # Unicode, i.e. characters that would be spelled as two
1012 # separate code units on a narrow platform.
1013 for c in map(ord, self.value):
1014 if c > 65535: # can only happen on wide platforms
1016 # We only look for the first code unit (D800-DBFF) of a
1017 # surrogate pair - if we find one, the other one
1018 # (DC00-DFFF) is likely there, too. If we don't find it,
1019 # any second code unit cannot make for a surrogate pair by
1021 if c >= 0xD800 and c <= 0xDBFF:
1025 def generate_evaluation_code(self, code):
1026 self.result_code = code.get_py_string_const(self.value)
1028 def calculate_result_code(self):
1029 return self.result_code
1031 def compile_time_value(self, env):
1035 class StringNode(PyConstNode):
1036 # A Python str object, i.e. a byte string in Python 2.x and a
1037 # unicode string in Python 3.x
1039 # value BytesLiteral
1040 # unicode_value EncodedString
1041 # is_identifier boolean
1044 is_identifier = None
1045 unicode_value = None
1047 def coerce_to(self, dst_type, env):
1048 if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1049 # if dst_type is Builtin.bytes_type:
1050 # # special case: bytes = 'str literal'
1051 # return BytesNode(self.pos, value=self.value)
1052 if not dst_type.is_pyobject:
1053 return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1054 self.check_for_coercion_error(dst_type, fail=True)
1056 # this will be a unicode string in Py3, so make sure we can decode it
1057 if self.value.encoding:
1058 encoding = self.value.encoding
1060 self.value.decode(encoding)
1061 except UnicodeDecodeError:
1062 error(self.pos, "String decoding as '%s' failed. Consider using a byte string or unicode string explicitly, or adjust the source code encoding." % encoding)
1066 def can_coerce_to_char_literal(self):
1067 return not self.is_identifier and len(self.value) == 1
1069 def generate_evaluation_code(self, code):
1070 self.result_code = code.get_py_string_const(
1071 self.value, identifier=self.is_identifier, is_str=True)
1073 def get_constant_c_result_code(self):
1076 def calculate_result_code(self):
1077 return self.result_code
1079 def compile_time_value(self, env):
1083 class IdentifierStringNode(StringNode):
1084 # A special str value that represents an identifier (bytes in Py2,
1086 is_identifier = True
1089 class LongNode(AtomicExprNode):
1090 # Python long integer literal
1094 type = py_object_type
1096 def calculate_constant_result(self):
1097 self.constant_result = Utils.str_to_number(self.value)
1099 def compile_time_value(self, denv):
1100 return Utils.str_to_number(self.value)
1102 def analyse_types(self, env):
1105 def may_be_none(self):
1108 gil_message = "Constructing Python long int"
1110 def generate_result_code(self, code):
1112 '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1115 code.error_goto_if_null(self.result(), self.pos)))
1116 code.put_gotref(self.py_result())
1119 class ImagNode(AtomicExprNode):
1120 # Imaginary number literal
1122 # value float imaginary part
1124 type = PyrexTypes.c_double_complex_type
1126 def calculate_constant_result(self):
1127 self.constant_result = complex(0.0, self.value)
1129 def compile_time_value(self, denv):
1130 return complex(0.0, self.value)
1132 def analyse_types(self, env):
1133 self.type.create_declaration_utility_code(env)
1135 def may_be_none(self):
1138 def coerce_to(self, dst_type, env):
1139 if self.type is dst_type:
1141 node = ImagNode(self.pos, value=self.value)
1142 if dst_type.is_pyobject:
1144 node.type = PyrexTypes.py_object_type
1145 # We still need to perform normal coerce_to processing on the
1146 # result, because we might be coercing to an extension type,
1147 # in which case a type test node will be needed.
1148 return AtomicExprNode.coerce_to(node, dst_type, env)
1150 gil_message = "Constructing complex number"
1152 def calculate_result_code(self):
1153 if self.type.is_pyobject:
1154 return self.result()
1156 return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1158 def generate_result_code(self, code):
1159 if self.type.is_pyobject:
1161 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1164 code.error_goto_if_null(self.result(), self.pos)))
1165 code.put_gotref(self.py_result())
1168 class NewExprNode(AtomicExprNode):
1172 # cppclass node c++ class to create
1176 def infer_type(self, env):
1177 type = self.cppclass.analyse_as_type(env)
1178 if type is None or not type.is_cpp_class:
1179 error(self.pos, "new operator can only be applied to a C++ class")
1180 self.type = error_type
1183 constructor = type.scope.lookup(u'<init>')
1184 if constructor is None:
1185 return_type = PyrexTypes.CFuncType(type, [])
1186 return_type = PyrexTypes.CPtrType(return_type)
1187 type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1188 constructor = type.scope.lookup(u'<init>')
1189 self.class_type = type
1190 self.entry = constructor
1191 self.type = constructor.type
1194 def analyse_types(self, env):
1195 if self.type is None:
1196 self.infer_type(env)
1198 def may_be_none(self):
1201 def generate_result_code(self, code):
1204 def calculate_result_code(self):
1205 return "new " + self.class_type.declaration_code("")
1208 class NameNode(AtomicExprNode):
1209 # Reference to a local or global variable name.
1211 # name string Python name of the variable
1212 # entry Entry Symbol table entry
1213 # type_entry Entry For extension type names, the original type entry
1216 is_cython_module = False
1217 cython_attribute = None
1218 lhs_of_first_assignment = False
1219 is_used_as_rvalue = 0
1223 def create_analysed_rvalue(pos, env, entry):
1224 node = NameNode(pos)
1225 node.analyse_types(env, entry=entry)
1228 def as_cython_attribute(self):
1229 return self.cython_attribute
1231 create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1233 def type_dependencies(self, env):
1234 if self.entry is None:
1235 self.entry = env.lookup(self.name)
1236 if self.entry is not None and self.entry.type.is_unspecified:
1237 return (self.entry,)
1241 def infer_type(self, env):
1242 if self.entry is None:
1243 self.entry = env.lookup(self.name)
1244 if self.entry is None:
1245 return py_object_type
1246 elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
1247 self.name == self.entry.type.name:
1248 # Unfortunately the type attribute of type objects
1249 # is used for the pointer to the type they represent.
1252 return self.entry.type
1254 def compile_time_value(self, denv):
1256 return denv.lookup(self.name)
1258 error(self.pos, "Compile-time name '%s' not defined" % self.name)
1260 def get_constant_c_result_code(self):
1261 if not self.entry or self.entry.type.is_pyobject:
1263 return self.entry.cname
1265 def coerce_to(self, dst_type, env):
1266 # If coercing to a generic pyobject and this is a builtin
1267 # C function with a Python equivalent, manufacture a NameNode
1268 # referring to the Python builtin.
1269 #print "NameNode.coerce_to:", self.name, dst_type ###
1270 if dst_type is py_object_type:
1272 if entry and entry.is_cfunction:
1273 var_entry = entry.as_variable
1275 if var_entry.is_builtin and Options.cache_builtins:
1276 var_entry = env.declare_builtin(var_entry.name, self.pos)
1277 node = NameNode(self.pos, name = self.name)
1278 node.entry = var_entry
1279 node.analyse_rvalue_entry(env)
1281 return super(NameNode, self).coerce_to(dst_type, env)
1283 def analyse_as_module(self, env):
1284 # Try to interpret this as a reference to a cimported module.
1285 # Returns the module scope, or None.
1288 entry = env.lookup(self.name)
1289 if entry and entry.as_module:
1290 return entry.as_module
1293 def analyse_as_type(self, env):
1294 if self.cython_attribute:
1295 type = PyrexTypes.parse_basic_type(self.cython_attribute)
1297 type = PyrexTypes.parse_basic_type(self.name)
1302 entry = env.lookup(self.name)
1303 if entry and entry.is_type:
1308 def analyse_as_extension_type(self, env):
1309 # Try to interpret this as a reference to an extension type.
1310 # Returns the extension type, or None.
1313 entry = env.lookup(self.name)
1314 if entry and entry.is_type and entry.type.is_extension_type:
1319 def analyse_target_declaration(self, env):
1321 self.entry = env.lookup_here(self.name)
1323 if env.directives['warn.undeclared']:
1324 warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1325 if env.directives['infer_types'] != False:
1326 type = unspecified_type
1328 type = py_object_type
1329 self.entry = env.declare_var(self.name, type, self.pos)
1330 env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
1331 env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1332 if self.entry.is_declared_generic:
1333 self.result_ctype = py_object_type
1335 def analyse_types(self, env):
1336 if self.entry is None:
1337 self.entry = env.lookup(self.name)
1339 self.entry = env.declare_builtin(self.name, self.pos)
1341 self.type = PyrexTypes.error_type
1346 if entry.type.is_buffer:
1348 Buffer.used_buffer_aux_vars(entry)
1349 if entry.utility_code:
1350 env.use_utility_code(entry.utility_code)
1351 self.analyse_rvalue_entry(env)
1353 def analyse_target_types(self, env):
1354 self.analyse_entry(env)
1355 if not self.is_lvalue():
1356 error(self.pos, "Assignment to non-lvalue '%s'"
1358 self.type = PyrexTypes.error_type
1360 if self.entry.type.is_buffer:
1362 Buffer.used_buffer_aux_vars(self.entry)
1364 def analyse_rvalue_entry(self, env):
1365 #print "NameNode.analyse_rvalue_entry:", self.name ###
1366 #print "Entry:", self.entry.__dict__ ###
1367 self.analyse_entry(env)
1369 if entry.is_declared_generic:
1370 self.result_ctype = py_object_type
1371 if entry.is_pyglobal or entry.is_builtin:
1372 if Options.cache_builtins and entry.is_builtin:
1376 env.use_utility_code(get_name_interned_utility_code)
1377 self.is_used_as_rvalue = 1
1379 def nogil_check(self, env):
1380 if self.is_used_as_rvalue:
1382 if entry.is_builtin:
1383 # if not Options.cache_builtins: # cached builtins are ok
1385 elif entry.is_pyglobal:
1388 gil_message = "Accessing Python global or builtin"
1390 def analyse_entry(self, env):
1391 #print "NameNode.analyse_entry:", self.name ###
1392 self.check_identifier_kind()
1397 def check_identifier_kind(self):
1398 # Check that this is an appropriate kind of name for use in an
1399 # expression. Also finds the variable entry associated with
1400 # an extension type.
1402 if entry.is_type and entry.type.is_extension_type:
1403 self.type_entry = entry
1404 if not (entry.is_const or entry.is_variable
1405 or entry.is_builtin or entry.is_cfunction
1406 or entry.is_cpp_class):
1407 if self.entry.as_variable:
1408 self.entry = self.entry.as_variable
1411 "'%s' is not a constant, variable or function identifier" % self.name)
1413 def is_simple(self):
1414 # If it's not a C variable, it'll be in a temp.
1417 def calculate_target_results(self, env):
1420 def check_const(self):
1422 if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1427 def check_const_addr(self):
1429 if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1430 self.addr_not_const()
1434 def is_lvalue(self):
1435 return self.entry.is_variable and \
1436 not self.entry.type.is_array and \
1437 not self.entry.is_readonly
1439 def is_ephemeral(self):
1440 # Name nodes are never ephemeral, even if the
1441 # result is in a temporary.
1444 def calculate_result_code(self):
1447 return "<error>" # There was an error earlier
1450 def generate_result_code(self, code):
1451 assert hasattr(self, 'entry')
1454 return # There was an error earlier
1455 if entry.is_builtin and Options.cache_builtins:
1456 return # Lookup already cached
1457 elif entry.is_pyclass_attr:
1458 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1459 interned_cname = code.intern_identifier(self.entry.name)
1460 if entry.is_builtin:
1461 namespace = Naming.builtins_cname
1462 else: # entry.is_pyglobal
1463 namespace = entry.scope.namespace_cname
1464 code.globalstate.use_utility_code(getitem_dict_utility_code)
1466 '%s = PyObject_GetItem(%s, %s); %s' % (
1470 code.error_goto_if_null(self.result(), self.pos)))
1471 code.put_gotref(self.py_result())
1473 elif entry.is_pyglobal or entry.is_builtin:
1474 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1475 interned_cname = code.intern_identifier(self.entry.name)
1476 if entry.is_builtin:
1477 namespace = Naming.builtins_cname
1478 else: # entry.is_pyglobal
1479 namespace = entry.scope.namespace_cname
1480 code.globalstate.use_utility_code(get_name_interned_utility_code)
1482 '%s = __Pyx_GetName(%s, %s); %s' % (
1486 code.error_goto_if_null(self.result(), self.pos)))
1487 code.put_gotref(self.py_result())
1489 elif entry.is_local and False:
1490 # control flow not good enough yet
1491 assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1492 if assigned is False:
1493 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1494 elif not Options.init_local_none and assigned is None:
1495 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1496 (entry.cname, entry.name, code.error_goto(self.pos)))
1497 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
1499 def generate_assignment_code(self, rhs, code):
1500 #print "NameNode.generate_assignment_code:", self.name ###
1503 return # There was an error earlier
1505 if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1506 and not self.lhs_of_first_assignment):
1507 error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1509 # is_pyglobal seems to be True for module level-globals only.
1510 # We use this to access class->tp_dict if necessary.
1511 if entry.is_pyglobal:
1512 assert entry.type.is_pyobject, "Python global or builtin not a Python object"
1513 interned_cname = code.intern_identifier(self.entry.name)
1514 namespace = self.entry.scope.namespace_cname
1516 # if the entry is a member we have to cheat: SetAttr does not work
1517 # on types, so we create a descriptor which is then added to tp_dict
1518 code.put_error_if_neg(self.pos,
1519 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1523 rhs.generate_disposal_code(code)
1524 rhs.free_temps(code)
1525 # in Py2.6+, we need to invalidate the method cache
1526 code.putln("PyType_Modified(%s);" %
1527 entry.scope.parent_type.typeptr_cname)
1528 elif entry.is_pyclass_attr:
1529 code.put_error_if_neg(self.pos,
1530 'PyObject_SetItem(%s, %s, %s)' % (
1534 rhs.generate_disposal_code(code)
1535 rhs.free_temps(code)
1537 code.put_error_if_neg(self.pos,
1538 'PyObject_SetAttr(%s, %s, %s)' % (
1542 if debug_disposal_code:
1543 print("NameNode.generate_assignment_code:")
1544 print("...generating disposal code for %s" % rhs)
1545 rhs.generate_disposal_code(code)
1546 rhs.free_temps(code)
1548 if self.type.is_buffer:
1549 # Generate code for doing the buffer release/acquisition.
1550 # This might raise an exception in which case the assignment (done
1551 # below) will not happen.
1553 # The reason this is not in a typetest-like node is because the
1554 # variables that the acquired buffer info is stored to is allocated
1555 # per entry and coupled with it.
1556 self.generate_acquire_buffer(rhs, code)
1558 if self.type.is_pyobject:
1559 #print "NameNode.generate_assignment_code: to", self.name ###
1560 #print "...from", rhs ###
1561 #print "...LHS type", self.type, "ctype", self.ctype() ###
1562 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1563 if self.use_managed_ref:
1564 rhs.make_owned_reference(code)
1565 if entry.is_cglobal:
1566 code.put_gotref(self.py_result())
1567 if not self.lhs_of_first_assignment:
1568 if entry.is_local and not Options.init_local_none:
1569 initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1570 if initialized is True:
1571 code.put_decref(self.result(), self.ctype())
1572 elif initialized is None:
1573 code.put_xdecref(self.result(), self.ctype())
1575 code.put_decref(self.result(), self.ctype())
1576 if entry.is_cglobal:
1577 code.put_giveref(rhs.py_result())
1579 code.putln('%s = %s;' % (self.result(),
1580 rhs.result_as(self.ctype())))
1581 if debug_disposal_code:
1582 print("NameNode.generate_assignment_code:")
1583 print("...generating post-assignment code for %s" % rhs)
1584 rhs.generate_post_assignment_code(code)
1585 rhs.free_temps(code)
1587 def generate_acquire_buffer(self, rhs, code):
1588 # rhstmp is only used in case the rhs is a complicated expression leading to
1589 # the object, to avoid repeating the same C expression for every reference
1590 # to the rhs. It does NOT hold a reference.
1591 pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1593 rhstmp = rhs.result_as(self.ctype())
1595 rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1596 code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1598 buffer_aux = self.entry.buffer_aux
1599 bufstruct = buffer_aux.buffer_info_var.cname
1601 Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1602 is_initialized=not self.lhs_of_first_assignment,
1603 pos=self.pos, code=code)
1606 code.putln("%s = 0;" % rhstmp)
1607 code.funcstate.release_temp(rhstmp)
1609 def generate_deletion_code(self, code):
1610 if self.entry is None:
1611 return # There was an error earlier
1612 if not self.entry.is_pyglobal:
1613 error(self.pos, "Deletion of local or C global name not supported")
1615 if self.entry.is_pyclass_attr:
1616 namespace = self.entry.scope.namespace_cname
1617 code.put_error_if_neg(self.pos,
1618 'PyMapping_DelItemString(%s, "%s")' % (
1622 code.put_error_if_neg(self.pos,
1623 '__Pyx_DelAttrString(%s, "%s")' % (
1624 Naming.module_cname,
1627 def annotate(self, code):
1628 if hasattr(self, 'is_called') and self.is_called:
1629 pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1630 if self.type.is_pyobject:
1631 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1633 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1635 class BackquoteNode(ExprNode):
1640 type = py_object_type
1644 def analyse_types(self, env):
1645 self.arg.analyse_types(env)
1646 self.arg = self.arg.coerce_to_pyobject(env)
1649 gil_message = "Backquote expression"
1651 def calculate_constant_result(self):
1652 self.constant_result = repr(self.arg.constant_result)
1654 def generate_result_code(self, code):
1656 "%s = PyObject_Repr(%s); %s" % (
1658 self.arg.py_result(),
1659 code.error_goto_if_null(self.result(), self.pos)))
1660 code.put_gotref(self.py_result())
1664 class ImportNode(ExprNode):
1665 # Used as part of import statement implementation.
1666 # Implements result =
1667 # __import__(module_name, globals(), None, name_list)
1669 # module_name StringNode dotted name of module
1670 # name_list ListNode or None list of names to be imported
1672 type = py_object_type
1674 subexprs = ['module_name', 'name_list']
1676 def analyse_types(self, env):
1677 self.module_name.analyse_types(env)
1678 self.module_name = self.module_name.coerce_to_pyobject(env)
1680 self.name_list.analyse_types(env)
1681 self.name_list.coerce_to_pyobject(env)
1683 env.use_utility_code(import_utility_code)
1685 gil_message = "Python import"
1687 def generate_result_code(self, code):
1689 name_list_code = self.name_list.py_result()
1691 name_list_code = "0"
1693 "%s = __Pyx_Import(%s, %s); %s" % (
1695 self.module_name.py_result(),
1697 code.error_goto_if_null(self.result(), self.pos)))
1698 code.put_gotref(self.py_result())
1701 class IteratorNode(ExprNode):
1702 # Used as part of for statement implementation.
1704 # allocate_counter_temp/release_counter_temp needs to be called
1705 # by parent (ForInStatNode)
1707 # Implements result = iter(sequence)
1711 type = py_object_type
1713 subexprs = ['sequence']
1715 def analyse_types(self, env):
1716 self.sequence.analyse_types(env)
1717 if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
1718 not self.sequence.type.is_string:
1719 # C array iteration will be transformed later on
1720 self.type = self.sequence.type
1722 self.sequence = self.sequence.coerce_to_pyobject(env)
1725 gil_message = "Iterating over Python object"
1727 def allocate_counter_temp(self, code):
1728 self.counter_cname = code.funcstate.allocate_temp(
1729 PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1731 def release_counter_temp(self, code):
1732 code.funcstate.release_temp(self.counter_cname)
1734 def generate_result_code(self, code):
1735 if self.sequence.type.is_array or self.sequence.type.is_ptr:
1736 raise InternalError("for in carray slice not transformed")
1737 is_builtin_sequence = self.sequence.type is list_type or \
1738 self.sequence.type is tuple_type
1739 may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
1740 if is_builtin_sequence:
1742 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1743 elif may_be_a_sequence:
1745 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1746 self.sequence.py_result(),
1747 self.sequence.py_result()))
1748 if may_be_a_sequence:
1750 "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1753 self.sequence.py_result(),
1755 code.putln("} else {")
1756 if is_builtin_sequence:
1758 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1759 code.error_goto(self.pos))
1761 code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1764 self.sequence.py_result(),
1765 code.error_goto_if_null(self.result(), self.pos)))
1766 code.put_gotref(self.py_result())
1767 if may_be_a_sequence:
1771 class NextNode(AtomicExprNode):
1772 # Used as part of for statement implementation.
1773 # Implements result = iterator.next()
1774 # Created during analyse_types phase.
1775 # The iterator is not owned by this node.
1779 type = py_object_type
1781 def __init__(self, iterator, env):
1782 self.pos = iterator.pos
1783 self.iterator = iterator
1784 if iterator.type.is_ptr or iterator.type.is_array:
1785 self.type = iterator.type.base_type
1788 def generate_result_code(self, code):
1789 sequence_type = self.iterator.sequence.type
1790 if sequence_type is list_type:
1791 type_checks = [(list_type, "List")]
1792 elif sequence_type is tuple_type:
1793 type_checks = [(tuple_type, "Tuple")]
1794 elif not sequence_type.is_builtin_type:
1795 type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1799 for py_type, prefix in type_checks:
1800 if len(type_checks) > 1:
1802 "if (likely(Py%s_CheckExact(%s))) {" % (
1803 prefix, self.iterator.py_result()))
1805 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1806 self.iterator.counter_cname,
1808 self.iterator.py_result()))
1810 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1813 self.iterator.py_result(),
1814 self.iterator.counter_cname,
1816 self.iterator.counter_cname))
1817 if len(type_checks) > 1:
1819 if len(type_checks) == 1:
1823 "%s = PyIter_Next(%s);" % (
1825 self.iterator.py_result()))
1829 code.putln(code.error_goto_if_PyErr(self.pos))
1830 code.putln("break;")
1832 code.put_gotref(self.py_result())
1836 class ExcValueNode(AtomicExprNode):
1837 # Node created during analyse_types phase
1838 # of an ExceptClauseNode to fetch the current
1841 type = py_object_type
1843 def __init__(self, pos, env):
1844 ExprNode.__init__(self, pos)
1846 def set_var(self, var):
1849 def calculate_result_code(self):
1852 def generate_result_code(self, code):
1855 def analyse_types(self, env):
1859 class TempNode(ExprNode):
1860 # Node created during analyse_types phase
1861 # of some nodes to hold a temporary value.
1863 # Note: One must call "allocate" and "release" on
1864 # the node during code generation to get/release the temp.
1865 # This is because the temp result is often used outside of
1866 # the regular cycle.
1870 def __init__(self, pos, type, env):
1871 ExprNode.__init__(self, pos)
1873 if type.is_pyobject:
1874 self.result_ctype = py_object_type
1877 def analyse_types(self, env):
1880 def generate_result_code(self, code):
1883 def allocate(self, code):
1884 self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
1886 def release(self, code):
1887 code.funcstate.release_temp(self.temp_cname)
1888 self.temp_cname = None
1892 return self.temp_cname
1894 assert False, "Remember to call allocate/release on TempNode"
1897 # Do not participate in normal temp alloc/dealloc:
1898 def allocate_temp_result(self, code):
1901 def release_temp_result(self, code):
1904 class PyTempNode(TempNode):
1905 # TempNode holding a Python value.
1907 def __init__(self, pos, env):
1908 TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1910 class RawCNameExprNode(ExprNode):
1913 def __init__(self, pos, type=None):
1917 def analyse_types(self, env):
1920 def set_cname(self, cname):
1926 def generate_result_code(self, code):
1930 #-------------------------------------------------------------------
1934 #-------------------------------------------------------------------
1936 class IndexNode(ExprNode):
1937 # Sequence indexing.
1941 # indices [ExprNode]
1942 # is_buffer_access boolean Whether this is a buffer access.
1944 # indices is used on buffer access, index on non-buffer access.
1945 # The former contains a clean list of index parameters, the
1946 # latter whatever Python object is needed for index access.
1948 subexprs = ['base', 'index', 'indices']
1951 def __init__(self, pos, index, *args, **kw):
1952 ExprNode.__init__(self, pos, index=index, *args, **kw)
1955 def calculate_constant_result(self):
1956 self.constant_result = \
1957 self.base.constant_result[self.index.constant_result]
1959 def compile_time_value(self, denv):
1960 base = self.base.compile_time_value(denv)
1961 index = self.index.compile_time_value(denv)
1964 except Exception, e:
1965 self.compile_time_value_error(e)
1967 def is_ephemeral(self):
1968 return self.base.is_ephemeral()
1970 def analyse_target_declaration(self, env):
1973 def analyse_as_type(self, env):
1974 base_type = self.base.analyse_as_type(env)
1975 if base_type and not base_type.is_pyobject:
1976 if base_type.is_cpp_class:
1977 if isinstance(self.index, TupleNode):
1978 template_values = self.index.args
1980 template_values = [self.index]
1982 type_node = Nodes.TemplatedTypeNode(
1984 positional_args = template_values,
1985 keyword_args = None)
1986 return type_node.analyse(env, base_type = base_type)
1988 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1991 def type_dependencies(self, env):
1992 return self.base.type_dependencies(env)
1994 def infer_type(self, env):
1995 base_type = self.base.infer_type(env)
1996 if isinstance(self.index, SliceNode):
1998 if base_type.is_string:
1999 # sliced C strings must coerce to Python
2001 elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
2002 # slicing these returns the same type
2005 # TODO: Handle buffers (hopefully without too much redundancy).
2006 return py_object_type
2008 index_type = self.index.infer_type(env)
2009 if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2011 if base_type is unicode_type:
2012 # Py_UNICODE will automatically coerce to a unicode string
2013 # if required, so this is safe. We only infer Py_UNICODE
2014 # when the index is a C integer type. Otherwise, we may
2015 # need to use normal Python item access, in which case
2016 # it's faster to return the one-char unicode string than
2017 # to receive it, throw it away, and potentially rebuild it
2018 # on a subsequent PyObject coercion.
2019 return PyrexTypes.c_py_unicode_type
2020 elif isinstance(self.base, BytesNode):
2021 #if env.global_scope().context.language_level >= 3:
2022 # # infering 'char' can be made to work in Python 3 mode
2023 # return PyrexTypes.c_char_type
2024 # Py2/3 return different types on indexing bytes objects
2025 return py_object_type
2026 elif base_type.is_ptr or base_type.is_array:
2027 return base_type.base_type
2029 # may be slicing or indexing, we don't know
2030 if base_type is unicode_type:
2031 # this type always returns its own type on Python indexing/slicing
2034 # TODO: Handle buffers (hopefully without too much redundancy).
2035 return py_object_type
2037 def analyse_types(self, env):
2038 self.analyse_base_and_index_types(env, getting = 1)
2040 def analyse_target_types(self, env):
2041 self.analyse_base_and_index_types(env, setting = 1)
2043 def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2044 # Note: This might be cleaned up by having IndexNode
2045 # parsed in a saner way and only construct the tuple if
2048 # Note that this function must leave IndexNode in a cloneable state.
2049 # For buffers, self.index is packed out on the initial analysis, and
2050 # when cloning self.indices is copied.
2051 self.is_buffer_access = False
2053 self.base.analyse_types(env)
2054 if self.base.type.is_error:
2055 # Do not visit child tree if base is undeclared to avoid confusing
2057 self.type = PyrexTypes.error_type
2060 is_slice = isinstance(self.index, SliceNode)
2061 # Potentially overflowing index value.
2062 if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2063 self.index = self.index.coerce_to_pyobject(env)
2065 # Handle the case where base is a literal char* (and we expect a string, not an int)
2066 if isinstance(self.base, BytesNode) or is_slice:
2067 if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2068 self.base = self.base.coerce_to_pyobject(env)
2070 skip_child_analysis = False
2071 buffer_access = False
2072 if self.base.type.is_buffer:
2073 assert hasattr(self.base, "entry") # Must be a NameNode-like node
2075 indices = self.indices
2077 if isinstance(self.index, TupleNode):
2078 indices = self.index.args
2080 indices = [self.index]
2081 if len(indices) == self.base.type.ndim:
2082 buffer_access = True
2083 skip_child_analysis = True
2085 x.analyse_types(env)
2086 if not x.type.is_int:
2087 buffer_access = False
2089 # On cloning, indices is cloned. Otherwise, unpack index into indices
2090 assert not (buffer_access and isinstance(self.index, CloneNode))
2093 self.indices = indices
2095 self.type = self.base.type.dtype
2096 self.is_buffer_access = True
2097 self.buffer_type = self.base.entry.type
2099 if getting and self.type.is_pyobject:
2102 if not self.base.entry.type.writable:
2103 error(self.pos, "Writing to readonly buffer")
2105 self.base.entry.buffer_aux.writable_needed = True
2107 base_type = self.base.type
2108 if isinstance(self.index, TupleNode):
2109 self.index.analyse_types(env, skip_children=skip_child_analysis)
2110 elif not skip_child_analysis:
2111 self.index.analyse_types(env)
2112 self.original_index_type = self.index.type
2113 if base_type is PyrexTypes.c_py_unicode_type:
2114 # we infer Py_UNICODE for unicode strings in some
2115 # cases, but indexing must still work for them
2116 if self.index.constant_result in (0, -1):
2117 # FIXME: we know that this node is redundant -
2118 # currently, this needs to get handled in Optimize.py
2120 self.base = self.base.coerce_to_pyobject(env)
2121 base_type = self.base.type
2122 if base_type.is_pyobject:
2123 if self.index.type.is_int:
2125 and (base_type in (list_type, tuple_type, unicode_type))
2126 and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
2127 and not env.directives['boundscheck']):
2131 self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
2133 self.index = self.index.coerce_to_pyobject(env)
2135 if self.index.type.is_int and base_type is unicode_type:
2136 # Py_UNICODE will automatically coerce to a unicode string
2137 # if required, so this is fast and safe
2138 self.type = PyrexTypes.c_py_unicode_type
2139 elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
2140 self.type = base_type
2142 self.type = py_object_type
2144 if base_type.is_ptr or base_type.is_array:
2145 self.type = base_type.base_type
2147 self.type = base_type
2148 elif self.index.type.is_pyobject:
2149 self.index = self.index.coerce_to(
2150 PyrexTypes.c_py_ssize_t_type, env)
2151 elif not self.index.type.is_int:
2153 "Invalid index type '%s'" %
2155 elif base_type.is_cpp_class:
2156 function = env.lookup_operator("[]", [self.base, self.index])
2157 if function is None:
2158 error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
2159 self.type = PyrexTypes.error_type
2160 self.result_code = "<error>"
2162 func_type = function.type
2163 if func_type.is_ptr:
2164 func_type = func_type.base_type
2165 self.index = self.index.coerce_to(func_type.args[0].type, env)
2166 self.type = func_type.return_type
2167 if setting and not func_type.return_type.is_reference:
2168 error(self.pos, "Can't set non-reference result '%s'" % self.type)
2171 "Attempting to index non-array type '%s'" %
2173 self.type = PyrexTypes.error_type
2175 gil_message = "Indexing Python object"
2177 def nogil_check(self, env):
2178 if self.is_buffer_access:
2179 if env.directives['boundscheck']:
2180 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
2182 elif self.type.is_pyobject:
2183 error(self.pos, "Cannot access buffer with object dtype without gil")
2185 super(IndexNode, self).nogil_check(env)
2188 def check_const_addr(self):
2189 return self.base.check_const_addr() and self.index.check_const()
2191 def is_lvalue(self):
2194 def calculate_result_code(self):
2195 if self.is_buffer_access:
2196 return "(*%s)" % self.buffer_ptr_code
2197 elif self.base.type is list_type:
2198 return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2199 elif self.base.type is tuple_type:
2200 return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
2201 elif self.base.type is unicode_type and self.type is PyrexTypes.c_py_unicode_type:
2202 return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2203 elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
2204 error(self.pos, "Invalid use of pointer slice")
2206 return "(%s[%s])" % (
2207 self.base.result(), self.index.result())
2209 def extra_index_params(self):
2210 if self.index.type.is_int:
2211 if self.original_index_type.signed:
2212 size_adjustment = ""
2214 size_adjustment = "+1"
2215 return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
2219 def generate_subexpr_evaluation_code(self, code):
2220 self.base.generate_evaluation_code(code)
2221 if not self.indices:
2222 self.index.generate_evaluation_code(code)
2224 for i in self.indices:
2225 i.generate_evaluation_code(code)
2227 def generate_subexpr_disposal_code(self, code):
2228 self.base.generate_disposal_code(code)
2229 if not self.indices:
2230 self.index.generate_disposal_code(code)
2232 for i in self.indices:
2233 i.generate_disposal_code(code)
2235 def free_subexpr_temps(self, code):
2236 self.base.free_temps(code)
2237 if not self.indices:
2238 self.index.free_temps(code)
2240 for i in self.indices:
2243 def generate_result_code(self, code):
2244 if self.is_buffer_access:
2245 if code.globalstate.directives['nonecheck']:
2246 self.put_nonecheck(code)
2247 self.buffer_ptr_code = self.buffer_lookup_code(code)
2248 if self.type.is_pyobject:
2249 # is_temp is True, so must pull out value and incref it.
2250 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
2251 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2253 if self.type.is_pyobject:
2254 if self.index.type.is_int:
2255 index_code = self.index.result()
2256 if self.base.type is list_type:
2257 function = "__Pyx_GetItemInt_List"
2258 elif self.base.type is tuple_type:
2259 function = "__Pyx_GetItemInt_Tuple"
2261 function = "__Pyx_GetItemInt"
2262 code.globalstate.use_utility_code(getitem_int_utility_code)
2264 index_code = self.index.py_result()
2265 if self.base.type is dict_type:
2266 function = "__Pyx_PyDict_GetItem"
2267 code.globalstate.use_utility_code(getitem_dict_utility_code)
2269 function = "PyObject_GetItem"
2271 "%s = %s(%s, %s%s); if (!%s) %s" % (
2274 self.base.py_result(),
2276 self.extra_index_params(),
2278 code.error_goto(self.pos)))
2279 code.put_gotref(self.py_result())
2280 elif self.type is PyrexTypes.c_py_unicode_type and self.base.type is unicode_type:
2281 assert self.index.type.is_int
2282 index_code = self.index.result()
2283 function = "__Pyx_GetItemInt_Unicode"
2284 code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
2286 "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
2289 self.base.py_result(),
2291 self.extra_index_params(),
2293 code.error_goto(self.pos)))
2295 def generate_setitem_code(self, value_code, code):
2296 if self.index.type.is_int:
2297 function = "__Pyx_SetItemInt"
2298 index_code = self.index.result()
2299 code.globalstate.use_utility_code(setitem_int_utility_code)
2301 index_code = self.index.py_result()
2302 if self.base.type is dict_type:
2303 function = "PyDict_SetItem"
2304 # It would seem that we could specialized lists/tuples, but that
2305 # shouldn't happen here.
2306 # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
2307 # not a PyObject*, and bad conversion here would give the wrong
2308 # exception. Also, tuples are supposed to be immutable, and raise
2309 # TypeErrors when trying to set their entries (PyTuple_SetItem
2310 # is for creating new tuples from).
2312 function = "PyObject_SetItem"
2314 "if (%s(%s, %s, %s%s) < 0) %s" % (
2316 self.base.py_result(),
2319 self.extra_index_params(),
2320 code.error_goto(self.pos)))
2322 def generate_buffer_setitem_code(self, rhs, code, op=""):
2323 # Used from generate_assignment_code and InPlaceAssignmentNode
2324 if code.globalstate.directives['nonecheck']:
2325 self.put_nonecheck(code)
2326 ptrexpr = self.buffer_lookup_code(code)
2327 if self.buffer_type.dtype.is_pyobject:
2328 # Must manage refcounts. Decref what is already there
2329 # and incref what we put in.
2330 ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2331 rhs_code = rhs.result()
2332 code.putln("%s = %s;" % (ptr, ptrexpr))
2333 code.put_gotref("*%s" % ptr)
2334 code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2337 code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2338 code.put_giveref("*%s" % ptr)
2339 code.funcstate.release_temp(ptr)
2342 code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2344 def generate_assignment_code(self, rhs, code):
2345 self.generate_subexpr_evaluation_code(code)
2346 if self.is_buffer_access:
2347 self.generate_buffer_setitem_code(rhs, code)
2348 elif self.type.is_pyobject:
2349 self.generate_setitem_code(rhs.py_result(), code)
2353 self.result(), rhs.result()))
2354 self.generate_subexpr_disposal_code(code)
2355 self.free_subexpr_temps(code)
2356 rhs.generate_disposal_code(code)
2357 rhs.free_temps(code)
2359 def generate_deletion_code(self, code):
2360 self.generate_subexpr_evaluation_code(code)
2361 #if self.type.is_pyobject:
2362 if self.index.type.is_int:
2363 function = "__Pyx_DelItemInt"
2364 index_code = self.index.result()
2365 code.globalstate.use_utility_code(delitem_int_utility_code)
2367 index_code = self.index.py_result()
2368 if self.base.type is dict_type:
2369 function = "PyDict_DelItem"
2371 function = "PyObject_DelItem"
2373 "if (%s(%s, %s%s) < 0) %s" % (
2375 self.base.py_result(),
2377 self.extra_index_params(),
2378 code.error_goto(self.pos)))
2379 self.generate_subexpr_disposal_code(code)
2380 self.free_subexpr_temps(code)
2382 def buffer_lookup_code(self, code):
2383 # Assign indices to temps
2384 index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2385 for temp, index in zip(index_temps, self.indices):
2386 code.putln("%s = %s;" % (temp, index.result()))
2387 # Generate buffer access code using these temps
2389 # The above could happen because child_attrs is wrong somewhere so that
2390 # options are not propagated.
2391 return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2392 index_signeds=[i.type.signed for i in self.indices],
2393 index_cnames=index_temps,
2394 directives=code.globalstate.directives,
2395 pos=self.pos, code=code)
2397 def put_nonecheck(self, code):
2398 code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2399 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2400 code.putln("__Pyx_RaiseNoneIndexingError();")
2401 code.putln(code.error_goto(self.pos))
2404 class SliceIndexNode(ExprNode):
2405 # 2-element slice indexing
2408 # start ExprNode or None
2409 # stop ExprNode or None
2411 subexprs = ['base', 'start', 'stop']
2413 def infer_type(self, env):
2414 base_type = self.base.infer_type(env)
2415 if base_type.is_string:
2417 elif base_type in (bytes_type, str_type, unicode_type,
2418 list_type, tuple_type):
2420 return py_object_type
2422 def calculate_constant_result(self):
2423 self.constant_result = self.base.constant_result[
2424 self.start.constant_result : self.stop.constant_result]
2426 def compile_time_value(self, denv):
2427 base = self.base.compile_time_value(denv)
2428 if self.start is None:
2431 start = self.start.compile_time_value(denv)
2432 if self.stop is None:
2435 stop = self.stop.compile_time_value(denv)
2437 return base[start:stop]
2438 except Exception, e:
2439 self.compile_time_value_error(e)
2441 def analyse_target_declaration(self, env):
2444 def analyse_target_types(self, env):
2445 self.analyse_types(env)
2446 # when assigning, we must accept any Python type
2447 if self.type.is_pyobject:
2448 self.type = py_object_type
2450 def analyse_types(self, env):
2451 self.base.analyse_types(env)
2453 self.start.analyse_types(env)
2455 self.stop.analyse_types(env)
2456 base_type = self.base.type
2457 if base_type.is_string:
2458 self.type = bytes_type
2459 elif base_type.is_ptr:
2460 self.type = base_type
2461 elif base_type.is_array:
2462 # we need a ptr type here instead of an array type, as
2463 # array types can result in invalid type casts in the C
2465 self.type = PyrexTypes.CPtrType(base_type.base_type)
2467 self.base = self.base.coerce_to_pyobject(env)
2468 self.type = py_object_type
2469 if base_type.is_builtin_type:
2470 # slicing builtin types returns something of the same type
2471 self.type = base_type
2472 c_int = PyrexTypes.c_py_ssize_t_type
2474 self.start = self.start.coerce_to(c_int, env)
2476 self.stop = self.stop.coerce_to(c_int, env)
2479 nogil_check = Node.gil_error
2480 gil_message = "Slicing Python object"
2482 def generate_result_code(self, code):
2483 if not self.type.is_pyobject:
2485 "Slicing is not currently supported for '%s'." % self.type)
2487 if self.base.type.is_string:
2488 if self.stop is None:
2490 "%s = PyBytes_FromString(%s + %s); %s" % (
2494 code.error_goto_if_null(self.result(), self.pos)))
2497 "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2503 code.error_goto_if_null(self.result(), self.pos)))
2506 "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
2508 self.base.py_result(),
2511 code.error_goto_if_null(self.result(), self.pos)))
2512 code.put_gotref(self.py_result())
2514 def generate_assignment_code(self, rhs, code):
2515 self.generate_subexpr_evaluation_code(code)
2516 if self.type.is_pyobject:
2517 code.put_error_if_neg(self.pos,
2518 "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2519 self.base.py_result(),
2526 start_offset = self.start_code()
2527 if start_offset == '0':
2531 if rhs.type.is_array:
2532 array_length = rhs.type.size
2533 self.generate_slice_guard_code(code, array_length)
2536 "Slice assignments from pointers are not yet supported.")
2537 # FIXME: fix the array size according to start/stop
2538 array_length = self.base.type.size
2539 for i in range(array_length):
2540 code.putln("%s[%s%s] = %s[%d];" % (
2541 self.base.result(), start_offset, i,
2543 self.generate_subexpr_disposal_code(code)
2544 self.free_subexpr_temps(code)
2545 rhs.generate_disposal_code(code)
2546 rhs.free_temps(code)
2548 def generate_deletion_code(self, code):
2549 if not self.base.type.is_pyobject:
2551 "Deleting slices is only supported for Python types, not '%s'." % self.type)
2553 self.generate_subexpr_evaluation_code(code)
2554 code.put_error_if_neg(self.pos,
2555 "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
2556 self.base.py_result(),
2559 self.generate_subexpr_disposal_code(code)
2561 def generate_slice_guard_code(self, code, target_size):
2562 if not self.base.type.is_array:
2564 slice_size = self.base.type.size
2567 stop = self.stop.result()
2571 slice_size = self.base.type.size + stop
2578 start = self.start.result()
2582 start = self.base.type.size + start
2590 error(self.pos, "Assignment to empty slice.")
2591 elif start is None and stop is None:
2592 # we know the exact slice length
2593 if target_size != slice_size:
2594 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2595 slice_size, target_size))
2596 elif start is not None:
2599 check = "(%s)-(%s)" % (stop, start)
2600 else: # stop is not None:
2603 code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2604 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));' % (
2605 target_size, check))
2606 code.putln(code.error_goto(self.pos))
2609 def start_code(self):
2611 return self.start.result()
2615 def stop_code(self):
2617 return self.stop.result()
2618 elif self.base.type.is_array:
2619 return self.base.type.size
2621 return "PY_SSIZE_T_MAX"
2623 def calculate_result_code(self):
2624 # self.result() is not used, but this method must exist
2628 class SliceNode(ExprNode):
2629 # start:stop:step in subscript list
2635 type = py_object_type
2638 def calculate_constant_result(self):
2639 self.constant_result = self.base.constant_result[
2640 self.start.constant_result : \
2641 self.stop.constant_result : \
2642 self.step.constant_result]
2644 def compile_time_value(self, denv):
2645 start = self.start.compile_time_value(denv)
2646 if self.stop is None:
2649 stop = self.stop.compile_time_value(denv)
2650 if self.step is None:
2653 step = self.step.compile_time_value(denv)
2655 return slice(start, stop, step)
2656 except Exception, e:
2657 self.compile_time_value_error(e)
2659 subexprs = ['start', 'stop', 'step']
2661 def analyse_types(self, env):
2662 self.start.analyse_types(env)
2663 self.stop.analyse_types(env)
2664 self.step.analyse_types(env)
2665 self.start = self.start.coerce_to_pyobject(env)
2666 self.stop = self.stop.coerce_to_pyobject(env)
2667 self.step = self.step.coerce_to_pyobject(env)
2669 gil_message = "Constructing Python slice object"
2671 def generate_result_code(self, code):
2673 "%s = PySlice_New(%s, %s, %s); %s" % (
2675 self.start.py_result(),
2676 self.stop.py_result(),
2677 self.step.py_result(),
2678 code.error_goto_if_null(self.result(), self.pos)))
2679 code.put_gotref(self.py_result())
2682 class CallNode(ExprNode):
2684 # allow overriding the default 'may_be_none' behaviour
2685 may_return_none = None
2687 def may_be_none(self):
2688 if self.may_return_none is not None:
2689 return self.may_return_none
2690 return ExprNode.may_be_none(self)
2692 def analyse_as_type_constructor(self, env):
2693 type = self.function.analyse_as_type(env)
2694 if type and type.is_struct_or_union:
2695 args, kwds = self.explicit_args_kwds()
2697 for arg, member in zip(args, type.scope.var_entries):
2698 items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
2700 items += kwds.key_value_pairs
2701 self.key_value_pairs = items
2702 self.__class__ = DictNode
2703 self.analyse_types(env)
2704 self.coerce_to(type, env)
2706 elif type and type.is_cpp_class:
2707 for arg in self.args:
2708 arg.analyse_types(env)
2709 constructor = type.scope.lookup("<init>")
2710 self.function = RawCNameExprNode(self.function.pos, constructor.type)
2711 self.function.entry = constructor
2712 self.function.set_cname(type.declaration_code(""))
2713 self.analyse_c_function_call(env)
2716 def is_lvalue(self):
2717 return self.type.is_reference
2719 def nogil_check(self, env):
2720 func_type = self.function_type()
2721 if func_type.is_pyobject:
2723 elif not getattr(func_type, 'nogil', False):
2726 gil_message = "Calling gil-requiring function"
2729 class SimpleCallNode(CallNode):
2730 # Function call without keyword, * or ** args.
2734 # arg_tuple ExprNode or None used internally
2735 # self ExprNode or None used internally
2736 # coerced_self ExprNode or None used internally
2737 # wrapper_call bool used internally
2738 # has_optional_args bool used internally
2739 # nogil bool used internally
2741 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2746 wrapper_call = False
2747 has_optional_args = False
2751 def compile_time_value(self, denv):
2752 function = self.function.compile_time_value(denv)
2753 args = [arg.compile_time_value(denv) for arg in self.args]
2755 return function(*args)
2756 except Exception, e:
2757 self.compile_time_value_error(e)
2759 def type_dependencies(self, env):
2760 # TODO: Update when Danilo's C++ code merged in to handle the
2761 # the case of function overloading.
2762 return self.function.type_dependencies(env)
2764 def infer_type(self, env):
2765 function = self.function
2766 func_type = function.infer_type(env)
2767 if isinstance(self.function, NewExprNode):
2768 return PyrexTypes.CPtrType(self.function.class_type)
2769 if func_type.is_ptr:
2770 func_type = func_type.base_type
2771 if func_type.is_cfunction:
2772 return func_type.return_type
2773 elif func_type is type_type:
2774 if function.is_name and function.entry and function.entry.type:
2775 result_type = function.entry.type
2776 if result_type.is_extension_type:
2778 elif result_type.is_builtin_type:
2779 if function.entry.name == 'float':
2780 return PyrexTypes.c_double_type
2781 elif function.entry.name in Builtin.types_that_construct_their_instance:
2783 return py_object_type
2785 def analyse_as_type(self, env):
2786 attr = self.function.as_cython_attribute()
2787 if attr == 'pointer':
2788 if len(self.args) != 1:
2789 error(self.args.pos, "only one type allowed.")
2791 type = self.args[0].analyse_as_type(env)
2793 error(self.args[0].pos, "Unknown type")
2795 return PyrexTypes.CPtrType(type)
2797 def explicit_args_kwds(self):
2798 return self.args, None
2800 def analyse_types(self, env):
2801 if self.analyse_as_type_constructor(env):
2805 self.analysed = True
2806 function = self.function
2807 function.is_called = 1
2808 self.function.analyse_types(env)
2809 if function.is_attribute and function.entry and function.entry.is_cmethod:
2810 # Take ownership of the object from which the attribute
2811 # was obtained, because we need to pass it as 'self'.
2812 self.self = function.obj
2813 function.obj = CloneNode(self.self)
2814 func_type = self.function_type()
2815 if func_type.is_pyobject:
2816 self.arg_tuple = TupleNode(self.pos, args = self.args)
2817 self.arg_tuple.analyse_types(env)
2819 if func_type is Builtin.type_type and function.is_name and \
2820 function.entry and \
2821 function.entry.is_builtin and \
2822 function.entry.name in Builtin.types_that_construct_their_instance:
2823 # calling a builtin type that returns a specific object type
2824 if function.entry.name == 'float':
2825 # the following will come true later on in a transform
2826 self.type = PyrexTypes.c_double_type
2827 self.result_ctype = PyrexTypes.c_double_type
2829 self.type = Builtin.builtin_types[function.entry.name]
2830 self.result_ctype = py_object_type
2831 self.may_return_none = False
2832 elif function.is_name and function.type_entry:
2833 # We are calling an extension type constructor. As
2834 # long as we do not support __new__(), the result type
2836 self.type = function.type_entry.type
2837 self.result_ctype = py_object_type
2838 self.may_return_none = False
2840 self.type = py_object_type
2843 for arg in self.args:
2844 arg.analyse_types(env)
2845 if self.self and func_type.args:
2846 # Coerce 'self' to the type expected by the method.
2847 self_arg = func_type.args[0]
2848 if self_arg.not_none: # C methods must do the None test for self at *call* time
2849 self.self = self.self.as_none_safe_node(
2850 "'NoneType' object has no attribute '%s'" % self.function.entry.name,
2851 'PyExc_AttributeError')
2852 expected_type = self_arg.type
2853 self.coerced_self = CloneNode(self.self).coerce_to(
2855 # Insert coerced 'self' argument into argument list.
2856 self.args.insert(0, self.coerced_self)
2857 self.analyse_c_function_call(env)
2859 def function_type(self):
2860 # Return the type of the function being called, coercing a function
2861 # pointer to a function if necessary.
2862 func_type = self.function.type
2863 if func_type.is_ptr:
2864 func_type = func_type.base_type
2867 def analyse_c_function_call(self, env):
2868 if self.function.type is error_type:
2869 self.type = error_type
2871 if self.function.type.is_cpp_class:
2872 overloaded_entry = self.function.type.scope.lookup("operator()")
2873 if overloaded_entry is None:
2874 self.type = PyrexTypes.error_type
2875 self.result_code = "<error>"
2877 elif hasattr(self.function, 'entry'):
2878 overloaded_entry = self.function.entry
2880 overloaded_entry = None
2881 if overloaded_entry:
2882 entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
2884 self.type = PyrexTypes.error_type
2885 self.result_code = "<error>"
2887 self.function.entry = entry
2888 self.function.type = entry.type
2889 func_type = self.function_type()
2891 func_type = self.function_type()
2892 if not func_type.is_cfunction:
2893 error(self.pos, "Calling non-function type '%s'" % func_type)
2894 self.type = PyrexTypes.error_type
2895 self.result_code = "<error>"
2898 max_nargs = len(func_type.args)
2899 expected_nargs = max_nargs - func_type.optional_arg_count
2900 actual_nargs = len(self.args)
2901 if func_type.optional_arg_count and expected_nargs != actual_nargs:
2902 self.has_optional_args = 1
2905 for i in range(min(max_nargs, actual_nargs)):
2906 formal_type = func_type.args[i].type
2907 self.args[i] = self.args[i].coerce_to(formal_type, env)
2908 for i in range(max_nargs, actual_nargs):
2909 if self.args[i].type.is_pyobject:
2910 error(self.args[i].pos,
2911 "Python object cannot be passed as a varargs parameter")
2912 # Calc result type and code fragment
2913 if isinstance(self.function, NewExprNode):
2914 self.type = PyrexTypes.CPtrType(self.function.class_type)
2916 self.type = func_type.return_type
2917 if self.type.is_pyobject:
2918 self.result_ctype = py_object_type
2920 elif func_type.exception_value is not None \
2921 or func_type.exception_check:
2923 # Called in 'nogil' context?
2924 self.nogil = env.nogil
2926 func_type.exception_check and
2927 func_type.exception_check != '+'):
2928 env.use_utility_code(pyerr_occurred_withgil_utility_code)
2929 # C++ exception handler
2930 if func_type.exception_check == '+':
2931 if func_type.exception_value is None:
2932 env.use_utility_code(cpp_exception_utility_code)
2934 def calculate_result_code(self):
2935 return self.c_call_code()
2937 def c_call_code(self):
2938 func_type = self.function_type()
2939 if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2941 formal_args = func_type.args
2943 args = zip(formal_args, self.args)
2944 max_nargs = len(func_type.args)
2945 expected_nargs = max_nargs - func_type.optional_arg_count
2946 actual_nargs = len(self.args)
2947 for formal_arg, actual_arg in args[:expected_nargs]:
2948 arg_code = actual_arg.result_as(formal_arg.type)
2949 arg_list_code.append(arg_code)
2951 if func_type.is_overridable:
2952 arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2954 if func_type.optional_arg_count:
2955 if expected_nargs == actual_nargs:
2956 optional_args = 'NULL'
2958 optional_args = "&%s" % self.opt_arg_struct
2959 arg_list_code.append(optional_args)
2961 for actual_arg in self.args[len(formal_args):]:
2962 arg_list_code.append(actual_arg.result())
2963 result = "%s(%s)" % (self.function.result(),
2964 ', '.join(arg_list_code))
2967 def generate_result_code(self, code):
2968 func_type = self.function_type()
2969 if func_type.is_pyobject:
2970 arg_code = self.arg_tuple.py_result()
2972 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2974 self.function.py_result(),
2976 code.error_goto_if_null(self.result(), self.pos)))
2977 code.put_gotref(self.py_result())
2978 elif func_type.is_cfunction:
2979 if self.has_optional_args:
2980 actual_nargs = len(self.args)
2981 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2982 self.opt_arg_struct = code.funcstate.allocate_temp(
2983 func_type.op_arg_struct.base_type, manage_ref=True)
2984 code.putln("%s.%s = %s;" % (
2985 self.opt_arg_struct,
2986 Naming.pyrex_prefix + "n",
2987 len(self.args) - expected_nargs))
2988 args = zip(func_type.args, self.args)
2989 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2990 code.putln("%s.%s = %s;" % (
2991 self.opt_arg_struct,
2992 func_type.opt_arg_cname(formal_arg.name),
2993 actual_arg.result_as(formal_arg.type)))
2995 if self.type.is_pyobject and self.is_temp:
2996 exc_checks.append("!%s" % self.result())
2998 exc_val = func_type.exception_value
2999 exc_check = func_type.exception_check
3000 if exc_val is not None:
3001 exc_checks.append("%s == %s" % (self.result(), exc_val))
3004 exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3006 exc_checks.append("PyErr_Occurred()")
3007 if self.is_temp or exc_checks:
3008 rhs = self.c_call_code()
3010 lhs = "%s = " % self.result()
3011 if self.is_temp and self.type.is_pyobject:
3012 #return_type = self.type # func_type.return_type
3013 #print "SimpleCallNode.generate_result_code: casting", rhs, \
3014 # "from", return_type, "to pyobject" ###
3015 rhs = typecast(py_object_type, self.type, rhs)
3018 if func_type.exception_check == '+':
3019 if func_type.exception_value is None:
3020 raise_py_exception = "__Pyx_CppExn2PyErr()"
3021 elif func_type.exception_value.type.is_pyobject:
3022 raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
3023 func_type.exception_value.entry.cname,
3024 func_type.exception_value.entry.cname)
3026 raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3028 raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
3030 "try {%s%s;} catch(...) {%s; %s}" % (
3034 code.error_goto(self.pos)))
3037 goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
3040 code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3041 if self.type.is_pyobject and self.result():
3042 code.put_gotref(self.py_result())
3043 if self.has_optional_args:
3044 code.funcstate.release_temp(self.opt_arg_struct)
3047 class PythonCapiFunctionNode(ExprNode):
3049 def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3053 self.type = func_type
3054 self.utility_code = utility_code
3056 def analyse_types(self, env):
3059 def generate_result_code(self, code):
3060 if self.utility_code:
3061 code.globalstate.use_utility_code(self.utility_code)
3063 def calculate_result_code(self):
3066 class PythonCapiCallNode(SimpleCallNode):
3067 # Python C-API Function call (only created in transforms)
3069 # By default, we assume that the call never returns None, as this
3070 # is true for most C-API functions in CPython. If this does not
3071 # apply to a call, set the following to True (or None to inherit
3072 # the default behaviour).
3073 may_return_none = False
3075 def __init__(self, pos, function_name, func_type,
3076 utility_code = None, py_name=None, **kwargs):
3077 self.type = func_type.return_type
3078 self.result_ctype = self.type
3079 self.function = PythonCapiFunctionNode(
3080 pos, py_name, function_name, func_type,
3081 utility_code = utility_code)
3082 # call this last so that we can override the constructed
3083 # attributes above with explicit keyword arguments if required
3084 SimpleCallNode.__init__(self, pos, **kwargs)
3087 class GeneralCallNode(CallNode):
3088 # General Python function call, including keyword,
3089 # * and ** arguments.
3092 # positional_args ExprNode Tuple of positional arguments
3093 # keyword_args ExprNode or None Dict of keyword arguments
3094 # starstar_arg ExprNode or None Dict of extra keyword args
3096 type = py_object_type
3098 subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
3100 nogil_check = Node.gil_error
3102 def compile_time_value(self, denv):
3103 function = self.function.compile_time_value(denv)
3104 positional_args = self.positional_args.compile_time_value(denv)
3105 keyword_args = self.keyword_args.compile_time_value(denv)
3106 starstar_arg = self.starstar_arg.compile_time_value(denv)
3108 keyword_args.update(starstar_arg)
3109 return function(*positional_args, **keyword_args)
3110 except Exception, e:
3111 self.compile_time_value_error(e)
3113 def explicit_args_kwds(self):
3114 if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3115 raise PostParseError(self.pos,
3116 'Compile-time keyword arguments must be explicit.')
3117 return self.positional_args.args, self.keyword_args
3119 def analyse_types(self, env):
3120 if self.analyse_as_type_constructor(env):
3122 self.function.analyse_types(env)
3123 self.positional_args.analyse_types(env)
3124 if self.keyword_args:
3125 self.keyword_args.analyse_types(env)
3126 if self.starstar_arg:
3127 self.starstar_arg.analyse_types(env)
3128 if not self.function.type.is_pyobject:
3129 if self.function.type.is_error:
3130 self.type = error_type
3132 if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3133 error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3135 self.function = self.function.coerce_to_pyobject(env)
3136 self.positional_args = \
3137 self.positional_args.coerce_to_pyobject(env)
3138 if self.starstar_arg:
3139 self.starstar_arg = \
3140 self.starstar_arg.coerce_to_pyobject(env)
3141 function = self.function
3142 if function.is_name and function.type_entry:
3143 # We are calling an extension type constructor. As long
3144 # as we do not support __new__(), the result type is clear
3145 self.type = function.type_entry.type
3146 self.result_ctype = py_object_type
3147 self.may_return_none = False
3149 self.type = py_object_type
3152 def generate_result_code(self, code):
3153 if self.type.is_error: return
3154 kwargs_call_function = "PyEval_CallObjectWithKeywords"
3155 if self.keyword_args and self.starstar_arg:
3156 code.put_error_if_neg(self.pos,
3157 "PyDict_Update(%s, %s)" % (
3158 self.keyword_args.py_result(),
3159 self.starstar_arg.py_result()))
3160 keyword_code = self.keyword_args.py_result()
3161 elif self.keyword_args:
3162 keyword_code = self.keyword_args.py_result()
3163 elif self.starstar_arg:
3164 keyword_code = self.starstar_arg.py_result()
3165 if self.starstar_arg.type is not Builtin.dict_type:
3166 # CPython supports calling functions with non-dicts, so do we
3167 code.globalstate.use_utility_code(kwargs_call_utility_code)
3168 kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
3171 if not keyword_code:
3172 call_code = "PyObject_Call(%s, %s, NULL)" % (
3173 self.function.py_result(),
3174 self.positional_args.py_result())
3176 call_code = "%s(%s, %s, %s)" % (
3177 kwargs_call_function,
3178 self.function.py_result(),
3179 self.positional_args.py_result(),
3185 code.error_goto_if_null(self.result(), self.pos)))
3186 code.put_gotref(self.py_result())
3189 class AsTupleNode(ExprNode):
3190 # Convert argument to tuple. Used for normalising
3191 # the * argument of a function call.
3197 def calculate_constant_result(self):
3198 self.constant_result = tuple(self.base.constant_result)
3200 def compile_time_value(self, denv):
3201 arg = self.arg.compile_time_value(denv)
3204 except Exception, e:
3205 self.compile_time_value_error(e)
3207 def analyse_types(self, env):
3208 self.arg.analyse_types(env)
3209 self.arg = self.arg.coerce_to_pyobject(env)
3210 self.type = tuple_type
3213 def may_be_none(self):
3216 nogil_check = Node.gil_error
3217 gil_message = "Constructing Python tuple"
3219 def generate_result_code(self, code):
3221 "%s = PySequence_Tuple(%s); %s" % (
3223 self.arg.py_result(),
3224 code.error_goto_if_null(self.result(), self.pos)))
3225 code.put_gotref(self.py_result())
3228 class AttributeNode(ExprNode):
3233 # needs_none_check boolean Used if obj is an extension type.
3234 # If set to True, it is known that the type is not None.
3238 # is_py_attr boolean Is a Python getattr operation
3239 # member string C name of struct member
3240 # is_called boolean Function call is being done on result
3241 # entry Entry Symbol table entry of attribute
3246 type = PyrexTypes.error_type
3249 needs_none_check = True
3251 def as_cython_attribute(self):
3252 if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
3253 return self.attribute
3254 cy = self.obj.as_cython_attribute()
3256 return "%s.%s" % (cy, self.attribute)
3258 def coerce_to(self, dst_type, env):
3259 # If coercing to a generic pyobject and this is a cpdef function
3260 # we can create the corresponding attribute
3261 if dst_type is py_object_type:
3263 if entry and entry.is_cfunction and entry.as_variable:
3264 # must be a cpdef function
3266 self.entry = entry.as_variable
3267 self.analyse_as_python_attribute(env)
3269 return ExprNode.coerce_to(self, dst_type, env)
3271 def calculate_constant_result(self):
3272 attr = self.attribute
3273 if attr.startswith("__") and attr.endswith("__"):
3275 self.constant_result = getattr(self.obj.constant_result, attr)
3277 def compile_time_value(self, denv):
3278 attr = self.attribute
3279 if attr.startswith("__") and attr.endswith("__"):
3281 "Invalid attribute name '%s' in compile-time expression" % attr)
3283 obj = self.obj.compile_time_value(denv)
3285 return getattr(obj, attr)
3286 except Exception, e:
3287 self.compile_time_value_error(e)
3289 def type_dependencies(self, env):
3290 return self.obj.type_dependencies(env)
3292 def infer_type(self, env):
3293 if self.analyse_as_cimported_attribute(env, 0):
3294 return self.entry.type
3295 elif self.analyse_as_unbound_cmethod(env):
3296 return self.entry.type
3298 self.analyse_attribute(env, obj_type = self.obj.infer_type(env))
3301 def analyse_target_declaration(self, env):
3304 def analyse_target_types(self, env):
3305 self.analyse_types(env, target = 1)
3307 def analyse_types(self, env, target = 0):
3308 if self.analyse_as_cimported_attribute(env, target):
3310 if not target and self.analyse_as_unbound_cmethod(env):
3312 self.analyse_as_ordinary_attribute(env, target)
3314 def analyse_as_cimported_attribute(self, env, target):
3315 # Try to interpret this as a reference to an imported
3316 # C const, type, var or function. If successful, mutates
3317 # this node into a NameNode and returns 1, otherwise
3319 module_scope = self.obj.analyse_as_module(env)
3321 entry = module_scope.lookup_here(self.attribute)
3323 entry.is_cglobal or entry.is_cfunction
3324 or entry.is_type or entry.is_const):
3325 self.mutate_into_name_node(env, entry, target)
3329 def analyse_as_unbound_cmethod(self, env):
3330 # Try to interpret this as a reference to an unbound
3331 # C method of an extension type. If successful, mutates
3332 # this node into a NameNode and returns 1, otherwise
3334 type = self.obj.analyse_as_extension_type(env)
3336 entry = type.scope.lookup_here(self.attribute)
3337 if entry and entry.is_cmethod:
3338 # Create a temporary entry describing the C method
3339 # as an ordinary function.
3340 ubcm_entry = Symtab.Entry(entry.name,
3341 "%s->%s" % (type.vtabptr_cname, entry.cname),
3343 ubcm_entry.is_cfunction = 1
3344 ubcm_entry.func_cname = entry.func_cname
3345 ubcm_entry.is_unbound_cmethod = 1
3346 self.mutate_into_name_node(env, ubcm_entry, None)
3350 def analyse_as_type(self, env):
3351 module_scope = self.obj.analyse_as_module(env)
3353 return module_scope.lookup_type(self.attribute)
3354 if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
3355 base_type = self.obj.analyse_as_type(env)
3356 if base_type and hasattr(base_type, 'scope'):
3357 return base_type.scope.lookup_type(self.attribute)
3360 def analyse_as_extension_type(self, env):
3361 # Try to interpret this as a reference to an extension type
3362 # in a cimported module. Returns the extension type, or None.
3363 module_scope = self.obj.analyse_as_module(env)
3365 entry = module_scope.lookup_here(self.attribute)
3366 if entry and entry.is_type and entry.type.is_extension_type:
3370 def analyse_as_module(self, env):
3371 # Try to interpret this as a reference to a cimported module
3372 # in another cimported module. Returns the module scope, or None.
3373 module_scope = self.obj.analyse_as_module(env)
3375 entry = module_scope.lookup_here(self.attribute)
3376 if entry and entry.as_module:
3377 return entry.as_module
3380 def mutate_into_name_node(self, env, entry, target):
3381 # Mutate this node into a NameNode and complete the
3382 # analyse_types phase.
3383 self.__class__ = NameNode
3384 self.name = self.attribute
3389 NameNode.analyse_target_types(self, env)
3391 NameNode.analyse_rvalue_entry(self, env)
3393 def analyse_as_ordinary_attribute(self, env, target):
3394 self.obj.analyse_types(env)
3395 self.analyse_attribute(env)
3396 if self.entry and self.entry.is_cmethod and not self.is_called:
3397 # error(self.pos, "C method can only be called")
3399 ## Reference to C array turns into pointer to first element.
3400 #while self.type.is_array:
3401 # self.type = self.type.element_ptr_type()
3405 self.result_ctype = py_object_type
3407 def analyse_attribute(self, env, obj_type = None):
3408 # Look up attribute and set self.type and self.member.
3410 self.member = self.attribute
3411 if obj_type is None:
3412 if self.obj.type.is_string:
3413 self.obj = self.obj.coerce_to_pyobject(env)
3414 obj_type = self.obj.type
3416 if obj_type.is_string:
3417 obj_type = py_object_type
3418 if obj_type.is_ptr or obj_type.is_array:
3419 obj_type = obj_type.base_type
3421 elif obj_type.is_extension_type:
3425 if obj_type.has_attributes:
3427 if obj_type.attributes_known():
3428 entry = obj_type.scope.lookup_here(self.attribute)
3429 if entry and entry.is_member:
3433 "Cannot select attribute of incomplete type '%s'"
3435 self.type = PyrexTypes.error_type
3439 if obj_type.is_extension_type and entry.name == "__weakref__":
3440 error(self.pos, "Illegal use of special attribute __weakref__")
3441 # methods need the normal attribute lookup
3442 # because they do not have struct entries
3443 if entry.is_variable or entry.is_cmethod:
3444 self.type = entry.type
3445 self.member = entry.cname
3448 # If it's not a variable or C method, it must be a Python
3449 # method of an extension type, so we treat it like a Python
3452 # If we get here, the base object is not a struct/union/extension
3453 # type, or it is an extension type and the attribute is either not
3454 # declared or is declared as a Python method. Treat it as a Python
3455 # attribute reference.
3456 self.analyse_as_python_attribute(env, obj_type)
3458 def analyse_as_python_attribute(self, env, obj_type = None):
3459 if obj_type is None:
3460 obj_type = self.obj.type
3461 self.member = self.attribute
3462 self.type = py_object_type
3464 if not obj_type.is_pyobject and not obj_type.is_error:
3465 if obj_type.can_coerce_to_pyobject(env):
3466 self.obj = self.obj.coerce_to_pyobject(env)
3469 "Object of type '%s' has no attribute '%s'" %
3470 (obj_type, self.attribute))
3472 def nogil_check(self, env):
3476 gil_message = "Accessing Python attribute"
3478 def is_simple(self):
3480 return self.result_in_temp() or self.obj.is_simple()
3482 return NameNode.is_simple(self)
3484 def is_lvalue(self):
3488 return NameNode.is_lvalue(self)
3490 def is_ephemeral(self):
3492 return self.obj.is_ephemeral()
3494 return NameNode.is_ephemeral(self)
3496 def calculate_result_code(self):
3497 #print "AttributeNode.calculate_result_code:", self.member ###
3498 #print "...obj node =", self.obj, "code", self.obj.result() ###
3499 #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
3501 obj_code = obj.result_as(obj.type)
3502 #print "...obj_code =", obj_code ###
3503 if self.entry and self.entry.is_cmethod:
3504 if obj.type.is_extension_type:
3505 return "((struct %s *)%s%s%s)->%s" % (
3506 obj.type.vtabstruct_cname, obj_code, self.op,
3507 obj.type.vtabslot_cname, self.member)
3510 elif obj.type.is_complex:
3511 return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
3513 return "%s%s%s" % (obj_code, self.op, self.member)
3515 def generate_result_code(self, code):
3516 interned_attr_cname = code.intern_identifier(self.attribute)
3519 '%s = PyObject_GetAttr(%s, %s); %s' % (
3521 self.obj.py_result(),
3522 interned_attr_cname,
3523 code.error_goto_if_null(self.result(), self.pos)))
3524 code.put_gotref(self.py_result())
3526 # result_code contains what is needed, but we may need to insert
3527 # a check and raise an exception
3528 if (self.obj.type.is_extension_type
3529 and self.needs_none_check
3530 and code.globalstate.directives['nonecheck']):
3531 self.put_nonecheck(code)
3533 def generate_assignment_code(self, rhs, code):
3534 interned_attr_cname = code.intern_identifier(self.attribute)
3535 self.obj.generate_evaluation_code(code)
3537 code.put_error_if_neg(self.pos,
3538 'PyObject_SetAttr(%s, %s, %s)' % (
3539 self.obj.py_result(),
3540 interned_attr_cname,
3542 rhs.generate_disposal_code(code)
3543 rhs.free_temps(code)
3544 elif self.obj.type.is_complex:
3545 code.putln("__Pyx_SET_C%s(%s, %s);" % (
3546 self.member.upper(),
3547 self.obj.result_as(self.obj.type),
3548 rhs.result_as(self.ctype())))
3550 if (self.obj.type.is_extension_type
3551 and self.needs_none_check
3552 and code.globalstate.directives['nonecheck']):
3553 self.put_nonecheck(code)
3555 select_code = self.result()
3556 if self.type.is_pyobject and self.use_managed_ref:
3557 rhs.make_owned_reference(code)
3558 code.put_giveref(rhs.py_result())
3559 code.put_gotref(select_code)
3560 code.put_decref(select_code, self.ctype())
3564 rhs.result_as(self.ctype())))
3566 rhs.generate_post_assignment_code(code)
3567 rhs.free_temps(code)
3568 self.obj.generate_disposal_code(code)
3569 self.obj.free_temps(code)
3571 def generate_deletion_code(self, code):
3572 interned_attr_cname = code.intern_identifier(self.attribute)
3573 self.obj.generate_evaluation_code(code)
3574 if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3575 and self.entry.scope.entries.has_key(u'__del__')):
3576 code.put_error_if_neg(self.pos,
3577 'PyObject_DelAttr(%s, %s)' % (
3578 self.obj.py_result(),
3579 interned_attr_cname))
3581 error(self.pos, "Cannot delete C attribute of extension type")
3582 self.obj.generate_disposal_code(code)
3583 self.obj.free_temps(code)
3585 def annotate(self, code):
3587 code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3589 code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3591 def put_nonecheck(self, code):
3592 code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3593 code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3594 code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3595 code.putln(code.error_goto(self.pos))
3599 #-------------------------------------------------------------------
3603 #-------------------------------------------------------------------
3605 class StarredTargetNode(ExprNode):
3606 # A starred expression like "*a"
3608 # This is only allowed in sequence assignment targets such as
3610 # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
3612 # and will be removed during type analysis (or generate an error
3613 # if it's found at unexpected places).
3617 subexprs = ['target']
3619 type = py_object_type
3622 def __init__(self, pos, target):
3624 self.target = target
3626 def analyse_declarations(self, env):
3627 error(self.pos, "can use starred expression only as assignment target")
3628 self.target.analyse_declarations(env)
3630 def analyse_types(self, env):
3631 error(self.pos, "can use starred expression only as assignment target")
3632 self.target.analyse_types(env)
3633 self.type = self.target.type
3635 def analyse_target_declaration(self, env):
3636 self.target.analyse_target_declaration(env)
3638 def analyse_target_types(self, env):
3639 self.target.analyse_target_types(env)
3640 self.type = self.target.type
3642 def calculate_result_code(self):
3645 def generate_result_code(self, code):
3649 class SequenceNode(ExprNode):
3650 # Base class for list and tuple constructor nodes.
3651 # Contains common code for performing sequence unpacking.
3655 # unpacked_items [ExprNode] or None
3656 # coerced_unpacked_items [ExprNode] or None
3660 is_sequence_constructor = 1
3661 unpacked_items = None
3663 def compile_time_value_list(self, denv):
3664 return [arg.compile_time_value(denv) for arg in self.args]
3666 def replace_starred_target_node(self):
3667 # replace a starred node in the targets by the contained expression
3668 self.starred_assignment = False
3670 for arg in self.args:
3672 if self.starred_assignment:
3673 error(arg.pos, "more than 1 starred expression in assignment")
3674 self.starred_assignment = True
3676 arg.is_starred = True
3680 def analyse_target_declaration(self, env):
3681 self.replace_starred_target_node()
3682 for arg in self.args:
3683 arg.analyse_target_declaration(env)
3685 def analyse_types(self, env, skip_children=False):
3686 for i in range(len(self.args)):
3688 if not skip_children: arg.analyse_types(env)
3689 self.args[i] = arg.coerce_to_pyobject(env)
3691 # not setting self.type here, subtypes do this
3693 def may_be_none(self):
3696 def analyse_target_types(self, env):
3697 self.iterator = PyTempNode(self.pos, env)
3698 self.unpacked_items = []
3699 self.coerced_unpacked_items = []
3700 for arg in self.args:
3701 arg.analyse_target_types(env)
3703 if not arg.type.assignable_from(Builtin.list_type):
3705 "starred target must have Python object (list) type")
3706 if arg.type is py_object_type:
3707 arg.type = Builtin.list_type
3708 unpacked_item = PyTempNode(self.pos, env)
3709 coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3710 self.unpacked_items.append(unpacked_item)
3711 self.coerced_unpacked_items.append(coerced_unpacked_item)
3712 self.type = py_object_type
3714 def generate_result_code(self, code):
3715 self.generate_operation_code(code)
3717 def generate_assignment_code(self, rhs, code):
3718 if self.starred_assignment:
3719 self.generate_starred_assignment_code(rhs, code)
3721 self.generate_parallel_assignment_code(rhs, code)
3723 for item in self.unpacked_items:
3725 rhs.free_temps(code)
3727 def generate_parallel_assignment_code(self, rhs, code):
3728 # Need to work around the fact that generate_evaluation_code
3729 # allocates the temps in a rather hacky way -- the assignment
3730 # is evaluated twice, within each if-block.
3732 if rhs.type is tuple_type:
3733 tuple_check = "likely(%s != Py_None)"
3735 tuple_check = "PyTuple_CheckExact(%s)"
3737 "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3738 tuple_check % rhs.py_result(),
3741 code.putln("PyObject* tuple = %s;" % rhs.py_result())
3742 for item in self.unpacked_items:
3744 for i in range(len(self.args)):
3745 item = self.unpacked_items[i]
3747 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3750 code.put_incref(item.result(), item.ctype())
3751 value_node = self.coerced_unpacked_items[i]
3752 value_node.generate_evaluation_code(code)
3753 rhs.generate_disposal_code(code)
3755 for i in range(len(self.args)):
3756 self.args[i].generate_assignment_code(
3757 self.coerced_unpacked_items[i], code)
3759 code.putln("} else {")
3761 if rhs.type is tuple_type:
3762 code.globalstate.use_utility_code(tuple_unpacking_error_code)
3763 code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3764 rhs.py_result(), len(self.args)))
3765 code.putln(code.error_goto(self.pos))
3767 code.globalstate.use_utility_code(unpacking_utility_code)
3769 self.iterator.allocate(code)
3771 "%s = PyObject_GetIter(%s); %s" % (
3772 self.iterator.result(),
3774 code.error_goto_if_null(self.iterator.result(), self.pos)))
3775 code.put_gotref(self.iterator.py_result())
3776 rhs.generate_disposal_code(code)
3777 for i in range(len(self.args)):
3778 item = self.unpacked_items[i]
3779 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3780 self.iterator.py_result(), i)
3784 typecast(item.ctype(), py_object_type, unpack_code),
3785 code.error_goto_if_null(item.result(), self.pos)))
3786 code.put_gotref(item.py_result())
3787 value_node = self.coerced_unpacked_items[i]
3788 value_node.generate_evaluation_code(code)
3789 code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
3790 self.iterator.py_result(),
3792 if debug_disposal_code:
3793 print("UnpackNode.generate_assignment_code:")
3794 print("...generating disposal code for %s" % self.iterator)
3795 self.iterator.generate_disposal_code(code)
3796 self.iterator.free_temps(code)
3797 self.iterator.release(code)
3799 for i in range(len(self.args)):
3800 self.args[i].generate_assignment_code(
3801 self.coerced_unpacked_items[i], code)
3805 def generate_starred_assignment_code(self, rhs, code):
3806 code.globalstate.use_utility_code(unpacking_utility_code)
3808 for i, arg in enumerate(self.args):
3810 starred_target = self.unpacked_items[i]
3811 fixed_args_left = self.args[:i]
3812 fixed_args_right = self.args[i+1:]
3815 self.iterator.allocate(code)
3817 "%s = PyObject_GetIter(%s); %s" % (
3818 self.iterator.result(),
3820 code.error_goto_if_null(self.iterator.result(), self.pos)))
3821 code.put_gotref(self.iterator.py_result())
3822 rhs.generate_disposal_code(code)
3824 for item in self.unpacked_items:
3826 for i in range(len(fixed_args_left)):
3827 item = self.unpacked_items[i]
3828 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3829 self.iterator.py_result(), i)
3833 typecast(item.ctype(), py_object_type, unpack_code),
3834 code.error_goto_if_null(item.result(), self.pos)))
3835 code.put_gotref(item.py_result())
3836 value_node = self.coerced_unpacked_items[i]
3837 value_node.generate_evaluation_code(code)
3839 target_list = starred_target.result()
3840 code.putln("%s = PySequence_List(%s); %s" % (
3841 target_list, self.iterator.py_result(),
3842 code.error_goto_if_null(target_list, self.pos)))
3843 code.put_gotref(target_list)
3844 if fixed_args_right:
3845 code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
3846 unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
3847 code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
3848 (target_list, len(unpacked_right_args))))
3849 code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
3850 len(fixed_args_left), target_list,
3851 code.error_goto(self.pos)))
3853 for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
3854 self.coerced_unpacked_items[::-1])):
3856 "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
3858 target_list, target_list))
3859 # resize the list the hard way
3860 code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
3861 code.put_gotref(arg.py_result())
3862 coerced_arg.generate_evaluation_code(code)
3864 self.iterator.generate_disposal_code(code)
3865 self.iterator.free_temps(code)
3866 self.iterator.release(code)
3868 for i in range(len(self.args)):
3869 self.args[i].generate_assignment_code(
3870 self.coerced_unpacked_items[i], code)
3872 def annotate(self, code):
3873 for arg in self.args:
3875 if self.unpacked_items:
3876 for arg in self.unpacked_items:
3878 for arg in self.coerced_unpacked_items:
3882 class TupleNode(SequenceNode):
3883 # Tuple constructor.
3887 gil_message = "Constructing Python tuple"
3889 def analyse_types(self, env, skip_children=False):
3890 if len(self.args) == 0:
3894 SequenceNode.analyse_types(self, env, skip_children)
3896 def calculate_result_code(self):
3897 if len(self.args) > 0:
3898 error(self.pos, "Positive length tuples must be constructed.")
3900 return Naming.empty_tuple
3902 def calculate_constant_result(self):
3903 self.constant_result = tuple([
3904 arg.constant_result for arg in self.args])
3906 def compile_time_value(self, denv):
3907 values = self.compile_time_value_list(denv)
3909 return tuple(values)
3910 except Exception, e:
3911 self.compile_time_value_error(e)
3913 def generate_operation_code(self, code):
3914 if len(self.args) == 0:
3915 # result_code is Naming.empty_tuple
3918 "%s = PyTuple_New(%s); %s" % (
3921 code.error_goto_if_null(self.result(), self.pos)))
3922 code.put_gotref(self.py_result())
3923 for i in range(len(self.args)):
3925 if not arg.result_in_temp():
3926 code.put_incref(arg.result(), arg.ctype())
3928 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3932 code.put_giveref(arg.py_result())
3934 def generate_subexpr_disposal_code(self, code):
3935 # We call generate_post_assignment_code here instead
3936 # of generate_disposal_code, because values were stored
3937 # in the tuple using a reference-stealing operation.
3938 for arg in self.args:
3939 arg.generate_post_assignment_code(code)
3940 # Should NOT call free_temps -- this is invoked by the default
3941 # generate_evaluation_code which will do that.
3944 class ListNode(SequenceNode):
3947 # obj_conversion_errors [PyrexError] used internally
3948 # orignial_args [ExprNode] used internally
3950 obj_conversion_errors = []
3953 gil_message = "Constructing Python list"
3955 def type_dependencies(self, env):
3958 def infer_type(self, env):
3959 # TOOD: Infer non-object list arrays.
3962 def analyse_expressions(self, env):
3963 SequenceNode.analyse_expressions(self, env)
3964 self.coerce_to_pyobject(env)
3966 def analyse_types(self, env):
3968 self.original_args = list(self.args)
3969 SequenceNode.analyse_types(self, env)
3970 self.obj_conversion_errors = held_errors()
3971 release_errors(ignore=True)
3973 def coerce_to(self, dst_type, env):
3974 if dst_type.is_pyobject:
3975 for err in self.obj_conversion_errors:
3977 self.obj_conversion_errors = []
3978 if not self.type.subtype_of(dst_type):
3979 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3980 elif dst_type.is_ptr:
3981 base_type = dst_type.base_type
3982 self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3983 for i in range(len(self.original_args)):
3985 if isinstance(arg, CoerceToPyTypeNode):
3987 self.args[i] = arg.coerce_to(base_type, env)
3988 elif dst_type.is_struct:
3989 if len(self.args) > len(dst_type.scope.var_entries):
3990 error(self.pos, "Too may members for '%s'" % dst_type)
3992 if len(self.args) < len(dst_type.scope.var_entries):
3993 warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3994 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3995 if isinstance(arg, CoerceToPyTypeNode):
3997 self.args[i] = arg.coerce_to(member.type, env)
3998 self.type = dst_type
4000 self.type = error_type
4001 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4004 def release_temp(self, env):
4005 if self.type.is_array:
4006 # To be valid C++, we must allocate the memory on the stack
4007 # manually and be sure not to reuse it for something else.
4010 SequenceNode.release_temp(self, env)
4012 def calculate_constant_result(self):
4013 self.constant_result = [
4014 arg.constant_result for arg in self.args]
4016 def compile_time_value(self, denv):
4017 return self.compile_time_value_list(denv)
4019 def generate_operation_code(self, code):
4020 if self.type.is_pyobject:
4021 for err in self.obj_conversion_errors:
4023 code.putln("%s = PyList_New(%s); %s" %
4026 code.error_goto_if_null(self.result(), self.pos)))
4027 code.put_gotref(self.py_result())
4028 for i in range(len(self.args)):
4030 #if not arg.is_temp:
4031 if not arg.result_in_temp():
4032 code.put_incref(arg.result(), arg.ctype())
4033 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
4037 code.put_giveref(arg.py_result())
4038 elif self.type.is_array:
4039 for i, arg in enumerate(self.args):
4040 code.putln("%s[%s] = %s;" % (
4044 elif self.type.is_struct:
4045 for arg, member in zip(self.args, self.type.scope.var_entries):
4046 code.putln("%s.%s = %s;" % (
4051 raise InternalError("List type never specified")
4053 def generate_subexpr_disposal_code(self, code):
4054 # We call generate_post_assignment_code here instead
4055 # of generate_disposal_code, because values were stored
4056 # in the list using a reference-stealing operation.
4057 for arg in self.args:
4058 arg.generate_post_assignment_code(code)
4059 # Should NOT call free_temps -- this is invoked by the default
4060 # generate_evaluation_code which will do that.
4063 class ScopedExprNode(ExprNode):
4064 # Abstract base class for ExprNodes that have their own local
4065 # scope, such as generator expressions.
4067 # expr_scope Scope the inner scope of the expression
4072 def analyse_types(self, env):
4073 # nothing to do here, the children will be analysed separately
4076 def analyse_expressions(self, env):
4077 # nothing to do here, the children will be analysed separately
4080 def analyse_scoped_expressions(self, env):
4081 # this is called with the expr_scope as env
4084 def init_scope(self, outer_scope, expr_scope=None):
4085 self.expr_scope = expr_scope
4088 class ComprehensionNode(ScopedExprNode):
4089 subexprs = ["target"]
4090 child_attrs = ["loop", "append"]
4092 # leak loop variables or not? non-leaking Py3 behaviour is
4093 # default, except for list comprehensions where the behaviour
4094 # differs in Py2 and Py3 (see Parsing.py)
4095 has_local_scope = True
4097 def infer_type(self, env):
4098 return self.target.infer_type(env)
4100 def analyse_declarations(self, env):
4101 self.append.target = self # this is used in the PyList_Append of the inner loop
4102 self.init_scope(env)
4103 if self.expr_scope is not None:
4104 self.loop.analyse_declarations(self.expr_scope)
4106 self.loop.analyse_declarations(env)
4108 def init_scope(self, outer_scope, expr_scope=None):
4109 if expr_scope is not None:
4110 self.expr_scope = expr_scope
4111 elif self.has_local_scope:
4112 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4114 self.expr_scope = None
4116 def analyse_types(self, env):
4117 self.target.analyse_expressions(env)
4118 self.type = self.target.type
4119 if not self.has_local_scope:
4120 self.loop.analyse_expressions(env)
4122 def analyse_expressions(self, env):
4123 self.analyse_types(env)
4125 def analyse_scoped_expressions(self, env):
4126 if self.has_local_scope:
4127 self.loop.analyse_expressions(env)
4129 def may_be_none(self):
4132 def calculate_result_code(self):
4133 return self.target.result()
4135 def generate_result_code(self, code):
4136 self.generate_operation_code(code)
4138 def generate_operation_code(self, code):
4139 self.loop.generate_execution_code(code)
4141 def annotate(self, code):
4142 self.loop.annotate(code)
4145 class ComprehensionAppendNode(Node):
4146 # Need to be careful to avoid infinite recursion:
4147 # target must not be in child_attrs/subexprs
4149 child_attrs = ['expr']
4151 type = PyrexTypes.c_int_type
4153 def analyse_expressions(self, env):
4154 self.expr.analyse_expressions(env)
4155 if not self.expr.type.is_pyobject:
4156 self.expr = self.expr.coerce_to_pyobject(env)
4158 def generate_execution_code(self, code):
4159 if self.target.type is list_type:
4160 function = "PyList_Append"
4161 elif self.target.type is set_type:
4162 function = "PySet_Add"
4164 raise InternalError(
4165 "Invalid type for comprehension node: %s" % self.target.type)
4167 self.expr.generate_evaluation_code(code)
4168 code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
4170 self.target.result(),
4173 self.expr.generate_disposal_code(code)
4174 self.expr.free_temps(code)
4176 def generate_function_definitions(self, env, code):
4177 self.expr.generate_function_definitions(env, code)
4179 def annotate(self, code):
4180 self.expr.annotate(code)
4182 class DictComprehensionAppendNode(ComprehensionAppendNode):
4183 child_attrs = ['key_expr', 'value_expr']
4185 def analyse_expressions(self, env):
4186 self.key_expr.analyse_expressions(env)
4187 if not self.key_expr.type.is_pyobject:
4188 self.key_expr = self.key_expr.coerce_to_pyobject(env)
4189 self.value_expr.analyse_expressions(env)
4190 if not self.value_expr.type.is_pyobject:
4191 self.value_expr = self.value_expr.coerce_to_pyobject(env)
4193 def generate_execution_code(self, code):
4194 self.key_expr.generate_evaluation_code(code)
4195 self.value_expr.generate_evaluation_code(code)
4196 code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
4197 self.target.result(),
4198 self.key_expr.result(),
4199 self.value_expr.result()
4201 self.key_expr.generate_disposal_code(code)
4202 self.key_expr.free_temps(code)
4203 self.value_expr.generate_disposal_code(code)
4204 self.value_expr.free_temps(code)
4206 def generate_function_definitions(self, env, code):
4207 self.key_expr.generate_function_definitions(env, code)
4208 self.value_expr.generate_function_definitions(env, code)
4210 def annotate(self, code):
4211 self.key_expr.annotate(code)
4212 self.value_expr.annotate(code)
4215 class GeneratorExpressionNode(ScopedExprNode):
4216 # A generator expression, e.g. (i for i in range(10))
4218 # Result is a generator.
4220 # loop ForStatNode the for-loop, containing a YieldExprNode
4222 child_attrs = ["loop"]
4224 type = py_object_type
4226 def analyse_declarations(self, env):
4227 self.init_scope(env)
4228 self.loop.analyse_declarations(self.expr_scope)
4230 def init_scope(self, outer_scope, expr_scope=None):
4231 if expr_scope is not None:
4232 self.expr_scope = expr_scope
4234 self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
4236 def analyse_types(self, env):
4239 def analyse_scoped_expressions(self, env):
4240 self.loop.analyse_expressions(env)
4242 def may_be_none(self):
4245 def annotate(self, code):
4246 self.loop.annotate(code)
4249 class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
4250 # An inlined generator expression for which the result is
4251 # calculated inside of the loop. This will only be created by
4252 # transforms when replacing builtin calls on generator
4255 # loop ForStatNode the for-loop, not containing any YieldExprNodes
4256 # result_node ResultRefNode the reference to the result value temp
4257 # orig_func String the name of the builtin function this node replaces
4259 child_attrs = ["loop"]
4261 def analyse_types(self, env):
4262 self.type = self.result_node.type
4265 def coerce_to(self, dst_type, env):
4266 if self.orig_func == 'sum' and dst_type.is_numeric:
4267 # we can optimise by dropping the aggregation variable into C
4268 self.result_node.type = self.type = dst_type
4270 return GeneratorExpressionNode.coerce_to(self, dst_type, env)
4272 def generate_result_code(self, code):
4273 self.result_node.result_code = self.result()
4274 self.loop.generate_execution_code(code)
4277 class SetNode(ExprNode):
4284 gil_message = "Constructing Python set"
4286 def analyse_types(self, env):
4287 for i in range(len(self.args)):
4289 arg.analyse_types(env)
4290 self.args[i] = arg.coerce_to_pyobject(env)
4291 self.type = set_type
4294 def may_be_none(self):
4297 def calculate_constant_result(self):
4298 self.constant_result = set([
4299 arg.constant_result for arg in self.args])
4301 def compile_time_value(self, denv):
4302 values = [arg.compile_time_value(denv) for arg in self.args]
4305 except Exception, e:
4306 self.compile_time_value_error(e)
4308 def generate_evaluation_code(self, code):
4309 code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4310 self.allocate_temp_result(code)
4312 "%s = PySet_New(0); %s" % (
4314 code.error_goto_if_null(self.result(), self.pos)))
4315 code.put_gotref(self.py_result())
4316 for arg in self.args:
4317 arg.generate_evaluation_code(code)
4319 code.error_goto_if_neg(
4320 "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
4322 arg.generate_disposal_code(code)
4323 arg.free_temps(code)
4326 class DictNode(ExprNode):
4327 # Dictionary constructor.
4329 # key_value_pairs [DictItemNode]
4331 # obj_conversion_errors [PyrexError] used internally
4333 subexprs = ['key_value_pairs']
4337 obj_conversion_errors = []
4339 def calculate_constant_result(self):
4340 self.constant_result = dict([
4341 item.constant_result for item in self.key_value_pairs])
4343 def compile_time_value(self, denv):
4344 pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
4345 for item in self.key_value_pairs]
4348 except Exception, e:
4349 self.compile_time_value_error(e)
4351 def type_dependencies(self, env):
4354 def infer_type(self, env):
4355 # TOOD: Infer struct constructors.
4358 def analyse_types(self, env):
4360 for item in self.key_value_pairs:
4361 item.analyse_types(env)
4362 self.obj_conversion_errors = held_errors()
4363 release_errors(ignore=True)
4365 def may_be_none(self):
4368 def coerce_to(self, dst_type, env):
4369 if dst_type.is_pyobject:
4370 self.release_errors()
4371 if not self.type.subtype_of(dst_type):
4372 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4373 elif dst_type.is_struct_or_union:
4374 self.type = dst_type
4375 if not dst_type.is_struct and len(self.key_value_pairs) != 1:
4376 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
4377 elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
4378 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
4379 for item in self.key_value_pairs:
4380 if isinstance(item.key, CoerceToPyTypeNode):
4381 item.key = item.key.arg
4382 if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4383 error(item.key.pos, "Invalid struct field identifier")
4384 item.key = StringNode(item.key.pos, value="<error>")
4386 key = str(item.key.value) # converts string literals to unicode in Py3
4387 member = dst_type.scope.lookup_here(key)
4389 error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4392 if isinstance(value, CoerceToPyTypeNode):
4394 item.value = value.coerce_to(member.type, env)
4396 self.type = error_type
4397 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
4400 def release_errors(self):
4401 for err in self.obj_conversion_errors:
4403 self.obj_conversion_errors = []
4405 gil_message = "Constructing Python dict"
4407 def generate_evaluation_code(self, code):
4408 # Custom method used here because key-value
4409 # pairs are evaluated and used one at a time.
4410 code.mark_pos(self.pos)
4411 self.allocate_temp_result(code)
4412 if self.type.is_pyobject:
4413 self.release_errors()
4415 "%s = PyDict_New(); %s" % (
4417 code.error_goto_if_null(self.result(), self.pos)))
4418 code.put_gotref(self.py_result())
4419 for item in self.key_value_pairs:
4420 item.generate_evaluation_code(code)
4421 if self.type.is_pyobject:
4422 code.put_error_if_neg(self.pos,
4423 "PyDict_SetItem(%s, %s, %s)" % (
4425 item.key.py_result(),
4426 item.value.py_result()))
4428 code.putln("%s.%s = %s;" % (
4431 item.value.result()))
4432 item.generate_disposal_code(code)
4433 item.free_temps(code)
4435 def annotate(self, code):
4436 for item in self.key_value_pairs:
4439 class DictItemNode(ExprNode):
4440 # Represents a single item in a DictNode
4444 subexprs = ['key', 'value']
4446 nogil_check = None # Parent DictNode takes care of it
4448 def calculate_constant_result(self):
4449 self.constant_result = (
4450 self.key.constant_result, self.value.constant_result)
4452 def analyse_types(self, env):
4453 self.key.analyse_types(env)
4454 self.value.analyse_types(env)
4455 self.key = self.key.coerce_to_pyobject(env)
4456 self.value = self.value.coerce_to_pyobject(env)
4458 def generate_evaluation_code(self, code):
4459 self.key.generate_evaluation_code(code)
4460 self.value.generate_evaluation_code(code)
4462 def generate_disposal_code(self, code):
4463 self.key.generate_disposal_code(code)
4464 self.value.generate_disposal_code(code)
4466 def free_temps(self, code):
4467 self.key.free_temps(code)
4468 self.value.free_temps(code)
4471 return iter([self.key, self.value])
4473 class ModuleNameMixin(object):
4474 def set_mod_name(self, env):
4475 self.module_name = env.global_scope().qualified_name
4477 def get_py_mod_name(self, code):
4478 return code.get_py_string_const(
4479 self.module_name, identifier=True)
4481 class ClassNode(ExprNode, ModuleNameMixin):
4482 # Helper class used in the implementation of Python
4483 # class definitions. Constructs a class object given
4484 # a name, tuple of bases and class dictionary.
4486 # name EncodedString Name of the class
4487 # bases ExprNode Base class tuple
4488 # dict ExprNode Class dict (not owned by this node)
4489 # doc ExprNode or None Doc string
4490 # module_name EncodedString Name of defining module
4491 # keyword_args ExprNode or None Py3 Dict of keyword arguments, passed to __new__
4492 # starstar_arg ExprNode or None Py3 Dict of extra keyword args, same here
4494 subexprs = ['bases', 'keyword_args', 'starstar_arg', 'doc']
4496 def analyse_types(self, env):
4497 self.bases.analyse_types(env)
4499 self.doc.analyse_types(env)
4500 self.doc = self.doc.coerce_to_pyobject(env)
4501 if self.keyword_args:
4502 self.keyword_args.analyse_types(env)
4503 if self.starstar_arg:
4504 self.starstar_arg.analyse_types(env)
4505 # make sure we have a Python object as **kwargs mapping
4506 self.starstar_arg = \
4507 self.starstar_arg.coerce_to_pyobject(env)
4508 self.type = py_object_type
4510 env.use_utility_code(create_class_utility_code);
4511 #TODO(craig,haoyu) This should be moved to a better place
4512 self.set_mod_name(env)
4514 def may_be_none(self):
4517 gil_message = "Constructing Python class"
4519 def generate_result_code(self, code):
4520 cname = code.intern_identifier(self.name)
4521 if self.keyword_args and self.starstar_arg:
4522 code.put_error_if_neg(self.pos,
4523 "PyDict_Update(%s, %s)" % (
4524 self.keyword_args.py_result(),
4525 self.starstar_arg.py_result()))
4526 keyword_code = self.keyword_args.py_result()
4527 elif self.keyword_args:
4528 keyword_code = self.keyword_args.py_result()
4529 elif self.starstar_arg:
4530 keyword_code = self.starstar_arg.py_result()
4532 keyword_code = 'NULL'
4535 code.put_error_if_neg(self.pos,
4536 'PyDict_SetItemString(%s, "__doc__", %s)' % (
4537 self.dict.py_result(),
4538 self.doc.py_result()))
4539 py_mod_name = self.get_py_mod_name(code)
4541 '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
4543 self.bases.py_result(),
4544 self.dict.py_result(),
4548 code.error_goto_if_null(self.result(), self.pos)))
4549 code.put_gotref(self.py_result())
4552 class BoundMethodNode(ExprNode):
4553 # Helper class used in the implementation of Python
4554 # class definitions. Constructs an bound method
4555 # object from a class and a function.
4557 # function ExprNode Function object
4558 # self_object ExprNode self object
4560 subexprs = ['function']
4562 def analyse_types(self, env):
4563 self.function.analyse_types(env)
4564 self.type = py_object_type
4567 gil_message = "Constructing an bound method"
4569 def generate_result_code(self, code):
4571 "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
4573 self.function.py_result(),
4574 self.self_object.py_result(),
4575 self.self_object.py_result(),
4576 code.error_goto_if_null(self.result(), self.pos)))
4577 code.put_gotref(self.py_result())
4579 class UnboundMethodNode(ExprNode):
4580 # Helper class used in the implementation of Python
4581 # class definitions. Constructs an unbound method
4582 # object from a class and a function.
4584 # function ExprNode Function object
4586 type = py_object_type
4589 subexprs = ['function']
4591 def analyse_types(self, env):
4592 self.function.analyse_types(env)
4594 def may_be_none(self):
4597 gil_message = "Constructing an unbound method"
4599 def generate_result_code(self, code):
4600 class_cname = code.pyclass_stack[-1].classobj.result()
4602 "%s = PyMethod_New(%s, 0, %s); %s" % (
4604 self.function.py_result(),
4606 code.error_goto_if_null(self.result(), self.pos)))
4607 code.put_gotref(self.py_result())
4610 class PyCFunctionNode(ExprNode, ModuleNameMixin):
4611 # Helper class used in the implementation of Python
4612 # class definitions. Constructs a PyCFunction object
4613 # from a PyMethodDef struct.
4615 # pymethdef_cname string PyMethodDef structure
4616 # self_object ExprNode or None
4618 # module_name EncodedString Name of defining module
4624 type = py_object_type
4627 def analyse_types(self, env):
4629 env.use_utility_code(binding_cfunc_utility_code)
4631 #TODO(craig,haoyu) This should be moved to a better place
4632 self.set_mod_name(env)
4634 def may_be_none(self):
4637 gil_message = "Constructing Python function"
4639 def self_result_code(self):
4640 if self.self_object is None:
4641 self_result = "NULL"
4643 self_result = self.self_object.py_result()
4646 def generate_result_code(self, code):
4648 constructor = "%s_NewEx" % Naming.binding_cfunc
4650 constructor = "PyCFunction_NewEx"
4651 py_mod_name = self.get_py_mod_name(code)
4653 '%s = %s(&%s, %s, %s); %s' % (
4656 self.pymethdef_cname,
4657 self.self_result_code(),
4659 code.error_goto_if_null(self.result(), self.pos)))
4660 code.put_gotref(self.py_result())
4662 class InnerFunctionNode(PyCFunctionNode):
4663 # Special PyCFunctionNode that depends on a closure class
4667 def self_result_code(self):
4668 return "((PyObject*)%s)" % Naming.cur_scope_cname
4670 class LambdaNode(InnerFunctionNode):
4671 # Lambda expression node (only used as a function reference)
4673 # args [CArgDeclNode] formal arguments
4674 # star_arg PyArgDeclNode or None * argument
4675 # starstar_arg PyArgDeclNode or None ** argument
4676 # lambda_name string a module-globally unique lambda name
4677 # result_expr ExprNode
4678 # def_node DefNode the underlying function 'def' node
4680 child_attrs = ['def_node']
4683 name = StringEncoding.EncodedString('<lambda>')
4685 def analyse_declarations(self, env):
4686 #self.def_node.needs_closure = self.needs_closure
4687 self.def_node.analyse_declarations(env)
4688 self.pymethdef_cname = self.def_node.entry.pymethdef_cname
4689 env.add_lambda_def(self.def_node)
4691 class YieldExprNode(ExprNode):
4692 # Yield expression node
4694 # arg ExprNode the value to return from the generator
4695 # label_name string name of the C label used for this yield
4698 type = py_object_type
4700 def analyse_types(self, env):
4702 if self.arg is not None:
4703 self.arg.analyse_types(env)
4704 if not self.arg.type.is_pyobject:
4705 self.arg = self.arg.coerce_to_pyobject(env)
4706 error(self.pos, "Generators are not supported")
4708 def generate_result_code(self, code):
4709 self.label_name = code.new_label('resume_from_yield')
4710 code.use_label(self.label_name)
4711 code.putln("/* FIXME: save temporary variables */")
4712 code.putln("/* FIXME: return from function, yielding value */")
4713 code.put_label(self.label_name)
4714 code.putln("/* FIXME: restore temporary variables and */")
4715 code.putln("/* FIXME: extract sent value from closure */")
4718 #-------------------------------------------------------------------
4720 # Unary operator nodes
4722 #-------------------------------------------------------------------
4724 compile_time_unary_operators = {
4725 'not': operator.not_,
4731 class UnopNode(ExprNode):
4735 # Processing during analyse_expressions phase:
4737 # analyse_c_operation
4738 # Called when the operand is not a pyobject.
4739 # - Check operand type and coerce if needed.
4740 # - Determine result type and result code fragment.
4741 # - Allocate temporary for result if needed.
4743 subexprs = ['operand']
4746 def calculate_constant_result(self):
4747 func = compile_time_unary_operators[self.operator]
4748 self.constant_result = func(self.operand.constant_result)
4750 def compile_time_value(self, denv):
4751 func = compile_time_unary_operators.get(self.operator)
4754 "Unary '%s' not supported in compile-time expression"
4756 operand = self.operand.compile_time_value(denv)
4758 return func(operand)
4759 except Exception, e:
4760 self.compile_time_value_error(e)
4762 def infer_type(self, env):
4763 operand_type = self.operand.infer_type(env)
4764 if operand_type.is_pyobject:
4765 return py_object_type
4769 def analyse_types(self, env):
4770 self.operand.analyse_types(env)
4771 if self.is_py_operation():
4772 self.coerce_operand_to_pyobject(env)
4773 self.type = py_object_type
4775 elif self.is_cpp_operation():
4776 self.analyse_cpp_operation(env)
4778 self.analyse_c_operation(env)
4780 def check_const(self):
4781 return self.operand.check_const()
4783 def is_py_operation(self):
4784 return self.operand.type.is_pyobject
4786 def nogil_check(self, env):
4787 if self.is_py_operation():
4790 def is_cpp_operation(self):
4791 type = self.operand.type
4792 return type.is_cpp_class
4794 def coerce_operand_to_pyobject(self, env):
4795 self.operand = self.operand.coerce_to_pyobject(env)
4797 def generate_result_code(self, code):
4798 if self.operand.type.is_pyobject:
4799 self.generate_py_operation_code(code)
4801 def generate_py_operation_code(self, code):
4802 function = self.py_operation_function()
4804 "%s = %s(%s); %s" % (
4807 self.operand.py_result(),
4808 code.error_goto_if_null(self.result(), self.pos)))
4809 code.put_gotref(self.py_result())
4811 def type_error(self):
4812 if not self.operand.type.is_error:
4813 error(self.pos, "Invalid operand type for '%s' (%s)" %
4814 (self.operator, self.operand.type))
4815 self.type = PyrexTypes.error_type
4817 def analyse_cpp_operation(self, env):
4818 type = self.operand.type
4820 type = type.base_type
4821 function = type.scope.lookup("operator%s" % self.operator)
4823 error(self.pos, "'%s' operator not defined for %s"
4824 % (self.operator, type))
4827 func_type = function.type
4828 if func_type.is_ptr:
4829 func_type = func_type.base_type
4830 self.type = func_type.return_type
4833 class NotNode(ExprNode):
4838 type = PyrexTypes.c_bint_type
4840 subexprs = ['operand']
4842 def calculate_constant_result(self):
4843 self.constant_result = not self.operand.constant_result
4845 def compile_time_value(self, denv):
4846 operand = self.operand.compile_time_value(denv)
4849 except Exception, e:
4850 self.compile_time_value_error(e)
4852 def infer_type(self, env):
4853 return PyrexTypes.c_bint_type
4855 def analyse_types(self, env):
4856 self.operand.analyse_types(env)
4857 self.operand = self.operand.coerce_to_boolean(env)
4859 def calculate_result_code(self):
4860 return "(!%s)" % self.operand.result()
4862 def generate_result_code(self, code):
4866 class UnaryPlusNode(UnopNode):
4867 # unary '+' operator
4871 def analyse_c_operation(self, env):
4872 self.type = self.operand.type
4874 def py_operation_function(self):
4875 return "PyNumber_Positive"
4877 def calculate_result_code(self):
4878 if self.is_cpp_operation():
4879 return "(+%s)" % self.operand.result()
4881 return self.operand.result()
4884 class UnaryMinusNode(UnopNode):
4885 # unary '-' operator
4889 def analyse_c_operation(self, env):
4890 if self.operand.type.is_numeric:
4891 self.type = self.operand.type
4894 if self.type.is_complex:
4897 def py_operation_function(self):
4898 return "PyNumber_Negative"
4900 def calculate_result_code(self):
4902 return "(-%s)" % self.operand.result()
4904 return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
4906 def get_constant_c_result_code(self):
4907 value = self.operand.get_constant_c_result_code()
4909 return "(-%s)" % (value)
4911 class TildeNode(UnopNode):
4912 # unary '~' operator
4914 def analyse_c_operation(self, env):
4915 if self.operand.type.is_int:
4916 self.type = self.operand.type
4920 def py_operation_function(self):
4921 return "PyNumber_Invert"
4923 def calculate_result_code(self):
4924 return "(~%s)" % self.operand.result()
4927 class CUnopNode(UnopNode):
4929 def is_py_operation(self):
4932 class DereferenceNode(CUnopNode):
4937 def analyse_c_operation(self, env):
4938 if self.operand.type.is_ptr:
4939 self.type = self.operand.type.base_type
4943 def calculate_result_code(self):
4944 return "(*%s)" % self.operand.result()
4947 class DecrementIncrementNode(CUnopNode):
4948 # unary ++/-- operator
4950 def analyse_c_operation(self, env):
4951 if self.operand.type.is_ptr or self.operand.type.is_numeric:
4952 self.type = self.operand.type
4956 def calculate_result_code(self):
4958 return "(%s%s)" % (self.operator, self.operand.result())
4960 return "(%s%s)" % (self.operand.result(), self.operator)
4962 def inc_dec_constructor(is_prefix, operator):
4963 return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
4966 class AmpersandNode(ExprNode):
4967 # The C address-of operator.
4971 subexprs = ['operand']
4973 def infer_type(self, env):
4974 return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
4976 def analyse_types(self, env):
4977 self.operand.analyse_types(env)
4978 argtype = self.operand.type
4979 if not (argtype.is_cfunction or self.operand.is_lvalue()):
4980 self.error("Taking address of non-lvalue")
4982 if argtype.is_pyobject:
4983 self.error("Cannot take address of Python variable")
4985 self.type = PyrexTypes.c_ptr_type(argtype)
4987 def check_const(self):
4988 return self.operand.check_const_addr()
4990 def error(self, mess):
4991 error(self.pos, mess)
4992 self.type = PyrexTypes.error_type
4993 self.result_code = "<error>"
4995 def calculate_result_code(self):
4996 return "(&%s)" % self.operand.result()
4998 def generate_result_code(self, code):
5002 unop_node_classes = {
5004 "-": UnaryMinusNode,
5008 def unop_node(pos, operator, operand):
5009 # Construct unnop node of appropriate class for
5011 if isinstance(operand, IntNode) and operator == '-':
5012 return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
5013 elif isinstance(operand, UnopNode) and operand.operator == operator:
5014 warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5015 return unop_node_classes[operator](pos,
5016 operator = operator,
5020 class TypecastNode(ExprNode):
5024 # base_type CBaseTypeNode
5025 # declarator CDeclaratorNode
5027 # If used from a transform, one can if wanted specify the attribute
5028 # "type" directly and leave base_type and declarator to None
5030 subexprs = ['operand']
5031 base_type = declarator = type = None
5033 def type_dependencies(self, env):
5036 def infer_type(self, env):
5037 if self.type is None:
5038 base_type = self.base_type.analyse(env)
5039 _, self.type = self.declarator.analyse(base_type, env)
5042 def analyse_types(self, env):
5043 if self.type is None:
5044 base_type = self.base_type.analyse(env)
5045 _, self.type = self.declarator.analyse(base_type, env)
5046 if self.type.is_cfunction:
5048 "Cannot cast to a function type")
5049 self.type = PyrexTypes.error_type
5050 self.operand.analyse_types(env)
5051 to_py = self.type.is_pyobject
5052 from_py = self.operand.type.is_pyobject
5053 if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
5054 error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
5055 if to_py and not from_py:
5056 if self.type is bytes_type and self.operand.type.is_int:
5057 # FIXME: the type cast node isn't needed in this case
5058 # and can be dropped once analyse_types() can return a
5060 self.operand = CoerceIntToBytesNode(self.operand, env)
5061 elif self.operand.type.can_coerce_to_pyobject(env):
5062 self.result_ctype = py_object_type
5063 self.operand = self.operand.coerce_to_pyobject(env)
5065 if self.operand.type.is_ptr:
5066 if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
5067 error(self.pos, "Python objects cannot be cast from pointers of primitive types")
5069 # Should this be an error?
5070 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5071 self.operand = self.operand.coerce_to_simple(env)
5072 elif from_py and not to_py:
5073 if self.type.create_from_py_utility_code(env):
5074 self.operand = self.operand.coerce_to(self.type, env)
5075 elif self.type.is_ptr:
5076 if not (self.type.base_type.is_void or self.type.base_type.is_struct):
5077 error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5079 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5080 elif from_py and to_py:
5081 if self.typecheck and self.type.is_extension_type:
5082 self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5083 elif self.type.is_complex and self.operand.type.is_complex:
5084 self.operand = self.operand.coerce_to_simple(env)
5086 def nogil_check(self, env):
5087 if self.type and self.type.is_pyobject and self.is_temp:
5090 def check_const(self):
5091 return self.operand.check_const()
5093 def calculate_constant_result(self):
5094 # we usually do not know the result of a type cast at code
5098 def calculate_result_code(self):
5099 if self.type.is_complex:
5100 operand_result = self.operand.result()
5101 if self.operand.type.is_complex:
5102 real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
5103 imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
5105 real_part = self.type.real_type.cast_code(operand_result)
5107 return "%s(%s, %s)" % (
5108 self.type.from_parts,
5112 return self.type.cast_code(self.operand.result())
5114 def get_constant_c_result_code(self):
5115 operand_result = self.operand.get_constant_c_result_code()
5117 return self.type.cast_code(operand_result)
5119 def result_as(self, type):
5120 if self.type.is_pyobject and not self.is_temp:
5121 # Optimise away some unnecessary casting
5122 return self.operand.result_as(type)
5124 return ExprNode.result_as(self, type)
5126 def generate_result_code(self, code):
5129 "%s = (PyObject *)%s;" % (
5131 self.operand.result()))
5132 code.put_incref(self.result(), self.ctype())
5135 class SizeofNode(ExprNode):
5136 # Abstract base class for sizeof(x) expression nodes.
5138 type = PyrexTypes.c_size_t_type
5140 def check_const(self):
5143 def generate_result_code(self, code):
5147 class SizeofTypeNode(SizeofNode):
5148 # C sizeof function applied to a type
5150 # base_type CBaseTypeNode
5151 # declarator CDeclaratorNode
5156 def analyse_types(self, env):
5157 # we may have incorrectly interpreted a dotted name as a type rather than an attribute
5158 # this could be better handled by more uniformly treating types as runtime-available objects
5159 if 0 and self.base_type.module_path:
5160 path = self.base_type.module_path
5161 obj = env.lookup(path[0])
5162 if obj.as_module is None:
5163 operand = NameNode(pos=self.pos, name=path[0])
5164 for attr in path[1:]:
5165 operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
5166 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
5167 self.operand = operand
5168 self.__class__ = SizeofVarNode
5169 self.analyse_types(env)
5171 if self.arg_type is None:
5172 base_type = self.base_type.analyse(env)
5173 _, arg_type = self.declarator.analyse(base_type, env)
5174 self.arg_type = arg_type
5177 def check_type(self):
5178 arg_type = self.arg_type
5179 if arg_type.is_pyobject and not arg_type.is_extension_type:
5180 error(self.pos, "Cannot take sizeof Python object")
5181 elif arg_type.is_void:
5182 error(self.pos, "Cannot take sizeof void")
5183 elif not arg_type.is_complete():
5184 error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5186 def calculate_result_code(self):
5187 if self.arg_type.is_extension_type:
5188 # the size of the pointer is boring
5189 # we want the size of the actual struct
5190 arg_code = self.arg_type.declaration_code("", deref=1)
5192 arg_code = self.arg_type.declaration_code("")
5193 return "(sizeof(%s))" % arg_code
5196 class SizeofVarNode(SizeofNode):
5197 # C sizeof function applied to a variable
5201 subexprs = ['operand']
5203 def analyse_types(self, env):
5204 # We may actually be looking at a type rather than a variable...
5205 # If we are, traditional analysis would fail...
5206 operand_as_type = self.operand.analyse_as_type(env)
5208 self.arg_type = operand_as_type
5209 self.__class__ = SizeofTypeNode
5212 self.operand.analyse_types(env)
5214 def calculate_result_code(self):
5215 return "(sizeof(%s))" % self.operand.result()
5217 def generate_result_code(self, code):
5220 class TypeofNode(ExprNode):
5221 # Compile-time type of an expression, as a string.
5224 # literal StringNode # internal
5227 type = py_object_type
5229 subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5231 def analyse_types(self, env):
5232 self.operand.analyse_types(env)
5233 self.literal = StringNode(
5234 self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
5235 self.literal.analyse_types(env)
5236 self.literal = self.literal.coerce_to_pyobject(env)
5238 def may_be_none(self):
5241 def generate_evaluation_code(self, code):
5242 self.literal.generate_evaluation_code(code)
5244 def calculate_result_code(self):
5245 return self.literal.calculate_result_code()
5247 #-------------------------------------------------------------------
5249 # Binary operator nodes
5251 #-------------------------------------------------------------------
5253 def _not_in(x, seq):
5256 compile_time_binary_operators = {
5264 'is_not': operator.is_not,
5267 '/': operator.truediv,
5268 '//': operator.floordiv,
5269 '<<': operator.lshift,
5274 '>>': operator.rshift,
5277 'in': operator.contains,
5281 def get_compile_time_binop(node):
5282 func = compile_time_binary_operators.get(node.operator)
5285 "Binary '%s' not supported in compile-time expression"
5289 class BinopNode(ExprNode):
5294 # Processing during analyse_expressions phase:
5296 # analyse_c_operation
5297 # Called when neither operand is a pyobject.
5298 # - Check operand types and coerce if needed.
5299 # - Determine result type and result code fragment.
5300 # - Allocate temporary for result if needed.
5302 subexprs = ['operand1', 'operand2']
5304 def calculate_constant_result(self):
5305 func = compile_time_binary_operators[self.operator]
5306 self.constant_result = func(
5307 self.operand1.constant_result,
5308 self.operand2.constant_result)
5310 def compile_time_value(self, denv):
5311 func = get_compile_time_binop(self)
5312 operand1 = self.operand1.compile_time_value(denv)
5313 operand2 = self.operand2.compile_time_value(denv)
5315 return func(operand1, operand2)
5316 except Exception, e:
5317 self.compile_time_value_error(e)
5319 def infer_type(self, env):
5320 return self.result_type(self.operand1.infer_type(env),
5321 self.operand2.infer_type(env))
5323 def analyse_types(self, env):
5324 self.operand1.analyse_types(env)
5325 self.operand2.analyse_types(env)
5326 if self.is_py_operation():
5327 self.coerce_operands_to_pyobjects(env)
5328 self.type = self.result_type(self.operand1.type,
5330 assert self.type.is_pyobject
5332 elif self.is_cpp_operation():
5333 self.analyse_cpp_operation(env)
5335 self.analyse_c_operation(env)
5337 def is_py_operation(self):
5338 return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5340 def is_py_operation_types(self, type1, type2):
5341 return type1.is_pyobject or type2.is_pyobject
5343 def is_cpp_operation(self):
5344 return (self.operand1.type.is_cpp_class
5345 or self.operand2.type.is_cpp_class)
5347 def analyse_cpp_operation(self, env):
5348 type1 = self.operand1.type
5349 type2 = self.operand2.type
5350 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
5354 func_type = entry.type
5355 if func_type.is_ptr:
5356 func_type = func_type.base_type
5357 if len(func_type.args) == 1:
5358 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
5360 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
5361 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
5362 self.type = func_type.return_type
5364 def result_type(self, type1, type2):
5365 if self.is_py_operation_types(type1, type2):
5367 type2 = Builtin.bytes_type
5369 type1 = Builtin.bytes_type
5370 elif self.operator == '%' \
5371 and type1 in (Builtin.str_type, Builtin.unicode_type):
5372 # note that b'%s' % b'abc' doesn't work in Py3
5374 if type1.is_builtin_type:
5376 if self.operator in '**%+|&^':
5377 # FIXME: at least these operators should be safe - others?
5379 elif self.operator == '*':
5380 if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
5382 # multiplication of containers/numbers with an
5383 # integer value always (?) returns the same type
5386 elif type2.is_builtin_type and type1.is_int and self.operator == '*':
5387 # multiplication of containers/numbers with an
5388 # integer value always (?) returns the same type
5390 return py_object_type
5392 return self.compute_c_result_type(type1, type2)
5394 def nogil_check(self, env):
5395 if self.is_py_operation():
5398 def coerce_operands_to_pyobjects(self, env):
5399 self.operand1 = self.operand1.coerce_to_pyobject(env)
5400 self.operand2 = self.operand2.coerce_to_pyobject(env)
5402 def check_const(self):
5403 return self.operand1.check_const() and self.operand2.check_const()
5405 def generate_result_code(self, code):
5406 #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
5407 if self.operand1.type.is_pyobject:
5408 function = self.py_operation_function()
5409 if function == "PyNumber_Power":
5410 extra_args = ", Py_None"
5414 "%s = %s(%s, %s%s); %s" % (
5417 self.operand1.py_result(),
5418 self.operand2.py_result(),
5420 code.error_goto_if_null(self.result(), self.pos)))
5421 code.put_gotref(self.py_result())
5423 def type_error(self):
5424 if not (self.operand1.type.is_error
5425 or self.operand2.type.is_error):
5426 error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5427 (self.operator, self.operand1.type,
5428 self.operand2.type))
5429 self.type = PyrexTypes.error_type
5432 class CBinopNode(BinopNode):
5434 def analyse_types(self, env):
5435 BinopNode.analyse_types(self, env)
5436 if self.is_py_operation():
5437 self.type = PyrexTypes.error_type
5439 def py_operation_function():
5442 def calculate_result_code(self):
5443 return "(%s %s %s)" % (
5444 self.operand1.result(),
5446 self.operand2.result())
5449 def c_binop_constructor(operator):
5450 def make_binop_node(pos, **operands):
5451 return CBinopNode(pos, operator=operator, **operands)
5452 return make_binop_node
5454 class NumBinopNode(BinopNode):
5455 # Binary operation taking numeric arguments.
5459 def analyse_c_operation(self, env):
5460 type1 = self.operand1.type
5461 type2 = self.operand2.type
5462 self.type = self.compute_c_result_type(type1, type2)
5466 if self.type.is_complex:
5468 if not self.infix or (type1.is_numeric and type2.is_numeric):
5469 self.operand1 = self.operand1.coerce_to(self.type, env)
5470 self.operand2 = self.operand2.coerce_to(self.type, env)
5472 def compute_c_result_type(self, type1, type2):
5473 if self.c_types_okay(type1, type2):
5474 return PyrexTypes.widest_numeric_type(type1, type2)
5478 def get_constant_c_result_code(self):
5479 value1 = self.operand1.get_constant_c_result_code()
5480 value2 = self.operand2.get_constant_c_result_code()
5481 if value1 and value2:
5482 return "(%s %s %s)" % (value1, self.operator, value2)
5486 def c_types_okay(self, type1, type2):
5487 #print "NumBinopNode.c_types_okay:", type1, type2 ###
5488 return (type1.is_numeric or type1.is_enum) \
5489 and (type2.is_numeric or type2.is_enum)
5491 def calculate_result_code(self):
5493 return "(%s %s %s)" % (
5494 self.operand1.result(),
5496 self.operand2.result())
5498 func = self.type.binary_op(self.operator)
5500 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5501 return "%s(%s, %s)" % (
5503 self.operand1.result(),
5504 self.operand2.result())
5506 def is_py_operation_types(self, type1, type2):
5507 return (type1 is PyrexTypes.c_py_unicode_type or
5508 type2 is PyrexTypes.c_py_unicode_type or
5509 BinopNode.is_py_operation_types(self, type1, type2))
5511 def py_operation_function(self):
5512 return self.py_functions[self.operator]
5516 "^": "PyNumber_Xor",
5517 "&": "PyNumber_And",
5518 "<<": "PyNumber_Lshift",
5519 ">>": "PyNumber_Rshift",
5520 "+": "PyNumber_Add",
5521 "-": "PyNumber_Subtract",
5522 "*": "PyNumber_Multiply",
5523 "/": "__Pyx_PyNumber_Divide",
5524 "//": "PyNumber_FloorDivide",
5525 "%": "PyNumber_Remainder",
5526 "**": "PyNumber_Power"
5530 class IntBinopNode(NumBinopNode):
5531 # Binary operation taking integer arguments.
5533 def c_types_okay(self, type1, type2):
5534 #print "IntBinopNode.c_types_okay:", type1, type2 ###
5535 return (type1.is_int or type1.is_enum) \
5536 and (type2.is_int or type2.is_enum)
5539 class AddNode(NumBinopNode):
5542 def is_py_operation_types(self, type1, type2):
5543 if type1.is_string and type2.is_string:
5546 return NumBinopNode.is_py_operation_types(self, type1, type2)
5548 def compute_c_result_type(self, type1, type2):
5549 #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
5550 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5552 elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
5555 return NumBinopNode.compute_c_result_type(
5559 class SubNode(NumBinopNode):
5562 def compute_c_result_type(self, type1, type2):
5563 if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
5565 elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
5566 return PyrexTypes.c_int_type
5568 return NumBinopNode.compute_c_result_type(
5572 class MulNode(NumBinopNode):
5575 def is_py_operation_types(self, type1, type2):
5576 if (type1.is_string and type2.is_int) \
5577 or (type2.is_string and type1.is_int):
5580 return NumBinopNode.is_py_operation_types(self, type1, type2)
5583 class DivNode(NumBinopNode):
5584 # '/' or '//' operator.
5587 truedivision = None # == "unknown" if operator == '/'
5588 ctruedivision = False
5589 cdivision_warnings = False
5590 zerodivision_check = None
5592 def find_compile_time_binary_operator(self, op1, op2):
5593 func = compile_time_binary_operators[self.operator]
5594 if self.operator == '/' and self.truedivision is None:
5595 # => true div for floats, floor div for integers
5596 if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
5597 func = compile_time_binary_operators['//']
5600 def calculate_constant_result(self):
5601 op1 = self.operand1.constant_result
5602 op2 = self.operand2.constant_result
5603 func = self.find_compile_time_binary_operator(op1, op2)
5604 self.constant_result = func(
5605 self.operand1.constant_result,
5606 self.operand2.constant_result)
5608 def compile_time_value(self, denv):
5609 operand1 = self.operand1.compile_time_value(denv)
5610 operand2 = self.operand2.compile_time_value(denv)
5612 func = self.find_compile_time_binary_operator(
5613 self, operand1, operand2)
5614 return func(operand1, operand2)
5615 except Exception, e:
5616 self.compile_time_value_error(e)
5618 def analyse_types(self, env):
5619 if self.cdivision or env.directives['cdivision']:
5620 self.ctruedivision = False
5622 self.ctruedivision = self.truedivision
5623 NumBinopNode.analyse_types(self, env)
5624 if self.is_cpp_operation():
5625 self.cdivision = True
5626 if not self.type.is_pyobject:
5627 self.zerodivision_check = (
5628 self.cdivision is None and not env.directives['cdivision']
5629 and (not self.operand2.has_constant_result() or
5630 self.operand2.constant_result == 0))
5631 if self.zerodivision_check or env.directives['cdivision_warnings']:
5632 # Need to check ahead of time to warn or raise zero division error
5633 self.operand1 = self.operand1.coerce_to_simple(env)
5634 self.operand2 = self.operand2.coerce_to_simple(env)
5636 error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
5638 def compute_c_result_type(self, type1, type2):
5639 if self.operator == '/' and self.ctruedivision:
5640 if not type1.is_float and not type2.is_float:
5641 widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
5642 widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
5644 return NumBinopNode.compute_c_result_type(self, type1, type2)
5646 def zero_division_message(self):
5647 if self.type.is_int:
5648 return "integer division or modulo by zero"
5650 return "float division"
5652 def generate_evaluation_code(self, code):
5653 if not self.type.is_pyobject and not self.type.is_complex:
5654 if self.cdivision is None:
5655 self.cdivision = (code.globalstate.directives['cdivision']
5656 or not self.type.signed
5657 or self.type.is_float)
5658 if not self.cdivision:
5659 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
5660 NumBinopNode.generate_evaluation_code(self, code)
5661 self.generate_div_warning_code(code)
5663 def generate_div_warning_code(self, code):
5664 if not self.type.is_pyobject:
5665 if self.zerodivision_check:
5667 zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
5669 zero_test = "%s == 0" % self.operand2.result()
5670 code.putln("if (unlikely(%s)) {" % zero_test)
5671 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
5672 code.putln(code.error_goto(self.pos))
5674 if self.type.is_int and self.type.signed and self.operator != '%':
5675 code.globalstate.use_utility_code(division_overflow_test_code)
5676 code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
5677 self.type.declaration_code(''),
5678 self.operand2.result(),
5679 self.operand1.result()))
5680 code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
5681 code.putln(code.error_goto(self.pos))
5683 if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
5684 code.globalstate.use_utility_code(cdivision_warning_utility_code)
5685 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
5686 self.operand1.result(),
5687 self.operand2.result()))
5688 code.putln(code.set_error_info(self.pos));
5689 code.put("if (__Pyx_cdivision_warning()) ")
5690 code.put_goto(code.error_label)
5693 def calculate_result_code(self):
5694 if self.type.is_complex:
5695 return NumBinopNode.calculate_result_code(self)
5696 elif self.type.is_float and self.operator == '//':
5697 return "floor(%s / %s)" % (
5698 self.operand1.result(),
5699 self.operand2.result())
5700 elif self.truedivision or self.cdivision:
5701 op1 = self.operand1.result()
5702 op2 = self.operand2.result()
5703 if self.truedivision:
5704 if self.type != self.operand1.type:
5705 op1 = self.type.cast_code(op1)
5706 if self.type != self.operand2.type:
5707 op2 = self.type.cast_code(op2)
5708 return "(%s / %s)" % (op1, op2)
5710 return "__Pyx_div_%s(%s, %s)" % (
5711 self.type.specialization_name(),
5712 self.operand1.result(),
5713 self.operand2.result())
5716 class ModNode(DivNode):
5719 def is_py_operation_types(self, type1, type2):
5720 return (type1.is_string
5722 or NumBinopNode.is_py_operation_types(self, type1, type2))
5724 def zero_division_message(self):
5725 if self.type.is_int:
5726 return "integer division or modulo by zero"
5728 return "float divmod()"
5730 def generate_evaluation_code(self, code):
5731 if not self.type.is_pyobject:
5732 if self.cdivision is None:
5733 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
5734 if not self.cdivision:
5735 if self.type.is_int:
5736 code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
5738 code.globalstate.use_utility_code(
5739 mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
5740 NumBinopNode.generate_evaluation_code(self, code)
5741 self.generate_div_warning_code(code)
5743 def calculate_result_code(self):
5745 if self.type.is_float:
5746 return "fmod%s(%s, %s)" % (
5747 self.type.math_h_modifier,
5748 self.operand1.result(),
5749 self.operand2.result())
5751 return "(%s %% %s)" % (
5752 self.operand1.result(),
5753 self.operand2.result())
5755 return "__Pyx_mod_%s(%s, %s)" % (
5756 self.type.specialization_name(),
5757 self.operand1.result(),
5758 self.operand2.result())
5760 class PowNode(NumBinopNode):
5763 def analyse_c_operation(self, env):
5764 NumBinopNode.analyse_c_operation(self, env)
5765 if self.type.is_complex:
5766 if self.type.real_type.is_float:
5767 self.operand1 = self.operand1.coerce_to(self.type, env)
5768 self.operand2 = self.operand2.coerce_to(self.type, env)
5769 self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
5771 error(self.pos, "complex int powers not supported")
5772 self.pow_func = "<error>"
5773 elif self.type.is_float:
5774 self.pow_func = "pow" + self.type.math_h_modifier
5776 self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
5777 env.use_utility_code(
5778 int_pow_utility_code.specialize(func_name=self.pow_func,
5779 type=self.type.declaration_code('')))
5781 def calculate_result_code(self):
5782 # Work around MSVC overloading ambiguity.
5783 def typecast(operand):
5784 if self.type == operand.type:
5785 return operand.result()
5787 return self.type.cast_code(operand.result())
5788 return "%s(%s, %s)" % (
5790 typecast(self.operand1),
5791 typecast(self.operand2))
5794 # Note: This class is temporarily "shut down" into an ineffective temp
5797 # More sophisticated temp reuse was going on before, one could have a
5798 # look at adding this again after /all/ classes are converted to the
5799 # new temp scheme. (The temp juggling cannot work otherwise).
5800 class BoolBinopNode(ExprNode):
5801 # Short-circuiting boolean operation.
5807 subexprs = ['operand1', 'operand2']
5809 def infer_type(self, env):
5810 type1 = self.operand1.infer_type(env)
5811 type2 = self.operand2.infer_type(env)
5812 return PyrexTypes.independent_spanning_type(type1, type2)
5814 def may_be_none(self):
5815 if self.operator == 'or':
5816 return self.operand2.may_be_none()
5818 return self.operand1.may_be_none() or self.operand2.may_be_none()
5820 def calculate_constant_result(self):
5821 if self.operator == 'and':
5822 self.constant_result = \
5823 self.operand1.constant_result and \
5824 self.operand2.constant_result
5826 self.constant_result = \
5827 self.operand1.constant_result or \
5828 self.operand2.constant_result
5830 def compile_time_value(self, denv):
5831 if self.operator == 'and':
5832 return self.operand1.compile_time_value(denv) \
5833 and self.operand2.compile_time_value(denv)
5835 return self.operand1.compile_time_value(denv) \
5836 or self.operand2.compile_time_value(denv)
5838 def coerce_to_boolean(self, env):
5839 return BoolBinopNode(
5841 operator = self.operator,
5842 operand1 = self.operand1.coerce_to_boolean(env),
5843 operand2 = self.operand2.coerce_to_boolean(env),
5844 type = PyrexTypes.c_bint_type,
5845 is_temp = self.is_temp)
5847 def analyse_types(self, env):
5848 self.operand1.analyse_types(env)
5849 self.operand2.analyse_types(env)
5850 self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
5851 self.operand1 = self.operand1.coerce_to(self.type, env)
5852 self.operand2 = self.operand2.coerce_to(self.type, env)
5854 # For what we're about to do, it's vital that
5855 # both operands be temp nodes.
5856 self.operand1 = self.operand1.coerce_to_simple(env)
5857 self.operand2 = self.operand2.coerce_to_simple(env)
5860 gil_message = "Truth-testing Python object"
5862 def check_const(self):
5863 return self.operand1.check_const() and self.operand2.check_const()
5865 def generate_evaluation_code(self, code):
5866 code.mark_pos(self.pos)
5867 self.operand1.generate_evaluation_code(code)
5868 test_result, uses_temp = self.generate_operand1_test(code)
5869 if self.operator == 'and':
5878 code.funcstate.release_temp(test_result)
5879 self.operand1.generate_disposal_code(code)
5880 self.operand2.generate_evaluation_code(code)
5881 self.allocate_temp_result(code)
5882 self.operand2.make_owned_reference(code)
5883 code.putln("%s = %s;" % (self.result(), self.operand2.result()))
5884 self.operand2.generate_post_assignment_code(code)
5885 self.operand2.free_temps(code)
5886 code.putln("} else {")
5887 self.operand1.make_owned_reference(code)
5888 code.putln("%s = %s;" % (self.result(), self.operand1.result()))
5889 self.operand1.generate_post_assignment_code(code)
5890 self.operand1.free_temps(code)
5893 def generate_operand1_test(self, code):
5894 # Generate code to test the truth of the first operand.
5895 if self.type.is_pyobject:
5896 test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
5899 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5901 self.operand1.py_result(),
5902 code.error_goto_if_neg(test_result, self.pos)))
5904 test_result = self.operand1.result()
5905 return (test_result, self.type.is_pyobject)
5908 class CondExprNode(ExprNode):
5909 # Short-circuiting conditional expression.
5913 # false_val ExprNode
5918 subexprs = ['test', 'true_val', 'false_val']
5920 def type_dependencies(self, env):
5921 return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
5923 def infer_type(self, env):
5924 return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
5925 self.false_val.infer_type(env))
5927 def calculate_constant_result(self):
5928 if self.test.constant_result:
5929 self.constant_result = self.true_val.constant_result
5931 self.constant_result = self.false_val.constant_result
5933 def analyse_types(self, env):
5934 self.test.analyse_types(env)
5935 self.test = self.test.coerce_to_boolean(env)
5936 self.true_val.analyse_types(env)
5937 self.false_val.analyse_types(env)
5938 self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
5939 if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
5940 self.true_val = self.true_val.coerce_to(self.type, env)
5941 self.false_val = self.false_val.coerce_to(self.type, env)
5943 if self.type == PyrexTypes.error_type:
5946 def type_error(self):
5947 if not (self.true_val.type.is_error or self.false_val.type.is_error):
5948 error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
5949 (self.true_val.type, self.false_val.type))
5950 self.type = PyrexTypes.error_type
5952 def check_const(self):
5953 return (self.test.check_const()
5954 and self.true_val.check_const()
5955 and self.false_val.check_const())
5957 def generate_evaluation_code(self, code):
5958 # Because subexprs may not be evaluated we can use a more optimal
5959 # subexpr allocation strategy than the default, so override evaluation_code.
5961 code.mark_pos(self.pos)
5962 self.allocate_temp_result(code)
5963 self.test.generate_evaluation_code(code)
5964 code.putln("if (%s) {" % self.test.result() )
5965 self.eval_and_get(code, self.true_val)
5966 code.putln("} else {")
5967 self.eval_and_get(code, self.false_val)
5969 self.test.generate_disposal_code(code)
5970 self.test.free_temps(code)
5972 def eval_and_get(self, code, expr):
5973 expr.generate_evaluation_code(code)
5974 expr.make_owned_reference(code)
5975 code.putln("%s = %s;" % (self.result(), expr.result()))
5976 expr.generate_post_assignment_code(code)
5977 expr.free_temps(code)
5979 richcmp_constants = {
5989 class CmpNode(object):
5990 # Mixin class containing code common to PrimaryCmpNodes
5991 # and CascadedCmpNodes.
5993 special_bool_cmp_function = None
5995 def infer_type(self, env):
5996 # TODO: Actually implement this (after merging with -unstable).
5997 return py_object_type
5999 def calculate_cascaded_constant_result(self, operand1_result):
6000 func = compile_time_binary_operators[self.operator]
6001 operand2_result = self.operand2.constant_result
6002 result = func(operand1_result, operand2_result)
6004 self.cascade.calculate_cascaded_constant_result(operand2_result)
6005 if self.cascade.constant_result:
6006 self.constant_result = result and self.cascade.constant_result
6008 self.constant_result = result
6010 def cascaded_compile_time_value(self, operand1, denv):
6011 func = get_compile_time_binop(self)
6012 operand2 = self.operand2.compile_time_value(denv)
6014 result = func(operand1, operand2)
6015 except Exception, e:
6016 self.compile_time_value_error(e)
6019 cascade = self.cascade
6021 # FIXME: I bet this must call cascaded_compile_time_value()
6022 result = result and cascade.cascaded_compile_time_value(operand2, denv)
6025 def is_cpp_comparison(self):
6026 return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6028 def find_common_int_type(self, env, op, operand1, operand2):
6029 # type1 != type2 and at least one of the types is not a C int
6030 type1 = operand1.type
6031 type2 = operand2.type
6032 type1_can_be_int = False
6033 type2_can_be_int = False
6035 if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6036 and operand1.can_coerce_to_char_literal():
6037 type1_can_be_int = True
6038 if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6039 and operand2.can_coerce_to_char_literal():
6040 type2_can_be_int = True
6043 if type2_can_be_int:
6046 if type1_can_be_int:
6048 elif type1_can_be_int:
6049 if type2_can_be_int:
6050 return PyrexTypes.c_uchar_type
6054 def find_common_type(self, env, op, operand1, common_type=None):
6055 operand2 = self.operand2
6056 type1 = operand1.type
6057 type2 = operand2.type
6059 new_common_type = None
6061 # catch general errors
6062 if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
6063 type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
6064 error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6065 new_common_type = error_type
6067 # try to use numeric comparisons where possible
6068 elif type1.is_complex or type2.is_complex:
6069 if op not in ('==', '!='):
6070 error(self.pos, "complex types are unordered")
6071 new_common_type = error_type
6072 if type1.is_pyobject:
6073 new_common_type = type1
6074 elif type2.is_pyobject:
6075 new_common_type = type2
6077 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6078 elif type1.is_numeric and type2.is_numeric:
6079 new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6080 elif common_type is None or not common_type.is_pyobject:
6081 new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6083 if new_common_type is None:
6084 # fall back to generic type compatibility tests
6086 new_common_type = type1
6087 elif type1.is_pyobject or type2.is_pyobject:
6088 if type2.is_numeric or type2.is_string:
6089 if operand2.check_for_coercion_error(type1):
6090 new_common_type = error_type
6092 new_common_type = py_object_type
6093 elif type1.is_numeric or type1.is_string:
6094 if operand1.check_for_coercion_error(type2):
6095 new_common_type = error_type
6097 new_common_type = py_object_type
6098 elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
6099 new_common_type = py_object_type
6101 # one Python type and one non-Python type, not assignable
6102 self.invalid_types_error(operand1, op, operand2)
6103 new_common_type = error_type
6104 elif type1.assignable_from(type2):
6105 new_common_type = type1
6106 elif type2.assignable_from(type1):
6107 new_common_type = type2
6109 # C types that we couldn't handle up to here are an error
6110 self.invalid_types_error(operand1, op, operand2)
6111 new_common_type = error_type
6113 if new_common_type.is_string and (isinstance(operand1, BytesNode) or
6114 isinstance(operand2, BytesNode)):
6115 # special case when comparing char* to bytes literal: must
6116 # compare string values!
6117 new_common_type = bytes_type
6119 # recursively merge types
6120 if common_type is None or new_common_type.is_error:
6121 common_type = new_common_type
6123 # we could do a lot better by splitting the comparison
6124 # into a non-Python part and a Python part, but this is
6126 common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6129 common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6133 def invalid_types_error(self, operand1, op, operand2):
6134 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6135 (op, operand1.type, operand2.type))
6137 def is_python_comparison(self):
6138 return (not self.is_ptr_contains()
6139 and not self.is_c_string_contains()
6140 and (self.has_python_operands()
6141 or (self.cascade and self.cascade.is_python_comparison())
6142 or self.operator in ('in', 'not_in')))
6144 def coerce_operands_to(self, dst_type, env):
6145 operand2 = self.operand2
6146 if operand2.type != dst_type:
6147 self.operand2 = operand2.coerce_to(dst_type, env)
6149 self.cascade.coerce_operands_to(dst_type, env)
6151 def is_python_result(self):
6152 return ((self.has_python_operands() and
6153 self.special_bool_cmp_function is None and
6154 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6155 not self.is_c_string_contains() and
6156 not self.is_ptr_contains())
6157 or (self.cascade and self.cascade.is_python_result()))
6159 def is_c_string_contains(self):
6160 return self.operator in ('in', 'not_in') and \
6161 ((self.operand1.type.is_int
6162 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
6163 (self.operand1.type is PyrexTypes.c_py_unicode_type
6164 and self.operand2.type is unicode_type))
6166 def is_ptr_contains(self):
6167 if self.operator in ('in', 'not_in'):
6168 container_type = self.operand2.type
6169 return (container_type.is_ptr or container_type.is_array) \
6170 and not container_type.is_string
6172 def find_special_bool_compare_function(self, env):
6173 if self.operator in ('==', '!='):
6174 type1, type2 = self.operand1.type, self.operand2.type
6175 if type1.is_pyobject and type2.is_pyobject:
6176 if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
6177 env.use_utility_code(pyunicode_equals_utility_code)
6178 self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
6182 def generate_operation_code(self, code, result_code,
6183 operand1, op , operand2):
6184 if self.type.is_pyobject:
6185 coerce_result = "__Pyx_PyBool_FromLong"
6192 if self.special_bool_cmp_function:
6193 if operand1.type.is_pyobject:
6194 result1 = operand1.py_result()
6196 result1 = operand1.result()
6197 if operand2.type.is_pyobject:
6198 result2 = operand2.py_result()
6200 result2 = operand2.result()
6201 code.putln("%s = %s(%s, %s, %s); %s" % (
6203 self.special_bool_cmp_function,
6206 richcmp_constants[op],
6207 code.error_goto_if_neg(result_code, self.pos)))
6208 elif op == 'in' or op == 'not_in':
6209 code.globalstate.use_utility_code(contains_utility_code)
6210 if self.type.is_pyobject:
6211 coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6213 negation = "__Pyx_NegateNonNeg"
6214 if operand2.type is dict_type:
6215 method = "PyDict_Contains"
6217 method = "PySequence_Contains"
6218 if self.type.is_pyobject:
6219 error_clause = code.error_goto_if_null
6220 got_ref = "__Pyx_XGOTREF(%s); " % result_code
6222 error_clause = code.error_goto_if_neg
6225 "%s = %s(%s(%s(%s, %s))); %s%s" % (
6230 operand2.py_result(),
6231 operand1.py_result(),
6233 error_clause(result_code, self.pos)))
6234 elif (operand1.type.is_pyobject
6235 and op not in ('is', 'is_not')):
6236 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6238 operand1.py_result(),
6239 operand2.py_result(),
6240 richcmp_constants[op],
6241 code.error_goto_if_null(result_code, self.pos)))
6242 code.put_gotref(result_code)
6243 elif operand1.type.is_complex:
6248 code.putln("%s = %s(%s%s(%s, %s));" % (
6252 operand1.type.unary_op('eq'),
6256 type1 = operand1.type
6257 type2 = operand2.type
6258 if (type1.is_extension_type or type2.is_extension_type) \
6259 and not type1.same_as(type2):
6260 common_type = py_object_type
6261 elif type1.is_numeric:
6262 common_type = PyrexTypes.widest_numeric_type(type1, type2)
6265 code1 = operand1.result_as(common_type)
6266 code2 = operand2.result_as(common_type)
6267 code.putln("%s = %s(%s %s %s);" % (
6271 self.c_operator(op),
6274 def c_operator(self, op):
6277 elif op == 'is_not':
6282 contains_utility_code = UtilityCode(
6284 static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
6285 static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6286 return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
6290 char_in_bytes_utility_code = UtilityCode(
6292 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
6295 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
6296 const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
6297 char* char_start = PyBytes_AS_STRING(bytes);
6299 for (pos=char_start; pos < char_start+length; pos++) {
6300 if (character == pos[0]) return 1;
6306 pyunicode_in_unicode_utility_code = UtilityCode(
6308 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
6311 static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6312 const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
6313 Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6315 for (pos=char_start; pos < char_start+length; pos++) {
6316 if (character == pos[0]) return 1;
6322 pyunicode_equals_utility_code = UtilityCode(
6324 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
6327 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
6328 if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6329 return (equals == Py_EQ);
6330 } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
6331 if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
6332 return (equals == Py_NE);
6333 } else if (PyUnicode_GET_SIZE(s1) == 1) {
6334 if (equals == Py_EQ)
6335 return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
6337 return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
6339 int result = PyUnicode_Compare(s1, s2);
6340 if ((result == -1) && unlikely(PyErr_Occurred()))
6342 return (equals == Py_EQ) ? (result == 0) : (result != 0);
6344 } else if ((s1 == Py_None) & (s2 == Py_None)) {
6345 return (equals == Py_EQ);
6346 } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
6347 return (equals == Py_NE);
6348 } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
6349 return (equals == Py_NE);
6352 PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
6355 result = __Pyx_PyObject_IsTrue(py_result);
6356 Py_DECREF(py_result);
6363 class PrimaryCmpNode(ExprNode, CmpNode):
6364 # Non-cascaded comparison or first comparison of
6365 # a cascaded sequence.
6370 # cascade CascadedCmpNode
6372 # We don't use the subexprs mechanism, because
6373 # things here are too complicated for it to handle.
6374 # Instead, we override all the framework methods
6377 child_attrs = ['operand1', 'operand2', 'cascade']
6381 def infer_type(self, env):
6382 # TODO: Actually implement this (after merging with -unstable).
6383 return py_object_type
6385 def type_dependencies(self, env):
6388 def calculate_constant_result(self):
6389 self.calculate_cascaded_constant_result(self.operand1.constant_result)
6391 def compile_time_value(self, denv):
6392 operand1 = self.operand1.compile_time_value(denv)
6393 return self.cascaded_compile_time_value(operand1, denv)
6395 def analyse_types(self, env):
6396 self.operand1.analyse_types(env)
6397 self.operand2.analyse_types(env)
6398 if self.is_cpp_comparison():
6399 self.analyse_cpp_comparison(env)
6401 error(self.pos, "Cascading comparison not yet supported for cpp types.")
6404 self.cascade.analyse_types(env)
6406 if self.operator in ('in', 'not_in'):
6407 if self.is_c_string_contains():
6408 self.is_pycmp = False
6411 error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
6413 if self.operand2.type is unicode_type:
6414 env.use_utility_code(pyunicode_in_unicode_utility_code)
6416 if self.operand1.type is PyrexTypes.c_uchar_type:
6417 self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
6418 if self.operand2.type is not bytes_type:
6419 self.operand2 = self.operand2.coerce_to(bytes_type, env)
6420 env.use_utility_code(char_in_bytes_utility_code)
6421 self.operand2 = self.operand2.as_none_safe_node(
6422 "argument of type 'NoneType' is not iterable")
6423 elif self.is_ptr_contains():
6425 error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
6426 self.type = PyrexTypes.c_bint_type
6427 # Will be transformed by IterationTransform
6430 if self.operand2.type is dict_type:
6431 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6432 common_type = py_object_type
6433 self.is_pycmp = True
6434 elif self.find_special_bool_compare_function(env):
6435 common_type = None # if coercion needed, the method call above has already done it
6436 self.is_pycmp = False # result is bint
6437 self.is_temp = True # must check for error return
6439 common_type = self.find_common_type(env, self.operator, self.operand1)
6440 self.is_pycmp = common_type.is_pyobject
6442 if common_type is not None and not common_type.is_error:
6443 if self.operand1.type != common_type:
6444 self.operand1 = self.operand1.coerce_to(common_type, env)
6445 self.coerce_operands_to(common_type, env)
6448 self.operand2 = self.operand2.coerce_to_simple(env)
6449 self.cascade.coerce_cascaded_operands_to_temp(env)
6450 if self.is_python_result():
6451 self.type = PyrexTypes.py_object_type
6453 self.type = PyrexTypes.c_bint_type
6456 cdr.type = self.type
6458 if self.is_pycmp or self.cascade:
6461 def analyse_cpp_comparison(self, env):
6462 type1 = self.operand1.type
6463 type2 = self.operand2.type
6464 entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
6466 error(self.pos, "Invalid types for '%s' (%s, %s)" %
6467 (self.operator, type1, type2))
6468 self.type = PyrexTypes.error_type
6469 self.result_code = "<error>"
6471 func_type = entry.type
6472 if func_type.is_ptr:
6473 func_type = func_type.base_type
6474 if len(func_type.args) == 1:
6475 self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6477 self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
6478 self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
6479 self.type = func_type.return_type
6481 def has_python_operands(self):
6482 return (self.operand1.type.is_pyobject
6483 or self.operand2.type.is_pyobject)
6485 def check_const(self):
6490 return self.operand1.check_const() and self.operand2.check_const()
6492 def calculate_result_code(self):
6493 if self.operand1.type.is_complex:
6494 if self.operator == "!=":
6498 return "(%s%s(%s, %s))" % (
6500 self.operand1.type.binary_op('=='),
6501 self.operand1.result(),
6502 self.operand2.result())
6503 elif self.is_c_string_contains():
6504 if self.operand2.type is bytes_type:
6505 method = "__Pyx_BytesContains"
6507 method = "__Pyx_UnicodeContains"
6508 if self.operator == "not_in":
6512 return "(%s%s(%s, %s))" % (
6515 self.operand2.result(),
6516 self.operand1.result())
6518 return "(%s %s %s)" % (
6519 self.operand1.result(),
6520 self.c_operator(self.operator),
6521 self.operand2.result())
6523 def generate_evaluation_code(self, code):
6524 self.operand1.generate_evaluation_code(code)
6525 self.operand2.generate_evaluation_code(code)
6527 self.allocate_temp_result(code)
6528 self.generate_operation_code(code, self.result(),
6529 self.operand1, self.operator, self.operand2)
6531 self.cascade.generate_evaluation_code(code,
6532 self.result(), self.operand2)
6533 self.operand1.generate_disposal_code(code)
6534 self.operand1.free_temps(code)
6535 self.operand2.generate_disposal_code(code)
6536 self.operand2.free_temps(code)
6538 def generate_subexpr_disposal_code(self, code):
6539 # If this is called, it is a non-cascaded cmp,
6540 # so only need to dispose of the two main operands.
6541 self.operand1.generate_disposal_code(code)
6542 self.operand2.generate_disposal_code(code)
6544 def free_subexpr_temps(self, code):
6545 # If this is called, it is a non-cascaded cmp,
6546 # so only need to dispose of the two main operands.
6547 self.operand1.free_temps(code)
6548 self.operand2.free_temps(code)
6550 def annotate(self, code):
6551 self.operand1.annotate(code)
6552 self.operand2.annotate(code)
6554 self.cascade.annotate(code)
6557 class CascadedCmpNode(Node, CmpNode):
6558 # A CascadedCmpNode is not a complete expression node. It
6559 # hangs off the side of another comparison node, shares
6560 # its left operand with that node, and shares its result
6561 # with the PrimaryCmpNode at the head of the chain.
6565 # cascade CascadedCmpNode
6567 child_attrs = ['operand2', 'cascade']
6570 constant_result = constant_value_not_set # FIXME: where to calculate this?
6572 def infer_type(self, env):
6573 # TODO: Actually implement this (after merging with -unstable).
6574 return py_object_type
6576 def type_dependencies(self, env):
6579 def has_constant_result(self):
6580 return self.constant_result is not constant_value_not_set and \
6581 self.constant_result is not not_a_constant
6583 def analyse_types(self, env):
6584 self.operand2.analyse_types(env)
6586 self.cascade.analyse_types(env)
6588 def has_python_operands(self):
6589 return self.operand2.type.is_pyobject
6591 def coerce_operands_to_pyobjects(self, env):
6592 self.operand2 = self.operand2.coerce_to_pyobject(env)
6593 if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
6594 self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6596 self.cascade.coerce_operands_to_pyobjects(env)
6598 def coerce_cascaded_operands_to_temp(self, env):
6600 #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
6601 self.operand2 = self.operand2.coerce_to_simple(env)
6602 self.cascade.coerce_cascaded_operands_to_temp(env)
6604 def generate_evaluation_code(self, code, result, operand1):
6605 if self.type.is_pyobject:
6606 code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
6607 code.put_decref(result, self.type)
6609 code.putln("if (%s) {" % result)
6610 self.operand2.generate_evaluation_code(code)
6611 self.generate_operation_code(code, result,
6612 operand1, self.operator, self.operand2)
6614 self.cascade.generate_evaluation_code(
6615 code, result, self.operand2)
6616 # Cascaded cmp result is always temp
6617 self.operand2.generate_disposal_code(code)
6618 self.operand2.free_temps(code)
6621 def annotate(self, code):
6622 self.operand2.annotate(code)
6624 self.cascade.annotate(code)
6627 binop_node_classes = {
6628 "or": BoolBinopNode,
6629 "and": BoolBinopNode,
6644 def binop_node(pos, operator, operand1, operand2):
6645 # Construct binop node of appropriate class for
6647 return binop_node_classes[operator](pos,
6648 operator = operator,
6649 operand1 = operand1,
6650 operand2 = operand2)
6652 #-------------------------------------------------------------------
6656 # Coercion nodes are special in that they are created during
6657 # the analyse_types phase of parse tree processing.
6658 # Their __init__ methods consequently incorporate some aspects
6661 #-------------------------------------------------------------------
6663 class CoercionNode(ExprNode):
6664 # Abstract base class for coercion nodes.
6666 # arg ExprNode node being coerced
6669 constant_result = not_a_constant
6671 def __init__(self, arg):
6675 print("%s Coercing %s" % (self, self.arg))
6677 def calculate_constant_result(self):
6678 # constant folding can break type coercion, so this is disabled
6681 def annotate(self, code):
6682 self.arg.annotate(code)
6683 if self.arg.type != self.type:
6684 file, line, col = self.pos
6685 code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
6688 class CastNode(CoercionNode):
6689 # Wrap a node in a C type cast.
6691 def __init__(self, arg, new_type):
6692 CoercionNode.__init__(self, arg)
6693 self.type = new_type
6695 def may_be_none(self):
6696 return self.arg.may_be_none()
6698 def calculate_result_code(self):
6699 return self.arg.result_as(self.type)
6701 def generate_result_code(self, code):
6702 self.arg.generate_result_code(code)
6705 class PyTypeTestNode(CoercionNode):
6706 # This node is used to check that a generic Python
6707 # object is an instance of a particular extension type.
6708 # This node borrows the result of its argument node.
6710 def __init__(self, arg, dst_type, env, notnone=False):
6711 # The arg is know to be a Python object, and
6712 # the dst_type is known to be an extension type.
6713 assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
6714 CoercionNode.__init__(self, arg)
6715 self.type = dst_type
6716 self.result_ctype = arg.ctype()
6717 self.notnone = notnone
6719 nogil_check = Node.gil_error
6720 gil_message = "Python type test"
6722 def analyse_types(self, env):
6725 def may_be_none(self):
6728 return self.arg.may_be_none()
6730 def result_in_temp(self):
6731 return self.arg.result_in_temp()
6733 def is_ephemeral(self):
6734 return self.arg.is_ephemeral()
6736 def calculate_constant_result(self):
6740 def calculate_result_code(self):
6741 return self.arg.result()
6743 def generate_result_code(self, code):
6744 if self.type.typeobj_is_available():
6745 if not self.type.is_builtin_type:
6746 code.globalstate.use_utility_code(type_test_utility_code)
6749 self.type.type_test_code(self.arg.py_result(), self.notnone),
6750 code.error_goto(self.pos)))
6752 error(self.pos, "Cannot test type of extern C class "
6753 "without type object name specification")
6755 def generate_post_assignment_code(self, code):
6756 self.arg.generate_post_assignment_code(code)
6758 def free_temps(self, code):
6759 self.arg.free_temps(code)
6762 class NoneCheckNode(CoercionNode):
6763 # This node is used to check that a Python object is not None and
6764 # raises an appropriate exception (as specified by the creating
6767 def __init__(self, arg, exception_type_cname, exception_message):
6768 CoercionNode.__init__(self, arg)
6769 self.type = arg.type
6770 self.result_ctype = arg.ctype()
6771 self.exception_type_cname = exception_type_cname
6772 self.exception_message = exception_message
6774 def analyse_types(self, env):
6777 def may_be_none(self):
6780 def result_in_temp(self):
6781 return self.arg.result_in_temp()
6783 def calculate_result_code(self):
6784 return self.arg.result()
6786 def generate_result_code(self, code):
6788 "if (unlikely(%s == Py_None)) {" % self.arg.result())
6789 code.putln('PyErr_SetString(%s, "%s"); %s ' % (
6790 self.exception_type_cname,
6791 StringEncoding.escape_byte_string(
6792 self.exception_message.encode('UTF-8')),
6793 code.error_goto(self.pos)))
6796 def generate_post_assignment_code(self, code):
6797 self.arg.generate_post_assignment_code(code)
6799 def free_temps(self, code):
6800 self.arg.free_temps(code)
6803 class CoerceToPyTypeNode(CoercionNode):
6804 # This node is used to convert a C data type
6805 # to a Python object.
6807 type = py_object_type
6810 def __init__(self, arg, env, type=py_object_type):
6811 CoercionNode.__init__(self, arg)
6812 if not arg.type.create_to_py_utility_code(env):
6814 "Cannot convert '%s' to Python object" % arg.type)
6815 if type is not py_object_type:
6816 self.type = py_object_type
6817 elif arg.type.is_string:
6818 self.type = bytes_type
6819 elif arg.type is PyrexTypes.c_py_unicode_type:
6820 self.type = unicode_type
6822 gil_message = "Converting to Python object"
6824 def may_be_none(self):
6825 # FIXME: is this always safe?
6828 def coerce_to_boolean(self, env):
6829 arg_type = self.arg.type
6830 if (arg_type == PyrexTypes.c_bint_type or
6831 (arg_type.is_pyobject and arg_type.name == 'bool')):
6832 return self.arg.coerce_to_temp(env)
6834 return CoerceToBooleanNode(self, env)
6836 def coerce_to_integer(self, env):
6837 # If not already some C integer type, coerce to longint.
6838 if self.arg.type.is_int:
6841 return self.arg.coerce_to(PyrexTypes.c_long_type, env)
6843 def analyse_types(self, env):
6844 # The arg is always already analysed
6847 def generate_result_code(self, code):
6848 function = self.arg.type.to_py_function
6849 code.putln('%s = %s(%s); %s' % (
6853 code.error_goto_if_null(self.result(), self.pos)))
6854 code.put_gotref(self.py_result())
6857 class CoerceIntToBytesNode(CoerceToPyTypeNode):
6858 # This node is used to convert a C int type to a Python bytes
6863 def __init__(self, arg, env):
6864 arg = arg.coerce_to_simple(env)
6865 CoercionNode.__init__(self, arg)
6866 self.type = Builtin.bytes_type
6868 def generate_result_code(self, code):
6870 arg_result = arg.result()
6871 if arg.type not in (PyrexTypes.c_char_type,
6872 PyrexTypes.c_uchar_type,
6873 PyrexTypes.c_schar_type):
6875 code.putln("if ((%s < 0) || (%s > 255)) {" % (
6876 arg_result, arg_result))
6878 code.putln("if (%s > 255) {" % arg_result)
6879 code.putln('PyErr_Format(PyExc_OverflowError, '
6880 '"value too large to pack into a byte"); %s' % (
6881 code.error_goto(self.pos)))
6884 if arg.type is not PyrexTypes.c_char_type:
6885 temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
6886 code.putln("%s = (char)%s;" % (temp, arg_result))
6888 code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
6891 code.error_goto_if_null(self.result(), self.pos)))
6892 if temp is not None:
6893 code.funcstate.release_temp(temp)
6894 code.put_gotref(self.py_result())
6897 class CoerceFromPyTypeNode(CoercionNode):
6898 # This node is used to convert a Python object
6901 def __init__(self, result_type, arg, env):
6902 CoercionNode.__init__(self, arg)
6903 self.type = result_type
6905 if not result_type.create_from_py_utility_code(env):
6907 "Cannot convert Python object to '%s'" % result_type)
6908 if self.type.is_string and self.arg.is_ephemeral():
6910 "Obtaining char * from temporary Python value")
6912 def analyse_types(self, env):
6913 # The arg is always already analysed
6916 def generate_result_code(self, code):
6917 function = self.type.from_py_function
6918 operand = self.arg.py_result()
6919 rhs = "%s(%s)" % (function, operand)
6920 if self.type.is_enum:
6921 rhs = typecast(self.type, c_long_type, rhs)
6922 code.putln('%s = %s; %s' % (
6925 code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
6926 if self.type.is_pyobject:
6927 code.put_gotref(self.py_result())
6930 class CoerceToBooleanNode(CoercionNode):
6931 # This node is used when a result needs to be used
6932 # in a boolean context.
6934 type = PyrexTypes.c_bint_type
6936 _special_builtins = {
6937 Builtin.list_type : 'PyList_GET_SIZE',
6938 Builtin.tuple_type : 'PyTuple_GET_SIZE',
6939 Builtin.bytes_type : 'PyBytes_GET_SIZE',
6940 Builtin.unicode_type : 'PyUnicode_GET_SIZE',
6943 def __init__(self, arg, env):
6944 CoercionNode.__init__(self, arg)
6945 if arg.type.is_pyobject:
6948 def nogil_check(self, env):
6949 if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
6952 gil_message = "Truth-testing Python object"
6954 def check_const(self):
6958 return self.arg.check_const()
6960 def calculate_result_code(self):
6961 return "(%s != 0)" % self.arg.result()
6963 def generate_result_code(self, code):
6964 if not self.is_temp:
6966 test_func = self._special_builtins.get(self.arg.type)
6967 if test_func is not None:
6968 code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
6970 self.arg.py_result(),
6972 self.arg.py_result()))
6975 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
6977 self.arg.py_result(),
6978 code.error_goto_if_neg(self.result(), self.pos)))
6980 class CoerceToComplexNode(CoercionNode):
6982 def __init__(self, arg, dst_type, env):
6983 if arg.type.is_complex:
6984 arg = arg.coerce_to_simple(env)
6985 self.type = dst_type
6986 CoercionNode.__init__(self, arg)
6987 dst_type.create_declaration_utility_code(env)
6989 def calculate_result_code(self):
6990 if self.arg.type.is_complex:
6991 real_part = "__Pyx_CREAL(%s)" % self.arg.result()
6992 imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
6994 real_part = self.arg.result()
6996 return "%s(%s, %s)" % (
6997 self.type.from_parts,
7001 def generate_result_code(self, code):
7004 class CoerceToTempNode(CoercionNode):
7005 # This node is used to force the result of another node
7006 # to be stored in a temporary. It is only used if the
7007 # argument node's result is not already in a temporary.
7009 def __init__(self, arg, env):
7010 CoercionNode.__init__(self, arg)
7011 self.type = self.arg.type
7012 self.constant_result = self.arg.constant_result
7014 if self.type.is_pyobject:
7015 self.result_ctype = py_object_type
7017 gil_message = "Creating temporary Python reference"
7019 def analyse_types(self, env):
7020 # The arg is always already analysed
7023 def coerce_to_boolean(self, env):
7024 self.arg = self.arg.coerce_to_boolean(env)
7025 if self.arg.is_simple():
7027 self.type = self.arg.type
7028 self.result_ctype = self.type
7031 def generate_result_code(self, code):
7032 #self.arg.generate_evaluation_code(code) # Already done
7033 # by generic generate_subexpr_evaluation_code!
7034 code.putln("%s = %s;" % (
7035 self.result(), self.arg.result_as(self.ctype())))
7036 if self.type.is_pyobject and self.use_managed_ref:
7037 code.put_incref(self.result(), self.ctype())
7040 class CloneNode(CoercionNode):
7041 # This node is employed when the result of another node needs
7042 # to be used multiple times. The argument node's result must
7043 # be in a temporary. This node "borrows" the result from the
7044 # argument node, and does not generate any evaluation or
7045 # disposal code for it. The original owner of the argument
7046 # node is responsible for doing those things.
7048 subexprs = [] # Arg is not considered a subexpr
7051 def __init__(self, arg):
7052 CoercionNode.__init__(self, arg)
7053 if hasattr(arg, 'type'):
7054 self.type = arg.type
7055 self.result_ctype = arg.result_ctype
7056 if hasattr(arg, 'entry'):
7057 self.entry = arg.entry
7060 return self.arg.result()
7062 def type_dependencies(self, env):
7063 return self.arg.type_dependencies(env)
7065 def infer_type(self, env):
7066 return self.arg.infer_type(env)
7068 def analyse_types(self, env):
7069 self.type = self.arg.type
7070 self.result_ctype = self.arg.result_ctype
7072 if hasattr(self.arg, 'entry'):
7073 self.entry = self.arg.entry
7075 def generate_evaluation_code(self, code):
7078 def generate_result_code(self, code):
7081 def generate_disposal_code(self, code):
7084 def free_temps(self, code):
7088 class ModuleRefNode(ExprNode):
7089 # Simple returns the module object
7091 type = py_object_type
7095 def analyse_types(self, env):
7098 def may_be_none(self):
7101 def calculate_result_code(self):
7102 return Naming.module_cname
7104 def generate_result_code(self, code):
7107 class DocstringRefNode(ExprNode):
7108 # Extracts the docstring of the body element
7111 type = py_object_type
7114 def __init__(self, pos, body):
7115 ExprNode.__init__(self, pos)
7116 assert body.type.is_pyobject
7119 def analyse_types(self, env):
7122 def generate_result_code(self, code):
7123 code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
7124 self.result(), self.body.result(),
7125 code.error_goto_if_null(self.result(), self.pos)))
7126 code.put_gotref(self.result())
7130 #------------------------------------------------------------------------------------
7132 # Runtime support code
7134 #------------------------------------------------------------------------------------
7136 get_name_interned_utility_code = UtilityCode(
7138 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7141 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
7143 result = PyObject_GetAttr(dict, name);
7145 PyErr_SetObject(PyExc_NameError, name);
7150 #------------------------------------------------------------------------------------
7152 import_utility_code = UtilityCode(
7154 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7157 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7158 PyObject *py_import = 0;
7159 PyObject *empty_list = 0;
7160 PyObject *module = 0;
7161 PyObject *global_dict = 0;
7162 PyObject *empty_dict = 0;
7164 py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
7170 empty_list = PyList_New(0);
7175 global_dict = PyModule_GetDict(%(GLOBALS)s);
7178 empty_dict = PyDict_New();
7181 module = PyObject_CallFunctionObjArgs(py_import,
7182 name, global_dict, empty_dict, list, NULL);
7184 Py_XDECREF(empty_list);
7185 Py_XDECREF(py_import);
7186 Py_XDECREF(empty_dict);
7190 "BUILTINS": Naming.builtins_cname,
7191 "GLOBALS": Naming.module_cname,
7194 #------------------------------------------------------------------------------------
7196 get_exception_utility_code = UtilityCode(
7198 static PyObject *__Pyx_GetExcValue(void); /*proto*/
7201 static PyObject *__Pyx_GetExcValue(void) {
7202 PyObject *type = 0, *value = 0, *tb = 0;
7203 PyObject *tmp_type, *tmp_value, *tmp_tb;
7204 PyObject *result = 0;
7205 PyThreadState *tstate = PyThreadState_Get();
7206 PyErr_Fetch(&type, &value, &tb);
7207 PyErr_NormalizeException(&type, &value, &tb);
7208 if (PyErr_Occurred())
7214 tmp_type = tstate->exc_type;
7215 tmp_value = tstate->exc_value;
7216 tmp_tb = tstate->exc_traceback;
7217 tstate->exc_type = type;
7218 tstate->exc_value = value;
7219 tstate->exc_traceback = tb;
7220 /* Make sure tstate is in a consistent state when we XDECREF
7221 these objects (XDECREF may run arbitrary code). */
7222 Py_XDECREF(tmp_type);
7223 Py_XDECREF(tmp_value);
7238 #------------------------------------------------------------------------------------
7240 type_test_utility_code = UtilityCode(
7242 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7245 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7246 if (unlikely(!type)) {
7247 PyErr_Format(PyExc_SystemError, "Missing type object");
7250 if (likely(PyObject_TypeCheck(obj, type)))
7252 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
7253 Py_TYPE(obj)->tp_name, type->tp_name);
7258 #------------------------------------------------------------------------------------
7260 create_class_utility_code = UtilityCode(
7262 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7263 PyObject *modname, PyObject *kwargs); /*proto*/
7264 static int __Pyx_PrepareClass(PyObject *metaclass, PyObject *bases, PyObject *name,
7265 PyObject *mkw, PyObject *dict); /*proto*/
7268 static int __Pyx_PrepareClass(PyObject *metaclass, PyObject *bases, PyObject *name,
7269 PyObject *mkw, PyObject *dict) {
7274 prep = PyObject_GetAttrString(metaclass, "__prepare__");
7276 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7281 pargs = PyTuple_New(2);
7288 PyTuple_SET_ITEM(pargs, 0, name);
7289 PyTuple_SET_ITEM(pargs, 1, bases);
7290 ns = PyEval_CallObjectWithKeywords(prep, pargs, mkw);
7295 /* XXX: This is hack, merge namespace back to dict,
7296 __prepare__ should be ran before dict initialization */
7297 if (PyDict_Merge(dict, ns, 0)) {
7305 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7306 PyObject *modname, PyObject *kwargs) {
7307 PyObject *result = NULL;
7308 PyObject *metaclass = NULL;
7309 PyObject *mkw = NULL;
7311 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
7314 /* Python3 metaclasses */
7316 mkw = PyDict_Copy(kwargs); /* Don't modify kwargs passed in! */
7319 metaclass = PyDict_GetItemString(mkw, "metaclass");
7321 Py_INCREF(metaclass);
7322 if (PyDict_DelItemString(mkw, "metaclass") < 0)
7324 if (__Pyx_PrepareClass(metaclass, bases, name, mkw, dict))
7329 /* Python2 __metaclass__ */
7330 metaclass = PyDict_GetItemString(dict, "__metaclass__");
7332 /* Default metaclass */
7333 #if PY_MAJOR_VERSION < 3
7334 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7335 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7336 metaclass = PyObject_GetAttrString(base, "__class__");
7339 metaclass = (PyObject *)base->ob_type;
7342 metaclass = (PyObject *) &PyClass_Type;
7344 if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
7345 PyObject *base = PyTuple_GET_ITEM(bases, 0);
7346 metaclass = (PyObject *)base->ob_type;
7348 metaclass = (PyObject *) &PyType_Type;
7351 Py_INCREF(metaclass);
7353 if (mkw && PyDict_Size(mkw) > 0) {
7354 PyObject *margs = PyTuple_New(3);
7360 PyTuple_SET_ITEM(margs, 0, name);
7361 PyTuple_SET_ITEM(margs, 1, bases);
7362 PyTuple_SET_ITEM(margs, 2, dict);
7363 result = PyEval_CallObjectWithKeywords(metaclass, margs, mkw);
7366 result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
7369 Py_DECREF(metaclass);
7375 #------------------------------------------------------------------------------------
7377 cpp_exception_utility_code = UtilityCode(
7379 #ifndef __Pyx_CppExn2PyErr
7380 static void __Pyx_CppExn2PyErr() {
7382 if (PyErr_Occurred())
7383 ; // let the latest Python exn pass through and ignore the current one
7386 } catch (const std::invalid_argument& exn) {
7387 // Catch a handful of different errors here and turn them into the
7388 // equivalent Python errors.
7389 // Change invalid_argument to ValueError
7390 PyErr_SetString(PyExc_ValueError, exn.what());
7391 } catch (const std::out_of_range& exn) {
7392 // Change out_of_range to IndexError
7393 PyErr_SetString(PyExc_IndexError, exn.what());
7394 } catch (const std::exception& exn) {
7395 PyErr_SetString(PyExc_RuntimeError, exn.what());
7399 PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
7407 pyerr_occurred_withgil_utility_code= UtilityCode(
7409 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
7412 static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
7415 PyGILState_STATE _save = PyGILState_Ensure();
7417 err = !!PyErr_Occurred();
7419 PyGILState_Release(_save);
7426 #------------------------------------------------------------------------------------
7428 raise_noneattr_error_utility_code = UtilityCode(
7430 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
7433 static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
7434 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
7438 raise_noneindex_error_utility_code = UtilityCode(
7440 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
7443 static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
7444 PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
7448 raise_none_iter_error_utility_code = UtilityCode(
7450 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
7453 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
7454 PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
7458 #------------------------------------------------------------------------------------
7460 getitem_dict_utility_code = UtilityCode(
7463 #if PY_MAJOR_VERSION >= 3
7464 static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7466 if (unlikely(d == Py_None)) {
7467 __Pyx_RaiseNoneIndexingError();
7470 value = PyDict_GetItemWithError(d, key);
7471 if (unlikely(!value)) {
7472 if (!PyErr_Occurred())
7473 PyErr_SetObject(PyExc_KeyError, key);
7480 #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
7483 requires = [raise_noneindex_error_utility_code])
7485 #------------------------------------------------------------------------------------
7487 getitem_int_pyunicode_utility_code = UtilityCode(
7489 #define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7490 __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
7491 __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7493 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
7494 if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
7495 return PyUnicode_AS_UNICODE(ustring)[i];
7496 } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
7497 i += PyUnicode_GET_SIZE(ustring);
7498 return PyUnicode_AS_UNICODE(ustring)[i];
7500 PyErr_SetString(PyExc_IndexError, "string index out of range");
7501 return (Py_UNICODE)-1;
7505 static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
7507 PyObject *uchar_string;
7508 if (!j) return (Py_UNICODE)-1;
7509 uchar_string = PyObject_GetItem(ustring, j);
7511 if (!uchar_string) return (Py_UNICODE)-1;
7512 uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
7513 Py_DECREF(uchar_string);
7518 getitem_int_utility_code = UtilityCode(
7521 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
7523 if (!j) return NULL;
7524 r = PyObject_GetItem(o, j);
7531 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7532 __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
7533 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7535 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
7536 if (likely(o != Py_None)) {
7537 if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
7538 PyObject *r = Py%(type)s_GET_ITEM(o, i);
7542 else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
7543 PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
7548 return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7550 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
7553 #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7554 __Pyx_GetItemInt_Fast(o, i) : \\
7555 __Pyx_GetItemInt_Generic(o, to_py_func(i)))
7557 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
7559 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7560 r = PyList_GET_ITEM(o, i);
7563 else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
7564 r = PyTuple_GET_ITEM(o, i);
7567 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
7568 r = PySequence_GetItem(o, i);
7571 r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
7581 #------------------------------------------------------------------------------------
7583 setitem_int_utility_code = UtilityCode(
7585 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7586 __Pyx_SetItemInt_Fast(o, i, v) : \\
7587 __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
7589 static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
7592 r = PyObject_SetItem(o, j, v);
7597 static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
7598 if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
7600 Py_DECREF(PyList_GET_ITEM(o, i));
7601 PyList_SET_ITEM(o, i, v);
7604 else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
7605 return PySequence_SetItem(o, i, v);
7607 PyObject *j = PyInt_FromSsize_t(i);
7608 return __Pyx_SetItemInt_Generic(o, j, v);
7615 #------------------------------------------------------------------------------------
7617 delitem_int_utility_code = UtilityCode(
7619 #define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
7620 __Pyx_DelItemInt_Fast(o, i) : \\
7621 __Pyx_DelItem_Generic(o, to_py_func(i)))
7623 static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
7626 r = PyObject_DelItem(o, j);
7631 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
7632 if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
7633 return PySequence_DelItem(o, i);
7635 PyObject *j = PyInt_FromSsize_t(i);
7636 return __Pyx_DelItem_Generic(o, j);
7643 #------------------------------------------------------------------------------------
7645 raise_too_many_values_to_unpack = UtilityCode(
7647 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
7650 static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
7651 PyErr_Format(PyExc_ValueError,
7652 #if PY_VERSION_HEX < 0x02050000
7653 "too many values to unpack (expected %d)", (int)expected);
7655 "too many values to unpack (expected %zd)", expected);
7660 raise_need_more_values_to_unpack = UtilityCode(
7662 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
7665 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
7666 PyErr_Format(PyExc_ValueError,
7667 #if PY_VERSION_HEX < 0x02050000
7668 "need more than %d value%s to unpack", (int)index,
7670 "need more than %zd value%s to unpack", index,
7672 (index == 1) ? "" : "s");
7676 #------------------------------------------------------------------------------------
7678 tuple_unpacking_error_code = UtilityCode(
7680 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
7683 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
7685 __Pyx_RaiseNoneNotIterableError();
7686 } else if (PyTuple_GET_SIZE(t) < index) {
7687 __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
7689 __Pyx_RaiseTooManyValuesError(index);
7693 requires = [raise_none_iter_error_utility_code,
7694 raise_need_more_values_to_unpack,
7695 raise_too_many_values_to_unpack]
7698 unpacking_utility_code = UtilityCode(
7700 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
7701 static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
7704 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
7706 if (!(item = PyIter_Next(iter))) {
7707 if (!PyErr_Occurred()) {
7708 __Pyx_RaiseNeedMoreValuesError(index);
7714 static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
7716 if ((item = PyIter_Next(iter))) {
7718 __Pyx_RaiseTooManyValuesError(expected);
7721 else if (!PyErr_Occurred())
7727 requires = [raise_need_more_values_to_unpack,
7728 raise_too_many_values_to_unpack]
7731 #------------------------------------------------------------------------------------
7733 # CPython supports calling functions with non-dict kwargs by
7734 # converting them to a dict first
7736 kwargs_call_utility_code = UtilityCode(
7738 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
7741 static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
7743 if (likely(PyDict_Check(kwargs))) {
7744 return PyEval_CallObjectWithKeywords(callable, args, kwargs);
7746 PyObject* real_dict;
7747 real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
7748 if (unlikely(!real_dict))
7750 result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
7751 Py_DECREF(real_dict);
7752 return result; /* may be NULL */
7759 #------------------------------------------------------------------------------------
7761 int_pow_utility_code = UtilityCode(
7763 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
7766 static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
7778 if (unlikely(e<0)) return 0;
7781 t *= (b * (e&1)) | ((~e)&1); /* 1 or b */
7789 # ------------------------------ Division ------------------------------------
7791 div_int_utility_code = UtilityCode(
7793 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
7796 static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
7798 %(type)s r = a - q*b;
7799 q -= ((r != 0) & ((r ^ b) < 0));
7804 mod_int_utility_code = UtilityCode(
7806 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
7809 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
7810 %(type)s r = a %% b;
7811 r += ((r != 0) & ((r ^ b) < 0)) * b;
7816 mod_float_utility_code = UtilityCode(
7818 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
7821 static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
7822 %(type)s r = fmod%(math_h_modifier)s(a, b);
7823 r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
7828 cdivision_warning_utility_code = UtilityCode(
7830 static int __Pyx_cdivision_warning(void); /* proto */
7833 static int __Pyx_cdivision_warning(void) {
7834 return PyErr_WarnExplicit(PyExc_RuntimeWarning,
7835 "division with oppositely signed operands, C and Python semantics differ",
7842 'FILENAME': Naming.filename_cname,
7843 'LINENO': Naming.lineno_cname,
7847 division_overflow_test_code = UtilityCode(
7849 #define UNARY_NEG_WOULD_OVERFLOW(x) \
7850 (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
7854 binding_cfunc_utility_code = UtilityCode(
7856 #define %(binding_cfunc)s_USED 1
7859 PyCFunctionObject func;
7860 } %(binding_cfunc)s_object;
7862 PyTypeObject %(binding_cfunc)s_type;
7863 PyTypeObject *%(binding_cfunc)s = NULL;
7865 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
7866 #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
7868 int %(binding_cfunc)s_init(void); /* proto */
7869 """ % Naming.__dict__,
7872 PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
7873 %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
7878 op->func.m_self = self;
7880 op->func.m_module = module;
7881 PyObject_GC_Track(op);
7882 return (PyObject *)op;
7885 static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
7886 PyObject_GC_UnTrack(m);
7887 Py_XDECREF(m->func.m_self);
7888 Py_XDECREF(m->func.m_module);
7892 static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
7895 return PyMethod_New(func, obj, type);
7898 int %(binding_cfunc)s_init(void) {
7899 %(binding_cfunc)s_type = PyCFunction_Type;
7900 %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
7901 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
7902 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
7903 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
7906 %(binding_cfunc)s = &%(binding_cfunc)s_type;
7910 """ % Naming.__dict__)