From 0e82c56fc040e817de097b7f4f66b4c266c0e2d5 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 26 Feb 2024 14:52:42 -0500 Subject: [PATCH] add suffix kwarg to `tempname` (#53474) `tempname` checks that the name its returning is not already a file, however if you want that filename to contain other information, like a file extension, that can mean the uniquing isn't complete. This adds `tempname(suffix = "_foo.txt")` to include a suffix in the name and uniquing check. --------- Co-authored-by: Jameson Nash --- NEWS.md | 3 +++ base/file.jl | 12 ++++++++---- test/file.jl | 3 +++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6b5fd28082b9b2..c37cb9efdd9b86 100644 --- a/NEWS.md +++ b/NEWS.md @@ -27,6 +27,9 @@ New library functions New library features -------------------- +* `tempname` can now take a suffix string to allow the file name to include a suffix and include that suffix in + the uniquing checking ([#53474]) + Standard library changes ------------------------ diff --git a/base/file.jl b/base/file.jl index 6347f042e3422e..6156bafacdc47a 100644 --- a/base/file.jl +++ b/base/file.jl @@ -620,13 +620,13 @@ end # Obtain a temporary filename. -function tempname(parent::AbstractString=tempdir(); max_tries::Int = 100, cleanup::Bool=true) +function tempname(parent::AbstractString=tempdir(); max_tries::Int = 100, cleanup::Bool=true, suffix::AbstractString="") isdir(parent) || throw(ArgumentError("$(repr(parent)) is not a directory")) prefix = joinpath(parent, temp_prefix) filename = nothing for i in 1:max_tries - filename = string(prefix, _rand_filename()) + filename = string(prefix, _rand_filename(), suffix) if ispath(filename) filename = nothing else @@ -682,7 +682,7 @@ end # os-test """ - tempname(parent=tempdir(); cleanup=true) -> String + tempname(parent=tempdir(); cleanup=true, suffix="") -> String Generate a temporary file path. This function only returns a path; no file is created. The path is likely to be unique, but this cannot be guaranteed due to @@ -693,7 +693,8 @@ existing at the time of the call to `tempname`. When called with no arguments, the temporary name will be an absolute path to a temporary name in the system temporary directory as given by `tempdir()`. If a `parent` directory argument is given, the temporary path will be in that -directory instead. +directory instead. If a suffix is given the tempname will end with that suffix +and be tested for uniqueness with that suffix. The `cleanup` option controls whether the process attempts to delete the returned path automatically when the process exits. Note that the `tempname` @@ -705,6 +706,9 @@ you do and `cleanup` is `true` it will be deleted upon process termination. The `parent` and `cleanup` arguments were added in 1.4. Prior to Julia 1.4 the path `tempname` would never be cleaned up at process termination. +!!! compat "Julia 1.12" + The `suffix` keyword argument was added in Julia 1.12. + !!! warning This can lead to security holes if another process obtains the same diff --git a/test/file.jl b/test/file.jl index e0241c5ef38df1..1ce7a5cdb440b7 100644 --- a/test/file.jl +++ b/test/file.jl @@ -124,6 +124,9 @@ end end @test_throws ArgumentError tempname(randstring()) end +@testset "tempname with suffix" begin + @test !isfile(tempname(suffix = "_foo.txt")) +end child_eval(code::String) = eval(Meta.parse(readchomp(`$(Base.julia_cmd()) -E $code`)))