Author: Ronan Lamy <[email protected]>
Branch: py3.6
Changeset: r97122:2ab7f3bbe84f
Date: 2019-08-09 16:17 +0100
http://bitbucket.org/pypy/pypy/changeset/2ab7f3bbe84f/

Log:    fix bad merge in idlelib

diff too long, truncating to 2000 out of 2142 lines

diff --git a/lib-python/3/idlelib/filelist.py b/lib-python/3/idlelib/filelist.py
--- a/lib-python/3/idlelib/filelist.py
+++ b/lib-python/3/idlelib/filelist.py
@@ -120,7 +120,7 @@
     fixwordbreaks(root)
     root.withdraw()
     flist = FileList(root)
-        flist.new()
+    flist.new()
     if flist.inversedict:
         root.mainloop()
 
diff --git a/lib-python/3/idlelib/help.html b/lib-python/3/idlelib/help.html
--- a/lib-python/3/idlelib/help.html
+++ b/lib-python/3/idlelib/help.html
@@ -66,14 +66,14 @@
           <a href="tkinter.scrolledtext.html" title="tkinter.scrolledtext 
&#8212; Scrolled Text Widget"
              accesskey="P">previous</a> |</li>
 
-        <li><img src="../_static/py.png" alt=""
-                 style="vertical-align: middle; margin-top: -1px"/></li>
+    <li><img src="../_static/py.png" alt=""
+             style="vertical-align: middle; margin-top: -1px"/></li>
     <li><a href="https://www.python.org/";>Python</a> &#187;</li>
 
 
-        <li>
+    <li>
       <a href="../index.html">3.8.0a0 Documentation</a> &#187;
-        </li>
+    </li>
 
           <li class="nav-item nav-item-1"><a href="index.html" >The Python 
Standard Library</a> &#187;</li>
           <li class="nav-item nav-item-2"><a href="tk.html" 
accesskey="U">Graphical User Interfaces with Tk</a> &#187;</li>
@@ -862,14 +862,14 @@
           <a href="tkinter.scrolledtext.html" title="tkinter.scrolledtext 
&#8212; Scrolled Text Widget"
              >previous</a> |</li>
 
-        <li><img src="../_static/py.png" alt=""
-                 style="vertical-align: middle; margin-top: -1px"/></li>
+    <li><img src="../_static/py.png" alt=""
+             style="vertical-align: middle; margin-top: -1px"/></li>
     <li><a href="https://www.python.org/";>Python</a> &#187;</li>
 
 
-        <li>
+    <li>
       <a href="../index.html">3.8.0a0 Documentation</a> &#187;
-        </li>
+    </li>
 
           <li class="nav-item nav-item-1"><a href="index.html" >The Python 
Standard Library</a> &#187;</li>
           <li class="nav-item nav-item-2"><a href="tk.html" >Graphical User 
Interfaces with Tk</a> &#187;</li>
@@ -895,8 +895,8 @@
     <br />
 
     The Python Software Foundation is a non-profit corporation.
-    <a href="https://www.python.org/psf/donations/";>Please donate.</a>
-    <br />
+<a href="https://www.python.org/psf/donations/";>Please donate.</a>
+<br />
     <br />
 
     Last updated on Nov 12, 2018.
