Пример #1
0
def copy_assignee(n, ctx):
    if isinstance(n, ast.Name):
        ret = ast.Name(id=n.id, ctx=ctx)
    elif isinstance(n, ast.Attribute):
        ret = ast.Attribute(value=n.value, attr=n.attr, ctx=ctx)
    elif isinstance(n, ast.Subscript):
        ret = ast.Subscript(value=n.value, slice=n.slice, ctx=ctx)
    elif isinstance(n, ast.List):
        elts = [copy_assignee(e, ctx) for e in n.elts]
        ret = ast.List(elts=elts, ctx=ctx)
    elif isinstance(n, ast.Tuple):
        elts = [copy_assignee(e, ctx) for e in n.elts]
        ret = ast.Tuple(elts=elts, ctx=ctx)
    elif isinstance(n, ast.Starred):
        ret = ast.Starred(value=copy_assignee(n.value, ctx), ctx=ctx)
    elif isinstance(n, ast.Call):
        args = [copy_assignee(e, ctx) for e in n.args]
        ret = ast.Call(func=n.func,
                       args=args,
                       keywords=n.keywords,
                       starargs=n.starargs,
                       kwargs=n.kwargs)
    else:
        return n
    ast.copy_location(ret, n)
    return ret
Пример #2
0
def _to_custom_constructor_body(
    signature_data: SignatureData,
    class_parameter_name: str = CLASS_PARAMETER_NAME,
    positional_kinds: Sequence[inspect._ParameterKind] = (
        inspect._POSITIONAL_ONLY, inspect._POSITIONAL_OR_KEYWORD)
) -> List[ast.stmt]:
    positionals_names = chain.from_iterable(
        signature_data.get(kind, []) for kind in positional_kinds)
    keywords_names = signature_data.get(inspect._KEYWORD_ONLY, [])
    positional_arguments = [
        ast.Name(parameter_name, ast.Load())
        for parameter_name in positionals_names
    ]
    if inspect._VAR_POSITIONAL in signature_data:
        variadic_positional_name, = signature_data[inspect._VAR_POSITIONAL]
        variadic_positional_node = ast.Starred(
            ast.Name(variadic_positional_name, ast.Load()), ast.Load())
        positional_arguments.append(variadic_positional_node)
    keyword_arguments = [
        ast.keyword(parameter_name, ast.Name(parameter_name, ast.Load()))
        for parameter_name in keywords_names
    ]
    if inspect._VAR_KEYWORD in signature_data:
        variadic_keyword_name, = signature_data[inspect._VAR_KEYWORD]
        variadic_keyword_node = ast.keyword(
            None, ast.Name(variadic_keyword_name, ast.Load()))
        keyword_arguments.append(variadic_keyword_node)
    return [
        ast.Return(
            ast.Call(ast.Name(class_parameter_name, ast.Load()),
                     positional_arguments, keyword_arguments))
    ]
Пример #3
0
    def _create_args(self,
                     stmt: param_stmt.ParametrizedStatement) -> List[ast.expr]:
        """Creates the positional arguments, i.e., POSITIONAL_ONLY,
        POSITIONAL_OR_KEYWORD and VAR_POSITIONAL.

        Args:
            stmt: The parameterised statement

        Returns:
            A list of AST statements
        """
        args: List[ast.expr] = []
        gen_callable: GenericCallableAccessibleObject = cast(
            GenericCallableAccessibleObject, stmt.accessible_object())
        for param_name in gen_callable.inferred_signature.parameters:
            if param_name in stmt.args:
                param_kind = gen_callable.inferred_signature.signature.parameters[
                    param_name].kind
                if param_kind in (
                        Parameter.POSITIONAL_ONLY,
                        Parameter.POSITIONAL_OR_KEYWORD,
                ):
                    args.append(
                        au.create_var_name(self._variable_names,
                                           stmt.args[param_name], True))
                elif param_kind == Parameter.VAR_POSITIONAL:
                    # Append *args, if necessary.
                    args.append(
                        ast.Starred(
                            value=au.create_var_name(self._variable_names,
                                                     stmt.args[param_name],
                                                     True),
                            ctx=ast.Load(),
                        ))
        return args
