Example #1
0
 def WrapCallable(self, c, fname, retnum, line_number):
   """Process callable return type AST.Type c."""
   assert c.HasField('callable'), ('WrapCallable called on AST that has no'
                                   ' "callable":\n' + str(c))
   cname = Ident(c.callable.name.cpp_name) or fname+'_ret%d_lambda' % retnum
   wname = 'lambda_'+cname
   for i, r in enumerate(c.callable.returns):
     if r.type.HasField('callable'):
       for s in self.WrapCallable(r.type, cname, i, line_number):
         yield s
   if not c.cpp_type:
     assert c.callable, 'Non-callable param has empty cpp_type'
     c.cpp_type = 'std::function<%s>' % astutils.StdFuncParamStr(c.callable)
   for s in gen.FunctionCall(
       '', wname, doc=c.lang_type,
       catch=self.catch_cpp_exceptions and not c.callable.cpp_noexcept,
       call=['void* fp = PyCapsule_GetPointer(self, typeid(%s).name());'
             % c.cpp_type,
             'if (fp == nullptr) return nullptr;',
             '(*static_cast<%s*>(fp))' % c.cpp_type],
       postcall_init=None, typepostconversion=self.typemap,
       func_ast=c.callable, lineno=line_number): yield s
   defname = wname + '_def'
   yield gen.FromFunctionDef(c.cpp_type, defname, wname,
                             VARARGS if len(c.callable.params) else NOARGS,
                             'Calls '+c.cpp_type)
   self.types.add(types.CallableType(c.cpp_type, c.lang_type, defname))
Example #2
0
 def testCallableType(self):
   t = types.CallableType('cname::cpp_type', '(x:py)->None', 'lambda_Name_def')
   header = '\n'.join(t.GenHeader()) + '\n'
   self.assertMultiLineEqual(header, textwrap.dedent("""\
     // (x:py)->None
     PyObject* Clif_PyObjFrom(cname::cpp_type, py::PostConv);
   """))
Example #3
0
File: pyext.py Project: sr-gi/clif
 def WrapOneCallable(self, c, fname, ret_or_arg, line_number, class_ns,
                     only_pyobjas):
     """Process callable return or param type of AST.Type c."""
     assert c.HasField('callable'), (
         'WrapOneCallable called on AST that has no'
         ' "callable":\n' + str(c))
     cname = Ident(
         c.callable.name.cpp_name) or fname + '_%s_lambda' % ret_or_arg
     wname = 'lambda_' + cname
     for s in self._WrapAllCallables(c.callable, cname, line_number,
                                     class_ns, not only_pyobjas):
         yield s
     if only_pyobjas is ret_or_arg.startswith('ret'):
         # Clif_PyObjFrom() for this callable is not needed (only Clif_PyObjAs()).
         return
     if not c.cpp_type:
         assert c.callable, 'Non-callable param has empty cpp_type'
         c.cpp_type = 'std::function<%s>' % astutils.StdFuncParamStr(
             c.callable)
     if c.cpp_type in self.types_std_function_cpp_types:
         return
     self.types_std_function_cpp_types.add(c.cpp_type)
     for s in gen.FunctionCall(
             '',
             wname,
             doc=c.lang_type,
             catch=self.catch_cpp_exceptions
             and not c.callable.cpp_noexcept,
             call=[
                 'void* fp = PyCapsule_GetPointer(self, typeid(%s).name());'
                 % c.cpp_type, 'if (fp == nullptr) return nullptr;',
                 '(*static_cast<%s*>(fp))' % c.cpp_type
             ],
             postcall_init=None,
             typepostconversion=self.typemap,
             func_ast=c.callable,
             lineno=line_number):
         yield s
     defname = wname + '_def'
     yield ''
     yield gen.FromFunctionDef(
         c.cpp_type, defname, wname,
         VARARGS if len(c.callable.params) else NOARGS,
         'Calls ' + c.cpp_type)
     if class_ns:
         defname = class_ns + '::' + defname
     self.types.append(types.CallableType(c.cpp_type, c.lang_type, defname))