def Export(self, codeunit, exported_names): if not self.info.exclude: decls = self.GetDeclarations(self.info.name) for decl in decls: self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy) self.ExportDeclaration(decl, len(decls) == 1, codeunit) self.ExportOpaquePointer(decl, codeunit) self.GenerateOverloads(decls, codeunit) exported_names[self.Name()] = 1
def MethodDefinition(self, method): '''Returns a list of lines, which should be put inside the class_ statement to export this method.''' # dont define abstract methods pyste = namespaces.pyste rename = self.info[method.name].rename or method.name default_names = self.DefaultImplementationNames(method) class_name = self.class_.FullName() wrapper_name = pyste + self.wrapper_name result = method.result.FullName() is_method_unique = method.is_unique constantness = '' if method.const: constantness = ' const' # create a list of default-impl pointers minArgs = method.minArgs maxArgs = method.maxArgs if method.abstract: default_pointers = [] elif is_method_unique: default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names] else: default_pointers = [] for impl_name, argNum in zip(default_names, range(minArgs, maxArgs + 1)): param_list = [x.FullName() for x in method.parameters[:argNum]] params = ', '.join(param_list) signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness) default_pointer = '(%s)&%s::%s' % (signature, wrapper_name, impl_name) default_pointers.append(default_pointer) # get the pointer of the method pointer = method.PointerDeclaration() if method.abstract: pointer = namespaces.python + ('pure_virtual(%s)' % pointer) # warn the user if this method needs a policy and doesn't have one method_info = self.info[method.name] method_info.policy = exporterutils.HandlePolicy(method, method_info.policy) # Add policy to overloaded methods also policy = method_info.policy or '' if policy: policy = ', %s%s()' % (namespaces.python, policy.Code()) # generate the defs definitions = [] # basic def if default_pointers: definitions.append( '.def("%s", %s, %s%s)' % (rename, pointer, default_pointers[-1], policy)) for default_pointer in default_pointers[:-1]: definitions.append('.def("%s", %s%s)' % (rename, default_pointer, policy)) else: definitions.append('.def("%s", %s%s)' % (rename, pointer, policy)) return definitions
def ExportMethods(self): '''Export all the non-virtual methods of this class, plus any function that is to be exported as a method''' declared = {} def DeclareOverloads(m): 'Declares the macro for the generation of the overloads' if (isinstance(m, Method) and m.static) or type(m) == Function: func = m.FullName() macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS' else: func = m.name macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS' code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func, m.minArgs, m.maxArgs) if code not in declared: declared[code] = True self.Add('declaration', code) def Pointer(m): 'returns the correct pointer declaration for the method m' # check if this method has a wrapper set for him wrapper = self.info[m.name].wrapper if wrapper: return '&' + wrapper.FullName() else: return m.PointerDeclaration() def IsExportable(m): 'Returns true if the given method is exportable by this routine' ignore = (Constructor, ClassOperator, Destructor) return isinstance( m, Function) and not isinstance(m, ignore) and not m.virtual methods = [x for x in self.public_members if IsExportable(x)] methods.extend(self.GetAddedMethods()) staticmethods = {} for method in methods: method_info = self.info[method.name] # skip this method if it was excluded by the user if method_info.exclude: continue # rename the method if the user requested name = method_info.rename or method.name # warn the user if this method needs a policy and doesn't have one method_info.policy = exporterutils.HandlePolicy( method, method_info.policy) # check for policies policy = method_info.policy or '' if policy: policy = ', %s%s()' % (namespaces.python, policy.Code()) # check for overloads overload = '' if method.minArgs != method.maxArgs and not method_info.wrapper: # add the overloads for this method DeclareOverloads(method) overload_name = self.OverloadName(method) overload = ', %s%s()' % (namespaces.pyste, overload_name) # build the .def string to export the method pointer = Pointer(method) code = '.def("%s", %s' % (name, pointer) code += policy code += overload code += ')' self.Add('inside', code) # static method if isinstance(method, Method) and method.static: staticmethods[name] = 1 # add wrapper code if this method has one wrapper = method_info.wrapper if wrapper and wrapper.code: self.Add('declaration', wrapper.code) # export staticmethod statements for name in staticmethods: code = '.staticmethod("%s")' % name self.Add('inside', code)