Пример #4
0
    def _storeize(self, expr, name, func=None):
        """Return a new `name` object with an ast.Store() context"""
        if not func:
            func = ast.Store

        if isinstance(name, Result):
            if not name.is_expr():
                raise self._syntax_error(
                    expr, "Can't assign or delete a non-expression")
            name = name.expr

        if isinstance(name, (ast.Tuple, ast.List)):
            typ = type(name)
            new_elts = []
            for x in name.elts:
                new_elts.append(self._storeize(expr, x, func))
            new_name = typ(elts=new_elts)
        elif isinstance(name, ast.Name):
            new_name = ast.Name(id=name.id)
        elif isinstance(name, ast.Subscript):
            new_name = ast.Subscript(value=name.value, slice=name.slice)
        elif isinstance(name, ast.Attribute):
            new_name = ast.Attribute(value=name.value, attr=name.attr)
        elif isinstance(name, ast.Starred):
            new_name = ast.Starred(
                value=self._storeize(expr, name.value, func))
        else:
            raise self._syntax_error(
                expr, "Can't assign or delete a " + ("constant" if isinstance(
                    name, ast.Constant) else type(expr).__name__))

        new_name.ctx = func()
        ast.copy_location(new_name, name)
        return new_name
 def add_before_call_used_args_capturing_call(call_code, node,
                                              all_source_code):
     """
     When a method is called, capture the arguments of the method before executing it
     """
     old_args_nodes_ast = ast.List(node.args, ctx=ast.Load())
     old_args_code = ast.List([
         ast.Constant(n=ast.get_source_segment(all_source_code, arg),
                      kind=None) for arg in node.args
     ],
                              ctx=ast.Load())
     new_args_node = ast.Starred(value=ast.Call(
         func=ast.Name(id='before_call_used_args', ctx=ast.Load()),
         args=[
             ast.Constant(n=False, kind=None),
             ast.Constant(n=call_code, kind=None), old_args_code,
             ast.Constant(n=node.lineno, kind=None),
             ast.Constant(n=node.col_offset, kind=None),
             ast.Constant(n=node.end_lineno, kind=None),
             ast.Constant(n=node.end_col_offset, kind=None),
             ast.Constant(n=False, kind=None), old_args_nodes_ast
         ],
         keywords=[]),
                                 ctx=ast.Load())
     node.args = [new_args_node]
Пример #6
0
def _to_custom_constructor_body(
    signature_data: SignatureData,
    class_parameter_name: str = CLASS_PARAMETER_NAME,
    positional_kinds: Sequence[inspect._ParameterKind] = (
        inspect._POSITIONAL_ONLY, inspect._POSITIONAL_OR_KEYWORD)
) -> List[ast.stmt]:
    positionals = flatten(
        signature_data.get(kind, []) for kind in positional_kinds)
    keywords = signature_data.get(inspect._KEYWORD_ONLY, [])
    positional_arguments = [
        _to_loaded_name(parameter_name) for parameter_name, *_ in positionals
    ]
    if inspect._VAR_POSITIONAL in signature_data:
        (variadic_positional_name,
         *_), = (signature_data[inspect._VAR_POSITIONAL])
        variadic_positional_node = ast.Starred(
            _to_loaded_name(variadic_positional_name), ast.Load())
        positional_arguments.append(variadic_positional_node)
    keyword_arguments = [
        ast.keyword(name, _to_loaded_name(name))
        for name, _, is_callable in keywords
    ]
    if inspect._VAR_KEYWORD in signature_data:
        (variadic_keyword_name, *_), = signature_data[inspect._VAR_KEYWORD]
        variadic_keyword_node = ast.keyword(
            None, _to_loaded_name(variadic_keyword_name))
        keyword_arguments.append(variadic_keyword_node)
    return [
        ast.Return(
            ast.Call(_to_loaded_name(class_parameter_name),
                     positional_arguments, keyword_arguments))
    ]
Пример #7
0
def Call(*,
         func,
         args,
         keywords,
         starargs,
         kwargs,
         lineno=None,
         col_offset=None):
    if flags.PY3_VERSION >= 5:
        if starargs is not None:
            args += [ast.Starred(starargs, ast.Load())]
        if kwargs is not None:
            keywords += [ast.keyword(arg=None, value=kwargs)]
        if lineno is not None and col_offset is not None:
            return ast.Call(func=func,
                            args=args,
                            keywords=keywords,
                            lineno=lineno,
                            col_offset=col_offset)
        else:
            return ast.Call(func=func, args=args, keywords=keywords)
    else:
        return ast.Call(func=func,
                        args=args,
                        keywords=keywords,
                        starargs=starargs,
                        kwargs=kwargs,
                        lineno=lineno,
                        col_offset=col_offset)
