def validate_axes(pos, axes): if len(axes) >= Options.buffer_max_dims: error(pos, "More dimensions than the maximum number" " of buffer dimensions were used.") return False return True
def error(self, message, pos = None, fatal = True): if pos is None: pos = self.position() if self.sy == 'INDENT': err = error(pos, "Possible inconsistent indentation") err = error(pos, message) if fatal: raise err
def declare_struct_or_union(self, name, kind, scope, typedef_flag, pos, cname = None, visibility = 'private', is_cplus = 0, base_types = None): # Add an entry for a struct or union definition. if not cname: if self.in_cinclude or visibility == 'public': cname = name else: cname = self.mangle(Naming.type_prefix, name) entry = self.lookup_here(name) if not entry: type = CStructOrUnionType(name, kind, scope, typedef_flag, cname, is_cplus = is_cplus, base_types = base_types) entry = self.declare_type(name, type, pos, cname, visibility = visibility, defining = scope is not None) self.sue_entries.append(entry) else: if not (entry.is_type and entry.type.is_struct_or_union and entry.type.kind == kind): entry.redeclared(pos) elif scope and entry.type.scope: error(pos, "'%s' already defined" % name) else: self.check_previous_typedef_flag(entry, typedef_flag, pos) self.check_previous_visibility(entry, visibility, pos) if scope: entry.pos = pos entry.type.set_scope(scope) self.type_entries.append(entry) if not scope and not entry.type.scope: self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) return entry
def error(self, message, pos=None, fatal=True): if pos is None: pos = self.position() if self.sy == 'INDENT': err = error(pos, "Possible inconsistent indentation") err = error(pos, message) if fatal: raise err
def report(self): self.messages.sort() for pos, is_error, message in self.messages: if is_error: error(pos, message) else: warning(pos, message, 2)
def get_copy_new_utility(pos, from_memview, to_memview): if from_memview.dtype != to_memview.dtype: return error(pos, "dtypes must be the same!") if len(from_memview.axes) != len(to_memview.axes): return error(pos, "number of dimensions must be same") if not (to_memview.is_c_contig or to_memview.is_f_contig): return error(pos, "to_memview must be c or f contiguous.") for (access, packing) in from_memview.axes: if access != 'direct': return error(pos, "cannot handle 'full' or 'ptr' access at this time.") if to_memview.is_c_contig: mode = 'c' contig_flag = memview_c_contiguous elif to_memview.is_f_contig: mode = 'fortran' contig_flag = memview_f_contiguous return load_memview_c_utility( "CopyContentsUtility", context=dict(context, mode=mode, dtype_decl=to_memview.dtype.declaration_code(''), contig_flag=contig_flag, ndim=to_memview.ndim, func_cname=copy_c_or_fortran_cname(to_memview), dtype_is_object=int(to_memview.dtype.is_pyobject)), requires=[copy_contents_new_utility])
def parse(self, source_desc, scope, pxd, full_module_name): if not isinstance(source_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") source_filename = source_desc.filename scope.cpp = self.cpp # Parse the given source file and return a parse tree. try: f = Utils.open_source_file(source_filename, "rU") try: import Parsing s = PyrexScanner(f, source_desc, source_encoding=f.encoding, scope=scope, context=self) tree = Parsing.p_module(s, pxd, full_module_name) finally: f.close() except UnicodeDecodeError, msg: #import traceback #traceback.print_exc() error(( source_desc, 0, 0 ), "Decoding error, missing or incorrect coding=<encoding-name> at top of source (%s)" % msg)
def declare_var(self, name, type, pos, cname = None, visibility = 'private', is_cdef = 0): # Add an entry for an attribute. if self.defined: error(pos, "C attributes cannot be added in implementation part of" " extension type") if get_special_method_signature(name): error(pos, "The name '%s' is reserved for a special method." % name) if not cname: cname = name entry = self.declare(name, cname, type, pos) entry.visibility = visibility entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject: self.has_pyobject_attrs = 1 if visibility not in ('private', 'public', 'readonly'): error(pos, "Attribute of extension type cannot be declared %s" % visibility) if visibility in ('public', 'readonly'): if type.pymemberdef_typecode: self.public_attr_entries.append(entry) else: error(pos, "C attribute of type '%s' cannot be accessed from Python" % type) if visibility == 'public' and type.is_extension_type: error(pos, "Non-generic Python attribute cannot be exposed for writing from Python") return entry
def declare_global(self, name, pos): # Pull entry from global scope into local scope. if self.lookup_here(name): error(pos, "'%s' redeclared") else: entry = self.global_scope().lookup_target(name) self.entries[name] = entry
def find_include_file(self, filename, pos): # Search list of include directories for filename. # Reports an error and returns None if not found. path = self.search_include_directories(filename, "", pos, include=True) if not path: error(pos, "'%s' not found" % filename) return path
def find(self, name, pos): # Look up name, report error if not found. entry = self.lookup(name) if entry: return entry else: error(pos, "'%s' is not declared" % name)
def declare_struct_or_union(self, name, kind, scope, typedef_flag, pos, cname=None): # Add an entry for a struct or union definition. if not cname: if self.in_cinclude: cname = name else: cname = self.mangle(Naming.type_prefix, name) entry = self.lookup_here(name) if not entry: type = CStructOrUnionType(name, kind, scope, typedef_flag, cname) entry = self.declare_type(name, type, pos, cname) self.sue_entries.append(entry) else: if not (entry.is_type and entry.type.is_struct_or_union): error(pos, "'%s' redeclared" % name) elif scope and entry.type.scope: error(pos, "'%s' already defined" % name) else: self.check_previous_typedef_flag(entry, typedef_flag, pos) if scope: entry.type.scope = scope if not scope and not entry.type.scope: self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) return entry
def generate_enum_definition(self, entry, code): type = entry.type name = entry.cname or entry.name or "" header, footer = \ self.sue_header_footer(type, "enum", name) code.putln("") code.putln(header) enum_values = entry.enum_values if not enum_values: error(entry.pos, "Empty enum definition not allowed outside a" " 'cdef extern from' block") else: last_entry = enum_values[-1] for value_entry in enum_values: if value_entry.value == value_entry.name: value_code = value_entry.cname else: value_code = ("%s = %s" % ( value_entry.cname, value_entry.value)) if value_entry is not last_entry: value_code += "," code.putln(value_code) code.putln(footer)
def mark_assignment(self, lhs, rhs, inplace_op=None): if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)): if lhs.entry is None: # TODO: This shouldn't happen... return if self.parallel_block_stack: parallel_node = self.parallel_block_stack[-1] previous_assignment = parallel_node.assignments.get(lhs.entry) # If there was a previous assignment to the variable, keep the # previous assignment position if previous_assignment: pos, previous_inplace_op = previous_assignment if (inplace_op and previous_inplace_op and inplace_op != previous_inplace_op): # x += y; x *= y t = (inplace_op, previous_inplace_op) error(lhs.pos, "Reduction operator '%s' is inconsistent " "with previous reduction operator '%s'" % t) else: pos = lhs.pos parallel_node.assignments[lhs.entry] = (pos, inplace_op) parallel_node.assigned_nodes.append(lhs) elif isinstance(lhs, ExprNodes.SequenceNode): for arg in lhs.args: self.mark_assignment(arg, object_expr) else: # Could use this info to infer cdef class attributes... pass
def declare_struct_or_union(self, name, kind, scope, typedef_flag, pos, cname = None): # Add an entry for a struct or union definition. if not cname: if self.in_cinclude: cname = name else: cname = self.mangle(Naming.type_prefix, name) entry = self.lookup_here(name) if not entry: type = CStructOrUnionType(name, kind, scope, typedef_flag, cname) entry = self.declare_type(name, type, pos, cname) self.sue_entries.append(entry) else: if not (entry.is_type and entry.type.is_struct_or_union): error(pos, "'%s' redeclared" % name) elif scope and entry.type.scope: error(pos, "'%s' already defined" % name) else: self.check_previous_typedef_flag(entry, typedef_flag, pos) if scope: entry.type.scope = scope if not scope and not entry.type.scope: self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) return entry
def get_copy_new_utility(pos, from_memview, to_memview): if from_memview.dtype != to_memview.dtype: return error(pos, "dtypes must be the same!") if len(from_memview.axes) != len(to_memview.axes): return error(pos, "number of dimensions must be same") if not (to_memview.is_c_contig or to_memview.is_f_contig): return error(pos, "to_memview must be c or f contiguous.") for (access, packing) in from_memview.axes: if access != 'direct': return error( pos, "cannot handle 'full' or 'ptr' access at this time.") if to_memview.is_c_contig: mode = 'c' contig_flag = memview_c_contiguous elif to_memview.is_f_contig: mode = 'fortran' contig_flag = memview_f_contiguous return load_memview_c_utility( "CopyContentsUtility", context=dict( context, mode=mode, dtype_decl=to_memview.dtype.declaration_code(''), contig_flag=contig_flag, ndim=to_memview.ndim, func_cname=copy_c_or_fortran_cname(to_memview), dtype_is_object=int(to_memview.dtype.is_pyobject)), requires=[copy_contents_new_utility])
def mark_assignment(self, lhs, rhs, inplace_op=None): if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)): if lhs.entry is None: # TODO: This shouldn't happen... return if self.parallel_block_stack: parallel_node = self.parallel_block_stack[-1] previous_assignment = parallel_node.assignments.get(lhs.entry) # If there was a previous assignment to the variable, keep the # previous assignment position if previous_assignment: pos, previous_inplace_op = previous_assignment if (inplace_op and previous_inplace_op and inplace_op != previous_inplace_op): # x += y; x *= y t = (inplace_op, previous_inplace_op) error( lhs.pos, "Reduction operator '%s' is inconsistent " "with previous reduction operator '%s'" % t) else: pos = lhs.pos parallel_node.assignments[lhs.entry] = (pos, inplace_op) parallel_node.assigned_nodes.append(lhs) elif isinstance(lhs, ExprNodes.SequenceNode): for arg in lhs.args: self.mark_assignment(arg, object_expr) else: # Could use this info to infer cdef class attributes... pass
def declare_global(self, name, pos): # Pull entry from global scope into local scope. if self.lookup_here(name): error(pos, "'%s' already declared") else: entry = self.global_scope().lookup_target(name) self.entries[name] = entry
def generate_type_ready_code(self, env, entry, code): # Generate a call to PyType_Ready for an extension # type defined in this module. type = entry.type typeobj_cname = type.typeobj_cname scope = type.scope if scope: # could be None if there was an error if entry.visibility <> 'extern': for slot in TypeSlots.slot_table: slot.generate_dynamic_init_code(scope, code) code.putln("if (PyType_Ready(&%s) < 0) %s" % (typeobj_cname, code.error_goto(entry.pos))) if type.vtable_cname: code.putln("if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (typeobj_cname, type.vtabptr_cname, code.error_goto(entry.pos))) env.use_utility_code(Nodes.set_vtable_utility_code) code.putln( 'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (Naming.module_cname, scope.class_name, typeobj_cname, code.error_goto(entry.pos))) weakref_entry = scope.lookup_here("__weakref__") if weakref_entry: if weakref_entry.type is py_object_type: tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname code.putln( "if (%s == 0) %s = offsetof(struct %s, %s);" % (tp_weaklistoffset, tp_weaklistoffset, type.objstruct_cname, weakref_entry.cname)) else: error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
def declare_var(self, name, type, pos, cname=None, visibility='private', is_cdef=0): # Add an entry for a global variable. If it is a Python # object type, and not declared with cdef, it will live # in the module dictionary, otherwise it will be a C # global variable. entry = Scope.declare_var(self, name, type, pos, cname, visibility, is_cdef) if not visibility in ('private', 'public', 'extern'): error(pos, "Module-level variable cannot be declared %s" % visibility) if not is_cdef: if not (type.is_pyobject and not type.is_extension_type): raise InternalError( "Non-cdef global variable is not a generic Python object") entry.is_pyglobal = 1 entry.namespace_cname = self.module_cname if Options.intern_names: entry.interned_cname = self.intern(name) else: entry.is_cglobal = 1 self.var_entries.append(entry) return entry
def check_c_classes(self): # Performs post-analysis checking and finishing up of extension types # being implemented in this module. This is called only for the main # .pyx file scope, not for cimported .pxd scopes. # # Checks all extension types declared in this scope to # make sure that: # # * The extension type is implemented # * All required object and type names have been specified or generated # * All non-inherited C methods are implemented # # Also carries out the following: # * Allocates vtable-related names if needed. # debug_check_c_classes = 0 if debug_check_c_classes: print "Scope.check_c_classes: checking scope", self.qualified_name for entry in self.c_class_entries: if debug_check_c_classes: print "...entry", entry.name, entry print "......type =", entry.type print "......visibility =", entry.visibility type = entry.type name = entry.name visibility = entry.visibility # Check defined if not type.scope: error(entry.pos, "C class '%s' is declared but not defined" % name) # Generate typeobj_cname if visibility <> 'extern' and not type.typeobj_cname: type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) ## Generate typeptr_cname #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) # Check C methods defined if type.scope: for method_entry in type.scope.cfunc_entries: if not method_entry.is_inherited and not method_entry.func_cname: error(method_entry.pos, "C method '%s' is declared but not defined" % method_entry.name) ## Generate var entry #self.attach_var_entry_to_c_class(entry) # Allocated vtable-related names if necessary #print "ModuleScope.check_c_classes:", type ### if type.base_type and type.base_type.vtabslot_cname: #print "...allocating vtabslot_cname because base type has one" ### type.vtabslot_cname = "%s.%s" % ( Naming.obj_base_cname, type.base_type.vtabslot_cname) elif type.scope and type.scope.cfunc_entries: #print "...allocating vtabslot_cname because there are C methods" ### type.vtabslot_cname = Naming.vtabslot_cname if type.vtabslot_cname: #print "...allocating other vtable related cnames" ### type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name) type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name) type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
def visit_NameNode(self, node): if self.flow.block: entry = node.entry or self.env.lookup(node.name) if entry: self.flow.mark_reference(node, entry) if entry in self.reductions and not self.in_inplace_assignment: error(node.pos, "Cannot read reduction variable in loop body") return node
def declare_var(self, name, type, pos, cname = None, visibility = 'private', is_cdef = 0): # Add an entry for a local variable. if visibility in ('public', 'readonly'): error(pos, "Local variable cannot be declared %s" % visibility) entry = Scope.declare_var(self, name, type, pos, cname, visibility, is_cdef) entry.init_to_none = type.is_pyobject self.var_entries.append(entry) return entry
def visit_DelStatNode(self, node): for arg in node.args: if arg.is_name: entry = arg.entry or self.env.lookup(arg.name) if entry.in_closure or entry.from_closure: error(arg.pos, "can not delete variable '%s' " "referenced in nested scope" % entry.name) # Mark reference self.visit(arg) self.flow.mark_deletion(arg, entry) return node
def declare_pyfunction(self, name, pos): # Add an entry for a method. signature = get_property_accessor_signature(name) if signature: entry = self.declare(name, name, py_object_type, pos) entry.signature = signature return entry else: error(pos, "Only __get__, __set__ and __del__ methods allowed " "in a property declaration") return None
def find_module(self, module_name, relative_to = None, pos = None, need_pxd = 1): # Finds and returns the module scope corresponding to # the given relative or absolute module name. If this # is the first time the module has been requested, finds # the corresponding .pxd file and process it. # If relative_to is not None, it must be a module scope, # and the module will first be searched for relative to # that module, provided its name is not a dotted name. debug_find_module = 0 if debug_find_module: print("Context.find_module: module_name = %s, relative_to = %s, pos = %s, need_pxd = %s" % ( module_name, relative_to, pos, need_pxd)) scope = None pxd_pathname = None if "." not in module_name and relative_to: if debug_find_module: print("...trying relative import") scope = relative_to.lookup_submodule(module_name) if not scope: qualified_name = relative_to.qualify_name(module_name) pxd_pathname = self.find_pxd_file(qualified_name, pos) if pxd_pathname: scope = relative_to.find_submodule(module_name) if not scope: if debug_find_module: print("...trying absolute import") scope = self for name in module_name.split("."): scope = scope.find_submodule(name) if debug_find_module: print("...scope =", scope) if not scope.pxd_file_loaded: if debug_find_module: print("...pxd not loaded") scope.pxd_file_loaded = 1 if not pxd_pathname: if debug_find_module: print("...looking for pxd file") pxd_pathname = self.find_pxd_file(module_name, pos) if debug_find_module: print("......found ", pxd_pathname) if not pxd_pathname and need_pxd: error(pos, "'%s.pxd' not found" % module_name) if pxd_pathname: try: if debug_find_module: print("Context.find_module: Parsing %s" % pxd_pathname) pxd_tree = self.parse(pxd_pathname, scope.type_names, pxd = 1, full_module_name = module_name) pxd_tree.analyse_declarations(scope) except CompileError: pass return scope
def visit_DelStatNode(self, node): for arg in node.args: if arg.is_name: entry = arg.entry or self.env.lookup(arg.name) if entry.in_closure or entry.from_closure: error( arg.pos, "can not delete variable '%s' " "referenced in nested scope" % entry.name) # Mark reference self._visit(arg) self.flow.mark_deletion(arg, entry) return node
def declare_pyfunction(self, name, pos): # Add an entry for a method. signature = get_property_accessor_signature(name) if signature: entry = self.declare(name, name, py_object_type, pos) entry.signature = signature return entry else: error( pos, "Only __get__, __set__ and __del__ methods allowed " "in a property declaration") return None
def declare_cfunction(self, name, type, pos, **kwds): #print "StructOrUnionScope.declare_cfunction:", name ### if not self.is_cplus: error(pos, "C struct/union member cannot be a function") # Define it anyway to suppress further errors elif name == "__init__": type.pos = pos self.cplus_constructors.append(type) return #kwds['defining'] = 1 #Scope.declare_cfunction(self, name, type, pos, *args, **kwds) self.declare_var(name, type, pos, **kwds)
def declare(self, name, cname, type, pos): # Create new entry, and add to dictionary if # name is not None. Reports an error if already # declared. dict = self.entries if name and dict.has_key(name): error(pos, "'%s' already declared" % name) entry = Entry(name, cname, type, pos = pos) entry.in_cinclude = self.in_cinclude if name: entry.qualified_name = self.qualify_name(name) dict[name] = entry return entry
def find_qualified_name(self, module_and_name, pos): # Look up qualified name, report error if not found. # module_and_name = [path, name] where path is a list of names. module_path, name = module_and_name scope = self.find_imported_module(module_path, pos) if scope: entry = scope.lookup_here(name) if not entry: mess = "'%s' is not declared" % name if module_path: mess = "%s in module '%s'" % (mess, ".".join(module_path)) error(pos, mess) return entry
def declare(self, name, cname, type, pos): # Create new entry, and add to dictionary if # name is not None. Reports an error if already # declared. dict = self.entries if name and dict.has_key(name): error(pos, "'%s' redeclared" % name) entry = Entry(name, cname, type, pos=pos) entry.in_cinclude = self.in_cinclude if name: entry.qualified_name = self.qualify_name(name) dict[name] = entry return entry
def find_imported_module(self, path, pos): # Look up qualified name, must be a module, report error if not found. # Path is a list of names. scope = self for name in path: entry = scope.find(name, pos) if not entry: return None if entry.as_module: scope = entry.as_module else: error(pos, "'%s' is not a cimported module" % scope.qualified_name) return None return scope
def parse(self, source_desc, scope, pxd, full_module_name): if not isinstance(source_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") source_filename = source_desc.filename scope.cpp = self.cpp # Parse the given source file and return a parse tree. num_errors = Errors.num_errors try: f = Utils.open_source_file(source_filename, "rU") try: import Parsing s = PyrexScanner(f, source_desc, source_encoding=f.encoding, scope=scope, context=self) tree = Parsing.p_module(s, pxd, full_module_name) finally: f.close() except UnicodeDecodeError, e: #import traceback #traceback.print_exc() line = 1 column = 0 msg = e.args[-1] position = e.args[2] encoding = e.args[0] f = open(source_filename, "rb") try: byte_data = f.read() finally: f.close() # FIXME: make this at least a little less inefficient for idx, c in enumerate(byte_data): if c in (ord('\n'), '\n'): line += 1 column = 0 if idx == position: break column += 1 error( (source_desc, line, column), "Decoding error, missing or incorrect coding=<encoding-name> " "at top of source (cannot decode with encoding %r: %s)" % (encoding, msg))
def declare_module(self, name, scope, pos): # Declare a cimported module. This is represented as a # Python module-level variable entry with a module # scope attached to it. Reports an error and returns # None if previously declared as something else. entry = self.lookup_here(name) if entry: if not (entry.is_pyglobal and not entry.as_module): error(pos, "'%s' redeclared" % name) return None else: entry = self.declare_var(name, py_object_type, pos) entry.as_module = scope self.cimported_modules.append(scope) return entry
def declare_var(self, name, type, pos, cname = None, visibility = 'private', **kwds): # Add an entry for an attribute. if not cname: cname = name entry = self.declare(name, cname, type, pos) entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject: error(pos, "C struct/union member cannot be a Python object") if visibility <> 'private': error(pos, "C struct/union member cannot be declared %s" % visibility) return entry
def declare_var(self, name, type, pos, cname=None, visibility='private', is_cdef=0): # Add an entry for a local variable. if visibility in ('public', 'readonly'): error(pos, "Local variable cannot be declared %s" % visibility) entry = Scope.declare_var(self, name, type, pos, cname, visibility, is_cdef) entry.init_to_none = type.is_pyobject self.var_entries.append(entry) return entry
def check_c_classes(self): # Performs post-analysis checking and finishing up of extension types # being implemented in this module. This is called only for the main # .pyx file scope, not for cimported .pxd scopes. # # Checks all extension types declared in this scope to # make sure that: # # * The extension type is implemented # * All required object and type names have been specified or generated # * All non-inherited C methods are implemented # # Also allocates a name for the vtable if needed. # debug_check_c_classes = 0 if debug_check_c_classes: print "Scope.check_c_classes: checking scope", self.qualified_name for entry in self.c_class_entries: if debug_check_c_classes: print "...entry", entry.name, entry print "......type =", entry.type print "......visibility =", entry.visibility type = entry.type name = entry.name visibility = entry.visibility # Check defined if not type.scope: error(entry.pos, "C class '%s' is declared but not defined" % name) # Generate typeobj_cname if visibility <> 'extern' and not type.typeobj_cname: type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) ## Generate typeptr_cname #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) # Check C methods defined if type.scope: for method_entry in type.scope.cfunc_entries: if not method_entry.is_inherited and not method_entry.func_cname: error( method_entry.pos, "C method '%s' is declared but not defined" % method_entry.name) # Allocate vtable name if necessary if type.vtabslot_cname: #print "ModuleScope.check_c_classes: allocating vtable cname for", self ### type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
def parse(self, source_desc, scope, pxd, full_module_name): if not isinstance(source_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") source_filename = source_desc.filename scope.cpp = self.cpp # Parse the given source file and return a parse tree. num_errors = Errors.num_errors try: f = Utils.open_source_file(source_filename, "rU") try: import Parsing s = PyrexScanner(f, source_desc, source_encoding=f.encoding, scope=scope, context=self) tree = Parsing.p_module(s, pxd, full_module_name) finally: f.close() except UnicodeDecodeError, e: # import traceback # traceback.print_exc() line = 1 column = 0 msg = e.args[-1] position = e.args[2] encoding = e.args[0] f = open(source_filename, "rb") try: byte_data = f.read() finally: f.close() # FIXME: make this at least a little less inefficient for idx, c in enumerate(byte_data): if c in (ord("\n"), "\n"): line += 1 column = 0 if idx == position: break column += 1 error( (source_desc, line, column), "Decoding error, missing or incorrect coding=<encoding-name> " "at top of source (cannot decode with encoding %r: %s)" % (encoding, msg), )
def parse(self, source_desc, scope, pxd, full_module_name): if not isinstance(source_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") source_filename = Utils.encode_filename(source_desc.filename) # Parse the given source file and return a parse tree. try: f = Utils.open_source_file(source_filename, "rU") try: s = PyrexScanner(f, source_desc, source_encoding = f.encoding, scope = scope, context = self) tree = Parsing.p_module(s, pxd, full_module_name) finally: f.close() except UnicodeDecodeError, msg: #import traceback #traceback.print_exc() error((source_desc, 0, 0), "Decoding error, missing or incorrect coding=<encoding-name> at top of source (%s)" % msg)
def generate_struct_union_definition(self, entry, code): type = entry.type scope = type.scope if scope: header, footer = \ self.sue_header_footer(type, type.kind, type.cname) code.putln("") code.putln(header) var_entries = scope.var_entries if not var_entries: error( entry.pos, "Empty struct or union definition not allowed outside a" " 'cdef extern from' block") for attr in var_entries: code.putln("%s;" % attr.type.declaration_code(attr.cname)) code.putln(footer)
def visit_ParallelStatNode(self, node): if self.parallel_block_stack: node.parent = self.parallel_block_stack[-1] else: node.parent = None nested = False if node.is_prange: if not node.parent: node.is_parallel = True else: node.is_parallel = (node.parent.is_prange or not node.parent.is_parallel) nested = node.parent.is_prange else: node.is_parallel = True # Note: nested with parallel() blocks are handled by # ParallelRangeTransform! # nested = node.parent nested = node.parent and node.parent.is_prange self.parallel_block_stack.append(node) nested = nested or len(self.parallel_block_stack) > 2 if not self.parallel_errors and nested: error(node.pos, "Parallel nesting not supported due to bugs in gcc 4.5") self.parallel_errors = True if node.is_prange: child_attrs = node.child_attrs node.child_attrs = ['body', 'target', 'args'] self.visitchildren(node) node.child_attrs = child_attrs self.parallel_block_stack.pop() if node.else_clause: node.else_clause = self.visit(node.else_clause) else: self.visitchildren(node) self.parallel_block_stack.pop() self.parallel_errors = False return node
def generate_struct_union_definition(self, entry, code): type = entry.type scope = type.scope if scope: header, footer = \ self.sue_header_footer(type, type.kind, type.cname) code.putln("") code.putln(header) var_entries = scope.var_entries if not var_entries: error(entry.pos, "Empty struct or union definition not allowed outside a" " 'cdef extern from' block") for attr in var_entries: code.putln( "%s;" % attr.type.declaration_code(attr.cname)) code.putln(footer)
def check_c_classes(self): # Performs post-analysis checking and finishing up of extension types # being implemented in this module. This is called only for the main # .pyx file scope and its associated .pxd scope, not for cimported .pxd # scopes. # # Checks all extension types declared in this scope to # make sure that: # # * The extension type is implemented # * All required object and type names have been specified or generated # * All non-inherited C methods are implemented # # Also allocates a name for the vtable if needed. # debug_check_c_classes = 0 if debug_check_c_classes: print "Scope.check_c_classes: checking scope", self.qualified_name for entry in self.c_class_entries: if debug_check_c_classes: print "...entry", entry.name, entry print "......type =", entry.type print "......visibility =", entry.visibility type = entry.type name = entry.name visibility = entry.visibility # Check defined if not type.scope: error(entry.pos, "C class '%s' is declared but not defined" % name) # Generate typeobj_cname if visibility <> 'extern' and not type.typeobj_cname: type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) ## Generate typeptr_cname #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) # Check C methods defined if type.scope: for method_entry in type.scope.cfunc_entries: if not method_entry.is_inherited and not method_entry.func_cname: error(method_entry.pos, "C method '%s' is declared but not defined" % method_entry.name) # Allocate vtable name if necessary if type.vtabslot_cname: #print "ModuleScope.check_c_classes: allocating vtable cname for", self ### type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
def declare_var(self, name, type, pos, cname=None, visibility='private', is_cdef=0): # Add an entry for an attribute. if not cname: cname = name entry = self.declare(name, cname, type, pos) entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject: error(pos, "C struct/union member cannot be a Python object") if visibility <> 'private': error(pos, "C struct/union member cannot be declared %s" % visibility) return entry
def visit_ParallelStatNode(self, node): if self.parallel_block_stack: node.parent = self.parallel_block_stack[-1] else: node.parent = None nested = False if node.is_prange: if not node.parent: node.is_parallel = True else: node.is_parallel = node.parent.is_prange or not node.parent.is_parallel nested = node.parent.is_prange else: node.is_parallel = True # Note: nested with parallel() blocks are handled by # ParallelRangeTransform! # nested = node.parent nested = node.parent and node.parent.is_prange self.parallel_block_stack.append(node) nested = nested or len(self.parallel_block_stack) > 2 if not self.parallel_errors and nested and not node.is_prange: error(node.pos, "Only prange() may be nested") self.parallel_errors = True if node.is_prange: child_attrs = node.child_attrs node.child_attrs = ["body", "target", "args"] self.visitchildren(node) node.child_attrs = child_attrs self.parallel_block_stack.pop() if node.else_clause: node.else_clause = self.visit(node.else_clause) else: self.visitchildren(node) self.parallel_block_stack.pop() self.parallel_errors = False return node
def find_submodule(self, module_name): entry = self.entries.get(module_name, None) if entry and entry.as_module: return entry.as_module else: # TODO: fix find_submodule control flow so that we're not # expected to create a submodule here (to protect CythonScope's # possible immutability). Hack ourselves out of the situation # for now. raise error((StringSourceDescriptor(u"cython", u""), 0, 0), "cython.%s is not available" % module_name)
def declare_var(self, name, type, pos, cname=None, visibility='private', is_cdef=0): # Add an entry for an attribute. if self.defined: error( pos, "C attributes cannot be added in implementation part of" " extension type") if get_special_method_signature(name): error(pos, "The name '%s' is reserved for a special method." % name) if not cname: cname = name entry = self.declare(name, cname, type, pos) entry.visibility = visibility entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject: self.has_pyobject_attrs = 1 if visibility not in ('private', 'public', 'readonly'): error( pos, "Attribute of extension type cannot be declared %s" % visibility) if visibility in ('public', 'readonly'): if type.pymemberdef_typecode: self.public_attr_entries.append(entry) else: error( pos, "C attribute of type '%s' cannot be accessed from Python" % type) if visibility == 'public' and type.is_extension_type: error( pos, "Non-generic Python attribute cannot be exposed for writing from Python" ) return entry
def generate_enum_definition(self, entry, code): type = entry.type name = entry.cname or entry.name or "" header, footer = \ self.sue_header_footer(type, "enum", name) code.putln("") code.putln(header) enum_values = entry.enum_values if not enum_values: error( entry.pos, "Empty enum definition not allowed outside a" " 'cdef extern from' block") else: last_entry = enum_values[-1] for value_entry in enum_values: if value_entry.value == value_entry.name: value_code = value_entry.cname else: value_code = ("%s = %s" % (value_entry.cname, value_entry.value)) if value_entry is not last_entry: value_code += "," code.putln(value_code) code.putln(footer)
def find_module(self, module_name, pos): error("cython.%s is not available" % module_name, pos)
def visit_YieldExprNode(self, node): if self.parallel_block_stack: error(node.pos, "Yield not allowed in parallel sections") return node
def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos): if typedef_flag and not self.in_cinclude: error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")