-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Introduce AnnotatedIOBuffer #51807
Introduce AnnotatedIOBuffer #51807
Conversation
43f88eb
to
b67d93b
Compare
This CI failure:
Means that Specifically, calls to |
3c2f0e2
to
a3d0329
Compare
Thanks for having a look, in response I've just added these two methods: write(io::AnnotatedIOBuffer, x::AbstractString) = write(io.io, x)
write(io::AnnotatedIOBuffer, s::Union{SubString{String}, String}) = write(io.io, x) |
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.
This seems like a good idea. However, I think it makes sense to include at least one motivating usage of this type in this PR (or a linked PR that depends on it) because I don't like introducing additional complexity that does not have any impact on publicly accessible functionality.
In addition to avoiding premature addition of complexity (which I doubt this is) the request to add a motivating use case is a nice principle to follow because having a use of AnnotatedIOBuffer
gives context for the API design decisions of the type.
Thanks for the comments Lilith. Regarding adding a usage example, there are three PRs I have in mind currently that need this: improving the The latter two will be more work I suspect, so I'll see if I can whip up the |
a3d0329
to
912854f
Compare
75f4654
to
1b43f6b
Compare
For a basic example of this being useful, perhaps JuliaLang/StyledStrings.jl#12 is a decent starting point? The |
From triage: Jeff is afraid that everyone will have to use annotated things for all IO in Base (and the whole ecosystem?) if we go this route. This is not something that we can talk about as a single issue. We need to discuss the overarching vision of all IO in Julia. This has far reaching consequences and shouldn't be merged as a small thing when it's really a huge thing. This is not to say that we don't want to do this, but that if we do decide to do this, it should be a broad sweeping decision. Let's talk about this at next triage 1:30 UTC on November 9. |
1b43f6b
to
f508212
Compare
f508212
to
cfa9616
Compare
cfa9616
to
87a832a
Compare
Triage didn't get to this, try again in a month's time 😞 |
Triage had a chat about this, and while not unanimous was broadly in support of this. We concluded that it would be best to put some of the major point in the discussion here, and give an opportunity for objections/problems we've overlooked to be mentioned. Should nothing (new) come up, this can be merged in a week or so. Triage conversation points:
|
1bc3cb9
to
16a3361
Compare
Alrighty, time for round 2 of
😁 |
Ah gotcha. That seems somewhat like type piracy though, no, since you have to load StyledStrings for this |
Seems to have an ambiguity error:
Also, I see you added the "don't squash" label, but it doesn't appear that each commit here is functionally independent. If not, they would normally be squashed to preserve the one commit == one feature / change expectation. |
It is indeed, type pirate-y. However, I don't really see much of a way around it. One of the reasons (by a few people, IIRC) given in support of Now, Do please let me know if you have any better ideas around this. |
I guess that makes sense, maybe StyledStrings is just one of those that needs to be loaded by default, like Logging, FileWatching, and Libdl. They are conceptually separated out of Base, and could be removed during a build if absolutely required, but are not actually separable or "replaceable batteries" in that sense. |
Once the tests are passing, this looks good to merge |
I'm not actually quite sure what's going on with that ambiguity, might you be able to elaborate on it? |
I guess it depends on what you look for in a PR. I get the sense that you're seeing this as a PR that "provides AnnotatedIOBuffer" and so there should be one commit that "introduces AnnotatedIOBuffer". I tend to think of PRs as a collection of atomic commits that collectively provide a feature/change, and a useful history of how that happened. These commits are that.
I'd think the history of the development (so long as the commits are atomic, which they are) would be more valuable than dumping the collection of changes fully formed into the repo, no? I guess it depends on how much you see git as a tool to track the development history of a project vs. just a means of distributed work. Depending on how you look at it, forget being independent of each other, some of the commits here aren't even independent of other PRs 😛 (e.g. the NEWS and insert! commits, affect content from previous PRs unrelated to this PR, but I wouldn't think are worth separating out into separate PRs). |
On this note, once #51869 is sorted out (imminently hopefully 🤞), |
While `String` is the only concrete type for which `read(::IOBuffer, ::Type{<:AbstractString})` is defined, is is entirely conceivable that some other custom string type could define a similar `read` method. Since making reading an `AnnotatedString` from an `AnnotatedIOBuffer` more generic is as easy as replacing the hardcoded `String` with a type parameter, we may as well do so.
The `read(::AnnotatedIOBuffer, AnnotatedString)` method is intended as an approximate analogue to `read(::IOBuffer, String)`. In the same sense, it makes sense to define `read(::AnnotatedIOBuffer, AnnotatedChar)` as an analogue to `read(::IOBuffer, Char)`.
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
16a3361
to
2b9839b
Compare
Commits should not reflect the history of the development, but rather are curated set of changes that each can be viewed independently as being a complete change |
Right, but I don't see the two as being mutually exclusive — or do you not view commits like |
Seen another way, each separate commit is a statement that individual commits could be reverted and the feature (up to that commit in the sequence) are still a complete implementation. Thus if someone encounters a problem later, we can revert and reland just the problematic commits. That breaks down if some arbitrary, unknown subset of commits are half-broken aspirational in progress work which is only valid at the merge commit point |
If it was in a separate PR, it would be a standalone commit, but as a complete sequence, each change to the API or implementation in the development process should not result in a separate commit to master |
You seem to be describing atomic commits, no? The commits here are atomic, and can be handled individually. None of them are half-broken "aspirational" commits. 37 changes have been rebased into 8 logical commits, and the codebase is "valid" at each point, CI should pass at each step. If the whole thing needs to be reverted for some reason, you can just revert the merge commit instead of needing to squash everything into one commit 🤷, and I'd think it would be much easier to pinpoint where/what's gone wrong when less changes are bundled together. I'm not trying to be argumentative here, I'm just somewhat confused by this as it runs counter to the emphasis on the value of a detailed and useful history I've seen elsewhere. |
Feel free to just go ahead and squash merge this though, I care more about finally getting this PR over with than discussing whether it's worth preserving the commit history. |
A semi-automated way to look at it is that each separate commit should likely have tests if it represents a different change. Not always the case, but not all PRs need to have tests either. And if the later commits are changing the proposed API, then it is even less obvious that you would want someone to roll back this to a version with the older API as that would be a breaking change that wouldn't be allowed. |
I can't say I entirely see it, but this is good to merge from my POV. The CI hasn't completed yet, but the |
No ambiguity errors it looks like! 😀 |
Thanks for helping this over the line Jameson! |
This allows for styled content to be constructed incrementally, without resorting to repeated concatenation. It operates very similarly to IOContext, just with a special
write
method and specifically wrapping an IOBuffer.While I consider this functionality generally useful, I also have a specific use in
Markdown
in mind for this. For no it's not exported or public API, but I think we'd probably want to talk about making it public API in the future.For
Base
itself though, I think it's important to note that this lets us pass anAnnotatedIOBuffer
toshow
calls, and thus truncate printedAnnotatedStrings
without the issues of accidentally removing terminating escape codes etc. that we currently have (see #45521 for an example).With the way
printstyled
works, this benefit won't be seen immediately, but I see it as part of building the path to a nicer, less headache-inducing future.