Пример #8
0
 def run(self, interpreter: Interpreter):
     args = interpreter.stack.pop()
     class_type = interpreter.stack.pop()
     if isinstance(args, ast.Tuple):
         interpreter.stack.append(ast.Call(class_type, list(args.elts), []))
     else:
         interpreter.stack.append(
             ast.Call(class_type, [ast.Starred(args)], []))
Пример #9
0
    def visit_Call(self, node):
        """
        """

        # f(x, y, z) --> (lambda info, call: call)( # wrapper
        #                    (lambda: info)(),      # banner
        #                    (lambda: f)()(         # function
        #                        (lambda: x)(),     # arg
        #                        (lambda: y)(),     # arg
        #                        (lambda: z)(),     # arg
        #                    ),
        #                )

        if self.is_exempt(node):
            self.generic_visit(node)
            return node

        banner_call = self.insert_eager_call(
            node.lineno,
            constants.INNER_CALL_LINENO,
            banner.FunctionCallBanner(self.preprocessor.code, node).summary,
        )
        self.generic_visit(node)
        function_call = ast.Call(
            func=self.insert_eager_call(
                node.func.lineno,
                constants.FN_WRAPPER_LINENO,
                node.func,
            ),
            args=[(ast.Starred(
                value=self.insert_lazy_call(
                    arg.value.lineno,
                    constants.RG_WRAPPER_LINENO,
                    ('arg', arg.value),
                ),
                ctx=ast.Load(),
            ) if isinstance(arg, ast.Starred) else self.insert_lazy_call(
                arg.lineno,
                constants.RG_WRAPPER_LINENO,
                ('arg', arg),
            )) for arg in node.args],
            keywords=[
                ast.keyword(arg=keyword.arg,
                            value=self.insert_lazy_call(
                                keyword.value.lineno,
                                constants.RG_WRAPPER_LINENO,
                                ('arg', keyword.value),
                            )) for keyword in node.keywords
            ],
            lineno=node.lineno,
        )
        wrapper_call = self.insert_lazy_call(
            node.lineno,
            constants.PG_WRAPPER_LINENO,
            ('info', banner_call),
            ('call', function_call),
        )
        return wrapper_call
Пример #10
0
def ClassDef(*,
             name,
             bases,
             keywords,
             starargs,
             kwargs,
             body,
             decorator_list,
             lineno=None,
             col_offset=None):
    if flags.PY_VERSION == 2:
        # Ignore keywords and starargs, they shouldnt be there in the first place if Py2
        return ast.ClassDef(name=name,
                            bases=bases,
                            body=body,
                            decorator_list=decorator_list,
                            lineno=lineno,
                            col_offset=col_offset)
    elif flags.PY_VERSION == 3:
        if flags.PY3_VERSION >= 5:
            if starargs is not None:
                bases += [ast.Starred(starargs, ast.Load())]
            if kwargs is not None:
                keywords += [ast.keyword(arg=None, value=kwargs)]
            if lineno is not None and col_offset is not None:
                return ast.ClassDef(name=name,
                                    bases=bases,
                                    keywords=keywords,
                                    body=body,
                                    decorator_list=decorator_list,
                                    lineno=lineno,
                                    col_offset=col_offset)
            else:
                return ast.ClassDef(name=name,
                                    bases=bases,
                                    keywords=keywords,
                                    body=body,
                                    decorator_list=decorator_list)
        else:
            if lineno is not None and col_offset is not None:
                return ast.ClassDef(name=name,
                                    bases=bases,
                                    keywords=keywords,
                                    starargs=starargs,
                                    kwargs=kwargs,
                                    body=body,
                                    decorator_list=decorator_list,
                                    lineno=lineno,
                                    col_offset=col_offset)
            else:
                return ast.ClassDef(name=name,
                                    bases=bases,
                                    keywords=keywords,
                                    starargs=starargs,
                                    kwargs=kwargs,
                                    body=body,
                                    decorator_list=decorator_list)
