Issue 18131: Tkinter Variables require a proper master (original) (raw)
The signature for tkinter class Variable and its subclasses StringVar, IntVar, DoubleVar, BooleanVar is def init(self, master=None, value=None, name=None): However, the None default is invalid because of self._tk = master.tk The preceding lines if not master: master = _default_root might suggest that None is acceptible. But _default_root is set to None at the top of the file, so that just replaces None with None.
If Variables must have a gui widget parent, then they cannot be used in gui-free tests, even though they have no graphic representation.
Moveover, not everything is a proper master. configSectionNameDialog.py . GetCfgSectionNameDialog(Toplevel) . Create.Widgets(self) has these lines: self.name = StringVar(self) self.fontSize = StringVar(self) However, these are not (always) garbage collectable.
After fixing the dialog test at the bottom of the file, and running it with 3.3 python_d -m idlelib.configSectionNameDialog (#18130), and adding the gc flag, I repeatedly got [sys:1: ResourceWarning: gc: 2 uncollectable objects at shutdown [<tkinter.StringVar object at 0x02C597E0>, <tkinter.StringVar ...]] (This only showed when running from the console, not when running within Idle started within the interactive debug interpreter.)
Running the test multiple times within a session, by repeatedly creating new dialogs with the [dialog] button in the test window, multiplied the uncollected objects.
Replacing 'self' with 'self.parent' solved the problem, at least in the test situation.
My first message discussed two different issues. The first, generalized, is that unconditionally using tkinter._default_root, which can be either None or absent, as a backup for master=None in init functions, seems a bit sloppy. Image.init does this check if not master: master = _default_root if not master: raise RuntimeError('Too early to create image') but that will fail if _default_root has been deleted. Also, the message is wrong in that it is not 'too early' if an explicit master is passed. I am thinking that all uses of _default_root should raise something like WhateverError("An explicit master is required when _default_root is None or deleted.") Serhiy, what do you think?
The second issue noted that while widgets often have a container widget as master, the non-graphics classes like Variable and Font should have a Tk and not a widget as master. I have corrected idlelib.configHandler and there is a tkinter patch on another issue (applied yet?) to automatically replace master=widget by master-widget.tk. So Variable calls are no longer part of this issue.
I am thinking that all uses of _default_root should raise something like WhateverError("An explicit master is required when _default_root is None or deleted.") Serhiy, what do you think?
Technically all works (raises some exception), but I agree that error message can be more friendly. But _default_root is implementation detail. This name doesn't mean anything for non-experienced user (and experienced user already knows about these mystical RuntimeError and NameError). The message should say something like "No default root window" if _default_root is None and "The master argument is mandatory after calling NoDefautRoot()" if _default_root isn't set.
And now we came to the way how to create default root window. Issue4343 looks related (I haven't looked at it close however).
Second issue was fixed in .