| 860 | return nodes.Slice(lineno=lineno, *args) |
| 861 | |
| 862 | def parse_call_args(self) -> t.Tuple: |
| 863 | token = self.stream.expect("lparen") |
| 864 | args = [] |
| 865 | kwargs = [] |
| 866 | dyn_args = None |
| 867 | dyn_kwargs = None |
| 868 | require_comma = False |
| 869 | |
| 870 | def ensure(expr: bool) -> None: |
| 871 | if not expr: |
| 872 | self.fail("invalid syntax for function call expression", token.lineno) |
| 873 | |
| 874 | while self.stream.current.type != "rparen": |
| 875 | if require_comma: |
| 876 | self.stream.expect("comma") |
| 877 | |
| 878 | # support for trailing comma |
| 879 | if self.stream.current.type == "rparen": |
| 880 | break |
| 881 | |
| 882 | if self.stream.current.type == "mul": |
| 883 | ensure(dyn_args is None and dyn_kwargs is None) |
| 884 | next(self.stream) |
| 885 | dyn_args = self.parse_expression() |
| 886 | elif self.stream.current.type == "pow": |
| 887 | ensure(dyn_kwargs is None) |
| 888 | next(self.stream) |
| 889 | dyn_kwargs = self.parse_expression() |
| 890 | else: |
| 891 | if ( |
| 892 | self.stream.current.type == "name" |
| 893 | and self.stream.look().type == "assign" |
| 894 | ): |
| 895 | # Parsing a kwarg |
| 896 | ensure(dyn_kwargs is None) |
| 897 | key = self.stream.current.value |
| 898 | self.stream.skip(2) |
| 899 | value = self.parse_expression() |
| 900 | kwargs.append(nodes.Keyword(key, value, lineno=value.lineno)) |
| 901 | else: |
| 902 | # Parsing an arg |
| 903 | ensure(dyn_args is None and dyn_kwargs is None and not kwargs) |
| 904 | args.append(self.parse_expression()) |
| 905 | |
| 906 | require_comma = True |
| 907 | |
| 908 | self.stream.expect("rparen") |
| 909 | return args, kwargs, dyn_args, dyn_kwargs |
| 910 | |
| 911 | def parse_call(self, node: nodes.Expr) -> nodes.Call: |
| 912 | # The lparen will be expected in parse_call_args, but the lineno |