Esempio n. 1
0
 def args(args=None):
     return _ast.arguments(
         args=args,
         posonlyargs=[],
         kwonlyargs=[],
         kw_defaults=[],
         defaults=[])
Esempio n. 2
0
def arguments(args: List[_ast.arg], vararg: _ast.arg) -> _ast.arguments:
    return _ast.arguments(
        args=args,
        posonlyargs=[],
        vararg=vararg,
        kwonlyargs=[],
        kw_defaults=[],
        kwarg=None,
        defaults=[],
    )
Esempio n. 3
0
def make_function(code, defaults=None, lineno=0):
        from meta.decompiler.disassemble import disassemble

        instructions = Instructions(disassemble(code))

        stmnts = instructions.stmnt()

        if code.co_flags & 2:
            vararg = None
            kwarg = None

        varnames = list(code.co_varnames[:code.co_argcount])
        co_locals = list(code.co_varnames[code.co_argcount:])

        #have var args
        if code.co_flags & 4:
            vararg = co_locals.pop(0)

        #have kw args
        if code.co_flags & 8:
            kwarg = co_locals.pop()

        args = [_ast.Name(id=argname, ctx=_ast.Param(), lineno=lineno, col_offset=0) for argname in varnames]
            
        args = _ast.arguments(args=args,
                              defaults=defaults if defaults else [],
                              kwarg=kwarg,
                              vararg=vararg,
                              lineno=lineno, col_offset=0
                              )
        if code.co_name == '<lambda>':
            if len(stmnts) == 2:
                if isinstance(stmnts[0], _ast.If) and isinstance(stmnts[1], _ast.Return):
                    assert len(stmnts[0].body) == 1
                    assert isinstance(stmnts[0].body[0], _ast.Return)
                    stmnts = [_ast.Return(_ast.IfExp(stmnts[0].test, stmnts[0].body[0].value, stmnts[1].value))]
                    
            assert len(stmnts) == 1, stmnts
            assert isinstance(stmnts[0], _ast.Return)

            stmnt = stmnts[0].value
            ast_obj = _ast.Lambda(args=args, body=stmnt, lineno=lineno, col_offset=0)
        else:

            if instructions.seen_yield:
                return_ = stmnts[-1]

                assert isinstance(return_, _ast.Return)
                assert isinstance(return_.value, _ast.Name)
                assert return_.value.id == 'None'
                return_.value = None
            ast_obj = _ast.FunctionDef(name=code.co_name, args=args, body=stmnts, decorator_list=[], lineno=lineno, col_offset=0)

        return ast_obj
Esempio n. 4
0
def make_function(code, defaults=None, lineno=0):
        from graphlab.meta.decompiler.disassemble import disassemble

        instructions = Instructions(disassemble(code))

        stmnts = instructions.stmnt()

        if code.co_flags & 2:
            vararg = None
            kwarg = None

        varnames = list(code.co_varnames[:code.co_argcount])
        co_locals = list(code.co_varnames[code.co_argcount:])

        #have var args
        if code.co_flags & 4:
            vararg = co_locals.pop(0)

        #have kw args
        if code.co_flags & 8:
            kwarg = co_locals.pop()

        args = [_ast.Name(id=argname, ctx=_ast.Param(), lineno=lineno, col_offset=0) for argname in varnames]
            
        args = _ast.arguments(args=args,
                              defaults=defaults if defaults else [],
                              kwarg=kwarg,
                              vararg=vararg,
                              lineno=lineno, col_offset=0
                              )
        if code.co_name == '<lambda>':
            if len(stmnts) == 2:
                if isinstance(stmnts[0], _ast.If) and isinstance(stmnts[1], _ast.Return):
                    assert len(stmnts[0].body) == 1
                    assert isinstance(stmnts[0].body[0], _ast.Return)
                    stmnts = [_ast.Return(_ast.IfExp(stmnts[0].test, stmnts[0].body[0].value, stmnts[1].value))]
                    
            assert len(stmnts) == 1, stmnts
            assert isinstance(stmnts[0], _ast.Return)

            stmnt = stmnts[0].value
            ast_obj = _ast.Lambda(args=args, body=stmnt, lineno=lineno, col_offset=0)
        else:

            if instructions.seen_yield:
                return_ = stmnts[-1]

                assert isinstance(return_, _ast.Return)
                assert isinstance(return_.value, _ast.Name)
                assert return_.value.id == 'None'
                return_.value = None
            ast_obj = _ast.FunctionDef(name=code.co_name, args=args, body=stmnts, decorator_list=[], lineno=lineno, col_offset=0)

        return ast_obj