Пример #11
0
    def visit_Assign(self, node):
        rhs_visitor = RHSVisitor()
        rhs_visitor.visit(node.value)
        if isinstance(node.targets[0], (ast.Tuple, ast.List)):  # x,y = [1,2]
            if isinstance(node.value, (ast.Tuple, ast.List)):
                return self.assign_tuple_target(
                    node.targets[0].elts, node.value.elts, rhs_visitor.result
                )
            elif isinstance(node.value, ast.Call):
                call = None
                for element in node.targets[0].elts:
                    label = LabelVisitor()
                    label.visit(element)
                    call = self.assignment_call_node(label.result, node)
                return call
            elif isinstance(
                node.value, ast.Name
            ):  # Treat `x, y = z` like `x, y = (*z,)`
                value_node = ast.Starred(node.value, ast.Load())
                ast.copy_location(value_node, node)
                return self.assign_tuple_target(
                    node.targets[0].elts, [value_node], rhs_visitor.result
                )
            else:
                label = LabelVisitor()
                label.visit(node)
                return self.append_node(
                    AssignmentNode(
                        label.result,
                        label.result,
                        node,
                        rhs_visitor.result,
                        path=self.filenames[-1],
                    )
                )

        elif len(node.targets) > 1:  # x = y = 3
            return self.assign_multi_target(node, rhs_visitor.result)
        else:
            if isinstance(node.value, ast.Call):  # x = call()
                label = LabelVisitor()
                label.visit(node.targets[0])
                return self.assignment_call_node(label.result, node)
            else:  # x = 4
                label = LabelVisitor()
                label.visit(node)
                return self.append_node(
                    AssignmentNode(
                        label.result,
                        extract_left_hand_side(node.targets[0]),
                        node,
                        rhs_visitor.result,
                        path=self.filenames[-1],
                    )
                )
Пример #12
0
	def __build__init(self):

		super_func_call = ast.Call(func=ast.Name(id='super', ctx=ast.Load()), args=[], keywords=[])
		if (sys.version_info[0], sys.version_info[1]) == (3, 5) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 6) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 7) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 8):
			super_func = ast.Call(
									func=ast.Attribute(value=super_func_call, attr='__init__', ctx=ast.Load()),
									args=[ast.Starred(value=ast.Name(id='args', ctx=ast.Load()), ctx=ast.Load())],
									keywords=[ast.keyword(arg=None, value=ast.Name(id='kwargs', ctx=ast.Load()), ctx=ast.Load())],
							)
		elif (sys.version_info[0], sys.version_info[1]) == (3,4):
			super_func = ast.Call(
									func=ast.Attribute(value=super_func_call, attr='__init__', ctx=ast.Load()),
									args=[],
									keywords=[],
									starargs=ast.Name(id='args', ctx=ast.Load()),
									kwargs=ast.Name(id='kwargs', ctx=ast.Load()),

							)
		else:
			print("Version:", sys.version_info)
			raise RuntimeError("This script only functions on python 3.4, 3.5, 3.6, or 3.7. Active python version {}.{}".format(*sys.version_info))

		super_init = ast.Expr(
							value=super_func,
							lineno     = self.__get_line(),
							col_offset = 0,
						)

		body = [super_init]

		sig = ast.arguments(
					args=[ast.arg('self', None)],
					vararg=ast.arg(arg='args', annotation=None),
					kwarg=ast.arg(arg='kwargs', annotation=None),
					varargannotation=None,
					posonlyargs=[],
					kwonlyargs=[],
					kwargannotation=None,
					defaults=[],
					kw_defaults=[])

		func = ast.FunctionDef(
			name = "__init__",
			args = sig,
			body = body,
			decorator_list = [],
			lineno     = self.__get_line(),
			col_offset = 0,
			)

		return func
