Skip to content

Commit

Permalink
pythongh-16484: Fix collisions between Checkbutton and ttk.Checkbutto…
Browse files Browse the repository at this point in the history
…n default names

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 committed Mar 8, 2024
1 parent 0b64714 commit c0b7b0f
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 c0b7b0f

Please sign in to comment.