-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Add takestring!(x) to create a string from the content of x, emptying it #54372
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
base: master
Are you sure you want to change the base?
Conversation
Also, check for uses of julia/stdlib/FileWatching/src/pidfile.jl Lines 283 to 288 in f3561ae
#53962 |
The name makes me think that |
I would be in favor of that. Every time I have used an IOBuffer I have had to go to the docs to figure out how to get the data out of it correctly. |
So what's the specification of |
It does not truncate - except when the argument is a |
Do we need an underscore here? |
Triage had a long talk about this, #54369, #54156 and #54273. The conclusions we came to are
|
The style guide says not to use underscores "when readable" without, which I think applies here. |
String(::Memory)
not truncateString(::Memory)
not truncate
Can this be refined to "mutating an Array after its alias has been turned into a String is UB"? edit: For the record , I don't think it's right for us to put this contract on an API that's not marked |
Yes. observing it is not great but not UB. the only UB is if you mutate it. |
|
After triage, this PR now contains the following changes:
|
Thanks for the thorough review, @nhz2. I addressed your points and rebased on master. As soon as all tests pass, this PR is good to go. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the compat version number, this looks good.
CI failures are unrelated. |
eeb64a0
to
39be004
Compare
Looks like this is going to go through another round of triage discussion. |
String(::Memory)
not truncate
Triage likes this. |
@jakobnissen thanks so much for all your work here! The one request from triage was a rebase to 1 commit that implements the new functions and a 2nd that switches uses/docs over. |
39be004
to
e814159
Compare
This function creates a string from an IOBuffer or a Vector, emptying the input object and reusing the memory where possible.
This commit switches the usage of the pattern `String(take!(::IOBuffer))` to use the new `takestring!` or `unsafe_takestring!` functions across Base, and in doc- strings. Not all occurrences in e.g. tests are switched over, as this would consistute a lot of code churn for no real purpose.
e814159
to
3083d4e
Compare
io.size = 0 | ||
io.offset_or_compacted = 0 | ||
s | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is jl_genericmemory_to_string
(the no-copy path) only reachable if the io is writable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, takestring!
is mainly used for IOBuffer
s that are used as string builders, so they are already writable.
Also, the last time I checked, calling jl_genericmemory_to_string
can make the reading from the memory invalid: #54372 (comment) , though this might have changed since then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When IOBuffer is not writable, the IOBuffer doesn't take ownership of the memory, and allows it to be shared, e.g. between multiple IOBuffers (and that also makes IOBuffer more safe in general since the user can keep a reference to the memory they wrapped the IOBuffer around). Therefore, we need to copy it out.
Luckily, as Nathan said, that's usually not a performance problem for takestring! where the iobuffer is mutable.
Assuming |
Removing |
This PR adds the
takestring
function. It currently has two methods:takestring!(x)::String
creates a string from the content ofx
, emptyingx
. It's currently only defined forVector{UInt8}
.takestring(::GenericIOBuffer)::String
creates a string from the content of the buffer, and resets the buffer to the initial state.For the motivation for this function, and discussion, read the comments on this PR further down.