Пример #13
0
    def visit_Assign(self, node):
        rhs_visitor = RHSVisitor()
        rhs_visitor.visit(node.value)
        if isinstance(node.targets[0], (ast.Tuple, ast.List)):  # x,y = [1,2]
            if isinstance(node.value, (ast.Tuple, ast.List)):
                return self.assign_tuple_target(node.targets[0].elts,
                                                node.value.elts,
                                                rhs_visitor.result)
            elif isinstance(node.value, ast.Call):
                call = None
                for element in node.targets[0].elts:
                    label = LabelVisitor()
                    label.visit(element)
                    call = self.assignment_call_node(label.result, node)
                return call
            elif isinstance(node.value,
                            ast.Name):  # Treat `x, y = z` like `x, y = (*z,)`
                value_node = ast.Starred(node.value, ast.Load())
                ast.copy_location(value_node, node)
                return self.assign_tuple_target(node.targets[0].elts,
                                                [value_node],
                                                rhs_visitor.result)
            else:
                label = LabelVisitor()
                label.visit(node)
                log.warn(
                    'Assignment not properly handled in %s. Could result in not finding a vulnerability.'
                    'Assignment: %s',
                    getattr(self, 'filenames', ['?'])[0],
                    self.label.result,
                )
                return self.append_node(
                    AssignmentNode(label.result,
                                   label.result,
                                   node,
                                   rhs_visitor.result,
                                   path=self.filenames[-1]))

        elif len(node.targets) > 1:  # x = y = 3
            return self.assign_multi_target(node, rhs_visitor.result)
        else:
            if isinstance(node.value, ast.Call):  # x = call()
                label = LabelVisitor()
                label.visit(node.targets[0])
                return self.assignment_call_node(label.result, node)
            else:  # x = 4
                label = LabelVisitor()
                label.visit(node)
                return self.append_node(
                    AssignmentNode(label.result,
                                   extract_left_hand_side(node.targets[0]),
                                   node,
                                   rhs_visitor.result,
                                   path=self.filenames[-1]))
Пример #14
0
 def run(self, interpreter: Interpreter):
     args = interpreter.stack.pop()
     func = interpreter.stack.pop()
     if isinstance(args, ast.Tuple):
         call = ast.Call(func, list(args.elts), [])
     else:
         call = ast.Call(func, [ast.Starred(args)], [])
     # Any call to reduce can have global side effects, since it runs arbitrary Python code.
     # However, if we just save it to the stack, then it might not make it to the final AST unless the stack
     # value is actually used. So save the result to a temp variable, and then put that on the stack:
     var_name = interpreter.new_variable(call)
     interpreter.stack.append(ast.Name(var_name, ast.Load()))
Пример #15
0
def _node_with_binop(node: ast.AST, binop: ast.BinOp) -> ast.expr:
    if isinstance(node, ast.Call):
        node.args = [ast.Starred(value=binop, ctx=ast.Load())]
        return node
    elif isinstance(node, ast.List):
        # NOTE (mb 2018-06-29): Operands of the binop are always lists
        return binop
    elif isinstance(node, ast.Set):
        return ast.Call(func=ast.Name(id="set", ctx=ast.Load()), args=[binop], keywords=[])
    elif isinstance(node, ast.Tuple):
        return ast.Call(func=ast.Name(id="tuple", ctx=ast.Load()), args=[binop], keywords=[])
    else:
        raise TypeError(f"Unexpected node type {type(node)}")
Пример #16
0
    def function_body_to_z3(self, func):
        argpairs = [(a.value.arg, True) if type(a) == ast.Starred else
                    (a.arg, False) for a in func.args.args]

        argnames = [a.arg for a in func.args.args]
        argvars = [z3.Const(name, Unk) for name in argnames]
        arg_name_to_var = dict(zip(argnames, argvars))
        arg_name_to_def = {name: ast.arg(arg=name) for name in argnames}
        self.scopes.append(arg_name_to_def)
        for name, definition in arg_name_to_def.items():
            self.env.refs[definition] = arg_name_to_var[name]
        z3body = self.visit(func.body)
        self.scopes.pop()

        z3vars = [
            ast.Starred(
                value=arg_name_to_var[n]) if is_starred else arg_name_to_var[n]
            for n, is_starred in argpairs
        ]

        return z3body, z3vars
Пример #17
0
    def visit_argument(self, arg_value, arg_name=None, nstars=0):
        """ Rewrite AST node appearing as function argument.
        """
        # Unpack starred expression in Python 3.5+.
        starred = ast_has_starred and isinstance(arg_value, ast.Starred)
        if starred:
            arg_value = arg_value.value
            nstars = 1

        # Create new call.
        args = [self.visit_with_state(arg_value, boxed=True)]
        if arg_name:
            args += [ast.Str(arg_name)]
        keywords = []
        if nstars:
            keywords += [ast.keyword('nstars', ast.Num(nstars))]
        call = to_call(self.tracer_method('trace_argument'), args, keywords)

        # Repack starred expression in Python 3.5+.
        if starred:
            call = ast.Starred(call, ast.Load())
        return call
