3 # Pyrex - Parse tree nodes
6 import sys, os, time, copy
12 from sets import Set as set
16 from Errors import error, warning, InternalError
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
30 absolute_path_length = 0
32 def relative_position(pos):
34 We embed the relative filename in the generated C file, since we
35 don't want to have to regnerate and compile all the source code
36 whenever the Python install directory moves (which could happen,
37 e.g,. when distributing binaries.)
40 a position tuple -- (absolute filename, line number column position)
48 global absolute_path_length
49 if absolute_path_length==0:
50 absolute_path_length = len(os.path.abspath(os.getcwd()))
51 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
53 def embed_position(pos, docstring):
54 if not Options.embed_pos_in_docstring:
56 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
59 return EncodedString(pos_line)
61 # make sure we can encode the filename in the docstring encoding
62 # otherwise make the docstring a unicode string
63 encoding = docstring.encoding
64 if encoding is not None:
66 encoded_bytes = pos_line.encode(encoding)
67 except UnicodeEncodeError:
71 # reuse the string encoding of the original docstring
72 doc = EncodedString(pos_line)
74 doc = EncodedString(pos_line + u'\n' + docstring)
75 doc.encoding = encoding
79 from Code import CCodeWriter
80 from types import FunctionType
82 def write_func_call(func):
84 if len(args) > 1 and isinstance(args[1], CCodeWriter):
85 # here we annotate the code with this function call
86 # but only if new code is generated
88 marker = ' /* %s -> %s.%s %s */' % (
89 ' ' * code.call_level,
90 node.__class__.__name__,
93 pristine = code.buffer.stream.tell()
95 start = code.buffer.stream.tell()
97 res = func(*args, **kwds)
99 if start == code.buffer.stream.tell():
100 code.buffer.stream.seek(pristine)
102 marker = marker.replace('->', '<-')
106 return func(*args, **kwds)
109 class VerboseCodeWriter(type):
110 # Set this as a metaclass to trace function calls in code.
111 # This slows down code generation and makes much larger files.
112 def __new__(cls, name, bases, attrs):
114 for mname, m in attrs.items():
115 if isinstance(m, FunctionType):
116 attrs[mname] = write_func_call(m)
117 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
121 # pos (string, int, int) Source file position
122 # is_name boolean Is a NameNode
123 # is_literal boolean Is a ConstNode
125 if DebugFlags.debug_trace_code_generation:
126 __metaclass__ = VerboseCodeWriter
132 # All descandants should set child_attrs to a list of the attributes
133 # containing nodes considered "children" in the tree. Each such attribute
134 # can either contain a single node or a list of nodes. See Visitor.py.
137 def __init__(self, pos, **kw):
139 self.__dict__.update(kw)
141 gil_message = "Operation"
145 def gil_error(self, env=None):
146 error(self.pos, "%s not allowed without gil" % self.gil_message)
148 cpp_message = "Operation"
150 def cpp_check(self, env):
155 error(self.pos, "%s only allowed in c++" % self.cpp_message)
157 def clone_node(self):
158 """Clone the node. This is defined as a shallow copy, except for member lists
159 amongst the child attributes (from get_child_accessors) which are also
160 copied. Lists containing child nodes are thus seen as a way for the node
161 to hold multiple children directly; the list is not treated as a seperate
162 level in the tree."""
163 result = copy.copy(self)
164 for attrname in result.child_attrs:
165 value = getattr(result, attrname)
166 if isinstance(value, list):
167 setattr(result, attrname, [x for x in value])
172 # There are 4 phases of parse tree processing, applied in order to
173 # all the statements in a given scope-block:
175 # (0) analyse_control_flow
176 # Create the control flow tree into which state can be asserted and
179 # (1) analyse_declarations
180 # Make symbol table entries for all declarations at the current
181 # level, both explicit (def, cdef, etc.) and implicit (assignment
182 # to an otherwise undeclared name).
184 # (2) analyse_expressions
185 # Determine the result types of expressions and fill in the
186 # 'type' attribute of each ExprNode. Insert coercion nodes into the
187 # tree where needed to convert to and from Python objects.
188 # Allocate temporary locals for intermediate results. Fill
189 # in the 'result_code' attribute of each ExprNode with a C code
193 # Emit C code for all declarations, statements and expressions.
194 # Recursively applies the 3 processing phases to the bodies of
198 def analyse_control_flow(self, env):
201 def analyse_declarations(self, env):
204 def analyse_expressions(self, env):
205 raise InternalError("analyse_expressions not implemented for %s" % \
206 self.__class__.__name__)
208 def generate_code(self, code):
209 raise InternalError("generate_code not implemented for %s" % \
210 self.__class__.__name__)
212 def annotate(self, code):
213 # mro does the wrong thing
214 if isinstance(self, BlockNode):
215 self.body.annotate(code)
220 except AttributeError:
222 if not self.child_attrs:
225 for attr in self.child_attrs:
226 child = getattr(self, attr)
227 # Sometimes lists, sometimes nodes
230 elif isinstance(child, list):
232 pos = max(pos, c.end_pos())
234 pos = max(pos, child.end_pos())
238 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
240 return "<...nesting level cutoff...>"
241 if encountered is None:
243 if id(self) in encountered:
244 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
245 encountered.add(id(self))
247 def dump_child(x, level):
248 if isinstance(x, Node):
249 return x.dump(level, filter_out, cutoff-1, encountered)
250 elif isinstance(x, list):
251 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
256 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
258 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
261 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
262 for key, value in attrs:
263 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
264 res += "%s>" % indent
267 class CompilerDirectivesNode(Node):
269 Sets compiler directives for the children nodes
271 # directives {string:value} A dictionary holding the right value for
272 # *all* possible directives.
274 child_attrs = ["body"]
276 def analyse_control_flow(self, env):
278 env.directives = self.directives
279 self.body.analyse_control_flow(env)
282 def analyse_declarations(self, env):
284 env.directives = self.directives
285 self.body.analyse_declarations(env)
288 def analyse_expressions(self, env):
290 env.directives = self.directives
291 self.body.analyse_expressions(env)
294 def generate_function_definitions(self, env, code):
295 env_old = env.directives
296 code_old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.generate_function_definitions(env, code)
299 env.directives = env_old
300 code.globalstate.directives = code_old
302 def generate_execution_code(self, code):
303 old = code.globalstate.directives
304 code.globalstate.directives = self.directives
305 self.body.generate_execution_code(code)
306 code.globalstate.directives = old
308 def annotate(self, code):
309 old = code.globalstate.directives
310 code.globalstate.directives = self.directives
311 self.body.annotate(code)
312 code.globalstate.directives = old
314 class BlockNode(object):
315 # Mixin class for nodes representing a declaration block.
317 def generate_cached_builtins_decls(self, env, code):
318 entries = env.global_scope().undeclared_cached_builtins
319 for entry in entries:
320 code.globalstate.add_cached_builtin_decl(entry)
324 class StatListNode(Node):
325 # stats a list of StatNode
327 child_attrs = ["stats"]
329 def create_analysed(pos, env, *args, **kw):
330 node = StatListNode(pos, *args, **kw)
331 return node # No node-specific analysis necesarry
332 create_analysed = staticmethod(create_analysed)
334 def analyse_control_flow(self, env):
335 for stat in self.stats:
336 stat.analyse_control_flow(env)
338 def analyse_declarations(self, env):
339 #print "StatListNode.analyse_declarations" ###
340 for stat in self.stats:
341 stat.analyse_declarations(env)
343 def analyse_expressions(self, env):
344 #print "StatListNode.analyse_expressions" ###
345 for stat in self.stats:
346 stat.analyse_expressions(env)
348 def generate_function_definitions(self, env, code):
349 #print "StatListNode.generate_function_definitions" ###
350 for stat in self.stats:
351 stat.generate_function_definitions(env, code)
353 def generate_execution_code(self, code):
354 #print "StatListNode.generate_execution_code" ###
355 for stat in self.stats:
356 code.mark_pos(stat.pos)
357 stat.generate_execution_code(code)
359 def annotate(self, code):
360 for stat in self.stats:
364 class StatNode(Node):
366 # Code generation for statements is split into the following subphases:
368 # (1) generate_function_definitions
369 # Emit C code for the definitions of any structs,
370 # unions, enums and functions defined in the current
373 # (2) generate_execution_code
374 # Emit C code for executable statements.
377 def generate_function_definitions(self, env, code):
380 def generate_execution_code(self, code):
381 raise InternalError("generate_execution_code not implemented for %s" % \
382 self.__class__.__name__)
385 class CDefExternNode(StatNode):
386 # include_file string or None
389 child_attrs = ["body"]
391 def analyse_declarations(self, env):
392 if self.include_file:
393 env.add_include_file(self.include_file)
394 old_cinclude_flag = env.in_cinclude
396 self.body.analyse_declarations(env)
397 env.in_cinclude = old_cinclude_flag
399 def analyse_expressions(self, env):
402 def generate_execution_code(self, code):
405 def annotate(self, code):
406 self.body.annotate(code)
409 class CDeclaratorNode(Node):
410 # Part of a C declaration.
412 # Processing during analyse_declarations phase:
415 # Returns (name, type) pair where name is the
416 # CNameDeclaratorNode of the name being declared
417 # and type is the type it is being declared as.
419 # calling_convention string Calling convention of CFuncDeclaratorNode
420 # for which this is a base
424 calling_convention = ""
427 class CNameDeclaratorNode(CDeclaratorNode):
428 # name string The Pyrex name being declared
429 # cname string or None C name, if specified
430 # default ExprNode or None the value assigned on declaration
432 child_attrs = ['default']
436 def analyse(self, base_type, env, nonempty = 0):
437 if nonempty and self.name == '':
438 # May have mistaken the name for the type.
439 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440 error(self.pos, "Missing argument name")
441 elif base_type.is_void:
442 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
444 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445 base_type = py_object_type
446 self.type = base_type
447 return self, base_type
449 class CPtrDeclaratorNode(CDeclaratorNode):
450 # base CDeclaratorNode
452 child_attrs = ["base"]
454 def analyse(self, base_type, env, nonempty = 0):
455 if base_type.is_pyobject:
457 "Pointer base type cannot be a Python object")
458 ptr_type = PyrexTypes.c_ptr_type(base_type)
459 return self.base.analyse(ptr_type, env, nonempty = nonempty)
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462 # base CDeclaratorNode
464 child_attrs = ["base"]
466 def analyse(self, base_type, env, nonempty = 0):
467 if base_type.is_pyobject:
469 "Reference base type cannot be a Python object")
470 ref_type = PyrexTypes.c_ref_type(base_type)
471 return self.base.analyse(ref_type, env, nonempty = nonempty)
473 class CArrayDeclaratorNode(CDeclaratorNode):
474 # base CDeclaratorNode
477 child_attrs = ["base", "dimension"]
479 def analyse(self, base_type, env, nonempty = 0):
480 if base_type.is_cpp_class:
481 from ExprNodes import TupleNode
482 if isinstance(self.dimension, TupleNode):
483 args = self.dimension.args
485 args = self.dimension,
486 values = [v.analyse_as_type(env) for v in args]
488 ix = values.index(None)
489 error(args[ix].pos, "Template parameter not a type.")
491 base_type = base_type.specialize_here(self.pos, values)
492 return self.base.analyse(base_type, env, nonempty = nonempty)
494 self.dimension.analyse_const_expression(env)
495 if not self.dimension.type.is_int:
496 error(self.dimension.pos, "Array dimension not integer")
497 size = self.dimension.get_constant_c_result_code()
506 if not base_type.is_complete():
508 "Array element type '%s' is incomplete" % base_type)
509 if base_type.is_pyobject:
511 "Array element cannot be a Python object")
512 if base_type.is_cfunction:
514 "Array element cannot be a function")
515 array_type = PyrexTypes.c_array_type(base_type, size)
516 return self.base.analyse(array_type, env, nonempty = nonempty)
519 class CFuncDeclaratorNode(CDeclaratorNode):
520 # base CDeclaratorNode
521 # args [CArgDeclNode]
522 # has_varargs boolean
523 # exception_value ConstNode
524 # exception_check boolean True if PyErr_Occurred check needed
525 # nogil boolean Can be called without gil
526 # with_gil boolean Acquire gil around function body
528 child_attrs = ["base", "args", "exception_value"]
531 optional_arg_count = 0
533 def analyse(self, return_type, env, nonempty = 0):
537 for i, arg_node in enumerate(self.args):
538 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
539 is_self_arg = (i == 0 and env.is_c_class_scope))
540 name = name_declarator.name
541 if name_declarator.cname:
543 "Function argument cannot have C name specification")
544 # Turn *[] argument into **
546 type = PyrexTypes.c_ptr_type(type.base_type)
547 # Catch attempted C-style func(void) decl
549 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
550 func_type_args.append(
551 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
553 self.optional_arg_count += 1
554 elif self.optional_arg_count:
555 error(self.pos, "Non-default argument follows default argument")
557 if self.optional_arg_count:
558 scope = StructOrUnionScope()
559 arg_count_member = '%sn' % Naming.pyrex_prefix
560 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
561 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
562 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
563 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
564 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
569 cname = struct_cname)
570 self.op_args_struct.defined_in_pxd = 1
571 self.op_args_struct.used = 1
575 if self.exception_check == '+':
576 env.add_include_file('stdexcept')
577 if return_type.is_pyobject \
578 and (self.exception_value or self.exception_check) \
579 and self.exception_check != '+':
581 "Exception clause not allowed for function returning Python object")
583 if self.exception_value:
584 self.exception_value.analyse_const_expression(env)
585 if self.exception_check == '+':
586 self.exception_value.analyse_types(env)
587 exc_val_type = self.exception_value.type
588 if not exc_val_type.is_error and \
589 not exc_val_type.is_pyobject and \
590 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
591 error(self.exception_value.pos,
592 "Exception value must be a Python exception or cdef function with no arguments.")
593 exc_val = self.exception_value
595 self.exception_value = self.exception_value.coerce_to(return_type, env)
596 if self.exception_value.analyse_const_expression(env):
597 exc_val = self.exception_value.get_constant_c_result_code()
599 raise InternalError("get_constant_c_result_code not implemented for %s" %
600 self.exception_value.__class__.__name__)
601 if not return_type.assignable_from(self.exception_value.type):
602 error(self.exception_value.pos,
603 "Exception value incompatible with function return type")
604 exc_check = self.exception_check
605 if return_type.is_array:
607 "Function cannot return an array")
608 if return_type.is_cfunction:
610 "Function cannot return a function")
611 func_type = PyrexTypes.CFuncType(
612 return_type, func_type_args, self.has_varargs,
613 optional_arg_count = self.optional_arg_count,
614 exception_value = exc_val, exception_check = exc_check,
615 calling_convention = self.base.calling_convention,
616 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
617 if self.optional_arg_count:
618 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
619 callspec = env.directives['callspec']
621 current = func_type.calling_convention
622 if current and current != callspec:
623 error(self.pos, "cannot have both '%s' and '%s' "
624 "calling conventions" % (current, callspec))
625 func_type.calling_convention = callspec
626 return self.base.analyse(func_type, env)
629 class CArgDeclNode(Node):
630 # Item in a function declaration argument list.
632 # base_type CBaseTypeNode
633 # declarator CDeclaratorNode
634 # not_none boolean Tagged with 'not None'
635 # or_none boolean Tagged with 'or None'
636 # accept_none boolean Resolved boolean for not_none/or_none
637 # default ExprNode or None
638 # default_value PyObjectConst constant for default value
639 # annotation ExprNode or None Py3 function arg annotation
640 # is_self_arg boolean Is the "self" arg of an extension type method
641 # is_type_arg boolean Is the "class" arg of an extension type classmethod
642 # is_kw_only boolean Is a keyword-only argument
644 child_attrs = ["base_type", "declarator", "default"]
650 name_declarator = None
654 def analyse(self, env, nonempty = 0, is_self_arg = False):
656 self.base_type.is_self_arg = self.is_self_arg = True
657 if self.type is None:
658 # The parser may missinterpret names as types...
660 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
662 self.declarator.name = self.base_type.name
663 self.base_type.name = None
664 self.base_type.is_basic_c_type = False
667 could_be_name = False
668 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
669 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
670 self.declarator.name = self.base_type.arg_name
671 # The parser is unable to resolve the ambiguity of [] as part of the
672 # type (e.g. in buffers) or empty declarator (as with arrays).
673 # This is only arises for empty multi-dimensional arrays.
674 if (base_type.is_array
675 and isinstance(self.base_type, TemplatedTypeNode)
676 and isinstance(self.declarator, CArrayDeclaratorNode)):
677 declarator = self.declarator
678 while isinstance(declarator.base, CArrayDeclaratorNode):
679 declarator = declarator.base
680 declarator.base = self.base_type.array_declarator
681 base_type = base_type.base_type
682 return self.declarator.analyse(base_type, env, nonempty = nonempty)
684 return self.name_declarator, self.type
686 def calculate_default_value_code(self, code):
687 if self.default_value is None:
689 if self.default.is_literal:
690 # will not output any code, just assign the result_code
691 self.default.generate_evaluation_code(code)
692 return self.type.cast_code(self.default.result())
693 self.default_value = code.get_argument_default_const(self.type)
694 return self.default_value
696 def annotate(self, code):
698 self.default.annotate(code)
701 class CBaseTypeNode(Node):
702 # Abstract base class for C base type nodes.
704 # Processing during analyse_declarations phase:
711 def analyse_as_type(self, env):
712 return self.analyse(env)
714 class CAnalysedBaseTypeNode(Node):
719 def analyse(self, env, could_be_name = False):
722 class CSimpleBaseTypeNode(CBaseTypeNode):
724 # module_path [string] Qualifying name components
725 # is_basic_c_type boolean
729 # is_self_arg boolean Is self argument of C method
730 # ##is_type_arg boolean Is type argument of class method
733 arg_name = None # in case the argument name was interpreted as a type
735 def analyse(self, env, could_be_name = False):
736 # Return type descriptor.
737 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
739 if self.is_basic_c_type:
740 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
742 error(self.pos, "Unrecognised type modifier combination")
743 elif self.name == "object" and not self.module_path:
744 type = py_object_type
745 elif self.name is None:
746 if self.is_self_arg and env.is_c_class_scope:
747 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
748 type = env.parent_type
749 ## elif self.is_type_arg and env.is_c_class_scope:
750 ## type = Builtin.type_type
752 type = py_object_type
755 scope = env.find_imported_module(self.module_path, self.pos)
759 if scope.is_c_class_scope:
760 scope = scope.global_scope()
761 entry = scope.lookup(self.name)
762 if entry and entry.is_type:
765 if self.is_self_arg and env.is_c_class_scope:
766 type = env.parent_type
767 ## elif self.is_type_arg and env.is_c_class_scope:
768 ## type = Builtin.type_type
770 type = py_object_type
771 self.arg_name = self.name
774 if not self.name in self.templates:
775 error(self.pos, "'%s' is not a type identifier" % self.name)
776 type = PyrexTypes.TemplatePlaceholderType(self.name)
778 error(self.pos, "'%s' is not a type identifier" % self.name)
780 if not type.is_numeric or type.is_complex:
781 error(self.pos, "can only complexify c numeric types")
782 type = PyrexTypes.CComplexType(type)
783 type.create_declaration_utility_code(env)
787 return PyrexTypes.error_type
789 class CNestedBaseTypeNode(CBaseTypeNode):
790 # For C++ classes that live inside other C++ classes.
793 # base_type CBaseTypeNode
795 child_attrs = ['base_type']
797 def analyse(self, env, could_be_name = None):
798 base_type = self.base_type.analyse(env)
799 if base_type is PyrexTypes.error_type:
800 return PyrexTypes.error_type
801 if not base_type.is_cpp_class:
802 error(self.pos, "'%s' is not a valid type scope" % base_type)
803 return PyrexTypes.error_type
804 type_entry = base_type.scope.lookup_here(self.name)
805 if not type_entry or not type_entry.is_type:
806 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
807 return PyrexTypes.error_type
808 return type_entry.type
810 class TemplatedTypeNode(CBaseTypeNode):
812 # positional_args [ExprNode] List of positional arguments
813 # keyword_args DictNode Keyword arguments
814 # base_type_node CBaseTypeNode
817 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
820 child_attrs = ["base_type_node", "positional_args",
821 "keyword_args", "dtype_node"]
827 def analyse(self, env, could_be_name = False, base_type = None):
828 if base_type is None:
829 base_type = self.base_type_node.analyse(env)
830 if base_type.is_error: return base_type
832 if base_type.is_cpp_class:
834 if self.keyword_args and self.keyword_args.key_value_pairs:
835 error(self.pos, "c++ templates cannot take keyword arguments");
836 self.type = PyrexTypes.error_type
839 for template_node in self.positional_args:
840 type = template_node.analyse_as_type(env)
842 error(template_node.pos, "unknown type in template argument")
844 template_types.append(type)
845 self.type = base_type.specialize_here(self.pos, template_types)
847 elif base_type.is_pyobject:
851 options = Buffer.analyse_buffer_options(
854 self.positional_args,
856 base_type.buffer_defaults)
858 if sys.version_info[0] < 3:
859 # Py 2.x enforces byte strings as keyword arguments ...
860 options = dict([ (name.encode('ASCII'), value)
861 for name, value in options.iteritems() ])
863 self.type = PyrexTypes.BufferType(base_type, **options)
867 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
868 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
869 error(self.pos, "invalid array declaration")
870 self.type = PyrexTypes.error_type
872 # It would be nice to merge this class with CArrayDeclaratorNode,
873 # but arrays are part of the declaration, not the type...
874 if not self.positional_args:
877 dimension = self.positional_args[0]
878 self.array_declarator = CArrayDeclaratorNode(self.pos,
879 base = empty_declarator,
880 dimension = dimension)
881 self.type = self.array_declarator.analyse(base_type, env)[1]
885 class CComplexBaseTypeNode(CBaseTypeNode):
886 # base_type CBaseTypeNode
887 # declarator CDeclaratorNode
889 child_attrs = ["base_type", "declarator"]
891 def analyse(self, env, could_be_name = False):
892 base = self.base_type.analyse(env, could_be_name)
893 _, type = self.declarator.analyse(base, env)
897 class CVarDefNode(StatNode):
898 # C variable definition or forward/extern function declaration.
900 # visibility 'private' or 'public' or 'extern'
901 # base_type CBaseTypeNode
902 # declarators [CDeclaratorNode]
906 # decorators [cython.locals(...)] or None
907 # directive_locals { string : NameNode } locals defined by cython.locals(...)
909 child_attrs = ["base_type", "declarators"]
912 directive_locals = {}
914 def analyse_declarations(self, env, dest_scope = None):
917 self.dest_scope = dest_scope
918 base_type = self.base_type.analyse(env)
920 # If the field is an external typedef, we cannot be sure about the type,
921 # so do conversion ourself rather than rely on the CPython mechanism (through
922 # a property; made in AnalyseDeclarationsTransform).
923 if (dest_scope.is_c_class_scope
924 and self.visibility in ('public', 'readonly')):
927 need_property = False
928 visibility = self.visibility
930 for declarator in self.declarators:
931 name_declarator, type = declarator.analyse(base_type, env)
932 if not type.is_complete():
933 if not (self.visibility == 'extern' and type.is_array):
934 error(declarator.pos,
935 "Variable type '%s' is incomplete" % type)
936 if self.visibility == 'extern' and type.is_pyobject:
937 error(declarator.pos,
938 "Python object cannot be declared extern")
939 name = name_declarator.name
940 cname = name_declarator.cname
942 error(declarator.pos, "Missing name in declaration.")
944 if type.is_cfunction:
945 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
948 if entry is not None:
949 entry.directive_locals = self.directive_locals
951 if self.directive_locals:
952 error(self.pos, "Decorators can only be followed by functions")
953 if self.in_pxd and self.visibility != 'extern':
955 "Only 'extern' C variable declaration allowed in .pxd file")
956 entry = dest_scope.declare_var(name, type, declarator.pos,
957 cname = cname, visibility = visibility, is_cdef = 1)
958 entry.needs_property = need_property
961 class CStructOrUnionDefNode(StatNode):
963 # cname string or None
964 # kind "struct" or "union"
965 # typedef_flag boolean
966 # visibility "public" or "private"
968 # attributes [CVarDefNode] or None
972 child_attrs = ["attributes"]
974 def analyse_declarations(self, env):
976 if self.visibility == 'extern' and self.packed:
977 error(self.pos, "Cannot declare extern struct as 'packed'")
978 if self.attributes is not None:
979 scope = StructOrUnionScope(self.name)
980 self.entry = env.declare_struct_or_union(
981 self.name, self.kind, scope, self.typedef_flag, self.pos,
982 self.cname, visibility = self.visibility, packed = self.packed)
983 if self.attributes is not None:
984 if self.in_pxd and not env.in_cinclude:
985 self.entry.defined_in_pxd = 1
986 for attr in self.attributes:
987 attr.analyse_declarations(env, scope)
988 if self.visibility != 'extern':
989 need_typedef_indirection = False
990 for attr in scope.var_entries:
993 type = type.base_type
994 if type == self.entry.type:
995 error(attr.pos, "Struct cannot contain itself as a member.")
996 if self.typedef_flag:
998 type = type.base_type
999 if type == self.entry.type:
1000 need_typedef_indirection = True
1001 if need_typedef_indirection:
1002 # C can't handle typedef structs that refer to themselves.
1003 struct_entry = self.entry
1004 self.entry = env.declare_typedef(
1005 self.name, struct_entry.type, self.pos,
1006 cname = self.cname, visibility='ignore')
1007 struct_entry.type.typedef_flag = False
1008 # FIXME: this might be considered a hack ;-)
1009 struct_entry.cname = struct_entry.type.cname = \
1010 '_' + self.entry.type.typedef_cname
1012 def analyse_expressions(self, env):
1015 def generate_execution_code(self, code):
1019 class CppClassNode(CStructOrUnionDefNode):
1022 # cname string or None
1023 # visibility "extern"
1025 # attributes [CVarDefNode] or None
1027 # base_classes [string]
1028 # templates [string] or None
1030 def analyse_declarations(self, env):
1032 if self.attributes is not None:
1033 scope = CppClassScope(self.name, env)
1034 base_class_types = []
1035 for base_class_name in self.base_classes:
1036 base_class_entry = env.lookup(base_class_name)
1037 if base_class_entry is None:
1038 error(self.pos, "'%s' not found" % base_class_name)
1039 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1040 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1042 base_class_types.append(base_class_entry.type)
1043 if self.templates is None:
1044 template_types = None
1046 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1047 self.entry = env.declare_cpp_class(
1048 self.name, scope, self.pos,
1049 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1050 self.entry.is_cpp_class = 1
1051 if self.attributes is not None:
1052 if self.in_pxd and not env.in_cinclude:
1053 self.entry.defined_in_pxd = 1
1054 for attr in self.attributes:
1055 attr.analyse_declarations(scope)
1057 class CEnumDefNode(StatNode):
1058 # name string or None
1059 # cname string or None
1060 # items [CEnumDefItemNode]
1061 # typedef_flag boolean
1062 # visibility "public" or "private"
1066 child_attrs = ["items"]
1068 def analyse_declarations(self, env):
1069 self.entry = env.declare_enum(self.name, self.pos,
1070 cname = self.cname, typedef_flag = self.typedef_flag,
1071 visibility = self.visibility)
1072 if self.items is not None:
1073 if self.in_pxd and not env.in_cinclude:
1074 self.entry.defined_in_pxd = 1
1075 for item in self.items:
1076 item.analyse_declarations(env, self.entry)
1078 def analyse_expressions(self, env):
1081 def generate_execution_code(self, code):
1082 if self.visibility == 'public':
1083 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1084 for item in self.entry.enum_values:
1085 code.putln("%s = PyInt_FromLong(%s); %s" % (
1088 code.error_goto_if_null(temp, item.pos)))
1089 code.put_gotref(temp)
1090 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1091 Naming.module_cname,
1094 code.error_goto(item.pos)))
1095 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1096 code.funcstate.release_temp(temp)
1099 class CEnumDefItemNode(StatNode):
1101 # cname string or None
1102 # value ExprNode or None
1104 child_attrs = ["value"]
1106 def analyse_declarations(self, env, enum_entry):
1108 self.value.analyse_const_expression(env)
1109 if not self.value.type.is_int:
1110 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1111 self.value.analyse_const_expression(env)
1112 entry = env.declare_const(self.name, enum_entry.type,
1113 self.value, self.pos, cname = self.cname,
1114 visibility = enum_entry.visibility)
1115 enum_entry.enum_values.append(entry)
1118 class CTypeDefNode(StatNode):
1119 # base_type CBaseTypeNode
1120 # declarator CDeclaratorNode
1121 # visibility "public" or "private"
1124 child_attrs = ["base_type", "declarator"]
1126 def analyse_declarations(self, env):
1127 base = self.base_type.analyse(env)
1128 name_declarator, type = self.declarator.analyse(base, env)
1129 name = name_declarator.name
1130 cname = name_declarator.cname
1131 entry = env.declare_typedef(name, type, self.pos,
1132 cname = cname, visibility = self.visibility)
1133 if self.in_pxd and not env.in_cinclude:
1134 entry.defined_in_pxd = 1
1136 def analyse_expressions(self, env):
1138 def generate_execution_code(self, code):
1142 class FuncDefNode(StatNode, BlockNode):
1143 # Base class for function definition nodes.
1145 # return_type PyrexType
1146 # #filename string C name of filename string const
1147 # entry Symtab.Entry
1148 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1149 # needs_outer_scope boolean Whether or not this function requires outer scope
1150 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1154 needs_closure = False
1155 needs_outer_scope = False
1158 def analyse_default_values(self, env):
1159 genv = env.global_scope()
1161 for arg in self.args:
1165 arg.default.analyse_types(env)
1166 arg.default = arg.default.coerce_to(arg.type, genv)
1169 "This argument cannot have a default value")
1174 error(arg.pos, "Non-default argument following default argument")
1176 def need_gil_acquisition(self, lenv):
1179 def create_local_scope(self, env):
1181 while genv.is_py_class_scope or genv.is_c_class_scope:
1182 genv = genv.outer_scope
1183 if self.needs_closure:
1184 lenv = ClosureScope(name=self.entry.name,
1186 scope_name=self.entry.cname)
1188 lenv = LocalScope(name=self.entry.name,
1191 lenv.return_type = self.return_type
1192 type = self.entry.type
1193 if type.is_cfunction:
1194 lenv.nogil = type.nogil and not type.with_gil
1195 self.local_scope = lenv
1196 lenv.directives = env.directives
1199 def generate_function_definitions(self, env, code):
1202 lenv = self.local_scope
1203 if lenv.is_closure_scope and not lenv.is_passthrough:
1204 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1205 Naming.outer_scope_cname)
1207 outer_scope_cname = Naming.outer_scope_cname
1208 lenv.mangle_closure_cnames(outer_scope_cname)
1209 # Generate closure function definitions
1210 self.body.generate_function_definitions(lenv, code)
1211 # generate lambda function definitions
1212 for node in lenv.lambda_defs:
1213 node.generate_function_definitions(lenv, code)
1215 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1216 self.entry.scope.is_c_class_scope)
1217 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1218 self.entry.scope.is_c_class_scope)
1219 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1221 if 'cython_unused' not in self.modifiers:
1222 self.modifiers = self.modifiers + ['cython_unused']
1224 preprocessor_guard = None
1225 if self.entry.is_special and not is_buffer_slot:
1226 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1228 preprocessor_guard = slot.preprocessor_guard_code()
1229 if (self.entry.name == '__long__' and
1230 not self.entry.scope.lookup_here('__int__')):
1231 preprocessor_guard = None
1233 profile = code.globalstate.directives['profile']
1236 error(self.pos, "Cannot profile nogil function.")
1237 code.globalstate.use_utility_code(profile_utility_code)
1239 # Generate C code for header and body of function
1240 code.enter_cfunc_scope()
1241 code.return_from_error_cleanup_label = code.new_label()
1243 # ----- Top-level constants used by this function
1244 code.mark_pos(self.pos)
1245 self.generate_cached_builtins_decls(lenv, code)
1246 # ----- Function header
1249 if preprocessor_guard:
1250 code.putln(preprocessor_guard)
1252 with_pymethdef = self.needs_assignment_synthesis(env, code)
1254 self.py_func.generate_function_header(code,
1255 with_pymethdef = with_pymethdef,
1257 self.generate_function_header(code,
1258 with_pymethdef = with_pymethdef)
1259 # ----- Local variable declarations
1260 # Find function scope
1262 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1263 cenv = cenv.outer_scope
1264 if self.needs_closure:
1265 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1267 elif self.needs_outer_scope:
1268 if lenv.is_passthrough:
1269 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1271 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1273 self.generate_argument_declarations(lenv, code)
1274 for entry in lenv.var_entries:
1275 if not entry.in_closure:
1276 code.put_var_declaration(entry)
1278 if not self.return_type.is_void:
1279 if self.return_type.is_pyobject:
1283 (self.return_type.declaration_code(Naming.retval_cname),
1285 tempvardecl_code = code.insertion_point()
1286 self.generate_keyword_list(code)
1288 code.put_trace_declarations()
1289 # ----- Extern library function declarations
1290 lenv.generate_library_function_declarations(code)
1291 # ----- GIL acquisition
1292 acquire_gil = self.acquire_gil
1294 env.use_utility_code(force_init_threads_utility_code)
1295 code.putln("#ifdef WITH_THREAD")
1296 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1297 code.putln("#endif")
1298 # ----- set up refnanny
1300 code.put_setup_refcount_context(self.entry.name)
1301 # ----- Automatic lead-ins for certain special functions
1302 if is_getbuffer_slot:
1303 self.getbuffer_init(code)
1304 # ----- Create closure scope object
1305 if self.needs_closure:
1306 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1307 Naming.cur_scope_cname,
1308 lenv.scope_class.type.declaration_code(''),
1309 lenv.scope_class.type.typeptr_cname,
1310 lenv.scope_class.type.typeptr_cname,
1311 Naming.empty_tuple))
1312 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1313 if is_getbuffer_slot:
1314 self.getbuffer_error_cleanup(code)
1316 code.put_finish_refcount_context()
1317 # FIXME: what if the error return value is a Python value?
1318 code.putln("return %s;" % self.error_value())
1320 code.put_gotref(Naming.cur_scope_cname)
1321 # Note that it is unsafe to decref the scope at this point.
1322 if self.needs_outer_scope:
1323 code.putln("%s = (%s)%s;" % (
1325 cenv.scope_class.type.declaration_code(''),
1327 if lenv.is_passthrough:
1328 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1329 elif self.needs_closure:
1330 # inner closures own a reference to their outer parent
1331 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1332 code.put_giveref(outer_scope_cname)
1333 # ----- Trace function call
1335 # this looks a bit late, but if we don't get here due to a
1336 # fatal error before hand, it's not really worth tracing
1337 code.put_trace_call(self.entry.name, self.pos)
1338 # ----- Fetch arguments
1339 self.generate_argument_parsing_code(env, code)
1340 # If an argument is assigned to in the body, we must
1341 # incref it to properly keep track of refcounts.
1342 for entry in lenv.arg_entries:
1343 if entry.type.is_pyobject:
1344 if entry.assignments and not entry.in_closure:
1345 code.put_var_incref(entry)
1346 # ----- Initialise local variables
1347 for entry in lenv.var_entries:
1348 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1349 code.put_init_var_to_py_none(entry)
1350 # ----- Initialise local buffer auxiliary variables
1351 for entry in lenv.var_entries + lenv.arg_entries:
1352 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1353 code.putln("%s.buf = NULL;" %
1354 entry.buffer_aux.buffer_info_var.cname)
1355 # ----- Check and convert arguments
1356 self.generate_argument_type_tests(code)
1357 # ----- Acquire buffer arguments
1358 for entry in lenv.arg_entries:
1359 if entry.type.is_buffer:
1360 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1362 # -------------------------
1363 # ----- Function body -----
1364 # -------------------------
1365 self.body.generate_execution_code(code)
1367 # ----- Default return value
1369 if self.return_type.is_pyobject:
1370 #if self.return_type.is_extension_type:
1371 # lhs = "(PyObject *)%s" % Naming.retval_cname
1373 lhs = Naming.retval_cname
1374 code.put_init_to_py_none(lhs, self.return_type)
1376 val = self.return_type.default_value
1378 code.putln("%s = %s;" % (Naming.retval_cname, val))
1379 # ----- Error cleanup
1380 if code.error_label in code.labels_used:
1381 code.put_goto(code.return_label)
1382 code.put_label(code.error_label)
1383 for cname, type in code.funcstate.all_managed_temps():
1384 code.put_xdecref(cname, type)
1386 # Clean up buffers -- this calls a Python function
1387 # so need to save and restore error state
1388 buffers_present = len(lenv.buffer_entries) > 0
1390 code.globalstate.use_utility_code(restore_exception_utility_code)
1391 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1392 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1393 for entry in lenv.buffer_entries:
1394 Buffer.put_release_buffer_code(code, entry)
1395 #code.putln("%s = 0;" % entry.cname)
1396 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1398 err_val = self.error_value()
1399 exc_check = self.caller_will_check_exceptions()
1400 if err_val is not None or exc_check:
1401 # TODO: Fix exception tracing (though currently unused by cProfile).
1402 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1403 # code.put_trace_exception()
1404 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1406 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1407 % self.entry.qualified_name, 0)
1409 '__Pyx_WriteUnraisable("%s");' %
1410 self.entry.qualified_name)
1411 env.use_utility_code(unraisable_exception_utility_code)
1412 env.use_utility_code(restore_exception_utility_code)
1413 default_retval = self.return_type.default_value
1414 if err_val is None and default_retval:
1415 err_val = default_retval
1416 if err_val is not None:
1417 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1419 if is_getbuffer_slot:
1420 self.getbuffer_error_cleanup(code)
1422 # If we are using the non-error cleanup section we should
1423 # jump past it if we have an error. The if-test below determine
1424 # whether this section is used.
1425 if buffers_present or is_getbuffer_slot:
1426 code.put_goto(code.return_from_error_cleanup_label)
1429 # ----- Non-error return cleanup
1430 code.put_label(code.return_label)
1431 for entry in lenv.buffer_entries:
1433 Buffer.put_release_buffer_code(code, entry)
1434 if is_getbuffer_slot:
1435 self.getbuffer_normal_cleanup(code)
1436 # ----- Return cleanup for both error and no-error return
1437 code.put_label(code.return_from_error_cleanup_label)
1438 if not Options.init_local_none:
1439 for entry in lenv.var_entries:
1440 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1441 entry.xdecref_cleanup = 1
1443 for entry in lenv.var_entries:
1444 if entry.type.is_pyobject:
1445 if entry.used and not entry.in_closure:
1446 code.put_var_decref(entry)
1447 elif entry.in_closure and self.needs_closure:
1448 code.put_giveref(entry.cname)
1449 # Decref any increfed args
1450 for entry in lenv.arg_entries:
1451 if entry.type.is_pyobject:
1452 if entry.in_closure:
1453 code.put_var_giveref(entry)
1454 elif entry.assignments:
1455 code.put_var_decref(entry)
1456 if self.needs_closure:
1457 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1460 # This code is duplicated in ModuleNode.generate_module_init_func
1462 default_retval = self.return_type.default_value
1463 err_val = self.error_value()
1464 if err_val is None and default_retval:
1465 err_val = default_retval
1466 if self.return_type.is_pyobject:
1467 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1469 if self.entry.is_special and self.entry.name == "__hash__":
1470 # Returning -1 for __hash__ is supposed to signal an error
1471 # We do as Python instances and coerce -1 into -2.
1472 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1473 Naming.retval_cname, Naming.retval_cname))
1476 if self.return_type.is_pyobject:
1477 code.put_trace_return(Naming.retval_cname)
1479 code.put_trace_return("Py_None")
1481 code.put_finish_refcount_context()
1484 code.putln("#ifdef WITH_THREAD")
1485 code.putln("PyGILState_Release(_save);")
1486 code.putln("#endif")
1488 if not self.return_type.is_void:
1489 code.putln("return %s;" % Naming.retval_cname)
1493 if preprocessor_guard:
1494 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1496 # ----- Go back and insert temp variable declarations
1497 tempvardecl_code.put_temp_declarations(code.funcstate)
1498 # ----- Python version
1499 code.exit_cfunc_scope()
1501 self.py_func.generate_function_definitions(env, code)
1502 self.generate_wrapper_functions(code)
1504 def declare_argument(self, env, arg):
1505 if arg.type.is_void:
1506 error(arg.pos, "Invalid use of 'void'")
1507 elif not arg.type.is_complete() and not arg.type.is_array:
1509 "Argument type '%s' is incomplete" % arg.type)
1510 return env.declare_arg(arg.name, arg.type, arg.pos)
1512 def generate_arg_type_test(self, arg, code):
1513 # Generate type test for one argument.
1514 if arg.type.typeobj_is_available():
1515 code.globalstate.use_utility_code(arg_type_test_utility_code)
1516 typeptr_cname = arg.type.typeptr_cname
1517 arg_code = "((PyObject *)%s)" % arg.entry.cname
1519 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1524 arg.type.is_builtin_type,
1525 code.error_goto(arg.pos)))
1527 error(arg.pos, "Cannot test type of extern C class "
1528 "without type object name specification")
1530 def generate_arg_none_check(self, arg, code):
1531 # Generate None check for one argument.
1532 code.globalstate.use_utility_code(arg_type_test_utility_code)
1533 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1534 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1536 code.error_goto(arg.pos)))
1539 def generate_wrapper_functions(self, code):
1542 def generate_execution_code(self, code):
1543 # Evaluate and store argument default values
1544 for arg in self.args:
1545 default = arg.default
1547 if not default.is_literal:
1548 default.generate_evaluation_code(code)
1549 default.make_owned_reference(code)
1550 result = default.result_as(arg.type)
1553 arg.calculate_default_value_code(code),
1555 if arg.type.is_pyobject:
1556 code.put_giveref(default.result())
1557 default.generate_post_assignment_code(code)
1558 default.free_temps(code)
1559 # For Python class methods, create and store function object
1561 self.assmt.generate_execution_code(code)
1564 # Special code for the __getbuffer__ function
1566 def getbuffer_init(self, code):
1567 info = self.local_scope.arg_entries[1].cname
1568 # Python 3.0 betas have a bug in memoryview which makes it call
1569 # getbuffer with a NULL parameter. For now we work around this;
1570 # the following line should be removed when this bug is fixed.
1571 code.putln("if (%s == NULL) return 0;" % info)
1572 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1573 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1575 def getbuffer_error_cleanup(self, code):
1576 info = self.local_scope.arg_entries[1].cname
1577 code.put_gotref("%s->obj" % info)
1578 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1581 def getbuffer_normal_cleanup(self, code):
1582 info = self.local_scope.arg_entries[1].cname
1583 code.putln("if (%s->obj == Py_None) {" % info)
1584 code.put_gotref("Py_None")
1585 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1588 class CFuncDefNode(FuncDefNode):
1589 # C function definition.
1591 # modifiers ['inline']
1592 # visibility 'private' or 'public' or 'extern'
1593 # base_type CBaseTypeNode
1594 # declarator CDeclaratorNode
1597 # decorators [DecoratorNode] list of decorators
1599 # with_gil boolean Acquire GIL around body
1601 # py_func wrapper for calling from Python
1602 # overridable whether or not this is a cpdef function
1603 # inline_in_pxd whether this is an inline function in a pxd file
1605 child_attrs = ["base_type", "declarator", "body", "py_func"]
1607 inline_in_pxd = False
1609 directive_locals = {}
1611 def unqualified_name(self):
1612 return self.entry.name
1614 def analyse_declarations(self, env):
1615 self.directive_locals.update(env.directives['locals'])
1616 base_type = self.base_type.analyse(env)
1617 # The 2 here is because we need both function and argument names.
1618 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1619 if not type.is_cfunction:
1621 "Suite attached to non-function declaration")
1622 # Remember the actual type according to the function header
1623 # written here, because the type in the symbol table entry
1624 # may be different if we're overriding a C method inherited
1625 # from the base type of an extension type.
1627 type.is_overridable = self.overridable
1628 declarator = self.declarator
1629 while not hasattr(declarator, 'args'):
1630 declarator = declarator.base
1631 self.args = declarator.args
1632 for formal_arg, type_arg in zip(self.args, type.args):
1633 formal_arg.type = type_arg.type
1634 formal_arg.name = type_arg.name
1635 formal_arg.cname = type_arg.cname
1636 name = name_declarator.name
1637 cname = name_declarator.cname
1638 self.entry = env.declare_cfunction(
1639 name, type, self.pos,
1640 cname = cname, visibility = self.visibility,
1641 defining = self.body is not None,
1642 api = self.api, modifiers = self.modifiers)
1643 self.entry.inline_func_in_pxd = self.inline_in_pxd
1644 self.return_type = type.return_type
1646 if self.overridable and not env.is_module_scope:
1647 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1648 # An error will be produced in the cdef function
1649 self.overridable = False
1651 if self.overridable:
1653 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1654 self.py_func = DefNode(pos = self.pos,
1655 name = self.entry.name,
1658 starstar_arg = None,
1660 body = py_func_body,
1662 self.py_func.is_module_scope = env.is_module_scope
1663 self.py_func.analyse_declarations(env)
1664 self.entry.as_variable = self.py_func.entry
1665 # Reset scope entry the above cfunction
1666 env.entries[name] = self.entry
1667 if not env.is_module_scope or Options.lookup_module_cpdef:
1668 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1669 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1670 self.create_local_scope(env)
1672 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1674 args = self.type.args
1675 if omit_optional_args:
1676 args = args[:len(args) - self.type.optional_arg_count]
1677 arg_names = [arg.name for arg in args]
1679 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1681 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1682 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1683 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1684 c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1685 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1687 def declare_arguments(self, env):
1688 for arg in self.type.args:
1690 error(arg.pos, "Missing argument name")
1691 self.declare_argument(env, arg)
1693 def need_gil_acquisition(self, lenv):
1694 return self.type.with_gil
1696 def nogil_check(self, env):
1698 with_gil = type.with_gil
1699 if type.nogil and not with_gil:
1700 if type.return_type.is_pyobject:
1702 "Function with Python return type cannot be declared nogil")
1703 for entry in self.local_scope.var_entries:
1704 if entry.type.is_pyobject:
1705 error(self.pos, "Function declared nogil has Python locals or temporaries")
1707 def analyse_expressions(self, env):
1708 self.local_scope.directives = env.directives
1709 if self.py_func is not None:
1710 # this will also analyse the default values
1711 self.py_func.analyse_expressions(env)
1713 self.analyse_default_values(env)
1714 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1716 def needs_assignment_synthesis(self, env, code=None):
1719 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1722 visibility = self.entry.visibility
1723 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1724 arg_decls.append(arg.declaration_code())
1725 if with_dispatch and self.overridable:
1726 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1727 if type.optional_arg_count and with_opt_args:
1728 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1729 if type.has_varargs:
1730 arg_decls.append("...")
1732 arg_decls = ["void"]
1734 cname = self.entry.func_cname
1735 entity = type.function_header_code(cname, ', '.join(arg_decls))
1736 if visibility == 'public':
1737 dll_linkage = "DL_EXPORT"
1740 header = self.return_type.declaration_code(entity,
1741 dll_linkage = dll_linkage)
1742 if visibility == 'extern':
1743 storage_class = "%s " % Naming.extern_c_macro
1744 elif visibility == 'public':
1747 storage_class = "static "
1748 if 'inline' in self.modifiers:
1749 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1750 code.putln("%s%s %s {" % (
1752 ' '.join(self.modifiers).upper(), # macro forms
1755 def generate_argument_declarations(self, env, code):
1756 for arg in self.args:
1758 result = arg.calculate_default_value_code(code)
1759 code.putln('%s = %s;' % (
1760 arg.type.declaration_code(arg.cname), result))
1762 def generate_keyword_list(self, code):
1765 def generate_argument_parsing_code(self, env, code):
1767 if self.type.optional_arg_count:
1768 code.putln('if (%s) {' % Naming.optional_args_cname)
1769 for arg in self.args:
1771 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1772 declarator = arg.declarator
1773 while not hasattr(declarator, 'name'):
1774 declarator = declarator.base
1775 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1777 for _ in range(self.type.optional_arg_count):
1781 def generate_argument_conversion_code(self, code):
1784 def generate_argument_type_tests(self, code):
1785 # Generate type tests for args whose type in a parent
1786 # class is a supertype of the declared type.
1787 for arg in self.type.args:
1788 if arg.needs_type_test:
1789 self.generate_arg_type_test(arg, code)
1790 elif arg.type.is_pyobject and not arg.accept_none:
1791 self.generate_arg_none_check(arg, code)
1793 def error_value(self):
1794 if self.return_type.is_pyobject:
1798 return self.entry.type.exception_value
1800 def caller_will_check_exceptions(self):
1801 return self.entry.type.exception_check
1803 def generate_wrapper_functions(self, code):
1804 # If the C signature of a function has changed, we need to generate
1805 # wrappers to put in the slots here.
1808 func_type = entry.type
1809 while entry.prev_entry is not None:
1811 entry = entry.prev_entry
1812 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1814 self.generate_function_header(code,
1816 with_dispatch = entry.type.is_overridable,
1817 with_opt_args = entry.type.optional_arg_count,
1818 cname = entry.func_cname)
1819 if not self.return_type.is_void:
1821 args = self.type.args
1822 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1823 if entry.type.is_overridable:
1824 arglist.append(Naming.skip_dispatch_cname)
1825 elif func_type.is_overridable:
1827 if entry.type.optional_arg_count:
1828 arglist.append(Naming.optional_args_cname)
1829 elif func_type.optional_arg_count:
1830 arglist.append('NULL')
1831 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1835 class PyArgDeclNode(Node):
1836 # Argument which must be a Python object (used
1837 # for * and ** arguments).
1840 # entry Symtab.Entry
1841 # annotation ExprNode or None Py3 argument annotation
1844 def generate_function_definitions(self, env, code):
1845 self.entry.generate_function_definitions(env, code)
1847 class DecoratorNode(Node):
1850 # decorator NameNode or CallNode or AttributeNode
1851 child_attrs = ['decorator']
1854 class DefNode(FuncDefNode):
1855 # A Python function definition.
1857 # name string the Python name of the function
1858 # lambda_name string the internal name of a lambda 'function'
1859 # decorators [DecoratorNode] list of decorators
1860 # args [CArgDeclNode] formal arguments
1861 # star_arg PyArgDeclNode or None * argument
1862 # starstar_arg PyArgDeclNode or None ** argument
1863 # doc EncodedString or None
1865 # return_type_annotation
1866 # ExprNode or None the Py3 return type annotation
1868 # The following subnode is constructed internally
1869 # when the def statement is inside a Python class definition.
1871 # assmt AssignmentNode Function construction/assignment
1873 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1878 num_required_kw_args = 0
1879 reqd_kw_flags_cname = "0"
1882 return_type_annotation = None
1887 def __init__(self, pos, **kwds):
1888 FuncDefNode.__init__(self, pos, **kwds)
1890 for arg in self.args:
1897 self.num_kwonly_args = k
1898 self.num_required_kw_args = rk
1899 self.num_required_args = r
1901 def as_cfunction(self, cfunc=None, scope=None):
1903 error(self.star_arg.pos, "cdef function cannot have star argument")
1904 if self.starstar_arg:
1905 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1908 for formal_arg in self.args:
1909 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1910 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1912 type = py_object_type,
1913 pos = formal_arg.pos))
1914 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1916 has_varargs = False,
1917 exception_value = None,
1918 exception_check = False,
1921 is_overridable = True)
1922 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1926 cfunc_type = cfunc.type
1927 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1928 error(self.pos, "wrong number of arguments")
1929 error(cfunc.pos, "previous declaration here")
1930 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1931 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1932 is_self_arg = (i == 0 and scope.is_c_class_scope))
1933 if type is None or type is PyrexTypes.py_object_type:
1934 formal_arg.type = type_arg.type
1935 formal_arg.name_declarator = name_declarator
1937 if cfunc_type.exception_value is None:
1938 exception_value = None
1940 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1941 declarator = CFuncDeclaratorNode(self.pos,
1942 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1944 has_varargs = False,
1945 exception_check = cfunc_type.exception_check,
1946 exception_value = exception_value,
1947 with_gil = cfunc_type.with_gil,
1948 nogil = cfunc_type.nogil)
1949 return CFuncDefNode(self.pos,
1951 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1952 declarator = declarator,
1955 overridable = cfunc_type.is_overridable,
1957 with_gil = cfunc_type.with_gil,
1958 nogil = cfunc_type.nogil,
1959 visibility = 'private',
1961 directive_locals = getattr(cfunc, 'directive_locals', {}))
1963 def analyse_declarations(self, env):
1964 self.is_classmethod = self.is_staticmethod = False
1966 for decorator in self.decorators:
1967 func = decorator.decorator
1969 self.is_classmethod |= func.name == 'classmethod'
1970 self.is_staticmethod |= func.name == 'staticmethod'
1972 if self.is_classmethod and env.lookup_here('classmethod'):
1973 # classmethod() was overridden - not much we can do here ...
1974 self.is_classmethod = False
1975 if self.is_staticmethod and env.lookup_here('staticmethod'):
1976 # staticmethod() was overridden - not much we can do here ...
1977 self.is_staticmethod = False
1979 if self.name == '__new__':
1980 self.is_staticmethod = 1
1982 self.analyse_argument_types(env)
1983 if self.name == '<lambda>':
1984 self.declare_lambda_function(env)
1986 self.declare_pyfunction(env)
1987 self.analyse_signature(env)
1988 self.return_type = self.entry.signature.return_type()
1989 self.create_local_scope(env)
1991 def analyse_argument_types(self, env):
1992 directive_locals = self.directive_locals = env.directives['locals']
1993 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1994 for arg in self.args:
1995 if hasattr(arg, 'name'):
1997 name_declarator = None
1999 base_type = arg.base_type.analyse(env)
2000 name_declarator, type = \
2001 arg.declarator.analyse(base_type, env)
2002 arg.name = name_declarator.name
2003 if arg.name in directive_locals:
2004 type_node = directive_locals[arg.name]
2005 other_type = type_node.analyse_as_type(env)
2006 if other_type is None:
2007 error(type_node.pos, "Not a type")
2008 elif (type is not PyrexTypes.py_object_type
2009 and not type.same_as(other_type)):
2010 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2011 error(type_node.pos, "Previous declaration here")
2014 if name_declarator and name_declarator.cname:
2016 "Python function argument cannot have C name specification")
2017 arg.type = type.as_argument_type()
2019 arg.needs_conversion = 0
2020 arg.needs_type_test = 0
2022 if arg.type.is_pyobject:
2024 arg.accept_none = True
2026 arg.accept_none = False
2027 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2028 if arg.default and arg.default.constant_result is None:
2029 # special case: def func(MyType obj = None)
2030 arg.accept_none = True
2032 # default depends on compiler directive
2033 arg.accept_none = allow_none_for_extension_args
2035 # probably just a plain 'object'
2036 arg.accept_none = True
2038 arg.accept_none = True # won't be used, but must be there
2040 error(arg.pos, "Only Python type arguments can have 'not None'")
2042 error(arg.pos, "Only Python type arguments can have 'or None'")
2044 def analyse_signature(self, env):
2045 if self.entry.is_special:
2046 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2047 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2048 # Use the simpler calling signature for zero- and one-argument functions.
2049 if self.entry.signature is TypeSlots.pyfunction_signature:
2050 if len(self.args) == 0:
2051 self.entry.signature = TypeSlots.pyfunction_noargs
2052 elif len(self.args) == 1:
2053 if self.args[0].default is None and not self.args[0].kw_only:
2054 self.entry.signature = TypeSlots.pyfunction_onearg
2055 elif self.entry.signature is TypeSlots.pymethod_signature:
2056 if len(self.args) == 1:
2057 self.entry.signature = TypeSlots.unaryfunc
2058 elif len(self.args) == 2:
2059 if self.args[1].default is None and not self.args[1].kw_only:
2060 self.entry.signature = TypeSlots.ibinaryfunc
2062 sig = self.entry.signature
2063 nfixed = sig.num_fixed_args()
2064 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2065 and len(self.args) == 0 and self.star_arg:
2066 # this is the only case where a diverging number of
2067 # arguments is not an error - when we have no explicit
2068 # 'self' parameter as in method(*args)
2069 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2070 self.self_in_stararg = 1
2073 for i in range(min(nfixed, len(self.args))):
2076 if sig.is_self_arg(i) and not self.is_staticmethod:
2077 if self.is_classmethod:
2079 arg.hdr_type = arg.type = Builtin.type_type
2082 arg.hdr_type = arg.type = env.parent_type
2083 arg.needs_conversion = 0
2085 arg.hdr_type = sig.fixed_arg_type(i)
2086 if not arg.type.same_as(arg.hdr_type):
2087 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2088 arg.needs_type_test = 1
2090 arg.needs_conversion = 1
2091 if arg.needs_conversion:
2092 arg.hdr_cname = Naming.arg_prefix + arg.name
2094 arg.hdr_cname = Naming.var_prefix + arg.name
2096 if nfixed > len(self.args):
2097 self.bad_signature()
2099 elif nfixed < len(self.args):
2100 if not sig.has_generic_args:
2101 self.bad_signature()
2102 for arg in self.args:
2103 if arg.is_generic and \
2104 (arg.type.is_extension_type or arg.type.is_builtin_type):
2105 arg.needs_type_test = 1
2107 def bad_signature(self):
2108 sig = self.entry.signature
2109 expected_str = "%d" % sig.num_fixed_args()
2110 if sig.has_generic_args:
2111 expected_str = expected_str + " or more"
2113 if name.startswith("__") and name.endswith("__"):
2114 desc = "Special method"
2118 "%s %s has wrong number of arguments "
2119 "(%d declared, %s expected)" % (
2120 desc, self.name, len(self.args), expected_str))
2122 def signature_has_nongeneric_args(self):
2123 argcount = len(self.args)
2124 if argcount == 0 or (
2125 argcount == 1 and (self.args[0].is_self_arg or
2126 self.args[0].is_type_arg)):
2130 def signature_has_generic_args(self):
2131 return self.entry.signature.has_generic_args
2133 def declare_pyfunction(self, env):
2134 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2136 entry = env.lookup_here(name)
2137 if entry and entry.type.is_cfunction and not self.is_wrapper:
2138 warning(self.pos, "Overriding cdef method with def method.", 5)
2139 entry = env.declare_pyfunction(name, self.pos)
2141 prefix = env.scope_prefix
2142 entry.func_cname = \
2143 Naming.pyfunc_prefix + prefix + name
2144 entry.pymethdef_cname = \
2145 Naming.pymethdef_prefix + prefix + name
2146 if Options.docstrings:
2147 entry.doc = embed_position(self.pos, self.doc)
2149 Naming.funcdoc_prefix + prefix + name
2150 if entry.is_special:
2151 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2152 entry.wrapperbase_cname = None
2154 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2158 def declare_lambda_function(self, env):
2160 prefix = env.scope_prefix
2162 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2163 entry = env.declare_lambda_function(func_cname, self.pos)
2164 entry.pymethdef_cname = \
2165 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2166 entry.qualified_name = env.qualify_name(self.lambda_name)
2170 def declare_arguments(self, env):
2171 for arg in self.args:
2173 error(arg.pos, "Missing argument name")
2175 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2176 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2177 if arg.needs_conversion:
2178 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2179 if arg.type.is_pyobject:
2180 arg.entry.init = "0"
2181 arg.entry.init_to_none = 0
2183 arg.entry = self.declare_argument(env, arg)
2185 arg.entry.is_self_arg = arg.is_self_arg
2187 if arg.is_self_arg or arg.is_type_arg or \
2188 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2189 arg.entry.is_declared_generic = 1
2190 self.declare_python_arg(env, self.star_arg)
2191 self.declare_python_arg(env, self.starstar_arg)
2193 def declare_python_arg(self, env, arg):
2195 if env.directives['infer_types'] != False:
2196 type = PyrexTypes.unspecified_type
2198 type = py_object_type
2199 entry = env.declare_var(arg.name, type, arg.pos)
2202 entry.init_to_none = 0
2203 entry.xdecref_cleanup = 1
2205 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2207 def analyse_expressions(self, env):
2208 self.local_scope.directives = env.directives
2209 self.analyse_default_values(env)
2210 if self.needs_assignment_synthesis(env):
2211 # Shouldn't we be doing this at the module level too?
2212 self.synthesize_assignment_node(env)
2214 def needs_assignment_synthesis(self, env, code=None):
2215 # Should enable for module level as well, that will require more testing...
2216 if env.is_module_scope:
2218 return env.directives['binding']
2220 return code.globalstate.directives['binding']
2221 return env.is_py_class_scope or env.is_closure_scope
2223 def synthesize_assignment_node(self, env):
2226 while genv.is_py_class_scope or genv.is_c_class_scope:
2227 genv = genv.outer_scope
2229 if genv.is_closure_scope:
2230 rhs = ExprNodes.InnerFunctionNode(
2231 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2233 rhs = ExprNodes.PyCFunctionNode(
2234 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2236 if env.is_py_class_scope:
2237 if not self.is_staticmethod and not self.is_classmethod:
2240 self.assmt = SingleAssignmentNode(self.pos,
2241 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2243 self.assmt.analyse_declarations(env)
2244 self.assmt.analyse_expressions(env)
2246 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2248 sig = self.entry.signature
2249 if sig.has_dummy_arg or self.self_in_stararg:
2250 arg_code_list.append(
2251 "PyObject *%s" % Naming.self_cname)
2252 for arg in self.args:
2253 if not arg.is_generic:
2254 if arg.is_self_arg or arg.is_type_arg:
2255 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2257 arg_code_list.append(
2258 arg.hdr_type.declaration_code(arg.hdr_cname))
2259 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2260 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2261 if sig.has_generic_args:
2262 arg_code_list.append(
2263 "PyObject *%s, PyObject *%s"
2264 % (Naming.args_cname, Naming.kwds_cname))
2265 arg_code = ", ".join(arg_code_list)
2266 dc = self.return_type.declaration_code(self.entry.func_cname)
2267 mf = " ".join(self.modifiers).upper()
2269 header = "static %s%s(%s)" % (mf, dc, arg_code)
2270 code.putln("%s; /*proto*/" % header)
2273 if (Options.docstrings and self.entry.doc and
2274 not self.entry.scope.is_property_scope and
2275 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2276 docstr = self.entry.doc
2277 if docstr.is_unicode:
2278 docstr = docstr.utf8encode()
2280 'static char %s[] = "%s";' % (
2281 self.entry.doc_cname,
2282 split_string_literal(escape_byte_string(docstr))))
2283 if self.entry.is_special:
2285 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2288 "static PyMethodDef %s = " %
2289 self.entry.pymethdef_cname)
2290 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2291 code.putln("%s {" % header)
2293 def generate_argument_declarations(self, env, code):
2294 for arg in self.args:
2295 if arg.is_generic: # or arg.needs_conversion:
2296 if arg.needs_conversion:
2297 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2298 elif not arg.entry.in_closure:
2299 code.put_var_declaration(arg.entry)
2301 def generate_keyword_list(self, code):
2302 if self.signature_has_generic_args() and \
2303 self.signature_has_nongeneric_args():
2305 "static PyObject **%s[] = {" %
2306 Naming.pykwdlist_cname)
2307 for arg in self.args:
2309 pystring_cname = code.intern_identifier(arg.name)
2310 code.put('&%s,' % pystring_cname)
2313 def generate_argument_parsing_code(self, env, code):
2314 # Generate PyArg_ParseTuple call for generic
2315 # arguments, if any.
2316 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2317 # get rid of unused argument warning
2318 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2320 old_error_label = code.new_error_label()
2321 our_error_label = code.error_label
2322 end_label = code.new_label("argument_unpacking_done")
2324 has_kwonly_args = self.num_kwonly_args > 0
2325 has_star_or_kw_args = self.star_arg is not None \
2326 or self.starstar_arg is not None or has_kwonly_args
2328 for arg in self.args:
2329 if not arg.type.is_pyobject:
2330 done = arg.type.create_from_py_utility_code(env)
2331 if not done: pass # will fail later
2333 if not self.signature_has_generic_args():
2334 if has_star_or_kw_args:
2335 error(self.pos, "This method cannot have * or keyword arguments")
2336 self.generate_argument_conversion_code(code)
2338 elif not self.signature_has_nongeneric_args():
2339 # func(*args) or func(**kw) or func(*args, **kw)
2340 self.generate_stararg_copy_code(code)
2343 positional_args = []
2345 for arg in self.args:
2346 arg_entry = arg.entry
2349 if not arg.is_self_arg and not arg.is_type_arg:
2351 kw_only_args.append(arg)
2353 positional_args.append(arg)
2355 kw_only_args.append(arg)
2356 elif not arg.is_self_arg and not arg.is_type_arg:
2357 positional_args.append(arg)
2359 self.generate_tuple_and_keyword_parsing_code(
2360 positional_args, kw_only_args, end_label, code)
2362 code.error_label = old_error_label
2363 if code.label_used(our_error_label):
2364 if not code.label_used(end_label):
2365 code.put_goto(end_label)
2366 code.put_label(our_error_label)
2367 if has_star_or_kw_args:
2368 self.generate_arg_decref(self.star_arg, code)
2369 if self.starstar_arg:
2370 if self.starstar_arg.entry.xdecref_cleanup:
2371 code.put_var_xdecref(self.starstar_arg.entry)
2373 code.put_var_decref(self.starstar_arg.entry)
2374 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2375 # The arguments are put into the closure one after the
2376 # other, so when type errors are found, all references in
2377 # the closure instance must be properly ref-counted to
2378 # facilitate generic closure instance deallocation. In
2379 # the case of an argument type error, it's best to just
2380 # DECREF+clear the already handled references, as this
2381 # frees their references as early as possible.
2382 for arg in self.args:
2383 if arg.type.is_pyobject and arg.entry.in_closure:
2384 code.put_var_xdecref_clear(arg.entry)
2385 if self.needs_closure:
2386 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2387 code.put_finish_refcount_context()
2388 code.putln("return %s;" % self.error_value())
2389 if code.label_used(end_label):
2390 code.put_label(end_label)
2392 def generate_arg_assignment(self, arg, item, code):
2393 if arg.type.is_pyobject:
2395 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2397 code.putln("%s = %s;" % (entry.cname, item))
2398 if entry.in_closure:
2399 code.put_var_incref(entry)
2401 func = arg.type.from_py_function
2403 code.putln("%s = %s(%s); %s" % (
2407 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2409 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2411 def generate_arg_xdecref(self, arg, code):
2413 code.put_var_xdecref(arg.entry)
2415 def generate_arg_decref(self, arg, code):
2417 code.put_var_decref(arg.entry)
2419 def generate_stararg_copy_code(self, code):
2420 if not self.star_arg:
2421 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2422 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2424 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2425 self.name, Naming.args_cname, self.error_value()))
2428 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2430 if self.starstar_arg:
2432 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2434 kwarg_check = "%s" % Naming.kwds_cname
2436 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2437 Naming.kwds_cname, Naming.kwds_cname)
2439 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2440 kwarg_check, Naming.kwds_cname, self.name,
2441 bool(self.starstar_arg), self.error_value()))
2443 if self.starstar_arg:
2444 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2445 self.starstar_arg.entry.cname,
2448 code.putln("if (unlikely(!%s)) return %s;" % (
2449 self.starstar_arg.entry.cname, self.error_value()))
2450 self.starstar_arg.entry.xdecref_cleanup = 0
2451 code.put_gotref(self.starstar_arg.entry.cname)
2453 if self.self_in_stararg:
2454 # need to create a new tuple with 'self' inserted as first item
2455 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2456 self.star_arg.entry.cname,
2458 self.star_arg.entry.cname))
2459 if self.starstar_arg:
2461 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2462 code.putln("return %s;" % self.error_value())
2465 code.putln("return %s;" % self.error_value())
2466 code.put_gotref(self.star_arg.entry.cname)
2467 code.put_incref(Naming.self_cname, py_object_type)
2468 code.put_giveref(Naming.self_cname)
2469 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2470 self.star_arg.entry.cname, Naming.self_cname))
2471 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2472 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2473 temp, temp, Naming.args_cname, temp))
2474 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2475 Naming.args_cname, temp))
2476 code.put_incref("item", py_object_type)
2477 code.put_giveref("item")
2478 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2479 self.star_arg.entry.cname, temp))
2481 code.funcstate.release_temp(temp)
2482 self.star_arg.entry.xdecref_cleanup = 0
2484 code.put_incref(Naming.args_cname, py_object_type)
2485 code.putln("%s = %s;" % (
2486 self.star_arg.entry.cname,
2488 self.star_arg.entry.xdecref_cleanup = 0
2490 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2491 kw_only_args, success_label, code):
2492 argtuple_error_label = code.new_label("argtuple_error")
2494 min_positional_args = self.num_required_args - self.num_required_kw_args
2495 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2496 min_positional_args -= 1
2497 max_positional_args = len(positional_args)
2498 has_fixed_positional_count = not self.star_arg and \
2499 min_positional_args == max_positional_args
2501 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2502 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2503 if self.num_required_kw_args:
2504 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2506 if self.starstar_arg or self.star_arg:
2507 self.generate_stararg_init_code(max_positional_args, code)
2509 # --- optimised code when we receive keyword arguments
2510 if self.num_required_kw_args:
2511 likely_hint = "likely"
2513 likely_hint = "unlikely"
2514 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2515 self.generate_keyword_unpacking_code(
2516 min_positional_args, max_positional_args,
2517 has_fixed_positional_count,
2518 positional_args, kw_only_args, argtuple_error_label, code)
2520 # --- optimised code when we do not receive any keyword arguments
2521 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2522 # Python raises arg tuple related errors first, so we must
2523 # check the length here
2524 if min_positional_args == max_positional_args and not self.star_arg:
2528 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2529 Naming.args_cname, compare, min_positional_args))
2530 code.put_goto(argtuple_error_label)
2532 if self.num_required_kw_args:
2533 # pure error case: keywords required but not passed
2534 if max_positional_args > min_positional_args and not self.star_arg:
2535 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2536 Naming.args_cname, max_positional_args))
2537 code.put_goto(argtuple_error_label)
2538 code.putln('} else {')
2539 for i, arg in enumerate(kw_only_args):
2541 pystring_cname = code.intern_identifier(arg.name)
2542 # required keyword-only argument missing
2543 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2546 code.putln(code.error_goto(self.pos))
2549 elif min_positional_args == max_positional_args:
2550 # parse the exact number of positional arguments from the
2552 code.putln('} else {')
2553 for i, arg in enumerate(positional_args):
2554 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2555 self.generate_arg_assignment(arg, item, code)
2556 self.generate_arg_default_assignments(code)
2559 # parse the positional arguments from the variable length
2561 code.putln('} else {')
2562 self.generate_arg_default_assignments(code)
2563 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2565 code.putln('default:')
2566 reversed_args = list(enumerate(positional_args))[::-1]
2567 for i, arg in reversed_args:
2568 if i >= min_positional_args-1:
2569 if min_positional_args > 1:
2570 code.putln('case %2d:' % (i+1)) # pure code beautification
2572 code.put('case %2d: ' % (i+1))
2573 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2574 self.generate_arg_assignment(arg, item, code)
2575 if min_positional_args == 0:
2576 code.put('case 0: ')
2577 code.putln('break;')
2579 if min_positional_args:
2580 for i in range(min_positional_args-1, -1, -1):
2581 code.putln('case %2d:' % i)
2582 code.put_goto(argtuple_error_label)
2584 code.put('default: ')
2585 code.put_goto(argtuple_error_label)
2590 if code.label_used(argtuple_error_label):
2591 code.put_goto(success_label)
2592 code.put_label(argtuple_error_label)
2593 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2594 self.name, has_fixed_positional_count,
2595 min_positional_args, max_positional_args,
2597 code.putln(code.error_goto(self.pos))
2599 def generate_arg_default_assignments(self, code):
2600 for arg in self.args:
2601 if arg.is_generic and arg.default:
2605 arg.calculate_default_value_code(code)))
2607 def generate_stararg_init_code(self, max_positional_args, code):
2608 if self.starstar_arg:
2609 self.starstar_arg.entry.xdecref_cleanup = 0
2610 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2611 self.starstar_arg.entry.cname,
2612 self.starstar_arg.entry.cname,
2613 self.error_value()))
2614 code.put_gotref(self.starstar_arg.entry.cname)
2616 self.star_arg.entry.xdecref_cleanup = 0
2617 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2619 max_positional_args))
2620 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2621 self.star_arg.entry.cname, Naming.args_cname,
2622 max_positional_args, Naming.args_cname))
2623 code.put_gotref(self.star_arg.entry.cname)
2624 if self.starstar_arg:
2626 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2627 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2628 code.putln('return %s;' % self.error_value())
2631 code.putln("if (unlikely(!%s)) return %s;" % (
2632 self.star_arg.entry.cname, self.error_value()))
2633 code.putln('} else {')
2634 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2635 code.put_incref(Naming.empty_tuple, py_object_type)
2638 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2639 has_fixed_positional_count, positional_args,
2640 kw_only_args, argtuple_error_label, code):
2641 all_args = tuple(positional_args) + tuple(kw_only_args)
2642 max_args = len(all_args)
2644 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2646 # the 'values' array collects borrowed references to arguments
2647 # before doing any type coercion etc.
2648 code.putln("PyObject* values[%d] = {%s};" % (
2649 max_args, ','.join('0'*max_args)))
2651 # assign borrowed Python default values to the values array,
2652 # so that they can be overwritten by received arguments below
2653 for i, arg in enumerate(all_args):
2654 if arg.default and arg.type.is_pyobject:
2655 default_value = arg.calculate_default_value_code(code)
2656 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2658 # parse the args tuple and check that it's not too long
2659 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2661 code.putln('default:')
2662 for i in range(max_positional_args-1, -1, -1):
2663 code.put('case %2d: ' % (i+1))
2664 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2665 i, Naming.args_cname, i))
2666 code.putln('case 0: break;')
2667 if not self.star_arg:
2668 code.put('default: ') # more arguments than allowed
2669 code.put_goto(argtuple_error_label)
2672 # now fill up the positional/required arguments with values
2674 if self.num_required_args or max_positional_args > 0:
2675 last_required_arg = -1
2676 for i, arg in enumerate(all_args):
2678 last_required_arg = i
2679 if last_required_arg < max_positional_args:
2680 last_required_arg = max_positional_args-1
2681 num_required_args = self.num_required_args
2682 if max_positional_args > 0:
2683 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2684 for i, arg in enumerate(all_args[:last_required_arg+1]):
2685 if max_positional_args > 0 and i <= max_positional_args:
2686 if self.star_arg and i == max_positional_args:
2687 code.putln('default:')
2689 code.putln('case %2d:' % i)
2690 pystring_cname = code.intern_identifier(arg.name)
2693 # handled separately below
2695 code.putln('if (kw_args > 0) {')
2696 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2697 Naming.kwds_cname, pystring_cname))
2698 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2701 num_required_args -= 1
2702 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2703 i, Naming.kwds_cname, pystring_cname))
2704 code.putln('if (likely(values[%d])) kw_args--;' % i);
2705 if i < min_positional_args:
2707 # special case: we know arg 0 is missing
2709 code.put_goto(argtuple_error_label)
2711 # print the correct number of values (args or
2712 # kwargs) that were passed into positional
2713 # arguments up to this point
2714 code.putln('else {')
2715 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2716 self.name, has_fixed_positional_count,
2717 min_positional_args, max_positional_args, i))
2718 code.putln(code.error_goto(self.pos))
2721 code.putln('else {')
2722 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2723 self.name, pystring_cname))
2724 code.putln(code.error_goto(self.pos))
2726 if max_positional_args > 0:
2729 if kw_only_args and not self.starstar_arg:
2730 # unpack optional keyword-only arguments
2731 # checking for interned strings in a dict is faster than iterating
2732 # but it's too likely that we must iterate if we expect **kwargs
2734 for i, arg in enumerate(all_args[max_positional_args:]):
2735 if not arg.kw_only or not arg.default:
2737 optional_args.append((i+max_positional_args, arg))
2739 # this mimics an unrolled loop so that we can "break" out of it
2740 code.putln('while (kw_args > 0) {')
2741 code.putln('PyObject* value;')
2742 for i, arg in optional_args:
2743 pystring_cname = code.intern_identifier(arg.name)
2745 'value = PyDict_GetItem(%s, %s);' % (
2746 Naming.kwds_cname, pystring_cname))
2748 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2749 code.putln('break;')
2752 code.putln('if (unlikely(kw_args > 0)) {')
2753 # non-positional/-required kw args left in dict: default args,
2754 # kw-only args, **kwargs or error
2756 # This is sort of a catch-all: except for checking required
2757 # arguments, this will always do the right thing for unpacking
2758 # keyword arguments, so that we can concentrate on optimising
2759 # common cases above.
2760 if max_positional_args == 0:
2763 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2764 Naming.args_cname, max_positional_args,
2765 Naming.args_cname, max_positional_args))
2766 pos_arg_count = "used_pos_args"
2768 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2769 code.globalstate.use_utility_code(parse_keywords_utility_code)
2771 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2773 Naming.pykwdlist_cname,
2774 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2777 code.putln(code.error_goto(self.pos))
2780 # convert arg values to their final type and assign them
2781 for i, arg in enumerate(all_args):
2782 if arg.default and not arg.type.is_pyobject:
2783 code.putln("if (values[%d]) {" % i)
2784 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2785 if arg.default and not arg.type.is_pyobject:
2786 code.putln('} else {')
2790 arg.calculate_default_value_code(code)))
2793 def generate_argument_conversion_code(self, code):
2794 # Generate code to convert arguments from signature type to
2795 # declared type, if needed. Also copies signature arguments
2796 # into closure fields.
2797 for arg in self.args:
2798 if arg.needs_conversion:
2799 self.generate_arg_conversion(arg, code)
2800 elif arg.entry.in_closure:
2801 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2802 if arg.type.is_pyobject:
2803 code.put_var_incref(arg.entry)
2805 def generate_arg_conversion(self, arg, code):
2806 # Generate conversion code for one argument.
2807 old_type = arg.hdr_type
2809 if old_type.is_pyobject:
2811 code.putln("if (%s) {" % arg.hdr_cname)
2813 code.putln("assert(%s); {" % arg.hdr_cname)
2814 self.generate_arg_conversion_from_pyobject(arg, code)
2816 elif new_type.is_pyobject:
2817 self.generate_arg_conversion_to_pyobject(arg, code)
2819 if new_type.assignable_from(old_type):
2821 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2824 "Cannot convert 1 argument from '%s' to '%s'" %
2825 (old_type, new_type))
2827 def generate_arg_conversion_from_pyobject(self, arg, code):
2829 func = new_type.from_py_function
2830 # copied from CoerceFromPyTypeNode
2832 lhs = arg.entry.cname
2833 rhs = "%s(%s)" % (func, arg.hdr_cname)
2834 if new_type.is_enum:
2835 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2836 code.putln("%s = %s; %s" % (
2839 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2842 "Cannot convert Python object argument to type '%s'"
2845 def generate_arg_conversion_to_pyobject(self, arg, code):
2846 old_type = arg.hdr_type
2847 func = old_type.to_py_function
2849 code.putln("%s = %s(%s); %s" % (
2853 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2854 code.put_var_gotref(arg.entry)
2857 "Cannot convert argument of type '%s' to Python object"
2860 def generate_argument_type_tests(self, code):
2861 # Generate type tests for args whose signature
2862 # type is PyObject * and whose declared type is
2863 # a subtype thereof.
2864 for arg in self.args:
2865 if arg.needs_type_test:
2866 self.generate_arg_type_test(arg, code)
2867 elif not arg.accept_none and arg.type.is_pyobject:
2868 self.generate_arg_none_check(arg, code)
2870 def error_value(self):
2871 return self.entry.signature.error_value
2873 def caller_will_check_exceptions(self):
2876 class OverrideCheckNode(StatNode):
2877 # A Node for dispatching to the def method if it
2886 child_attrs = ['body']
2890 def analyse_expressions(self, env):
2891 self.args = env.arg_entries
2892 if self.py_func.is_module_scope:
2897 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2898 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2899 call_node = ExprNodes.SimpleCallNode(self.pos,
2900 function=self.func_node,
2901 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2902 self.body = ReturnStatNode(self.pos, value=call_node)
2903 self.body.analyse_expressions(env)
2905 def generate_execution_code(self, code):
2906 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2907 # Check to see if we are an extension type
2908 if self.py_func.is_module_scope:
2909 self_arg = "((PyObject *)%s)" % Naming.module_cname
2911 self_arg = "((PyObject *)%s)" % self.args[0].cname
2912 code.putln("/* Check if called by wrapper */")
2913 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2914 code.putln("/* Check if overriden in Python */")
2915 if self.py_func.is_module_scope:
2916 code.putln("else {")
2918 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2919 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2920 self.func_node.set_cname(func_node_temp)
2921 # need to get attribute manually--scope would return cdef method
2922 err = code.error_goto_if_null(func_node_temp, self.pos)
2923 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2924 func_node_temp, self_arg, interned_attr_cname, err))
2925 code.put_gotref(func_node_temp)
2926 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2927 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2928 func_node_temp, self.py_func.entry.func_cname)
2929 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2930 self.body.generate_execution_code(code)
2932 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2933 code.funcstate.release_temp(func_node_temp)
2936 class ClassDefNode(StatNode, BlockNode):
2939 class PyClassDefNode(ClassDefNode):
2940 # A Python class definition.
2942 # name EncodedString Name of the class
2943 # doc string or None
2944 # body StatNode Attribute definition code
2945 # entry Symtab.Entry
2946 # scope PyClassScope
2947 # decorators [DecoratorNode] list of decorators or None
2949 # The following subnodes are constructed internally:
2951 # dict DictNode Class dictionary or Py3 namespace
2952 # classobj ClassNode Class object
2953 # target NameNode Variable to assign class object to
2955 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2957 py3_style_class = False # Python3 style class (bases+kwargs)
2959 def __init__(self, pos, name, bases, doc, body, decorators = None,
2960 keyword_args = None, starstar_arg = None):
2961 StatNode.__init__(self, pos)
2965 self.decorators = decorators
2967 if self.doc and Options.docstrings:
2968 doc = embed_position(self.pos, self.doc)
2969 doc_node = ExprNodes.StringNode(pos, value = doc)
2972 if keyword_args or starstar_arg:
2973 self.py3_style_class = True
2975 self.metaclass = None
2976 if keyword_args and not starstar_arg:
2977 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
2978 if item.key.value == 'metaclass':
2979 if self.metaclass is not None:
2980 error(item.pos, "keyword argument 'metaclass' passed multiple times")
2981 # special case: we already know the metaclass,
2982 # so we don't need to do the "build kwargs,
2983 # find metaclass" dance at runtime
2984 self.metaclass = item.value
2985 del keyword_args.key_value_pairs[i]
2986 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
2987 self.mkw = ExprNodes.KeywordArgsNode(
2988 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
2990 self.mkw = ExprNodes.NullNode(pos)
2991 if self.metaclass is None:
2992 self.metaclass = ExprNodes.PyClassMetaclassNode(
2993 pos, mkw = self.mkw, bases = self.bases)
2994 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
2995 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
2997 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
2998 bases = self.bases, dict = self.dict, doc = doc_node,
2999 metaclass = self.metaclass, mkw = self.mkw)
3001 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3002 self.metaclass = None
3005 self.classobj = ExprNodes.ClassNode(pos, name = name,
3006 bases = bases, dict = self.dict, doc = doc_node)
3007 self.target = ExprNodes.NameNode(pos, name = name)
3009 def as_cclass(self):
3011 Return this node as if it were declared as an extension class
3013 if self.py3_style_class:
3014 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3016 bases = self.classobj.bases.args
3018 base_class_name = None
3019 base_class_module = None
3020 elif len(bases) == 1:
3023 from ExprNodes import AttributeNode, NameNode
3024 while isinstance(base, AttributeNode):
3025 path.insert(0, base.attribute)
3027 if isinstance(base, NameNode):
3028 path.insert(0, base.name)
3029 base_class_name = path[-1]
3031 base_class_module = u'.'.join(path[:-1])
3033 base_class_module = None
3035 error(self.classobj.bases.args.pos, "Invalid base class")
3037 error(self.classobj.bases.args.pos, "C class may only have one base class")
3040 return CClassDefNode(self.pos,
3041 visibility = 'private',
3043 class_name = self.name,
3044 base_class_module = base_class_module,
3045 base_class_name = base_class_name,
3046 decorators = self.decorators,
3051 def create_scope(self, env):
3053 while genv.is_py_class_scope or genv.is_c_class_scope:
3054 genv = genv.outer_scope
3055 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3058 def analyse_declarations(self, env):
3059 self.target.analyse_target_declaration(env)
3060 cenv = self.create_scope(env)
3061 cenv.directives = env.directives
3062 cenv.class_obj_cname = self.target.entry.cname
3063 self.body.analyse_declarations(cenv)
3065 def analyse_expressions(self, env):
3066 if self.py3_style_class:
3067 self.bases.analyse_expressions(env)
3068 self.metaclass.analyse_expressions(env)
3069 self.mkw.analyse_expressions(env)
3070 self.dict.analyse_expressions(env)
3071 self.classobj.analyse_expressions(env)
3072 genv = env.global_scope()
3074 self.body.analyse_expressions(cenv)
3075 self.target.analyse_target_expression(env, self.classobj)
3077 def generate_function_definitions(self, env, code):
3078 self.body.generate_function_definitions(self.scope, code)
3080 def generate_execution_code(self, code):
3081 code.pyclass_stack.append(self)
3083 if self.py3_style_class:
3084 self.bases.generate_evaluation_code(code)
3085 self.mkw.generate_evaluation_code(code)
3086 self.metaclass.generate_evaluation_code(code)
3087 self.dict.generate_evaluation_code(code)
3088 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3089 self.body.generate_execution_code(code)
3090 self.classobj.generate_evaluation_code(code)
3091 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3092 self.target.generate_assignment_code(self.classobj, code)
3093 self.dict.generate_disposal_code(code)
3094 self.dict.free_temps(code)
3095 if self.py3_style_class:
3096 self.mkw.generate_disposal_code(code)
3097 self.mkw.free_temps(code)
3098 self.metaclass.generate_disposal_code(code)
3099 self.metaclass.free_temps(code)
3100 self.bases.generate_disposal_code(code)
3101 self.bases.free_temps(code)
3102 code.pyclass_stack.pop()
3104 class CClassDefNode(ClassDefNode):
3105 # An extension type definition.
3107 # visibility 'private' or 'public' or 'extern'
3108 # typedef_flag boolean
3110 # module_name string or None For import of extern type objects
3111 # class_name string Unqualified name of class
3112 # as_name string or None Name to declare as in this scope
3113 # base_class_module string or None Module containing the base class
3114 # base_class_name string or None Name of the base class
3115 # objstruct_name string or None Specified C name of object struct
3116 # typeobj_name string or None Specified C name of type object
3117 # in_pxd boolean Is in a .pxd file
3118 # decorators [DecoratorNode] list of decorators or None
3119 # doc string or None
3120 # body StatNode or None
3121 # entry Symtab.Entry
3122 # base_type PyExtensionType or None
3123 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3124 # buffer_defaults_pos
3126 child_attrs = ["body"]
3127 buffer_defaults_node = None
3128 buffer_defaults_pos = None
3129 typedef_flag = False
3131 objstruct_name = None
3135 def analyse_declarations(self, env):
3136 #print "CClassDefNode.analyse_declarations:", self.class_name
3137 #print "...visibility =", self.visibility
3138 #print "...module_name =", self.module_name
3141 if self.buffer_defaults_node:
3142 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3143 env, [], self.buffer_defaults_node,
3144 need_complete=False)
3146 buffer_defaults = None
3148 if env.in_cinclude and not self.objstruct_name:
3149 error(self.pos, "Object struct name specification required for "
3150 "C class defined in 'extern from' block")
3151 self.base_type = None
3152 # Now that module imports are cached, we need to
3153 # import the modules for extern classes.
3154 if self.module_name:
3156 for module in env.cimported_modules:
3157 if module.name == self.module_name:
3158 self.module = module
3159 if self.module is None:
3160 self.module = ModuleScope(self.module_name, None, env.context)
3161 self.module.has_extern_class = 1
3162 env.add_imported_module(self.module)
3164 if self.base_class_name:
3165 if self.base_class_module:
3166 base_class_scope = env.find_module(self.base_class_module, self.pos)
3168 base_class_scope = env
3169 if self.base_class_name == 'object':
3170 # extension classes are special and don't need to inherit from object
3171 if base_class_scope is None or base_class_scope.lookup('object') is None:
3172 self.base_class_name = None
3173 self.base_class_module = None
3174 base_class_scope = None
3175 if base_class_scope:
3176 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3177 if base_class_entry:
3178 if not base_class_entry.is_type:
3179 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3180 elif not base_class_entry.type.is_extension_type:
3181 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3182 elif not base_class_entry.type.is_complete():
3183 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3184 self.base_class_name, self.class_name))
3185 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3186 base_class_entry.type.scope.directives['final']:
3187 error(self.pos, "Base class '%s' of type '%s' is final" % (
3188 self.base_class_name, self.class_name))
3190 self.base_type = base_class_entry.type
3191 has_body = self.body is not None
3192 if self.module_name and self.visibility != 'extern':
3193 module_path = self.module_name.split(".")
3194 home_scope = env.find_imported_module(module_path, self.pos)
3200 if self.visibility == 'extern':
3201 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3202 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3204 self.entry = home_scope.declare_c_class(
3205 name = self.class_name,
3207 defining = has_body and self.in_pxd,
3208 implementing = has_body and not self.in_pxd,
3209 module_name = self.module_name,
3210 base_type = self.base_type,
3211 objstruct_cname = self.objstruct_name,
3212 typeobj_cname = self.typeobj_name,
3213 visibility = self.visibility,
3214 typedef_flag = self.typedef_flag,
3216 buffer_defaults = buffer_defaults)
3217 if home_scope is not env and self.visibility == 'extern':
3218 env.add_imported_entry(self.class_name, self.entry, self.pos)
3219 self.scope = scope = self.entry.type.scope
3220 if scope is not None:
3221 scope.directives = env.directives
3223 if self.doc and Options.docstrings:
3224 scope.doc = embed_position(self.pos, self.doc)
3227 self.body.analyse_declarations(scope)
3231 scope.implemented = 1
3232 env.allocate_vtable_names(self.entry)
3234 def analyse_expressions(self, env):
3236 scope = self.entry.type.scope
3237 self.body.analyse_expressions(scope)
3239 def generate_function_definitions(self, env, code):
3241 self.body.generate_function_definitions(
3242 self.entry.type.scope, code)
3244 def generate_execution_code(self, code):
3245 # This is needed to generate evaluation code for
3246 # default values of method arguments.
3248 self.body.generate_execution_code(code)
3250 def annotate(self, code):
3252 self.body.annotate(code)
3255 class PropertyNode(StatNode):
3256 # Definition of a property in an extension type.
3259 # doc EncodedString or None Doc string
3262 child_attrs = ["body"]
3264 def analyse_declarations(self, env):
3265 entry = env.declare_property(self.name, self.doc, self.pos)
3267 entry.scope.directives = env.directives
3268 self.body.analyse_declarations(entry.scope)
3270 def analyse_expressions(self, env):
3271 self.body.analyse_expressions(env)
3273 def generate_function_definitions(self, env, code):
3274 self.body.generate_function_definitions(env, code)
3276 def generate_execution_code(self, code):
3279 def annotate(self, code):
3280 self.body.annotate(code)
3283 class GlobalNode(StatNode):
3284 # Global variable declaration.
3290 def analyse_declarations(self, env):
3291 for name in self.names:
3292 env.declare_global(name, self.pos)
3294 def analyse_expressions(self, env):
3297 def generate_execution_code(self, code):
3301 class ExprStatNode(StatNode):
3302 # Expression used as a statement.
3306 child_attrs = ["expr"]
3308 def analyse_declarations(self, env):
3310 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3311 func = self.expr.function.as_cython_attribute()
3312 if func == u'declare':
3313 args, kwds = self.expr.explicit_args_kwds()
3315 error(self.expr.pos, "Variable names must be specified.")
3316 for var, type_node in kwds.key_value_pairs:
3317 type = type_node.analyse_as_type(env)
3319 error(type_node.pos, "Unknown type")
3321 env.declare_var(var.value, type, var.pos, is_cdef = True)
3322 self.__class__ = PassStatNode
3324 def analyse_expressions(self, env):
3325 self.expr.analyse_expressions(env)
3327 def generate_execution_code(self, code):
3328 self.expr.generate_evaluation_code(code)
3329 if not self.expr.is_temp and self.expr.result():
3330 code.putln("%s;" % self.expr.result())
3331 self.expr.generate_disposal_code(code)
3332 self.expr.free_temps(code)
3334 def generate_function_definitions(self, env, code):
3335 self.expr.generate_function_definitions(env, code)
3337 def annotate(self, code):
3338 self.expr.annotate(code)
3341 class AssignmentNode(StatNode):
3342 # Abstract base class for assignment nodes.
3344 # The analyse_expressions and generate_execution_code
3345 # phases of assignments are split into two sub-phases
3346 # each, to enable all the right hand sides of a
3347 # parallel assignment to be evaluated before assigning
3348 # to any of the left hand sides.
3350 def analyse_expressions(self, env):
3351 self.analyse_types(env)
3353 # def analyse_expressions(self, env):
3354 # self.analyse_expressions_1(env)
3355 # self.analyse_expressions_2(env)
3357 def generate_execution_code(self, code):
3358 self.generate_rhs_evaluation_code(code)
3359 self.generate_assignment_code(code)
3362 class SingleAssignmentNode(AssignmentNode):
3363 # The simplest case:
3367 # lhs ExprNode Left hand side
3368 # rhs ExprNode Right hand side
3369 # first bool Is this guaranteed the first assignment to lhs?
3371 child_attrs = ["lhs", "rhs"]
3373 declaration_only = False
3375 def analyse_declarations(self, env):
3378 # handle declarations of the form x = cython.foo()
3379 if isinstance(self.rhs, ExprNodes.CallNode):
3380 func_name = self.rhs.function.as_cython_attribute()
3382 args, kwds = self.rhs.explicit_args_kwds()
3384 if func_name in ['declare', 'typedef']:
3385 if len(args) > 2 or kwds is not None:
3386 error(self.rhs.pos, "Can only declare one type at a time.")
3388 type = args[0].analyse_as_type(env)
3390 error(args[0].pos, "Unknown type")
3393 if func_name == 'declare':
3394 if isinstance(lhs, ExprNodes.NameNode):
3395 vars = [(lhs.name, lhs.pos)]
3396 elif isinstance(lhs, ExprNodes.TupleNode):
3397 vars = [(var.name, var.pos) for var in lhs.args]
3399 error(lhs.pos, "Invalid declaration")
3401 for var, pos in vars:
3402 env.declare_var(var, type, pos, is_cdef = True)
3407 self.declaration_only = True
3409 self.declaration_only = True
3410 if not isinstance(lhs, ExprNodes.NameNode):
3411 error(lhs.pos, "Invalid declaration.")
3412 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3414 elif func_name in ['struct', 'union']:
3415 self.declaration_only = True
3416 if len(args) > 0 or kwds is None:
3417 error(self.rhs.pos, "Struct or union members must be given by name.")
3420 for member, type_node in kwds.key_value_pairs:
3421 type = type_node.analyse_as_type(env)
3423 error(type_node.pos, "Unknown type")
3425 members.append((member.value, type, member.pos))
3426 if len(members) < len(kwds.key_value_pairs):
3428 if not isinstance(self.lhs, ExprNodes.NameNode):
3429 error(self.lhs.pos, "Invalid declaration.")
3430 name = self.lhs.name
3431 scope = StructOrUnionScope(name)
3432 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3433 for member, type, pos in members:
3434 scope.declare_var(member, type, pos)
3436 if self.declaration_only:
3439 self.lhs.analyse_target_declaration(env)
3441 def analyse_types(self, env, use_temp = 0):
3442 self.rhs.analyse_types(env)
3443 self.lhs.analyse_target_types(env)
3444 self.lhs.gil_assignment_check(env)
3445 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3447 self.rhs = self.rhs.coerce_to_temp(env)
3449 def generate_rhs_evaluation_code(self, code):
3450 self.rhs.generate_evaluation_code(code)
3452 def generate_assignment_code(self, code):
3453 self.lhs.generate_assignment_code(self.rhs, code)
3455 def generate_function_definitions(self, env, code):
3456 self.rhs.generate_function_definitions(env, code)
3458 def annotate(self, code):
3459 self.lhs.annotate(code)
3460 self.rhs.annotate(code)
3463 class CascadedAssignmentNode(AssignmentNode):
3464 # An assignment with multiple left hand sides:
3468 # lhs_list [ExprNode] Left hand sides
3469 # rhs ExprNode Right hand sides
3473 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3475 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3476 coerced_rhs_list = None
3478 def analyse_declarations(self, env):
3479 for lhs in self.lhs_list:
3480 lhs.analyse_target_declaration(env)
3482 def analyse_types(self, env, use_temp = 0):
3483 self.rhs.analyse_types(env)
3484 if not self.rhs.is_simple():
3486 self.rhs = self.rhs.coerce_to_temp(env)
3488 self.rhs = self.rhs.coerce_to_simple(env)
3489 from ExprNodes import CloneNode
3490 self.coerced_rhs_list = []
3491 for lhs in self.lhs_list:
3492 lhs.analyse_target_types(env)
3493 lhs.gil_assignment_check(env)
3494 rhs = CloneNode(self.rhs)
3495 rhs = rhs.coerce_to(lhs.type, env)
3496 self.coerced_rhs_list.append(rhs)
3498 def generate_rhs_evaluation_code(self, code):
3499 self.rhs.generate_evaluation_code(code)
3501 def generate_assignment_code(self, code):
3502 for i in range(len(self.lhs_list)):
3503 lhs = self.lhs_list[i]
3504 rhs = self.coerced_rhs_list[i]
3505 rhs.generate_evaluation_code(code)
3506 lhs.generate_assignment_code(rhs, code)
3507 # Assignment has disposed of the cloned RHS
3508 self.rhs.generate_disposal_code(code)
3509 self.rhs.free_temps(code)
3511 def generate_function_definitions(self, env, code):
3512 self.rhs.generate_function_definitions(env, code)
3514 def annotate(self, code):
3515 for i in range(len(self.lhs_list)):
3516 lhs = self.lhs_list[i].annotate(code)
3517 rhs = self.coerced_rhs_list[i].annotate(code)
3518 self.rhs.annotate(code)
3521 class ParallelAssignmentNode(AssignmentNode):
3522 # A combined packing/unpacking assignment:
3526 # This has been rearranged by the parser into
3528 # a = d ; b = e ; c = f
3530 # but we must evaluate all the right hand sides
3531 # before assigning to any of the left hand sides.
3533 # stats [AssignmentNode] The constituent assignments
3535 child_attrs = ["stats"]
3537 def analyse_declarations(self, env):
3538 for stat in self.stats:
3539 stat.analyse_declarations(env)
3541 def analyse_expressions(self, env):
3542 for stat in self.stats:
3543 stat.analyse_types(env, use_temp = 1)
3545 # def analyse_expressions(self, env):
3546 # for stat in self.stats:
3547 # stat.analyse_expressions_1(env, use_temp = 1)
3548 # for stat in self.stats:
3549 # stat.analyse_expressions_2(env)
3551 def generate_execution_code(self, code):
3552 for stat in self.stats:
3553 stat.generate_rhs_evaluation_code(code)
3554 for stat in self.stats:
3555 stat.generate_assignment_code(code)
3557 def generate_function_definitions(self, env, code):
3558 for stat in self.stats:
3559 stat.generate_function_definitions(env, code)
3561 def annotate(self, code):
3562 for stat in self.stats:
3566 class InPlaceAssignmentNode(AssignmentNode):
3567 # An in place arithmetic operand:
3573 # lhs ExprNode Left hand side
3574 # rhs ExprNode Right hand side
3575 # op char one of "+-*/%^&|"
3576 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3578 # This code is a bit tricky because in order to obey Python
3579 # semantics the sub-expressions (e.g. indices) of the lhs must
3580 # not be evaluated twice. So we must re-use the values calculated
3581 # in evaluation phase for the assignment phase as well.
3582 # Fortunately, the type of the lhs node is fairly constrained
3583 # (it must be a NameNode, AttributeNode, or IndexNode).
3585 child_attrs = ["lhs", "rhs"]
3587 def analyse_declarations(self, env):
3588 self.lhs.analyse_target_declaration(env)
3590 def analyse_types(self, env):
3591 self.rhs.analyse_types(env)
3592 self.lhs.analyse_target_types(env)
3594 def generate_execution_code(self, code):
3596 self.rhs.generate_evaluation_code(code)
3597 self.lhs.generate_subexpr_evaluation_code(code)
3598 c_op = self.operator
3602 error(self.pos, "No C inplace power operator")
3603 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3604 if self.lhs.type.is_pyobject:
3605 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3606 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3607 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3608 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3611 # TODO: make sure overload is declared
3612 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3613 self.lhs.generate_subexpr_disposal_code(code)
3614 self.lhs.free_subexpr_temps(code)
3615 self.rhs.generate_disposal_code(code)
3616 self.rhs.free_temps(code)
3618 def annotate(self, code):
3619 self.lhs.annotate(code)
3620 self.rhs.annotate(code)
3622 def create_binop_node(self):
3624 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3627 class PrintStatNode(StatNode):
3630 # arg_tuple TupleNode
3631 # stream ExprNode or None (stdout)
3632 # append_newline boolean
3634 child_attrs = ["arg_tuple", "stream"]
3636 def analyse_expressions(self, env):
3638 self.stream.analyse_expressions(env)
3639 self.stream = self.stream.coerce_to_pyobject(env)
3640 self.arg_tuple.analyse_expressions(env)
3641 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3642 env.use_utility_code(printing_utility_code)
3643 if len(self.arg_tuple.args) == 1 and self.append_newline:
3644 env.use_utility_code(printing_one_utility_code)
3646 nogil_check = Node.gil_error
3647 gil_message = "Python print statement"
3649 def generate_execution_code(self, code):
3651 self.stream.generate_evaluation_code(code)
3652 stream_result = self.stream.py_result()
3655 if len(self.arg_tuple.args) == 1 and self.append_newline:
3656 arg = self.arg_tuple.args[0]
3657 arg.generate_evaluation_code(code)
3660 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3663 code.error_goto(self.pos)))
3664 arg.generate_disposal_code(code)
3665 arg.free_temps(code)
3667 self.arg_tuple.generate_evaluation_code(code)
3669 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3671 self.arg_tuple.py_result(),
3672 self.append_newline,
3673 code.error_goto(self.pos)))
3674 self.arg_tuple.generate_disposal_code(code)
3675 self.arg_tuple.free_temps(code)
3678 self.stream.generate_disposal_code(code)
3679 self.stream.free_temps(code)
3681 def generate_function_definitions(self, env, code):
3683 self.stream.generate_function_definitions(env, code)
3684 self.arg_tuple.generate_function_definitions(env, code)
3686 def annotate(self, code):
3688 self.stream.annotate(code)
3689 self.arg_tuple.annotate(code)
3692 class ExecStatNode(StatNode):
3697 child_attrs = ["args"]
3699 def analyse_expressions(self, env):
3700 for i, arg in enumerate(self.args):
3701 arg.analyse_expressions(env)
3702 arg = arg.coerce_to_pyobject(env)
3704 env.use_utility_code(Builtin.pyexec_utility_code)
3706 nogil_check = Node.gil_error
3707 gil_message = "Python exec statement"
3709 def generate_execution_code(self, code):
3711 for arg in self.args:
3712 arg.generate_evaluation_code(code)
3713 args.append( arg.py_result() )
3714 args = tuple(args + ['0', '0'][:3-len(args)])
3715 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3716 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3717 (temp_result,) + args))
3718 for arg in self.args:
3719 arg.generate_disposal_code(code)
3720 arg.free_temps(code)
3722 code.error_goto_if_null(temp_result, self.pos))
3723 code.put_gotref(temp_result)
3724 code.put_decref_clear(temp_result, py_object_type)
3725 code.funcstate.release_temp(temp_result)
3727 def annotate(self, code):
3728 for arg in self.args:
3732 class DelStatNode(StatNode):
3737 child_attrs = ["args"]
3739 def analyse_declarations(self, env):
3740 for arg in self.args:
3741 arg.analyse_target_declaration(env)
3743 def analyse_expressions(self, env):
3744 for arg in self.args:
3745 arg.analyse_target_expression(env, None)
3746 if arg.type.is_pyobject:
3748 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3750 elif arg.type.is_cpp_class:
3751 error(arg.pos, "Deletion of non-heap C++ object")
3753 error(arg.pos, "Deletion of non-Python, non-C++ object")
3754 #arg.release_target_temp(env)
3756 def nogil_check(self, env):
3757 for arg in self.args:
3758 if arg.type.is_pyobject:
3761 gil_message = "Deleting Python object"
3763 def generate_execution_code(self, code):
3764 for arg in self.args:
3765 if arg.type.is_pyobject:
3766 arg.generate_deletion_code(code)
3767 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3768 arg.generate_result_code(code)
3769 code.putln("delete %s;" % arg.result())
3770 # else error reported earlier
3772 def annotate(self, code):
3773 for arg in self.args:
3777 class PassStatNode(StatNode):
3782 def analyse_expressions(self, env):
3785 def generate_execution_code(self, code):
3789 class BreakStatNode(StatNode):
3793 def analyse_expressions(self, env):
3796 def generate_execution_code(self, code):
3797 if not code.break_label:
3798 error(self.pos, "break statement not inside loop")
3800 code.put_goto(code.break_label)
3803 class ContinueStatNode(StatNode):
3807 def analyse_expressions(self, env):
3810 def generate_execution_code(self, code):
3811 if code.funcstate.in_try_finally:
3812 error(self.pos, "continue statement inside try of try...finally")
3813 elif not code.continue_label:
3814 error(self.pos, "continue statement not inside loop")
3816 code.put_goto(code.continue_label)
3819 class ReturnStatNode(StatNode):
3822 # value ExprNode or None
3823 # return_type PyrexType
3825 child_attrs = ["value"]
3827 def analyse_expressions(self, env):
3828 return_type = env.return_type
3829 self.return_type = return_type
3831 error(self.pos, "Return not inside a function body")
3834 self.value.analyse_types(env)
3835 if return_type.is_void or return_type.is_returncode:
3836 error(self.value.pos,
3837 "Return with value in void function")
3839 self.value = self.value.coerce_to(env.return_type, env)
3841 if (not return_type.is_void
3842 and not return_type.is_pyobject
3843 and not return_type.is_returncode):
3844 error(self.pos, "Return value required")
3846 def nogil_check(self, env):
3847 if self.return_type.is_pyobject:
3850 gil_message = "Returning Python object"
3852 def generate_execution_code(self, code):
3853 code.mark_pos(self.pos)
3854 if not self.return_type:
3855 # error reported earlier
3857 if self.return_type.is_pyobject:
3858 code.put_xdecref(Naming.retval_cname,
3861 self.value.generate_evaluation_code(code)
3862 self.value.make_owned_reference(code)
3865 Naming.retval_cname,
3866 self.value.result_as(self.return_type)))
3867 self.value.generate_post_assignment_code(code)
3868 self.value.free_temps(code)
3870 if self.return_type.is_pyobject:
3871 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3872 elif self.return_type.is_returncode:
3875 Naming.retval_cname,
3876 self.return_type.default_value))
3877 for cname, type in code.funcstate.temps_holding_reference():
3878 code.put_decref_clear(cname, type)
3879 code.put_goto(code.return_label)
3881 def generate_function_definitions(self, env, code):
3882 if self.value is not None:
3883 self.value.generate_function_definitions(env, code)
3885 def annotate(self, code):
3887 self.value.annotate(code)
3890 class RaiseStatNode(StatNode):
3893 # exc_type ExprNode or None
3894 # exc_value ExprNode or None
3895 # exc_tb ExprNode or None
3897 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3899 def analyse_expressions(self, env):
3901 self.exc_type.analyse_types(env)
3902 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3904 self.exc_value.analyse_types(env)
3905 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3907 self.exc_tb.analyse_types(env)
3908 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3909 env.use_utility_code(raise_utility_code)
3911 nogil_check = Node.gil_error
3912 gil_message = "Raising exception"
3914 def generate_execution_code(self, code):
3916 self.exc_type.generate_evaluation_code(code)
3917 type_code = self.exc_type.py_result()
3921 self.exc_value.generate_evaluation_code(code)
3922 value_code = self.exc_value.py_result()
3926 self.exc_tb.generate_evaluation_code(code)
3927 tb_code = self.exc_tb.py_result()
3931 "__Pyx_Raise(%s, %s, %s);" % (
3935 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3937 obj.generate_disposal_code(code)
3938 obj.free_temps(code)
3940 code.error_goto(self.pos))
3942 def generate_function_definitions(self, env, code):
3943 if self.exc_type is not None:
3944 self.exc_type.generate_function_definitions(env, code)
3945 if self.exc_value is not None:
3946 self.exc_value.generate_function_definitions(env, code)
3947 if self.exc_tb is not None:
3948 self.exc_tb.generate_function_definitions(env, code)
3950 def annotate(self, code):
3952 self.exc_type.annotate(code)
3954 self.exc_value.annotate(code)
3956 self.exc_tb.annotate(code)
3959 class ReraiseStatNode(StatNode):
3963 def analyse_expressions(self, env):
3964 env.use_utility_code(restore_exception_utility_code)
3966 nogil_check = Node.gil_error
3967 gil_message = "Raising exception"
3969 def generate_execution_code(self, code):
3970 vars = code.funcstate.exc_vars
3972 for varname in vars:
3973 code.put_giveref(varname)
3974 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3975 for varname in vars:
3976 code.put("%s = 0; " % varname)
3978 code.putln(code.error_goto(self.pos))
3980 error(self.pos, "Reraise not inside except clause")
3983 class AssertStatNode(StatNode):
3987 # value ExprNode or None
3989 child_attrs = ["cond", "value"]
3991 def analyse_expressions(self, env):
3992 self.cond = self.cond.analyse_boolean_expression(env)
3994 self.value.analyse_types(env)
3995 self.value = self.value.coerce_to_pyobject(env)
3997 nogil_check = Node.gil_error
3998 gil_message = "Raising exception"
4000 def generate_execution_code(self, code):
4001 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
4002 self.cond.generate_evaluation_code(code)
4004 "if (unlikely(!%s)) {" %
4007 self.value.generate_evaluation_code(code)
4009 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4010 self.value.py_result())
4011 self.value.generate_disposal_code(code)
4012 self.value.free_temps(code)
4015 "PyErr_SetNone(PyExc_AssertionError);")
4017 code.error_goto(self.pos))
4020 self.cond.generate_disposal_code(code)
4021 self.cond.free_temps(code)
4022 code.putln("#endif")
4024 def generate_function_definitions(self, env, code):
4025 self.cond.generate_function_definitions(env, code)
4026 if self.value is not None:
4027 self.value.generate_function_definitions(env, code)
4029 def annotate(self, code):
4030 self.cond.annotate(code)
4032 self.value.annotate(code)
4035 class IfStatNode(StatNode):
4038 # if_clauses [IfClauseNode]
4039 # else_clause StatNode or None
4041 child_attrs = ["if_clauses", "else_clause"]
4043 def analyse_control_flow(self, env):
4044 env.start_branching(self.pos)
4045 for if_clause in self.if_clauses:
4046 if_clause.analyse_control_flow(env)
4047 env.next_branch(if_clause.end_pos())
4048 if self.else_clause:
4049 self.else_clause.analyse_control_flow(env)
4050 env.finish_branching(self.end_pos())
4052 def analyse_declarations(self, env):
4053 for if_clause in self.if_clauses:
4054 if_clause.analyse_declarations(env)
4055 if self.else_clause:
4056 self.else_clause.analyse_declarations(env)
4058 def analyse_expressions(self, env):
4059 for if_clause in self.if_clauses:
4060 if_clause.analyse_expressions(env)
4061 if self.else_clause:
4062 self.else_clause.analyse_expressions(env)
4064 def generate_execution_code(self, code):
4065 code.mark_pos(self.pos)
4066 end_label = code.new_label()
4067 for if_clause in self.if_clauses:
4068 if_clause.generate_execution_code(code, end_label)
4069 if self.else_clause:
4070 code.putln("/*else*/ {")
4071 self.else_clause.generate_execution_code(code)
4073 code.put_label(end_label)
4075 def generate_function_definitions(self, env, code):
4076 for clause in self.if_clauses:
4077 clause.generate_function_definitions(env, code)
4078 if self.else_clause is not None:
4079 self.else_clause.generate_function_definitions(env, code)
4081 def annotate(self, code):
4082 for if_clause in self.if_clauses:
4083 if_clause.annotate(code)
4084 if self.else_clause:
4085 self.else_clause.annotate(code)
4088 class IfClauseNode(Node):
4089 # if or elif clause in an if statement
4091 # condition ExprNode
4094 child_attrs = ["condition", "body"]
4096 def analyse_control_flow(self, env):
4097 self.body.analyse_control_flow(env)
4099 def analyse_declarations(self, env):
4100 self.body.analyse_declarations(env)
4102 def analyse_expressions(self, env):
4104 self.condition.analyse_temp_boolean_expression(env)
4105 self.body.analyse_expressions(env)
4107 def get_constant_condition_result(self):
4108 if self.condition.has_constant_result():
4109 return bool(self.condition.constant_result)
4113 def generate_execution_code(self, code, end_label):
4114 self.condition.generate_evaluation_code(code)
4117 self.condition.result())
4118 self.condition.generate_disposal_code(code)
4119 self.condition.free_temps(code)
4120 self.body.generate_execution_code(code)
4121 code.put_goto(end_label)
4124 def generate_function_definitions(self, env, code):
4125 self.condition.generate_function_definitions(env, code)
4126 self.body.generate_function_definitions(env, code)
4128 def annotate(self, code):
4129 self.condition.annotate(code)
4130 self.body.annotate(code)
4133 class SwitchCaseNode(StatNode):
4134 # Generated in the optimization of an if-elif-else node
4136 # conditions [ExprNode]
4139 child_attrs = ['conditions', 'body']
4141 def generate_execution_code(self, code):
4142 for cond in self.conditions:
4143 code.mark_pos(cond.pos)
4144 cond.generate_evaluation_code(code)
4145 code.putln("case %s:" % cond.result())
4146 self.body.generate_execution_code(code)
4147 code.putln("break;")
4149 def generate_function_definitions(self, env, code):
4150 for cond in self.conditions:
4151 cond.generate_function_definitions(env, code)
4152 self.body.generate_function_definitions(env, code)
4154 def annotate(self, code):
4155 for cond in self.conditions:
4157 self.body.annotate(code)
4159 class SwitchStatNode(StatNode):
4160 # Generated in the optimization of an if-elif-else node
4163 # cases [SwitchCaseNode]
4164 # else_clause StatNode or None
4166 child_attrs = ['test', 'cases', 'else_clause']
4168 def generate_execution_code(self, code):
4169 self.test.generate_evaluation_code(code)
4170 code.putln("switch (%s) {" % self.test.result())
4171 for case in self.cases:
4172 case.generate_execution_code(code)
4173 if self.else_clause is not None:
4174 code.putln("default:")
4175 self.else_clause.generate_execution_code(code)
4176 code.putln("break;")
4179 def generate_function_definitions(self, env, code):
4180 self.test.generate_function_definitions(env, code)
4181 for case in self.cases:
4182 case.generate_function_definitions(env, code)
4183 if self.else_clause is not None:
4184 self.else_clause.generate_function_definitions(env, code)
4186 def annotate(self, code):
4187 self.test.annotate(code)
4188 for case in self.cases:
4190 if self.else_clause is not None:
4191 self.else_clause.annotate(code)
4193 class LoopNode(object):
4195 def analyse_control_flow(self, env):
4196 env.start_branching(self.pos)
4197 self.body.analyse_control_flow(env)
4198 env.next_branch(self.body.end_pos())
4199 if self.else_clause:
4200 self.else_clause.analyse_control_flow(env)
4201 env.finish_branching(self.end_pos())
4204 class WhileStatNode(LoopNode, StatNode):
4207 # condition ExprNode
4209 # else_clause StatNode
4211 child_attrs = ["condition", "body", "else_clause"]
4213 def analyse_declarations(self, env):
4214 self.body.analyse_declarations(env)
4215 if self.else_clause:
4216 self.else_clause.analyse_declarations(env)
4218 def analyse_expressions(self, env):
4220 self.condition.analyse_temp_boolean_expression(env)
4221 self.body.analyse_expressions(env)
4222 if self.else_clause:
4223 self.else_clause.analyse_expressions(env)
4225 def generate_execution_code(self, code):
4226 old_loop_labels = code.new_loop_labels()
4229 self.condition.generate_evaluation_code(code)
4230 self.condition.generate_disposal_code(code)
4233 self.condition.result())
4234 self.condition.free_temps(code)
4235 self.body.generate_execution_code(code)
4236 code.put_label(code.continue_label)
4238 break_label = code.break_label
4239 code.set_loop_labels(old_loop_labels)
4240 if self.else_clause:
4241 code.putln("/*else*/ {")
4242 self.else_clause.generate_execution_code(code)
4244 code.put_label(break_label)
4246 def generate_function_definitions(self, env, code):
4247 self.condition.generate_function_definitions(env, code)
4248 self.body.generate_function_definitions(env, code)
4249 if self.else_clause is not None:
4250 self.else_clause.generate_function_definitions(env, code)
4252 def annotate(self, code):
4253 self.condition.annotate(code)
4254 self.body.annotate(code)
4255 if self.else_clause:
4256 self.else_clause.annotate(code)
4259 def ForStatNode(pos, **kw):
4260 if 'iterator' in kw:
4261 return ForInStatNode(pos, **kw)
4263 return ForFromStatNode(pos, **kw)
4265 class ForInStatNode(LoopNode, StatNode):
4269 # iterator IteratorNode
4271 # else_clause StatNode
4272 # item NextNode used internally
4274 child_attrs = ["target", "iterator", "body", "else_clause"]
4277 def analyse_declarations(self, env):
4278 self.target.analyse_target_declaration(env)
4279 self.body.analyse_declarations(env)
4280 if self.else_clause:
4281 self.else_clause.analyse_declarations(env)
4283 def analyse_expressions(self, env):
4285 self.target.analyse_target_types(env)
4286 self.iterator.analyse_expressions(env)
4287 self.item = ExprNodes.NextNode(self.iterator, env)
4288 self.item = self.item.coerce_to(self.target.type, env)
4289 self.body.analyse_expressions(env)
4290 if self.else_clause:
4291 self.else_clause.analyse_expressions(env)
4293 def generate_execution_code(self, code):
4294 old_loop_labels = code.new_loop_labels()
4295 self.iterator.allocate_counter_temp(code)
4296 self.iterator.generate_evaluation_code(code)
4299 self.item.generate_evaluation_code(code)
4300 self.target.generate_assignment_code(self.item, code)
4301 self.body.generate_execution_code(code)
4302 code.put_label(code.continue_label)
4305 break_label = code.break_label
4306 code.set_loop_labels(old_loop_labels)
4308 if self.else_clause:
4309 # in nested loops, the 'else' block can contain a
4310 # 'continue' statement for the outer loop, but we may need
4311 # to generate cleanup code before taking that path, so we
4313 orig_continue_label = code.continue_label
4314 code.continue_label = code.new_label('outer_continue')
4316 code.putln("/*else*/ {")
4317 self.else_clause.generate_execution_code(code)
4320 if code.label_used(code.continue_label):
4321 code.put_goto(break_label)
4322 code.put_label(code.continue_label)
4323 self.iterator.generate_disposal_code(code)
4324 code.put_goto(orig_continue_label)
4325 code.set_loop_labels(old_loop_labels)
4327 if code.label_used(break_label):
4328 code.put_label(break_label)
4329 self.iterator.release_counter_temp(code)
4330 self.iterator.generate_disposal_code(code)
4331 self.iterator.free_temps(code)
4333 def generate_function_definitions(self, env, code):
4334 self.target.generate_function_definitions(env, code)
4335 self.iterator.generate_function_definitions(env, code)
4336 self.body.generate_function_definitions(env, code)
4337 if self.else_clause is not None:
4338 self.else_clause.generate_function_definitions(env, code)
4340 def annotate(self, code):
4341 self.target.annotate(code)
4342 self.iterator.annotate(code)
4343 self.body.annotate(code)
4344 if self.else_clause:
4345 self.else_clause.annotate(code)
4346 self.item.annotate(code)
4349 class ForFromStatNode(LoopNode, StatNode):
4350 # for name from expr rel name rel expr
4357 # step ExprNode or None
4359 # else_clause StatNode or None
4365 # loopvar_node ExprNode (usually a NameNode or temp node)
4366 # py_loopvar_node PyTempNode or None
4367 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4369 is_py_target = False
4371 py_loopvar_node = None
4374 gil_message = "For-loop using object bounds or target"
4376 def nogil_check(self, env):
4377 for x in (self.target, self.bound1, self.bound2):
4378 if x.type.is_pyobject:
4381 def analyse_declarations(self, env):
4382 self.target.analyse_target_declaration(env)
4383 self.body.analyse_declarations(env)
4384 if self.else_clause:
4385 self.else_clause.analyse_declarations(env)
4387 def analyse_expressions(self, env):
4389 self.target.analyse_target_types(env)
4390 self.bound1.analyse_types(env)
4391 self.bound2.analyse_types(env)
4392 if self.step is not None:
4393 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4394 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4395 self.step.analyse_types(env)
4397 target_type = self.target.type
4398 if self.target.type.is_numeric:
4399 loop_type = self.target.type
4401 loop_type = PyrexTypes.c_int_type
4402 if not self.bound1.type.is_pyobject:
4403 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4404 if not self.bound2.type.is_pyobject:
4405 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4406 if self.step is not None and not self.step.type.is_pyobject:
4407 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4408 self.bound1 = self.bound1.coerce_to(loop_type, env)
4409 self.bound2 = self.bound2.coerce_to(loop_type, env)
4410 if not self.bound2.is_literal:
4411 self.bound2 = self.bound2.coerce_to_temp(env)
4412 if self.step is not None:
4413 self.step = self.step.coerce_to(loop_type, env)
4414 if not self.step.is_literal:
4415 self.step = self.step.coerce_to_temp(env)
4417 target_type = self.target.type
4418 if not (target_type.is_pyobject or target_type.is_numeric):
4419 error(self.target.pos,
4420 "for-from loop variable must be c numeric type or Python object")
4421 if target_type.is_numeric:
4422 self.is_py_target = False
4423 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4424 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4425 self.loopvar_node = self.target
4426 self.py_loopvar_node = None
4428 self.is_py_target = True
4429 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4430 self.loopvar_node = c_loopvar_node
4431 self.py_loopvar_node = \
4432 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4433 self.body.analyse_expressions(env)
4434 if self.else_clause:
4435 self.else_clause.analyse_expressions(env)
4437 def generate_execution_code(self, code):
4438 old_loop_labels = code.new_loop_labels()
4439 from_range = self.from_range
4440 self.bound1.generate_evaluation_code(code)
4441 self.bound2.generate_evaluation_code(code)
4442 offset, incop = self.relation_table[self.relation1]
4443 if self.step is not None:
4444 self.step.generate_evaluation_code(code)
4445 step = self.step.result()
4446 incop = "%s=%s" % (incop[0], step)
4448 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4449 self.loopvar_node.allocate(code)
4450 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4451 self.py_loopvar_node.allocate(code)
4453 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4455 loopvar_name = self.loopvar_node.result()
4457 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4459 self.bound1.result(), offset,
4460 loopvar_name, self.relation2, self.bound2.result(),
4461 loopvar_name, incop))
4462 if self.py_loopvar_node:
4463 self.py_loopvar_node.generate_evaluation_code(code)
4464 self.target.generate_assignment_code(self.py_loopvar_node, code)
4466 code.putln("%s = %s;" % (
4467 self.target.result(), loopvar_name))
4468 self.body.generate_execution_code(code)
4469 code.put_label(code.continue_label)
4470 if self.py_loopvar_node:
4471 # This mess is to make for..from loops with python targets behave
4472 # exactly like those with C targets with regards to re-assignment
4473 # of the loop variable.
4475 if self.target.entry.is_pyglobal:
4476 # We know target is a NameNode, this is the only ugly case.
4477 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4478 target_node.allocate(code)
4479 interned_cname = code.intern_identifier(self.target.entry.name)
4480 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4481 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4482 target_node.result(),
4483 Naming.module_cname,
4485 code.error_goto_if_null(target_node.result(), self.target.pos)))
4486 code.put_gotref(target_node.result())
4488 target_node = self.target
4489 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4490 from_py_node.temp_code = loopvar_name
4491 from_py_node.generate_result_code(code)
4492 if self.target.entry.is_pyglobal:
4493 code.put_decref(target_node.result(), target_node.type)
4494 target_node.release(code)
4496 if self.py_loopvar_node:
4497 # This is potentially wasteful, but we don't want the semantics to
4498 # depend on whether or not the loop is a python type.
4499 self.py_loopvar_node.generate_evaluation_code(code)
4500 self.target.generate_assignment_code(self.py_loopvar_node, code)
4502 code.funcstate.release_temp(loopvar_name)
4503 break_label = code.break_label
4504 code.set_loop_labels(old_loop_labels)
4505 if self.else_clause:
4506 code.putln("/*else*/ {")
4507 self.else_clause.generate_execution_code(code)
4509 code.put_label(break_label)
4510 self.bound1.generate_disposal_code(code)
4511 self.bound1.free_temps(code)
4512 self.bound2.generate_disposal_code(code)
4513 self.bound2.free_temps(code)
4514 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4515 self.loopvar_node.release(code)
4516 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4517 self.py_loopvar_node.release(code)
4518 if self.step is not None:
4519 self.step.generate_disposal_code(code)
4520 self.step.free_temps(code)
4523 # {relop : (initial offset, increment op)}
4530 def generate_function_definitions(self, env, code):
4531 self.target.generate_function_definitions(env, code)
4532 self.bound1.generate_function_definitions(env, code)
4533 self.bound2.generate_function_definitions(env, code)
4534 if self.step is not None:
4535 self.step.generate_function_definitions(env, code)
4536 self.body.generate_function_definitions(env, code)
4537 if self.else_clause is not None:
4538 self.else_clause.generate_function_definitions(env, code)
4540 def annotate(self, code):
4541 self.target.annotate(code)
4542 self.bound1.annotate(code)
4543 self.bound2.annotate(code)
4545 self.step.annotate(code)
4546 self.body.annotate(code)
4547 if self.else_clause:
4548 self.else_clause.annotate(code)
4551 class WithStatNode(StatNode):
4553 Represents a Python with statement.
4555 This is only used at parse tree level; and is not present in
4556 analysis or generation phases.
4558 # manager The with statement manager object
4559 # target Node (lhs expression)
4561 child_attrs = ["manager", "target", "body"]
4563 class TryExceptStatNode(StatNode):
4564 # try .. except statement
4567 # except_clauses [ExceptClauseNode]
4568 # else_clause StatNode or None
4570 child_attrs = ["body", "except_clauses", "else_clause"]
4572 def analyse_control_flow(self, env):
4573 env.start_branching(self.pos)
4574 self.body.analyse_control_flow(env)
4575 successful_try = env.control_flow # grab this for later
4576 env.next_branch(self.body.end_pos())
4577 env.finish_branching(self.body.end_pos())
4579 env.start_branching(self.except_clauses[0].pos)
4580 for except_clause in self.except_clauses:
4581 except_clause.analyse_control_flow(env)
4582 env.next_branch(except_clause.end_pos())
4584 # the else cause it executed only when the try clause finishes
4585 env.control_flow.incoming = successful_try
4586 if self.else_clause:
4587 self.else_clause.analyse_control_flow(env)
4588 env.finish_branching(self.end_pos())
4590 def analyse_declarations(self, env):
4591 self.body.analyse_declarations(env)
4592 for except_clause in self.except_clauses:
4593 except_clause.analyse_declarations(env)
4594 if self.else_clause:
4595 self.else_clause.analyse_declarations(env)
4596 env.use_utility_code(reset_exception_utility_code)
4598 def analyse_expressions(self, env):
4599 self.body.analyse_expressions(env)
4600 default_clause_seen = 0
4601 for except_clause in self.except_clauses:
4602 except_clause.analyse_expressions(env)
4603 if default_clause_seen:
4604 error(except_clause.pos, "default 'except:' must be last")
4605 if not except_clause.pattern:
4606 default_clause_seen = 1
4607 self.has_default_clause = default_clause_seen
4608 if self.else_clause:
4609 self.else_clause.analyse_expressions(env)
4611 nogil_check = Node.gil_error
4612 gil_message = "Try-except statement"
4614 def generate_execution_code(self, code):
4615 old_return_label = code.return_label
4616 old_break_label = code.break_label
4617 old_continue_label = code.continue_label
4618 old_error_label = code.new_error_label()
4619 our_error_label = code.error_label
4620 except_end_label = code.new_label('exception_handled')
4621 except_error_label = code.new_label('except_error')
4622 except_return_label = code.new_label('except_return')
4623 try_return_label = code.new_label('try_return')
4624 try_break_label = code.new_label('try_break')
4625 try_continue_label = code.new_label('try_continue')
4626 try_end_label = code.new_label('try_end')
4629 code.putln("PyObject %s;" %
4630 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4631 code.putln("__Pyx_ExceptionSave(%s);" %
4632 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4633 for var in Naming.exc_save_vars:
4634 code.put_xgotref(var)
4637 code.return_label = try_return_label
4638 code.break_label = try_break_label
4639 code.continue_label = try_continue_label
4640 self.body.generate_execution_code(code)
4643 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4644 code.error_label = except_error_label
4645 code.return_label = except_return_label
4646 if self.else_clause:
4649 self.else_clause.generate_execution_code(code)
4652 for var in Naming.exc_save_vars:
4653 code.put_xdecref_clear(var, py_object_type)
4654 code.put_goto(try_end_label)
4655 if code.label_used(try_return_label):
4656 code.put_label(try_return_label)
4657 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4658 code.putln("__Pyx_ExceptionReset(%s);" %
4659 ', '.join(Naming.exc_save_vars))
4660 code.put_goto(old_return_label)
4661 code.put_label(our_error_label)
4662 for temp_name, type in temps_to_clean_up:
4663 code.put_xdecref_clear(temp_name, type)
4664 for except_clause in self.except_clauses:
4665 except_clause.generate_handling_code(code, except_end_label)
4667 error_label_used = code.label_used(except_error_label)
4668 if error_label_used or not self.has_default_clause:
4669 if error_label_used:
4670 code.put_label(except_error_label)
4671 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4672 code.putln("__Pyx_ExceptionReset(%s);" %
4673 ', '.join(Naming.exc_save_vars))
4674 code.put_goto(old_error_label)
4676 for exit_label, old_label in zip(
4677 [try_break_label, try_continue_label, except_return_label],
4678 [old_break_label, old_continue_label, old_return_label]):
4680 if code.label_used(exit_label):
4681 code.put_label(exit_label)
4682 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4683 code.putln("__Pyx_ExceptionReset(%s);" %
4684 ', '.join(Naming.exc_save_vars))
4685 code.put_goto(old_label)
4687 if code.label_used(except_end_label):
4688 code.put_label(except_end_label)
4689 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4690 code.putln("__Pyx_ExceptionReset(%s);" %
4691 ', '.join(Naming.exc_save_vars))
4692 code.put_label(try_end_label)
4695 code.return_label = old_return_label
4696 code.break_label = old_break_label
4697 code.continue_label = old_continue_label
4698 code.error_label = old_error_label
4700 def generate_function_definitions(self, env, code):
4701 self.body.generate_function_definitions(env, code)
4702 for except_clause in self.except_clauses:
4703 except_clause.generate_function_definitions(env, code)
4704 if self.else_clause is not None:
4705 self.else_clause.generate_function_definitions(env, code)
4707 def annotate(self, code):
4708 self.body.annotate(code)
4709 for except_node in self.except_clauses:
4710 except_node.annotate(code)
4711 if self.else_clause:
4712 self.else_clause.annotate(code)
4715 class ExceptClauseNode(Node):
4716 # Part of try ... except statement.
4718 # pattern [ExprNode]
4719 # target ExprNode or None
4721 # excinfo_target NameNode or None optional target for exception info
4722 # match_flag string result of exception match
4723 # exc_value ExcValueNode used internally
4724 # function_name string qualified name of enclosing function
4725 # exc_vars (string * 3) local exception variables
4727 # excinfo_target is never set by the parser, but can be set by a transform
4728 # in order to extract more extensive information about the exception as a
4729 # sys.exc_info()-style tuple into a target variable
4731 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4734 excinfo_target = None
4736 def analyse_declarations(self, env):
4738 self.target.analyse_target_declaration(env)
4739 if self.excinfo_target is not None:
4740 self.excinfo_target.analyse_target_declaration(env)
4741 self.body.analyse_declarations(env)
4743 def analyse_expressions(self, env):
4745 genv = env.global_scope()
4746 self.function_name = env.qualified_name
4748 # normalise/unpack self.pattern into a list
4749 for i, pattern in enumerate(self.pattern):
4750 pattern.analyse_expressions(env)
4751 self.pattern[i] = pattern.coerce_to_pyobject(env)
4754 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4755 self.target.analyse_target_expression(env, self.exc_value)
4756 if self.excinfo_target is not None:
4758 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4759 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4760 self.excinfo_tuple.analyse_expressions(env)
4761 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4763 self.body.analyse_expressions(env)
4765 def generate_handling_code(self, code, end_label):
4766 code.mark_pos(self.pos)
4769 for pattern in self.pattern:
4770 pattern.generate_evaluation_code(code)
4771 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4773 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4775 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4776 for pattern in self.pattern:
4777 pattern.generate_disposal_code(code)
4778 pattern.free_temps(code)
4782 code.funcstate.release_temp(match_flag)
4784 code.putln("/*except:*/ {")
4786 if not getattr(self.body, 'stats', True) and \
4787 self.excinfo_target is None and self.target is None:
4788 # most simple case: no exception variable, empty body (pass)
4789 # => reset the exception state, done
4790 code.putln("PyErr_Restore(0,0,0);")
4791 code.put_goto(end_label)
4795 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4798 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4799 # We always have to fetch the exception value even if
4800 # there is no target, because this also normalises the
4801 # exception and stores it in the thread state.
4802 code.globalstate.use_utility_code(get_exception_utility_code)
4803 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4804 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4805 code.error_goto(self.pos)))
4809 self.exc_value.set_var(exc_vars[1])
4810 self.exc_value.generate_evaluation_code(code)
4811 self.target.generate_assignment_code(self.exc_value, code)
4812 if self.excinfo_target is not None:
4813 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4814 node.set_var(tempvar)
4815 self.excinfo_tuple.generate_evaluation_code(code)
4816 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4818 old_break_label, old_continue_label = code.break_label, code.continue_label
4819 code.break_label = code.new_label('except_break')
4820 code.continue_label = code.new_label('except_continue')
4822 old_exc_vars = code.funcstate.exc_vars
4823 code.funcstate.exc_vars = exc_vars
4824 self.body.generate_execution_code(code)
4825 code.funcstate.exc_vars = old_exc_vars
4826 for var in exc_vars:
4827 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4828 code.put_goto(end_label)
4830 if code.label_used(code.break_label):
4831 code.put_label(code.break_label)
4832 for var in exc_vars:
4833 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4834 code.put_goto(old_break_label)
4835 code.break_label = old_break_label
4837 if code.label_used(code.continue_label):
4838 code.put_label(code.continue_label)
4839 for var in exc_vars:
4840 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4841 code.put_goto(old_continue_label)
4842 code.continue_label = old_continue_label
4844 for temp in exc_vars:
4845 code.funcstate.release_temp(temp)
4850 def generate_function_definitions(self, env, code):
4851 if self.target is not None:
4852 self.target.generate_function_definitions(env, code)
4853 self.body.generate_function_definitions(env, code)
4855 def annotate(self, code):
4857 for pattern in self.pattern:
4858 pattern.annotate(code)
4860 self.target.annotate(code)
4861 self.body.annotate(code)
4864 class TryFinallyStatNode(StatNode):
4865 # try ... finally statement
4868 # finally_clause StatNode
4870 # The plan is that we funnel all continue, break
4871 # return and error gotos into the beginning of the
4872 # finally block, setting a variable to remember which
4873 # one we're doing. At the end of the finally block, we
4874 # switch on the variable to figure out where to go.
4875 # In addition, if we're doing an error, we save the
4876 # exception on entry to the finally block and restore
4879 child_attrs = ["body", "finally_clause"]
4881 preserve_exception = 1
4883 disallow_continue_in_try_finally = 0
4884 # There doesn't seem to be any point in disallowing
4885 # continue in the try block, since we have no problem
4888 def create_analysed(pos, env, body, finally_clause):
4889 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4891 create_analysed = staticmethod(create_analysed)
4893 def analyse_control_flow(self, env):
4894 env.start_branching(self.pos)
4895 self.body.analyse_control_flow(env)
4896 env.next_branch(self.body.end_pos())
4897 env.finish_branching(self.body.end_pos())
4898 self.finally_clause.analyse_control_flow(env)
4900 def analyse_declarations(self, env):
4901 self.body.analyse_declarations(env)
4902 self.finally_clause.analyse_declarations(env)
4904 def analyse_expressions(self, env):
4905 self.body.analyse_expressions(env)
4906 self.finally_clause.analyse_expressions(env)
4908 nogil_check = Node.gil_error
4909 gil_message = "Try-finally statement"
4911 def generate_execution_code(self, code):
4912 old_error_label = code.error_label
4913 old_labels = code.all_new_labels()
4914 new_labels = code.get_all_labels()
4915 new_error_label = code.error_label
4916 catch_label = code.new_label()
4919 if self.disallow_continue_in_try_finally:
4920 was_in_try_finally = code.funcstate.in_try_finally
4921 code.funcstate.in_try_finally = 1
4922 self.body.generate_execution_code(code)
4923 if self.disallow_continue_in_try_finally:
4924 code.funcstate.in_try_finally = was_in_try_finally
4927 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4928 code.mark_pos(self.finally_clause.pos)
4932 error_label_used = 0
4933 for i, new_label in enumerate(new_labels):
4934 if new_label in code.labels_used:
4935 cases_used.append(i)
4936 if new_label == new_error_label:
4937 error_label_used = 1
4938 error_label_case = i
4942 if error_label_used and self.preserve_exception:
4944 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4946 "int %s;" % Naming.exc_lineno_name)
4947 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4948 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4949 code.putln(exc_var_init_zero)
4951 exc_var_init_zero = None
4952 code.use_label(catch_label)
4954 "__pyx_why = 0; goto %s;" % catch_label)
4955 for i in cases_used:
4956 new_label = new_labels[i]
4957 #if new_label and new_label != "<try>":
4958 if new_label == new_error_label and self.preserve_exception:
4959 self.put_error_catcher(code,
4960 new_error_label, i+1, catch_label, temps_to_clean_up)
4962 code.put('%s: ' % new_label)
4963 if exc_var_init_zero:
4964 code.putln(exc_var_init_zero)
4965 code.putln("__pyx_why = %s; goto %s;" % (
4968 code.put_label(catch_label)
4969 code.set_all_labels(old_labels)
4970 if error_label_used:
4971 code.new_error_label()
4972 finally_error_label = code.error_label
4973 self.finally_clause.generate_execution_code(code)
4974 if error_label_used:
4975 if finally_error_label in code.labels_used and self.preserve_exception:
4976 over_label = code.new_label()
4977 code.put_goto(over_label);
4978 code.put_label(finally_error_label)
4979 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4980 for var in Naming.exc_vars:
4981 code.putln("Py_XDECREF(%s);" % var)
4983 code.put_goto(old_error_label)
4984 code.put_label(over_label)
4985 code.error_label = old_error_label
4988 "switch (__pyx_why) {")
4989 for i in cases_used:
4990 old_label = old_labels[i]
4991 if old_label == old_error_label and self.preserve_exception:
4992 self.put_error_uncatcher(code, i+1, old_error_label)
4994 code.use_label(old_label)
4996 "case %s: goto %s;" % (
5004 def generate_function_definitions(self, env, code):
5005 self.body.generate_function_definitions(env, code)
5006 self.finally_clause.generate_function_definitions(env, code)
5008 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5009 code.globalstate.use_utility_code(restore_exception_utility_code)
5016 for temp_name, type in temps_to_clean_up:
5017 code.put_xdecref_clear(temp_name, type)
5019 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5023 Naming.exc_lineno_name, Naming.lineno_cname))
5024 code.put_goto(catch_label)
5027 def put_error_uncatcher(self, code, i, error_label):
5028 code.globalstate.use_utility_code(restore_exception_utility_code)
5033 "__Pyx_ErrRestore(%s, %s, %s);" %
5037 Naming.lineno_cname, Naming.exc_lineno_name))
5038 for var in Naming.exc_vars:
5042 code.put_goto(error_label)
5046 def annotate(self, code):
5047 self.body.annotate(code)
5048 self.finally_clause.annotate(code)
5051 class GILStatNode(TryFinallyStatNode):
5052 # 'with gil' or 'with nogil' statement
5054 # state string 'gil' or 'nogil'
5058 preserve_exception = 0
5060 def __init__(self, pos, state, body):
5062 TryFinallyStatNode.__init__(self, pos,
5064 finally_clause = GILExitNode(pos, state = state))
5066 def analyse_expressions(self, env):
5067 env.use_utility_code(force_init_threads_utility_code)
5068 was_nogil = env.nogil
5070 TryFinallyStatNode.analyse_expressions(self, env)
5071 env.nogil = was_nogil
5075 def generate_execution_code(self, code):
5076 code.mark_pos(self.pos)
5078 if self.state == 'gil':
5079 code.putln("#ifdef WITH_THREAD")
5080 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5081 code.putln("#endif")
5083 code.putln("#ifdef WITH_THREAD")
5084 code.putln("PyThreadState *_save;")
5085 code.putln("#endif")
5086 code.putln("Py_UNBLOCK_THREADS")
5087 TryFinallyStatNode.generate_execution_code(self, code)
5091 class GILExitNode(StatNode):
5092 # Used as the 'finally' block in a GILStatNode
5094 # state string 'gil' or 'nogil'
5098 def analyse_expressions(self, env):
5101 def generate_execution_code(self, code):
5102 if self.state == 'gil':
5103 code.putln("#ifdef WITH_THREAD")
5104 code.putln("PyGILState_Release(_save);")
5105 code.putln("#endif")
5107 code.putln("Py_BLOCK_THREADS")
5110 class CImportStatNode(StatNode):
5113 # module_name string Qualified name of module being imported
5114 # as_name string or None Name specified in "as" clause, if any
5118 def analyse_declarations(self, env):
5119 if not env.is_module_scope:
5120 error(self.pos, "cimport only allowed at module level")
5122 module_scope = env.find_module(self.module_name, self.pos)
5123 if "." in self.module_name:
5124 names = [EncodedString(name) for name in self.module_name.split(".")]
5126 top_module_scope = env.context.find_submodule(top_name)
5127 module_scope = top_module_scope
5128 for name in names[1:]:
5129 submodule_scope = module_scope.find_submodule(name)
5130 module_scope.declare_module(name, submodule_scope, self.pos)
5131 module_scope = submodule_scope
5133 env.declare_module(self.as_name, module_scope, self.pos)
5135 env.declare_module(top_name, top_module_scope, self.pos)
5137 name = self.as_name or self.module_name
5138 env.declare_module(name, module_scope, self.pos)
5140 def analyse_expressions(self, env):
5143 def generate_execution_code(self, code):
5147 class FromCImportStatNode(StatNode):
5148 # from ... cimport statement
5150 # module_name string Qualified name of module
5151 # imported_names [(pos, name, as_name, kind)] Names to be imported
5155 def analyse_declarations(self, env):
5156 if not env.is_module_scope:
5157 error(self.pos, "cimport only allowed at module level")
5159 module_scope = env.find_module(self.module_name, self.pos)
5160 env.add_imported_module(module_scope)
5161 for pos, name, as_name, kind in self.imported_names:
5163 for local_name, entry in module_scope.entries.items():
5164 env.add_imported_entry(local_name, entry, pos)
5166 entry = module_scope.lookup(name)
5168 if kind and not self.declaration_matches(entry, kind):
5169 entry.redeclared(pos)
5171 if kind == 'struct' or kind == 'union':
5172 entry = module_scope.declare_struct_or_union(name,
5173 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5174 elif kind == 'class':
5175 entry = module_scope.declare_c_class(name, pos = pos,
5176 module_name = self.module_name)
5178 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5179 if submodule_scope.parent_module is module_scope:
5180 env.declare_module(as_name or name, submodule_scope, self.pos)
5182 error(pos, "Name '%s' not declared in module '%s'"
5183 % (name, self.module_name))
5186 local_name = as_name or name
5187 env.add_imported_entry(local_name, entry, pos)
5189 def declaration_matches(self, entry, kind):
5190 if not entry.is_type:
5194 if not type.is_extension_type:
5197 if not type.is_struct_or_union:
5199 if kind != type.kind:
5203 def analyse_expressions(self, env):
5206 def generate_execution_code(self, code):
5210 class FromImportStatNode(StatNode):
5211 # from ... import statement
5214 # items [(string, NameNode)]
5215 # interned_items [(string, NameNode, ExprNode)]
5216 # item PyTempNode used internally
5217 # import_star boolean used internally
5219 child_attrs = ["module"]
5222 def analyse_declarations(self, env):
5223 for name, target in self.items:
5225 if not env.is_module_scope:
5226 error(self.pos, "import * only allowed at module level")
5228 env.has_import_star = 1
5229 self.import_star = 1
5231 target.analyse_target_declaration(env)
5233 def analyse_expressions(self, env):
5235 self.module.analyse_expressions(env)
5236 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5237 self.interned_items = []
5238 for name, target in self.items:
5240 for _, entry in env.entries.items():
5241 if not entry.is_type and entry.type.is_extension_type:
5242 env.use_utility_code(ExprNodes.type_test_utility_code)
5245 entry = env.lookup(target.name)
5246 # check whether or not entry is already cimported
5247 if (entry.is_type and entry.type.name == name
5248 and hasattr(entry.type, 'module_name')):
5249 if entry.type.module_name == self.module.module_name.value:
5250 # cimported with absolute name
5253 # cimported with relative name
5254 module = env.find_module(self.module.module_name.value,
5256 if entry.type.module_name == module.qualified_name:
5258 except AttributeError:
5260 target.analyse_target_expression(env, None)
5261 if target.type is py_object_type:
5264 coerced_item = self.item.coerce_to(target.type, env)
5265 self.interned_items.append((name, target, coerced_item))
5267 def generate_execution_code(self, code):
5268 self.module.generate_evaluation_code(code)
5269 if self.import_star:
5271 'if (%s(%s) < 0) %s;' % (
5273 self.module.py_result(),
5274 code.error_goto(self.pos)))
5275 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5276 self.item.set_cname(item_temp)
5277 for name, target, coerced_item in self.interned_items:
5278 cname = code.intern_identifier(name)
5280 '%s = PyObject_GetAttr(%s, %s); %s' % (
5282 self.module.py_result(),
5284 code.error_goto_if_null(item_temp, self.pos)))
5285 code.put_gotref(item_temp)
5286 if coerced_item is None:
5287 target.generate_assignment_code(self.item, code)
5289 coerced_item.allocate_temp_result(code)
5290 coerced_item.generate_result_code(code)
5291 target.generate_assignment_code(coerced_item, code)
5292 code.put_decref_clear(item_temp, py_object_type)
5293 code.funcstate.release_temp(item_temp)
5294 self.module.generate_disposal_code(code)
5295 self.module.free_temps(code)
5299 #------------------------------------------------------------------------------------
5301 # Runtime support code
5303 #------------------------------------------------------------------------------------
5305 utility_function_predeclarations = \
5307 /* inline attribute */
5308 #ifndef CYTHON_INLINE
5309 #if defined(__GNUC__)
5310 #define CYTHON_INLINE __inline__
5311 #elif defined(_MSC_VER)
5312 #define CYTHON_INLINE __inline
5313 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5314 #define CYTHON_INLINE inline
5316 #define CYTHON_INLINE
5320 /* unused attribute */
5321 #ifndef CYTHON_UNUSED
5322 # if defined(__GNUC__)
5323 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5324 # define CYTHON_UNUSED __attribute__ ((__unused__))
5326 # define CYTHON_UNUSED
5328 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5329 # define CYTHON_UNUSED __attribute__ ((__unused__))
5331 # define CYTHON_UNUSED
5335 typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
5339 if Options.gcc_branch_hints:
5340 branch_prediction_macros = \
5343 /* Test for GCC > 2.95 */
5344 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5345 #define likely(x) __builtin_expect(!!(x), 1)
5346 #define unlikely(x) __builtin_expect(!!(x), 0)
5347 #else /* __GNUC__ > 2 ... */
5348 #define likely(x) (x)
5349 #define unlikely(x) (x)
5350 #endif /* __GNUC__ > 2 ... */
5351 #else /* __GNUC__ */
5352 #define likely(x) (x)
5353 #define unlikely(x) (x)
5354 #endif /* __GNUC__ */
5357 branch_prediction_macros = \
5359 #define likely(x) (x)
5360 #define unlikely(x) (x)
5363 #get_name_predeclaration = \
5364 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5366 #get_name_interned_predeclaration = \
5367 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5369 #------------------------------------------------------------------------------------
5371 printing_utility_code = UtilityCode(
5373 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5374 #if PY_MAJOR_VERSION >= 3
5375 static PyObject* %s = 0;
5376 static PyObject* %s = 0;
5378 """ % (Naming.print_function, Naming.print_function_kwargs),
5380 #if PY_MAJOR_VERSION >= 3
5384 """ % (Naming.print_function, Naming.print_function_kwargs),
5386 #if PY_MAJOR_VERSION < 3
5387 static PyObject *__Pyx_GetStdout(void) {
5388 PyObject *f = PySys_GetObject((char *)"stdout");
5390 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5395 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5400 if (!(f = __Pyx_GetStdout()))
5403 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5404 if (PyFile_SoftSpace(f, 1)) {
5405 if (PyFile_WriteString(" ", f) < 0)
5408 v = PyTuple_GET_ITEM(arg_tuple, i);
5409 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5411 if (PyString_Check(v)) {
5412 char *s = PyString_AsString(v);
5413 Py_ssize_t len = PyString_Size(v);
5415 isspace(Py_CHARMASK(s[len-1])) &&
5417 PyFile_SoftSpace(f, 0);
5421 if (PyFile_WriteString("\n", f) < 0)
5423 PyFile_SoftSpace(f, 0);
5428 #else /* Python 3 has a print function */
5430 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5431 PyObject* kwargs = 0;
5432 PyObject* result = 0;
5433 PyObject* end_string;
5434 if (unlikely(!%(PRINT_FUNCTION)s)) {
5435 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5436 if (!%(PRINT_FUNCTION)s)
5440 kwargs = PyDict_New();
5441 if (unlikely(!kwargs))
5443 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5446 end_string = PyUnicode_FromStringAndSize(" ", 1);
5447 if (unlikely(!end_string))
5449 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5450 Py_DECREF(end_string);
5453 Py_DECREF(end_string);
5455 } else if (!newline) {
5456 if (unlikely(!%(PRINT_KWARGS)s)) {
5457 %(PRINT_KWARGS)s = PyDict_New();
5458 if (unlikely(!%(PRINT_KWARGS)s))
5460 end_string = PyUnicode_FromStringAndSize(" ", 1);
5461 if (unlikely(!end_string))
5463 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5464 Py_DECREF(end_string);
5467 Py_DECREF(end_string);
5469 kwargs = %(PRINT_KWARGS)s;
5471 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5472 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5479 if (kwargs != %(PRINT_KWARGS)s)
5485 """ % {'BUILTINS' : Naming.builtins_cname,
5486 'PRINT_FUNCTION' : Naming.print_function,
5487 'PRINT_KWARGS' : Naming.print_function_kwargs}
5491 printing_one_utility_code = UtilityCode(
5493 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5496 #if PY_MAJOR_VERSION < 3
5498 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5500 if (!(f = __Pyx_GetStdout()))
5503 if (PyFile_SoftSpace(f, 0)) {
5504 if (PyFile_WriteString(" ", f) < 0)
5507 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5509 if (PyFile_WriteString("\n", f) < 0)
5512 /* the line below is just to avoid compiler
5513 * compiler warnings about unused functions */
5514 return __Pyx_Print(f, NULL, 0);
5517 #else /* Python 3 has a print function */
5519 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5521 PyObject* arg_tuple = PyTuple_New(1);
5522 if (unlikely(!arg_tuple))
5525 PyTuple_SET_ITEM(arg_tuple, 0, o);
5526 res = __Pyx_Print(stream, arg_tuple, 1);
5527 Py_DECREF(arg_tuple);
5533 requires=[printing_utility_code])
5537 #------------------------------------------------------------------------------------
5539 # Exception raising code
5541 # Exceptions are raised by __Pyx_Raise() and stored as plain
5542 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5543 # 'except' statement, curexc_* is moved over to exc_* by
5544 # __Pyx_GetException()
5546 restore_exception_utility_code = UtilityCode(
5548 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5549 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5552 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5553 PyObject *tmp_type, *tmp_value, *tmp_tb;
5554 PyThreadState *tstate = PyThreadState_GET();
5556 tmp_type = tstate->curexc_type;
5557 tmp_value = tstate->curexc_value;
5558 tmp_tb = tstate->curexc_traceback;
5559 tstate->curexc_type = type;
5560 tstate->curexc_value = value;
5561 tstate->curexc_traceback = tb;
5562 Py_XDECREF(tmp_type);
5563 Py_XDECREF(tmp_value);
5567 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5568 PyThreadState *tstate = PyThreadState_GET();
5569 *type = tstate->curexc_type;
5570 *value = tstate->curexc_value;
5571 *tb = tstate->curexc_traceback;
5573 tstate->curexc_type = 0;
5574 tstate->curexc_value = 0;
5575 tstate->curexc_traceback = 0;
5580 # The following function is based on do_raise() from ceval.c. There
5581 # are separate versions for Python2 and Python3 as exception handling
5582 # has changed quite a lot between the two versions.
5584 raise_utility_code = UtilityCode(
5586 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5589 #if PY_MAJOR_VERSION < 3
5590 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5594 /* First, check the traceback argument, replacing None with NULL. */
5595 if (tb == Py_None) {
5599 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5600 PyErr_SetString(PyExc_TypeError,
5601 "raise: arg 3 must be a traceback or None");
5604 /* Next, replace a missing value with None */
5605 if (value == NULL) {
5609 #if PY_VERSION_HEX < 0x02050000
5610 if (!PyClass_Check(type))
5612 if (!PyType_Check(type))
5615 /* Raising an instance. The value should be a dummy. */
5616 if (value != Py_None) {
5617 PyErr_SetString(PyExc_TypeError,
5618 "instance exception may not have a separate value");
5621 /* Normalize to raise <class>, <instance> */
5624 #if PY_VERSION_HEX < 0x02050000
5625 if (PyInstance_Check(type)) {
5626 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5631 PyErr_SetString(PyExc_TypeError,
5632 "raise: exception must be an old-style class or instance");
5636 type = (PyObject*) Py_TYPE(type);
5638 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5639 PyErr_SetString(PyExc_TypeError,
5640 "raise: exception class must be a subclass of BaseException");
5646 __Pyx_ErrRestore(type, value, tb);
5655 #else /* Python 3+ */
5657 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5658 if (tb == Py_None) {
5660 } else if (tb && !PyTraceBack_Check(tb)) {
5661 PyErr_SetString(PyExc_TypeError,
5662 "raise: arg 3 must be a traceback or None");
5665 if (value == Py_None)
5668 if (PyExceptionInstance_Check(type)) {
5670 PyErr_SetString(PyExc_TypeError,
5671 "instance exception may not have a separate value");
5675 type = (PyObject*) Py_TYPE(value);
5676 } else if (!PyExceptionClass_Check(type)) {
5677 PyErr_SetString(PyExc_TypeError,
5678 "raise: exception class must be a subclass of BaseException");
5682 PyErr_SetObject(type, value);
5685 PyThreadState *tstate = PyThreadState_GET();
5686 PyObject* tmp_tb = tstate->curexc_traceback;
5689 tstate->curexc_traceback = tb;
5699 requires=[restore_exception_utility_code])
5701 #------------------------------------------------------------------------------------
5703 get_exception_utility_code = UtilityCode(
5705 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5708 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5709 PyObject *local_type, *local_value, *local_tb;
5710 PyObject *tmp_type, *tmp_value, *tmp_tb;
5711 PyThreadState *tstate = PyThreadState_GET();
5712 local_type = tstate->curexc_type;
5713 local_value = tstate->curexc_value;
5714 local_tb = tstate->curexc_traceback;
5715 tstate->curexc_type = 0;
5716 tstate->curexc_value = 0;
5717 tstate->curexc_traceback = 0;
5718 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5719 if (unlikely(tstate->curexc_type))
5721 #if PY_MAJOR_VERSION >= 3
5722 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5726 *value = local_value;
5728 Py_INCREF(local_type);
5729 Py_INCREF(local_value);
5730 Py_INCREF(local_tb);
5731 tmp_type = tstate->exc_type;
5732 tmp_value = tstate->exc_value;
5733 tmp_tb = tstate->exc_traceback;
5734 tstate->exc_type = local_type;
5735 tstate->exc_value = local_value;
5736 tstate->exc_traceback = local_tb;
5737 /* Make sure tstate is in a consistent state when we XDECREF
5738 these objects (XDECREF may run arbitrary code). */
5739 Py_XDECREF(tmp_type);
5740 Py_XDECREF(tmp_value);
5747 Py_XDECREF(local_type);
5748 Py_XDECREF(local_value);
5749 Py_XDECREF(local_tb);
5755 #------------------------------------------------------------------------------------
5757 get_exception_tuple_utility_code = UtilityCode(proto="""
5758 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5760 # I doubt that calling __Pyx_GetException() here is correct as it moves
5761 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5762 # exception handlers later on from receiving it.
5764 static PyObject *__Pyx_GetExceptionTuple(void) {
5765 PyObject *type = NULL, *value = NULL, *tb = NULL;
5766 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5767 PyObject* exc_info = PyTuple_New(3);
5772 PyTuple_SET_ITEM(exc_info, 0, type);
5773 PyTuple_SET_ITEM(exc_info, 1, value);
5774 PyTuple_SET_ITEM(exc_info, 2, tb);
5781 requires=[get_exception_utility_code])
5783 #------------------------------------------------------------------------------------
5785 reset_exception_utility_code = UtilityCode(
5787 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5788 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5791 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5792 PyThreadState *tstate = PyThreadState_GET();
5793 *type = tstate->exc_type;
5794 *value = tstate->exc_value;
5795 *tb = tstate->exc_traceback;
5801 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5802 PyObject *tmp_type, *tmp_value, *tmp_tb;
5803 PyThreadState *tstate = PyThreadState_GET();
5804 tmp_type = tstate->exc_type;
5805 tmp_value = tstate->exc_value;
5806 tmp_tb = tstate->exc_traceback;
5807 tstate->exc_type = type;
5808 tstate->exc_value = value;
5809 tstate->exc_traceback = tb;
5810 Py_XDECREF(tmp_type);
5811 Py_XDECREF(tmp_value);
5816 #------------------------------------------------------------------------------------
5818 arg_type_test_utility_code = UtilityCode(
5820 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5821 const char *name, int exact); /*proto*/
5824 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5825 const char *name, int exact)
5828 PyErr_Format(PyExc_SystemError, "Missing type object");
5831 if (none_allowed && obj == Py_None) return 1;
5833 if (Py_TYPE(obj) == type) return 1;
5836 if (PyObject_TypeCheck(obj, type)) return 1;
5838 PyErr_Format(PyExc_TypeError,
5839 "Argument '%s' has incorrect type (expected %s, got %s)",
5840 name, type->tp_name, Py_TYPE(obj)->tp_name);
5845 #------------------------------------------------------------------------------------
5847 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5848 # many or too few positional arguments were found. This handles
5849 # Py_ssize_t formatting correctly.
5851 raise_argtuple_invalid_utility_code = UtilityCode(
5853 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5854 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5857 static void __Pyx_RaiseArgtupleInvalid(
5858 const char* func_name,
5862 Py_ssize_t num_found)
5864 Py_ssize_t num_expected;
5865 const char *number, *more_or_less;
5867 if (num_found < num_min) {
5868 num_expected = num_min;
5869 more_or_less = "at least";
5871 num_expected = num_max;
5872 more_or_less = "at most";
5875 more_or_less = "exactly";
5877 number = (num_expected == 1) ? "" : "s";
5878 PyErr_Format(PyExc_TypeError,
5879 #if PY_VERSION_HEX < 0x02050000
5880 "%s() takes %s %d positional argument%s (%d given)",
5882 "%s() takes %s %zd positional argument%s (%zd given)",
5884 func_name, more_or_less, num_expected, number, num_found);
5888 raise_keyword_required_utility_code = UtilityCode(
5890 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5893 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5894 const char* func_name,
5897 PyErr_Format(PyExc_TypeError,
5898 #if PY_MAJOR_VERSION >= 3
5899 "%s() needs keyword-only argument %U", func_name, kw_name);
5901 "%s() needs keyword-only argument %s", func_name,
5902 PyString_AS_STRING(kw_name));
5907 raise_double_keywords_utility_code = UtilityCode(
5909 static void __Pyx_RaiseDoubleKeywordsError(
5910 const char* func_name, PyObject* kw_name); /*proto*/
5913 static void __Pyx_RaiseDoubleKeywordsError(
5914 const char* func_name,
5917 PyErr_Format(PyExc_TypeError,
5918 #if PY_MAJOR_VERSION >= 3
5919 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5921 "%s() got multiple values for keyword argument '%s'", func_name,
5922 PyString_AS_STRING(kw_name));
5927 #------------------------------------------------------------------------------------
5929 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5930 # were passed to a function, or if any keywords were passed to a
5931 # function that does not accept them.
5933 keyword_string_check_utility_code = UtilityCode(
5935 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5936 const char* function_name, int kw_allowed); /*proto*/
5939 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5941 const char* function_name,
5946 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5947 #if PY_MAJOR_VERSION < 3
5948 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5950 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5952 goto invalid_keyword_type;
5954 if ((!kw_allowed) && unlikely(key))
5955 goto invalid_keyword;
5957 invalid_keyword_type:
5958 PyErr_Format(PyExc_TypeError,
5959 "%s() keywords must be strings", function_name);
5962 PyErr_Format(PyExc_TypeError,
5963 #if PY_MAJOR_VERSION < 3
5964 "%s() got an unexpected keyword argument '%s'",
5965 function_name, PyString_AsString(key));
5967 "%s() got an unexpected keyword argument '%U'",
5968 function_name, key);
5974 #------------------------------------------------------------------------------------
5976 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5977 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5978 # keywords will raise an invalid keyword error.
5980 # Three kinds of errors are checked: 1) non-string keywords, 2)
5981 # unexpected keywords and 3) overlap with positional arguments.
5983 # If num_posargs is greater 0, it denotes the number of positional
5984 # arguments that were passed and that must therefore not appear
5985 # amongst the keywords as well.
5987 # This method does not check for required keyword arguments.
5990 parse_keywords_utility_code = UtilityCode(
5992 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5993 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5994 const char* function_name); /*proto*/
5997 static int __Pyx_ParseOptionalKeywords(
5999 PyObject **argnames[],
6002 Py_ssize_t num_pos_args,
6003 const char* function_name)
6005 PyObject *key = 0, *value = 0;
6008 PyObject*** first_kw_arg = argnames + num_pos_args;
6010 while (PyDict_Next(kwds, &pos, &key, &value)) {
6011 name = first_kw_arg;
6012 while (*name && (**name != key)) name++;
6014 values[name-argnames] = value;
6016 #if PY_MAJOR_VERSION < 3
6017 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6019 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6021 goto invalid_keyword_type;
6023 for (name = first_kw_arg; *name; name++) {
6024 #if PY_MAJOR_VERSION >= 3
6025 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6026 PyUnicode_Compare(**name, key) == 0) break;
6028 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6029 _PyString_Eq(**name, key)) break;
6033 values[name-argnames] = value;
6035 /* unexpected keyword found */
6036 for (name=argnames; name != first_kw_arg; name++) {
6037 if (**name == key) goto arg_passed_twice;
6038 #if PY_MAJOR_VERSION >= 3
6039 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6040 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6042 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6043 _PyString_Eq(**name, key)) goto arg_passed_twice;
6047 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6049 goto invalid_keyword;
6057 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6059 invalid_keyword_type:
6060 PyErr_Format(PyExc_TypeError,
6061 "%s() keywords must be strings", function_name);
6064 PyErr_Format(PyExc_TypeError,
6065 #if PY_MAJOR_VERSION < 3
6066 "%s() got an unexpected keyword argument '%s'",
6067 function_name, PyString_AsString(key));
6069 "%s() got an unexpected keyword argument '%U'",
6070 function_name, key);
6077 #------------------------------------------------------------------------------------
6079 traceback_utility_code = UtilityCode(
6081 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6084 #include "compile.h"
6085 #include "frameobject.h"
6086 #include "traceback.h"
6088 static void __Pyx_AddTraceback(const char *funcname) {
6089 PyObject *py_srcfile = 0;
6090 PyObject *py_funcname = 0;
6091 PyObject *py_globals = 0;
6092 PyCodeObject *py_code = 0;
6093 PyFrameObject *py_frame = 0;
6095 #if PY_MAJOR_VERSION < 3
6096 py_srcfile = PyString_FromString(%(FILENAME)s);
6098 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6100 if (!py_srcfile) goto bad;
6102 #if PY_MAJOR_VERSION < 3
6103 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6105 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6109 #if PY_MAJOR_VERSION < 3
6110 py_funcname = PyString_FromString(funcname);
6112 py_funcname = PyUnicode_FromString(funcname);
6115 if (!py_funcname) goto bad;
6116 py_globals = PyModule_GetDict(%(GLOBALS)s);
6117 if (!py_globals) goto bad;
6118 py_code = PyCode_New(
6119 0, /*int argcount,*/
6120 #if PY_MAJOR_VERSION >= 3
6121 0, /*int kwonlyargcount,*/
6124 0, /*int stacksize,*/
6126 %(EMPTY_BYTES)s, /*PyObject *code,*/
6127 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6128 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6129 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6130 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6131 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6132 py_srcfile, /*PyObject *filename,*/
6133 py_funcname, /*PyObject *name,*/
6134 %(LINENO)s, /*int firstlineno,*/
6135 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6137 if (!py_code) goto bad;
6138 py_frame = PyFrame_New(
6139 PyThreadState_GET(), /*PyThreadState *tstate,*/
6140 py_code, /*PyCodeObject *code,*/
6141 py_globals, /*PyObject *globals,*/
6142 0 /*PyObject *locals*/
6144 if (!py_frame) goto bad;
6145 py_frame->f_lineno = %(LINENO)s;
6146 PyTraceBack_Here(py_frame);
6148 Py_XDECREF(py_srcfile);
6149 Py_XDECREF(py_funcname);
6150 Py_XDECREF(py_code);
6151 Py_XDECREF(py_frame);
6154 'FILENAME': Naming.filename_cname,
6155 'LINENO': Naming.lineno_cname,
6156 'CFILENAME': Naming.cfilenm_cname,
6157 'CLINENO': Naming.clineno_cname,
6158 'GLOBALS': Naming.module_cname,
6159 'EMPTY_TUPLE' : Naming.empty_tuple,
6160 'EMPTY_BYTES' : Naming.empty_bytes,
6163 #------------------------------------------------------------------------------------
6165 unraisable_exception_utility_code = UtilityCode(
6167 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6170 static void __Pyx_WriteUnraisable(const char *name) {
6171 PyObject *old_exc, *old_val, *old_tb;
6173 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6174 #if PY_MAJOR_VERSION < 3
6175 ctx = PyString_FromString(name);
6177 ctx = PyUnicode_FromString(name);
6179 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6181 PyErr_WriteUnraisable(Py_None);
6183 PyErr_WriteUnraisable(ctx);
6188 requires=[restore_exception_utility_code])
6190 #------------------------------------------------------------------------------------
6192 set_vtable_utility_code = UtilityCode(
6194 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6197 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6198 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6199 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6201 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6205 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6215 #------------------------------------------------------------------------------------
6217 get_vtable_utility_code = UtilityCode(
6219 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6222 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6223 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6226 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6227 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6229 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6231 if (!*(void **)vtabptr)
6241 #------------------------------------------------------------------------------------
6243 init_string_tab_utility_code = UtilityCode(
6245 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6248 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6250 #if PY_MAJOR_VERSION < 3
6251 if (t->is_unicode) {
6252 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6253 } else if (t->intern) {
6254 *t->p = PyString_InternFromString(t->s);
6256 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6258 #else /* Python 3+ has unicode identifiers */
6259 if (t->is_unicode | t->is_str) {
6261 *t->p = PyUnicode_InternFromString(t->s);
6262 } else if (t->encoding) {
6263 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6265 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6268 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6279 #------------------------------------------------------------------------------------
6281 force_init_threads_utility_code = UtilityCode(
6283 #ifndef __PYX_FORCE_INIT_THREADS
6284 #if PY_VERSION_HEX < 0x02040200
6285 #define __PYX_FORCE_INIT_THREADS 1
6287 #define __PYX_FORCE_INIT_THREADS 0
6292 #------------------------------------------------------------------------------------
6294 # Note that cPython ignores PyTrace_EXCEPTION,
6295 # but maybe some other profilers don't.
6297 profile_utility_code = UtilityCode(proto="""
6298 #ifndef CYTHON_PROFILE
6299 #define CYTHON_PROFILE 1
6302 #ifndef CYTHON_PROFILE_REUSE_FRAME
6303 #define CYTHON_PROFILE_REUSE_FRAME 0
6308 #include "compile.h"
6309 #include "frameobject.h"
6310 #include "traceback.h"
6312 #if CYTHON_PROFILE_REUSE_FRAME
6313 #define CYTHON_FRAME_MODIFIER static
6314 #define CYTHON_FRAME_DEL
6316 #define CYTHON_FRAME_MODIFIER
6317 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6320 #define __Pyx_TraceDeclarations \\
6321 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6322 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6323 int __Pyx_use_tracing = 0;
6325 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6326 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6327 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6330 #define __Pyx_TraceException() \\
6331 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6332 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6334 PyThreadState_GET()->c_profilefunc( \\
6335 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6336 Py_DECREF(exc_info); \\
6340 #define __Pyx_TraceReturn(result) \\
6341 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6342 PyThreadState_GET()->c_profilefunc( \\
6343 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6344 CYTHON_FRAME_DEL; \\
6347 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6348 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6352 #define __Pyx_TraceDeclarations
6353 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6354 #define __Pyx_TraceException()
6355 #define __Pyx_TraceReturn(result)
6357 #endif /* CYTHON_PROFILE */
6360 "FRAME": Naming.frame_cname,
6361 "FRAME_CODE": Naming.frame_code_cname,
6367 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6368 PyFrameObject** frame,
6369 const char *funcname,
6370 const char *srcfile,
6372 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6373 if (*code == NULL) {
6374 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6375 if (*code == NULL) return 0;
6377 *frame = PyFrame_New(
6378 PyThreadState_GET(), /*PyThreadState *tstate*/
6379 *code, /*PyCodeObject *code*/
6380 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6381 0 /*PyObject *locals*/
6383 if (*frame == NULL) return 0;
6386 (*frame)->f_tstate = PyThreadState_GET();
6388 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6391 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6392 PyObject *py_srcfile = 0;
6393 PyObject *py_funcname = 0;
6394 PyCodeObject *py_code = 0;
6396 #if PY_MAJOR_VERSION < 3
6397 py_funcname = PyString_FromString(funcname);
6398 py_srcfile = PyString_FromString(srcfile);
6400 py_funcname = PyUnicode_FromString(funcname);
6401 py_srcfile = PyUnicode_FromString(srcfile);
6403 if (!py_funcname | !py_srcfile) goto bad;
6405 py_code = PyCode_New(
6406 0, /*int argcount,*/
6407 #if PY_MAJOR_VERSION >= 3
6408 0, /*int kwonlyargcount,*/
6411 0, /*int stacksize,*/
6413 %(EMPTY_BYTES)s, /*PyObject *code,*/
6414 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6415 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6416 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6417 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6418 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6419 py_srcfile, /*PyObject *filename,*/
6420 py_funcname, /*PyObject *name,*/
6421 firstlineno, /*int firstlineno,*/
6422 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6426 Py_XDECREF(py_srcfile);
6427 Py_XDECREF(py_funcname);
6432 #endif /* CYTHON_PROFILE */
6434 'EMPTY_TUPLE' : Naming.empty_tuple,
6435 'EMPTY_BYTES' : Naming.empty_bytes,
6436 "MODULE": Naming.module_cname,