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, GeneratorLocalScope, \
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 (%d) -- 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 (%d)>" % (self.__class__.__name__, id(self))
261 res = "<%s (%d)\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 arg_node in self.args:
538 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
539 name = name_declarator.name
540 if name_declarator.cname:
542 "Function argument cannot have C name specification")
543 # Turn *[] argument into **
545 type = PyrexTypes.c_ptr_type(type.base_type)
546 # Catch attempted C-style func(void) decl
548 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
549 func_type_args.append(
550 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
552 self.optional_arg_count += 1
553 elif self.optional_arg_count:
554 error(self.pos, "Non-default argument follows default argument")
556 if self.optional_arg_count:
557 scope = StructOrUnionScope()
558 arg_count_member = '%sn' % Naming.pyrex_prefix
559 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
560 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
561 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
562 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
563 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
568 cname = struct_cname)
569 self.op_args_struct.defined_in_pxd = 1
570 self.op_args_struct.used = 1
574 if self.exception_check == '+':
575 env.add_include_file('stdexcept')
576 if return_type.is_pyobject \
577 and (self.exception_value or self.exception_check) \
578 and self.exception_check != '+':
580 "Exception clause not allowed for function returning Python object")
582 if self.exception_value:
583 self.exception_value.analyse_const_expression(env)
584 if self.exception_check == '+':
585 self.exception_value.analyse_types(env)
586 exc_val_type = self.exception_value.type
587 if not exc_val_type.is_error and \
588 not exc_val_type.is_pyobject and \
589 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
590 error(self.exception_value.pos,
591 "Exception value must be a Python exception or cdef function with no arguments.")
592 exc_val = self.exception_value
594 if self.exception_value.analyse_const_expression(env):
595 exc_val = self.exception_value.get_constant_c_result_code()
597 raise InternalError("get_constant_c_result_code not implemented for %s" %
598 self.exception_value.__class__.__name__)
599 if not return_type.assignable_from(self.exception_value.type):
600 error(self.exception_value.pos,
601 "Exception value incompatible with function return type")
602 exc_check = self.exception_check
603 if return_type.is_array:
605 "Function cannot return an array")
606 if return_type.is_cfunction:
608 "Function cannot return a function")
609 func_type = PyrexTypes.CFuncType(
610 return_type, func_type_args, self.has_varargs,
611 optional_arg_count = self.optional_arg_count,
612 exception_value = exc_val, exception_check = exc_check,
613 calling_convention = self.base.calling_convention,
614 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
615 if self.optional_arg_count:
616 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
617 callspec = env.directives['callspec']
619 current = func_type.calling_convention
620 if current and current != callspec:
621 error(self.pos, "cannot have both '%s' and '%s' "
622 "calling conventions" % (current, callspec))
623 func_type.calling_convention = callspec
624 return self.base.analyse(func_type, env)
627 class CArgDeclNode(Node):
628 # Item in a function declaration argument list.
630 # base_type CBaseTypeNode
631 # declarator CDeclaratorNode
632 # not_none boolean Tagged with 'not None'
633 # default ExprNode or None
634 # default_value PyObjectConst constant for default value
635 # is_self_arg boolean Is the "self" arg of an extension type method
636 # is_type_arg boolean Is the "class" arg of an extension type classmethod
637 # is_kw_only boolean Is a keyword-only argument
639 child_attrs = ["base_type", "declarator", "default"]
645 name_declarator = None
648 def analyse(self, env, nonempty = 0):
649 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
650 if self.type is None:
651 # The parser may missinterpret names as types...
653 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
655 self.declarator.name = self.base_type.name
656 self.base_type.name = None
657 self.base_type.is_basic_c_type = False
660 could_be_name = False
661 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
662 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
663 self.declarator.name = self.base_type.arg_name
664 # The parser is unable to resolve the ambiguity of [] as part of the
665 # type (e.g. in buffers) or empty declarator (as with arrays).
666 # This is only arises for empty multi-dimensional arrays.
667 if (base_type.is_array
668 and isinstance(self.base_type, TemplatedTypeNode)
669 and isinstance(self.declarator, CArrayDeclaratorNode)):
670 declarator = self.declarator
671 while isinstance(declarator.base, CArrayDeclaratorNode):
672 declarator = declarator.base
673 declarator.base = self.base_type.array_declarator
674 base_type = base_type.base_type
675 return self.declarator.analyse(base_type, env, nonempty = nonempty)
677 return self.name_declarator, self.type
679 def calculate_default_value_code(self, code):
680 if self.default_value is None:
682 if self.default.is_literal:
683 # will not output any code, just assign the result_code
684 self.default.generate_evaluation_code(code)
685 return self.type.cast_code(self.default.result())
686 self.default_value = code.get_argument_default_const(self.type)
687 return self.default_value
689 def annotate(self, code):
691 self.default.annotate(code)
694 class CBaseTypeNode(Node):
695 # Abstract base class for C base type nodes.
697 # Processing during analyse_declarations phase:
704 def analyse_as_type(self, env):
705 return self.analyse(env)
707 class CAnalysedBaseTypeNode(Node):
712 def analyse(self, env, could_be_name = False):
715 class CSimpleBaseTypeNode(CBaseTypeNode):
717 # module_path [string] Qualifying name components
718 # is_basic_c_type boolean
722 # is_self_arg boolean Is self argument of C method
723 # ##is_type_arg boolean Is type argument of class method
726 arg_name = None # in case the argument name was interpreted as a type
728 def analyse(self, env, could_be_name = False):
729 # Return type descriptor.
730 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
732 if self.is_basic_c_type:
733 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
735 error(self.pos, "Unrecognised type modifier combination")
736 elif self.name == "object" and not self.module_path:
737 type = py_object_type
738 elif self.name is None:
739 if self.is_self_arg and env.is_c_class_scope:
740 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
741 type = env.parent_type
742 ## elif self.is_type_arg and env.is_c_class_scope:
743 ## type = Builtin.type_type
745 type = py_object_type
748 scope = env.find_imported_module(self.module_path, self.pos)
752 if scope.is_c_class_scope:
753 scope = scope.global_scope()
754 entry = scope.lookup(self.name)
755 if entry and entry.is_type:
758 if self.is_self_arg and env.is_c_class_scope:
759 type = env.parent_type
760 ## elif self.is_type_arg and env.is_c_class_scope:
761 ## type = Builtin.type_type
763 type = py_object_type
764 self.arg_name = self.name
767 if not self.name in self.templates:
768 error(self.pos, "'%s' is not a type identifier" % self.name)
769 type = PyrexTypes.TemplatePlaceholderType(self.name)
771 error(self.pos, "'%s' is not a type identifier" % self.name)
773 if not type.is_numeric or type.is_complex:
774 error(self.pos, "can only complexify c numeric types")
775 type = PyrexTypes.CComplexType(type)
776 type.create_declaration_utility_code(env)
780 return PyrexTypes.error_type
782 class CNestedBaseTypeNode(CBaseTypeNode):
783 # For C++ classes that live inside other C++ classes.
786 # base_type CBaseTypeNode
788 child_attrs = ['base_type']
790 def analyse(self, env, could_be_name = None):
791 base_type = self.base_type.analyse(env)
792 if base_type is PyrexTypes.error_type:
793 return PyrexTypes.error_type
794 if not base_type.is_cpp_class:
795 error(self.pos, "'%s' is not a valid type scope" % base_type)
796 return PyrexTypes.error_type
797 type_entry = base_type.scope.lookup_here(self.name)
798 if not type_entry or not type_entry.is_type:
799 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
800 return PyrexTypes.error_type
801 return type_entry.type
803 class TemplatedTypeNode(CBaseTypeNode):
805 # positional_args [ExprNode] List of positional arguments
806 # keyword_args DictNode Keyword arguments
807 # base_type_node CBaseTypeNode
810 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
813 child_attrs = ["base_type_node", "positional_args",
814 "keyword_args", "dtype_node"]
820 def analyse(self, env, could_be_name = False, base_type = None):
821 if base_type is None:
822 base_type = self.base_type_node.analyse(env)
823 if base_type.is_error: return base_type
825 if base_type.is_cpp_class:
827 if self.keyword_args and self.keyword_args.key_value_pairs:
828 error(self.pos, "c++ templates cannot take keyword arguments");
829 self.type = PyrexTypes.error_type
832 for template_node in self.positional_args:
833 template_types.append(template_node.analyse_as_type(env))
834 self.type = base_type.specialize_here(self.pos, template_types)
836 elif base_type.is_pyobject:
840 options = Buffer.analyse_buffer_options(
843 self.positional_args,
845 base_type.buffer_defaults)
847 if sys.version_info[0] < 3:
848 # Py 2.x enforces byte strings as keyword arguments ...
849 options = dict([ (name.encode('ASCII'), value)
850 for name, value in options.iteritems() ])
852 self.type = PyrexTypes.BufferType(base_type, **options)
856 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
857 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
858 error(self.pos, "invalid array declaration")
859 self.type = PyrexTypes.error_type
861 # It would be nice to merge this class with CArrayDeclaratorNode,
862 # but arrays are part of the declaration, not the type...
863 if not self.positional_args:
866 dimension = self.positional_args[0]
867 self.array_declarator = CArrayDeclaratorNode(self.pos,
868 base = empty_declarator,
869 dimension = dimension)
870 self.type = self.array_declarator.analyse(base_type, env)[1]
874 class CComplexBaseTypeNode(CBaseTypeNode):
875 # base_type CBaseTypeNode
876 # declarator CDeclaratorNode
878 child_attrs = ["base_type", "declarator"]
880 def analyse(self, env, could_be_name = False):
881 base = self.base_type.analyse(env, could_be_name)
882 _, type = self.declarator.analyse(base, env)
886 class CVarDefNode(StatNode):
887 # C variable definition or forward/extern function declaration.
889 # visibility 'private' or 'public' or 'extern'
890 # base_type CBaseTypeNode
891 # declarators [CDeclaratorNode]
894 # need_properties [entry]
896 # decorators [cython.locals(...)] or None
897 # directive_locals { string : NameNode } locals defined by cython.locals(...)
899 child_attrs = ["base_type", "declarators"]
903 directive_locals = {}
905 def analyse_declarations(self, env, dest_scope = None):
908 self.dest_scope = dest_scope
909 base_type = self.base_type.analyse(env)
911 # If the field is an external typedef, we cannot be sure about the type,
912 # so do conversion ourself rather than rely on the CPython mechanism (through
913 # a property; made in AnalyseDeclarationsTransform).
914 if (dest_scope.is_c_class_scope
915 and self.visibility == 'public'
916 and base_type.is_pyobject
917 and (base_type.is_builtin_type or base_type.is_extension_type)):
918 self.need_properties = []
920 visibility = 'private'
922 need_property = False
923 visibility = self.visibility
925 for declarator in self.declarators:
926 name_declarator, type = declarator.analyse(base_type, env)
927 if not type.is_complete():
928 if not (self.visibility == 'extern' and type.is_array):
929 error(declarator.pos,
930 "Variable type '%s' is incomplete" % type)
931 if self.visibility == 'extern' and type.is_pyobject:
932 error(declarator.pos,
933 "Python object cannot be declared extern")
934 name = name_declarator.name
935 cname = name_declarator.cname
937 error(declarator.pos, "Missing name in declaration.")
939 if type.is_cfunction:
940 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
941 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
943 if entry is not None:
944 entry.directive_locals = self.directive_locals
946 if self.directive_locals:
947 s.error("Decorators can only be followed by functions")
948 if self.in_pxd and self.visibility != 'extern':
950 "Only 'extern' C variable declaration allowed in .pxd file")
951 entry = dest_scope.declare_var(name, type, declarator.pos,
952 cname = cname, visibility = visibility, is_cdef = 1)
954 self.need_properties.append(entry)
955 entry.needs_property = 1
958 class CStructOrUnionDefNode(StatNode):
960 # cname string or None
961 # kind "struct" or "union"
962 # typedef_flag boolean
963 # visibility "public" or "private"
965 # attributes [CVarDefNode] or None
969 child_attrs = ["attributes"]
971 def analyse_declarations(self, env):
973 if self.visibility == 'extern' and self.packed:
974 error(self.pos, "Cannot declare extern struct as 'packed'")
975 if self.attributes is not None:
976 scope = StructOrUnionScope(self.name)
977 self.entry = env.declare_struct_or_union(
978 self.name, self.kind, scope, self.typedef_flag, self.pos,
979 self.cname, visibility = self.visibility, packed = self.packed)
980 if self.attributes is not None:
981 if self.in_pxd and not env.in_cinclude:
982 self.entry.defined_in_pxd = 1
983 for attr in self.attributes:
984 attr.analyse_declarations(env, scope)
985 if self.visibility != 'extern':
986 need_typedef_indirection = False
987 for attr in scope.var_entries:
990 type = type.base_type
991 if type == self.entry.type:
992 error(attr.pos, "Struct cannot contain itself as a member.")
993 if self.typedef_flag:
995 type = type.base_type
996 if type == self.entry.type:
997 need_typedef_indirection = True
998 if need_typedef_indirection:
999 # C can't handle typedef structs that refer to themselves.
1000 struct_entry = self.entry
1001 self.entry = env.declare_typedef(
1002 self.name, struct_entry.type, self.pos,
1003 cname = self.cname, visibility='ignore')
1004 struct_entry.type.typedef_flag = False
1005 # FIXME: this might be considered a hack ;-)
1006 struct_entry.cname = struct_entry.type.cname = \
1007 '_' + self.entry.type.typedef_cname
1009 def analyse_expressions(self, env):
1012 def generate_execution_code(self, code):
1016 class CppClassNode(CStructOrUnionDefNode):
1019 # cname string or None
1020 # visibility "extern"
1022 # attributes [CVarDefNode] or None
1024 # base_classes [string]
1025 # templates [string] or None
1027 def analyse_declarations(self, env):
1029 if len(self.attributes) != 0:
1030 scope = CppClassScope(self.name, env)
1032 self.attributes = None
1033 base_class_types = []
1034 for base_class_name in self.base_classes:
1035 base_class_entry = env.lookup(base_class_name)
1036 if base_class_entry is None:
1037 error(self.pos, "'%s' not found" % base_class_name)
1038 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1039 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1041 base_class_types.append(base_class_entry.type)
1042 if self.templates is None:
1043 template_types = None
1045 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1046 self.entry = env.declare_cpp_class(
1047 self.name, scope, self.pos,
1048 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1049 self.entry.is_cpp_class = 1
1050 if self.attributes is not None:
1051 if self.in_pxd and not env.in_cinclude:
1052 self.entry.defined_in_pxd = 1
1053 for attr in self.attributes:
1054 attr.analyse_declarations(scope)
1056 class CEnumDefNode(StatNode):
1057 # name string or None
1058 # cname string or None
1059 # items [CEnumDefItemNode]
1060 # typedef_flag boolean
1061 # visibility "public" or "private"
1065 child_attrs = ["items"]
1067 def analyse_declarations(self, env):
1068 self.entry = env.declare_enum(self.name, self.pos,
1069 cname = self.cname, typedef_flag = self.typedef_flag,
1070 visibility = self.visibility)
1071 if self.items is not None:
1072 if self.in_pxd and not env.in_cinclude:
1073 self.entry.defined_in_pxd = 1
1074 for item in self.items:
1075 item.analyse_declarations(env, self.entry)
1077 def analyse_expressions(self, env):
1080 def generate_execution_code(self, code):
1081 if self.visibility == 'public':
1082 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1083 for item in self.entry.enum_values:
1084 code.putln("%s = PyInt_FromLong(%s); %s" % (
1087 code.error_goto_if_null(temp, item.pos)))
1088 code.put_gotref(temp)
1089 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1090 Naming.module_cname,
1093 code.error_goto(item.pos)))
1094 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1095 code.funcstate.release_temp(temp)
1098 class CEnumDefItemNode(StatNode):
1100 # cname string or None
1101 # value ExprNode or None
1103 child_attrs = ["value"]
1105 def analyse_declarations(self, env, enum_entry):
1107 self.value.analyse_const_expression(env)
1108 if not self.value.type.is_int:
1109 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1110 self.value.analyse_const_expression(env)
1111 entry = env.declare_const(self.name, enum_entry.type,
1112 self.value, self.pos, cname = self.cname,
1113 visibility = enum_entry.visibility)
1114 enum_entry.enum_values.append(entry)
1117 class CTypeDefNode(StatNode):
1118 # base_type CBaseTypeNode
1119 # declarator CDeclaratorNode
1120 # visibility "public" or "private"
1123 child_attrs = ["base_type", "declarator"]
1125 def analyse_declarations(self, env):
1126 base = self.base_type.analyse(env)
1127 name_declarator, type = self.declarator.analyse(base, env)
1128 name = name_declarator.name
1129 cname = name_declarator.cname
1130 entry = env.declare_typedef(name, type, self.pos,
1131 cname = cname, visibility = self.visibility)
1132 if self.in_pxd and not env.in_cinclude:
1133 entry.defined_in_pxd = 1
1135 def analyse_expressions(self, env):
1137 def generate_execution_code(self, code):
1141 class FuncDefNode(StatNode, BlockNode):
1142 # Base class for function definition nodes.
1144 # return_type PyrexType
1145 # #filename string C name of filename string const
1146 # entry Symtab.Entry
1147 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1148 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1152 needs_closure = False
1155 def analyse_default_values(self, env):
1156 genv = env.global_scope()
1158 for arg in self.args:
1162 arg.default.analyse_types(env)
1163 arg.default = arg.default.coerce_to(arg.type, genv)
1166 "This argument cannot have a default value")
1171 error(arg.pos, "Non-default argument following default argument")
1173 def need_gil_acquisition(self, lenv):
1176 def create_local_scope(self, env):
1178 while genv.is_py_class_scope or genv.is_c_class_scope:
1179 genv = env.outer_scope
1180 if self.needs_closure:
1181 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv, parent_scope = env)
1183 lenv = LocalScope(name = self.entry.name, outer_scope = genv, parent_scope = env)
1184 lenv.return_type = self.return_type
1185 type = self.entry.type
1186 if type.is_cfunction:
1187 lenv.nogil = type.nogil and not type.with_gil
1188 self.local_scope = lenv
1189 lenv.directives = env.directives
1192 def generate_function_definitions(self, env, code):
1195 lenv = self.local_scope
1197 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1198 self.entry.scope.is_c_class_scope)
1200 profile = code.globalstate.directives['profile']
1203 error(self.pos, "Cannot profile nogil function.")
1204 code.globalstate.use_utility_code(profile_utility_code)
1206 # Generate C code for header and body of function
1207 code.enter_cfunc_scope()
1208 code.return_from_error_cleanup_label = code.new_label()
1210 # ----- Top-level constants used by this function
1211 code.mark_pos(self.pos)
1212 self.generate_cached_builtins_decls(lenv, code)
1213 # ----- Function header
1216 self.py_func.generate_function_header(code,
1217 with_pymethdef = env.is_py_class_scope,
1219 self.generate_function_header(code,
1220 with_pymethdef = env.is_py_class_scope)
1221 # ----- Local variable declarations
1222 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1223 self.generate_argument_declarations(lenv, code)
1224 if self.needs_closure:
1225 code.putln("/* TODO: declare and create scope object */")
1226 code.put_var_declarations(lenv.var_entries)
1228 if not self.return_type.is_void:
1229 if self.return_type.is_pyobject:
1233 (self.return_type.declaration_code(
1234 Naming.retval_cname),
1236 tempvardecl_code = code.insertion_point()
1237 self.generate_keyword_list(code)
1239 code.put_trace_declarations()
1240 # ----- Extern library function declarations
1241 lenv.generate_library_function_declarations(code)
1242 # ----- GIL acquisition
1243 acquire_gil = self.acquire_gil
1245 env.use_utility_code(force_init_threads_utility_code)
1246 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1247 # ----- Automatic lead-ins for certain special functions
1249 code.put_setup_refcount_context(self.entry.name)
1251 code.put_trace_call(self.entry.name, self.pos)
1252 if is_getbuffer_slot:
1253 self.getbuffer_init(code)
1254 # ----- Fetch arguments
1255 self.generate_argument_parsing_code(env, code)
1256 # If an argument is assigned to in the body, we must
1257 # incref it to properly keep track of refcounts.
1258 for entry in lenv.arg_entries:
1259 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1260 code.put_var_incref(entry)
1261 # ----- Initialise local variables
1262 for entry in lenv.var_entries:
1263 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1264 code.put_init_var_to_py_none(entry)
1265 # ----- Initialise local buffer auxiliary variables
1266 for entry in lenv.var_entries + lenv.arg_entries:
1267 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1268 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1269 # ----- Check and convert arguments
1270 self.generate_argument_type_tests(code)
1271 # ----- Acquire buffer arguments
1272 for entry in lenv.arg_entries:
1273 if entry.type.is_buffer:
1274 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1275 # ----- Function body
1276 self.body.generate_execution_code(code)
1277 # ----- Default return value
1279 if self.return_type.is_pyobject:
1280 #if self.return_type.is_extension_type:
1281 # lhs = "(PyObject *)%s" % Naming.retval_cname
1283 lhs = Naming.retval_cname
1284 code.put_init_to_py_none(lhs, self.return_type)
1286 val = self.return_type.default_value
1288 code.putln("%s = %s;" % (Naming.retval_cname, val))
1289 # ----- Error cleanup
1290 if code.error_label in code.labels_used:
1291 code.put_goto(code.return_label)
1292 code.put_label(code.error_label)
1293 for cname, type in code.funcstate.all_managed_temps():
1294 code.put_xdecref(cname, type)
1296 # Clean up buffers -- this calls a Python function
1297 # so need to save and restore error state
1298 buffers_present = len(lenv.buffer_entries) > 0
1300 code.globalstate.use_utility_code(restore_exception_utility_code)
1301 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1302 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1303 for entry in lenv.buffer_entries:
1304 Buffer.put_release_buffer_code(code, entry)
1305 #code.putln("%s = 0;" % entry.cname)
1306 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1308 err_val = self.error_value()
1309 exc_check = self.caller_will_check_exceptions()
1310 if err_val is not None or exc_check:
1311 # TODO: Fix exception tracing (though currently unused by cProfile).
1312 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1313 # code.put_trace_exception()
1314 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1316 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1317 % self.entry.qualified_name, 0)
1319 '__Pyx_WriteUnraisable("%s");' %
1320 self.entry.qualified_name)
1321 env.use_utility_code(unraisable_exception_utility_code)
1322 env.use_utility_code(restore_exception_utility_code)
1323 default_retval = self.return_type.default_value
1324 if err_val is None and default_retval:
1325 err_val = default_retval
1326 if err_val is not None:
1329 Naming.retval_cname,
1332 if is_getbuffer_slot:
1333 self.getbuffer_error_cleanup(code)
1335 # If we are using the non-error cleanup section we should
1336 # jump past it if we have an error. The if-test below determine
1337 # whether this section is used.
1338 if buffers_present or is_getbuffer_slot:
1339 code.put_goto(code.return_from_error_cleanup_label)
1342 # ----- Non-error return cleanup
1343 code.put_label(code.return_label)
1344 for entry in lenv.buffer_entries:
1346 Buffer.put_release_buffer_code(code, entry)
1347 if is_getbuffer_slot:
1348 self.getbuffer_normal_cleanup(code)
1349 # ----- Return cleanup for both error and no-error return
1350 code.put_label(code.return_from_error_cleanup_label)
1351 if not Options.init_local_none:
1352 for entry in lenv.var_entries:
1353 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1354 entry.xdecref_cleanup = 1
1355 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1356 # Decref any increfed args
1357 for entry in lenv.arg_entries:
1358 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1359 code.put_var_decref(entry)
1361 # code.putln("/* TODO: decref scope object */")
1363 # This code is duplicated in ModuleNode.generate_module_init_func
1365 default_retval = self.return_type.default_value
1366 err_val = self.error_value()
1367 if err_val is None and default_retval:
1368 err_val = default_retval
1369 if self.return_type.is_pyobject:
1370 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1372 if self.entry.is_special and self.entry.name == "__hash__":
1373 # Returning -1 for __hash__ is supposed to signal an error
1374 # We do as Python instances and coerce -1 into -2.
1375 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1376 Naming.retval_cname, Naming.retval_cname))
1379 if self.return_type.is_pyobject:
1380 code.put_trace_return(Naming.retval_cname)
1382 code.put_trace_return("Py_None")
1384 code.put_finish_refcount_context()
1387 code.putln("PyGILState_Release(_save);")
1389 if not self.return_type.is_void:
1390 code.putln("return %s;" % Naming.retval_cname)
1393 # ----- Go back and insert temp variable declarations
1394 tempvardecl_code.put_temp_declarations(code.funcstate)
1395 # ----- Python version
1396 code.exit_cfunc_scope()
1398 self.py_func.generate_function_definitions(env, code)
1399 self.generate_wrapper_functions(code)
1401 def declare_argument(self, env, arg):
1402 if arg.type.is_void:
1403 error(arg.pos, "Invalid use of 'void'")
1404 elif not arg.type.is_complete() and not arg.type.is_array:
1406 "Argument type '%s' is incomplete" % arg.type)
1407 return env.declare_arg(arg.name, arg.type, arg.pos)
1409 def generate_wrapper_functions(self, code):
1412 def generate_execution_code(self, code):
1413 # Evaluate and store argument default values
1414 for arg in self.args:
1415 default = arg.default
1417 if not default.is_literal:
1418 default.generate_evaluation_code(code)
1419 default.make_owned_reference(code)
1420 result = default.result_as(arg.type)
1423 arg.calculate_default_value_code(code),
1425 if arg.type.is_pyobject:
1426 code.put_giveref(default.result())
1427 default.generate_post_assignment_code(code)
1428 default.free_temps(code)
1429 # For Python class methods, create and store function object
1431 self.assmt.generate_execution_code(code)
1434 # Special code for the __getbuffer__ function
1436 def getbuffer_init(self, code):
1437 info = self.local_scope.arg_entries[1].cname
1438 # Python 3.0 betas have a bug in memoryview which makes it call
1439 # getbuffer with a NULL parameter. For now we work around this;
1440 # the following line should be removed when this bug is fixed.
1441 code.putln("if (%s == NULL) return 0;" % info)
1442 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1443 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1445 def getbuffer_error_cleanup(self, code):
1446 info = self.local_scope.arg_entries[1].cname
1447 code.put_gotref("%s->obj" % info)
1448 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1451 def getbuffer_normal_cleanup(self, code):
1452 info = self.local_scope.arg_entries[1].cname
1453 code.putln("if (%s->obj == Py_None) {" % info)
1454 code.put_gotref("Py_None")
1455 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1458 class CFuncDefNode(FuncDefNode):
1459 # C function definition.
1461 # modifiers ['inline']
1462 # visibility 'private' or 'public' or 'extern'
1463 # base_type CBaseTypeNode
1464 # declarator CDeclaratorNode
1467 # decorators [DecoratorNode] list of decorators
1469 # with_gil boolean Acquire GIL around body
1471 # py_func wrapper for calling from Python
1472 # overridable whether or not this is a cpdef function
1473 # inline_in_pxd whether this is an inline function in a pxd file
1475 child_attrs = ["base_type", "declarator", "body", "py_func"]
1477 inline_in_pxd = False
1479 directive_locals = {}
1481 def unqualified_name(self):
1482 return self.entry.name
1484 def analyse_declarations(self, env):
1485 self.directive_locals.update(env.directives['locals'])
1486 base_type = self.base_type.analyse(env)
1487 # The 2 here is because we need both function and argument names.
1488 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1489 if not type.is_cfunction:
1491 "Suite attached to non-function declaration")
1492 # Remember the actual type according to the function header
1493 # written here, because the type in the symbol table entry
1494 # may be different if we're overriding a C method inherited
1495 # from the base type of an extension type.
1497 type.is_overridable = self.overridable
1498 declarator = self.declarator
1499 while not hasattr(declarator, 'args'):
1500 declarator = declarator.base
1501 self.args = declarator.args
1502 for formal_arg, type_arg in zip(self.args, type.args):
1503 formal_arg.type = type_arg.type
1504 formal_arg.name = type_arg.name
1505 formal_arg.cname = type_arg.cname
1506 name = name_declarator.name
1507 cname = name_declarator.cname
1508 self.entry = env.declare_cfunction(
1509 name, type, self.pos,
1510 cname = cname, visibility = self.visibility,
1511 defining = self.body is not None,
1512 api = self.api, modifiers = self.modifiers)
1513 self.entry.inline_func_in_pxd = self.inline_in_pxd
1514 self.return_type = type.return_type
1516 if self.overridable and not env.is_module_scope:
1517 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1518 # An error will be produced in the cdef function
1519 self.overridable = False
1521 if self.overridable:
1523 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1524 self.py_func = DefNode(pos = self.pos,
1525 name = self.entry.name,
1528 starstar_arg = None,
1530 body = py_func_body,
1532 self.py_func.is_module_scope = env.is_module_scope
1533 self.py_func.analyse_declarations(env)
1534 self.entry.as_variable = self.py_func.entry
1535 # Reset scope entry the above cfunction
1536 env.entries[name] = self.entry
1537 if not env.is_module_scope or Options.lookup_module_cpdef:
1538 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1539 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1540 self.create_local_scope(env)
1542 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1544 args = self.type.args
1545 if omit_optional_args:
1546 args = args[:len(args) - self.type.optional_arg_count]
1547 arg_names = [arg.name for arg in args]
1549 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1551 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1552 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1553 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1554 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)
1555 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1557 def declare_arguments(self, env):
1558 for arg in self.type.args:
1560 error(arg.pos, "Missing argument name")
1561 self.declare_argument(env, arg)
1563 def need_gil_acquisition(self, lenv):
1564 return self.type.with_gil
1566 def nogil_check(self, env):
1568 with_gil = type.with_gil
1569 if type.nogil and not with_gil:
1570 if type.return_type.is_pyobject:
1572 "Function with Python return type cannot be declared nogil")
1573 for entry in self.local_scope.var_entries:
1574 if entry.type.is_pyobject:
1575 error(self.pos, "Function declared nogil has Python locals or temporaries")
1577 def analyse_expressions(self, env):
1578 self.local_scope.directives = env.directives
1579 if self.py_func is not None:
1580 # this will also analyse the default values
1581 self.py_func.analyse_expressions(env)
1583 self.analyse_default_values(env)
1584 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1586 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1589 visibility = self.entry.visibility
1590 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1591 arg_decls.append(arg.declaration_code())
1592 if with_dispatch and self.overridable:
1593 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1594 if type.optional_arg_count and with_opt_args:
1595 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1596 if type.has_varargs:
1597 arg_decls.append("...")
1599 arg_decls = ["void"]
1601 cname = self.entry.func_cname
1602 entity = type.function_header_code(cname, ', '.join(arg_decls))
1603 if visibility == 'public':
1604 dll_linkage = "DL_EXPORT"
1607 header = self.return_type.declaration_code(entity,
1608 dll_linkage = dll_linkage)
1609 if visibility == 'extern':
1610 storage_class = "%s " % Naming.extern_c_macro
1611 elif visibility == 'public':
1614 storage_class = "static "
1615 if 'inline' in self.modifiers:
1616 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1617 code.putln("%s%s %s {" % (
1619 ' '.join(self.modifiers).upper(), # macro forms
1622 def generate_argument_declarations(self, env, code):
1623 for arg in self.args:
1625 result = arg.calculate_default_value_code(code)
1626 code.putln('%s = %s;' % (
1627 arg.type.declaration_code(arg.cname), result))
1629 def generate_keyword_list(self, code):
1632 def generate_argument_parsing_code(self, env, code):
1634 if self.type.optional_arg_count:
1635 code.putln('if (%s) {' % Naming.optional_args_cname)
1636 for arg in self.args:
1638 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1639 declarator = arg.declarator
1640 while not hasattr(declarator, 'name'):
1641 declarator = declarator.base
1642 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1644 for _ in range(self.type.optional_arg_count):
1648 def generate_argument_conversion_code(self, code):
1651 def generate_argument_type_tests(self, code):
1652 # Generate type tests for args whose type in a parent
1653 # class is a supertype of the declared type.
1654 for arg in self.type.args:
1655 if arg.needs_type_test:
1656 self.generate_arg_type_test(arg, code)
1658 def generate_arg_type_test(self, arg, code):
1659 # Generate type test for one argument.
1660 if arg.type.typeobj_is_available():
1661 typeptr_cname = arg.type.typeptr_cname
1662 arg_code = "((PyObject *)%s)" % arg.cname
1664 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1669 type.is_builtin_type,
1670 code.error_goto(arg.pos)))
1672 error(arg.pos, "Cannot test type of extern C class "
1673 "without type object name specification")
1675 def error_value(self):
1676 if self.return_type.is_pyobject:
1680 return self.entry.type.exception_value
1682 def caller_will_check_exceptions(self):
1683 return self.entry.type.exception_check
1685 def generate_wrapper_functions(self, code):
1686 # If the C signature of a function has changed, we need to generate
1687 # wrappers to put in the slots here.
1690 func_type = entry.type
1691 while entry.prev_entry is not None:
1693 entry = entry.prev_entry
1694 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1696 self.generate_function_header(code,
1698 with_dispatch = entry.type.is_overridable,
1699 with_opt_args = entry.type.optional_arg_count,
1700 cname = entry.func_cname)
1701 if not self.return_type.is_void:
1703 args = self.type.args
1704 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1705 if entry.type.is_overridable:
1706 arglist.append(Naming.skip_dispatch_cname)
1707 elif func_type.is_overridable:
1709 if entry.type.optional_arg_count:
1710 arglist.append(Naming.optional_args_cname)
1711 elif func_type.optional_arg_count:
1712 arglist.append('NULL')
1713 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1717 class PyArgDeclNode(Node):
1718 # Argument which must be a Python object (used
1719 # for * and ** arguments).
1722 # entry Symtab.Entry
1726 class DecoratorNode(Node):
1729 # decorator NameNode or CallNode or AttributeNode
1730 child_attrs = ['decorator']
1733 class DefNode(FuncDefNode):
1734 # A Python function definition.
1736 # name string the Python name of the function
1737 # decorators [DecoratorNode] list of decorators
1738 # args [CArgDeclNode] formal arguments
1739 # star_arg PyArgDeclNode or None * argument
1740 # starstar_arg PyArgDeclNode or None ** argument
1741 # doc EncodedString or None
1744 # The following subnode is constructed internally
1745 # when the def statement is inside a Python class definition.
1747 # assmt AssignmentNode Function construction/assignment
1749 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1753 num_required_kw_args = 0
1754 reqd_kw_flags_cname = "0"
1761 def __init__(self, pos, **kwds):
1762 FuncDefNode.__init__(self, pos, **kwds)
1764 for arg in self.args:
1771 self.num_kwonly_args = k
1772 self.num_required_kw_args = rk
1773 self.num_required_args = r
1775 def as_cfunction(self, cfunc=None, scope=None):
1777 error(self.star_arg.pos, "cdef function cannot have star argument")
1778 if self.starstar_arg:
1779 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1782 for formal_arg in self.args:
1783 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1784 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1786 type = py_object_type,
1787 pos = formal_arg.pos))
1788 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1790 has_varargs = False,
1791 exception_value = None,
1792 exception_check = False,
1795 is_overridable = True)
1796 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1798 cfunc_type = cfunc.type
1799 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1800 error(self.pos, "wrong number of arguments")
1801 error(cfunc.pos, "previous declaration here")
1802 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1803 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1804 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1805 formal_arg.type = type_arg.type
1806 formal_arg.name_declarator = name_declarator
1808 if cfunc_type.exception_value is None:
1809 exception_value = None
1811 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1812 declarator = CFuncDeclaratorNode(self.pos,
1813 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1815 has_varargs = False,
1816 exception_check = cfunc_type.exception_check,
1817 exception_value = exception_value,
1818 with_gil = cfunc_type.with_gil,
1819 nogil = cfunc_type.nogil)
1820 return CFuncDefNode(self.pos,
1822 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1823 declarator = declarator,
1826 overridable = cfunc_type.is_overridable,
1828 with_gil = cfunc_type.with_gil,
1829 nogil = cfunc_type.nogil,
1830 visibility = 'private',
1832 directive_locals = getattr(cfunc, 'directive_locals', {}))
1834 def analyse_declarations(self, env):
1835 self.is_classmethod = self.is_staticmethod = False
1837 for decorator in self.decorators:
1838 func = decorator.decorator
1840 self.is_classmethod |= func.name == 'classmethod'
1841 self.is_staticmethod |= func.name == 'staticmethod'
1843 if self.is_classmethod and env.lookup_here('classmethod'):
1844 # classmethod() was overridden - not much we can do here ...
1845 self.is_classmethod = False
1846 if self.is_staticmethod and env.lookup_here('staticmethod'):
1847 # staticmethod() was overridden - not much we can do here ...
1848 self.is_staticmethod = False
1850 self.analyse_argument_types(env)
1851 self.declare_pyfunction(env)
1852 self.analyse_signature(env)
1853 self.return_type = self.entry.signature.return_type()
1854 self.create_local_scope(env)
1856 def analyse_argument_types(self, env):
1857 directive_locals = self.directive_locals = env.directives['locals']
1858 for arg in self.args:
1859 if hasattr(arg, 'name'):
1861 name_declarator = None
1863 base_type = arg.base_type.analyse(env)
1864 name_declarator, type = \
1865 arg.declarator.analyse(base_type, env)
1866 arg.name = name_declarator.name
1867 if arg.name in directive_locals:
1868 type_node = directive_locals[arg.name]
1869 other_type = type_node.analyse_as_type(env)
1870 if other_type is None:
1871 error(type_node.pos, "Not a type")
1872 elif (type is not PyrexTypes.py_object_type
1873 and not type.same_as(other_type)):
1874 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1875 error(type_node.pos, "Previous declaration here")
1878 if name_declarator and name_declarator.cname:
1880 "Python function argument cannot have C name specification")
1881 arg.type = type.as_argument_type()
1883 arg.needs_conversion = 0
1884 arg.needs_type_test = 0
1886 if arg.not_none and not arg.type.is_extension_type:
1888 "Only extension type arguments can have 'not None'")
1890 def analyse_signature(self, env):
1891 any_type_tests_needed = 0
1892 if self.entry.is_special:
1893 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1894 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1895 # Use the simpler calling signature for zero- and one-argument functions.
1896 if self.entry.signature is TypeSlots.pyfunction_signature:
1897 if len(self.args) == 0:
1898 self.entry.signature = TypeSlots.pyfunction_noargs
1899 elif len(self.args) == 1:
1900 if self.args[0].default is None and not self.args[0].kw_only:
1901 self.entry.signature = TypeSlots.pyfunction_onearg
1902 elif self.entry.signature is TypeSlots.pymethod_signature:
1903 if len(self.args) == 1:
1904 self.entry.signature = TypeSlots.unaryfunc
1905 elif len(self.args) == 2:
1906 if self.args[1].default is None and not self.args[1].kw_only:
1907 self.entry.signature = TypeSlots.ibinaryfunc
1909 sig = self.entry.signature
1910 nfixed = sig.num_fixed_args()
1911 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
1912 and len(self.args) == 0 and self.star_arg:
1913 # this is the only case where a diverging number of
1914 # arguments is not an error - when we have no explicit
1915 # 'self' parameter as in method(*args)
1916 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
1917 self.self_in_stararg = 1
1920 for i in range(min(nfixed, len(self.args))):
1923 if sig.is_self_arg(i) and not self.is_staticmethod:
1924 if self.is_classmethod:
1926 arg.hdr_type = arg.type = Builtin.type_type
1929 arg.hdr_type = arg.type = env.parent_type
1930 arg.needs_conversion = 0
1932 arg.hdr_type = sig.fixed_arg_type(i)
1933 if not arg.type.same_as(arg.hdr_type):
1934 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1935 arg.needs_type_test = 1
1936 any_type_tests_needed = 1
1938 arg.needs_conversion = 1
1939 if arg.needs_conversion:
1940 arg.hdr_cname = Naming.arg_prefix + arg.name
1942 arg.hdr_cname = Naming.var_prefix + arg.name
1944 if nfixed > len(self.args):
1945 self.bad_signature()
1947 elif nfixed < len(self.args):
1948 if not sig.has_generic_args:
1949 self.bad_signature()
1950 for arg in self.args:
1951 if arg.is_generic and \
1952 (arg.type.is_extension_type or arg.type.is_builtin_type):
1953 arg.needs_type_test = 1
1954 any_type_tests_needed = 1
1955 if any_type_tests_needed:
1956 env.use_utility_code(arg_type_test_utility_code)
1958 def bad_signature(self):
1959 sig = self.entry.signature
1960 expected_str = "%d" % sig.num_fixed_args()
1961 if sig.has_generic_args:
1962 expected_str = expected_str + " or more"
1964 if name.startswith("__") and name.endswith("__"):
1965 desc = "Special method"
1969 "%s %s has wrong number of arguments "
1970 "(%d declared, %s expected)" % (
1971 desc, self.name, len(self.args), expected_str))
1973 def signature_has_nongeneric_args(self):
1974 argcount = len(self.args)
1975 if argcount == 0 or (
1976 argcount == 1 and (self.args[0].is_self_arg or
1977 self.args[0].is_type_arg)):
1981 def signature_has_generic_args(self):
1982 return self.entry.signature.has_generic_args
1984 def declare_pyfunction(self, env):
1985 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1987 entry = env.lookup_here(self.name)
1988 if entry and entry.type.is_cfunction and not self.is_wrapper:
1989 warning(self.pos, "Overriding cdef method with def method.", 5)
1990 entry = env.declare_pyfunction(self.name, self.pos)
1992 prefix = env.scope_prefix
1993 entry.func_cname = \
1994 Naming.pyfunc_prefix + prefix + name
1995 entry.pymethdef_cname = \
1996 Naming.pymethdef_prefix + prefix + name
1997 if Options.docstrings:
1998 entry.doc = embed_position(self.pos, self.doc)
2000 Naming.funcdoc_prefix + prefix + name
2004 def declare_arguments(self, env):
2005 for arg in self.args:
2007 error(arg.pos, "Missing argument name")
2008 if arg.needs_conversion:
2009 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2010 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2011 env.control_flow.set_state((), (arg.name, 'initalized'), True)
2012 if arg.type.is_pyobject:
2013 arg.entry.init = "0"
2014 arg.entry.init_to_none = 0
2016 arg.entry = self.declare_argument(env, arg)
2018 arg.entry.is_self_arg = arg.is_self_arg
2020 if arg.is_self_arg or arg.is_type_arg or \
2021 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2022 arg.entry.is_declared_generic = 1
2023 self.declare_python_arg(env, self.star_arg)
2024 self.declare_python_arg(env, self.starstar_arg)
2026 def declare_python_arg(self, env, arg):
2028 if env.directives['infer_types'] != False:
2029 type = PyrexTypes.unspecified_type
2031 type = py_object_type
2032 entry = env.declare_var(arg.name, type, arg.pos)
2035 entry.init_to_none = 0
2036 entry.xdecref_cleanup = 1
2038 env.control_flow.set_state((), (arg.name, 'initalized'), True)
2040 def analyse_expressions(self, env):
2041 self.local_scope.directives = env.directives
2042 self.analyse_default_values(env)
2043 if env.is_py_class_scope:
2044 self.synthesize_assignment_node(env)
2046 def synthesize_assignment_node(self, env):
2048 self.assmt = SingleAssignmentNode(self.pos,
2049 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2050 rhs = ExprNodes.UnboundMethodNode(self.pos,
2051 function = ExprNodes.PyCFunctionNode(self.pos,
2052 pymethdef_cname = self.entry.pymethdef_cname)))
2053 self.assmt.analyse_declarations(env)
2054 self.assmt.analyse_expressions(env)
2056 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2058 sig = self.entry.signature
2059 if sig.has_dummy_arg or self.self_in_stararg:
2060 arg_code_list.append(
2061 "PyObject *%s" % Naming.self_cname)
2062 for arg in self.args:
2063 if not arg.is_generic:
2064 if arg.is_self_arg or arg.is_type_arg:
2065 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2067 arg_code_list.append(
2068 arg.hdr_type.declaration_code(arg.hdr_cname))
2069 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2070 arg_code_list.append("PyObject *unused")
2071 if sig.has_generic_args:
2072 arg_code_list.append(
2073 "PyObject *%s, PyObject *%s"
2074 % (Naming.args_cname, Naming.kwds_cname))
2075 arg_code = ", ".join(arg_code_list)
2076 dc = self.return_type.declaration_code(self.entry.func_cname)
2077 header = "static %s(%s)" % (dc, arg_code)
2078 code.putln("%s; /*proto*/" % header)
2081 if self.entry.doc and Options.docstrings:
2082 docstr = self.entry.doc
2083 if docstr.is_unicode:
2084 docstr = docstr.utf8encode()
2086 'static char %s[] = "%s";' % (
2087 self.entry.doc_cname,
2088 split_string_literal(escape_byte_string(docstr))))
2091 "static PyMethodDef %s = " %
2092 self.entry.pymethdef_cname)
2093 code.put_pymethoddef(self.entry, ";")
2094 code.putln("%s {" % header)
2096 def generate_argument_declarations(self, env, code):
2097 for arg in self.args:
2098 if arg.is_generic: # or arg.needs_conversion:
2099 if arg.needs_conversion:
2100 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2102 code.put_var_declaration(arg.entry)
2104 def generate_keyword_list(self, code):
2105 if self.signature_has_generic_args() and \
2106 self.signature_has_nongeneric_args():
2108 "static PyObject **%s[] = {" %
2109 Naming.pykwdlist_cname)
2110 for arg in self.args:
2112 pystring_cname = code.intern_identifier(arg.name)
2113 code.put('&%s,' % pystring_cname)
2116 def generate_argument_parsing_code(self, env, code):
2117 # Generate PyArg_ParseTuple call for generic
2118 # arguments, if any.
2119 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2120 # get rid of unused argument warning
2121 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2123 old_error_label = code.new_error_label()
2124 our_error_label = code.error_label
2125 end_label = code.new_label("argument_unpacking_done")
2127 has_kwonly_args = self.num_kwonly_args > 0
2128 has_star_or_kw_args = self.star_arg is not None \
2129 or self.starstar_arg is not None or has_kwonly_args
2131 for arg in self.args:
2132 if not arg.type.is_pyobject:
2133 done = arg.type.create_from_py_utility_code(env)
2134 if not done: pass # will fail later
2136 if not self.signature_has_generic_args():
2137 if has_star_or_kw_args:
2138 error(self.pos, "This method cannot have * or keyword arguments")
2139 self.generate_argument_conversion_code(code)
2141 elif not self.signature_has_nongeneric_args():
2142 # func(*args) or func(**kw) or func(*args, **kw)
2143 self.generate_stararg_copy_code(code)
2146 positional_args = []
2148 for arg in self.args:
2149 arg_entry = arg.entry
2152 if not arg.is_self_arg and not arg.is_type_arg:
2154 kw_only_args.append(arg)
2156 positional_args.append(arg)
2158 kw_only_args.append(arg)
2159 elif not arg.is_self_arg and not arg.is_type_arg:
2160 positional_args.append(arg)
2162 self.generate_tuple_and_keyword_parsing_code(
2163 positional_args, kw_only_args, end_label, code)
2165 code.error_label = old_error_label
2166 if code.label_used(our_error_label):
2167 if not code.label_used(end_label):
2168 code.put_goto(end_label)
2169 code.put_label(our_error_label)
2170 if has_star_or_kw_args:
2171 self.generate_arg_decref(self.star_arg, code)
2172 if self.starstar_arg:
2173 if self.starstar_arg.entry.xdecref_cleanup:
2174 code.put_var_xdecref(self.starstar_arg.entry)
2176 code.put_var_decref(self.starstar_arg.entry)
2177 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2178 code.putln("return %s;" % self.error_value())
2179 if code.label_used(end_label):
2180 code.put_label(end_label)
2182 def generate_arg_assignment(self, arg, item, code):
2183 if arg.type.is_pyobject:
2185 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2186 code.putln("%s = %s;" % (arg.entry.cname, item))
2188 func = arg.type.from_py_function
2190 code.putln("%s = %s(%s); %s" % (
2194 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2196 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2198 def generate_arg_xdecref(self, arg, code):
2200 code.put_var_xdecref(arg.entry)
2202 def generate_arg_decref(self, arg, code):
2204 code.put_var_decref(arg.entry)
2206 def generate_stararg_copy_code(self, code):
2207 if not self.star_arg:
2208 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2209 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2211 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2212 self.name, Naming.args_cname, self.error_value()))
2215 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2217 if self.starstar_arg:
2219 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2221 kwarg_check = "%s" % Naming.kwds_cname
2223 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2224 Naming.kwds_cname, Naming.kwds_cname)
2226 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2227 kwarg_check, Naming.kwds_cname, self.name,
2228 bool(self.starstar_arg), self.error_value()))
2230 if self.starstar_arg:
2231 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2232 self.starstar_arg.entry.cname,
2235 code.putln("if (unlikely(!%s)) return %s;" % (
2236 self.starstar_arg.entry.cname, self.error_value()))
2237 self.starstar_arg.entry.xdecref_cleanup = 0
2238 code.put_gotref(self.starstar_arg.entry.cname)
2240 if self.self_in_stararg:
2241 # need to create a new tuple with 'self' inserted as first item
2242 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2243 self.star_arg.entry.cname,
2245 self.star_arg.entry.cname))
2246 if self.starstar_arg:
2248 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2249 code.putln("return %s;" % self.error_value())
2252 code.putln("return %s;" % self.error_value())
2253 code.put_gotref(self.star_arg.entry.cname)
2254 code.put_incref(Naming.self_cname, py_object_type)
2255 code.put_giveref(Naming.self_cname)
2256 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2257 self.star_arg.entry.cname, Naming.self_cname))
2258 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2259 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2260 temp, temp, Naming.args_cname, temp))
2261 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2262 Naming.args_cname, temp))
2263 code.put_incref("item", py_object_type)
2264 code.put_giveref("item")
2265 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2266 self.star_arg.entry.cname, temp))
2268 code.funcstate.release_temp(temp)
2269 self.star_arg.entry.xdecref_cleanup = 0
2271 code.put_incref(Naming.args_cname, py_object_type)
2272 code.putln("%s = %s;" % (
2273 self.star_arg.entry.cname,
2275 self.star_arg.entry.xdecref_cleanup = 0
2277 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2278 kw_only_args, success_label, code):
2279 argtuple_error_label = code.new_label("argtuple_error")
2281 min_positional_args = self.num_required_args - self.num_required_kw_args
2282 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2283 min_positional_args -= 1
2284 max_positional_args = len(positional_args)
2285 has_fixed_positional_count = not self.star_arg and \
2286 min_positional_args == max_positional_args
2288 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2289 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2290 if self.num_required_kw_args:
2291 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2293 if self.starstar_arg or self.star_arg:
2294 self.generate_stararg_init_code(max_positional_args, code)
2296 # --- optimised code when we receive keyword arguments
2297 if self.num_required_kw_args:
2298 likely_hint = "likely"
2300 likely_hint = "unlikely"
2301 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2302 self.generate_keyword_unpacking_code(
2303 min_positional_args, max_positional_args,
2304 has_fixed_positional_count,
2305 positional_args, kw_only_args, argtuple_error_label, code)
2307 # --- optimised code when we do not receive any keyword arguments
2308 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2309 # Python raises arg tuple related errors first, so we must
2310 # check the length here
2311 if min_positional_args == max_positional_args and not self.star_arg:
2315 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2316 Naming.args_cname, compare, min_positional_args))
2317 code.put_goto(argtuple_error_label)
2319 if self.num_required_kw_args:
2320 # pure error case: keywords required but not passed
2321 if max_positional_args > min_positional_args and not self.star_arg:
2322 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2323 Naming.args_cname, max_positional_args))
2324 code.put_goto(argtuple_error_label)
2325 code.putln('} else {')
2326 for i, arg in enumerate(kw_only_args):
2328 pystring_cname = code.intern_identifier(arg.name)
2329 # required keyword-only argument missing
2330 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2333 code.putln(code.error_goto(self.pos))
2336 elif min_positional_args == max_positional_args:
2337 # parse the exact number of positional arguments from the
2339 code.putln('} else {')
2340 for i, arg in enumerate(positional_args):
2341 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2342 self.generate_arg_assignment(arg, item, code)
2343 self.generate_arg_default_assignments(code)
2346 # parse the positional arguments from the variable length
2348 code.putln('} else {')
2349 self.generate_arg_default_assignments(code)
2350 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2352 code.putln('default:')
2353 reversed_args = list(enumerate(positional_args))[::-1]
2354 for i, arg in reversed_args:
2355 if i >= min_positional_args-1:
2356 if min_positional_args > 1:
2357 code.putln('case %2d:' % (i+1)) # pure code beautification
2359 code.put('case %2d: ' % (i+1))
2360 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2361 self.generate_arg_assignment(arg, item, code)
2362 if min_positional_args == 0:
2363 code.put('case 0: ')
2364 code.putln('break;')
2366 if min_positional_args:
2367 for i in range(min_positional_args-1, -1, -1):
2368 code.putln('case %2d:' % i)
2369 code.put_goto(argtuple_error_label)
2371 code.put('default: ')
2372 code.put_goto(argtuple_error_label)
2377 if code.label_used(argtuple_error_label):
2378 code.put_goto(success_label)
2379 code.put_label(argtuple_error_label)
2380 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2381 self.name, has_fixed_positional_count,
2382 min_positional_args, max_positional_args,
2384 code.putln(code.error_goto(self.pos))
2386 def generate_arg_default_assignments(self, code):
2387 for arg in self.args:
2388 if arg.is_generic and arg.default:
2392 arg.calculate_default_value_code(code)))
2394 def generate_stararg_init_code(self, max_positional_args, code):
2395 if self.starstar_arg:
2396 self.starstar_arg.entry.xdecref_cleanup = 0
2397 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2398 self.starstar_arg.entry.cname,
2399 self.starstar_arg.entry.cname,
2400 self.error_value()))
2401 code.put_gotref(self.starstar_arg.entry.cname)
2403 self.star_arg.entry.xdecref_cleanup = 0
2404 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2406 max_positional_args))
2407 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2408 self.star_arg.entry.cname, Naming.args_cname,
2409 max_positional_args, Naming.args_cname))
2410 code.put_gotref(self.star_arg.entry.cname)
2411 if self.starstar_arg:
2413 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2414 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2415 code.putln('return %s;' % self.error_value())
2418 code.putln("if (unlikely(!%s)) return %s;" % (
2419 self.star_arg.entry.cname, self.error_value()))
2420 code.putln('} else {')
2421 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2422 code.put_incref(Naming.empty_tuple, py_object_type)
2425 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2426 has_fixed_positional_count, positional_args,
2427 kw_only_args, argtuple_error_label, code):
2428 all_args = tuple(positional_args) + tuple(kw_only_args)
2429 max_args = len(all_args)
2432 for i, arg in enumerate(all_args):
2433 if arg.default and arg.type.is_pyobject:
2434 default_value = arg.calculate_default_value_code(code)
2435 if arg.type is not PyrexTypes.py_object_type:
2436 default_value = "(PyObject*)"+default_value
2437 default_args.append((i, default_value))
2439 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2441 # it looks funny to separate the init-to-0 from setting the
2442 # default value, but C89 needs this
2443 code.putln("PyObject* values[%d] = {%s};" % (
2444 max_args, ','.join('0'*max_args)))
2445 for i, default_value in default_args:
2446 code.putln('values[%d] = %s;' % (i, default_value))
2448 # parse the tuple and check that it's not too long
2449 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2451 code.putln('default:')
2452 for i in range(max_positional_args-1, -1, -1):
2453 code.put('case %2d: ' % (i+1))
2454 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2455 i, Naming.args_cname, i))
2456 code.putln('case 0: break;')
2457 if not self.star_arg:
2458 code.put('default: ') # more arguments than allowed
2459 code.put_goto(argtuple_error_label)
2462 # now fill up the positional/required arguments with values
2464 if self.num_required_args or max_positional_args > 0:
2465 last_required_arg = -1
2466 for i, arg in enumerate(all_args):
2468 last_required_arg = i
2469 if last_required_arg < max_positional_args:
2470 last_required_arg = max_positional_args-1
2471 num_required_args = self.num_required_args
2472 if max_positional_args > 0:
2473 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2474 for i, arg in enumerate(all_args[:last_required_arg+1]):
2475 if max_positional_args > 0 and i <= max_positional_args:
2476 if self.star_arg and i == max_positional_args:
2477 code.putln('default:')
2479 code.putln('case %2d:' % i)
2480 pystring_cname = code.intern_identifier(arg.name)
2483 # handled separately below
2485 code.putln('if (kw_args > %d) {' % num_required_args)
2486 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2487 Naming.kwds_cname, pystring_cname))
2488 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2491 num_required_args -= 1
2492 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2493 i, Naming.kwds_cname, pystring_cname))
2494 code.putln('if (likely(values[%d])) kw_args--;' % i);
2495 if i < min_positional_args:
2497 # special case: we know arg 0 is missing
2499 code.put_goto(argtuple_error_label)
2501 # print the correct number of values (args or
2502 # kwargs) that were passed into positional
2503 # arguments up to this point
2504 code.putln('else {')
2505 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2506 self.name, has_fixed_positional_count,
2507 min_positional_args, max_positional_args, i))
2508 code.putln(code.error_goto(self.pos))
2511 code.putln('else {')
2512 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2513 self.name, pystring_cname))
2514 code.putln(code.error_goto(self.pos))
2516 if max_positional_args > 0:
2519 if kw_only_args and not self.starstar_arg:
2520 # unpack optional keyword-only arguments
2521 # checking for interned strings in a dict is faster than iterating
2522 # but it's too likely that we must iterate if we expect **kwargs
2524 for i, arg in enumerate(all_args[max_positional_args:]):
2525 if not arg.kw_only or not arg.default:
2527 optional_args.append((i+max_positional_args, arg))
2529 # this mimics an unrolled loop so that we can "break" out of it
2530 code.putln('while (kw_args > 0) {')
2531 code.putln('PyObject* value;')
2532 for i, arg in optional_args:
2533 pystring_cname = code.intern_identifier(arg.name)
2535 'value = PyDict_GetItem(%s, %s);' % (
2536 Naming.kwds_cname, pystring_cname))
2538 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2539 code.putln('break;')
2542 code.putln('if (unlikely(kw_args > 0)) {')
2543 # non-positional/-required kw args left in dict: default args,
2544 # kw-only args, **kwargs or error
2546 # This is sort of a catch-all: except for checking required
2547 # arguments, this will always do the right thing for unpacking
2548 # keyword arguments, so that we can concentrate on optimising
2549 # common cases above.
2550 if max_positional_args == 0:
2553 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2554 Naming.args_cname, max_positional_args,
2555 Naming.args_cname, max_positional_args))
2556 pos_arg_count = "used_pos_args"
2558 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2559 code.globalstate.use_utility_code(parse_keywords_utility_code)
2561 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2563 Naming.pykwdlist_cname,
2564 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2567 code.putln(code.error_goto(self.pos))
2570 # convert arg values to their final type and assign them
2571 for i, arg in enumerate(all_args):
2572 if arg.default and not arg.type.is_pyobject:
2573 code.putln("if (values[%d]) {" % i)
2574 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2575 if arg.default and not arg.type.is_pyobject:
2576 code.putln('} else {')
2580 arg.calculate_default_value_code(code)))
2583 def generate_argument_conversion_code(self, code):
2584 # Generate code to convert arguments from
2585 # signature type to declared type, if needed.
2586 for arg in self.args:
2587 if arg.needs_conversion:
2588 self.generate_arg_conversion(arg, code)
2590 def generate_arg_conversion(self, arg, code):
2591 # Generate conversion code for one argument.
2592 old_type = arg.hdr_type
2594 if old_type.is_pyobject:
2596 code.putln("if (%s) {" % arg.hdr_cname)
2598 code.putln("assert(%s); {" % arg.hdr_cname)
2599 self.generate_arg_conversion_from_pyobject(arg, code)
2601 elif new_type.is_pyobject:
2602 self.generate_arg_conversion_to_pyobject(arg, code)
2604 if new_type.assignable_from(old_type):
2606 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2609 "Cannot convert 1 argument from '%s' to '%s'" %
2610 (old_type, new_type))
2612 def generate_arg_conversion_from_pyobject(self, arg, code):
2614 func = new_type.from_py_function
2615 # copied from CoerceFromPyTypeNode
2617 code.putln("%s = %s(%s); %s" % (
2621 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2624 "Cannot convert Python object argument to type '%s'"
2627 def generate_arg_conversion_to_pyobject(self, arg, code):
2628 old_type = arg.hdr_type
2629 func = old_type.to_py_function
2631 code.putln("%s = %s(%s); %s" % (
2635 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2636 code.put_var_gotref(arg.entry)
2639 "Cannot convert argument of type '%s' to Python object"
2642 def generate_argument_type_tests(self, code):
2643 # Generate type tests for args whose signature
2644 # type is PyObject * and whose declared type is
2645 # a subtype thereof.
2646 for arg in self.args:
2647 if arg.needs_type_test:
2648 self.generate_arg_type_test(arg, code)
2650 def generate_arg_type_test(self, arg, code):
2651 # Generate type test for one argument.
2652 if arg.type.typeobj_is_available():
2653 typeptr_cname = arg.type.typeptr_cname
2654 arg_code = "((PyObject *)%s)" % arg.entry.cname
2656 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2661 arg.type.is_builtin_type,
2662 code.error_goto(arg.pos)))
2664 error(arg.pos, "Cannot test type of extern C class "
2665 "without type object name specification")
2667 def error_value(self):
2668 return self.entry.signature.error_value
2670 def caller_will_check_exceptions(self):
2673 class OverrideCheckNode(StatNode):
2674 # A Node for dispatching to the def method if it
2683 child_attrs = ['body']
2687 def analyse_expressions(self, env):
2688 self.args = env.arg_entries
2689 if self.py_func.is_module_scope:
2694 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2695 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2696 call_node = ExprNodes.SimpleCallNode(self.pos,
2697 function=self.func_node,
2698 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2699 self.body = ReturnStatNode(self.pos, value=call_node)
2700 self.body.analyse_expressions(env)
2702 def generate_execution_code(self, code):
2703 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2704 # Check to see if we are an extension type
2705 if self.py_func.is_module_scope:
2706 self_arg = "((PyObject *)%s)" % Naming.module_cname
2708 self_arg = "((PyObject *)%s)" % self.args[0].cname
2709 code.putln("/* Check if called by wrapper */")
2710 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2711 code.putln("/* Check if overriden in Python */")
2712 if self.py_func.is_module_scope:
2713 code.putln("else {")
2715 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2716 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2717 self.func_node.set_cname(func_node_temp)
2718 # need to get attribute manually--scope would return cdef method
2719 err = code.error_goto_if_null(func_node_temp, self.pos)
2720 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2721 func_node_temp, self_arg, interned_attr_cname, err))
2722 code.put_gotref(func_node_temp)
2723 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2724 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2725 func_node_temp, self.py_func.entry.func_cname)
2726 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2727 self.body.generate_execution_code(code)
2729 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2730 code.funcstate.release_temp(func_node_temp)
2733 class ClassDefNode(StatNode, BlockNode):
2736 class PyClassDefNode(ClassDefNode):
2737 # A Python class definition.
2739 # name EncodedString Name of the class
2740 # doc string or None
2741 # body StatNode Attribute definition code
2742 # entry Symtab.Entry
2743 # scope PyClassScope
2744 # decorators [DecoratorNode] list of decorators or None
2746 # The following subnodes are constructed internally:
2748 # dict DictNode Class dictionary
2749 # classobj ClassNode Class object
2750 # target NameNode Variable to assign class object to
2752 child_attrs = ["body", "dict", "classobj", "target"]
2755 def __init__(self, pos, name, bases, doc, body, decorators = None):
2756 StatNode.__init__(self, pos)
2760 self.decorators = decorators
2762 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2763 if self.doc and Options.docstrings:
2764 doc = embed_position(self.pos, self.doc)
2765 # FIXME: correct string node?
2766 doc_node = ExprNodes.StringNode(pos, value = doc)
2769 self.classobj = ExprNodes.ClassNode(pos, name = name,
2770 bases = bases, dict = self.dict, doc = doc_node)
2771 self.target = ExprNodes.NameNode(pos, name = name)
2773 def as_cclass(self):
2775 Return this node as if it were declared as an extension class
2777 bases = self.classobj.bases.args
2779 base_class_name = None
2780 base_class_module = None
2781 elif len(bases) == 1:
2784 from ExprNodes import AttributeNode, NameNode
2785 while isinstance(base, AttributeNode):
2786 path.insert(0, base.attribute)
2788 if isinstance(base, NameNode):
2789 path.insert(0, base.name)
2790 base_class_name = path[-1]
2792 base_class_module = u'.'.join(path[:-1])
2794 base_class_module = None
2796 error(self.classobj.bases.args.pos, "Invalid base class")
2798 error(self.classobj.bases.args.pos, "C class may only have one base class")
2801 return CClassDefNode(self.pos,
2802 visibility = 'private',
2804 class_name = self.name,
2805 base_class_module = base_class_module,
2806 base_class_name = base_class_name,
2807 decorators = self.decorators,
2812 def create_scope(self, env):
2814 while env.is_py_class_scope or env.is_c_class_scope:
2815 env = env.outer_scope
2816 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2819 def analyse_declarations(self, env):
2820 self.target.analyse_target_declaration(env)
2821 cenv = self.create_scope(env)
2822 cenv.directives = env.directives
2823 cenv.class_obj_cname = self.target.entry.cname
2824 self.body.analyse_declarations(cenv)
2826 def analyse_expressions(self, env):
2827 self.dict.analyse_expressions(env)
2828 self.classobj.analyse_expressions(env)
2829 genv = env.global_scope()
2831 self.body.analyse_expressions(cenv)
2832 self.target.analyse_target_expression(env, self.classobj)
2834 def generate_function_definitions(self, env, code):
2835 self.body.generate_function_definitions(self.scope, code)
2837 def generate_execution_code(self, code):
2838 code.pyclass_stack.append(self)
2840 self.dict.generate_evaluation_code(code)
2841 self.classobj.generate_evaluation_code(code)
2842 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2843 self.body.generate_execution_code(code)
2844 self.target.generate_assignment_code(self.classobj, code)
2845 self.dict.generate_disposal_code(code)
2846 self.dict.free_temps(code)
2847 code.pyclass_stack.pop()
2850 class CClassDefNode(ClassDefNode):
2851 # An extension type definition.
2853 # visibility 'private' or 'public' or 'extern'
2854 # typedef_flag boolean
2856 # module_name string or None For import of extern type objects
2857 # class_name string Unqualified name of class
2858 # as_name string or None Name to declare as in this scope
2859 # base_class_module string or None Module containing the base class
2860 # base_class_name string or None Name of the base class
2861 # objstruct_name string or None Specified C name of object struct
2862 # typeobj_name string or None Specified C name of type object
2863 # in_pxd boolean Is in a .pxd file
2864 # decorators [DecoratorNode] list of decorators or None
2865 # doc string or None
2866 # body StatNode or None
2867 # entry Symtab.Entry
2868 # base_type PyExtensionType or None
2869 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2870 # buffer_defaults_pos
2872 child_attrs = ["body"]
2873 buffer_defaults_node = None
2874 buffer_defaults_pos = None
2875 typedef_flag = False
2877 objstruct_name = None
2881 def analyse_declarations(self, env):
2882 #print "CClassDefNode.analyse_declarations:", self.class_name
2883 #print "...visibility =", self.visibility
2884 #print "...module_name =", self.module_name
2887 if self.buffer_defaults_node:
2888 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2889 env, [], self.buffer_defaults_node,
2890 need_complete=False)
2892 buffer_defaults = None
2894 if env.in_cinclude and not self.objstruct_name:
2895 error(self.pos, "Object struct name specification required for "
2896 "C class defined in 'extern from' block")
2897 self.base_type = None
2898 # Now that module imports are cached, we need to
2899 # import the modules for extern classes.
2900 if self.module_name:
2902 for module in env.cimported_modules:
2903 if module.name == self.module_name:
2904 self.module = module
2905 if self.module is None:
2906 self.module = ModuleScope(self.module_name, None, env.context)
2907 self.module.has_extern_class = 1
2908 env.add_imported_module(self.module)
2910 if self.base_class_name:
2911 if self.base_class_module:
2912 base_class_scope = env.find_module(self.base_class_module, self.pos)
2914 base_class_scope = env
2915 if self.base_class_name == 'object':
2916 # extension classes are special and don't need to inherit from object
2917 if base_class_scope is None or base_class_scope.lookup('object') is None:
2918 self.base_class_name = None
2919 self.base_class_module = None
2920 base_class_scope = None
2921 if base_class_scope:
2922 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2923 if base_class_entry:
2924 if not base_class_entry.is_type:
2925 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2926 elif not base_class_entry.type.is_extension_type:
2927 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2928 elif not base_class_entry.type.is_complete():
2929 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2931 self.base_type = base_class_entry.type
2932 has_body = self.body is not None
2933 if self.module_name and self.visibility != 'extern':
2934 module_path = self.module_name.split(".")
2935 home_scope = env.find_imported_module(module_path, self.pos)
2941 if self.visibility == 'extern':
2942 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2943 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2945 self.entry = home_scope.declare_c_class(
2946 name = self.class_name,
2948 defining = has_body and self.in_pxd,
2949 implementing = has_body and not self.in_pxd,
2950 module_name = self.module_name,
2951 base_type = self.base_type,
2952 objstruct_cname = self.objstruct_name,
2953 typeobj_cname = self.typeobj_name,
2954 visibility = self.visibility,
2955 typedef_flag = self.typedef_flag,
2957 buffer_defaults = buffer_defaults)
2958 if home_scope is not env and self.visibility == 'extern':
2959 env.add_imported_entry(self.class_name, self.entry, pos)
2960 self.scope = scope = self.entry.type.scope
2961 if scope is not None:
2962 scope.directives = env.directives
2964 if self.doc and Options.docstrings:
2965 scope.doc = embed_position(self.pos, self.doc)
2968 self.body.analyse_declarations(scope)
2972 scope.implemented = 1
2973 env.allocate_vtable_names(self.entry)
2975 def analyse_expressions(self, env):
2977 scope = self.entry.type.scope
2978 self.body.analyse_expressions(scope)
2980 def generate_function_definitions(self, env, code):
2982 self.body.generate_function_definitions(
2983 self.entry.type.scope, code)
2985 def generate_execution_code(self, code):
2986 # This is needed to generate evaluation code for
2987 # default values of method arguments.
2989 self.body.generate_execution_code(code)
2991 def annotate(self, code):
2993 self.body.annotate(code)
2996 class PropertyNode(StatNode):
2997 # Definition of a property in an extension type.
3000 # doc EncodedString or None Doc string
3003 child_attrs = ["body"]
3005 def analyse_declarations(self, env):
3006 entry = env.declare_property(self.name, self.doc, self.pos)
3008 entry.scope.directives = env.directives
3009 self.body.analyse_declarations(entry.scope)
3011 def analyse_expressions(self, env):
3012 self.body.analyse_expressions(env)
3014 def generate_function_definitions(self, env, code):
3015 self.body.generate_function_definitions(env, code)
3017 def generate_execution_code(self, code):
3020 def annotate(self, code):
3021 self.body.annotate(code)
3024 class GlobalNode(StatNode):
3025 # Global variable declaration.
3031 def analyse_declarations(self, env):
3032 for name in self.names:
3033 env.declare_global(name, self.pos)
3035 def analyse_expressions(self, env):
3038 def generate_execution_code(self, code):
3042 class ExprStatNode(StatNode):
3043 # Expression used as a statement.
3047 child_attrs = ["expr"]
3049 def analyse_declarations(self, env):
3051 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3052 func = self.expr.function.as_cython_attribute()
3053 if func == u'declare':
3054 args, kwds = self.expr.explicit_args_kwds()
3056 error(self.expr.pos, "Variable names must be specified.")
3057 for var, type_node in kwds.key_value_pairs:
3058 type = type_node.analyse_as_type(env)
3060 error(type_node.pos, "Unknown type")
3062 env.declare_var(var.value, type, var.pos, is_cdef = True)
3063 self.__class__ = PassStatNode
3065 def analyse_expressions(self, env):
3066 self.expr.analyse_expressions(env)
3068 def generate_execution_code(self, code):
3069 self.expr.generate_evaluation_code(code)
3070 if not self.expr.is_temp and self.expr.result():
3071 code.putln("%s;" % self.expr.result())
3072 self.expr.generate_disposal_code(code)
3073 self.expr.free_temps(code)
3075 def annotate(self, code):
3076 self.expr.annotate(code)
3079 class AssignmentNode(StatNode):
3080 # Abstract base class for assignment nodes.
3082 # The analyse_expressions and generate_execution_code
3083 # phases of assignments are split into two sub-phases
3084 # each, to enable all the right hand sides of a
3085 # parallel assignment to be evaluated before assigning
3086 # to any of the left hand sides.
3088 def analyse_expressions(self, env):
3089 self.analyse_types(env)
3091 # def analyse_expressions(self, env):
3092 # self.analyse_expressions_1(env)
3093 # self.analyse_expressions_2(env)
3095 def generate_execution_code(self, code):
3096 self.generate_rhs_evaluation_code(code)
3097 self.generate_assignment_code(code)
3100 class SingleAssignmentNode(AssignmentNode):
3101 # The simplest case:
3105 # lhs ExprNode Left hand side
3106 # rhs ExprNode Right hand side
3107 # first bool Is this guaranteed the first assignment to lhs?
3109 child_attrs = ["lhs", "rhs"]
3111 declaration_only = False
3113 def analyse_declarations(self, env):
3116 # handle declarations of the form x = cython.foo()
3117 if isinstance(self.rhs, ExprNodes.CallNode):
3118 func_name = self.rhs.function.as_cython_attribute()
3120 args, kwds = self.rhs.explicit_args_kwds()
3122 if func_name in ['declare', 'typedef']:
3123 if len(args) > 2 or kwds is not None:
3124 error(rhs.pos, "Can only declare one type at a time.")
3126 type = args[0].analyse_as_type(env)
3128 error(args[0].pos, "Unknown type")
3131 if func_name == 'declare':
3132 if isinstance(lhs, ExprNodes.NameNode):
3133 vars = [(lhs.name, lhs.pos)]
3134 elif isinstance(lhs, ExprNodes.TupleNode):
3135 vars = [(var.name, var.pos) for var in lhs.args]
3137 error(lhs.pos, "Invalid declaration")
3139 for var, pos in vars:
3140 env.declare_var(var, type, pos, is_cdef = True)
3145 self.declaration_only = True
3147 self.declaration_only = True
3148 if not isinstance(lhs, ExprNodes.NameNode):
3149 error(lhs.pos, "Invalid declaration.")
3150 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3152 elif func_name in ['struct', 'union']:
3153 self.declaration_only = True
3154 if len(args) > 0 or kwds is None:
3155 error(rhs.pos, "Struct or union members must be given by name.")
3158 for member, type_node in kwds.key_value_pairs:
3159 type = type_node.analyse_as_type(env)
3161 error(type_node.pos, "Unknown type")
3163 members.append((member.value, type, member.pos))
3164 if len(members) < len(kwds.key_value_pairs):
3166 if not isinstance(self.lhs, ExprNodes.NameNode):
3167 error(self.lhs.pos, "Invalid declaration.")
3168 name = self.lhs.name
3169 scope = StructOrUnionScope(name)
3170 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3171 for member, type, pos in members:
3172 scope.declare_var(member, type, pos)
3174 if self.declaration_only:
3177 self.lhs.analyse_target_declaration(env)
3179 def analyse_types(self, env, use_temp = 0):
3180 self.rhs.analyse_types(env)
3181 self.lhs.analyse_target_types(env)
3182 self.lhs.gil_assignment_check(env)
3183 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3185 self.rhs = self.rhs.coerce_to_temp(env)
3187 def generate_rhs_evaluation_code(self, code):
3188 self.rhs.generate_evaluation_code(code)
3190 def generate_assignment_code(self, code):
3191 self.lhs.generate_assignment_code(self.rhs, code)
3193 def annotate(self, code):
3194 self.lhs.annotate(code)
3195 self.rhs.annotate(code)
3198 class CascadedAssignmentNode(AssignmentNode):
3199 # An assignment with multiple left hand sides:
3203 # lhs_list [ExprNode] Left hand sides
3204 # rhs ExprNode Right hand sides
3208 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3210 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3211 coerced_rhs_list = None
3213 def analyse_declarations(self, env):
3214 for lhs in self.lhs_list:
3215 lhs.analyse_target_declaration(env)
3217 def analyse_types(self, env, use_temp = 0):
3218 self.rhs.analyse_types(env)
3219 if not self.rhs.is_simple():
3221 self.rhs = self.rhs.coerce_to_temp(env)
3223 self.rhs = self.rhs.coerce_to_simple(env)
3224 from ExprNodes import CloneNode
3225 self.coerced_rhs_list = []
3226 for lhs in self.lhs_list:
3227 lhs.analyse_target_types(env)
3228 lhs.gil_assignment_check(env)
3229 rhs = CloneNode(self.rhs)
3230 rhs = rhs.coerce_to(lhs.type, env)
3231 self.coerced_rhs_list.append(rhs)
3233 def generate_rhs_evaluation_code(self, code):
3234 self.rhs.generate_evaluation_code(code)
3236 def generate_assignment_code(self, code):
3237 for i in range(len(self.lhs_list)):
3238 lhs = self.lhs_list[i]
3239 rhs = self.coerced_rhs_list[i]
3240 rhs.generate_evaluation_code(code)
3241 lhs.generate_assignment_code(rhs, code)
3242 # Assignment has disposed of the cloned RHS
3243 self.rhs.generate_disposal_code(code)
3244 self.rhs.free_temps(code)
3246 def annotate(self, code):
3247 for i in range(len(self.lhs_list)):
3248 lhs = self.lhs_list[i].annotate(code)
3249 rhs = self.coerced_rhs_list[i].annotate(code)
3250 self.rhs.annotate(code)
3253 class ParallelAssignmentNode(AssignmentNode):
3254 # A combined packing/unpacking assignment:
3258 # This has been rearranged by the parser into
3260 # a = d ; b = e ; c = f
3262 # but we must evaluate all the right hand sides
3263 # before assigning to any of the left hand sides.
3265 # stats [AssignmentNode] The constituent assignments
3267 child_attrs = ["stats"]
3269 def analyse_declarations(self, env):
3270 for stat in self.stats:
3271 stat.analyse_declarations(env)
3273 def analyse_expressions(self, env):
3274 for stat in self.stats:
3275 stat.analyse_types(env, use_temp = 1)
3277 # def analyse_expressions(self, env):
3278 # for stat in self.stats:
3279 # stat.analyse_expressions_1(env, use_temp = 1)
3280 # for stat in self.stats:
3281 # stat.analyse_expressions_2(env)
3283 def generate_execution_code(self, code):
3284 for stat in self.stats:
3285 stat.generate_rhs_evaluation_code(code)
3286 for stat in self.stats:
3287 stat.generate_assignment_code(code)
3289 def annotate(self, code):
3290 for stat in self.stats:
3294 class InPlaceAssignmentNode(AssignmentNode):
3295 # An in place arithmetic operand:
3301 # lhs ExprNode Left hand side
3302 # rhs ExprNode Right hand side
3303 # op char one of "+-*/%^&|"
3304 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3306 # This code is a bit tricky because in order to obey Python
3307 # semantics the sub-expressions (e.g. indices) of the lhs must
3308 # not be evaluated twice. So we must re-use the values calculated
3309 # in evaluation phase for the assignment phase as well.
3310 # Fortunately, the type of the lhs node is fairly constrained
3311 # (it must be a NameNode, AttributeNode, or IndexNode).
3313 child_attrs = ["lhs", "rhs"]
3316 def analyse_declarations(self, env):
3317 self.lhs.analyse_target_declaration(env)
3319 def analyse_types(self, env):
3320 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3321 self.rhs.analyse_types(env)
3322 self.lhs.analyse_target_types(env)
3324 if self.lhs.type.is_pyobject:
3325 self.rhs = self.rhs.coerce_to_pyobject(env)
3326 elif self.rhs.type.is_pyobject:
3327 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3328 if self.lhs.type.is_pyobject:
3329 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3330 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3332 def generate_execution_code(self, code):
3334 self.rhs.generate_evaluation_code(code)
3335 self.dup.generate_subexpr_evaluation_code(code)
3336 if self.dup.is_temp:
3337 self.dup.allocate_temp_result(code)
3338 # self.dup.generate_result_code is run only if it is not buffer access
3339 if self.operator == "**":
3343 if self.lhs.type.is_pyobject:
3344 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3345 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3346 self.dup.generate_result_code(code)
3347 self.result_value_temp.allocate(code)
3349 "%s = %s(%s, %s%s); %s" % (
3350 self.result_value.result(),
3351 self.py_operation_function(),
3352 self.dup.py_result(),
3353 self.rhs.py_result(),
3355 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3356 code.put_gotref(self.result_value.py_result())
3357 self.result_value.generate_evaluation_code(code) # May be a type check...
3358 self.rhs.generate_disposal_code(code)
3359 self.rhs.free_temps(code)
3360 self.dup.generate_disposal_code(code)
3361 self.dup.free_temps(code)
3362 self.lhs.generate_assignment_code(self.result_value, code)
3363 self.result_value_temp.release(code)
3365 c_op = self.operator
3369 error(self.pos, "No C inplace power operator")
3370 elif self.lhs.type.is_complex:
3371 error(self.pos, "Inplace operators not implemented for complex types.")
3373 # have to do assignment directly to avoid side-effects
3374 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3375 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3377 self.dup.generate_result_code(code)
3378 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3379 self.rhs.generate_disposal_code(code)
3380 self.rhs.free_temps(code)
3381 if self.dup.is_temp:
3382 self.dup.generate_subexpr_disposal_code(code)
3383 self.dup.free_subexpr_temps(code)
3385 def create_dup_node(self, env):
3388 self.dup.analyse_types(env)
3389 if isinstance(self.lhs, ExprNodes.NameNode):
3390 target_lhs = ExprNodes.NameNode(self.dup.pos,
3391 name = self.dup.name,
3392 is_temp = self.dup.is_temp,
3393 entry = self.dup.entry)
3394 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3395 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3396 obj = ExprNodes.CloneNode(self.lhs.obj),
3397 attribute = self.dup.attribute,
3398 is_temp = self.dup.is_temp)
3399 elif isinstance(self.lhs, ExprNodes.IndexNode):
3401 index = ExprNodes.CloneNode(self.lhs.index)
3404 if self.lhs.indices:
3405 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3408 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3409 base = ExprNodes.CloneNode(self.dup.base),
3412 is_temp = self.dup.is_temp)
3415 self.lhs = target_lhs
3418 def py_operation_function(self):
3419 return self.py_functions[self.operator]
3422 "|": "PyNumber_InPlaceOr",
3423 "^": "PyNumber_InPlaceXor",
3424 "&": "PyNumber_InPlaceAnd",
3425 "+": "PyNumber_InPlaceAdd",
3426 "-": "PyNumber_InPlaceSubtract",
3427 "*": "PyNumber_InPlaceMultiply",
3428 "/": "__Pyx_PyNumber_InPlaceDivide",
3429 "%": "PyNumber_InPlaceRemainder",
3430 "<<": "PyNumber_InPlaceLshift",
3431 ">>": "PyNumber_InPlaceRshift",
3432 "**": "PyNumber_InPlacePower",
3433 "//": "PyNumber_InPlaceFloorDivide",
3436 def annotate(self, code):
3437 self.lhs.annotate(code)
3438 self.rhs.annotate(code)
3439 self.dup.annotate(code)
3441 def create_binop_node(self):
3443 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3446 class PrintStatNode(StatNode):
3449 # arg_tuple TupleNode
3450 # stream ExprNode or None (stdout)
3451 # append_newline boolean
3453 child_attrs = ["arg_tuple", "stream"]
3455 def analyse_expressions(self, env):
3457 self.stream.analyse_expressions(env)
3458 self.stream = self.stream.coerce_to_pyobject(env)
3459 self.arg_tuple.analyse_expressions(env)
3460 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3461 env.use_utility_code(printing_utility_code)
3462 if len(self.arg_tuple.args) == 1 and self.append_newline:
3463 env.use_utility_code(printing_one_utility_code)
3465 nogil_check = Node.gil_error
3466 gil_message = "Python print statement"
3468 def generate_execution_code(self, code):
3470 self.stream.generate_evaluation_code(code)
3471 stream_result = self.stream.py_result()
3474 if len(self.arg_tuple.args) == 1 and self.append_newline:
3475 arg = self.arg_tuple.args[0]
3476 arg.generate_evaluation_code(code)
3479 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3482 code.error_goto(self.pos)))
3483 arg.generate_disposal_code(code)
3484 arg.free_temps(code)
3486 self.arg_tuple.generate_evaluation_code(code)
3488 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3490 self.arg_tuple.py_result(),
3491 self.append_newline,
3492 code.error_goto(self.pos)))
3493 self.arg_tuple.generate_disposal_code(code)
3494 self.arg_tuple.free_temps(code)
3497 self.stream.generate_disposal_code(code)
3498 self.stream.free_temps(code)
3500 def annotate(self, code):
3502 self.stream.annotate(code)
3503 self.arg_tuple.annotate(code)
3506 class ExecStatNode(StatNode):
3511 child_attrs = ["args"]
3513 def analyse_expressions(self, env):
3514 for i, arg in enumerate(self.args):
3515 arg.analyse_expressions(env)
3516 arg = arg.coerce_to_pyobject(env)
3518 env.use_utility_code(Builtin.pyexec_utility_code)
3520 nogil_check = Node.gil_error
3521 gil_message = "Python exec statement"
3523 def generate_execution_code(self, code):
3525 for arg in self.args:
3526 arg.generate_evaluation_code(code)
3527 args.append( arg.py_result() )
3528 args = tuple(args + ['0', '0'][:3-len(args)])
3529 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3530 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3531 (temp_result,) + args))
3532 for arg in self.args:
3533 arg.generate_disposal_code(code)
3534 arg.free_temps(code)
3536 code.error_goto_if_null(temp_result, self.pos))
3537 code.put_gotref(temp_result)
3538 code.put_decref_clear(temp_result, py_object_type)
3539 code.funcstate.release_temp(temp_result)
3541 def annotate(self, code):
3542 for arg in self.args:
3546 class DelStatNode(StatNode):
3551 child_attrs = ["args"]
3553 def analyse_declarations(self, env):
3554 for arg in self.args:
3555 arg.analyse_target_declaration(env)
3557 def analyse_expressions(self, env):
3558 for arg in self.args:
3559 arg.analyse_target_expression(env, None)
3560 if arg.type.is_pyobject:
3562 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3564 elif arg.type.is_cpp_class:
3565 error(arg.pos, "Deletion of non-heap C++ object")
3567 error(arg.pos, "Deletion of non-Python, non-C++ object")
3568 #arg.release_target_temp(env)
3570 def nogil_check(self, env):
3571 for arg in self.args:
3572 if arg.type.is_pyobject:
3575 gil_message = "Deleting Python object"
3577 def generate_execution_code(self, code):
3578 for arg in self.args:
3579 if arg.type.is_pyobject:
3580 arg.generate_deletion_code(code)
3581 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3582 arg.generate_result_code(code)
3583 code.putln("delete %s;" % arg.result())
3584 # else error reported earlier
3586 def annotate(self, code):
3587 for arg in self.args:
3591 class PassStatNode(StatNode):
3596 def analyse_expressions(self, env):
3599 def generate_execution_code(self, code):
3603 class BreakStatNode(StatNode):
3607 def analyse_expressions(self, env):
3610 def generate_execution_code(self, code):
3611 if not code.break_label:
3612 error(self.pos, "break statement not inside loop")
3614 code.put_goto(code.break_label)
3617 class ContinueStatNode(StatNode):
3621 def analyse_expressions(self, env):
3624 def generate_execution_code(self, code):
3625 if code.funcstate.in_try_finally:
3626 error(self.pos, "continue statement inside try of try...finally")
3627 elif not code.continue_label:
3628 error(self.pos, "continue statement not inside loop")
3630 code.put_goto(code.continue_label)
3633 class ReturnStatNode(StatNode):
3636 # value ExprNode or None
3637 # return_type PyrexType
3639 child_attrs = ["value"]
3641 def analyse_expressions(self, env):
3642 return_type = env.return_type
3643 self.return_type = return_type
3645 error(self.pos, "Return not inside a function body")
3648 self.value.analyse_types(env)
3649 if return_type.is_void or return_type.is_returncode:
3650 error(self.value.pos,
3651 "Return with value in void function")
3653 self.value = self.value.coerce_to(env.return_type, env)
3655 if (not return_type.is_void
3656 and not return_type.is_pyobject
3657 and not return_type.is_returncode):
3658 error(self.pos, "Return value required")
3660 def nogil_check(self, env):
3661 if self.return_type.is_pyobject:
3664 gil_message = "Returning Python object"
3666 def generate_execution_code(self, code):
3667 code.mark_pos(self.pos)
3668 if not self.return_type:
3669 # error reported earlier
3671 if self.return_type.is_pyobject:
3672 code.put_xdecref(Naming.retval_cname,
3675 self.value.generate_evaluation_code(code)
3676 self.value.make_owned_reference(code)
3679 Naming.retval_cname,
3680 self.value.result_as(self.return_type)))
3681 self.value.generate_post_assignment_code(code)
3682 self.value.free_temps(code)
3684 if self.return_type.is_pyobject:
3685 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3686 elif self.return_type.is_returncode:
3689 Naming.retval_cname,
3690 self.return_type.default_value))
3691 for cname, type in code.funcstate.temps_holding_reference():
3692 code.put_decref_clear(cname, type)
3693 code.put_goto(code.return_label)
3695 def annotate(self, code):
3697 self.value.annotate(code)
3700 class RaiseStatNode(StatNode):
3703 # exc_type ExprNode or None
3704 # exc_value ExprNode or None
3705 # exc_tb ExprNode or None
3707 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3709 def analyse_expressions(self, env):
3711 self.exc_type.analyse_types(env)
3712 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3714 self.exc_value.analyse_types(env)
3715 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3717 self.exc_tb.analyse_types(env)
3718 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3719 env.use_utility_code(raise_utility_code)
3721 nogil_check = Node.gil_error
3722 gil_message = "Raising exception"
3724 def generate_execution_code(self, code):
3726 self.exc_type.generate_evaluation_code(code)
3727 type_code = self.exc_type.py_result()
3731 self.exc_value.generate_evaluation_code(code)
3732 value_code = self.exc_value.py_result()
3736 self.exc_tb.generate_evaluation_code(code)
3737 tb_code = self.exc_tb.py_result()
3741 "__Pyx_Raise(%s, %s, %s);" % (
3745 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3747 obj.generate_disposal_code(code)
3748 obj.free_temps(code)
3750 code.error_goto(self.pos))
3752 def annotate(self, code):
3754 self.exc_type.annotate(code)
3756 self.exc_value.annotate(code)
3758 self.exc_tb.annotate(code)
3761 class ReraiseStatNode(StatNode):
3765 def analyse_expressions(self, env):
3766 env.use_utility_code(restore_exception_utility_code)
3768 nogil_check = Node.gil_error
3769 gil_message = "Raising exception"
3771 def generate_execution_code(self, code):
3772 vars = code.funcstate.exc_vars
3774 for varname in vars:
3775 code.put_giveref(varname)
3776 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3777 for varname in vars:
3778 code.put("%s = 0; " % varname)
3780 code.putln(code.error_goto(self.pos))
3782 error(self.pos, "Reraise not inside except clause")
3785 class AssertStatNode(StatNode):
3789 # value ExprNode or None
3791 child_attrs = ["cond", "value"]
3793 def analyse_expressions(self, env):
3794 self.cond = self.cond.analyse_boolean_expression(env)
3796 self.value.analyse_types(env)
3797 self.value = self.value.coerce_to_pyobject(env)
3799 nogil_check = Node.gil_error
3800 gil_message = "Raising exception"
3802 def generate_execution_code(self, code):
3803 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3804 self.cond.generate_evaluation_code(code)
3806 "if (unlikely(!%s)) {" %
3809 self.value.generate_evaluation_code(code)
3811 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3812 self.value.py_result())
3813 self.value.generate_disposal_code(code)
3814 self.value.free_temps(code)
3817 "PyErr_SetNone(PyExc_AssertionError);")
3819 code.error_goto(self.pos))
3822 self.cond.generate_disposal_code(code)
3823 self.cond.free_temps(code)
3824 code.putln("#endif")
3826 def annotate(self, code):
3827 self.cond.annotate(code)
3829 self.value.annotate(code)
3832 class IfStatNode(StatNode):
3835 # if_clauses [IfClauseNode]
3836 # else_clause StatNode or None
3838 child_attrs = ["if_clauses", "else_clause"]
3840 def analyse_control_flow(self, env):
3841 env.start_branching(self.pos)
3842 for if_clause in self.if_clauses:
3843 if_clause.analyse_control_flow(env)
3844 env.next_branch(if_clause.end_pos())
3845 if self.else_clause:
3846 self.else_clause.analyse_control_flow(env)
3847 env.finish_branching(self.end_pos())
3849 def analyse_declarations(self, env):
3850 for if_clause in self.if_clauses:
3851 if_clause.analyse_declarations(env)
3852 if self.else_clause:
3853 self.else_clause.analyse_declarations(env)
3855 def analyse_expressions(self, env):
3856 for if_clause in self.if_clauses:
3857 if_clause.analyse_expressions(env)
3858 if self.else_clause:
3859 self.else_clause.analyse_expressions(env)
3861 def generate_execution_code(self, code):
3862 code.mark_pos(self.pos)
3863 end_label = code.new_label()
3864 for if_clause in self.if_clauses:
3865 if_clause.generate_execution_code(code, end_label)
3866 if self.else_clause:
3867 code.putln("/*else*/ {")
3868 self.else_clause.generate_execution_code(code)
3870 code.put_label(end_label)
3872 def annotate(self, code):
3873 for if_clause in self.if_clauses:
3874 if_clause.annotate(code)
3875 if self.else_clause:
3876 self.else_clause.annotate(code)
3879 class IfClauseNode(Node):
3880 # if or elif clause in an if statement
3882 # condition ExprNode
3885 child_attrs = ["condition", "body"]
3887 def analyse_control_flow(self, env):
3888 self.body.analyse_control_flow(env)
3890 def analyse_declarations(self, env):
3891 self.condition.analyse_declarations(env)
3892 self.body.analyse_declarations(env)
3894 def analyse_expressions(self, env):
3896 self.condition.analyse_temp_boolean_expression(env)
3897 self.body.analyse_expressions(env)
3899 def generate_execution_code(self, code, end_label):
3900 self.condition.generate_evaluation_code(code)
3903 self.condition.result())
3904 self.condition.generate_disposal_code(code)
3905 self.condition.free_temps(code)
3906 self.body.generate_execution_code(code)
3907 code.put_goto(end_label)
3910 def annotate(self, code):
3911 self.condition.annotate(code)
3912 self.body.annotate(code)
3915 class SwitchCaseNode(StatNode):
3916 # Generated in the optimization of an if-elif-else node
3918 # conditions [ExprNode]
3921 child_attrs = ['conditions', 'body']
3923 def generate_execution_code(self, code):
3924 for cond in self.conditions:
3925 code.mark_pos(cond.pos)
3926 cond.generate_evaluation_code(code)
3927 code.putln("case %s:" % cond.result())
3928 self.body.generate_execution_code(code)
3929 code.putln("break;")
3931 def annotate(self, code):
3932 for cond in self.conditions:
3934 self.body.annotate(code)
3936 class SwitchStatNode(StatNode):
3937 # Generated in the optimization of an if-elif-else node
3940 # cases [SwitchCaseNode]
3941 # else_clause StatNode or None
3943 child_attrs = ['test', 'cases', 'else_clause']
3945 def generate_execution_code(self, code):
3946 code.putln("switch (%s) {" % self.test.result())
3947 for case in self.cases:
3948 case.generate_execution_code(code)
3949 if self.else_clause is not None:
3950 code.putln("default:")
3951 self.else_clause.generate_execution_code(code)
3952 code.putln("break;")
3955 def annotate(self, code):
3956 self.test.annotate(code)
3957 for case in self.cases:
3959 if self.else_clause is not None:
3960 self.else_clause.annotate(code)
3962 class LoopNode(object):
3964 def analyse_control_flow(self, env):
3965 env.start_branching(self.pos)
3966 self.body.analyse_control_flow(env)
3967 env.next_branch(self.body.end_pos())
3968 if self.else_clause:
3969 self.else_clause.analyse_control_flow(env)
3970 env.finish_branching(self.end_pos())
3973 class WhileStatNode(LoopNode, StatNode):
3976 # condition ExprNode
3978 # else_clause StatNode
3980 child_attrs = ["condition", "body", "else_clause"]
3982 def analyse_declarations(self, env):
3983 self.body.analyse_declarations(env)
3984 if self.else_clause:
3985 self.else_clause.analyse_declarations(env)
3987 def analyse_expressions(self, env):
3989 self.condition.analyse_temp_boolean_expression(env)
3990 self.body.analyse_expressions(env)
3991 if self.else_clause:
3992 self.else_clause.analyse_expressions(env)
3994 def generate_execution_code(self, code):
3995 old_loop_labels = code.new_loop_labels()
3998 self.condition.generate_evaluation_code(code)
3999 self.condition.generate_disposal_code(code)
4002 self.condition.result())
4003 self.condition.free_temps(code)
4004 self.body.generate_execution_code(code)
4005 code.put_label(code.continue_label)
4007 break_label = code.break_label
4008 code.set_loop_labels(old_loop_labels)
4009 if self.else_clause:
4010 code.putln("/*else*/ {")
4011 self.else_clause.generate_execution_code(code)
4013 code.put_label(break_label)
4015 def annotate(self, code):
4016 self.condition.annotate(code)
4017 self.body.annotate(code)
4018 if self.else_clause:
4019 self.else_clause.annotate(code)
4022 def ForStatNode(pos, **kw):
4023 if 'iterator' in kw:
4024 return ForInStatNode(pos, **kw)
4026 return ForFromStatNode(pos, **kw)
4028 class ForInStatNode(LoopNode, StatNode):
4032 # iterator IteratorNode
4034 # else_clause StatNode
4035 # item NextNode used internally
4037 child_attrs = ["target", "iterator", "body", "else_clause"]
4040 def analyse_declarations(self, env):
4041 self.target.analyse_target_declaration(env)
4042 self.body.analyse_declarations(env)
4043 if self.else_clause:
4044 self.else_clause.analyse_declarations(env)
4046 def analyse_expressions(self, env):
4048 self.target.analyse_target_types(env)
4049 self.iterator.analyse_expressions(env)
4050 self.item = ExprNodes.NextNode(self.iterator, env)
4051 self.item = self.item.coerce_to(self.target.type, env)
4052 self.body.analyse_expressions(env)
4053 if self.else_clause:
4054 self.else_clause.analyse_expressions(env)
4056 def generate_execution_code(self, code):
4057 old_loop_labels = code.new_loop_labels()
4058 self.iterator.allocate_counter_temp(code)
4059 self.iterator.generate_evaluation_code(code)
4062 self.item.generate_evaluation_code(code)
4063 self.target.generate_assignment_code(self.item, code)
4064 self.body.generate_execution_code(code)
4065 code.put_label(code.continue_label)
4068 break_label = code.break_label
4069 code.set_loop_labels(old_loop_labels)
4070 if self.else_clause:
4071 code.putln("/*else*/ {")
4072 self.else_clause.generate_execution_code(code)
4074 code.put_label(break_label)
4075 self.iterator.release_counter_temp(code)
4076 self.iterator.generate_disposal_code(code)
4077 self.iterator.free_temps(code)
4079 def annotate(self, code):
4080 self.target.annotate(code)
4081 self.iterator.annotate(code)
4082 self.body.annotate(code)
4083 if self.else_clause:
4084 self.else_clause.annotate(code)
4085 self.item.annotate(code)
4088 class ForFromStatNode(LoopNode, StatNode):
4089 # for name from expr rel name rel expr
4096 # step ExprNode or None
4098 # else_clause StatNode or None
4104 # loopvar_node ExprNode (usually a NameNode or temp node)
4105 # py_loopvar_node PyTempNode or None
4106 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4108 is_py_target = False
4110 py_loopvar_node = None
4113 gil_message = "For-loop using object bounds or target"
4115 def nogil_check(self, env):
4116 for x in (self.target, self.bound1, self.bound2):
4117 if x.type.is_pyobject:
4120 def analyse_declarations(self, env):
4121 self.target.analyse_target_declaration(env)
4122 self.body.analyse_declarations(env)
4123 if self.else_clause:
4124 self.else_clause.analyse_declarations(env)
4126 def analyse_expressions(self, env):
4128 self.target.analyse_target_types(env)
4129 self.bound1.analyse_types(env)
4130 self.bound2.analyse_types(env)
4131 if self.step is not None:
4132 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4133 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4134 self.step.analyse_types(env)
4136 target_type = self.target.type
4137 if self.target.type.is_numeric:
4138 loop_type = self.target.type
4140 loop_type = PyrexTypes.c_int_type
4141 if not self.bound1.type.is_pyobject:
4142 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4143 if not self.bound2.type.is_pyobject:
4144 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4145 if self.step is not None and not self.step.type.is_pyobject:
4146 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4147 self.bound1 = self.bound1.coerce_to(loop_type, env)
4148 self.bound2 = self.bound2.coerce_to(loop_type, env)
4149 if not self.bound2.is_literal:
4150 self.bound2 = self.bound2.coerce_to_temp(env)
4151 if self.step is not None:
4152 self.step = self.step.coerce_to(loop_type, env)
4153 if not self.step.is_literal:
4154 self.step = self.step.coerce_to_temp(env)
4156 target_type = self.target.type
4157 if not (target_type.is_pyobject or target_type.is_numeric):
4158 error(self.target.pos,
4159 "for-from loop variable must be c numeric type or Python object")
4160 if target_type.is_numeric:
4161 self.is_py_target = False
4162 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4163 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4164 self.loopvar_node = self.target
4165 self.py_loopvar_node = None
4167 self.is_py_target = True
4168 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4169 self.loopvar_node = c_loopvar_node
4170 self.py_loopvar_node = \
4171 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4172 self.body.analyse_expressions(env)
4173 if self.else_clause:
4174 self.else_clause.analyse_expressions(env)
4176 def generate_execution_code(self, code):
4177 old_loop_labels = code.new_loop_labels()
4178 from_range = self.from_range
4179 self.bound1.generate_evaluation_code(code)
4180 self.bound2.generate_evaluation_code(code)
4181 offset, incop = self.relation_table[self.relation1]
4182 if self.step is not None:
4183 self.step.generate_evaluation_code(code)
4184 step = self.step.result()
4185 incop = "%s=%s" % (incop[0], step)
4187 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4188 self.loopvar_node.allocate(code)
4189 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4190 self.py_loopvar_node.allocate(code)
4192 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4194 loopvar_name = self.loopvar_node.result()
4196 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4198 self.bound1.result(), offset,
4199 loopvar_name, self.relation2, self.bound2.result(),
4200 loopvar_name, incop))
4201 if self.py_loopvar_node:
4202 self.py_loopvar_node.generate_evaluation_code(code)
4203 self.target.generate_assignment_code(self.py_loopvar_node, code)
4205 code.putln("%s = %s;" % (
4206 self.target.result(), loopvar_name))
4207 self.body.generate_execution_code(code)
4208 code.put_label(code.continue_label)
4209 if self.py_loopvar_node:
4210 # This mess is to make for..from loops with python targets behave
4211 # exactly like those with C targets with regards to re-assignment
4212 # of the loop variable.
4214 if self.target.entry.is_pyglobal:
4215 # We know target is a NameNode, this is the only ugly case.
4216 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4217 target_node.allocate(code)
4218 interned_cname = code.intern_identifier(self.target.entry.name)
4219 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4220 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4221 target_node.result(),
4222 Naming.module_cname,
4224 code.error_goto_if_null(target_node.result(), self.target.pos)))
4225 code.put_gotref(target_node.result())
4227 target_node = self.target
4228 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4229 from_py_node.temp_code = loopvar_name
4230 from_py_node.generate_result_code(code)
4231 if self.target.entry.is_pyglobal:
4232 code.put_decref(target_node.result(), target_node.type)
4233 target_node.release(code)
4235 if self.py_loopvar_node:
4236 # This is potentially wasteful, but we don't want the semantics to
4237 # depend on whether or not the loop is a python type.
4238 self.py_loopvar_node.generate_evaluation_code(code)
4239 self.target.generate_assignment_code(self.py_loopvar_node, code)
4241 code.funcstate.release_temp(loopvar_name)
4242 break_label = code.break_label
4243 code.set_loop_labels(old_loop_labels)
4244 if self.else_clause:
4245 code.putln("/*else*/ {")
4246 self.else_clause.generate_execution_code(code)
4248 code.put_label(break_label)
4249 self.bound1.generate_disposal_code(code)
4250 self.bound1.free_temps(code)
4251 self.bound2.generate_disposal_code(code)
4252 self.bound2.free_temps(code)
4253 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4254 self.loopvar_node.release(code)
4255 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4256 self.py_loopvar_node.release(code)
4257 if self.step is not None:
4258 self.step.generate_disposal_code(code)
4259 self.step.free_temps(code)
4262 # {relop : (initial offset, increment op)}
4269 def annotate(self, code):
4270 self.target.annotate(code)
4271 self.bound1.annotate(code)
4272 self.bound2.annotate(code)
4274 self.bound2.annotate(code)
4275 self.body.annotate(code)
4276 if self.else_clause:
4277 self.else_clause.annotate(code)
4280 class WithStatNode(StatNode):
4282 Represents a Python with statement.
4284 This is only used at parse tree level; and is not present in
4285 analysis or generation phases.
4287 # manager The with statement manager object
4288 # target Node (lhs expression)
4290 child_attrs = ["manager", "target", "body"]
4292 class TryExceptStatNode(StatNode):
4293 # try .. except statement
4296 # except_clauses [ExceptClauseNode]
4297 # else_clause StatNode or None
4299 child_attrs = ["body", "except_clauses", "else_clause"]
4301 def analyse_control_flow(self, env):
4302 env.start_branching(self.pos)
4303 self.body.analyse_control_flow(env)
4304 successful_try = env.control_flow # grab this for later
4305 env.next_branch(self.body.end_pos())
4306 env.finish_branching(self.body.end_pos())
4308 env.start_branching(self.except_clauses[0].pos)
4309 for except_clause in self.except_clauses:
4310 except_clause.analyse_control_flow(env)
4311 env.next_branch(except_clause.end_pos())
4313 # the else cause it executed only when the try clause finishes
4314 env.control_flow.incoming = successful_try
4315 if self.else_clause:
4316 self.else_clause.analyse_control_flow(env)
4317 env.finish_branching(self.end_pos())
4319 def analyse_declarations(self, env):
4320 self.body.analyse_declarations(env)
4321 for except_clause in self.except_clauses:
4322 except_clause.analyse_declarations(env)
4323 if self.else_clause:
4324 self.else_clause.analyse_declarations(env)
4325 env.use_utility_code(reset_exception_utility_code)
4327 def analyse_expressions(self, env):
4328 self.body.analyse_expressions(env)
4329 default_clause_seen = 0
4330 for except_clause in self.except_clauses:
4331 except_clause.analyse_expressions(env)
4332 if default_clause_seen:
4333 error(except_clause.pos, "default 'except:' must be last")
4334 if not except_clause.pattern:
4335 default_clause_seen = 1
4336 self.has_default_clause = default_clause_seen
4337 if self.else_clause:
4338 self.else_clause.analyse_expressions(env)
4340 nogil_check = Node.gil_error
4341 gil_message = "Try-except statement"
4343 def generate_execution_code(self, code):
4344 old_return_label = code.return_label
4345 old_break_label = code.break_label
4346 old_continue_label = code.continue_label
4347 old_error_label = code.new_error_label()
4348 our_error_label = code.error_label
4349 except_end_label = code.new_label('exception_handled')
4350 except_error_label = code.new_label('except_error')
4351 except_return_label = code.new_label('except_return')
4352 try_return_label = code.new_label('try_return')
4353 try_break_label = code.new_label('try_break')
4354 try_continue_label = code.new_label('try_continue')
4355 try_end_label = code.new_label('try_end')
4358 code.putln("PyObject %s;" %
4359 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4360 code.putln("__Pyx_ExceptionSave(%s);" %
4361 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4362 for var in Naming.exc_save_vars:
4363 code.put_xgotref(var)
4366 code.return_label = try_return_label
4367 code.break_label = try_break_label
4368 code.continue_label = try_continue_label
4369 self.body.generate_execution_code(code)
4372 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4373 code.error_label = except_error_label
4374 code.return_label = except_return_label
4375 if self.else_clause:
4378 self.else_clause.generate_execution_code(code)
4381 for var in Naming.exc_save_vars:
4382 code.put_xdecref_clear(var, py_object_type)
4383 code.put_goto(try_end_label)
4384 if code.label_used(try_return_label):
4385 code.put_label(try_return_label)
4386 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4387 code.putln("__Pyx_ExceptionReset(%s);" %
4388 ', '.join(Naming.exc_save_vars))
4389 code.put_goto(old_return_label)
4390 code.put_label(our_error_label)
4391 for temp_name, type in temps_to_clean_up:
4392 code.put_xdecref_clear(temp_name, type)
4393 for except_clause in self.except_clauses:
4394 except_clause.generate_handling_code(code, except_end_label)
4396 error_label_used = code.label_used(except_error_label)
4397 if error_label_used or not self.has_default_clause:
4398 if error_label_used:
4399 code.put_label(except_error_label)
4400 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4401 code.putln("__Pyx_ExceptionReset(%s);" %
4402 ', '.join(Naming.exc_save_vars))
4403 code.put_goto(old_error_label)
4405 for exit_label, old_label in zip(
4406 [try_break_label, try_continue_label, except_return_label],
4407 [old_break_label, old_continue_label, old_return_label]):
4409 if code.label_used(exit_label):
4410 code.put_label(exit_label)
4411 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4412 code.putln("__Pyx_ExceptionReset(%s);" %
4413 ', '.join(Naming.exc_save_vars))
4414 code.put_goto(old_label)
4416 if code.label_used(except_end_label):
4417 code.put_label(except_end_label)
4418 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4419 code.putln("__Pyx_ExceptionReset(%s);" %
4420 ', '.join(Naming.exc_save_vars))
4421 code.put_label(try_end_label)
4424 code.return_label = old_return_label
4425 code.break_label = old_break_label
4426 code.continue_label = old_continue_label
4427 code.error_label = old_error_label
4429 def annotate(self, code):
4430 self.body.annotate(code)
4431 for except_node in self.except_clauses:
4432 except_node.annotate(code)
4433 if self.else_clause:
4434 self.else_clause.annotate(code)
4437 class ExceptClauseNode(Node):
4438 # Part of try ... except statement.
4441 # target ExprNode or None
4443 # excinfo_target NameNode or None optional target for exception info
4444 # match_flag string result of exception match
4445 # exc_value ExcValueNode used internally
4446 # function_name string qualified name of enclosing function
4447 # exc_vars (string * 3) local exception variables
4449 # excinfo_target is never set by the parser, but can be set by a transform
4450 # in order to extract more extensive information about the exception as a
4451 # sys.exc_info()-style tuple into a target variable
4453 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4456 excinfo_target = None
4458 def analyse_declarations(self, env):
4460 self.target.analyse_target_declaration(env)
4461 if self.excinfo_target is not None:
4462 self.excinfo_target.analyse_target_declaration(env)
4463 self.body.analyse_declarations(env)
4465 def analyse_expressions(self, env):
4467 genv = env.global_scope()
4468 self.function_name = env.qualified_name
4470 self.pattern.analyse_expressions(env)
4471 self.pattern = self.pattern.coerce_to_pyobject(env)
4474 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4475 self.target.analyse_target_expression(env, self.exc_value)
4476 if self.excinfo_target is not None:
4478 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4479 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4480 self.excinfo_tuple.analyse_expressions(env)
4481 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4483 self.body.analyse_expressions(env)
4485 def generate_handling_code(self, code, end_label):
4486 code.mark_pos(self.pos)
4488 self.pattern.generate_evaluation_code(code)
4490 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4492 "%s = PyErr_ExceptionMatches(%s);" % (
4494 self.pattern.py_result()))
4495 self.pattern.generate_disposal_code(code)
4496 self.pattern.free_temps(code)
4500 code.funcstate.release_temp(match_flag)
4502 code.putln("/*except:*/ {")
4504 if not getattr(self.body, 'stats', True):
4505 # most simple case: no exception variable, empty body (pass)
4506 # => reset the exception state, done
4507 code.putln("PyErr_Restore(0,0,0);")
4508 code.put_goto(end_label)
4512 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4515 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4516 # We always have to fetch the exception value even if
4517 # there is no target, because this also normalises the
4518 # exception and stores it in the thread state.
4519 code.globalstate.use_utility_code(get_exception_utility_code)
4520 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4521 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4522 code.error_goto(self.pos)))
4526 self.exc_value.set_var(exc_vars[1])
4527 self.exc_value.generate_evaluation_code(code)
4528 self.target.generate_assignment_code(self.exc_value, code)
4529 if self.excinfo_target is not None:
4530 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4531 node.set_var(tempvar)
4532 self.excinfo_tuple.generate_evaluation_code(code)
4533 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4535 old_break_label, old_continue_label = code.break_label, code.continue_label
4536 code.break_label = code.new_label('except_break')
4537 code.continue_label = code.new_label('except_continue')
4539 old_exc_vars = code.funcstate.exc_vars
4540 code.funcstate.exc_vars = exc_vars
4541 self.body.generate_execution_code(code)
4542 code.funcstate.exc_vars = old_exc_vars
4543 for var in exc_vars:
4544 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4545 code.put_goto(end_label)
4547 if code.label_used(code.break_label):
4548 code.put_label(code.break_label)
4549 for var in exc_vars:
4550 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4551 code.put_goto(old_break_label)
4552 code.break_label = old_break_label
4554 if code.label_used(code.continue_label):
4555 code.put_label(code.continue_label)
4556 for var in exc_vars:
4557 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4558 code.put_goto(old_continue_label)
4559 code.continue_label = old_continue_label
4561 for temp in exc_vars:
4562 code.funcstate.release_temp(temp)
4567 def annotate(self, code):
4569 self.pattern.annotate(code)
4571 self.target.annotate(code)
4572 self.body.annotate(code)
4575 class TryFinallyStatNode(StatNode):
4576 # try ... finally statement
4579 # finally_clause StatNode
4581 # The plan is that we funnel all continue, break
4582 # return and error gotos into the beginning of the
4583 # finally block, setting a variable to remember which
4584 # one we're doing. At the end of the finally block, we
4585 # switch on the variable to figure out where to go.
4586 # In addition, if we're doing an error, we save the
4587 # exception on entry to the finally block and restore
4590 child_attrs = ["body", "finally_clause"]
4592 preserve_exception = 1
4594 disallow_continue_in_try_finally = 0
4595 # There doesn't seem to be any point in disallowing
4596 # continue in the try block, since we have no problem
4599 def create_analysed(pos, env, body, finally_clause):
4600 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4602 create_analysed = staticmethod(create_analysed)
4604 def analyse_control_flow(self, env):
4605 env.start_branching(self.pos)
4606 self.body.analyse_control_flow(env)
4607 env.next_branch(self.body.end_pos())
4608 env.finish_branching(self.body.end_pos())
4609 self.finally_clause.analyse_control_flow(env)
4611 def analyse_declarations(self, env):
4612 self.body.analyse_declarations(env)
4613 self.finally_clause.analyse_declarations(env)
4615 def analyse_expressions(self, env):
4616 self.body.analyse_expressions(env)
4617 self.finally_clause.analyse_expressions(env)
4619 nogil_check = Node.gil_error
4620 gil_message = "Try-finally statement"
4622 def generate_execution_code(self, code):
4623 old_error_label = code.error_label
4624 old_labels = code.all_new_labels()
4625 new_labels = code.get_all_labels()
4626 new_error_label = code.error_label
4627 catch_label = code.new_label()
4630 if self.disallow_continue_in_try_finally:
4631 was_in_try_finally = code.funcstate.in_try_finally
4632 code.funcstate.in_try_finally = 1
4633 self.body.generate_execution_code(code)
4634 if self.disallow_continue_in_try_finally:
4635 code.funcstate.in_try_finally = was_in_try_finally
4638 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4642 error_label_used = 0
4643 for i, new_label in enumerate(new_labels):
4644 if new_label in code.labels_used:
4645 cases_used.append(i)
4646 if new_label == new_error_label:
4647 error_label_used = 1
4648 error_label_case = i
4652 if error_label_used and self.preserve_exception:
4654 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4656 "int %s;" % Naming.exc_lineno_name)
4657 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4658 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4659 code.putln(exc_var_init_zero)
4661 exc_var_init_zero = None
4662 code.use_label(catch_label)
4664 "__pyx_why = 0; goto %s;" % catch_label)
4665 for i in cases_used:
4666 new_label = new_labels[i]
4667 #if new_label and new_label != "<try>":
4668 if new_label == new_error_label and self.preserve_exception:
4669 self.put_error_catcher(code,
4670 new_error_label, i+1, catch_label, temps_to_clean_up)
4672 code.put('%s: ' % new_label)
4673 if exc_var_init_zero:
4674 code.putln(exc_var_init_zero)
4675 code.putln("__pyx_why = %s; goto %s;" % (
4678 code.put_label(catch_label)
4679 code.set_all_labels(old_labels)
4680 if error_label_used:
4681 code.new_error_label()
4682 finally_error_label = code.error_label
4683 self.finally_clause.generate_execution_code(code)
4684 if error_label_used:
4685 if finally_error_label in code.labels_used and self.preserve_exception:
4686 over_label = code.new_label()
4687 code.put_goto(over_label);
4688 code.put_label(finally_error_label)
4689 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4690 for var in Naming.exc_vars:
4691 code.putln("Py_XDECREF(%s);" % var)
4693 code.put_goto(old_error_label)
4694 code.put_label(over_label)
4695 code.error_label = old_error_label
4698 "switch (__pyx_why) {")
4699 for i in cases_used:
4700 old_label = old_labels[i]
4701 if old_label == old_error_label and self.preserve_exception:
4702 self.put_error_uncatcher(code, i+1, old_error_label)
4704 code.use_label(old_label)
4706 "case %s: goto %s;" % (
4714 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4715 code.globalstate.use_utility_code(restore_exception_utility_code)
4722 for temp_name, type in temps_to_clean_up:
4723 code.put_xdecref_clear(temp_name, type)
4725 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4729 Naming.exc_lineno_name, Naming.lineno_cname))
4730 code.put_goto(catch_label)
4733 def put_error_uncatcher(self, code, i, error_label):
4734 code.globalstate.use_utility_code(restore_exception_utility_code)
4739 "__Pyx_ErrRestore(%s, %s, %s);" %
4743 Naming.lineno_cname, Naming.exc_lineno_name))
4744 for var in Naming.exc_vars:
4748 code.put_goto(error_label)
4752 def annotate(self, code):
4753 self.body.annotate(code)
4754 self.finally_clause.annotate(code)
4757 class GILStatNode(TryFinallyStatNode):
4758 # 'with gil' or 'with nogil' statement
4760 # state string 'gil' or 'nogil'
4764 preserve_exception = 0
4766 def __init__(self, pos, state, body):
4768 TryFinallyStatNode.__init__(self, pos,
4770 finally_clause = GILExitNode(pos, state = state))
4772 def analyse_expressions(self, env):
4773 env.use_utility_code(force_init_threads_utility_code)
4774 was_nogil = env.nogil
4776 TryFinallyStatNode.analyse_expressions(self, env)
4777 env.nogil = was_nogil
4781 def generate_execution_code(self, code):
4782 code.mark_pos(self.pos)
4783 if self.state == 'gil':
4784 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4786 code.putln("{ PyThreadState *_save;")
4787 code.putln("Py_UNBLOCK_THREADS")
4788 TryFinallyStatNode.generate_execution_code(self, code)
4792 class GILExitNode(StatNode):
4793 # Used as the 'finally' block in a GILStatNode
4795 # state string 'gil' or 'nogil'
4799 def analyse_expressions(self, env):
4802 def generate_execution_code(self, code):
4803 if self.state == 'gil':
4804 code.putln("PyGILState_Release();")
4806 code.putln("Py_BLOCK_THREADS")
4809 class CImportStatNode(StatNode):
4812 # module_name string Qualified name of module being imported
4813 # as_name string or None Name specified in "as" clause, if any
4817 def analyse_declarations(self, env):
4818 if not env.is_module_scope:
4819 error(self.pos, "cimport only allowed at module level")
4821 module_scope = env.find_module(self.module_name, self.pos)
4822 if "." in self.module_name:
4823 names = [EncodedString(name) for name in self.module_name.split(".")]
4825 top_module_scope = env.context.find_submodule(top_name)
4826 module_scope = top_module_scope
4827 for name in names[1:]:
4828 submodule_scope = module_scope.find_submodule(name)
4829 module_scope.declare_module(name, submodule_scope, self.pos)
4830 module_scope = submodule_scope
4832 env.declare_module(self.as_name, module_scope, self.pos)
4834 env.declare_module(top_name, top_module_scope, self.pos)
4836 name = self.as_name or self.module_name
4837 env.declare_module(name, module_scope, self.pos)
4839 def analyse_expressions(self, env):
4842 def generate_execution_code(self, code):
4846 class FromCImportStatNode(StatNode):
4847 # from ... cimport statement
4849 # module_name string Qualified name of module
4850 # imported_names [(pos, name, as_name, kind)] Names to be imported
4854 def analyse_declarations(self, env):
4855 if not env.is_module_scope:
4856 error(self.pos, "cimport only allowed at module level")
4858 module_scope = env.find_module(self.module_name, self.pos)
4859 env.add_imported_module(module_scope)
4860 for pos, name, as_name, kind in self.imported_names:
4862 for local_name, entry in module_scope.entries.items():
4863 env.add_imported_entry(local_name, entry, pos)
4865 entry = module_scope.lookup(name)
4867 if kind and not self.declaration_matches(entry, kind):
4868 entry.redeclared(pos)
4870 if kind == 'struct' or kind == 'union':
4871 entry = module_scope.declare_struct_or_union(name,
4872 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4873 elif kind == 'class':
4874 entry = module_scope.declare_c_class(name, pos = pos,
4875 module_name = self.module_name)
4877 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4878 if submodule_scope.parent_module is module_scope:
4879 env.declare_module(as_name or name, submodule_scope, self.pos)
4881 error(pos, "Name '%s' not declared in module '%s'"
4882 % (name, self.module_name))
4885 local_name = as_name or name
4886 env.add_imported_entry(local_name, entry, pos)
4888 def declaration_matches(self, entry, kind):
4889 if not entry.is_type:
4893 if not type.is_extension_type:
4896 if not type.is_struct_or_union:
4898 if kind != type.kind:
4902 def analyse_expressions(self, env):
4905 def generate_execution_code(self, code):
4909 class FromImportStatNode(StatNode):
4910 # from ... import statement
4913 # items [(string, NameNode)]
4914 # interned_items [(string, NameNode, ExprNode)]
4915 # item PyTempNode used internally
4916 # import_star boolean used internally
4918 child_attrs = ["module"]
4921 def analyse_declarations(self, env):
4922 for name, target in self.items:
4924 if not env.is_module_scope:
4925 error(self.pos, "import * only allowed at module level")
4927 env.has_import_star = 1
4928 self.import_star = 1
4930 target.analyse_target_declaration(env)
4932 def analyse_expressions(self, env):
4934 self.module.analyse_expressions(env)
4935 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
4936 self.interned_items = []
4937 for name, target in self.items:
4939 for _, entry in env.entries.items():
4940 if not entry.is_type and entry.type.is_extension_type:
4941 env.use_utility_code(ExprNodes.type_test_utility_code)
4944 entry = env.lookup(target.name)
4945 if (entry.is_type and
4946 entry.type.name == name and
4947 entry.type.module_name == self.module.module_name.value):
4948 continue # already cimported
4949 target.analyse_target_expression(env, None)
4950 if target.type is py_object_type:
4953 coerced_item = self.item.coerce_to(target.type, env)
4954 self.interned_items.append(
4955 (name, target, coerced_item))
4957 def generate_execution_code(self, code):
4958 self.module.generate_evaluation_code(code)
4959 if self.import_star:
4961 'if (%s(%s) < 0) %s;' % (
4963 self.module.py_result(),
4964 code.error_goto(self.pos)))
4965 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
4966 self.item.set_cname(item_temp)
4967 for name, target, coerced_item in self.interned_items:
4968 cname = code.intern_identifier(name)
4970 '%s = PyObject_GetAttr(%s, %s); %s' % (
4972 self.module.py_result(),
4974 code.error_goto_if_null(item_temp, self.pos)))
4975 code.put_gotref(item_temp)
4976 if coerced_item is None:
4977 target.generate_assignment_code(self.item, code)
4979 coerced_item.allocate_temp_result(code)
4980 coerced_item.generate_result_code(code)
4981 target.generate_assignment_code(coerced_item, code)
4982 code.put_decref_clear(item_temp, py_object_type)
4983 code.funcstate.release_temp(item_temp)
4984 self.module.generate_disposal_code(code)
4985 self.module.free_temps(code)
4989 #------------------------------------------------------------------------------------
4991 # Runtime support code
4993 #------------------------------------------------------------------------------------
4995 utility_function_predeclarations = \
4997 #ifndef CYTHON_INLINE
4998 #if defined(__GNUC__)
4999 #define CYTHON_INLINE __inline__
5000 #elif defined(_MSC_VER)
5001 #define CYTHON_INLINE __inline
5002 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5003 #define CYTHON_INLINE inline
5005 #define CYTHON_INLINE
5009 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*/
5013 if Options.gcc_branch_hints:
5014 branch_prediction_macros = \
5017 /* Test for GCC > 2.95 */
5018 #if __GNUC__ > 2 || \
5019 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5020 #define likely(x) __builtin_expect(!!(x), 1)
5021 #define unlikely(x) __builtin_expect(!!(x), 0)
5022 #else /* __GNUC__ > 2 ... */
5023 #define likely(x) (x)
5024 #define unlikely(x) (x)
5025 #endif /* __GNUC__ > 2 ... */
5026 #else /* __GNUC__ */
5027 #define likely(x) (x)
5028 #define unlikely(x) (x)
5029 #endif /* __GNUC__ */
5032 branch_prediction_macros = \
5034 #define likely(x) (x)
5035 #define unlikely(x) (x)
5038 #get_name_predeclaration = \
5039 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5041 #get_name_interned_predeclaration = \
5042 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5044 #------------------------------------------------------------------------------------
5046 printing_utility_code = UtilityCode(
5048 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5049 #if PY_MAJOR_VERSION >= 3
5050 static PyObject* %s = 0;
5051 static PyObject* %s = 0;
5053 """ % (Naming.print_function, Naming.print_function_kwargs),
5055 #if PY_MAJOR_VERSION >= 3
5059 """ % (Naming.print_function, Naming.print_function_kwargs),
5061 #if PY_MAJOR_VERSION < 3
5062 static PyObject *__Pyx_GetStdout(void) {
5063 PyObject *f = PySys_GetObject((char *)"stdout");
5065 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5070 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5075 if (!(f = __Pyx_GetStdout()))
5078 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5079 if (PyFile_SoftSpace(f, 1)) {
5080 if (PyFile_WriteString(" ", f) < 0)
5083 v = PyTuple_GET_ITEM(arg_tuple, i);
5084 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5086 if (PyString_Check(v)) {
5087 char *s = PyString_AsString(v);
5088 Py_ssize_t len = PyString_Size(v);
5090 isspace(Py_CHARMASK(s[len-1])) &&
5092 PyFile_SoftSpace(f, 0);
5096 if (PyFile_WriteString("\n", f) < 0)
5098 PyFile_SoftSpace(f, 0);
5103 #else /* Python 3 has a print function */
5105 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5106 PyObject* kwargs = 0;
5107 PyObject* result = 0;
5108 PyObject* end_string;
5109 if (!%(PRINT_FUNCTION)s) {
5110 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5111 if (!%(PRINT_FUNCTION)s)
5115 kwargs = PyDict_New();
5116 if (unlikely(!kwargs))
5118 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5124 kwargs = %(PRINT_KWARGS)s;
5126 %(PRINT_KWARGS)s = PyDict_New();
5127 if unlikely((!%(PRINT_KWARGS)s))
5129 kwargs = %(PRINT_KWARGS)s;
5131 end_string = PyUnicode_FromStringAndSize(" ", 1);
5132 if (unlikely(!end_string))
5134 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5135 Py_DECREF(end_string);
5138 Py_DECREF(end_string);
5140 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5141 if (unlikely(kwargs) && (kwargs != %(PRINT_FUNCTION)s))
5148 if (kwargs != %(PRINT_FUNCTION)s)
5154 """ % {'BUILTINS' : Naming.builtins_cname,
5155 'PRINT_FUNCTION' : Naming.print_function,
5156 'PRINT_KWARGS' : Naming.print_function_kwargs}
5160 printing_one_utility_code = UtilityCode(
5162 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5165 #if PY_MAJOR_VERSION < 3
5167 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5169 if (!(f = __Pyx_GetStdout()))
5172 if (PyFile_SoftSpace(f, 0)) {
5173 if (PyFile_WriteString(" ", f) < 0)
5176 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5178 if (PyFile_WriteString("\n", f) < 0)
5181 /* the line below is just to avoid compiler
5182 * compiler warnings about unused functions */
5183 return __Pyx_Print(f, NULL, 0);
5186 #else /* Python 3 has a print function */
5188 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5190 PyObject* arg_tuple = PyTuple_New(1);
5191 if (unlikely(!arg_tuple))
5194 PyTuple_SET_ITEM(arg_tuple, 0, o);
5195 res = __Pyx_Print(stream, arg_tuple, 1);
5196 Py_DECREF(arg_tuple);
5202 requires=[printing_utility_code])
5206 #------------------------------------------------------------------------------------
5208 # Exception raising code
5210 # Exceptions are raised by __Pyx_Raise() and stored as plain
5211 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5212 # 'except' statement, curexc_* is moved over to exc_* by
5213 # __Pyx_GetException()
5215 restore_exception_utility_code = UtilityCode(
5217 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5218 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5221 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5222 PyObject *tmp_type, *tmp_value, *tmp_tb;
5223 PyThreadState *tstate = PyThreadState_GET();
5225 tmp_type = tstate->curexc_type;
5226 tmp_value = tstate->curexc_value;
5227 tmp_tb = tstate->curexc_traceback;
5228 tstate->curexc_type = type;
5229 tstate->curexc_value = value;
5230 tstate->curexc_traceback = tb;
5231 Py_XDECREF(tmp_type);
5232 Py_XDECREF(tmp_value);
5236 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5237 PyThreadState *tstate = PyThreadState_GET();
5238 *type = tstate->curexc_type;
5239 *value = tstate->curexc_value;
5240 *tb = tstate->curexc_traceback;
5242 tstate->curexc_type = 0;
5243 tstate->curexc_value = 0;
5244 tstate->curexc_traceback = 0;
5249 # The following function is based on do_raise() from ceval.c. There
5250 # are separate versions for Python2 and Python3 as exception handling
5251 # has changed quite a lot between the two versions.
5253 raise_utility_code = UtilityCode(
5255 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5258 #if PY_MAJOR_VERSION < 3
5259 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5263 /* First, check the traceback argument, replacing None with NULL. */
5264 if (tb == Py_None) {
5268 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5269 PyErr_SetString(PyExc_TypeError,
5270 "raise: arg 3 must be a traceback or None");
5273 /* Next, replace a missing value with None */
5274 if (value == NULL) {
5278 #if PY_VERSION_HEX < 0x02050000
5279 if (!PyClass_Check(type))
5281 if (!PyType_Check(type))
5284 /* Raising an instance. The value should be a dummy. */
5285 if (value != Py_None) {
5286 PyErr_SetString(PyExc_TypeError,
5287 "instance exception may not have a separate value");
5290 /* Normalize to raise <class>, <instance> */
5293 #if PY_VERSION_HEX < 0x02050000
5294 if (PyInstance_Check(type)) {
5295 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5300 PyErr_SetString(PyExc_TypeError,
5301 "raise: exception must be an old-style class or instance");
5305 type = (PyObject*) Py_TYPE(type);
5307 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5308 PyErr_SetString(PyExc_TypeError,
5309 "raise: exception class must be a subclass of BaseException");
5315 __Pyx_ErrRestore(type, value, tb);
5324 #else /* Python 3+ */
5326 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5327 if (tb == Py_None) {
5329 } else if (tb && !PyTraceBack_Check(tb)) {
5330 PyErr_SetString(PyExc_TypeError,
5331 "raise: arg 3 must be a traceback or None");
5334 if (value == Py_None)
5337 if (PyExceptionInstance_Check(type)) {
5339 PyErr_SetString(PyExc_TypeError,
5340 "instance exception may not have a separate value");
5344 type = (PyObject*) Py_TYPE(value);
5345 } else if (!PyExceptionClass_Check(type)) {
5346 PyErr_SetString(PyExc_TypeError,
5347 "raise: exception class must be a subclass of BaseException");
5351 PyErr_SetObject(type, value);
5354 PyThreadState *tstate = PyThreadState_GET();
5355 PyObject* tmp_tb = tstate->curexc_traceback;
5358 tstate->curexc_traceback = tb;
5368 requires=[restore_exception_utility_code])
5370 #------------------------------------------------------------------------------------
5372 get_exception_utility_code = UtilityCode(
5374 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5377 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5378 PyObject *local_type, *local_value, *local_tb;
5379 PyObject *tmp_type, *tmp_value, *tmp_tb;
5380 PyThreadState *tstate = PyThreadState_GET();
5381 local_type = tstate->curexc_type;
5382 local_value = tstate->curexc_value;
5383 local_tb = tstate->curexc_traceback;
5384 tstate->curexc_type = 0;
5385 tstate->curexc_value = 0;
5386 tstate->curexc_traceback = 0;
5387 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5388 if (unlikely(tstate->curexc_type))
5390 #if PY_MAJOR_VERSION >= 3
5391 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5395 *value = local_value;
5397 Py_INCREF(local_type);
5398 Py_INCREF(local_value);
5399 Py_INCREF(local_tb);
5400 tmp_type = tstate->exc_type;
5401 tmp_value = tstate->exc_value;
5402 tmp_tb = tstate->exc_traceback;
5403 tstate->exc_type = local_type;
5404 tstate->exc_value = local_value;
5405 tstate->exc_traceback = local_tb;
5406 /* Make sure tstate is in a consistent state when we XDECREF
5407 these objects (XDECREF may run arbitrary code). */
5408 Py_XDECREF(tmp_type);
5409 Py_XDECREF(tmp_value);
5416 Py_XDECREF(local_type);
5417 Py_XDECREF(local_value);
5418 Py_XDECREF(local_tb);
5424 #------------------------------------------------------------------------------------
5426 get_exception_tuple_utility_code = UtilityCode(proto="""
5427 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5429 # I doubt that calling __Pyx_GetException() here is correct as it moves
5430 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5431 # exception handlers later on from receiving it.
5433 static PyObject *__Pyx_GetExceptionTuple(void) {
5434 PyObject *type = NULL, *value = NULL, *tb = NULL;
5435 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5436 PyObject* exc_info = PyTuple_New(3);
5441 PyTuple_SET_ITEM(exc_info, 0, type);
5442 PyTuple_SET_ITEM(exc_info, 1, value);
5443 PyTuple_SET_ITEM(exc_info, 2, tb);
5450 requires=[get_exception_utility_code])
5452 #------------------------------------------------------------------------------------
5454 reset_exception_utility_code = UtilityCode(
5456 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5457 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5460 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5461 PyThreadState *tstate = PyThreadState_GET();
5462 *type = tstate->exc_type;
5463 *value = tstate->exc_value;
5464 *tb = tstate->exc_traceback;
5470 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5471 PyObject *tmp_type, *tmp_value, *tmp_tb;
5472 PyThreadState *tstate = PyThreadState_GET();
5473 tmp_type = tstate->exc_type;
5474 tmp_value = tstate->exc_value;
5475 tmp_tb = tstate->exc_traceback;
5476 tstate->exc_type = type;
5477 tstate->exc_value = value;
5478 tstate->exc_traceback = tb;
5479 Py_XDECREF(tmp_type);
5480 Py_XDECREF(tmp_value);
5485 #------------------------------------------------------------------------------------
5487 arg_type_test_utility_code = UtilityCode(
5489 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5490 const char *name, int exact); /*proto*/
5493 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5494 const char *name, int exact)
5497 PyErr_Format(PyExc_SystemError, "Missing type object");
5500 if (none_allowed && obj == Py_None) return 1;
5502 if (Py_TYPE(obj) == type) return 1;
5505 if (PyObject_TypeCheck(obj, type)) return 1;
5507 PyErr_Format(PyExc_TypeError,
5508 "Argument '%s' has incorrect type (expected %s, got %s)",
5509 name, type->tp_name, Py_TYPE(obj)->tp_name);
5514 #------------------------------------------------------------------------------------
5516 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5517 # many or too few positional arguments were found. This handles
5518 # Py_ssize_t formatting correctly.
5520 raise_argtuple_invalid_utility_code = UtilityCode(
5522 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5523 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5526 static void __Pyx_RaiseArgtupleInvalid(
5527 const char* func_name,
5531 Py_ssize_t num_found)
5533 Py_ssize_t num_expected;
5534 const char *number, *more_or_less;
5536 if (num_found < num_min) {
5537 num_expected = num_min;
5538 more_or_less = "at least";
5540 num_expected = num_max;
5541 more_or_less = "at most";
5544 more_or_less = "exactly";
5546 number = (num_expected == 1) ? "" : "s";
5547 PyErr_Format(PyExc_TypeError,
5548 #if PY_VERSION_HEX < 0x02050000
5549 "%s() takes %s %d positional argument%s (%d given)",
5551 "%s() takes %s %zd positional argument%s (%zd given)",
5553 func_name, more_or_less, num_expected, number, num_found);
5557 raise_keyword_required_utility_code = UtilityCode(
5559 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5562 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5563 const char* func_name,
5566 PyErr_Format(PyExc_TypeError,
5567 #if PY_MAJOR_VERSION >= 3
5568 "%s() needs keyword-only argument %U", func_name, kw_name);
5570 "%s() needs keyword-only argument %s", func_name,
5571 PyString_AS_STRING(kw_name));
5576 raise_double_keywords_utility_code = UtilityCode(
5578 static void __Pyx_RaiseDoubleKeywordsError(
5579 const char* func_name, PyObject* kw_name); /*proto*/
5582 static void __Pyx_RaiseDoubleKeywordsError(
5583 const char* func_name,
5586 PyErr_Format(PyExc_TypeError,
5587 #if PY_MAJOR_VERSION >= 3
5588 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5590 "%s() got multiple values for keyword argument '%s'", func_name,
5591 PyString_AS_STRING(kw_name));
5596 #------------------------------------------------------------------------------------
5598 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5599 # were passed to a function, or if any keywords were passed to a
5600 # function that does not accept them.
5602 keyword_string_check_utility_code = UtilityCode(
5604 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5605 const char* function_name, int kw_allowed); /*proto*/
5608 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5610 const char* function_name,
5615 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5616 #if PY_MAJOR_VERSION < 3
5617 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5619 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5621 goto invalid_keyword_type;
5623 if ((!kw_allowed) && unlikely(key))
5624 goto invalid_keyword;
5626 invalid_keyword_type:
5627 PyErr_Format(PyExc_TypeError,
5628 "%s() keywords must be strings", function_name);
5631 PyErr_Format(PyExc_TypeError,
5632 #if PY_MAJOR_VERSION < 3
5633 "%s() got an unexpected keyword argument '%s'",
5634 function_name, PyString_AsString(key));
5636 "%s() got an unexpected keyword argument '%U'",
5637 function_name, key);
5643 #------------------------------------------------------------------------------------
5645 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5646 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5647 # keywords will raise an invalid keyword error.
5649 # Three kinds of errors are checked: 1) non-string keywords, 2)
5650 # unexpected keywords and 3) overlap with positional arguments.
5652 # If num_posargs is greater 0, it denotes the number of positional
5653 # arguments that were passed and that must therefore not appear
5654 # amongst the keywords as well.
5656 # This method does not check for required keyword arguments.
5659 parse_keywords_utility_code = UtilityCode(
5661 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5662 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5663 const char* function_name); /*proto*/
5666 static int __Pyx_ParseOptionalKeywords(
5668 PyObject **argnames[],
5671 Py_ssize_t num_pos_args,
5672 const char* function_name)
5674 PyObject *key = 0, *value = 0;
5677 PyObject*** first_kw_arg = argnames + num_pos_args;
5679 while (PyDict_Next(kwds, &pos, &key, &value)) {
5680 name = first_kw_arg;
5681 while (*name && (**name != key)) name++;
5683 values[name-argnames] = value;
5685 #if PY_MAJOR_VERSION < 3
5686 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5688 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5690 goto invalid_keyword_type;
5692 for (name = first_kw_arg; *name; name++) {
5693 #if PY_MAJOR_VERSION >= 3
5694 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5695 PyUnicode_Compare(**name, key) == 0) break;
5697 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5698 _PyString_Eq(**name, key)) break;
5702 values[name-argnames] = value;
5704 /* unexpected keyword found */
5705 for (name=argnames; name != first_kw_arg; name++) {
5706 if (**name == key) goto arg_passed_twice;
5707 #if PY_MAJOR_VERSION >= 3
5708 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5709 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5711 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5712 _PyString_Eq(**name, key)) goto arg_passed_twice;
5716 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5718 goto invalid_keyword;
5726 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5728 invalid_keyword_type:
5729 PyErr_Format(PyExc_TypeError,
5730 "%s() keywords must be strings", function_name);
5733 PyErr_Format(PyExc_TypeError,
5734 #if PY_MAJOR_VERSION < 3
5735 "%s() got an unexpected keyword argument '%s'",
5736 function_name, PyString_AsString(key));
5738 "%s() got an unexpected keyword argument '%U'",
5739 function_name, key);
5746 #------------------------------------------------------------------------------------
5748 traceback_utility_code = UtilityCode(
5750 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5753 #include "compile.h"
5754 #include "frameobject.h"
5755 #include "traceback.h"
5757 static void __Pyx_AddTraceback(const char *funcname) {
5758 PyObject *py_srcfile = 0;
5759 PyObject *py_funcname = 0;
5760 PyObject *py_globals = 0;
5761 PyCodeObject *py_code = 0;
5762 PyFrameObject *py_frame = 0;
5764 #if PY_MAJOR_VERSION < 3
5765 py_srcfile = PyString_FromString(%(FILENAME)s);
5767 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5769 if (!py_srcfile) goto bad;
5771 #if PY_MAJOR_VERSION < 3
5772 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5774 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5778 #if PY_MAJOR_VERSION < 3
5779 py_funcname = PyString_FromString(funcname);
5781 py_funcname = PyUnicode_FromString(funcname);
5784 if (!py_funcname) goto bad;
5785 py_globals = PyModule_GetDict(%(GLOBALS)s);
5786 if (!py_globals) goto bad;
5787 py_code = PyCode_New(
5788 0, /*int argcount,*/
5789 #if PY_MAJOR_VERSION >= 3
5790 0, /*int kwonlyargcount,*/
5793 0, /*int stacksize,*/
5795 %(EMPTY_BYTES)s, /*PyObject *code,*/
5796 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5797 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5798 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5799 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5800 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5801 py_srcfile, /*PyObject *filename,*/
5802 py_funcname, /*PyObject *name,*/
5803 %(LINENO)s, /*int firstlineno,*/
5804 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5806 if (!py_code) goto bad;
5807 py_frame = PyFrame_New(
5808 PyThreadState_GET(), /*PyThreadState *tstate,*/
5809 py_code, /*PyCodeObject *code,*/
5810 py_globals, /*PyObject *globals,*/
5811 0 /*PyObject *locals*/
5813 if (!py_frame) goto bad;
5814 py_frame->f_lineno = %(LINENO)s;
5815 PyTraceBack_Here(py_frame);
5817 Py_XDECREF(py_srcfile);
5818 Py_XDECREF(py_funcname);
5819 Py_XDECREF(py_code);
5820 Py_XDECREF(py_frame);
5823 'FILENAME': Naming.filename_cname,
5824 'LINENO': Naming.lineno_cname,
5825 'CFILENAME': Naming.cfilenm_cname,
5826 'CLINENO': Naming.clineno_cname,
5827 'GLOBALS': Naming.module_cname,
5828 'EMPTY_TUPLE' : Naming.empty_tuple,
5829 'EMPTY_BYTES' : Naming.empty_bytes,
5832 #------------------------------------------------------------------------------------
5834 unraisable_exception_utility_code = UtilityCode(
5836 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5839 static void __Pyx_WriteUnraisable(const char *name) {
5840 PyObject *old_exc, *old_val, *old_tb;
5842 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5843 #if PY_MAJOR_VERSION < 3
5844 ctx = PyString_FromString(name);
5846 ctx = PyUnicode_FromString(name);
5848 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5850 PyErr_WriteUnraisable(Py_None);
5852 PyErr_WriteUnraisable(ctx);
5857 requires=[restore_exception_utility_code])
5859 #------------------------------------------------------------------------------------
5861 set_vtable_utility_code = UtilityCode(
5863 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5866 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5867 #if PY_VERSION_HEX < 0x03010000
5868 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
5870 PyObject *ob = PyCapsule_New(vtable, 0, 0);
5874 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
5884 #------------------------------------------------------------------------------------
5886 get_vtable_utility_code = UtilityCode(
5888 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5891 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5892 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5895 #if PY_VERSION_HEX < 0x03010000
5896 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
5898 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
5900 if (!*(void **)vtabptr)
5910 #------------------------------------------------------------------------------------
5912 init_string_tab_utility_code = UtilityCode(
5914 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5917 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5919 #if PY_MAJOR_VERSION < 3
5920 if (t->is_unicode) {
5921 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5922 } else if (t->intern) {
5923 *t->p = PyString_InternFromString(t->s);
5925 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5927 #else /* Python 3+ has unicode identifiers */
5928 if (t->is_unicode | t->is_str) {
5930 *t->p = PyUnicode_InternFromString(t->s);
5931 } else if (t->encoding) {
5932 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
5934 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5937 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5948 #------------------------------------------------------------------------------------
5950 force_init_threads_utility_code = UtilityCode(
5952 #ifndef __PYX_FORCE_INIT_THREADS
5953 #if PY_VERSION_HEX < 0x02040200
5954 #define __PYX_FORCE_INIT_THREADS 1
5956 #define __PYX_FORCE_INIT_THREADS 0
5961 #------------------------------------------------------------------------------------
5963 # Note that cPython ignores PyTrace_EXCEPTION,
5964 # but maybe some other profilers don't.
5966 profile_utility_code = UtilityCode(proto="""
5967 #ifndef CYTHON_PROFILE
5968 #define CYTHON_PROFILE 1
5971 #ifndef CYTHON_PROFILE_REUSE_FRAME
5972 #define CYTHON_PROFILE_REUSE_FRAME 0
5977 #include "compile.h"
5978 #include "frameobject.h"
5979 #include "traceback.h"
5981 #if CYTHON_PROFILE_REUSE_FRAME
5982 #define CYTHON_FRAME_MODIFIER static
5983 #define CYTHON_FRAME_DEL
5985 #define CYTHON_FRAME_MODIFIER
5986 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
5989 #define __Pyx_TraceDeclarations \\
5990 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
5991 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
5992 int __Pyx_use_tracing = 0;
5994 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
5995 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
5996 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
5999 #define __Pyx_TraceException() \\
6000 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6001 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6003 PyThreadState_GET()->c_profilefunc( \\
6004 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6005 Py_DECREF(exc_info); \\
6009 #define __Pyx_TraceReturn(result) \\
6010 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6011 PyThreadState_GET()->c_profilefunc( \\
6012 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6013 CYTHON_FRAME_DEL; \\
6016 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6017 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6021 #define __Pyx_TraceDeclarations
6022 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6023 #define __Pyx_TraceException()
6024 #define __Pyx_TraceReturn(result)
6026 #endif /* CYTHON_PROFILE */
6029 "FRAME": Naming.frame_cname,
6030 "FRAME_CODE": Naming.frame_code_cname,
6036 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6037 PyFrameObject** frame,
6038 const char *funcname,
6039 const char *srcfile,
6041 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6042 if (*code == NULL) {
6043 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6044 if (*code == NULL) return 0;
6046 *frame = PyFrame_New(
6047 PyThreadState_GET(), /*PyThreadState *tstate*/
6048 *code, /*PyCodeObject *code*/
6049 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6050 0 /*PyObject *locals*/
6052 if (*frame == NULL) return 0;
6055 (*frame)->f_tstate = PyThreadState_GET();
6057 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6060 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6061 PyObject *py_srcfile = 0;
6062 PyObject *py_funcname = 0;
6063 PyCodeObject *py_code = 0;
6065 #if PY_MAJOR_VERSION < 3
6066 py_funcname = PyString_FromString(funcname);
6067 py_srcfile = PyString_FromString(srcfile);
6069 py_funcname = PyUnicode_FromString(funcname);
6070 py_srcfile = PyUnicode_FromString(srcfile);
6072 if (!py_funcname | !py_srcfile) goto bad;
6074 py_code = PyCode_New(
6075 0, /*int argcount,*/
6076 #if PY_MAJOR_VERSION >= 3
6077 0, /*int kwonlyargcount,*/
6080 0, /*int stacksize,*/
6082 %(EMPTY_BYTES)s, /*PyObject *code,*/
6083 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6084 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6085 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6086 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6087 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6088 py_srcfile, /*PyObject *filename,*/
6089 py_funcname, /*PyObject *name,*/
6090 firstlineno, /*int firstlineno,*/
6091 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6095 Py_XDECREF(py_srcfile);
6096 Py_XDECREF(py_funcname);
6101 #endif /* CYTHON_PROFILE */
6103 'EMPTY_TUPLE' : Naming.empty_tuple,
6104 'EMPTY_BYTES' : Naming.empty_bytes,
6105 "MODULE": Naming.module_cname,