Пример #18
0
def subv(xbody, iotype, name):
    xast = ast.parse(xbody, f'{iotype}:{name}.body', 'single').body[0]
    if isinstance(xast, ast.Assign):
        if isinstance(xast.value, ast.Compare) and len(
                xast.value.ops) == 1 and isinstance(xast.value.ops[0], ast.In):
            # x = y in z -> (lambda x: z)(y)
            rast: ast.Call = ast.parse('x(y)',
                                       f'{iotype}:{name}.replacement_body',
                                       'eval').body  # call(...)
            targets = xast.targets[0]
            if isinstance(targets, ast.Tuple):
                targets = targets.elts
            else:
                targets = [targets]
            rast.func = ast.Lambda(
                ast.arguments([ast.arg(x, None) for x in targets], None, None,
                              None, None, []),
                (lambda x: x if len(targets) == 1 else ast.Starred(x))(
                    xast.value.comparators[0]))
            rast.args = [xast.value.left]
            xast = rast
    return xast
Пример #19
0
    def set_call_arguments(self, node, args):
        """Set the arguments for an ast.Call node.

        On Python 3.5+, the starargs and kwargs attributes does not exists
        anymore.

        Parameters
        ----------
        node : ast.Call
            Node was arguments should be set.

        args : Arguments
            Arguments for the function call.

        """
        pos_args = args.args
        if args.starargs:
            pos_args += [ast.Starred(value=args.starargs, ctx=Load)]
        key_args = args.keywords
        if args.kwargs:
            key_args += [ast.keyword(arg=None, value=args.kwargs)]
        node.args = pos_args
        node.keywords = key_args
Пример #20
0
def generate_function_call(max_depth=None):
    args_len = random.randrange(MAX_ARGS_LENGTH)
    kwargs_len = random.randrange(MAX_ARGS_LENGTH)

    starred_args = random.choice([False, True])
    starred_kwargs = random.choice([False, True])

    args = [
        generate_expression(max_depth=max_depth - 1) for _ in range(args_len)
    ]
    if starred_args:
        starred = ast.Starred(generate_expression(max_depth=max_depth - 1),
                              ast.Load)
        args.append(starred)

    kwargs = [
        _generate_keyword(max_depth=max_depth) for _ in range(kwargs_len)
    ]
    if starred_kwargs:
        kwargs.append(_generate_keyword(max_depth=max_depth, starred=True))

    name = generate_variable()
    return ast.Call(func=name, args=args, keywords=kwargs)
