bpo-15303: Support widgets with boolean value False in Tkinter (GH-23904)

Use `widget is None` instead of checking the boolean value of a widget.
This commit is contained in:
Serhiy Storchaka 2020-12-25 17:04:26 +02:00 committed by GitHub
parent 954a7427ba
commit bb70b2afe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 30 additions and 29 deletions

View File

@ -292,7 +292,7 @@ def _get_default_root(what=None):
if not _support_default_root: if not _support_default_root:
raise RuntimeError("No master specified and tkinter is " raise RuntimeError("No master specified and tkinter is "
"configured to not support default root") "configured to not support default root")
if not _default_root: if _default_root is None:
if what: if what:
raise RuntimeError(f"Too early to {what}: no default root window") raise RuntimeError(f"Too early to {what}: no default root window")
root = Tk() root = Tk()
@ -342,7 +342,7 @@ class Variable:
if name is not None and not isinstance(name, str): if name is not None and not isinstance(name, str):
raise TypeError("name must be a string") raise TypeError("name must be a string")
global _varnum global _varnum
if not master: if master is None:
master = _get_default_root('create variable') master = _get_default_root('create variable')
self._root = master._root() self._root = master._root()
self._tk = master.tk self._tk = master.tk
@ -808,7 +808,7 @@ class Misc:
function which shall be called. Additional parameters function which shall be called. Additional parameters
are given as parameters to the function call. Return are given as parameters to the function call. Return
identifier to cancel scheduling with after_cancel.""" identifier to cancel scheduling with after_cancel."""
if not func: if func is None:
# I'd rather use time.sleep(ms*0.001) # I'd rather use time.sleep(ms*0.001)
self.tk.call('after', ms) self.tk.call('after', ms)
return None return None
@ -1542,7 +1542,7 @@ class Misc:
def _root(self): def _root(self):
"""Internal function.""" """Internal function."""
w = self w = self
while w.master: w = w.master while w.master is not None: w = w.master
return w return w
_subst_format = ('%#', '%b', '%f', '%h', '%k', _subst_format = ('%#', '%b', '%f', '%h', '%k',
'%s', '%t', '%w', '%x', '%y', '%s', '%t', '%w', '%x', '%y',
@ -2306,7 +2306,7 @@ class Tk(Misc, Wm):
self.tk.createcommand('exit', _exit) self.tk.createcommand('exit', _exit)
self._tclCommands.append('tkerror') self._tclCommands.append('tkerror')
self._tclCommands.append('exit') self._tclCommands.append('exit')
if _support_default_root and not _default_root: if _support_default_root and _default_root is None:
_default_root = self _default_root = self
self.protocol("WM_DELETE_WINDOW", self.destroy) self.protocol("WM_DELETE_WINDOW", self.destroy)
@ -2534,7 +2534,7 @@ class BaseWidget(Misc):
def _setup(self, master, cnf): def _setup(self, master, cnf):
"""Internal function. Sets up information about children.""" """Internal function. Sets up information about children."""
if not master: if master is None:
master = _get_default_root() master = _get_default_root()
self.master = master self.master = master
self.tk = master.tk self.tk = master.tk
@ -3949,7 +3949,7 @@ class _setit:
def __call__(self, *args): def __call__(self, *args):
self.__var.set(self.__value) self.__var.set(self.__value)
if self.__callback: if self.__callback is not None:
self.__callback(self.__value, *args) self.__callback(self.__value, *args)
@ -3998,7 +3998,7 @@ class Image:
def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
self.name = None self.name = None
if not master: if master is None:
master = _get_default_root('create image') master = _get_default_root('create image')
self.tk = getattr(master, 'tk', master) self.tk = getattr(master, 'tk', master)
if not name: if not name:

View File

@ -18,7 +18,7 @@ class Dialog:
command = None command = None
def __init__(self, master=None, **options): def __init__(self, master=None, **options):
if not master: if master is None:
master = options.get('parent') master = options.get('parent')
self.master = master self.master = master
self.options = options self.options = options

View File

@ -108,7 +108,7 @@ __all__ = ["dnd_start", "DndHandler"]
def dnd_start(source, event): def dnd_start(source, event):
h = DndHandler(source, event) h = DndHandler(source, event)
if h.root: if h.root is not None:
return h return h
else: else:
return None return None
@ -143,7 +143,7 @@ class DndHandler:
def __del__(self): def __del__(self):
root = self.root root = self.root
self.root = None self.root = None
if root: if root is not None:
try: try:
del root.__dnd del root.__dnd
except AttributeError: except AttributeError:
@ -154,25 +154,25 @@ class DndHandler:
target_widget = self.initial_widget.winfo_containing(x, y) target_widget = self.initial_widget.winfo_containing(x, y)
source = self.source source = self.source
new_target = None new_target = None
while target_widget: while target_widget is not None:
try: try:
attr = target_widget.dnd_accept attr = target_widget.dnd_accept
except AttributeError: except AttributeError:
pass pass
else: else:
new_target = attr(source, event) new_target = attr(source, event)
if new_target: if new_target is not None:
break break
target_widget = target_widget.master target_widget = target_widget.master
old_target = self.target old_target = self.target
if old_target is new_target: if old_target is new_target:
if old_target: if old_target is not None:
old_target.dnd_motion(source, event) old_target.dnd_motion(source, event)
else: else:
if old_target: if old_target is not None:
self.target = None self.target = None
old_target.dnd_leave(source, event) old_target.dnd_leave(source, event)
if new_target: if new_target is not None:
new_target.dnd_enter(source, event) new_target.dnd_enter(source, event)
self.target = new_target self.target = new_target
@ -193,7 +193,7 @@ class DndHandler:
self.initial_widget.unbind("<Motion>") self.initial_widget.unbind("<Motion>")
widget['cursor'] = self.save_cursor widget['cursor'] = self.save_cursor
self.target = self.source = self.initial_widget = self.root = None self.target = self.source = self.initial_widget = self.root = None
if target: if target is not None:
if commit: if commit:
target.dnd_commit(source, event) target.dnd_commit(source, event)
else: else:
@ -215,9 +215,9 @@ class Icon:
if canvas is self.canvas: if canvas is self.canvas:
self.canvas.coords(self.id, x, y) self.canvas.coords(self.id, x, y)
return return
if self.canvas: if self.canvas is not None:
self.detach() self.detach()
if not canvas: if canvas is None:
return return
label = tkinter.Label(canvas, text=self.name, label = tkinter.Label(canvas, text=self.name,
borderwidth=2, relief="raised") borderwidth=2, relief="raised")
@ -229,7 +229,7 @@ class Icon:
def detach(self): def detach(self):
canvas = self.canvas canvas = self.canvas
if not canvas: if canvas is None:
return return
id = self.id id = self.id
label = self.label label = self.label

View File

@ -68,7 +68,7 @@ class Font:
def __init__(self, root=None, font=None, name=None, exists=False, def __init__(self, root=None, font=None, name=None, exists=False,
**options): **options):
if not root: if root is None:
root = tkinter._get_default_root('use font') root = tkinter._get_default_root('use font')
tk = getattr(root, 'tk', root) tk = getattr(root, 'tk', root)
if font: if font:
@ -183,7 +183,7 @@ class Font:
def families(root=None, displayof=None): def families(root=None, displayof=None):
"Get font families (as a tuple)" "Get font families (as a tuple)"
if not root: if root is None:
root = tkinter._get_default_root('use font.families()') root = tkinter._get_default_root('use font.families()')
args = () args = ()
if displayof: if displayof:
@ -193,7 +193,7 @@ def families(root=None, displayof=None):
def names(root=None): def names(root=None):
"Get names of defined fonts (as a tuple)" "Get names of defined fonts (as a tuple)"
if not root: if root is None:
root = tkinter._get_default_root('use font.names()') root = tkinter._get_default_root('use font.names()')
return root.tk.splitlist(root.tk.call("font", "names")) return root.tk.splitlist(root.tk.call("font", "names"))

View File

@ -99,7 +99,7 @@ class Dialog(Toplevel):
title -- the dialog title title -- the dialog title
''' '''
master = parent master = parent
if not master: if master is None:
master = _get_default_root('create dialog window') master = _get_default_root('create dialog window')
Toplevel.__init__(self, master) Toplevel.__init__(self, master)
@ -124,7 +124,7 @@ class Dialog(Toplevel):
self.buttonbox() self.buttonbox()
if not self.initial_focus: if self.initial_focus is None:
self.initial_focus = self self.initial_focus = self
self.protocol("WM_DELETE_WINDOW", self.cancel) self.protocol("WM_DELETE_WINDOW", self.cancel)

View File

@ -386,7 +386,7 @@ class TixWidget(tkinter.Widget):
self.tk.call(name, 'configure', '-' + option, value) self.tk.call(name, 'configure', '-' + option, value)
# These are missing from Tkinter # These are missing from Tkinter
def image_create(self, imgtype, cnf={}, master=None, **kw): def image_create(self, imgtype, cnf={}, master=None, **kw):
if not master: if master is None:
master = self master = self
if kw and cnf: cnf = _cnfmerge((cnf, kw)) if kw and cnf: cnf = _cnfmerge((cnf, kw))
elif kw: cnf = kw elif kw: cnf = kw
@ -467,7 +467,7 @@ class DisplayStyle:
(multiple) Display Items""" (multiple) Display Items"""
def __init__(self, itemtype, cnf={}, *, master=None, **kw): def __init__(self, itemtype, cnf={}, *, master=None, **kw):
if not master: if master is None:
if 'refwindow' in kw: if 'refwindow' in kw:
master = kw['refwindow'] master = kw['refwindow']
elif 'refwindow' in cnf: elif 'refwindow' in cnf:
@ -862,7 +862,7 @@ class HList(TixWidget, XView, YView):
return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw)) return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw))
def add_child(self, parent=None, cnf={}, **kw): def add_child(self, parent=None, cnf={}, **kw):
if not parent: if parent is None:
parent = '' parent = ''
return self.tk.call( return self.tk.call(
self._w, 'addchild', parent, *self._options(cnf, kw)) self._w, 'addchild', parent, *self._options(cnf, kw))

View File

@ -569,7 +569,7 @@ class Widget(tkinter.Widget):
matches statespec. statespec is expected to be a sequence.""" matches statespec. statespec is expected to be a sequence."""
ret = self.tk.getboolean( ret = self.tk.getboolean(
self.tk.call(self._w, "instate", ' '.join(statespec))) self.tk.call(self._w, "instate", ' '.join(statespec)))
if ret and callback: if ret and callback is not None:
return callback(*args, **kw) return callback(*args, **kw)
return ret return ret

View File

@ -0,0 +1 @@
:mod:`tkinter` supports now widgets with boolean value False.