Esempio n. 5
0
 def _replace_where_block_with_function(self, with_node):
     return _ast.FunctionDef(name=self.feature_name + '_where',
                             args=_ast.arguments(
                                 args=[_ast.arg(arg='self'), _ast.arg(arg='injectable_values')],
                                 kwonlyargs=[],
                                 kw_defaults=[],
                                 defaults=[]
                             ),
                             body=copy.deepcopy(with_node.body),
                             decorator_list=[],
                             returns=None)
Esempio n. 6
0
 def async_function(self, items):
     if len(items) == 2:
         (name, body) = items
         args = []
     else:
         (name, args, body) = items
     return _ast.AsyncFunctionDef(name=name,
                                  args=_ast.arguments(args=args,
                                                      defaults=[],
                                                      vararg=None,
                                                      kwarg=None),
                                  body=body,
                                  decorator_list=[])
Esempio n. 7
0
    def constructor_method(self, items):
        (args, body) = items

        method_args = [_ast.arg(arg='self', annotation=None)]
        method_args.extend(args)

        return _ast.FunctionDef(name='__init__',
                                args=_ast.arguments(args=method_args,
                                                    defaults=[],
                                                    vararg=None,
                                                    kwarg=None),
                                body=body,
                                decorator_list=[])
Esempio n. 8
0
def new_func(func_name, args, body, decorators=None, defaults=None):
    """AST function."""
    return FunctionDef(name=func_name,
                       returns=None,
                       args=arguments(
                           args=args,
                           vararg=None,
                           kwarg=None,
                           kw_defaults=[],
                           kwonlyargs=[],
                           defaults=[] if defaults is None else defaults),
                       body=body,
                       decorator_list=[] if decorators is None else decorators)
Esempio n. 9
0
 def test_functiondef(self):
     import _ast as ast
     fAst = ast.FunctionDef(
         name="foo",
         args=ast.arguments(
             args=[], vararg=None, kwarg=None, defaults=[],
             kwonlyargs=[], kw_defaults=[]),
         body=[], decorator_list=[], lineno=5, col_offset=0)
     exprAst = ast.Interactive(body=[fAst])
     compiled = compile(exprAst, "<foo>", "single")
     #
     d = {}
     eval(compiled, d, d)
     assert type(d['foo']) is type(lambda: 42)
     assert d['foo']() is None
Esempio n. 10
0
 def test_functiondef(self):
     import _ast as ast
     fAst = ast.FunctionDef(
         name="foo",
         args=ast.arguments(
             args=[], vararg=None, kwarg=None, defaults=[],
             kwonlyargs=[], kw_defaults=[]),
         body=[], decorator_list=[], lineno=5, col_offset=0)
     exprAst = ast.Interactive(body=[fAst])
     compiled = compile(exprAst, "<foo>", "single")
     #
     d = {}
     eval(compiled, d, d)
     assert type(d['foo']) is type(lambda: 42)
     assert d['foo']() is None
Esempio n. 11
0
    def _createrespond(self):
        """Create the `respond()` method on the final class."""
        args = arguments(
                args=[Name(id='self', ctx=Param())],
                vararg=None,
                kwarg=None,
                defaults=[])

        # the actual respond function
        respond = FunctionDef(
                name='respond',
                args=args,
                body=self.ast_.body, # whatever is left at the top level
                decorator_list=[])

        ast.copy_location(self.ast_, respond)
        ast.fix_missing_locations(respond)

        return respond
Esempio n. 12
0
def arguments(args=(), keys=(), values=(), vararg_name=None, kwarg_name=None):
    """Creates an _ast.FunctionDef node.

  Args:
    args: A list of args.
    keys: A list of keys, must be the same length as values.
    values: A list of values, correspond to keys.
    vararg_name: The name of the vararg variable, or None.
    kwarg_name: The name of the kwargs variable, or None.

  Raises:
    ValueError: If len(keys) != len(values).

  Returns:
    An _ast.FunctionDef node.
  """
    args, defaults = _ToArgsDefaults(args=args, keys=keys, values=values)
    return _ast.arguments(args=args,
                          defaults=defaults,
                          vararg=vararg_name,
                          kwarg=kwarg_name)