diff --git a/lib-python/3/idlelib/help.txt b/lib-python/3/idlelib/help.txt
deleted file mode 100644
--- a/lib-python/3/idlelib/help.txt
+++ /dev/null
@@ -1,372 +0,0 @@
-This file, idlelib/help.txt is out-of-date and no longer used by Idle.
-It is deprecated and will be removed in the future, possibly in 3.6
-----------------------------------------------------------------------
-
-[See the end of this file for ** TIPS ** on using IDLE !!]
-
-IDLE is the Python IDE built with the tkinter GUI toolkit.
-
-IDLE has the following features:
--coded in 100% pure Python, using the tkinter GUI toolkit
--cross-platform: works on Windows, Unix, and OS X
--multi-window text editor with multiple undo, Python colorizing, smart indent,
-call tips, and many other features
--Python shell window (a.k.a interactive interpreter)
--debugger (not complete, but you can set breakpoints, view and step)
-
-Menus:
-
-IDLE has two window types the Shell window and the Editor window. It is
-possible to have multiple editor windows simultaneously. IDLE's
-menus dynamically change based on which window is currently selected. Each menu
-documented below indicates which window type it is associated with. 
-
-File Menu (Shell and Editor):
-
-        New File         -- Create a new file editing window
-        Open...          -- Open an existing file
-        Open Module...   -- Open an existing module (searches sys.path)
-        Recent Files...  -- Open a list of recent files
-        Class Browser    -- Show classes and methods in current file
-        Path Browser     -- Show sys.path directories, modules, classes,
-                            and methods
-        ---
-        Save             -- Save current window to the associated file (unsaved
-                            windows have a * before and after the window title)
-
-        Save As...       -- Save current window to new file, which becomes
-                            the associated file
-        Save Copy As...  -- Save current window to different file
-                            without changing the associated file
-        ---
-        Print Window     -- Print the current window
-        ---
-        Close            -- Close current window (asks to save if unsaved)
-        Exit             -- Close all windows, quit (asks to save if unsaved)
-
-Edit Menu (Shell and Editor):
-
-        Undo             -- Undo last change to current window
-                            (a maximum of 1000 changes may be undone)
-        Redo             -- Redo last undone change to current window
-        ---
-        Cut              -- Copy a selection into system-wide clipboard,
-                            then delete the selection
-        Copy             -- Copy selection into system-wide clipboard
-        Paste            -- Insert system-wide clipboard into window
-        Select All       -- Select the entire contents of the edit buffer
-        ---
-        Find...          -- Open a search dialog box with many options
-        Find Again       -- Repeat last search
-        Find Selection   -- Search for the string in the selection
-        Find in Files... -- Open a search dialog box for searching files
-        Replace...       -- Open a search-and-replace dialog box
-        Go to Line       -- Ask for a line number and show that line
-        Expand Word      -- Expand the word you have typed to match another
-                            word in the same buffer; repeat to get a
-                            different expansion
-        Show Calltip     -- After an unclosed parenthesis for a function, open
-                            a small window with function parameter hints
-        Show Parens      -- Highlight the surrounding parenthesis
-        Show Completions -- Open a scroll window allowing selection keywords
-                            and attributes. (see '*TIPS*', below)
-
-Format Menu (Editor window only):
-
-        Indent Region       -- Shift selected lines right by the indent width
-                               (default 4 spaces)
-        Dedent Region       -- Shift selected lines left by the indent width
-                               (default 4 spaces)
-        Comment Out Region  -- Insert ## in front of selected lines
-        Uncomment Region    -- Remove leading # or ## from selected lines
-        Tabify Region       -- Turns *leading* stretches of spaces into tabs.
-                (Note: We recommend using 4 space blocks to indent Python 
code.)
-        Untabify Region     -- Turn *all* tabs into the corrent number of 
spaces
-        Toggle tabs         -- Open a dialog to switch between indenting with
-                               spaces and tabs.
-        New Indent Width... -- Open a dialog to change indent width.  The
-                               accepted default by the Python community is 4
-                               spaces.
-        Format Paragraph    -- Reformat the current blank-line-separated
-                               paragraph. All lines in the paragraph will be
-                               formatted to less than 80 columns.
-        ---
-        Strip trailing whitespace -- Removed any space characters after the end
-                                     of the last non-space character
-
-Run Menu (Editor window only):
-
-        Python Shell -- Open or wake up the Python shell window
-        ---
-        Check Module -- Check the syntax of the module currently open in the
-                        Editor window.  If the module has not been saved IDLE
-                        will prompt the user to save the code.
-        Run Module   -- Restart the shell to clean the environment, then
-                        execute the currently open module. If the module has
-                        not been saved IDLE will prompt the user to save the
-                        code.
-
-Shell Menu (Shell window only):
-
-        View Last Restart -- Scroll the shell window to the last Shell restart
-        Restart Shell     -- Restart the shell to clean the environment
-
-Debug Menu (Shell window only):
-
-        Go to File/Line   -- Look around the insert point for a filename
-                             and line number, open the file, and show the line.
-                             Useful to view the source lines referenced in an
-                             exception traceback.  Available in the context
-                             menu of the Shell window.
-        Debugger (toggle) -- This feature is not complete and considered
-                             experimental. Run commands in the shell under the
-                             debugger.
-        Stack Viewer      -- Show the stack traceback of the last exception
-        Auto-open Stack Viewer (toggle) -- Toggle automatically opening the
-                                           stack viewer on unhandled
-                                           exception
-
-Options Menu (Shell and Editor):
-
-        Configure IDLE -- Open a configuration dialog.  Fonts, indentation,
-                          keybindings, and color themes may be altered.
-                          Startup Preferences may be set, and additional Help
-                          sources can be specified.  On OS X, open the
-                          configuration dialog by selecting Preferences
-                          in the application menu.
-
-        ---
-        Code Context (toggle) -- Open a pane at the top of the edit window
-                                 which shows the block context of the section
-                                 of code which is scrolling off the top or the
-                                 window. This is not present in the Shell
-                                 window only the Editor window.
-
-Window Menu (Shell and Editor):
-
-        Zoom Height -- Toggles the window between normal size (40x80 initial
-        setting) and maximum height.  The initial size is in the Configure
-        IDLE dialog under the general tab.
-        ---
-        The rest of this menu lists the names of all open windows;
-        select one to bring it to the foreground (deiconifying it if
-        necessary).
-
-Help Menu:
-
-        About IDLE  -- Version, copyright, license, credits
-        ---
-        IDLE Help   -- Display this file which is a help file for IDLE
-                       detailing the menu options, basic editing and 
navigation,
-                       and other tips.
-        Python Docs -- Access local Python documentation, if
-                       installed.  Or will start a web browser and open
-                       docs.python.org showing the latest Python documentation.
-        ---
-        Additional help sources may be added here with the Configure IDLE
-        dialog under the General tab.
-
-Editor context menu (Right-click / Control-click on OS X in Edit window):
-
-        Cut              -- Copy a selection into system-wide clipboard,
-                            then delete the selection
-        Copy             -- Copy selection into system-wide clipboard
-        Paste            -- Insert system-wide clipboard into window
-        Set Breakpoint   -- Sets a breakpoint. Breakpoints are only enabled
-                            when the debugger is open.
-        Clear Breakpoint -- Clears the breakpoint on that line
-
-Shell context menu (Right-click / Control-click on OS X in Shell window):
-
-        Cut              -- Copy a selection into system-wide clipboard,
-                            then delete the selection
-        Copy             -- Copy selection into system-wide clipboard
-        Paste            -- Insert system-wide clipboard into window
-        ---
-        Go to file/line  -- Same as in Debug menu
-
-
-** TIPS **
-==========
-
-Additional Help Sources:
-
-        Windows users can Google on zopeshelf.chm to access Zope help files in
-        the Windows help format.  The Additional Help Sources feature of the
-        configuration GUI supports .chm, along with any other filetypes
-        supported by your browser.  Supply a Menu Item title, and enter the
-        location in the Help File Path slot of the New Help Source dialog.  Use
-        http:// and/or www. to identify external URLs, or download the file and
-        browse for its path on your machine using the Browse button.
-
-        All users can access the extensive sources of help, including
-        tutorials, available at docs.python.org.  Selected URLs can be added
-        or removed from the Help menu at any time using Configure IDLE.
-
-Basic editing and navigation:
-
-        Backspace deletes char to the left; DEL deletes char to the right.
-        Control-backspace deletes word left, Control-DEL deletes word right.
-        Arrow keys and Page Up/Down move around.
-        Control-left/right Arrow moves by words in a strange but useful way.
-        Home/End go to begin/end of line.
-        Control-Home/End go to begin/end of file.
-        Some useful Emacs bindings are inherited from Tcl/Tk:
-                Control-a     beginning of line
-                Control-e     end of line
-                Control-k     kill line (but doesn't put it in clipboard)
-                Control-l     center window around the insertion point
-        Standard keybindings (like Control-c to copy and Control-v to
-        paste) may work.  Keybindings are selected in the Configure IDLE
-        dialog.
-
-Automatic indentation:
-
-        After a block-opening statement, the next line is indented by 4 spaces
-        (in the Python Shell window by one tab).  After certain keywords
-        (break, return etc.) the next line is dedented.  In leading
-        indentation, Backspace deletes up to 4 spaces if they are there.  Tab
-        inserts spaces (in the Python Shell window one tab), number depends on
-        Indent Width. Currently tabs are restricted to four spaces due
-        to Tcl/Tk limitations.
-
-        See also the indent/dedent region commands in the edit menu.
-
-Completions:
-
-        Completions are supplied for functions, classes, and attributes of
-        classes, both built-in and user-defined.  Completions are also provided
-        for filenames.
-
-        The AutoCompleteWindow (ACW) will open after a predefined delay
-        (default is two seconds) after a '.' or (in a string) an os.sep is
-        typed.  If after one of those characters (plus zero or more other
-        characters) a tab is typed the ACW will open immediately if a possible
-        continuation is found.
-
-        If there is only one possible completion for the characters entered, a
-        tab will supply that completion without opening the ACW.
-
-        'Show Completions' will force open a completions window, by default the
-        Control-space keys will open a completions window.  In an empty
-        string, this will contain the files in the current directory.  On a
-        blank line, it will contain the built-in and user-defined functions and
-        classes in the current name spaces, plus any modules imported.  If some
-        characters have been entered, the ACW will attempt to be more specific.
-
-        If string of characters is typed, the ACW selection will jump to the
-        entry most closely matching those characters. Entering a tab will cause
-        the longest non-ambiguous match to be entered in the Edit window or
-        Shell.  Two tabs in a row will supply the current ACW selection, as
-        will return or a double click.  Cursor keys, Page Up/Down, mouse
-        selection, and the scroll wheel all operate on the ACW.
-
-        "Hidden" attributes can be accessed by typing the beginning of hidden
-        name after a '.',  e.g. '_'.  This allows access to modules with
-        '__all__' set, or to class-private attributes.
-
-        Completions and the 'Expand Word' facility can save a lot of typing!
-
-        Completions are currently limited to those in the namespaces.  Names in
-        an Editor window which are not via __main__ or sys.modules will not be
-        found.  Run the module once with your imports to correct this
-        situation.  Note that IDLE itself places quite a few modules in
-        sys.modules, so much can be found by default, e.g. the re module.
-
-        If you don't like the ACW popping up unbidden, simply make the delay
-        longer or disable the extension.  Or another option is the delay could
-        be set to zero. Another alternative to preventing ACW popups is to
-        disable the call tips extension.
-
-Python Shell window:
-
-        Control-c interrupts executing command.
-        Control-d sends end-of-file; closes window if typed at >>> prompt.
-        Alt-/ expand word is also useful to reduce typing.
-
-    Command history:
-
-        Alt-p retrieves previous command matching what you have typed. On OS X
-        use Control-p.
-        Alt-n retrieves next. On OS X use Control-n.
-        Return while cursor is on a previous command retrieves that command.
-
-    Syntax colors:
-
-        The coloring is applied in a background "thread", so you may
-        occasionally see uncolorized text.  To change the color
-        scheme, use the Configure IDLE / Highlighting dialog.
-
-    Python default syntax colors:
-
-        Keywords        orange
-        Builtins        royal purple
-        Strings         green
-        Comments        red
-        Definitions     blue
-
-    Shell default colors:
-
-        Console output  brown
-        stdout          blue
-        stderr          red
-        stdin           black
-
-Other preferences:
-
-        The font preferences, highlighting, keys, and general preferences can
-        be changed via the Configure IDLE menu option.  Be sure to note that
-        keys can be user defined, IDLE ships with four built in key sets. In
-        addition a user can create a custom key set in the Configure IDLE
-        dialog under the keys tab.
-
-Command line usage:
-
-        Enter idle -h at the command prompt to get a usage message.
-
-        idle.py [-c command] [-d] [-e] [-s] [-t title] [arg] ...
-
-        -c command  run this command
-        -d          enable debugger
-        -e          edit mode; arguments are files to be edited
-        -s          run $IDLESTARTUP or $PYTHONSTARTUP first
-        -t title    set title of shell window
-
-        If there are arguments:
-        1. If -e is used, arguments are files opened for editing and sys.argv
-           reflects the arguments passed to IDLE itself.
-        2. Otherwise, if -c is used, all arguments are placed in
-           sys.argv[1:...], with sys.argv[0] set to -c.
-        3. Otherwise, if neither -e nor -c is used, the first argument is a
-           script which is executed with the remaining arguments in
-           sys.argv[1:...]  and sys.argv[0] set to the script name.  If the
-           script name is -, no script is executed but an interactive Python
-           session is started; the arguments are still available in sys.argv.
-
-Running without a subprocess: (DEPRECATED in Python 3.4 see Issue 16123)
-
-        If IDLE is started with the -n command line switch it will run in a
-        single process and will not create the subprocess which runs the RPC
-        Python execution server.  This can be useful if Python cannot create
-        the subprocess or the RPC socket interface on your platform.  However,
-        in this mode user code is not isolated from IDLE itself.  Also, the
-        environment is not restarted when Run/Run Module (F5) is selected.  If
-        your code has been modified, you must reload() the affected modules and
-        re-import any specific items (e.g. from foo import baz) if the changes
-        are to take effect.  For these reasons, it is preferable to run IDLE
-        with the default subprocess if at all possible.
-
-Extensions:
-
-        IDLE contains an extension facility.  See the beginning of
-        config-extensions.def in the idlelib directory for further information.
-        The default extensions are currently:
-
-                FormatParagraph
-                AutoExpand
-                ZoomHeight
-                ScriptBinding
-                CallTips
-                ParenMatch
-                AutoComplete
-                CodeContext
diff --git a/lib-python/3/idlelib/idle_test/test_config_help.py 
b/lib-python/3/idlelib/idle_test/test_config_help.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_config_help.py
+++ /dev/null
@@ -1,106 +0,0 @@
-"""Unittests for idlelib.configHelpSourceEdit"""
-import unittest
-from idlelib.idle_test.mock_tk import Var, Mbox, Entry
-from idlelib import configHelpSourceEdit as help_dialog_module
-
-help_dialog = help_dialog_module.GetHelpSourceDialog
-
-
-class Dummy_help_dialog:
-    # Mock for testing the following methods of help_dialog
-    menu_ok = help_dialog.menu_ok
-    path_ok = help_dialog.path_ok
-    ok = help_dialog.ok
-    cancel = help_dialog.cancel
-    # Attributes, constant or variable, needed for tests
-    menu = Var()
-    entryMenu = Entry()
-    path = Var()
-    entryPath = Entry()
-    result = None
-    destroyed = False
-
-    def destroy(self):
-        self.destroyed = True
-
-
-# menu_ok and path_ok call Mbox.showerror if menu and path are not ok.
-orig_mbox = help_dialog_module.tkMessageBox
-showerror = Mbox.showerror
-
-
-class ConfigHelpTest(unittest.TestCase):
-    dialog = Dummy_help_dialog()
-
-    @classmethod
-    def setUpClass(cls):
-        help_dialog_module.tkMessageBox = Mbox
-
-    @classmethod
-    def tearDownClass(cls):
-        help_dialog_module.tkMessageBox = orig_mbox
-
-    def test_blank_menu(self):
-        self.dialog.menu.set('')
-        self.assertFalse(self.dialog.menu_ok())
-        self.assertEqual(showerror.title, 'Menu Item Error')
-        self.assertIn('No', showerror.message)
-
-    def test_long_menu(self):
-        self.dialog.menu.set('hello' * 10)
-        self.assertFalse(self.dialog.menu_ok())
-        self.assertEqual(showerror.title, 'Menu Item Error')
-        self.assertIn('long', showerror.message)
-
-    def test_good_menu(self):
-        self.dialog.menu.set('help')
-        showerror.title = 'No Error'  # should not be called
-        self.assertTrue(self.dialog.menu_ok())
-        self.assertEqual(showerror.title, 'No Error')
-
-    def test_blank_path(self):
-        self.dialog.path.set('')
-        self.assertFalse(self.dialog.path_ok())
-        self.assertEqual(showerror.title, 'File Path Error')
-        self.assertIn('No', showerror.message)
-
-    def test_invalid_file_path(self):
-        self.dialog.path.set('foobar' * 100)
-        self.assertFalse(self.dialog.path_ok())
-        self.assertEqual(showerror.title, 'File Path Error')
-        self.assertIn('not exist', showerror.message)
-
-    def test_invalid_url_path(self):
-        self.dialog.path.set('ww.foobar.com')
-        self.assertFalse(self.dialog.path_ok())
-        self.assertEqual(showerror.title, 'File Path Error')
-        self.assertIn('not exist', showerror.message)
-
-        self.dialog.path.set('htt.foobar.com')
-        self.assertFalse(self.dialog.path_ok())
-        self.assertEqual(showerror.title, 'File Path Error')
-        self.assertIn('not exist', showerror.message)
-
-    def test_good_path(self):
-        self.dialog.path.set('https://docs.python.org')
-        showerror.title = 'No Error'  # should not be called
-        self.assertTrue(self.dialog.path_ok())
-        self.assertEqual(showerror.title, 'No Error')
-
-    def test_ok(self):
-        self.dialog.destroyed = False
-        self.dialog.menu.set('help')
-        self.dialog.path.set('https://docs.python.org')
-        self.dialog.ok()
-        self.assertEqual(self.dialog.result, ('help',
-                                              'https://docs.python.org'))
-        self.assertTrue(self.dialog.destroyed)
-
-    def test_cancel(self):
-        self.dialog.destroyed = False
-        self.dialog.cancel()
-        self.assertEqual(self.dialog.result, None)
-        self.assertTrue(self.dialog.destroyed)
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=False)
diff --git a/lib-python/3/idlelib/idle_test/test_config_name.py 
b/lib-python/3/idlelib/idle_test/test_config_name.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_config_name.py
+++ /dev/null
@@ -1,75 +0,0 @@
-"""Unit tests for idlelib.configSectionNameDialog"""
-import unittest
-from idlelib.idle_test.mock_tk import Var, Mbox
-from idlelib import configSectionNameDialog as name_dialog_module
-
-name_dialog = name_dialog_module.GetCfgSectionNameDialog
-
-class Dummy_name_dialog:
-    # Mock for testing the following methods of name_dialog
-    name_ok = name_dialog.name_ok
-    Ok = name_dialog.Ok
-    Cancel = name_dialog.Cancel
-    # Attributes, constant or variable, needed for tests
-    used_names = ['used']
-    name = Var()
-    result = None
-    destroyed = False
-    def destroy(self):
-        self.destroyed = True
-
-# name_ok calls Mbox.showerror if name is not ok
-orig_mbox = name_dialog_module.tkMessageBox
-showerror = Mbox.showerror
-
-class ConfigNameTest(unittest.TestCase):
-    dialog = Dummy_name_dialog()
-
-    @classmethod
-    def setUpClass(cls):
-        name_dialog_module.tkMessageBox = Mbox
-
-    @classmethod
-    def tearDownClass(cls):
-        name_dialog_module.tkMessageBox = orig_mbox
-
-    def test_blank_name(self):
-        self.dialog.name.set(' ')
-        self.assertEqual(self.dialog.name_ok(), '')
-        self.assertEqual(showerror.title, 'Name Error')
-        self.assertIn('No', showerror.message)
-
-    def test_used_name(self):
-        self.dialog.name.set('used')
-        self.assertEqual(self.dialog.name_ok(), '')
-        self.assertEqual(showerror.title, 'Name Error')
-        self.assertIn('use', showerror.message)
-
-    def test_long_name(self):
-        self.dialog.name.set('good'*8)
-        self.assertEqual(self.dialog.name_ok(), '')
-        self.assertEqual(showerror.title, 'Name Error')
-        self.assertIn('too long', showerror.message)
-
-    def test_good_name(self):
-        self.dialog.name.set('  good ')
-        showerror.title = 'No Error'  # should not be called
-        self.assertEqual(self.dialog.name_ok(), 'good')
-        self.assertEqual(showerror.title, 'No Error')
-
-    def test_ok(self):
-        self.dialog.destroyed = False
-        self.dialog.name.set('good')
-        self.dialog.Ok()
-        self.assertEqual(self.dialog.result, 'good')
-        self.assertTrue(self.dialog.destroyed)
-
-    def test_cancel(self):
-        self.dialog.destroyed = False
-        self.dialog.Cancel()
-        self.assertEqual(self.dialog.result, '')
-        self.assertTrue(self.dialog.destroyed)
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=False)
diff --git a/lib-python/3/idlelib/idle_test/test_editmenu.py 
b/lib-python/3/idlelib/idle_test/test_editmenu.py
--- a/lib-python/3/idlelib/idle_test/test_editmenu.py
+++ b/lib-python/3/idlelib/idle_test/test_editmenu.py
@@ -17,7 +17,6 @@
     @classmethod
     def setUpClass(cls):
         cls.root = root = tk.Tk()
