Skip to content

IDLE: Make GUI test teardown less fragile #75465

Open

Description

@csabella
BPO 31284
Nosy @terryjreedy, @csabella
PRs
  • bpo-31284: IDLE: Fix WindowList warning message when running tests #3212
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/terryjreedy'
    closed_at = None
    created_at = <Date 2017-08-26.16:55:38.220>
    labels = ['expert-IDLE', 'type-feature', '3.7']
    title = 'IDLE: Make GUI test teardown less fragile'
    updated_at = <Date 2017-08-27.20:10:56.780>
    user = 'https://github.com/csabella'

    bugs.python.org fields:

    activity = <Date 2017-08-27.20:10:56.780>
    actor = 'terry.reedy'
    assignee = 'terry.reedy'
    closed = False
    closed_date = None
    closer = None
    components = ['IDLE']
    creation = <Date 2017-08-26.16:55:38.220>
    creator = 'cheryl.sabella'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 31284
    keywords = []
    message_count = 6.0
    messages = ['300885', '300908', '300909', '300912', '300919', '300925']
    nosy_count = 2.0
    nosy_names = ['terry.reedy', 'cheryl.sabella']
    pr_nums = ['3212']
    priority = 'normal'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue31284'
    versions = ['Python 3.6', 'Python 3.7']

    Activity

    1. csabella commented on Aug 26, 2017

      @csabella
      ContributorAuthor

      When running tests that use an EditorWindow, the following warning message occurs:

      warning: callback failed in WindowList <class '_tkinter.TclError'> : invalid command name ".!menu.windows"

      This warning comes from call_callbacks in WindowsList in windows.py when the callback is postwindowsmenu() from editor, which is set for the windows menu. The line end = menu.index("end") is the line that fails.

    2. terryjreedy commented on Aug 26, 2017

      @terryjreedy
      Member

      I don't remember ever seeing that message. Do you have code that reliably reproduces the problem?

          def postwindowsmenu(self):
              # Only called when Windows menu exists
              menu = self.menudict['windows']
              end = menu.index("end")
              ...
              windows.add_windows_to_menu(menu)

      ".!menu.windows" is the tk Windows Menu name, generated by tkinter and saved in menudict. The function claims that it is only called when the menu exists, but the error is that it does not exist, even though it is still in the dict. This is a bug. It must result from a bug either in IDLE or the test teardown code, or maybe both. I would rather fix the bug than shoot the messenger ;-)

      Side note: the callback handling strikes me as slightly crazy. Creating a ListedTopLevel calls registry.add, which calls all the callbacks, each of which regenerates the menu.

    3. csabella commented on Aug 26, 2017

      @csabella
      ContributorAuthor

      I saw it on my PR for the tests in outwin (bpo-30617) and I also found a comment from someone else in test_paragraph.py about it.

      I can reproduce it with this code:
      from idlelib import outwin
      from tkinter import Tk, Text
      root = Tk()
      w = outwin.OutputWindow(None, None, None, root)
      w.text = Text(root)
      root.mainloop()

      I agree that it would be best to fix the root of the problem. I thought maybe with the test, it's the way the OutputWindow is created I tried adding an flist, but that still didn't suppress the warning.

    4. terryjreedy commented on Aug 27, 2017

      @terryjreedy
      Member

      As you gave the code, the two windows just sit there with mainloop running. Replace it with
      root.update # likely should add _idletasks()
      #w.close()
      root.destroy()
      and run from IDLE editor and I see the ".!menu.windows" message. Uncomment the close and it goes away.

      Root.destroy recursively calls the .destroy methods of its children. Here, ListedTopLevel.destroy is called. It calls TopLevel.destroy and registry.delete. Its menubar child and its dropdown submenu are also destroyed. But LTL.destroy does *not* call the close method of the EditorWindow instance (which is *not* a widget). Without a reference, it cannot.

      Registry.delete, which is called for each ListedTopLevel *calls all the callbacks*, which it exactly should not do at shutdown. It does not unregister the associated callback. That is part of editor.close.

      In IDLE's normal operation, editor.close must somehow get called. In test setups and teardowns, I am careful to undo things in reverse order of creation. It is, in a sense, a bug, as things now stand, to create an OutputWindow(root) without calling its close method before destroying root.

      In configdialog, the callbacks are the Var tracers. The configdialog test teardown removes them all. Closing editorwindows should do the same. This is not to deny that making shutdown less fragile would be a good thing.

      I think having separate EditorWindow and EditorFrame classes that *are* widgets would help, as then better auxilliary shutdowns could be either part of or called from the destroy methods that get called when root.destroy is called.

      Aside from the ".!menu.windows" message in the idle shell, messages like the following appear in the command window if there is one, with or without the editor.close() call.

      invalid command name "96611576font_timer_event"
      while executing
      "96611576font_timer_event"
      ("after" script)

      "89887864font_timer_event"
      ("after" script)
      invalid command name "89718392timer_event"
      while executing
      Functions timer_event and font_timer_event are CodeContext methods. The messages don't appear if code_context is not enabled. I don't know how the messages are prevented (normally) when CondContext is enabled. The is no obvious graceful shutdown of the loops. They seem to end when self.text no longer exists so that self.text.after must fail. I already knew that this class needs work ;-).

    5. csabella commented on Aug 27, 2017

      @csabella
      ContributorAuthor

      Thank you for taking the time to research and explain that.

      It's funny, but on my code example, I got it to happen every time and you said it didn't happen unless you made the change to use root.update() and root.destroy(). I tried it out again and realized that I was closing the tk window before OutputWindow every time, thus I was getting the warning using root.mainloop(). Of course, if I close OutputWindow first, I don't get the warning. That's running from the command line.

      I suppose this issue needs to be split into the real bugs that you mentioned. It seems to be at least 2 or 3 different things to look at (EditorWindow and EditorFrame and CodeContext). I'll delete the current PR for this issue.

      Thanks!

    6. terryjreedy commented on Aug 27, 2017

      @terryjreedy
      Member

      I closed the patch; you can delete the branch.

      I changed the title to express the goal, though I am not sure how to get there yet. One thing is to be more aware of what callbacks and event loops are being set up and possibly not shut down gracefully.

      Your code as posted did not reproduce the error *without manual action*. Tests, including the one for bpo-30617, has better run without user intervention. Once I made the modification to get the error, or not, just by running it, I was pretty sure of the fix for the test.

    7. changed the title [-]IDLE: Fix WindowList invalid command name error when running tests[/-] [+]IDLE: Make GUI test teardown less fragile[/+] on Aug 27, 2017
    8. transferred this issue fromon Apr 10, 2022
    9. moved this to In Progress in IDLE Issueson Jul 27, 2022
    10. moved this from In Progress to Todo in IDLE Issueson May 22, 2023
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    testsTests in the Lib/test dirtopic-IDLEtype-featureA feature request or enhancement

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions