Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions Lib/tkinter/filedialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,27 @@ def askopenfilename(**options):


def asksaveasfilename(**options):
"Ask for a filename to save as"
"""Ask for a filename to save as"""

# If no default extension is provided, set it to the first filetype
if "defaultextension" not in options:
filetypes = options.get("filetypes")
if filetypes:
first_ext = filetypes[0][1] # Get "*.txt" from ("Text files", "*.txt")
if first_ext.startswith("*"):
options["defaultextension"] = first_ext[1:] # ".txt"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will work incorrectly in cases like "-.txt" or "*.a[0-9]". It is easier to just specify an unambiguous defaultextension argument in your code.

This change also removes possibility to enter extensionless name, which may be desirable.


filename = SaveAs(**options).show()

# Append extension if missing
if filename and '.' not in filename:
ext = options.get("defaultextension", "")
if ext and not filename.endswith(ext):
filename += ext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work for "hidden" dot-files, for file names containing a dot in the middle by accident, for relative file paths containing "../" or "./". It is easier to add an extension in your program after returning from asksaveasfilename(), in a way that specific to your program.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @serhiy-storchaka,
Thank you for the feedback!
I’ve updated the implementation to fully address the concerns:

Special extensions like "*.a[0-9]" are no longer auto-set as defaultextension.
Users can now explicitly save files without an extension if they choose.
Hidden files (".env", ".gitignore") and filenames with embedded dots ("file.v1.final") are now handled correctly.
Relative paths ("../file", "./config") and absolute paths are no longer modified.
Let me know if there are any other edge cases I may have missed!
Screenshot 2025-02-06 181319


return filename


return SaveAs(**options).show()


def askopenfilenames(**options):
Expand Down
Loading