From: Serhiy Storchaka Date: Mon, 22 Jun 2026 12:52:50 +0000 (+0300) Subject: gh-151878: Add tkinter Entry and Spinbox validate methods (GH-151879) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c42f36ac53c9f54c182d70fabe243a04934a8363;p=thirdparty%2FPython%2Fcpython.git gh-151878: Add tkinter Entry and Spinbox validate methods (GH-151879) Wrap the Tk "validate" widget command of the entry and spinbox widgets as the methods Entry.validate() and Spinbox.validate(), forcing an evaluation of the validatecommand independently of the validate option and returning whether the value is valid. Co-authored-by: Claude Opus 4.8 --- diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 249b1602a711..13fe3514b5eb 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -4254,6 +4254,14 @@ Widget classes Typically associated with mouse motion events, to produce the effect of dragging the entry at high speed through the window. + .. method:: validate() + + Force an evaluation of the command given by the *validatecommand* option, + independently of the conditions specified by the *validate* option, and + return whether the value is considered valid. + + .. versionadded:: next + .. class:: Frame(master=None, cnf={}, **kw) @@ -5206,6 +5214,14 @@ Widget classes .. versionadded:: 3.8 + .. method:: validate() + + Force an evaluation of the command given by the *validatecommand* option, + independently of the conditions specified by the *validate* option, and + return whether the value is considered valid. + + .. versionadded:: next + .. class:: Text(master=None, cnf={}, **kw) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 8abc4d0af8d1..3c625801c46a 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -163,6 +163,11 @@ tkinter synchronization of the displayed view with the underlying text. (Contributed by Serhiy Storchaka in :gh:`151675`.) +* Added a :meth:`!validate` method to the :class:`!tkinter.Entry` and + :class:`!tkinter.Spinbox` widgets, which forces an evaluation of the + validation command. + (Contributed by Serhiy Storchaka in :gh:`151878`.) + * Added new window-management methods :meth:`~tkinter.Misc.winfo_isdark` (dark mode detection), :meth:`~tkinter.Wm.wm_iconbadge` (application icon badge) and :meth:`~tkinter.Wm.wm_stackorder` (toplevel stacking order). diff --git a/Lib/test/test_tkinter/test_widgets.py b/Lib/test/test_tkinter/test_widgets.py index 4b51d219d87e..d0305562a0cb 100644 --- a/Lib/test/test_tkinter/test_widgets.py +++ b/Lib/test/test_tkinter/test_widgets.py @@ -589,6 +589,25 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): self.assertRaisesRegex(TclError, 'bad entry index "xyz"', widget.select_range, 'xyz', 'end') + def test_validate(self): + calls = [] + def validatecommand(value): + calls.append(value) + return value.isdigit() + # validate='none' means validation is never triggered automatically, + # so validate() exercises the forced evaluation. + widget = self.create(validate='none', + validatecommand=(self.root.register(validatecommand), '%P')) + widget.insert(0, '123') + result = widget.validate() + self.assertIs(result, True) + self.assertEqual(calls, ['123']) + widget.delete(0, 'end') + widget.insert(0, 'abc') + calls.clear() + self.assertIs(widget.validate(), False) + self.assertEqual(calls, ['abc']) + @add_configure_tests(StandardOptionsTests) class SpinboxTest(EntryTest, unittest.TestCase): diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 68de4a356896..974e386be1bb 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -3445,6 +3445,14 @@ class Entry(Widget, XView): select_to = selection_to + def validate(self): + """Force an evaluation of the validation command. + + This evaluates the command given by the validatecommand option, + independently of the conditions specified by the validate option. + Return whether the value is considered valid.""" + return self.tk.getboolean(self.tk.call(self._w, 'validate')) + class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" @@ -4957,6 +4965,14 @@ class Spinbox(Widget, XView): """Set the variable end of a selection to INDEX.""" self.selection('to', index) + def validate(self): + """Force an evaluation of the validation command. + + This evaluates the command given by the validatecommand option, + independently of the conditions specified by the validate option. + Return whether the value is considered valid.""" + return self.tk.getboolean(self.tk.call(self._w, 'validate')) + ########################################################################### diff --git a/Misc/NEWS.d/next/Library/2026-06-22-01-02-33.gh-issue-151878.IFIA5C.rst b/Misc/NEWS.d/next/Library/2026-06-22-01-02-33.gh-issue-151878.IFIA5C.rst new file mode 100644 index 000000000000..af0d2c25136c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-22-01-02-33.gh-issue-151878.IFIA5C.rst @@ -0,0 +1,3 @@ +Add the :meth:`!validate` method to the :class:`tkinter.Entry` and +:class:`tkinter.Spinbox` widgets, forcing an evaluation of the validation +command.