Esempio n. 13
0
    def visit_GeneratorExp(self, node):
        """Rewrite the GeneratorExp visitor function to turn the
        generator expression into a iterator function.  This is
        necessary to be able to correctly label any random functions
        that get called from within the generator expression.
        Basically, this function creates a function, and transforms
        the generator into a for loop that yields values from the.
        The function name is then returned, so that the parent node
        can handle the assignment properly.

        """

        # make an identifier for the list
        self.newline(node)
        iden = self._gen_iden(node)

        argids = []
        for gen in node.generators:
            argval = gen.iter
            argid = self._gen_iden(gen.iter)
            self.visit(
                _ast.Assign(targets=[_ast.Name(id=argid, ctx=_ast.Store())],
                            value=argval))
            argids.append(argid)

        elt = node.elt

        def parse_generator(nodes, ids):
            node = nodes[0]
            tempnode = _ast.For()
            tempnode.target = node.target
            tempnode.iter = _ast.Name(id=ids[0], ctx=_ast.Load())

            if len(nodes) == 1:
                yield_node = _ast.Expr(value=_ast.Yield(value=elt))
                body = [yield_node]
            else:
                body = [parse_generator(nodes[1:], ids[1:])]

            if len(node.ifs) == 1:
                ifnode = _ast.If(test=node.ifs[0], body=body, orelse=[])
                tempnode.body = [ifnode]

            elif len(node.ifs) > 1:
                ifnode = _ast.If(test=_ast.BoolOp(op=_ast.And(),
                                                  values=node.ifs),
                                 body=body,
                                 orelse=[])
                tempnode.body = [ifnode]

            else:
                tempnode.body = body

            tempnode.orelse = None
            return tempnode

        node = _ast.FunctionDef(
            name=iden,
            args=_ast.arguments(args=[], vararg=None, kwarg=None, defaults=[]),
            body=[parse_generator(node.generators, argids)],
            decorator_list=[])

        self.visit(node)
        return iden
Esempio n. 14
0
def make_function(code,
                  defaults=None,
                  annotations=(),
                  kw_defaults=(),
                  lineno=0):
    from ..decompiler.disassemble import disassemble

    instructions = Instructions(disassemble(code))

    stmnts = instructions.stmnt()

    if code.co_flags & 2:
        vararg = None
        kwarg = None

    varnames = list(code.co_varnames[:code.co_argcount])
    kwonly_varnames = list(code.co_varnames[code.co_argcount:code.co_argcount +
                                            code.co_kwonlyargcount])
    co_locals = list(code.co_varnames[code.co_argcount +
                                      code.co_kwonlyargcount:])

    assert (len(kw_defaults) % 2) == 0

    kw_defaults = list(kw_defaults)
    kw_default_dict = {}

    while kw_defaults:
        name = kw_defaults.pop(0)
        value = kw_defaults.pop(0)

        kw_default_dict[name.s] = value

    kw_defaults = []
    for argname in kwonly_varnames:
        kw_defaults.append(kw_default_dict.pop(argname))

    #have var args
    if code.co_flags & 4:
        vararg = co_locals.pop(0)

    #have kw args
    if code.co_flags & 8:
        kwarg = co_locals.pop()

    args = []
    annotation_names = [annotation.arg for annotation in annotations]

    for argname in varnames:
        if argname in annotation_names:
            arg = [
                annotation for annotation in annotations
                if annotation.arg == argname
            ][0]
        else:
            arg = _ast.arg(annotation=None,
                           arg=argname,
                           lineno=lineno,
                           col_offset=0)  #@UndefinedVariable

        args.append(arg)

    kwonlyargs = []

    for argname in kwonly_varnames:
        if argname in annotation_names:
            arg = [
                annotation for annotation in annotations
                if annotation.arg == argname
            ][0]
        else:
            arg = _ast.arg(annotation=None,
                           arg=argname,
                           lineno=lineno,
                           col_offset=0)  #@UndefinedVariable

        kwonlyargs.append(arg)

    if 'return' in annotation_names:
        arg = [
            annotation for annotation in annotations
            if annotation.arg == 'return'
        ][0]
        returns = arg.annotation
    else:
        returns = None

    if vararg in annotation_names:
        arg = [
            annotation for annotation in annotations
            if annotation.arg == vararg
        ][0]
        varargannotation = arg.annotation
    else:
        varargannotation = None

    if kwarg in annotation_names:
        arg = [
            annotation for annotation in annotations if annotation.arg == kwarg
        ][0]
        kwargannotation = arg.annotation
    else:
        kwargannotation = None

    args = _ast.arguments(args=args,
                          defaults=defaults if defaults else [],
                          kwarg=kwarg,
                          vararg=vararg,
                          kw_defaults=kw_defaults,
                          kwonlyargs=kwonlyargs,
                          kwargannotation=kwargannotation,
                          varargannotation=varargannotation,
                          lineno=lineno,
                          col_offset=0)

    if code.co_name == '<lambda>':
        if len(stmnts) == 2:
            if isinstance(stmnts[0], _ast.If) and isinstance(
                    stmnts[1], _ast.Return):
                assert len(stmnts[0].body) == 1
                assert isinstance(stmnts[0].body[0], _ast.Return)
                stmnts = [
                    _ast.Return(
                        _ast.IfExp(stmnts[0].test, stmnts[0].body[0].value,
                                   stmnts[1].value))
                ]

        assert isinstance(stmnts[0], _ast.Return)

        stmnt = stmnts[0].value
        ast_obj = _ast.Lambda(args=args,
                              body=stmnt,
                              lineno=lineno,
                              col_offset=0)
    else:

        if instructions.seen_yield:
            return_ = stmnts[-1]

            assert isinstance(return_, _ast.Return)
            assert isinstance(return_.value, _ast.Name)
            assert return_.value.id == 'None'
            return_.value = None

        ast_obj = _ast.FunctionDef(name=code.co_name,
                                   args=args,
                                   body=stmnts,
                                   decorator_list=[],
                                   returns=returns,
                                   lineno=lineno,
                                   col_offset=0)

    return ast_obj
