diff --git a/xonsh/parser.py b/xonsh/parser.py index 7fd323148..2a9f821ef 100644 --- a/xonsh/parser.py +++ b/xonsh/parser.py @@ -199,7 +199,7 @@ class Parser(object): self.lexer = lexer = Lexer() self.tokens = lexer.tokens - opt_rules = ( + opt_rules = [ 'newlines', 'arglist', 'func_call', 'rarrow_test', 'typedargslist', 'equals_test', 'colon_test', 'tfpdef', 'comma_tfpdef_list', 'comma_pow_tfpdef', 'vfpdef', 'comma_vfpdef_list', @@ -213,12 +213,13 @@ class Parser(object): 'op_factor_list', 'trailer_list', 'testlist_comp', 'yield_expr_or_testlist_comp', 'dictorsetmaker', 'comma_subscript_list', 'test', 'sliceop', 'comp_iter', - 'yield_arg', 'argument_comma_list', 'comma_argument_list', - 'test_comma_list', ) + 'yield_arg', 'test_comma_list',] + if VER_MAJOR_MINOR <= VER_3_4: + opt_rules += ['argument_comma_list', 'comma_argument_list',] for rule in opt_rules: self._opt_rule(rule) - list_rules = ( + list_rules = [ 'comma_tfpdef', 'comma_vfpdef', 'semi_small_stmt', 'comma_test_or_star_expr', 'period_or_ellipsis', 'comma_import_as_name', 'comma_dotted_as_name', 'period_name', @@ -226,9 +227,10 @@ class Parser(object): 'or_and_test', 'and_not_test', 'comp_op_expr', 'pipe_xor_expr', 'xor_and_expr', 'ampersand_shift_expr', 'shift_arith_expr', 'pm_term', 'op_factor', 'trailer', 'comma_subscript', - 'comma_expr_or_star_expr', 'comma_test', 'argument_comma', - 'comma_argument', 'comma_item', 'attr_period_name', 'test_comma', - 'equals_yield_expr_or_testlist', ) + 'comma_expr_or_star_expr', 'comma_test', 'comma_argument', 'comma_item', + 'attr_period_name', 'test_comma', 'equals_yield_expr_or_testlist', ] + if VER_MAJOR_MINOR <= VER_3_4: + list_rules += ['argument_comma',] for rule in list_rules: self._list_rule(rule) @@ -1978,61 +1980,79 @@ class Parser(object): else: args['args'].append(arg) - def p_arglist(self, p): - """arglist : argument comma_opt - | argument_comma_list argument comma_opt - | argument_comma_list_opt TIMES test comma_argument_list_opt - | argument_comma_list_opt TIMES test COMMA POW test - | argument_comma_list_opt TIMES test comma_argument_list COMMA POW test - | argument_comma_list_opt POW test - """ - lenp = len(p) - p1, p2 = p[1], p[2] - p0 = {'args': [], 'keywords': [], 'starargs': None, 'kwargs': None} - if lenp == 3: + # + # arglist rule had significant changes + # + if VER_3_5 <= VER_MAJOR_MINOR: + def p_arglist(self, p): + """arglist : argument comma_opt + | argument comma_argument_list comma_opt + """ + p0 = {'args': [], 'keywords': []} + p1, p2 = p[1], p[2] + p2 = None if p2 == ',' else p2 self._set_arg(p0, p1) - elif lenp == 4 and p2 != '**': - for arg in p1: - self._set_arg(p0, arg) - self._set_arg(p0, p2) - elif lenp == 4 and p2 == '**': - if p1 is not None: + if p2 is not None: + for arg in p2: + self._set_arg(p0, arg) + p[0] = p0 + else: # Python v3.4 + def p_arglist(self, p): + """arglist : argument comma_opt + | argument_comma_list argument comma_opt + | argument_comma_list_opt TIMES test comma_argument_list_opt + | argument_comma_list_opt TIMES test COMMA POW test + | argument_comma_list_opt TIMES test comma_argument_list COMMA POW test + | argument_comma_list_opt POW test + """ + lenp = len(p) + p1, p2 = p[1], p[2] + p0 = {'args': [], 'keywords': [], 'starargs': None, 'kwargs': None} + if lenp == 3: + self._set_arg(p0, p1) + elif lenp == 4 and p2 != '**': for arg in p1: self._set_arg(p0, arg) - self._set_arg(p0, p[3], ensure_kw=True) - elif lenp == 5: - p0['starargs'], p4 = p[3], p[4] - if p1 is not None: - for arg in p1: - self._set_arg(p0, arg) - if p4 is not None: + self._set_arg(p0, p2) + elif lenp == 4 and p2 == '**': + if p1 is not None: + for arg in p1: + self._set_arg(p0, arg) + self._set_arg(p0, p[3], ensure_kw=True) + elif lenp == 5: + p0['starargs'], p4 = p[3], p[4] + if p1 is not None: + for arg in p1: + self._set_arg(p0, arg) + if p4 is not None: + for arg in p4: + self._set_arg(p0, arg, ensure_kw=True) + elif lenp == 7: + p0['starargs'] = p[3] + if p1 is not None: + for arg in p1: + self._set_arg(p0, arg) + self._set_arg(p0, p[6], ensure_kw=True) + elif lenp == 8: + kwkey = 'keywords' if VER_MAJOR_MINOR >= VER_3_5 else 'kwargs' + p0['starargs'], p4 = p[3], p[4] + if p1 is not None: + for arg in p1: + self._set_arg(p0, arg) for arg in p4: self._set_arg(p0, arg, ensure_kw=True) - elif lenp == 7: - p0['starargs'] = p[3] - if p1 is not None: - for arg in p1: - self._set_arg(p0, arg) - self._set_arg(p0, p[6], ensure_kw=True) - elif lenp == 8: - kwkey = 'keywords' if VER_MAJOR_MINOR >= VER_3_5 else 'kwargs' - p0['starargs'], p4 = p[3], p[4] - if p1 is not None: - for arg in p1: - self._set_arg(p0, arg) - for arg in p4: - self._set_arg(p0, arg, ensure_kw=True) - self._set_arg(p0, p[7], ensure_kw=True) - else: - assert False - p[0] = p0 + self._set_arg(p0, p[7], ensure_kw=True) + else: + assert False + p[0] = p0 - def p_argument_comma(self, p): - """argument_comma : argument COMMA""" - p[0] = [p[1]] + if VER_MAJOR_MINOR <= VER_3_4: + def p_argument_comma(self, p): + """argument_comma : argument COMMA""" + p[0] = [p[1]] def p_comma_argument(self, p): - """comma_argument : COMMA argument """ + """comma_argument : COMMA argument""" p[0] = [p[2]] @docstring_by_version(