New submission from Richard Sheridan <richard.sheri...@gmail.com>:

This could also be considered a "behavior" type issue.

`TkappObject` has a member `dispatching` that could usefully be exposed by a 
very simple read-only method for users to determine at runtime if the tkinter 
mainloop is running. Matplotlib and I'm sure other packages rely on fragile 
hacks 
(https://github.com/matplotlib/matplotlib/blob/a68562aa230e5895136120f5073dd01f124d728d/lib/matplotlib/cbook/__init__.py#L65-L71)
 to determine this state. I ran into this in 
https://github.com/matplotlib/matplotlib/pull/17802. All these projects would 
be more reliable with a new "dispatching()" method on the TkappObject, 
tkinter.Misc objects, and possibly the tkinter module itself.

Internally, `dispatching` is used to, yes, determine if the mainloop is 
running. However, this determination is always done within the 
`WaitForMainloop` function 
(https://github.com/python/cpython/blob/bd4a3f21454a6012f4353e2255837561fc9f0e6a/Modules/_tkinter.c#L363-L380),
 which waits up to 1 second for the mainloop to come up. Apparently, this 
function allows a thread to implicitly wait for the loop to come up by calling 
any `TkappObject` method. This is a bad design choice in my opinion, because if 
client code wants to start immediately and the loop is not started by mistake, 
there will be a meaningless, hard-to-diagnose delay of one second before 
crashing. Instead, if some client code in a thread needs to wait for the 
mainloop to run, it should explicitly poll `dispatching()` on its own. This 
waiting behavior should be deprecated and, after a deprecation cycle perhaps, 
all `WaitForMainloop()` statements should be converted to inline 
`self->dispatching`.

The correctness of the `dispatching` flag is dampened by the currently 
existing, undocumented `willdispatch` method which simply arbitrarily sets the 
`dispatching` to 1. It seems `willdispatch` was added 18 years ago to 
circumvent a bug building pydoc caused by `WaitForMainloop` not waiting long 
enough, as it tricks `WaitForMainloop` into... not waiting for the mainloop. 
This was in my opinion a bad choice in comparison to adding a dispatching flag: 
again, if some thread needs to wait for the mainloop, it should poll 
`dispatching()`, and avoid adding spurious 1 second waits. `willdispatch` 
currently has no references in CPython and most GitHub references are to 
Pycharm stubs for the CPython method. It should be deprecated and removed to 
preserve the correctness of `dispatching`.

Happy to make a PR about this, except I don't understand clinic at all, nor the 
specifics of deprecation cycles in CPython.

----------
components: Tkinter
messages: 372722
nosy: Richard Sheridan
priority: normal
severity: normal
status: open
title: revise Tkinter mainloop dispatching flag behavior
type: enhancement
versions: Python 3.10, Python 3.5, Python 3.6, Python 3.7, Python 3.8, Python 
3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41176>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to