Skip to content

Commit 02497b7

Browse files
[3.11] gh-116484: Fix collisions between Checkbutton and ttk.Checkbutton default names (GH-116495) (GH-116902)
Change automatically generated tkinter.Checkbutton widget names to avoid collisions with automatically generated tkinter.ttk.Checkbutton widget names within the same parent widget. (cherry picked from commit c61cb50) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent eddfdb3 commit 02497b7

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

Lib/tkinter/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3073,11 +3073,16 @@ def __init__(self, master=None, cnf={}, **kw):
30733073
Widget.__init__(self, master, 'checkbutton', cnf, kw)
30743074

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

30833088
def deselect(self):

Lib/tkinter/test/test_ttk/test_widgets.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,29 @@ def test_unique_variables(self):
287287
b.pack()
288288
buttons.append(b)
289289
variables = [str(b['variable']) for b in buttons]
290-
print(variables)
291290
self.assertEqual(len(set(variables)), 4, variables)
292291

292+
def test_unique_variables2(self):
293+
buttons = []
294+
f = ttk.Frame(self.root)
295+
f.pack()
296+
f = ttk.Frame(self.root)
297+
f.pack()
298+
for j in 'AB':
299+
b = tkinter.Checkbutton(f, text=j)
300+
b.pack()
301+
buttons.append(b)
302+
# Should be larger than the number of all previously created
303+
# tkinter.Checkbutton widgets:
304+
for j in range(100):
305+
b = ttk.Checkbutton(f, text=str(j))
306+
b.pack()
307+
buttons.append(b)
308+
names = [str(b) for b in buttons]
309+
self.assertEqual(len(set(names)), len(buttons), names)
310+
variables = [str(b['variable']) for b in buttons]
311+
self.assertEqual(len(set(variables)), len(buttons), variables)
312+
293313

294314
@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
295315
class EntryTest(AbstractWidgetTest, unittest.TestCase):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Change automatically generated :class:`tkinter.Checkbutton` widget names to
2+
avoid collisions with automatically generated
3+
:class:`tkinter.ttk.Checkbutton` widget names within the same parent widget.

0 commit comments

Comments
 (0)