From 1a2485662aa91dd7b851b3e3e442f0da3d3fdae6 Mon Sep 17 00:00:00 2001 From: Hien Hoang Date: Thu, 29 Oct 2026 09:20:27 +0700 Subject: [PATCH 1/2] [tkinter] filedialog ask* functions can return an empty tuple when cancelled --- stdlib/@tests/test_cases/check_tkinter.py | 7 +++++++ stdlib/tkinter/filedialog.pyi | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/stdlib/@tests/test_cases/check_tkinter.py b/stdlib/@tests/test_cases/check_tkinter.py index 62ba0d11f045..359145f0e403 100644 --- a/stdlib/@tests/test_cases/check_tkinter.py +++ b/stdlib/@tests/test_cases/check_tkinter.py @@ -2,6 +2,7 @@ import sys import tkinter +import tkinter.filedialog import traceback import types from typing_extensions import assert_type @@ -71,3 +72,9 @@ def foo(x: int, y: str) -> None: t.count("1.0", "2.3", "indices", "lines", "chars", "ypixels", return_ints=True), tuple[int, ...] ) # (15, 1, 15, 19) assert_type(t.count("2.3", "2.3", "indices", "lines", "chars", "ypixels", return_ints=True), tuple[int, ...]) # (0, 0, 0, 0) + + +# Cancelling a dialog gives an empty string or an empty tuple, depending on the Tk version. +assert_type(tkinter.filedialog.askopenfilename(), str | tuple[()]) +assert_type(tkinter.filedialog.asksaveasfilename(), str | tuple[()]) +assert_type(tkinter.filedialog.askdirectory(), str | tuple[()]) diff --git a/stdlib/tkinter/filedialog.pyi b/stdlib/tkinter/filedialog.pyi index ba69e90aa2da..b1e4b27edb83 100644 --- a/stdlib/tkinter/filedialog.pyi +++ b/stdlib/tkinter/filedialog.pyi @@ -86,7 +86,7 @@ def asksaveasfilename( parent: Misc | None = None, title: str | None = None, typevariable: StringVar | str | None = None, -) -> str: ... # can be empty string +) -> str | tuple[()]: ... # empty string or empty tuple if cancelled, depending on the Tk version def askopenfilename( *, defaultextension: str | None = "", @@ -96,7 +96,7 @@ def askopenfilename( parent: Misc | None = None, title: str | None = None, typevariable: StringVar | str | None = None, -) -> str: ... # can be empty string +) -> str | tuple[()]: ... # empty string or empty tuple if cancelled, depending on the Tk version def askopenfilenames( *, defaultextension: str | None = "", @@ -113,7 +113,7 @@ def askdirectory( mustexist: bool | None = False, parent: Misc | None = None, title: str | None = None, -) -> str: ... # can be empty string +) -> str | tuple[()]: ... # empty string or empty tuple if cancelled, depending on the Tk version # TODO: If someone actually uses these, overload to have the actual return type of open(..., mode) def asksaveasfile( From b37beaaef693b83c38e899bf69406ad86c83ee57 Mon Sep 17 00:00:00 2001 From: Hien Hoang Date: Mon, 2 Nov 2026 08:16:17 +0700 Subject: [PATCH 2/2] Remove the filedialog test cases --- stdlib/@tests/test_cases/check_tkinter.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/stdlib/@tests/test_cases/check_tkinter.py b/stdlib/@tests/test_cases/check_tkinter.py index 359145f0e403..62ba0d11f045 100644 --- a/stdlib/@tests/test_cases/check_tkinter.py +++ b/stdlib/@tests/test_cases/check_tkinter.py @@ -2,7 +2,6 @@ import sys import tkinter -import tkinter.filedialog import traceback import types from typing_extensions import assert_type @@ -72,9 +71,3 @@ def foo(x: int, y: str) -> None: t.count("1.0", "2.3", "indices", "lines", "chars", "ypixels", return_ints=True), tuple[int, ...] ) # (15, 1, 15, 19) assert_type(t.count("2.3", "2.3", "indices", "lines", "chars", "ypixels", return_ints=True), tuple[int, ...]) # (0, 0, 0, 0) - - -# Cancelling a dialog gives an empty string or an empty tuple, depending on the Tk version. -assert_type(tkinter.filedialog.askopenfilename(), str | tuple[()]) -assert_type(tkinter.filedialog.asksaveasfilename(), str | tuple[()]) -assert_type(tkinter.filedialog.askdirectory(), str | tuple[()])