Skip to content

Commit

Permalink
pythongh-116484: Fix collisions between Checkbutton and ttk.Checkbutt…
Browse files Browse the repository at this point in the history
…on default names (pythonGH-116495)

Change automatically generated tkinter.Checkbutton widget names to
avoid collisions with automatically generated tkinter.ttk.Checkbutton
widget names within the same parent widget.
  • Loading branch information
serhiy-storchaka authored and adorilson committed Mar 25, 2024
1 parent 3fa0f98 commit 4f4b8fb
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
22 changes: 21 additions & 1 deletion Lib/test/test_ttk/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,29 @@ def test_unique_variables(self):
b.pack()
buttons.append(b)
variables = [str(b['variable']) for b in buttons]
print(variables)
self.assertEqual(len(set(variables)), 4, variables)

def test_unique_variables2(self):
buttons = []
f = ttk.Frame(self.root)
f.pack()
f = ttk.Frame(self.root)
f.pack()
for j in 'AB':
b = tkinter.Checkbutton(f, text=j)
b.pack()
buttons.append(b)
# Should be larger than the number of all previously created
# tkinter.Checkbutton widgets:
for j in range(100):
b = ttk.Checkbutton(f, text=str(j))
b.pack()
buttons.append(b)
names = [str(b) for b in buttons]
self.assertEqual(len(set(names)), len(buttons), names)
variables = [str(b['variable']) for b in buttons]
self.assertEqual(len(set(variables)), len(buttons), variables)


@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
class EntryTest(AbstractWidgetTest, unittest.TestCase):
Expand Down
7 changes: 6 additions & 1 deletion Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3166,11 +3166,16 @@ def __init__(self, master=None, cnf={}, **kw):
Widget.__init__(self, master, 'checkbutton', cnf, kw)

def _setup(self, master, cnf):
# Because Checkbutton defaults to a variable with the same name as
# the widget, Checkbutton default names must be globally unique,
# not just unique within the parent widget.
if not cnf.get('name'):
global _checkbutton_count
name = self.__class__.__name__.lower()
_checkbutton_count += 1
cnf['name'] = f'!{name}{_checkbutton_count}'
# To avoid collisions with ttk.Checkbutton, use the different
# name template.
cnf['name'] = f'!{name}-{_checkbutton_count}'
super()._setup(master, cnf)

def deselect(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Change automatically generated :class:`tkinter.Checkbutton` widget names to
avoid collisions with automatically generated
:class:`tkinter.ttk.Checkbutton` widget names within the same parent widget.

0 comments on commit 4f4b8fb

Please sign in to comment.