classification
Title: Better repr for tkinter widgets
Type: enhancement Stage: resolved
Components: Tkinter Versions: Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: ezio.melotti, gpolo, python-dev, serhiy.storchaka, terry.reedy
Priority: normal Keywords: patch

Created on 2014-02-15 11:53 by serhiy.storchaka, last changed 2014-04-13 18:03 by serhiy.storchaka. This issue is now closed.

Files
File name Uploaded Description Edit
tkinter_misc_repr.patch serhiy.storchaka, 2014-02-15 11:53 review
Messages (7)
msg211269 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-02-15 11:53
Here is a patch which adds more helpful repr for Tkinter widgets. Was

    <tkinter.Button object at 0xb6aa6964>

Becomes:

    <tkinter.Button object .3070343372.3066782348>

or (if you assigned names to widgets)

    <tkinter.Button object .panel.b1>

This is very helpful for debugging.
msg211879 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-02-21 22:18
I like this. It would make naming widgets more useful. I checked one Idle dialog and nothing is named. I suspect this is typical.

The proposed change would break a doctest that follows the fix in the doctest manual.
---
>>> C()   # the default repr() for instances embeds an address
<__main__.C instance at 0x00AC18F0>

The ELLIPSIS directive gives a nice approach for the last example:
>>>

>>> C() #doctest: +ELLIPSIS
<__main__.C instance at 0x...>
---
I think the recommendation should better be

<__main__.C instance ...>

except that 'instance' is now 'object' -- and *that* change must have broken much more that this one would.
msg211995 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2014-02-23 14:46
> <tkinter.Button object .3070343372.3066782348>

Not knowing the internal of tkinter, this seems somewhat confusing.
Is that an "anonymous name/id"?

> <tkinter.Button object .panel.b1>

This already looks more useful.  How is that determined?  Why the "first" object is missing (i.e. .panel seems to be an attribute of a missing object)?


Regarding the patch, are you sure that .__class__.__module__ is always available?  I seem to remember that it might be missing in some cases, e.g. modules written in C (but I might be confusing it with something else like __file__).
msg212001 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-02-23 15:33
> > <tkinter.Button object .3070343372.3066782348>
> 
> Not knowing the internal of tkinter, this seems somewhat confusing.
> Is that an "anonymous name/id"?

If the name parameter is not specified, repr(id(self)) is used. Here is a 
button with id() == 3066782348, its parent has id() == 3070343372 and its 
grandparent is root. str() for this button returns full name 
".3070343372.3066782348".

> > <tkinter.Button object .panel.b1>
> 
> This already looks more useful.  How is that determined?  Why the "first"
> object is missing (i.e. .panel seems to be an attribute of a missing
> object)?

Tk widgets are organized in hierarchical structure and names look similar to 
file system names. "." is the root, ".frame" is a frame in the root, 
".frame.b1" is a button in frame ".frame".

> Regarding the patch, are you sure that .__class__.__module__ is always
> available?  I seem to remember that it might be missing in some cases, e.g.
> modules written in C (but I might be confusing it with something else like
> __file__).

Yes, for example __module__ is absent in _tkinter.TkappType. But I think that 
every Python implemented class has __module__.
msg214250 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-03-20 17:35
Are there any questions or objections?
msg214284 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-03-20 21:07
After looking more at testing entire (Idle) dialogs and windows for sanity, I like the idea even more. A person can check that everything that is present looks ok, but code is at least as good as using a checklist to verify that what is present is exactly what should be present. For this, widgets should have meaningful and predictable names. Once widgets are given names, they should be used in the representation. The proposed

>>> top.winfo_children()
[<tkinter.Frame object .top.child]

is more helpful than the current

>>> top.winfo_children()
[<tkinter.Frame object at 0x000000000350BCF8>]


As for Ezio's question: The new method is defined in class tkinter.Misc and only applies to instances of subclasses thereof -- BaseWidget, Widget, etc, in tkinter.__init__ and ttk.Widget. I suppose other code might subclass something, but as far as I know, Idle classes 'have a' widget rather than 'being a' widget. But if Misc or a subclass could be sensibly subclassed in C code, you could, to be safe, change "top.__class__.__module__" to "getattr(top.__class__, '__module__', 'module'). I believe 'self._w' is safe as an object without ._w is not a tk widget.
msg215515 - (view) Author: Roundup Robot (python-dev) Date: 2014-04-04 12:46
New changeset 66770f126c71 by Serhiy Storchaka in branch 'default':
Issue #20636: Improved the repr of Tkinter widgets.
http://hg.python.org/cpython/rev/66770f126c71
History
Date User Action Args
2014-04-13 18:03:11serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2014-04-04 12:46:31python-devsetnosy: + python-dev
messages: + msg215515
2014-03-20 21:07:44terry.reedysetmessages: + msg214284
2014-03-20 17:35:36serhiy.storchakasetassignee: serhiy.storchaka
messages: + msg214250
2014-02-23 15:33:12serhiy.storchakasetmessages: + msg212001
2014-02-23 14:46:33ezio.melottisetnosy: + ezio.melotti
messages: + msg211995
2014-02-21 22:18:30terry.reedysetnosy: + terry.reedy
messages: + msg211879
2014-02-15 11:53:01serhiy.storchakacreate