Esempio n. 15
0
def make_function(code, defaults=None, annotations=(), kw_defaults=(), lineno=0):
        from graphlab.meta.decompiler.disassemble import disassemble

        instructions = Instructions(disassemble(code))

        stmnts = instructions.stmnt()

        if code.co_flags & 2:
            vararg = None
            kwarg = None

        varnames = list(code.co_varnames[:code.co_argcount])
        kwonly_varnames = list(code.co_varnames[code.co_argcount:code.co_argcount + code.co_kwonlyargcount])
        co_locals = list(code.co_varnames[code.co_argcount + code.co_kwonlyargcount:])

        assert (len(kw_defaults) % 2) == 0
        
        kw_defaults = list(kw_defaults)
        kw_default_dict = {}
        
        while kw_defaults:
            name = kw_defaults.pop(0)
            value = kw_defaults.pop(0)
            
            kw_default_dict[name.s] = value
        
        kw_defaults = []
        for argname in kwonly_varnames:
            kw_defaults.append(kw_default_dict.pop(argname))
        
        #have var args
        if code.co_flags & 4:
            vararg = co_locals.pop(0)

        #have kw args
        if code.co_flags & 8:
            kwarg = co_locals.pop()

        args = []
        annotation_names = [annotation.arg for annotation in annotations]
        
        for argname in varnames:
            if argname in annotation_names:
                arg = [annotation for annotation in annotations if annotation.arg == argname][0]
            else:
                arg = _ast.arg(annotation=None, arg=argname, lineno=lineno, col_offset=0) #@UndefinedVariable
                
            args.append(arg)

        kwonlyargs = []

        for argname in kwonly_varnames:
            if argname in annotation_names:
                arg = [annotation for annotation in annotations if annotation.arg == argname][0]
            else:
                arg = _ast.arg(annotation=None, arg=argname, lineno=lineno, col_offset=0) #@UndefinedVariable
                
            kwonlyargs.append(arg)
            
        if 'return' in annotation_names:
            arg = [annotation for annotation in annotations if annotation.arg == 'return'][0]
            returns = arg.annotation
        else:
            returns = None
        
        if vararg in annotation_names:
            arg = [annotation for annotation in annotations if annotation.arg == vararg][0]
            varargannotation = arg.annotation
        else:
            varargannotation = None
            
        if kwarg in annotation_names:
            arg = [annotation for annotation in annotations if annotation.arg == kwarg][0]
            kwargannotation = arg.annotation
        else:
            kwargannotation = None
        
        args = _ast.arguments(args=args,
                              defaults=defaults if defaults else [],
                              kwarg=kwarg,
                              vararg=vararg,
                              kw_defaults=kw_defaults,
                              kwonlyargs=kwonlyargs,
                              kwargannotation=kwargannotation,
                              varargannotation=varargannotation,
                              lineno=lineno, col_offset=0
                              )
        
        
        if code.co_name == '<lambda>':
            if len(stmnts) == 2:
                if isinstance(stmnts[0], _ast.If) and isinstance(stmnts[1], _ast.Return):
                    assert len(stmnts[0].body) == 1
                    assert isinstance(stmnts[0].body[0], _ast.Return)
                    stmnts = [_ast.Return(_ast.IfExp(stmnts[0].test, stmnts[0].body[0].value, stmnts[1].value))]

            assert isinstance(stmnts[0], _ast.Return)

            stmnt = stmnts[0].value
            ast_obj = _ast.Lambda(args=args, body=stmnt, lineno=lineno, col_offset=0)
        else:

            if instructions.seen_yield:
                return_ = stmnts[-1]

                assert isinstance(return_, _ast.Return)
                assert isinstance(return_.value, _ast.Name)
                assert return_.value.id == 'None'
                return_.value = None
            
            ast_obj = _ast.FunctionDef(name=code.co_name, args=args,
                                       body=stmnts, decorator_list=[],
                                       returns=returns,
                                       lineno=lineno, col_offset=0)

        return ast_obj
	def wrap_func(self, func):
		if self.func:
			raise RuntimeError("func is already set.")
		if not inspect.isfunction(func):
			raise TypeError("func:%r is not a function or method." % func)
			
		# Get function source code.
		#
		# HACK: Patch issue 1218234_. If getsource() is called on a
		# function, it's module is modified and reloaded afterward, and
		# getsource() is called again, then the returned source is the
		# cached source that was returned from the first call to
		# getsource(). This is due to the caching in the linecache module
		# not being tightly coupled with reload().
		#
		# .. 1218234: http://bugs.python.org/issue1218234
		func_file = inspect.getsourcefile(func)
		linecache.checkcache(func_file) # HACK: issue 1218234
		func_src, lineno = inspect.getsourcelines(func)
		
		# Dedent decorators and function def.
		dedent_func_lines(func_src)
		func_src = ''.join(func_src)
		
		# Parse function source code to AST.
		mod_ast = ast.parse(func_src)
		func_ast = mod_ast.body[0]
		
		# Wrap function in an enclosing function to create closure. This is
		# so that we can pass along our variables to the template function.
		if inspect.ismethod(func):
			enc_name = '__pdt_enc_%s_%s_%s' % (func.__module__, (func.im_self or func.im_class).__name__, func.__name__)
		else:
			enc_name = '__pdt_enc_%s_%s' % (func.__module__, func.__name__)
		enc_vars = {
			'__pdt_io_factory': self.io_factory,
			'__pdt_io_args': self.io_args,
			'__pdt_io_kw': self.io_kw
		}
		# def __pdt_enc_func(...):
		mod_ast.body[0] = _ast.FunctionDef(enc_name, _ast.arguments([
			_ast.Name('__pdt_io_factory', _ast_param),
			_ast.Name('__pdt_io_args', _ast_param),
			_ast.Name('__pdt_io_kw', _ast_param)
		], None, None, []), [
			# def func(...):
			#   ...
			func_ast,
			# return func
			_ast.Return(_ast.Name(func.__name__, _ast_load))
		], [])
		
		# Get template global namespace.
		# .. NOTE: This has to be the actual function globals (module dict)
		#    reference and NOT A COPY.
		func_globals = func.__globals__
		
		# Remove our decorator to prevent recursive wrapping. It is safe to
		# clear the whole list because decorators before ours have not yet
		# been called (but will be), and any decorators after ours would
		# have already caused an error with the call to get the function
		# source.
		func_ast.decorator_list = []
		
		# Add doc string and create template buffer at beginning of
		# function.
		func_body = []
		if self.doc:
			func_body.append(
				# """..."""
				_ast.Expr(_ast.Str(self.doc))
			)
		func_body += [
			# __pdt_buff = __pdt_io_factory(*__pdt_io_args, **__pdt_io_kw)
			_ast.Assign([_ast.Name('__pdt_buff', _ast_store)], _ast.Call(_ast.Name('__pdt_io_factory', _ast_load), [], [], _ast.Name('__pdt_io_args', _ast_load), _ast.Name('__pdt_io_kw', _ast_load))),
			# __pdt_write = __pdt_buff.write
			_ast.Assign([_ast.Name('__pdt_write', _ast_store)], _ast.Attribute(_ast.Name('__pdt_buff', _ast_load), 'write', _ast_load)),
			# __pdt_getvalue = __pdt_buff.getvalue
			_ast.Assign([_ast.Name('__pdt_getvalue', _ast_store)], _ast.Attribute(_ast.Name('__pdt_buff', _ast_load), 'getvalue', _ast_load))
		]

		# Wrap expressions to write to buffer.
		node_lists = [func_ast.body]
		while node_lists:
			nodes = node_lists.pop()
			for i, node in enumerate(nodes):
				if isinstance(node, _ast.Expr):
					# expr -> __pdt_write(expr)
					nodes[i] = _ast.Expr(_ast.Call(_ast.Name('__pdt_write', _ast_load), [node.value], [], None, None))
				elif isinstance(node, _ast.Return):
					if not node.value:
						# return -> return __pdt_getvalue()
						node.value = _ast.Call(_ast.Name('__pdt_getvalue', _ast_load), [], [], None, None)
				elif isinstance(node, (_ast.If, _ast.While, _ast.For)):
					node_lists += [node.body, node.orelse]
				elif isinstance(node, _ast.TryExcept):
					node_lists += [node.body, node.orelse, node.handlers]
				elif isinstance(node, _ast.TryFinally):
					node_lists += [node.body, node.finalbody]
				elif isinstance(node, (_ast.ExceptHandler, _ast.With)):
					node_lists.append(node.body)
				elif isinstance(node, _ast.Yield):
					raise TypeError("Generator functions are not supported.")
		
		func_body += func_ast.body
		
		# Return buffer at end of function.
		func_body.append(
			# return __pdt_getvalue()
			_ast.Return(_ast.Call(_ast.Name('__pdt_getvalue', _ast_load), [], [], None, None))
		)
		
		func_ast.body = func_body
		
		# XXX
		'''
		import sys
		sys.path.append("../dev")
		from astpp import dump
		print "LINENO", lineno
		'''
		
		# Generate line and column information for modified AST.
		ast.fix_missing_locations(mod_ast)
		
		# Fix line numbers.
		ast.increment_lineno(mod_ast, lineno - 1)
		
		# XXX
		'''
		print "%s()" % func.__name__
		print dump(mod_ast, True, True, ' ')
		'''
		
		# Compile template function.
		exec compile(mod_ast, func_file, 'exec') in func_globals
		
		# Store compiled template function.
		self.func = func_globals[enc_name](**enc_vars)
		del func_globals[enc_name]
