Download lib/python3.9/idlelib/idle_test/test_pyparse.py from camenduru/slahmr-test: direct link, hf CLI and curl.
- Browser
- Download file 19.4 kB
-
https://huggingface.co/camenduru/slahmr-test/resolve/main/lib/python3.9/idlelib/idle_test/test_pyparse.py
- Command line
-
hf download hf://camenduru/slahmr-test/lib/python3.9/idlelib/idle_test/test_pyparse.py
-
curl -L -o test_pyparse.py https://huggingface.co/camenduru/slahmr-test/resolve/main/lib/python3.9/idlelib/idle_test/test_pyparse.py
19.4 kB
| "Test pyparse, coverage 96%." | |
| from idlelib import pyparse | |
| import unittest | |
| from collections import namedtuple | |
| class ParseMapTest(unittest.TestCase): | |
| def test_parsemap(self): | |
| keepwhite = {ord(c): ord(c) for c in ' \t\n\r'} | |
| mapping = pyparse.ParseMap(keepwhite) | |
| self.assertEqual(mapping[ord('\t')], ord('\t')) | |
| self.assertEqual(mapping[ord('a')], ord('x')) | |
| self.assertEqual(mapping[1000], ord('x')) | |
| def test_trans(self): | |
| # trans is the production instance of ParseMap, used in _study1 | |
| parser = pyparse.Parser(4, 4) | |
| self.assertEqual('\t a([{b}])b"c\'d\n'.translate(pyparse.trans), | |
| 'xxx(((x)))x"x\'x\n') | |
| class PyParseTest(unittest.TestCase): | |
| def setUpClass(cls): | |
| cls.parser = pyparse.Parser(indentwidth=4, tabwidth=4) | |
| def tearDownClass(cls): | |
| del cls.parser | |
| def test_init(self): | |
| self.assertEqual(self.parser.indentwidth, 4) | |
| self.assertEqual(self.parser.tabwidth, 4) | |
| def test_set_code(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| # Not empty and doesn't end with newline. | |
| with self.assertRaises(AssertionError): | |
| setcode('a') | |
| tests = ('', | |
| 'a\n') | |
| for string in tests: | |
| with self.subTest(string=string): | |
| setcode(string) | |
| eq(p.code, string) | |
| eq(p.study_level, 0) | |
| def test_find_good_parse_start(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| start = p.find_good_parse_start | |
| def char_in_string_false(index): return False | |
| # First line starts with 'def' and ends with ':', then 0 is the pos. | |
| setcode('def spam():\n') | |
| eq(start(char_in_string_false), 0) | |
| # First line begins with a keyword in the list and ends | |
| # with an open brace, then 0 is the pos. This is how | |
| # hyperparser calls this function as the newline is not added | |
| # in the editor, but rather on the call to setcode. | |
| setcode('class spam( ' + ' \n') | |
| eq(start(char_in_string_false), 0) | |
| # Split def across lines. | |
| setcode('"""This is a module docstring"""\n' | |
| 'class C:\n' | |
| ' def __init__(self, a,\n' | |
| ' b=True):\n' | |
| ' pass\n' | |
| ) | |
| pos0, pos = 33, 42 # Start of 'class...', ' def' lines. | |
| # Passing no value or non-callable should fail (issue 32989). | |
| with self.assertRaises(TypeError): | |
| start() | |
| with self.assertRaises(TypeError): | |
| start(False) | |
| # Make text look like a string. This returns pos as the start | |
| # position, but it's set to None. | |
| self.assertIsNone(start(is_char_in_string=lambda index: True)) | |
| # Make all text look like it's not in a string. This means that it | |
| # found a good start position. | |
| eq(start(char_in_string_false), pos) | |
| # If the beginning of the def line is not in a string, then it | |
| # returns that as the index. | |
| eq(start(is_char_in_string=lambda index: index > pos), pos) | |
| # If the beginning of the def line is in a string, then it | |
| # looks for a previous index. | |
| eq(start(is_char_in_string=lambda index: index >= pos), pos0) | |
| # If everything before the 'def' is in a string, then returns None. | |
| # The non-continuation def line returns 44 (see below). | |
| eq(start(is_char_in_string=lambda index: index < pos), None) | |
| # Code without extra line break in def line - mostly returns the same | |
| # values. | |
| setcode('"""This is a module docstring"""\n' | |
| 'class C:\n' | |
| ' def __init__(self, a, b=True):\n' | |
| ' pass\n' | |
| ) # Does not affect class, def positions. | |
| eq(start(char_in_string_false), pos) | |
| eq(start(is_char_in_string=lambda index: index > pos), pos) | |
| eq(start(is_char_in_string=lambda index: index >= pos), pos0) | |
| # When the def line isn't split, this returns which doesn't match the | |
| # split line test. | |
| eq(start(is_char_in_string=lambda index: index < pos), pos) | |
| def test_set_lo(self): | |
| code = ( | |
| '"""This is a module docstring"""\n' | |
| 'class C:\n' | |
| ' def __init__(self, a,\n' | |
| ' b=True):\n' | |
| ' pass\n' | |
| ) | |
| pos = 42 | |
| p = self.parser | |
| p.set_code(code) | |
| # Previous character is not a newline. | |
| with self.assertRaises(AssertionError): | |
| p.set_lo(5) | |
| # A value of 0 doesn't change self.code. | |
| p.set_lo(0) | |
| self.assertEqual(p.code, code) | |
| # An index that is preceded by a newline. | |
| p.set_lo(pos) | |
| self.assertEqual(p.code, code[pos:]) | |
| def test_study1(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| study = p._study1 | |
| (NONE, BACKSLASH, FIRST, NEXT, BRACKET) = range(5) | |
| TestInfo = namedtuple('TestInfo', ['string', 'goodlines', | |
| 'continuation']) | |
| tests = ( | |
| TestInfo('', [0], NONE), | |
| # Docstrings. | |
| TestInfo('"""This is a complete docstring."""\n', [0, 1], NONE), | |
| TestInfo("'''This is a complete docstring.'''\n", [0, 1], NONE), | |
| TestInfo('"""This is a continued docstring.\n', [0, 1], FIRST), | |
| TestInfo("'''This is a continued docstring.\n", [0, 1], FIRST), | |
| TestInfo('"""Closing quote does not match."\n', [0, 1], FIRST), | |
| TestInfo('"""Bracket in docstring [\n', [0, 1], FIRST), | |
| TestInfo("'''Incomplete two line docstring.\n\n", [0, 2], NEXT), | |
| # Single-quoted strings. | |
| TestInfo('"This is a complete string."\n', [0, 1], NONE), | |
| TestInfo('"This is an incomplete string.\n', [0, 1], NONE), | |
| TestInfo("'This is more incomplete.\n\n", [0, 1, 2], NONE), | |
| # Comment (backslash does not continue comments). | |
| TestInfo('# Comment\\\n', [0, 1], NONE), | |
| # Brackets. | |
| TestInfo('("""Complete string in bracket"""\n', [0, 1], BRACKET), | |
| TestInfo('("""Open string in bracket\n', [0, 1], FIRST), | |
| TestInfo('a = (1 + 2) - 5 *\\\n', [0, 1], BACKSLASH), # No bracket. | |
| TestInfo('\n def function1(self, a,\n b):\n', | |
| [0, 1, 3], NONE), | |
| TestInfo('\n def function1(self, a,\\\n', [0, 1, 2], BRACKET), | |
| TestInfo('\n def function1(self, a,\n', [0, 1, 2], BRACKET), | |
| TestInfo('())\n', [0, 1], NONE), # Extra closer. | |
| TestInfo(')(\n', [0, 1], BRACKET), # Extra closer. | |
| # For the mismatched example, it doesn't look like continuation. | |
| TestInfo('{)(]\n', [0, 1], NONE), # Mismatched. | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) # resets study_level | |
| study() | |
| eq(p.study_level, 1) | |
| eq(p.goodlines, test.goodlines) | |
| eq(p.continuation, test.continuation) | |
| # Called again, just returns without reprocessing. | |
| self.assertIsNone(study()) | |
| def test_get_continuation_type(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| gettype = p.get_continuation_type | |
| (NONE, BACKSLASH, FIRST, NEXT, BRACKET) = range(5) | |
| TestInfo = namedtuple('TestInfo', ['string', 'continuation']) | |
| tests = ( | |
| TestInfo('', NONE), | |
| TestInfo('"""This is a continuation docstring.\n', FIRST), | |
| TestInfo("'''This is a multiline-continued docstring.\n\n", NEXT), | |
| TestInfo('a = (1 + 2) - 5 *\\\n', BACKSLASH), | |
| TestInfo('\n def function1(self, a,\\\n', BRACKET) | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| eq(gettype(), test.continuation) | |
| def test_study2(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| study = p._study2 | |
| TestInfo = namedtuple('TestInfo', ['string', 'start', 'end', 'lastch', | |
| 'openbracket', 'bracketing']) | |
| tests = ( | |
| TestInfo('', 0, 0, '', None, ((0, 0),)), | |
| TestInfo("'''This is a multiline continuation docstring.\n\n", | |
| 0, 48, "'", None, ((0, 0), (0, 1), (48, 0))), | |
| TestInfo(' # Comment\\\n', | |
| 0, 12, '', None, ((0, 0), (1, 1), (12, 0))), | |
| # A comment without a space is a special case | |
| TestInfo(' #Comment\\\n', | |
| 0, 0, '', None, ((0, 0),)), | |
| # Backslash continuation. | |
| TestInfo('a = (1 + 2) - 5 *\\\n', | |
| 0, 19, '*', None, ((0, 0), (4, 1), (11, 0))), | |
| # Bracket continuation with close. | |
| TestInfo('\n def function1(self, a,\n b):\n', | |
| 1, 48, ':', None, ((1, 0), (17, 1), (46, 0))), | |
| # Bracket continuation with unneeded backslash. | |
| TestInfo('\n def function1(self, a,\\\n', | |
| 1, 28, ',', 17, ((1, 0), (17, 1))), | |
| # Bracket continuation. | |
| TestInfo('\n def function1(self, a,\n', | |
| 1, 27, ',', 17, ((1, 0), (17, 1))), | |
| # Bracket continuation with comment at end of line with text. | |
| TestInfo('\n def function1(self, a, # End of line comment.\n', | |
| 1, 51, ',', 17, ((1, 0), (17, 1), (28, 2), (51, 1))), | |
| # Multi-line statement with comment line in between code lines. | |
| TestInfo(' a = ["first item",\n # Comment line\n "next item",\n', | |
| 0, 55, ',', 6, ((0, 0), (6, 1), (7, 2), (19, 1), | |
| (23, 2), (38, 1), (42, 2), (53, 1))), | |
| TestInfo('())\n', | |
| 0, 4, ')', None, ((0, 0), (0, 1), (2, 0), (3, 0))), | |
| TestInfo(')(\n', 0, 3, '(', 1, ((0, 0), (1, 0), (1, 1))), | |
| # Wrong closers still decrement stack level. | |
| TestInfo('{)(]\n', | |
| 0, 5, ']', None, ((0, 0), (0, 1), (2, 0), (2, 1), (4, 0))), | |
| # Character after backslash. | |
| TestInfo(':\\a\n', 0, 4, '\\a', None, ((0, 0),)), | |
| TestInfo('\n', 0, 0, '', None, ((0, 0),)), | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| study() | |
| eq(p.study_level, 2) | |
| eq(p.stmt_start, test.start) | |
| eq(p.stmt_end, test.end) | |
| eq(p.lastch, test.lastch) | |
| eq(p.lastopenbracketpos, test.openbracket) | |
| eq(p.stmt_bracketing, test.bracketing) | |
| # Called again, just returns without reprocessing. | |
| self.assertIsNone(study()) | |
| def test_get_num_lines_in_stmt(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| getlines = p.get_num_lines_in_stmt | |
| TestInfo = namedtuple('TestInfo', ['string', 'lines']) | |
| tests = ( | |
| TestInfo('[x for x in a]\n', 1), # Closed on one line. | |
| TestInfo('[x\nfor x in a\n', 2), # Not closed. | |
| TestInfo('[x\\\nfor x in a\\\n', 2), # "", unneeded backslashes. | |
| TestInfo('[x\nfor x in a\n]\n', 3), # Closed on multi-line. | |
| TestInfo('\n"""Docstring comment L1"""\nL2\nL3\nL4\n', 1), | |
| TestInfo('\n"""Docstring comment L1\nL2"""\nL3\nL4\n', 1), | |
| TestInfo('\n"""Docstring comment L1\\\nL2\\\nL3\\\nL4\\\n', 4), | |
| TestInfo('\n\n"""Docstring comment L1\\\nL2\\\nL3\\\nL4\\\n"""\n', 5) | |
| ) | |
| # Blank string doesn't have enough elements in goodlines. | |
| setcode('') | |
| with self.assertRaises(IndexError): | |
| getlines() | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| eq(getlines(), test.lines) | |
| def test_compute_bracket_indent(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| indent = p.compute_bracket_indent | |
| TestInfo = namedtuple('TestInfo', ['string', 'spaces']) | |
| tests = ( | |
| TestInfo('def function1(self, a,\n', 14), | |
| # Characters after bracket. | |
| TestInfo('\n def function1(self, a,\n', 18), | |
| TestInfo('\n\tdef function1(self, a,\n', 18), | |
| # No characters after bracket. | |
| TestInfo('\n def function1(\n', 8), | |
| TestInfo('\n\tdef function1(\n', 8), | |
| TestInfo('\n def function1( \n', 8), # Ignore extra spaces. | |
| TestInfo('[\n"first item",\n # Comment line\n "next item",\n', 0), | |
| TestInfo('[\n "first item",\n # Comment line\n "next item",\n', 2), | |
| TestInfo('["first item",\n # Comment line\n "next item",\n', 1), | |
| TestInfo('(\n', 4), | |
| TestInfo('(a\n', 1), | |
| ) | |
| # Must be C_BRACKET continuation type. | |
| setcode('def function1(self, a, b):\n') | |
| with self.assertRaises(AssertionError): | |
| indent() | |
| for test in tests: | |
| setcode(test.string) | |
| eq(indent(), test.spaces) | |
| def test_compute_backslash_indent(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| indent = p.compute_backslash_indent | |
| # Must be C_BACKSLASH continuation type. | |
| errors = (('def function1(self, a, b\\\n'), # Bracket. | |
| (' """ (\\\n'), # Docstring. | |
| ('a = #\\\n'), # Inline comment. | |
| ) | |
| for string in errors: | |
| with self.subTest(string=string): | |
| setcode(string) | |
| with self.assertRaises(AssertionError): | |
| indent() | |
| TestInfo = namedtuple('TestInfo', ('string', 'spaces')) | |
| tests = (TestInfo('a = (1 + 2) - 5 *\\\n', 4), | |
| TestInfo('a = 1 + 2 - 5 *\\\n', 4), | |
| TestInfo(' a = 1 + 2 - 5 *\\\n', 8), | |
| TestInfo(' a = "spam"\\\n', 6), | |
| TestInfo(' a = \\\n"a"\\\n', 4), | |
| TestInfo(' a = #\\\n"a"\\\n', 5), | |
| TestInfo('a == \\\n', 2), | |
| TestInfo('a != \\\n', 2), | |
| # Difference between containing = and those not. | |
| TestInfo('\\\n', 2), | |
| TestInfo(' \\\n', 6), | |
| TestInfo('\t\\\n', 6), | |
| TestInfo('a\\\n', 3), | |
| TestInfo('{}\\\n', 4), | |
| TestInfo('(1 + 2) - 5 *\\\n', 3), | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| eq(indent(), test.spaces) | |
| def test_get_base_indent_string(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| baseindent = p.get_base_indent_string | |
| TestInfo = namedtuple('TestInfo', ['string', 'indent']) | |
| tests = (TestInfo('', ''), | |
| TestInfo('def a():\n', ''), | |
| TestInfo('\tdef a():\n', '\t'), | |
| TestInfo(' def a():\n', ' '), | |
| TestInfo(' def a(\n', ' '), | |
| TestInfo('\t\n def a(\n', ' '), | |
| TestInfo('\t\n # Comment.\n', ' '), | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| eq(baseindent(), test.indent) | |
| def test_is_block_opener(self): | |
| yes = self.assertTrue | |
| no = self.assertFalse | |
| p = self.parser | |
| setcode = p.set_code | |
| opener = p.is_block_opener | |
| TestInfo = namedtuple('TestInfo', ['string', 'assert_']) | |
| tests = ( | |
| TestInfo('def a():\n', yes), | |
| TestInfo('\n def function1(self, a,\n b):\n', yes), | |
| TestInfo(':\n', yes), | |
| TestInfo('a:\n', yes), | |
| TestInfo('):\n', yes), | |
| TestInfo('(:\n', yes), | |
| TestInfo('":\n', no), | |
| TestInfo('\n def function1(self, a,\n', no), | |
| TestInfo('def function1(self, a):\n pass\n', no), | |
| TestInfo('# A comment:\n', no), | |
| TestInfo('"""A docstring:\n', no), | |
| TestInfo('"""A docstring:\n', no), | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| test.assert_(opener()) | |
| def test_is_block_closer(self): | |
| yes = self.assertTrue | |
| no = self.assertFalse | |
| p = self.parser | |
| setcode = p.set_code | |
| closer = p.is_block_closer | |
| TestInfo = namedtuple('TestInfo', ['string', 'assert_']) | |
| tests = ( | |
| TestInfo('return\n', yes), | |
| TestInfo('\tbreak\n', yes), | |
| TestInfo(' continue\n', yes), | |
| TestInfo(' raise\n', yes), | |
| TestInfo('pass \n', yes), | |
| TestInfo('pass\t\n', yes), | |
| TestInfo('return #\n', yes), | |
| TestInfo('raised\n', no), | |
| TestInfo('returning\n', no), | |
| TestInfo('# return\n', no), | |
| TestInfo('"""break\n', no), | |
| TestInfo('"continue\n', no), | |
| TestInfo('def function1(self, a):\n pass\n', yes), | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| test.assert_(closer()) | |
| def test_get_last_stmt_bracketing(self): | |
| eq = self.assertEqual | |
| p = self.parser | |
| setcode = p.set_code | |
| bracketing = p.get_last_stmt_bracketing | |
| TestInfo = namedtuple('TestInfo', ['string', 'bracket']) | |
| tests = ( | |
| TestInfo('', ((0, 0),)), | |
| TestInfo('a\n', ((0, 0),)), | |
| TestInfo('()()\n', ((0, 0), (0, 1), (2, 0), (2, 1), (4, 0))), | |
| TestInfo('(\n)()\n', ((0, 0), (0, 1), (3, 0), (3, 1), (5, 0))), | |
| TestInfo('()\n()\n', ((3, 0), (3, 1), (5, 0))), | |
| TestInfo('()(\n)\n', ((0, 0), (0, 1), (2, 0), (2, 1), (5, 0))), | |
| TestInfo('(())\n', ((0, 0), (0, 1), (1, 2), (3, 1), (4, 0))), | |
| TestInfo('(\n())\n', ((0, 0), (0, 1), (2, 2), (4, 1), (5, 0))), | |
| # Same as matched test. | |
| TestInfo('{)(]\n', ((0, 0), (0, 1), (2, 0), (2, 1), (4, 0))), | |
| TestInfo('(((())\n', | |
| ((0, 0), (0, 1), (1, 2), (2, 3), (3, 4), (5, 3), (6, 2))), | |
| ) | |
| for test in tests: | |
| with self.subTest(string=test.string): | |
| setcode(test.string) | |
| eq(bracketing(), test.bracket) | |
| if __name__ == '__main__': | |
| unittest.main(verbosity=2) | |