diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 2f1b2197809..274e26061a1 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -322,21 +322,19 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): # An absolutely minimal test of position information. Better # tests would be a big project. code = "def f(x):\n return x + 1" - st1 = parser.suite(code) - st2 = st1.totuple(line_info=1, col_info=1) + st = parser.suite(code) def walk(tree): node_type = tree[0] next = tree[1] - if isinstance(next, tuple): + if isinstance(next, (tuple, list)): for elt in tree[1:]: for x in walk(elt): yield x else: yield tree - terminals = list(walk(st2)) - self.assertEqual([ + expected = [ (1, 'def', 1, 0), (1, 'f', 1, 4), (7, '(', 1, 5), @@ -352,8 +350,25 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): (4, '', 2, 16), (6, '', 2, -1), (4, '', 2, -1), - (0, '', 2, -1)], - terminals) + (0, '', 2, -1), + ] + + self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))), + expected) + self.assertEqual(list(walk(st.totuple())), + [(t, n) for t, n, l, c in expected]) + self.assertEqual(list(walk(st.totuple(line_info=True))), + [(t, n, l) for t, n, l, c in expected]) + self.assertEqual(list(walk(st.totuple(col_info=True))), + [(t, n, c) for t, n, l, c in expected]) + self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))), + [list(x) for x in expected]) + self.assertEqual(list(walk(parser.st2tuple(st, line_info=True, + col_info=True))), + expected) + self.assertEqual(list(walk(parser.st2list(st, line_info=True, + col_info=True))), + [list(x) for x in expected]) def test_extended_unpacking(self): self.check_suite("*a = y") diff --git a/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst b/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst new file mode 100644 index 00000000000..586004a3c6c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst @@ -0,0 +1,2 @@ +Fixed a crash in the :mod:`parser` module when converting an ST object to a +tree of tuples or lists with ``line_info=False`` and ``col_info=True``. diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 2b98be40e30..38e5f750d57 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -135,18 +135,18 @@ node2tuple(node *n, /* node to convert */ goto error; (void) addelem(result, 1, w); - if (lineno == 1) { + if (lineno) { w = PyLong_FromLong(n->n_lineno); if (w == NULL) goto error; (void) addelem(result, 2, w); } - if (col_offset == 1) { + if (col_offset) { w = PyLong_FromLong(n->n_col_offset); if (w == NULL) goto error; - (void) addelem(result, 3, w); + (void) addelem(result, 2 + lineno, w); } } else {