Esempio n. 17
0
    def visit_GeneratorExp(self, node):
        """Rewrite the GeneratorExp visitor function to turn the
        generator expression into a iterator function.  This is
        necessary to be able to correctly label any random functions
        that get called from within the generator expression.
        Basically, this function creates a function, and transforms
        the generator into a for loop that yields values from the.
        The function name is then returned, so that the parent node
        can handle the assignment properly.

        """

        # make an identifier for the list
        self.newline(node)
        iden = self._gen_iden(node)
        
        argids = []
        for gen in node.generators:
            argval = gen.iter
            argid = self._gen_iden(gen.iter)
            self.visit(_ast.Assign(
                targets=[_ast.Name(id=argid, ctx=_ast.Store())],
                value=argval))
            argids.append(argid)

        elt = node.elt
        
        def parse_generator(nodes, ids):
            node = nodes[0]
            tempnode = _ast.For()
            tempnode.target = node.target
            tempnode.iter = _ast.Name(id=ids[0], ctx=_ast.Load())

            if len(nodes) == 1:
                yield_node = _ast.Expr(value=_ast.Yield(value=elt))
                body = [yield_node]
            else:
                body = [parse_generator(nodes[1:], ids[1:])]

            if len(node.ifs) == 1:
                ifnode = _ast.If(
                    test=node.ifs[0],
                    body=body,
                    orelse=[])
                tempnode.body = [ifnode]

            elif len(node.ifs) > 1:
                ifnode = _ast.If(
                    test=_ast.BoolOp(
                        op=_ast.And(),
                        values=node.ifs),
                    body=body,
                    orelse=[])
                tempnode.body = [ifnode]

            else:
                tempnode.body = body

            tempnode.orelse = None
            return tempnode
         
        node = _ast.FunctionDef(
            name=iden,
            args=_ast.arguments(args=[], vararg=None, kwarg=None, defaults=[]),
            body=[parse_generator(node.generators, argids)],
            decorator_list=[])
        
        self.visit(node)
        return iden