-        root.withdraw()
         cls.root.withdraw()
         pyshell.fix_x11_paste(root)
         cls.text = tk.Text(root)
diff --git a/lib-python/3/idlelib/idle_test/test_formatparagraph.py 
b/lib-python/3/idlelib/idle_test/test_formatparagraph.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_formatparagraph.py
+++ /dev/null
@@ -1,376 +0,0 @@
-# Test the functions and main class method of FormatParagraph.py
-import unittest
-from idlelib import FormatParagraph as fp
-from idlelib.EditorWindow import EditorWindow
-from tkinter import Tk, Text
-from test.support import requires
-
-
-class Is_Get_Test(unittest.TestCase):
-    """Test the is_ and get_ functions"""
-    test_comment = '# This is a comment'
-    test_nocomment = 'This is not a comment'
-    trailingws_comment = '# This is a comment   '
-    leadingws_comment = '    # This is a comment'
-    leadingws_nocomment = '    This is not a comment'
-
-    def test_is_all_white(self):
-        self.assertTrue(fp.is_all_white(''))
-        self.assertTrue(fp.is_all_white('\t\n\r\f\v'))
-        self.assertFalse(fp.is_all_white(self.test_comment))
-
-    def test_get_indent(self):
-        Equal = self.assertEqual
-        Equal(fp.get_indent(self.test_comment), '')
-        Equal(fp.get_indent(self.trailingws_comment), '')
-        Equal(fp.get_indent(self.leadingws_comment), '    ')
-        Equal(fp.get_indent(self.leadingws_nocomment), '    ')
-
-    def test_get_comment_header(self):
-        Equal = self.assertEqual
-        # Test comment strings
-        Equal(fp.get_comment_header(self.test_comment), '#')
-        Equal(fp.get_comment_header(self.trailingws_comment), '#')
-        Equal(fp.get_comment_header(self.leadingws_comment), '    #')
-        # Test non-comment strings
-        Equal(fp.get_comment_header(self.leadingws_nocomment), '    ')
-        Equal(fp.get_comment_header(self.test_nocomment), '')
-
-
-class FindTest(unittest.TestCase):
-    """Test the find_paragraph function in FormatParagraph.
-
-    Using the runcase() function, find_paragraph() is called with 'mark' set at
-    multiple indexes before and inside the test paragraph.
-
-    It appears that code with the same indentation as a quoted string is 
grouped
-    as part of the same paragraph, which is probably incorrect behavior.
-    """
-
-    @classmethod
-    def setUpClass(cls):
-        from idlelib.idle_test.mock_tk import Text
-        cls.text = Text()
-
-    def runcase(self, inserttext, stopline, expected):
-        # Check that find_paragraph returns the expected paragraph when
-        # the mark index is set to beginning, middle, end of each line
-        # up to but not including the stop line
-        text = self.text
-        text.insert('1.0', inserttext)
-        for line in range(1, stopline):
-            linelength = int(text.index("%d.end" % line).split('.')[1])
-            for col in (0, linelength//2, linelength):
-                tempindex = "%d.%d" % (line, col)
-                self.assertEqual(fp.find_paragraph(text, tempindex), expected)
-        text.delete('1.0', 'end')
-
-    def test_find_comment(self):
-        comment = (
-            "# Comment block with no blank lines before\n"
-            "# Comment line\n"
-            "\n")
-        self.runcase(comment, 3, ('1.0', '3.0', '#', comment[0:58]))
-
-        comment = (
-            "\n"
-            "# Comment block with whitespace line before and after\n"
-            "# Comment line\n"
-            "\n")
-        self.runcase(comment, 4, ('2.0', '4.0', '#', comment[1:70]))
-
-        comment = (
-            "\n"
-            "    # Indented comment block with whitespace before and after\n"
-            "    # Comment line\n"
-            "\n")
-        self.runcase(comment, 4, ('2.0', '4.0', '    #', comment[1:82]))
-
-        comment = (
-            "\n"
-            "# Single line comment\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:23]))
-
-        comment = (
-            "\n"
-            "    # Single line comment with leading whitespace\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:51]))
-
-        comment = (
-            "\n"
-            "# Comment immediately followed by code\n"
-            "x = 42\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:40]))
-
-        comment = (
-            "\n"
-            "    # Indented comment immediately followed by code\n"
-            "x = 42\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:53]))
-
-        comment = (
-            "\n"
-            "# Comment immediately followed by indented code\n"
-            "    x = 42\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:49]))
-
-    def test_find_paragraph(self):
-        teststring = (
-            '"""String with no blank lines before\n'
-            'String line\n'
-            '"""\n'
-            '\n')
-        self.runcase(teststring, 4, ('1.0', '4.0', '', teststring[0:53]))
-
-        teststring = (
-            "\n"
-            '"""String with whitespace line before and after\n'
-            'String line.\n'
-            '"""\n'
-            '\n')
-        self.runcase(teststring, 5, ('2.0', '5.0', '', teststring[1:66]))
-
-        teststring = (
-            '\n'
-            '    """Indented string with whitespace before and after\n'
-            '    Comment string.\n'
-            '    """\n'
-            '\n')
-        self.runcase(teststring, 5, ('2.0', '5.0', '    ', teststring[1:85]))
-
-        teststring = (
-            '\n'
-            '"""Single line string."""\n'
-            '\n')
-        self.runcase(teststring, 3, ('2.0', '3.0', '', teststring[1:27]))
-
-        teststring = (
-            '\n'
-            '    """Single line string with leading whitespace."""\n'
-            '\n')
-        self.runcase(teststring, 3, ('2.0', '3.0', '    ', teststring[1:55]))
-
-
-class ReformatFunctionTest(unittest.TestCase):
-    """Test the reformat_paragraph function without the editor window."""
-
-    def test_reformat_paragraph(self):
-        Equal = self.assertEqual
-        reform = fp.reformat_paragraph
-        hw = "O hello world"
-        Equal(reform(' ', 1), ' ')
-        Equal(reform("Hello    world", 20), "Hello  world")
-
-        # Test without leading newline
-        Equal(reform(hw, 1), "O\nhello\nworld")
-        Equal(reform(hw, 6), "O\nhello\nworld")
-        Equal(reform(hw, 7), "O hello\nworld")
-        Equal(reform(hw, 12), "O hello\nworld")
-        Equal(reform(hw, 13), "O hello world")
-
-        # Test with leading newline
-        hw = "\nO hello world"
-        Equal(reform(hw, 1), "\nO\nhello\nworld")
-        Equal(reform(hw, 6), "\nO\nhello\nworld")
-        Equal(reform(hw, 7), "\nO hello\nworld")
-        Equal(reform(hw, 12), "\nO hello\nworld")
-        Equal(reform(hw, 13), "\nO hello world")
-
-
-class ReformatCommentTest(unittest.TestCase):
-    """Test the reformat_comment function without the editor window."""
-
-    def test_reformat_comment(self):
-        Equal = self.assertEqual
-
-        # reformat_comment formats to a minimum of 20 characters
-        test_string = (
-            "    \"\"\"this is a test of a reformat for a triple quoted string"
-            " will it reformat to less than 70 characters for me?\"\"\"")
-        result = fp.reformat_comment(test_string, 70, "    ")
-        expected = (
-            "    \"\"\"this is a test of a reformat for a triple quoted string 
will it\n"
-            "    reformat to less than 70 characters for me?\"\"\"")
-        Equal(result, expected)
-
-        test_comment = (
-            "# this is a test of a reformat for a triple quoted string will "
-            "it reformat to less than 70 characters for me?")
-        result = fp.reformat_comment(test_comment, 70, "#")
-        expected = (
-            "# this is a test of a reformat for a triple quoted string will 
it\n"
-            "# reformat to less than 70 characters for me?")
-        Equal(result, expected)
-
-
-class FormatClassTest(unittest.TestCase):
-    def test_init_close(self):
-        instance = fp.FormatParagraph('editor')
-        self.assertEqual(instance.editwin, 'editor')
-        instance.close()
-        self.assertEqual(instance.editwin, None)
-
-
-# For testing format_paragraph_event, Initialize FormatParagraph with
-# a mock Editor with .text and  .get_selection_indices.  The text must
-# be a Text wrapper that adds two methods
-
-# A real EditorWindow creates unneeded, time-consuming baggage and
-# sometimes emits shutdown warnings like this:
-# "warning: callback failed in WindowList <class '_tkinter.TclError'>
-# : invalid command name ".55131368.windows".
-# Calling EditorWindow._close in tearDownClass prevents this but causes
-# other problems (windows left open).
-
-class TextWrapper:
-    def __init__(self, master):
-        self.text = Text(master=master)
-    def __getattr__(self, name):
-        return getattr(self.text, name)
-    def undo_block_start(self): pass
-    def undo_block_stop(self): pass
-
-class Editor:
-    def __init__(self, root):
-        self.text = TextWrapper(root)
-    get_selection_indices = EditorWindow. get_selection_indices
-
-class FormatEventTest(unittest.TestCase):
-    """Test the formatting of text inside a Text widget.
-
-    This is done with FormatParagraph.format.paragraph_event,
-    which calls functions in the module as appropriate.
-    """
-    test_string = (
-        "    '''this is a test of a reformat for a triple "
-        "quoted string will it reformat to less than 70 "
-        "characters for me?'''\n")
-    multiline_test_string = (
-        "    '''The first line is under the max width.\n"
-        "    The second line's length is way over the max width. It goes "
-        "on and on until it is over 100 characters long.\n"
-        "    Same thing with the third line. It is also way over the max "
-        "width, but FormatParagraph will fix it.\n"
-        "    '''\n")
-    multiline_test_comment = (
-        "# The first line is under the max width.\n"
-        "# The second line's length is way over the max width. It goes on "
-        "and on until it is over 100 characters long.\n"
-        "# Same thing with the third line. It is also way over the max "
-        "width, but FormatParagraph will fix it.\n"
-        "# The fourth line is short like the first line.")
-
-    @classmethod
-    def setUpClass(cls):
-        requires('gui')
-        cls.root = Tk()
-        editor = Editor(root=cls.root)
-        cls.text = editor.text.text  # Test code does not need the wrapper.
-        cls.formatter = fp.FormatParagraph(editor).format_paragraph_event
-        # Sets the insert mark just after the re-wrapped and inserted  text.
-
-    @classmethod
-    def tearDownClass(cls):
-        del cls.text, cls.formatter
-        cls.root.destroy()
-        del cls.root
-
-    def test_short_line(self):
-        self.text.insert('1.0', "Short line\n")
-        self.formatter("Dummy")
-        self.assertEqual(self.text.get('1.0', 'insert'), "Short line\n" )
-        self.text.delete('1.0', 'end')
-
-    def test_long_line(self):
-        text = self.text
-
-        # Set cursor ('insert' mark) to '1.0', within text.
-        text.insert('1.0', self.test_string)
-        text.mark_set('insert', '1.0')
-        self.formatter('ParameterDoesNothing', limit=70)
-        result = text.get('1.0', 'insert')
-        # find function includes \n
-        expected = (
-"    '''this is a test of a reformat for a triple quoted string will it\n"
-"    reformat to less than 70 characters for me?'''\n")  # yes
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-        # Select from 1.11 to line end.
-        text.insert('1.0', self.test_string)
-        text.tag_add('sel', '1.11', '1.end')
-        self.formatter('ParameterDoesNothing', limit=70)
-        result = text.get('1.0', 'insert')
-        # selection excludes \n
-        expected = (
-"    '''this is a test of a reformat for a triple quoted string will it 
reformat\n"
-" to less than 70 characters for me?'''")  # no
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-    def test_multiple_lines(self):
-        text = self.text
-        #  Select 2 long lines.
-        text.insert('1.0', self.multiline_test_string)
-        text.tag_add('sel', '2.0', '4.0')
-        self.formatter('ParameterDoesNothing', limit=70)
-        result = text.get('2.0', 'insert')
-        expected = (
-"    The second line's length is way over the max width. It goes on and\n"
-"    on until it is over 100 characters long. Same thing with the third\n"
-"    line. It is also way over the max width, but FormatParagraph will\n"
-"    fix it.\n")
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-    def test_comment_block(self):
-        text = self.text
-
-        # Set cursor ('insert') to '1.0', within block.
-        text.insert('1.0', self.multiline_test_comment)
-        self.formatter('ParameterDoesNothing', limit=70)
-        result = text.get('1.0', 'insert')
-        expected = (
-"# The first line is under the max width. The second line's length is\n"
-"# way over the max width. It goes on and on until it is over 100\n"
-"# characters long. Same thing with the third line. It is also way over\n"
-"# the max width, but FormatParagraph will fix it. The fourth line is\n"
-"# short like the first line.\n")
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-        # Select line 2, verify line 1 unaffected.
-        text.insert('1.0', self.multiline_test_comment)
-        text.tag_add('sel', '2.0', '3.0')
-        self.formatter('ParameterDoesNothing', limit=70)
-        result = text.get('1.0', 'insert')
-        expected = (
-"# The first line is under the max width.\n"
-"# The second line's length is way over the max width. It goes on and\n"
-"# on until it is over 100 characters long.\n")
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-# The following block worked with EditorWindow but fails with the mock.
-# Lines 2 and 3 get pasted together even though the previous block left
-# the previous line alone. More investigation is needed.
-##        # Select lines 3 and 4
-##        text.insert('1.0', self.multiline_test_comment)
-##        text.tag_add('sel', '3.0', '5.0')
-##        self.formatter('ParameterDoesNothing')
-##        result = text.get('3.0', 'insert')
-##        expected = (
-##"# Same thing with the third line. It is also way over the max width,\n"
-##"# but FormatParagraph will fix it. The fourth line is short like the\n"
-##"# first line.\n")
-##        self.assertEqual(result, expected)
-##        text.delete('1.0', 'end')
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=2)
diff --git a/lib-python/3/idlelib/idle_test/test_idlehistory.py 
b/lib-python/3/idlelib/idle_test/test_idlehistory.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_idlehistory.py
+++ /dev/null
@@ -1,168 +0,0 @@
-import unittest
-from test.support import requires
-
-import tkinter as tk
-from tkinter import Text as tkText
-from idlelib.idle_test.mock_tk import Text as mkText
-from idlelib.IdleHistory import History
-from idlelib.configHandler import idleConf
-
-line1 = 'a = 7'
-line2 = 'b = a'
-
-class StoreTest(unittest.TestCase):
-    '''Tests History.__init__ and History.store with mock Text'''
-
-    @classmethod
-    def setUpClass(cls):
-        cls.text = mkText()
-        cls.history = History(cls.text)
-
-    def tearDown(self):
-        self.text.delete('1.0', 'end')
-        self.history.history = []
-
-    def test_init(self):
-        self.assertIs(self.history.text, self.text)
-        self.assertEqual(self.history.history, [])
-        self.assertIsNone(self.history.prefix)
-        self.assertIsNone(self.history.pointer)
-        self.assertEqual(self.history.cyclic,
-                idleConf.GetOption("main", "History",  "cyclic", 1, "bool"))
-
-    def test_store_short(self):
-        self.history.store('a')
-        self.assertEqual(self.history.history, [])
-        self.history.store('  a  ')
-        self.assertEqual(self.history.history, [])
-
-    def test_store_dup(self):
-        self.history.store(line1)
-        self.assertEqual(self.history.history, [line1])
-        self.history.store(line2)
-        self.assertEqual(self.history.history, [line1, line2])
-        self.history.store(line1)
-        self.assertEqual(self.history.history, [line2, line1])
-
-    def test_store_reset(self):
-        self.history.prefix = line1
-        self.history.pointer = 0
-        self.history.store(line2)
-        self.assertIsNone(self.history.prefix)
-        self.assertIsNone(self.history.pointer)
-
-
-class TextWrapper:
-    def __init__(self, master):
-        self.text = tkText(master=master)
-        self._bell = False
-    def __getattr__(self, name):
-        return getattr(self.text, name)
-    def bell(self):
-        self._bell = True
-
-class FetchTest(unittest.TestCase):
-    '''Test History.fetch with wrapped tk.Text.
-    '''
-    @classmethod
-    def setUpClass(cls):
-        requires('gui')
-        cls.root = tk.Tk()
-        cls.root.withdraw()
-
-    def setUp(self):
-        self.text = text = TextWrapper(self.root)
-        text.insert('1.0', ">>> ")
-        text.mark_set('iomark', '1.4')
-        text.mark_gravity('iomark', 'left')
-        self.history = History(text)
-        self.history.history = [line1, line2]
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.root.destroy()
-        del cls.root
-
-    def fetch_test(self, reverse, line, prefix, index, *, bell=False):
-        # Perform one fetch as invoked by Alt-N or Alt-P
-        # Test the result. The line test is the most important.
-        # The last two are diagnostic of fetch internals.
-        History = self.history
-        History.fetch(reverse)
-
-        Equal = self.assertEqual
-        Equal(self.text.get('iomark', 'end-1c'), line)
-        Equal(self.text._bell, bell)
-        if bell:
-            self.text._bell = False
-        Equal(History.prefix, prefix)
-        Equal(History.pointer, index)
-        Equal(self.text.compare("insert", '==', "end-1c"), 1)
-
-    def test_fetch_prev_cyclic(self):
-        prefix = ''
-        test = self.fetch_test
-        test(True, line2, prefix, 1)
-        test(True, line1, prefix, 0)
-        test(True, prefix, None, None, bell=True)
-
-    def test_fetch_next_cyclic(self):
-        prefix = ''
-        test  = self.fetch_test
-        test(False, line1, prefix, 0)
-        test(False, line2, prefix, 1)
-        test(False, prefix, None, None, bell=True)
-
-    # Prefix 'a' tests skip line2, which starts with 'b'
-    def test_fetch_prev_prefix(self):
-        prefix = 'a'
-        self.text.insert('iomark', prefix)
-        self.fetch_test(True, line1, prefix, 0)
-        self.fetch_test(True, prefix, None, None, bell=True)
-
-    def test_fetch_next_prefix(self):
-        prefix = 'a'
-        self.text.insert('iomark', prefix)
-        self.fetch_test(False, line1, prefix, 0)
-        self.fetch_test(False, prefix, None, None, bell=True)
-
-    def test_fetch_prev_noncyclic(self):
-        prefix = ''
-        self.history.cyclic = False
-        test = self.fetch_test
-        test(True, line2, prefix, 1)
-        test(True, line1, prefix, 0)
-        test(True, line1, prefix, 0, bell=True)
-
-    def test_fetch_next_noncyclic(self):
-        prefix = ''
-        self.history.cyclic = False
-        test  = self.fetch_test
-        test(False, prefix, None, None, bell=True)
-        test(True, line2, prefix, 1)
-        test(False, prefix, None, None, bell=True)
-        test(False, prefix, None, None, bell=True)
-
-    def test_fetch_cursor_move(self):
-        # Move cursor after fetch
-        self.history.fetch(reverse=True)  # initialization
-        self.text.mark_set('insert', 'iomark')
-        self.fetch_test(True, line2, None, None, bell=True)
-
-    def test_fetch_edit(self):
-        # Edit after fetch
-        self.history.fetch(reverse=True)  # initialization
-        self.text.delete('iomark', 'insert', )
-        self.text.insert('iomark', 'a =')
-        self.fetch_test(True, line1, 'a =', 0)  # prefix is reset
-
-    def test_history_prev_next(self):
-        # Minimally test functions bound to events
-        self.history.history_prev('dummy event')
-        self.assertEqual(self.history.pointer, 1)
-        self.history.history_next('dummy event')
-        self.assertEqual(self.history.pointer, None)
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=2)
diff --git a/lib-python/3/idlelib/idle_test/test_io.py 
b/lib-python/3/idlelib/idle_test/test_io.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_io.py
+++ /dev/null
@@ -1,233 +0,0 @@
-import unittest
-import io
-from idlelib.PyShell import PseudoInputFile, PseudoOutputFile
-
-
-class S(str):
-    def __str__(self):
-        return '%s:str' % type(self).__name__
-    def __unicode__(self):
-        return '%s:unicode' % type(self).__name__
-    def __len__(self):
-        return 3
-    def __iter__(self):
-        return iter('abc')
-    def __getitem__(self, *args):
-        return '%s:item' % type(self).__name__
-    def __getslice__(self, *args):
-        return '%s:slice' % type(self).__name__
-
-class MockShell:
-    def __init__(self):
-        self.reset()
-
-    def write(self, *args):
-        self.written.append(args)
-
-    def readline(self):
-        return self.lines.pop()
-
-    def close(self):
-        pass
-
-    def reset(self):
-        self.written = []
-
-    def push(self, lines):
-        self.lines = list(lines)[::-1]
-
-
-class PseudeOutputFilesTest(unittest.TestCase):
-    def test_misc(self):
-        shell = MockShell()
-        f = PseudoOutputFile(shell, 'stdout', 'utf-8')
-        self.assertIsInstance(f, io.TextIOBase)
-        self.assertEqual(f.encoding, 'utf-8')
-        self.assertIsNone(f.errors)
-        self.assertIsNone(f.newlines)
-        self.assertEqual(f.name, '<stdout>')
-        self.assertFalse(f.closed)
-        self.assertTrue(f.isatty())
-        self.assertFalse(f.readable())
-        self.assertTrue(f.writable())
-        self.assertFalse(f.seekable())
-
-    def test_unsupported(self):
-        shell = MockShell()
-        f = PseudoOutputFile(shell, 'stdout', 'utf-8')
-        self.assertRaises(OSError, f.fileno)
-        self.assertRaises(OSError, f.tell)
-        self.assertRaises(OSError, f.seek, 0)
-        self.assertRaises(OSError, f.read, 0)
-        self.assertRaises(OSError, f.readline, 0)
-
-    def test_write(self):
-        shell = MockShell()
-        f = PseudoOutputFile(shell, 'stdout', 'utf-8')
-        f.write('test')
-        self.assertEqual(shell.written, [('test', 'stdout')])
-        shell.reset()
-        f.write('t\xe8st')
-        self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
-        shell.reset()
-
-        f.write(S('t\xe8st'))
-        self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
-        self.assertEqual(type(shell.written[0][0]), str)
-        shell.reset()
-
-        self.assertRaises(TypeError, f.write)
-        self.assertEqual(shell.written, [])
-        self.assertRaises(TypeError, f.write, b'test')
-        self.assertRaises(TypeError, f.write, 123)
-        self.assertEqual(shell.written, [])
-        self.assertRaises(TypeError, f.write, 'test', 'spam')
-        self.assertEqual(shell.written, [])
-
-    def test_writelines(self):
-        shell = MockShell()
-        f = PseudoOutputFile(shell, 'stdout', 'utf-8')
-        f.writelines([])
-        self.assertEqual(shell.written, [])
-        shell.reset()
-        f.writelines(['one\n', 'two'])
-        self.assertEqual(shell.written,
-                         [('one\n', 'stdout'), ('two', 'stdout')])
-        shell.reset()
-        f.writelines(['on\xe8\n', 'tw\xf2'])
-        self.assertEqual(shell.written,
-                         [('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')])
-        shell.reset()
-
-        f.writelines([S('t\xe8st')])
-        self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
-        self.assertEqual(type(shell.written[0][0]), str)
-        shell.reset()
-
-        self.assertRaises(TypeError, f.writelines)
-        self.assertEqual(shell.written, [])
-        self.assertRaises(TypeError, f.writelines, 123)
-        self.assertEqual(shell.written, [])
-        self.assertRaises(TypeError, f.writelines, [b'test'])
-        self.assertRaises(TypeError, f.writelines, [123])
-        self.assertEqual(shell.written, [])
-        self.assertRaises(TypeError, f.writelines, [], [])
-        self.assertEqual(shell.written, [])
-
-    def test_close(self):
-        shell = MockShell()
-        f = PseudoOutputFile(shell, 'stdout', 'utf-8')
-        self.assertFalse(f.closed)
-        f.write('test')
-        f.close()
-        self.assertTrue(f.closed)
-        self.assertRaises(ValueError, f.write, 'x')
-        self.assertEqual(shell.written, [('test', 'stdout')])
-        f.close()
-        self.assertRaises(TypeError, f.close, 1)
-
-
-class PseudeInputFilesTest(unittest.TestCase):
-    def test_misc(self):
-        shell = MockShell()
-        f = PseudoInputFile(shell, 'stdin', 'utf-8')
-        self.assertIsInstance(f, io.TextIOBase)
-        self.assertEqual(f.encoding, 'utf-8')
-        self.assertIsNone(f.errors)
-        self.assertIsNone(f.newlines)
-        self.assertEqual(f.name, '<stdin>')
-        self.assertFalse(f.closed)
-        self.assertTrue(f.isatty())
-        self.assertTrue(f.readable())
-        self.assertFalse(f.writable())
-        self.assertFalse(f.seekable())
-
-    def test_unsupported(self):
-        shell = MockShell()
-        f = PseudoInputFile(shell, 'stdin', 'utf-8')
-        self.assertRaises(OSError, f.fileno)
-        self.assertRaises(OSError, f.tell)
-        self.assertRaises(OSError, f.seek, 0)
-        self.assertRaises(OSError, f.write, 'x')
-        self.assertRaises(OSError, f.writelines, ['x'])
-
-    def test_read(self):
-        shell = MockShell()
-        f = PseudoInputFile(shell, 'stdin', 'utf-8')
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.read(), 'one\ntwo\n')
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.read(-1), 'one\ntwo\n')
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.read(None), 'one\ntwo\n')
-        shell.push(['one\n', 'two\n', 'three\n', ''])
-        self.assertEqual(f.read(2), 'on')
-        self.assertEqual(f.read(3), 'e\nt')
-        self.assertEqual(f.read(10), 'wo\nthree\n')
-
-        shell.push(['one\n', 'two\n'])
-        self.assertEqual(f.read(0), '')
-        self.assertRaises(TypeError, f.read, 1.5)
-        self.assertRaises(TypeError, f.read, '1')
-        self.assertRaises(TypeError, f.read, 1, 1)
-
-    def test_readline(self):
-        shell = MockShell()
-        f = PseudoInputFile(shell, 'stdin', 'utf-8')
-        shell.push(['one\n', 'two\n', 'three\n', 'four\n'])
-        self.assertEqual(f.readline(), 'one\n')
-        self.assertEqual(f.readline(-1), 'two\n')
-        self.assertEqual(f.readline(None), 'three\n')
-        shell.push(['one\ntwo\n'])
-        self.assertEqual(f.readline(), 'one\n')
-        self.assertEqual(f.readline(), 'two\n')
-        shell.push(['one', 'two', 'three'])
-        self.assertEqual(f.readline(), 'one')
-        self.assertEqual(f.readline(), 'two')
-        shell.push(['one\n', 'two\n', 'three\n'])
-        self.assertEqual(f.readline(2), 'on')
-        self.assertEqual(f.readline(1), 'e')
-        self.assertEqual(f.readline(1), '\n')
-        self.assertEqual(f.readline(10), 'two\n')
-
-        shell.push(['one\n', 'two\n'])
-        self.assertEqual(f.readline(0), '')
-        self.assertRaises(TypeError, f.readlines, 1.5)
-        self.assertRaises(TypeError, f.readlines, '1')
-        self.assertRaises(TypeError, f.readlines, 1, 1)
-
-    def test_readlines(self):
-        shell = MockShell()
-        f = PseudoInputFile(shell, 'stdin', 'utf-8')
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.readlines(), ['one\n', 'two\n'])
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.readlines(-1), ['one\n', 'two\n'])
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.readlines(None), ['one\n', 'two\n'])
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.readlines(0), ['one\n', 'two\n'])
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.readlines(3), ['one\n'])
-        shell.push(['one\n', 'two\n', ''])
-        self.assertEqual(f.readlines(4), ['one\n', 'two\n'])
-
-        shell.push(['one\n', 'two\n', ''])
-        self.assertRaises(TypeError, f.readlines, 1.5)
-        self.assertRaises(TypeError, f.readlines, '1')
-        self.assertRaises(TypeError, f.readlines, 1, 1)
-
-    def test_close(self):
-        shell = MockShell()
-        f = PseudoInputFile(shell, 'stdin', 'utf-8')
-        shell.push(['one\n', 'two\n', ''])
-        self.assertFalse(f.closed)
-        self.assertEqual(f.readline(), 'one\n')
-        f.close()
-        self.assertFalse(f.closed)
-        self.assertEqual(f.readline(), 'two\n')
-        self.assertRaises(TypeError, f.close, 1)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/lib-python/3/idlelib/idle_test/test_replacedialog.py 
b/lib-python/3/idlelib/idle_test/test_replacedialog.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_replacedialog.py
+++ /dev/null
@@ -1,293 +0,0 @@
-"""Unittest for idlelib.ReplaceDialog"""
-from test.support import requires
-requires('gui')
-
-import unittest
-from unittest.mock import Mock
-from tkinter import Tk, Text
-from idlelib.idle_test.mock_tk import Mbox
-import idlelib.SearchEngine as se
-import idlelib.ReplaceDialog as rd
-
-orig_mbox = se.tkMessageBox
-showerror = Mbox.showerror
-
-
-class ReplaceDialogTest(unittest.TestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.root = Tk()
-        cls.root.withdraw()
-        se.tkMessageBox = Mbox
-        cls.engine = se.SearchEngine(cls.root)
-        cls.dialog = rd.ReplaceDialog(cls.root, cls.engine)
-        cls.dialog.ok = Mock()
-        cls.text = Text(cls.root)
-        cls.text.undo_block_start = Mock()
-        cls.text.undo_block_stop = Mock()
-        cls.dialog.text = cls.text
-
-    @classmethod
-    def tearDownClass(cls):
-        se.tkMessageBox = orig_mbox
-        del cls.text, cls.dialog, cls.engine
-        cls.root.destroy()
-        del cls.root
-
-    def setUp(self):
-        self.text.insert('insert', 'This is a sample sTring')
-
-    def tearDown(self):
-        self.engine.patvar.set('')
-        self.dialog.replvar.set('')
-        self.engine.wordvar.set(False)
-        self.engine.casevar.set(False)
-        self.engine.revar.set(False)
-        self.engine.wrapvar.set(True)
-        self.engine.backvar.set(False)
-        showerror.title = ''
-        showerror.message = ''
-        self.text.delete('1.0', 'end')
-
-    def test_replace_simple(self):
-        # Test replace function with all options at default setting.
-        # Wrap around - True
-        # Regular Expression - False
-        # Match case - False
-        # Match word - False
-        # Direction - Forwards
-        text = self.text
-        equal = self.assertEqual
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace = self.dialog.replace_it
-
-        # test accessor method
-        self.engine.setpat('asdf')
-        equal(self.engine.getpat(), pv.get())
-
-        # text found and replaced
-        pv.set('a')
-        rv.set('asdf')
-        self.dialog.open(self.text)
-        replace()
-        equal(text.get('1.8', '1.12'), 'asdf')
-
-        # dont "match word" case
-        text.mark_set('insert', '1.0')
-        pv.set('is')
-        rv.set('hello')
-        replace()
-        equal(text.get('1.2', '1.7'), 'hello')
-
-        # dont "match case" case
-        pv.set('string')
-        rv.set('world')
-        replace()
-        equal(text.get('1.23', '1.28'), 'world')
-
-        # without "regular expression" case
-        text.mark_set('insert', 'end')
-        text.insert('insert', '\nline42:')
-        before_text = text.get('1.0', 'end')
-        pv.set('[a-z][\d]+')
-        replace()
-        after_text = text.get('1.0', 'end')
-        equal(before_text, after_text)
-
-        # test with wrap around selected and complete a cycle
-        text.mark_set('insert', '1.9')
-        pv.set('i')
-        rv.set('j')
-        replace()
-        equal(text.get('1.8'), 'i')
-        equal(text.get('2.1'), 'j')
-        replace()
-        equal(text.get('2.1'), 'j')
-        equal(text.get('1.8'), 'j')
-        before_text = text.get('1.0', 'end')
-        replace()
-        after_text = text.get('1.0', 'end')
-        equal(before_text, after_text)
-
-        # text not found
-        before_text = text.get('1.0', 'end')
-        pv.set('foobar')
-        replace()
-        after_text = text.get('1.0', 'end')
-        equal(before_text, after_text)
-
-        # test access method
-        self.dialog.find_it(0)
-
-    def test_replace_wrap_around(self):
-        text = self.text
-        equal = self.assertEqual
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace = self.dialog.replace_it
-        self.engine.wrapvar.set(False)
-
-        # replace candidate found both after and before 'insert'
-        text.mark_set('insert', '1.4')
-        pv.set('i')
-        rv.set('j')
-        replace()
-        equal(text.get('1.2'), 'i')
-        equal(text.get('1.5'), 'j')
-        replace()
-        equal(text.get('1.2'), 'i')
-        equal(text.get('1.20'), 'j')
-        replace()
-        equal(text.get('1.2'), 'i')
-
-        # replace candidate found only before 'insert'
-        text.mark_set('insert', '1.8')
-        pv.set('is')
-        before_text = text.get('1.0', 'end')
-        replace()
-        after_text = text.get('1.0', 'end')
-        equal(before_text, after_text)
-
-    def test_replace_whole_word(self):
-        text = self.text
-        equal = self.assertEqual
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace = self.dialog.replace_it
-        self.engine.wordvar.set(True)
-
-        pv.set('is')
-        rv.set('hello')
-        replace()
-        equal(text.get('1.0', '1.4'), 'This')
-        equal(text.get('1.5', '1.10'), 'hello')
-
-    def test_replace_match_case(self):
-        equal = self.assertEqual
-        text = self.text
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace = self.dialog.replace_it
-        self.engine.casevar.set(True)
-
-        before_text = self.text.get('1.0', 'end')
-        pv.set('this')
-        rv.set('that')
-        replace()
-        after_text = self.text.get('1.0', 'end')
-        equal(before_text, after_text)
-
-        pv.set('This')
-        replace()
-        equal(text.get('1.0', '1.4'), 'that')
-
-    def test_replace_regex(self):
-        equal = self.assertEqual
-        text = self.text
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace = self.dialog.replace_it
-        self.engine.revar.set(True)
-
-        before_text = text.get('1.0', 'end')
-        pv.set('[a-z][\d]+')
-        rv.set('hello')
-        replace()
-        after_text = text.get('1.0', 'end')
-        equal(before_text, after_text)
-
-        text.insert('insert', '\nline42')
-        replace()
-        equal(text.get('2.0', '2.8'), 'linhello')
-
-        pv.set('')
-        replace()
-        self.assertIn('error', showerror.title)
-        self.assertIn('Empty', showerror.message)
-
-        pv.set('[\d')
-        replace()
-        self.assertIn('error', showerror.title)
-        self.assertIn('Pattern', showerror.message)
-
-        showerror.title = ''
-        showerror.message = ''
-        pv.set('[a]')
-        rv.set('test\\')
-        replace()
-        self.assertIn('error', showerror.title)
-        self.assertIn('Invalid Replace Expression', showerror.message)
-
-        # test access method
-        self.engine.setcookedpat("\'")
-        equal(pv.get(), "\\'")
-
-    def test_replace_backwards(self):
-        equal = self.assertEqual
-        text = self.text
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace = self.dialog.replace_it
-        self.engine.backvar.set(True)
-
-        text.insert('insert', '\nis as ')
-
-        pv.set('is')
-        rv.set('was')
-        replace()
-        equal(text.get('1.2', '1.4'), 'is')
-        equal(text.get('2.0', '2.3'), 'was')
-        replace()
-        equal(text.get('1.5', '1.8'), 'was')
-        replace()
-        equal(text.get('1.2', '1.5'), 'was')
-
-    def test_replace_all(self):
-        text = self.text
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace_all = self.dialog.replace_all
-
-        text.insert('insert', '\n')
-        text.insert('insert', text.get('1.0', 'end')*100)
-        pv.set('is')
-        rv.set('was')
-        replace_all()
-        self.assertNotIn('is', text.get('1.0', 'end'))
-
-        self.engine.revar.set(True)
-        pv.set('')
-        replace_all()
-        self.assertIn('error', showerror.title)
-        self.assertIn('Empty', showerror.message)
-
-        pv.set('[s][T]')
-        rv.set('\\')
-        replace_all()
-
-        self.engine.revar.set(False)
-        pv.set('text which is not present')
-        rv.set('foobar')
-        replace_all()
-
-    def test_default_command(self):
-        text = self.text
-        pv = self.engine.patvar
-        rv = self.dialog.replvar
-        replace_find = self.dialog.default_command
-        equal = self.assertEqual
-
-        pv.set('This')
-        rv.set('was')
-        replace_find()
-        equal(text.get('sel.first', 'sel.last'), 'was')
-
-        self.engine.revar.set(True)
-        pv.set('')
-        replace_find()
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2)
diff --git a/lib-python/3/idlelib/idle_test/test_searchdialog.py 
b/lib-python/3/idlelib/idle_test/test_searchdialog.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_searchdialog.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""Test SearchDialog class in SearchDialogue.py"""
-
-# Does not currently test the event handler wrappers.
-# A usage test should simulate clicks and check hilighting.
-# Tests need to be coordinated with SearchDialogBase tests
-# to avoid duplication.
-
-from test.support import requires
-requires('gui')
-
-import unittest
-import tkinter as tk
-from tkinter import BooleanVar
-import idlelib.SearchEngine as se
-import idlelib.SearchDialog as sd
-
-
-class SearchDialogTest(unittest.TestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.root = tk.Tk()
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.root.destroy()
-        del cls.root
-
-    def setUp(self):
-        self.engine = se.SearchEngine(self.root)
-        self.dialog = sd.SearchDialog(self.root, self.engine)
-        self.text = tk.Text(self.root)
-        self.text.insert('1.0', 'Hello World!')
-
-    def test_find_again(self):
-        # Search for various expressions
-        text = self.text
-
-        self.engine.setpat('')
-        self.assertFalse(self.dialog.find_again(text))
-
-        self.engine.setpat('Hello')
-        self.assertTrue(self.dialog.find_again(text))
-
-        self.engine.setpat('Goodbye')
-        self.assertFalse(self.dialog.find_again(text))
-
-        self.engine.setpat('World!')
-        self.assertTrue(self.dialog.find_again(text))
-
-        self.engine.setpat('Hello World!')
-        self.assertTrue(self.dialog.find_again(text))
-
-        # Regular expression
-        self.engine.revar = BooleanVar(self.root, True)
-        self.engine.setpat('W[aeiouy]r')
-        self.assertTrue(self.dialog.find_again(text))
-
-    def test_find_selection(self):
-        # Select some text and make sure it's found
-        text = self.text
-        # Add additional line to find
-        self.text.insert('2.0', 'Hello World!')
-
-        text.tag_add('sel', '1.0', '1.4')       # Select 'Hello'
-        self.assertTrue(self.dialog.find_selection(text))
-
-        text.tag_remove('sel', '1.0', 'end')
-        text.tag_add('sel', '1.6', '1.11')      # Select 'World!'
-        self.assertTrue(self.dialog.find_selection(text))
-
-        text.tag_remove('sel', '1.0', 'end')
-        text.tag_add('sel', '1.0', '1.11')      # Select 'Hello World!'
-        self.assertTrue(self.dialog.find_selection(text))
-
-        # Remove additional line
-        text.delete('2.0', 'end')
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=2)
diff --git a/lib-python/3/idlelib/idle_test/test_searchdialogbase.py 
b/lib-python/3/idlelib/idle_test/test_searchdialogbase.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_searchdialogbase.py
+++ /dev/null
@@ -1,165 +0,0 @@
-'''Unittests for idlelib/SearchDialogBase.py
-
-Coverage: 99%. The only thing not covered is inconsequential --
-testing skipping of suite when self.needwrapbutton is false.
-
-'''
-import unittest
-from test.support import requires
-from tkinter import Tk, Toplevel, Frame ##, BooleanVar, StringVar
-from idlelib import SearchEngine as se
-from idlelib import SearchDialogBase as sdb
-from idlelib.idle_test.mock_idle import Func
-## from idlelib.idle_test.mock_tk import Var
-
-# The ## imports above & following could help make some tests gui-free.
-# However, they currently make radiobutton tests fail.
-##def setUpModule():
-##    # Replace tk objects used to initialize se.SearchEngine.
-##    se.BooleanVar = Var
-##    se.StringVar = Var
-##
-##def tearDownModule():
-##    se.BooleanVar = BooleanVar
-##    se.StringVar = StringVar
-
-class SearchDialogBaseTest(unittest.TestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        requires('gui')
-        cls.root = Tk()
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.root.destroy()
-        del cls.root
-
-    def setUp(self):
-        self.engine = se.SearchEngine(self.root)  # None also seems to work
-        self.dialog = sdb.SearchDialogBase(root=self.root, engine=self.engine)
-
-    def tearDown(self):
-        self.dialog.close()
-
-    def test_open_and_close(self):
-        # open calls create_widgets, which needs default_command
-        self.dialog.default_command = None
-
-        # Since text parameter of .open is not used in base class,
-        # pass dummy 'text' instead of tk.Text().
-        self.dialog.open('text')
-        self.assertEqual(self.dialog.top.state(), 'normal')
-        self.dialog.close()
-        self.assertEqual(self.dialog.top.state(), 'withdrawn')
-
-        self.dialog.open('text', searchphrase="hello")
-        self.assertEqual(self.dialog.ent.get(), 'hello')
-        self.dialog.close()
-
-    def test_create_widgets(self):
-        self.dialog.create_entries = Func()
-        self.dialog.create_option_buttons = Func()
-        self.dialog.create_other_buttons = Func()
-        self.dialog.create_command_buttons = Func()
-
-        self.dialog.default_command = None
-        self.dialog.create_widgets()
-
-        self.assertTrue(self.dialog.create_entries.called)
-        self.assertTrue(self.dialog.create_option_buttons.called)
-        self.assertTrue(self.dialog.create_other_buttons.called)
-        self.assertTrue(self.dialog.create_command_buttons.called)
-
-    def test_make_entry(self):
-        equal = self.assertEqual
-        self.dialog.row = 0
-        self.dialog.top = Toplevel(self.root)
-        entry, label = self.dialog.make_entry("Test:", 'hello')
-        equal(label['text'], 'Test:')
-
-        self.assertIn(entry.get(), 'hello')
-        egi = entry.grid_info()
-        equal(int(egi['row']), 0)
-        equal(int(egi['column']), 1)
-        equal(int(egi['rowspan']), 1)
-        equal(int(egi['columnspan']), 1)
-        equal(self.dialog.row, 1)
-
-    def test_create_entries(self):
-        self.dialog.row = 0
-        self.engine.setpat('hello')
-        self.dialog.create_entries()
-        self.assertIn(self.dialog.ent.get(), 'hello')
-
-    def test_make_frame(self):
-        self.dialog.row = 0
-        self.dialog.top = Toplevel(self.root)
-        frame, label = self.dialog.make_frame()
-        self.assertEqual(label, '')
-        self.assertIsInstance(frame, Frame)
-
-        frame, label = self.dialog.make_frame('testlabel')
-        self.assertEqual(label['text'], 'testlabel')
-        self.assertIsInstance(frame, Frame)
-
-    def btn_test_setup(self, meth):
-        self.dialog.top = Toplevel(self.root)
-        self.dialog.row = 0
-        return meth()
-
-    def test_create_option_buttons(self):
-        e = self.engine
-        for state in (0, 1):
-            for var in (e.revar, e.casevar, e.wordvar, e.wrapvar):
-                var.set(state)
-            frame, options = self.btn_test_setup(
-                    self.dialog.create_option_buttons)
-            for spec, button in zip (options, frame.pack_slaves()):
-                var, label = spec
-                self.assertEqual(button['text'], label)
-                self.assertEqual(var.get(), state)
-                if state == 1:
-                    button.deselect()
-                else:
-                    button.select()
-                self.assertEqual(var.get(), 1 - state)
-
-    def test_create_other_buttons(self):
-        for state in (False, True):
-            var = self.engine.backvar
-            var.set(state)
-            frame, others = self.btn_test_setup(
-                self.dialog.create_other_buttons)
-            buttons = frame.pack_slaves()
-            for spec, button in zip(others, buttons):
-                val, label = spec
-                self.assertEqual(button['text'], label)
-                if val == state:
-                    # hit other button, then this one
-                    # indexes depend on button order
-                    self.assertEqual(var.get(), state)
-                    buttons[val].select()
-                    self.assertEqual(var.get(), 1 - state)
-                    buttons[1-val].select()
-                    self.assertEqual(var.get(), state)
-
-    def test_make_button(self):
-        self.dialog.top = Toplevel(self.root)
-        self.dialog.buttonframe = Frame(self.dialog.top)
-        btn = self.dialog.make_button('Test', self.dialog.close)
-        self.assertEqual(btn['text'], 'Test')
-
-    def test_create_command_buttons(self):
-        self.dialog.create_command_buttons()
-        # Look for close button command in buttonframe
-        closebuttoncommand = ''
-        for child in self.dialog.buttonframe.winfo_children():
-            if child['text'] == 'close':
-                closebuttoncommand = child['command']
-        self.assertIn('close', closebuttoncommand)
-
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=2)
diff --git a/lib-python/3/idlelib/idle_test/test_undodelegator.py 
b/lib-python/3/idlelib/idle_test/test_undodelegator.py
deleted file mode 100644
--- a/lib-python/3/idlelib/idle_test/test_undodelegator.py
+++ /dev/null
@@ -1,135 +0,0 @@
-"""Unittest for UndoDelegator in idlelib.UndoDelegator.
-
-Coverage about 80% (retest).
-"""
-from test.support import requires
-requires('gui')
-
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to