diff options
-rw-r--r-- | Lib/idlelib/editor.py | 4 | ||||
-rw-r--r-- | Lib/idlelib/hyperparser.py | 8 | ||||
-rw-r--r-- | Lib/idlelib/idle_test/test_pyparse.py | 70 | ||||
-rw-r--r-- | Lib/idlelib/pyparse.py | 122 | ||||
-rw-r--r-- | Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst | 1 |
5 files changed, 103 insertions, 102 deletions
diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index b51c45c..ab9c7e6 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -1302,7 +1302,7 @@ class EditorWindow(object): startat = max(lno - context, 1) startatindex = repr(startat) + ".0" rawtext = text.get(startatindex, "insert") - y.set_str(rawtext) + y.set_code(rawtext) bod = y.find_good_parse_start( self.context_use_ps1, self._build_char_in_string_func(startatindex)) @@ -1316,7 +1316,7 @@ class EditorWindow(object): else: startatindex = "1.0" rawtext = text.get(startatindex, "insert") - y.set_str(rawtext) + y.set_code(rawtext) y.set_lo(0) c = y.get_continuation_type() diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py index 450a709..a42665b 100644 --- a/Lib/idlelib/hyperparser.py +++ b/Lib/idlelib/hyperparser.py @@ -44,7 +44,7 @@ class HyperParser: # at end. We add a space so that index won't be at end # of line, so that its status will be the same as the # char before it, if should. - parser.set_str(text.get(startatindex, stopatindex)+' \n') + parser.set_code(text.get(startatindex, stopatindex)+' \n') bod = parser.find_good_parse_start( editwin._build_char_in_string_func(startatindex)) if bod is not None or startat == 1: @@ -60,12 +60,12 @@ class HyperParser: # We add the newline because PyParse requires it. We add a # space so that index won't be at end of line, so that its # status will be the same as the char before it, if should. - parser.set_str(text.get(startatindex, stopatindex)+' \n') + parser.set_code(text.get(startatindex, stopatindex)+' \n') parser.set_lo(0) # We want what the parser has, minus the last newline and space. - self.rawtext = parser.str[:-2] - # Parser.str apparently preserves the statement we are in, so + self.rawtext = parser.code[:-2] + # Parser.code apparently preserves the statement we are in, so # that stopatindex can be used to synchronize the string with # the text box indices. self.stopatindex = stopatindex diff --git a/Lib/idlelib/idle_test/test_pyparse.py b/Lib/idlelib/idle_test/test_pyparse.py index c45815b..c7b645c 100644 --- a/Lib/idlelib/idle_test/test_pyparse.py +++ b/Lib/idlelib/idle_test/test_pyparse.py @@ -62,32 +62,32 @@ class PyParseTest(unittest.TestCase): self.assertEqual(self.parser.indentwidth, 4) self.assertEqual(self.parser.tabwidth, 4) - def test_set_str(self): + def test_set_code(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code # Not empty and doesn't end with newline. with self.assertRaises(AssertionError): - setstr('a') + setcode('a') tests = ('', 'a\n') for string in tests: with self.subTest(string=string): - setstr(string) - eq(p.str, 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 - setstr = p.set_str + setcode = p.set_code start = p.find_good_parse_start # Split def across lines. - setstr('"""This is a module docstring"""\n' + setcode('"""This is a module docstring"""\n' 'class C():\n' ' def __init__(self, a,\n' ' b=True):\n' @@ -117,7 +117,7 @@ class PyParseTest(unittest.TestCase): # Code without extra line break in def line - mostly returns the same # values. - setstr('"""This is a module docstring"""\n' + setcode('"""This is a module docstring"""\n' 'class C():\n' ' def __init__(self, a, b=True):\n' ' pass\n' @@ -138,19 +138,19 @@ class PyParseTest(unittest.TestCase): ' pass\n' ) p = self.parser - p.set_str(code) + 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.str. + # A value of 0 doesn't change self.code. p.set_lo(0) - self.assertEqual(p.str, code) + self.assertEqual(p.code, code) # An index that is preceded by a newline. p.set_lo(44) - self.assertEqual(p.str, code[44:]) + self.assertEqual(p.code, code[44:]) def test_tran(self): self.assertEqual('\t a([{b}])b"c\'d\n'.translate(self.parser._tran), @@ -159,7 +159,7 @@ class PyParseTest(unittest.TestCase): def test_study1(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code study = p._study1 (NONE, BACKSLASH, FIRST, NEXT, BRACKET) = range(5) @@ -197,7 +197,7 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) # resets study_level + setcode(test.string) # resets study_level study() eq(p.study_level, 1) eq(p.goodlines, test.goodlines) @@ -209,7 +209,7 @@ class PyParseTest(unittest.TestCase): def test_get_continuation_type(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code gettype = p.get_continuation_type (NONE, BACKSLASH, FIRST, NEXT, BRACKET) = range(5) @@ -224,13 +224,13 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) eq(gettype(), test.continuation) def test_study2(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code study = p._study2 TestInfo = namedtuple('TestInfo', ['string', 'start', 'end', 'lastch', @@ -276,7 +276,7 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) study() eq(p.study_level, 2) eq(p.stmt_start, test.start) @@ -291,7 +291,7 @@ class PyParseTest(unittest.TestCase): def test_get_num_lines_in_stmt(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code getlines = p.get_num_lines_in_stmt TestInfo = namedtuple('TestInfo', ['string', 'lines']) @@ -307,19 +307,19 @@ class PyParseTest(unittest.TestCase): ) # Blank string doesn't have enough elements in goodlines. - setstr('') + setcode('') with self.assertRaises(IndexError): getlines() for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) eq(getlines(), test.lines) def test_compute_bracket_indent(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code indent = p.compute_bracket_indent TestInfo = namedtuple('TestInfo', ['string', 'spaces']) @@ -340,18 +340,18 @@ class PyParseTest(unittest.TestCase): ) # Must be C_BRACKET continuation type. - setstr('def function1(self, a, b):\n') + setcode('def function1(self, a, b):\n') with self.assertRaises(AssertionError): indent() for test in tests: - setstr(test.string) + setcode(test.string) eq(indent(), test.spaces) def test_compute_backslash_indent(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code indent = p.compute_backslash_indent # Must be C_BACKSLASH continuation type. @@ -361,7 +361,7 @@ class PyParseTest(unittest.TestCase): ) for string in errors: with self.subTest(string=string): - setstr(string) + setcode(string) with self.assertRaises(AssertionError): indent() @@ -384,13 +384,13 @@ class PyParseTest(unittest.TestCase): ) for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) eq(indent(), test.spaces) def test_get_base_indent_string(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code baseindent = p.get_base_indent_string TestInfo = namedtuple('TestInfo', ['string', 'indent']) @@ -405,14 +405,14 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) eq(baseindent(), test.indent) def test_is_block_opener(self): yes = self.assertTrue no = self.assertFalse p = self.parser - setstr = p.set_str + setcode = p.set_code opener = p.is_block_opener TestInfo = namedtuple('TestInfo', ['string', 'assert_']) @@ -433,14 +433,14 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) test.assert_(opener()) def test_is_block_closer(self): yes = self.assertTrue no = self.assertFalse p = self.parser - setstr = p.set_str + setcode = p.set_code closer = p.is_block_closer TestInfo = namedtuple('TestInfo', ['string', 'assert_']) @@ -462,13 +462,13 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) test.assert_(closer()) def test_get_last_stmt_bracketing(self): eq = self.assertEqual p = self.parser - setstr = p.set_str + setcode = p.set_code bracketing = p.get_last_stmt_bracketing TestInfo = namedtuple('TestInfo', ['string', 'bracket']) @@ -489,7 +489,7 @@ class PyParseTest(unittest.TestCase): for test in tests: with self.subTest(string=test.string): - setstr(test.string) + setcode(test.string) eq(bracketing(), test.bracket) diff --git a/Lib/idlelib/pyparse.py b/Lib/idlelib/pyparse.py index 93607dc..443d198 100644 --- a/Lib/idlelib/pyparse.py +++ b/Lib/idlelib/pyparse.py @@ -149,9 +149,9 @@ class Parser: self.indentwidth = indentwidth self.tabwidth = tabwidth - def set_str(self, s): + def set_code(self, s): assert len(s) == 0 or s[-1] == '\n' - self.str = s + self.code = s self.study_level = 0 def find_good_parse_start(self, is_char_in_string=None, @@ -168,7 +168,7 @@ class Parser: function, meaning that when it says "no", it's absolutely guaranteed that the char is not in a string. """ - str, pos = self.str, None + code, pos = self.code, None if not is_char_in_string: # no clue -- make the caller pass everything @@ -177,13 +177,13 @@ class Parser: # Peek back from the end for a good place to start, # but don't try too often; pos will be left None, or # bumped to a legitimate synch point. - limit = len(str) + limit = len(code) for tries in range(5): - i = str.rfind(":\n", 0, limit) + i = code.rfind(":\n", 0, limit) if i < 0: break - i = str.rfind('\n', 0, i) + 1 # start of colon line (-1+1=0) - m = _synchre(str, i, limit) + i = code.rfind('\n', 0, i) + 1 # start of colon line (-1+1=0) + m = _synchre(code, i, limit) if m and not is_char_in_string(m.start()): pos = m.start() break @@ -197,7 +197,7 @@ class Parser: # going to have to parse the whole thing to be sure, so # give it one last try from the start, but stop wasting # time here regardless of the outcome. - m = _synchre(str) + m = _synchre(code) if m and not is_char_in_string(m.start()): pos = m.start() return pos @@ -206,7 +206,7 @@ class Parser: # matches. i = pos + 1 while 1: - m = _synchre(str, i) + m = _synchre(code, i) if m: s, i = m.span() if not is_char_in_string(s): @@ -220,9 +220,9 @@ class Parser: Intended to be called with the result of find_good_parse_start(). """ - assert lo == 0 or self.str[lo-1] == '\n' + assert lo == 0 or self.code[lo-1] == '\n' if lo > 0: - self.str = self.str[lo:] + self.code = self.code[lo:] # Build a translation table to map uninteresting chars to 'x', open # brackets to '(', close brackets to ')' while preserving quotes, @@ -249,13 +249,13 @@ class Parser: # to "(", all close brackets to ")", then collapse runs of # uninteresting characters. This can cut the number of chars # by a factor of 10-40, and so greatly speed the following loop. - str = self.str - str = str.translate(self._tran) - str = str.replace('xxxxxxxx', 'x') - str = str.replace('xxxx', 'x') - str = str.replace('xx', 'x') - str = str.replace('xx', 'x') - str = str.replace('\nx', '\n') + code = self.code + code = code.translate(self._tran) + code = code.replace('xxxxxxxx', 'x') + code = code.replace('xxxx', 'x') + code = code.replace('xx', 'x') + code = code.replace('xx', 'x') + code = code.replace('\nx', '\n') # Replacing x\n with \n would be incorrect because # x may be preceded by a backslash. @@ -266,9 +266,9 @@ class Parser: level = lno = 0 # level is nesting level; lno is line number self.goodlines = goodlines = [0] push_good = goodlines.append - i, n = 0, len(str) + i, n = 0, len(code) while i < n: - ch = str[i] + ch = code[i] i = i+1 # cases are checked in decreasing order of frequency @@ -295,19 +295,19 @@ class Parser: if ch == '"' or ch == "'": # consume the string quote = ch - if str[i-1:i+2] == quote * 3: + if code[i-1:i+2] == quote * 3: quote = quote * 3 firstlno = lno w = len(quote) - 1 i = i+w while i < n: - ch = str[i] + ch = code[i] i = i+1 if ch == 'x': continue - if str[i-1:i+w] == quote: + if code[i-1:i+w] == quote: i = i+w break @@ -322,7 +322,7 @@ class Parser: if ch == '\\': assert i < n - if str[i] == '\n': + if code[i] == '\n': lno = lno + 1 i = i+1 continue @@ -333,7 +333,7 @@ class Parser: # didn't break out of the loop, so we're still # inside a string if (lno - 1) == firstlno: - # before the previous \n in str, we were in the first + # before the previous \n in code, we were in the first # line of the string continuation = C_STRING_FIRST_LINE else: @@ -342,13 +342,13 @@ class Parser: if ch == '#': # consume the comment - i = str.find('\n', i) + i = code.find('\n', i) assert i >= 0 continue assert ch == '\\' assert i < n - if str[i] == '\n': + if code[i] == '\n': lno = lno + 1 if i+1 == n: continuation = C_BACKSLASH @@ -397,9 +397,9 @@ class Parser: self.study_level = 2 # Set p and q to slice indices of last interesting stmt. - str, goodlines = self.str, self.goodlines + code, goodlines = self.code, self.goodlines i = len(goodlines) - 1 # Index of newest line. - p = len(str) # End of goodlines[i] + p = len(code) # End of goodlines[i] while i: assert p # Make p be the index of the stmt at line number goodlines[i]. @@ -407,10 +407,10 @@ class Parser: q = p for nothing in range(goodlines[i-1], goodlines[i]): # tricky: sets p to 0 if no preceding newline - p = str.rfind('\n', 0, p-1) + 1 - # The stmt str[p:q] isn't a continuation, but may be blank + p = code.rfind('\n', 0, p-1) + 1 + # The stmt code[p:q] isn't a continuation, but may be blank # or a non-indenting comment line. - if _junkre(str, p): + if _junkre(code, p): i = i-1 else: break @@ -428,21 +428,21 @@ class Parser: bracketing = [(p, 0)] while p < q: # suck up all except ()[]{}'"#\\ - m = _chew_ordinaryre(str, p, q) + m = _chew_ordinaryre(code, p, q) if m: # we skipped at least one boring char newp = m.end() # back up over totally boring whitespace i = newp - 1 # index of last boring char - while i >= p and str[i] in " \t\n": + while i >= p and code[i] in " \t\n": i = i-1 if i >= p: - lastch = str[i] + lastch = code[i] p = newp if p >= q: break - ch = str[p] + ch = code[p] if ch in "([{": push_stack(p) @@ -469,14 +469,14 @@ class Parser: # have to. bracketing.append((p, len(stack)+1)) lastch = ch - p = _match_stringre(str, p, q).end() + p = _match_stringre(code, p, q).end() bracketing.append((p, len(stack))) continue if ch == '#': # consume comment and trailing newline bracketing.append((p, len(stack)+1)) - p = str.find('\n', p, q) + 1 + p = code.find('\n', p, q) + 1 assert p > 0 bracketing.append((p, len(stack))) continue @@ -484,9 +484,9 @@ class Parser: assert ch == '\\' p = p+1 # beyond backslash assert p < q - if str[p] != '\n': + if code[p] != '\n': # the program is invalid, but can't complain - lastch = ch + str[p] + lastch = ch + code[p] p = p+1 # beyond escaped char # end while p < q: @@ -503,28 +503,28 @@ class Parser: self._study2() assert self.continuation == C_BRACKET j = self.lastopenbracketpos - str = self.str - n = len(str) - origi = i = str.rfind('\n', 0, j) + 1 + code = self.code + n = len(code) + origi = i = code.rfind('\n', 0, j) + 1 j = j+1 # one beyond open bracket # find first list item; set i to start of its line while j < n: - m = _itemre(str, j) + m = _itemre(code, j) if m: j = m.end() - 1 # index of first interesting char extra = 0 break else: # this line is junk; advance to next line - i = j = str.find('\n', j) + 1 + i = j = code.find('\n', j) + 1 else: # nothing interesting follows the bracket; # reproduce the bracket line's indentation + a level j = i = origi - while str[j] in " \t": + while code[j] in " \t": j = j+1 extra = self.indentwidth - return len(str[i:j].expandtabs(self.tabwidth)) + extra + return len(code[i:j].expandtabs(self.tabwidth)) + extra def get_num_lines_in_stmt(self): """Return number of physical lines in last stmt. @@ -544,18 +544,18 @@ class Parser: """ self._study2() assert self.continuation == C_BACKSLASH - str = self.str + code = self.code i = self.stmt_start - while str[i] in " \t": + while code[i] in " \t": i = i+1 startpos = i # See whether the initial line starts an assignment stmt; i.e., # look for an = operator - endpos = str.find('\n', startpos) + 1 + endpos = code.find('\n', startpos) + 1 found = level = 0 while i < endpos: - ch = str[i] + ch = code[i] if ch in "([{": level = level + 1 i = i+1 @@ -564,14 +564,14 @@ class Parser: level = level - 1 i = i+1 elif ch == '"' or ch == "'": - i = _match_stringre(str, i, endpos).end() + i = _match_stringre(code, i, endpos).end() elif ch == '#': # This line is unreachable because the # makes a comment of # everything after it. break elif level == 0 and ch == '=' and \ - (i == 0 or str[i-1] not in "=<>!") and \ - str[i+1] != '=': + (i == 0 or code[i-1] not in "=<>!") and \ + code[i+1] != '=': found = 1 break else: @@ -581,16 +581,16 @@ class Parser: # found a legit =, but it may be the last interesting # thing on the line i = i+1 # move beyond the = - found = re.match(r"\s*\\", str[i:endpos]) is None + found = re.match(r"\s*\\", code[i:endpos]) is None if not found: # oh well ... settle for moving beyond the first chunk # of non-whitespace chars i = startpos - while str[i] not in " \t\n": + while code[i] not in " \t\n": i = i+1 - return len(str[self.stmt_start:i].expandtabs(\ + return len(code[self.stmt_start:i].expandtabs(\ self.tabwidth)) + 1 def get_base_indent_string(self): @@ -600,10 +600,10 @@ class Parser: self._study2() i, n = self.stmt_start, self.stmt_end j = i - str = self.str - while j < n and str[j] in " \t": + code = self.code + while j < n and code[j] in " \t": j = j + 1 - return str[i:j] + return code[i:j] def is_block_opener(self): "Return True if the last interesting statemtent opens a block." @@ -613,7 +613,7 @@ class Parser: def is_block_closer(self): "Return True if the last interesting statement closes a block." self._study2() - return _closere(self.str, self.stmt_start) is not None + return _closere(self.code, self.stmt_start) is not None def get_last_stmt_bracketing(self): """Return bracketing structure of the last interesting statement. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst b/Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst new file mode 100644 index 0000000..0832944 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst @@ -0,0 +1 @@ +Change ``str`` to ``code`` in pyparse. |