Пример #21
0
    def decorator(wrapped):
        if sys.hexversion < 0x03000000:
            spec = inspect.getargspec(wrapped)
            assert spec.varargs is not None
            varargs = spec.varargs
            keywords = spec.keywords
        else:
            spec = inspect.getfullargspec(wrapped)
            assert spec.varargs is not None
            assert spec.kwonlyargs == []
            assert spec.kwonlydefaults is None
            assert spec.annotations == {}
            varargs = spec.varargs
            keywords = spec.varkw

        name = wrapped.__name__

        # Example was generated with print ast.dump(ast.parse("def f(a, b, *args, **kwds):
        # return call_wrapped((a, b), *args, **kwds)"), include_attributes=True)
        # http://code.activestate.com/recipes/578353-code-to-source-and-back/ helped a lot
        # http://stackoverflow.com/questions/10303248#29927459

        if sys.hexversion < 0x03000000:
            wrapper_ast_args = ast.arguments(args=[
                ast.Name(id=a, ctx=ast.Param(), lineno=1, col_offset=0)
                for a in spec.args
            ],
                                             vararg=varargs,
                                             kwarg=keywords,
                                             defaults=[])
        else:
            wrapper_ast_args = ast.arguments(
                args=[
                    ast.arg(arg=a, annotation=None, lineno=1, col_offset=0)
                    for a in spec.args
                ],
                vararg=(None if varargs is None else ast.arg(
                    arg=varargs, annotation=None, lineno=1, col_offset=0)),
                kwonlyargs=[],
                kw_defaults=[],
                kwarg=(None if keywords is None else ast.arg(
                    arg=keywords, annotation=None, lineno=1, col_offset=0)),
                defaults=[])

        wrapped_func = ast.Name(id="wrapped",
                                ctx=ast.Load(),
                                lineno=1,
                                col_offset=0)
        wrapped_args = [
            ast.Name(id=a, ctx=ast.Load(), lineno=1, col_offset=0)
            for a in spec.args
        ]
        flatten_func = ast.Name(id="flatten",
                                ctx=ast.Load(),
                                lineno=1,
                                col_offset=0)
        flatten_args = [
            ast.Name(id=spec.varargs, ctx=ast.Load(), lineno=1, col_offset=0)
        ]

        if sys.hexversion < 0x03050000:
            return_value = ast.Call(
                func=wrapped_func,
                args=wrapped_args,
                keywords=[],
                starargs=ast.Call(func=flatten_func,
                                  args=flatten_args,
                                  keywords=[],
                                  starargs=None,
                                  kwargs=None,
                                  lineno=1,
                                  col_offset=0),
                kwargs=(None if keywords is None else ast.Name(
                    id=keywords, ctx=ast.Load(), lineno=1, col_offset=0)),
                lineno=1,
                col_offset=0)
        else:
            return_value = ast.Call(
                func=wrapped_func,
                args=wrapped_args + [
                    ast.Starred(value=ast.Call(func=flatten_func,
                                               args=flatten_args,
                                               keywords=[],
                                               lineno=1,
                                               col_offset=0),
                                ctx=ast.Load(),
                                lineno=1,
                                col_offset=0),
                ],
                keywords=([] if keywords is None else [
                    ast.keyword(arg=None,
                                value=ast.Name(id=keywords,
                                               ctx=ast.Load(),
                                               lineno=1,
                                               col_offset=0))
                ]),
                lineno=1,
                col_offset=0)

        wrapper_ast = ast.Module(body=[
            ast.FunctionDef(
                name=name,
                args=wrapper_ast_args,
                body=[ast.Return(value=return_value, lineno=1, col_offset=0)],
                decorator_list=[],
                lineno=1,
                col_offset=0)
        ])
        wrapper_code = [
            c for c in compile(wrapper_ast, "<ast_in_variadic_py>",
                               "exec").co_consts
            if isinstance(c, types.CodeType)
        ][0]
        wrapper = types.FunctionType(wrapper_code, {
            "wrapped": wrapped,
            "flatten": flatten
        },
                                     argdefs=spec.defaults)

        functools.update_wrapper(wrapper, wrapped)
        return wrapper
Пример #22
0
 def visit_Starred(self, node):
     result = self.visit(node.value)
     return ast.Starred(result, node.ctx)
Пример #23
0
 def test_Starred(self):
     self.verify(ast.Starred(ast.Name('X', ast.Store()), ast.Store()), '*X')
Пример #24
0
 def test_starred(self):
     left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
                     ast.Store())
     assign = ast.Assign([left], ast.Num(4))
     self.stmt(assign, "must have Store context")
