-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add after_info as a function to tkinter #77020
Comments
In tkinter, after_cancel has a call to after info: Since this is a supported command, there should be a function to access it directly. |
What is the use case for this method? How it could be used? |
I was working on the tests for bpo-32831. One of the methods was I don't know if there is a general need to know whether timer or idle events exist, but this command gives that information. |
I'm not sure what after_info(id) should return. |
I've made a pull request. I understand that you may not want to add this functionality, but perhaps the docstring will answer your questions. I took it from the Tcl docs page. |
I am in favor of exposing all of tk where it makes sense to do so, and I think it does here. After 'translating' the tk after_info entry into tkinter-ese, I would expect and want that Serhiy, I presume that this is what you were uncertain about. I am presuming above that f can be recovered. Returning the function kind as 'timer' or 'idle' is fine. In other contexts, an enumeration would be a possibility, but this does not seem to fit tkinter. I presume a bad id results in TclError. Do other tkinter functions allow TclError to propagate? My impression is no. If so, it should be replaced here in a way consistent with other tkinter practice. |
On one side, the first item of the list returned by the Tcl command On other side, This is what I was uncertain about. Maybe after_info() should return a Python callable if possible, and keep the original result otherwise? This complicates its implementation and definition. TclError is legal and expected. In some methods it is caught, either because the method is purposed to be called at widget destroying stage, when the order of different cleanup procedures is not specified, and Tcl names can be destroyed before destroying Tkinter wrappers, or because the method was implemented differently in the past, and catching TclError is needed for backward compatibility. after_info() is not the case. |
Note that in the tests for bpo-32831 you need to use call('after', 'info') if you want to backport them. |
I thought In order for it to return the python function name, I think the |
A person who can create a tcl callback with tk.call can inquire with tk.call('after', 'info', id). That does not cover callbacks created by tcl or extensions thereof, but references to such callbacks are unlikely to be useful to anyone who does not know any tcl. I see these choices for after_info(id): A. Return the tcl script reference even when it wraps a python function. I don't like this, as the tcl reference is useless to most people. B. Convert the reference to a Python function if possible but return it if not. This is a bit awkward to document and any use requires a type check. Having a function return such different types, depending on the input, is frowned upon. C. Convert the reference to a function if possibe and raise TypeError or ValueError is not. This is incomplete but easier for a pure Python programmer to deal with. The documentation could specify how those who want a tcl reference can get it. D. Don't implement after_info(id), at least not now, and just after_info(). Information about the current existence of a callback is contained in the list returned by after_info(). Each of the following pairs should be equivalent: assertIn(id, after_info())
assertEqual(len(after_info(id)), 2)
assertNotIn(id, after_info())
assertRaises(TclError, after_info, id) (For testing after_info(), assertIn and assertNotIn avoid assuming that tcl does not add any internal callbacks.) |
Good question. Currently the reference to a callable is kept in the dict until the object is destroyed. This can be considered as a bug (see bpo-1524639). |
I agreed with Cheryl's conclusion that likely after_cancel() had been called with None. The comments about 8.4 is wrong, and the solution in bpo-763637 is not correct. The current code code deletes the script for the first event if pass None to after_cancel(). Do you ming to open a PR for proper solving bpo-763637 Cheryl? |
I created bpo-32857 for the after_cancel issue. Thanks! |
A few questions about returning the Python function name (specifically, how to derive it). This doesn't address the open issue with what to do about a Tcl command not tied to a Python function.
Thanks! |
Real use case for after_info() (with not arg): bpo-33855 is about minimally testing all IDLE modules. At least import the module and create class instances when easily possible. For test_editor, I started with def test_init(self): # Temporary.
e = Editor(root=self.root)
self.assertEqual(e.root, self.root) and got in Shell warning: callback failed in WindowList <class '_tkinter.TclError'> : invalid command name ".!menu.windows" and in the console invalid command name "119640952recolorize" Perhaps this is why I previously omitted something so obvious (it add 24% to coverage). I added e._close(), which tries to cleanup, and the messages, in console only, are reduced to bgerror failed to handle background error. I would like to know what _close misses, but it is hard to track them down. for id in cls.root.tk.call('after', 'info'):
self.root.after_cancel(id) before cls.root.destroy() in shutDownClass stops the messages.For test_del in bpo-32831, I think the following might work, and be much shorter than the current code. n = len(self.root.tk.call('after', 'info')
self.cc.__del__()
self.assertEqual(len(self.root.tk.call('after', 'info')), n-2) |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: