Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-129534: Fix asksaveasfilename not appending file extension when none is provided #129682

Conversation

anjuraghuwanshi
Copy link

@anjuraghuwanshi anjuraghuwanshi commented Feb 5, 2025

This PR fixes an issue in tkinter.filedialog.asksaveasfilename where the selected file extension is not appended unless a defaultextension is explicitly set.

Changes Made:
If the user does not provide a file extension, the function now correctly appends the first available extension from filetypes, even if defaultextension is not set.
Ensured better consistency when saving files through the dialog.
Testing Done:
Manually tested with different file types (.txt, .csv, .xlsx, .parquet).
Verified that the correct extension is appended if none is provided by the user.
This fix improves the usability of tkinter.filedialog and aligns its behavior with user expectations. Let me know if further refinements are needed!

@ghost
Copy link

ghost commented Feb 5, 2025

All commit authors signed the Contributor License Agreement.
CLA signed

@bedevere-app
Copy link

bedevere-app bot commented Feb 5, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@terryjreedy terryjreedy changed the title Fix asksaveasfilename not appending file extension when none is provided gh-129534: Fix asksaveasfilename not appending file extension when none is provided Feb 5, 2025
@terryjreedy
Copy link
Member

terryjreedy commented Feb 5, 2025

PRs for an issue need the issue number, as I added it, to properly link the 2. Note new link at the bottom of the opening message of each. Don't worry about a possible news entry. The failed Ubuntu runs are currently flakey, so I assumed not related to PR and just re-ran them.

EDIT: rerun failed in build step, so likely nothing to be done here.

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

We are not going to introduce any differences in behavior compared to the underlying Tk command. Besides this, there are issues with the proposed changes which can only be resolved in the user code.

Comment on lines 391 to 396
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.

Comment on lines 401 to 404
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

@bedevere-app
Copy link

bedevere-app bot commented Feb 6, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link

bedevere-app bot commented Feb 6, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link

bedevere-app bot commented Feb 7, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@terryjreedy terryjreedy closed this Feb 7, 2025
@terryjreedy
Copy link
Member

Issue is closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants