mirror of
https://github.com/python/cpython.git
synced 2025-08-18 15:51:23 +00:00
[3.12] gh-104719: IDLE - test existence of all tokenize references. (GH-104767) (#104844)
gh-104719: IDLE - test existence of all tokenize references. (GH-104767)
Class editor.IndentSearcher contains all editor references to tokenize module.
Module io tokenize reference cover those other modules.
(cherry picked from commit e561c09975
)
Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
parent
b151660883
commit
5e1799ea2e
5 changed files with 54 additions and 12 deletions
|
@ -4,6 +4,9 @@ Released on 2023-10-02
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
||||||
|
gh-104719: Remove IDLE's modification of tokenize.tabsize and test
|
||||||
|
other uses of tokenize data and methods.
|
||||||
|
|
||||||
gh-104499: Fix completions for Tk Aqua 8.7 (currently blank).
|
gh-104499: Fix completions for Tk Aqua 8.7 (currently blank).
|
||||||
|
|
||||||
gh-104486: Make About print both tcl and tk versions if different,
|
gh-104486: Make About print both tcl and tk versions if different,
|
||||||
|
|
|
@ -1571,7 +1571,7 @@ class EditorWindow:
|
||||||
# blocks are found).
|
# blocks are found).
|
||||||
|
|
||||||
def guess_indent(self):
|
def guess_indent(self):
|
||||||
opener, indented = IndentSearcher(self.text, self.tabwidth).run()
|
opener, indented = IndentSearcher(self.text).run()
|
||||||
if opener and indented:
|
if opener and indented:
|
||||||
raw, indentsmall = get_line_indent(opener, self.tabwidth)
|
raw, indentsmall = get_line_indent(opener, self.tabwidth)
|
||||||
raw, indentlarge = get_line_indent(indented, self.tabwidth)
|
raw, indentlarge = get_line_indent(indented, self.tabwidth)
|
||||||
|
@ -1609,15 +1609,10 @@ def get_line_indent(line, tabwidth):
|
||||||
|
|
||||||
|
|
||||||
class IndentSearcher:
|
class IndentSearcher:
|
||||||
|
"Manage initial indent guess, returned by run method."
|
||||||
|
|
||||||
# .run() chews over the Text widget, looking for a block opener
|
def __init__(self, text):
|
||||||
# and the stmt following it. Returns a pair,
|
|
||||||
# (line containing block opener, line containing stmt)
|
|
||||||
# Either or both may be None.
|
|
||||||
|
|
||||||
def __init__(self, text, tabwidth):
|
|
||||||
self.text = text
|
self.text = text
|
||||||
self.tabwidth = tabwidth
|
|
||||||
self.i = self.finished = 0
|
self.i = self.finished = 0
|
||||||
self.blkopenline = self.indentedline = None
|
self.blkopenline = self.indentedline = None
|
||||||
|
|
||||||
|
@ -1633,7 +1628,8 @@ class IndentSearcher:
|
||||||
def tokeneater(self, type, token, start, end, line,
|
def tokeneater(self, type, token, start, end, line,
|
||||||
INDENT=tokenize.INDENT,
|
INDENT=tokenize.INDENT,
|
||||||
NAME=tokenize.NAME,
|
NAME=tokenize.NAME,
|
||||||
OPENERS=('class', 'def', 'for', 'if', 'try', 'while')):
|
OPENERS=('class', 'def', 'for', 'if', 'match', 'try',
|
||||||
|
'while', 'with')):
|
||||||
if self.finished:
|
if self.finished:
|
||||||
pass
|
pass
|
||||||
elif type == NAME and token in OPENERS:
|
elif type == NAME and token in OPENERS:
|
||||||
|
@ -1643,6 +1639,10 @@ class IndentSearcher:
|
||||||
self.finished = 1
|
self.finished = 1
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""Return 2 lines containing block opener and and indent.
|
||||||
|
|
||||||
|
Either the indent line or both may be None.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
tokens = tokenize.generate_tokens(self.readline)
|
tokens = tokenize.generate_tokens(self.readline)
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
|
@ -1654,6 +1654,7 @@ class IndentSearcher:
|
||||||
|
|
||||||
### end autoindent code ###
|
### end autoindent code ###
|
||||||
|
|
||||||
|
|
||||||
def prepstr(s):
|
def prepstr(s):
|
||||||
"""Extract the underscore from a string.
|
"""Extract the underscore from a string.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
"Test editor, coverage 35%."
|
"Test editor, coverage 53%."
|
||||||
|
|
||||||
from idlelib import editor
|
from idlelib import editor
|
||||||
import unittest
|
import unittest
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from test.support import requires
|
from test.support import requires
|
||||||
from tkinter import Tk
|
from tkinter import Tk, Text
|
||||||
|
|
||||||
Editor = editor.EditorWindow
|
Editor = editor.EditorWindow
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class EditorWindowTest(unittest.TestCase):
|
||||||
e._close()
|
e._close()
|
||||||
|
|
||||||
|
|
||||||
class TestGetLineIndent(unittest.TestCase):
|
class GetLineIndentTest(unittest.TestCase):
|
||||||
def test_empty_lines(self):
|
def test_empty_lines(self):
|
||||||
for tabwidth in [1, 2, 4, 6, 8]:
|
for tabwidth in [1, 2, 4, 6, 8]:
|
||||||
for line in ['', '\n']:
|
for line in ['', '\n']:
|
||||||
|
@ -181,6 +181,36 @@ class IndentAndNewlineTest(unittest.TestCase):
|
||||||
eq(get('1.0', 'end'), ' def f1(self, a,\n \n return a + b\n')
|
eq(get('1.0', 'end'), ' def f1(self, a,\n \n return a + b\n')
|
||||||
|
|
||||||
|
|
||||||
|
class IndentSearcherTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
requires('gui')
|
||||||
|
cls.root = Tk()
|
||||||
|
cls.root.withdraw()
|
||||||
|
cls.text = Text(cls.root)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
cls.root.destroy()
|
||||||
|
del cls.root
|
||||||
|
|
||||||
|
def test_searcher(self):
|
||||||
|
text = self.text
|
||||||
|
searcher = (self.text)
|
||||||
|
test_info = (# text, (block, indent))
|
||||||
|
("", (None, None)),
|
||||||
|
("[1,", (None, None)), # TokenError
|
||||||
|
("if 1:\n", ('if 1:\n', None)),
|
||||||
|
("if 1:\n 2\n 3\n", ('if 1:\n', ' 2\n')),
|
||||||
|
)
|
||||||
|
for code, expected_pair in test_info:
|
||||||
|
with self.subTest(code=code):
|
||||||
|
insert(text, code)
|
||||||
|
actual_pair = editor.IndentSearcher(text).run()
|
||||||
|
self.assertEqual(actual_pair, expected_pair)
|
||||||
|
|
||||||
|
|
||||||
class RMenuTest(unittest.TestCase):
|
class RMenuTest(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -8,6 +8,12 @@ from idlelib.editor import EditorWindow
|
||||||
from idlelib import util
|
from idlelib import util
|
||||||
from idlelib.idle_test.mock_idle import Func
|
from idlelib.idle_test.mock_idle import Func
|
||||||
|
|
||||||
|
# Fail if either tokenize.open and t.detect_encoding does not exist.
|
||||||
|
# These are used in loadfile and encode.
|
||||||
|
# Also used in pyshell.MI.execfile and runscript.tabnanny.
|
||||||
|
from tokenize import open, detect_encoding
|
||||||
|
# Remove when we have proper tests that use both.
|
||||||
|
|
||||||
|
|
||||||
class IOBindingTest(unittest.TestCase):
|
class IOBindingTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Remove IDLE's modification of tokenize.tabsize and test other uses of
|
||||||
|
tokenize data and methods.
|
Loading…
Add table
Add a link
Reference in a new issue