https://github.com/python/cpython/commit/71cbffde61449a224dffcae937f5f6be4f86ad09
commit: 71cbffde61449a224dffcae937f5f6be4f86ad09
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-01-20T09:16:36+02:00
summary:
gh-143754: Add Tkinter methods pack_content(), place_content() and
grid_content() (GH-143845)
They use Tk commands with new name like "pack content instead of old
"pack slaves".
files:
A Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst
M Doc/whatsnew/3.15.rst
M Lib/test/test_tkinter/test_geometry_managers.py
M Lib/tkinter/__init__.py
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index b7a27d5db63875..1dd66065b0f93d 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -792,6 +792,12 @@ tkinter
using Tcl's ``-all`` and ``-overlap`` options.
(Contributed by Rihaan Meher in :gh:`130848`)
+* Added new methods :meth:`!pack_content`, :meth:`!place_content` and
+ :meth:`!grid_content` which use Tk commands with new names (introduced
+ in Tk 8.6) instead of :meth:`!*_slaves` methods which use Tk commands
+ with outdated names.
+ (Contributed by Serhiy Storchaka in :gh:`143754`)
+
types
------
diff --git a/Lib/test/test_tkinter/test_geometry_managers.py
b/Lib/test/test_tkinter/test_geometry_managers.py
index b2ce143ff0948f..3dcdadd1aacf10 100644
--- a/Lib/test/test_tkinter/test_geometry_managers.py
+++ b/Lib/test/test_tkinter/test_geometry_managers.py
@@ -40,11 +40,11 @@ def test_pack_configure_after(self):
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
- self.assertEqual(pack.pack_slaves(), [a, b, c, d])
+ self.assertEqual(pack.pack_content(), [a, b, c, d])
a.pack_configure(after=b)
- self.assertEqual(pack.pack_slaves(), [b, a, c, d])
+ self.assertEqual(pack.pack_content(), [b, a, c, d])
a.pack_configure(after=a)
- self.assertEqual(pack.pack_slaves(), [b, a, c, d])
+ self.assertEqual(pack.pack_content(), [b, a, c, d])
def test_pack_configure_anchor(self):
pack, a, b, c, d = self.create2()
@@ -73,11 +73,11 @@ def test_pack_configure_before(self):
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
- self.assertEqual(pack.pack_slaves(), [a, b, c, d])
+ self.assertEqual(pack.pack_content(), [a, b, c, d])
a.pack_configure(before=d)
- self.assertEqual(pack.pack_slaves(), [b, c, a, d])
+ self.assertEqual(pack.pack_content(), [b, c, a, d])
a.pack_configure(before=a)
- self.assertEqual(pack.pack_slaves(), [b, c, a, d])
+ self.assertEqual(pack.pack_content(), [b, c, a, d])
def test_pack_configure_expand(self):
pack, a, b, c, d = self.create2()
@@ -110,10 +110,10 @@ def test_pack_configure_in(self):
c.pack_configure(side='top')
d.pack_configure(side='top')
a.pack_configure(in_=pack)
- self.assertEqual(pack.pack_slaves(), [b, c, d, a])
+ self.assertEqual(pack.pack_content(), [b, c, d, a])
a.pack_configure(in_=c)
- self.assertEqual(pack.pack_slaves(), [b, c, d])
- self.assertEqual(c.pack_slaves(), [a])
+ self.assertEqual(pack.pack_content(), [b, c, d])
+ self.assertEqual(c.pack_content(), [a])
with self.assertRaisesRegex(
TclError, """can't pack "?%s"? inside itself""" % (a,)):
a.pack_configure(in_=a)
@@ -223,11 +223,11 @@ def test_pack_forget(self):
a.pack_configure()
b.pack_configure()
c.pack_configure()
- self.assertEqual(pack.pack_slaves(), [a, b, c])
+ self.assertEqual(pack.pack_content(), [a, b, c])
b.pack_forget()
- self.assertEqual(pack.pack_slaves(), [a, c])
+ self.assertEqual(pack.pack_content(), [a, c])
b.pack_forget()
- self.assertEqual(pack.pack_slaves(), [a, c])
+ self.assertEqual(pack.pack_content(), [a, c])
d.pack_forget()
def test_pack_info(self):
@@ -273,6 +273,14 @@ def test_pack_propagate(self):
self.assertEqual(pack.winfo_reqwidth(), 20)
self.assertEqual(pack.winfo_reqheight(), 40)
+ def test_pack_content(self):
+ pack, a, b, c, d = self.create2()
+ self.assertEqual(pack.pack_content(), [])
+ a.pack_configure()
+ self.assertEqual(pack.pack_content(), [a])
+ b.pack_configure()
+ self.assertEqual(pack.pack_content(), [a, b])
+
def test_pack_slaves(self):
pack, a, b, c, d = self.create2()
self.assertEqual(pack.pack_slaves(), [])
@@ -477,6 +485,15 @@ def test_place_info(self):
with self.assertRaises(TypeError):
f2.place_info(0)
+ def test_place_content(self):
+ foo = tkinter.Frame(self.root)
+ bar = tkinter.Frame(self.root)
+ self.assertEqual(foo.place_content(), [])
+ bar.place_configure(in_=foo)
+ self.assertEqual(foo.place_content(), [bar])
+ with self.assertRaises(TypeError):
+ foo.place_content(0)
+
def test_place_slaves(self):
foo = tkinter.Frame(self.root)
bar = tkinter.Frame(self.root)
@@ -729,10 +746,10 @@ def test_grid_forget(self):
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
- self.assertEqual(self.root.grid_slaves(), [b])
+ self.assertEqual(self.root.grid_content(), [b])
b.grid_forget()
c.grid_forget()
- self.assertEqual(self.root.grid_slaves(), [])
+ self.assertEqual(self.root.grid_content(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
@@ -749,10 +766,10 @@ def test_grid_remove(self):
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
- self.assertEqual(self.root.grid_slaves(), [b])
+ self.assertEqual(self.root.grid_content(), [b])
b.grid_remove()
c.grid_remove()
- self.assertEqual(self.root.grid_slaves(), [])
+ self.assertEqual(self.root.grid_content(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
@@ -887,6 +904,23 @@ def test_grid_size(self):
f.grid_configure(row=4, column=5)
self.assertEqual(self.root.grid_size(), (6, 5))
+ def test_grid_content(self):
+ self.assertEqual(self.root.grid_content(), [])
+ a = tkinter.Label(self.root)
+ a.grid_configure(row=0, column=1)
+ b = tkinter.Label(self.root)
+ b.grid_configure(row=1, column=0)
+ c = tkinter.Label(self.root)
+ c.grid_configure(row=1, column=1)
+ d = tkinter.Label(self.root)
+ d.grid_configure(row=1, column=1)
+ self.assertEqual(self.root.grid_content(), [d, c, b, a])
+ self.assertEqual(self.root.grid_content(row=0), [a])
+ self.assertEqual(self.root.grid_content(row=1), [d, c, b])
+ self.assertEqual(self.root.grid_content(column=0), [b])
+ self.assertEqual(self.root.grid_content(column=1), [d, c, a])
+ self.assertEqual(self.root.grid_content(row=1, column=1), [d, c])
+
def test_grid_slaves(self):
self.assertEqual(self.root.grid_slaves(), [])
a = tkinter.Label(self.root)
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index be150e2b892e4b..d695e3ec9cb1b4 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -1885,9 +1885,21 @@ def pack_propagate(self, flag=_noarg_):
propagate = pack_propagate
- def pack_slaves(self):
+ def pack_content(self):
"""Returns a list of all of the content widgets in the packing order
for this container."""
+ try:
+ res = self.tk.call('pack', 'content', self._w)
+ except TclError:
+ if self.info_patchlevel() >= (8, 6):
+ raise
+ res = self.tk.call('pack', 'slaves', self._w)
+ return [self._nametowidget(x) for x in self.tk.splitlist(res)]
+
+ content = pack_content
+
+ def pack_slaves(self):
+ """Synonym for pack_content()."""
return [self._nametowidget(x) for x in
self.tk.splitlist(
self.tk.call('pack', 'slaves', self._w))]
@@ -1895,9 +1907,19 @@ def pack_slaves(self):
slaves = pack_slaves
# Place method that applies to the container widget
- def place_slaves(self):
+ def place_content(self):
"""Returns a list of all the content widgets for which this widget is
the container."""
+ try:
+ res = self.tk.call('place', 'content', self._w)
+ except TclError:
+ if self.info_patchlevel() >= (8, 6):
+ raise
+ res = self.tk.call('place', 'slaves', self._w)
+ return [self._nametowidget(x) for x in self.tk.splitlist(res)]
+
+ def place_slaves(self):
+ """Synonym for place_content()."""
return [self._nametowidget(x) for x in
self.tk.splitlist(
self.tk.call(
@@ -2018,7 +2040,7 @@ def grid_size(self):
size = grid_size
- def grid_slaves(self, row=None, column=None):
+ def grid_content(self, row=None, column=None):
"""Returns a list of the content widgets.
If no arguments are supplied, a list of all of the content in this
@@ -2027,6 +2049,21 @@ def grid_slaves(self, row=None, column=None):
column is returned.
"""
args = ()
+ if row is not None:
+ args = args + ('-row', row)
+ if column is not None:
+ args = args + ('-column', column)
+ try:
+ res = self.tk.call('grid', 'content', self._w, *args)
+ except TclError:
+ if self.info_patchlevel() >= (8, 6):
+ raise
+ res = self.tk.call('grid', 'slaves', self._w, *args)
+ return [self._nametowidget(x) for x in self.tk.splitlist(res)]
+
+ def grid_slaves(self, row=None, column=None):
+ """Synonym for grid_content()."""
+ args = ()
if row is not None:
args = args + ('-row', row)
if column is not None:
@@ -2641,6 +2678,7 @@ def pack_info(self):
info = pack_info
propagate = pack_propagate = Misc.pack_propagate
+ content = pack_content = Misc.pack_content
slaves = pack_slaves = Misc.pack_slaves
@@ -2698,6 +2736,7 @@ def place_info(self):
return d
info = place_info
+ content = place_content = Misc.place_content
slaves = place_slaves = Misc.place_slaves
@@ -2753,6 +2792,7 @@ def grid_info(self):
propagate = grid_propagate = Misc.grid_propagate
rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
size = grid_size = Misc.grid_size
+ content = grid_content = Misc.grid_content
slaves = grid_slaves = Misc.grid_slaves
diff --git
a/Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst
b/Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst
new file mode 100644
index 00000000000000..edfdd109400d08
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst
@@ -0,0 +1,3 @@
+Add new :mod:`tkinter` widget methods :meth:`!pack_content`,
+:meth:`!place_content` and :meth:`!grid_content` which are alternative
+spelling of old :meth:`!*_slaves` methods.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]