Пример #25
0
         ast.ExceptHandler(type=None),
         ast.ExceptHandler(type=1),
     ]),
     "must be placed last",
 ),
 (
     ast.Module([1, 2, ast.ImportFrom("__future__")]),
     "must occur at the top",
 ),
 (
     ast.Module(
         [ast.ImportFrom("__future__", names=[ast.alias(name="lol")])]),
     "'lol' is not defined",
 ),
 (
     ast.Assign(targets=[ast.Starred(), ast.Starred()]),
     "More then one starred expression",
 ),
 (
     ast.Assign(targets=([ast.Name("i")] * 500 + [ast.Starred()])),
     "Too many expressions",
 ),
 (
     ast.Assign(targets=([ast.Name("i")] * 500 + [ast.Starred()])),
     "Too many expressions",
 ),
 (ast.comprehension(is_async=1), "inside of a coroutine"),
 (ast.Yield(), "inside of a function"),
 (
     ast.AsyncFunctionDef(body=[ast.YieldFrom()]),
     "can't be used in a coroutine",
Пример #26
0
 def p_star_expr(self, p):
     ''' star_expr : STAR expr '''
     # We can assume Load as we will explicitely set Store
     p[0] = ast.Starred(value=p[2], ctx=Load)
Пример #27
0
 def visit_Starred(self, starred: ast.Starred) -> Tuple[ast.Starred, str]:
     # A Starred node can appear in a function call.
     res, expl = self.visit(starred.value)
     new_starred = ast.Starred(res, starred.ctx)
     return new_starred, "*" + expl
Пример #28
0
 def variadic_value(self, value):
     return value[0], ast.Starred(value[1], ast.Load())
Пример #29
0
 def visit_Starred(self, starred):
     # From Python 3.5, a Starred node can appear in a function call
     res, expl = self.visit(starred.value)
     new_starred = ast.Starred(res, starred.ctx)
     return new_starred, "*" + expl
Пример #30
0
    def generate(self, element, GC: GenerationContext):

        from anoky.generation.util import expr_wrap

        acode = element.code

        if isinstance(acode, Form):

            head = acode.first
            headcode = head.code

            if isinstance(
                    headcode,
                    Identifier) and headcode.full_name in GC.special_forms:

                head.color = colors.SPECIAL_FORM

                hcname = headcode.full_name

                special_form = GC.special_forms[hcname]

                generated_code = special_form.generate(element, GC)

                return generated_code

            else:
                # function call
                # #(func arg1 arg2 arg3 ...)

                func_element = head
                #func_element_code = headcode

                with GC.let(domain=ExDom):
                    func_code = GC.generate(func_element)

                arg_elements = acode[1:]

                args = []
                keywords = []

                for arg_element in arg_elements:
                    arg_element_code = arg_element.code

                    if isinstance(arg_element_code, Form):
                        if is_form(arg_element_code, '='):
                            # keyword argument

                            kw_name = arg_element_code[1].code.full_name

                            with GC.let(domain=ExDom):
                                value_code = GC.generate(arg_element_code[2])

                            keywords.append(ast.keyword(kw_name, value_code))

                        elif is_form(arg_element_code,
                                     '*') and len(arg_element_code) == 2:
                            # stared argument - expand as list
                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element_code[1])
                            args.append(ast.Starred(arg_code, ast.Load()))

                        elif is_form(arg_element_code,
                                     '**') and len(arg_element_code) == 2:
                            # double starred argument - expand as kwlist

                            assert len(arg_element_code) == 2
                            # verify no other dblstars already?

                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element_code[1])

                            keywords.append(ast.keyword(None, arg_code))

                        else:
                            # positional argument

                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element)

                            args.append(arg_code)

                    else:
                        # arg_element_code not a Form
                        # then generate as expression

                        with GC.let(domain=ExDom):
                            arg_code = GC.generate(arg_element)

                        args.append(arg_code)

                return expr_wrap(ast.Call(func_code, args, keywords), GC)

        if isinstance(acode, Seq):
            seq_codes = []
            with GC.let(domain=ExDom):
                for e in acode:
                    seq_codes.append(GC.generate(e))

            if GC.domain == LVDom:
                return ast.Tuple(seq_codes, ast.Store())
            elif GC.domain in [ExDom, SDom]:
                return expr_wrap(ast.Tuple(seq_codes, ast.Load()), GC)
            else:
                raise CodeGenerationError(
                    acode.range,
                    "Unexpected seq in domain `%s`." % str(GC.domain))

        if isinstance(acode, Literal):
            element.color = colors.LITERAL

            if acode.type is str:
                return expr_wrap(ast.Str(acode.value), GC)
            elif acode.type in [int, float]:
                return expr_wrap(ast.Num(acode.value), GC)
            else:
                assert False

        if isinstance(acode, Identifier):

            if acode.full_name == "True":
                return expr_wrap(ast.NameConstant(True), GC)

            elif acode.full_name == "False":
                return expr_wrap(ast.NameConstant(False), GC)

            elif acode.full_name == "None":
                return expr_wrap(ast.NameConstant(None), GC)

            elif acode.full_name in GC.special_forms:
                element.color = colors.SPECIAL_FORM
                raise CodeGenerationError(
                    acode.range,
                    "Refering to special form `%s` by name requires the use of `the`."
                    % acode.full_name)
            # elif acode.full_name in GC.macros:
            #     raise CodeGenerationError(acode.range,
            #                               "Refering to macro `%s` by name requires the use of `the`." % acode.full_name)
            # elif acode.full_name in GC.id_macros:
            #     raise CodeGenerationError(acode.range,
            #                               "Refering to identifier macro `%s` by name requires the use of `the`." % acode.full_name)

            elif GC.domain == LVDom:
                return ast.Name(acode.full_name, ast.Store())

            elif GC.domain == DelDom:
                return ast.Name(acode.full_name, ast.Del())

            else:
                return expr_wrap(ast.Name(acode.full_name, ast.Load()), GC)