api: add OIIO_NODISCARD_ERROR to ImageOutput methods#5201
Conversation
- Annotate all ImageOutput write methods (write_image, write_scanline, write_scanlines, write_tile, write_tiles, write_rectangle, write_deep_scanlines, write_deep_tiles, write_deep_image), as well as open, close, and copy_image, with OIIO_NODISCARD_ERROR. - Also fix the handful of internal callsites (imagebuf.cpp, maketexture.cpp, py_imagebuf.cpp) that were previously ignoring the return value of close(), either by propagating the error or by casting to void where the error path is already being handled. - Assisted-by: Claude Sonnet 4.6 Signed-off-by: rose413 <116857309+rose413@users.noreply.github.com>
|
|
|
The failure for the "VFX2023" test is unrelated to your PR and is being fixed separately. If everything else is ok, we will not hold up the merge just because of that. |
lgritz
left a comment
There was a problem hiding this comment.
This is looking really good.
I made some suggestions -- I think a few of the places in tests where you ignore the results, probably it would be better if we checked, and exit the loops early if there is a problem.
Oh, I guess in my explanations, I showed how to detect and exit the loop, but then didn't handle it. For tests, you don't need nice error recovery, but maybe just do a OIIO_CONTRACT_ASSERT(ok) after the loop?
| bool ok = out->open(output_filename, outspec); | ||
| OIIO_ASSERT(ok); | ||
| out->write_image(bufspec.format, &buffer[0]); | ||
| (void)out->write_image(bufspec.format, &buffer[0]); |
There was a problem hiding this comment.
Maybe?
| (void)out->write_image(bufspec.format, &buffer[0]); | |
| ok = out->write_image(bufspec.format, &buffer[0]); | |
| OIIO_ASSERT(ok); |
There was a problem hiding this comment.
I wrote OIIO_ASSERT, but probably OIIO_CONTRACT_ASSERT(ok) is the "more modern" idiom we're aiming for most of the time.
| imagesize_t scanlinesize = outspec.width * pixelsize; | ||
| for (int y = 0; y < outspec.height; ++y) { | ||
| out->write_scanline(y + outspec.y, outspec.z, bufspec.format, | ||
| (void)out->write_scanline(y + outspec.y, outspec.z, bufspec.format, |
There was a problem hiding this comment.
Maybe
bool ok = true;
for (int y = 0; y < outspec.height && ok; ++y) {
ok = out->write_scanline(y + outspec.y, outspec.z, bufspec.format,
&buffer[scanlinesize * y]);
}
| z + outspec.z, z + outspec.z + outspec.tile_depth, | ||
| bufspec.format, &buffer[scanlinesize * y], | ||
| pixelsize /*xstride*/, scanlinesize /*ystride*/); | ||
| (void)out->write_tiles(outspec.x, outspec.x + outspec.width, |
| bufspec.format, | ||
| &buffer[scanlinesize * y + pixelsize * x], | ||
| pixelsize, scanlinesize, planesize); | ||
| (void)out->write_tile(x + outspec.x, y + outspec.y, z + outspec.z, |
There was a problem hiding this comment.
Same here, maybe more like
bool ok = true;
for (int z = 0; z < outspec.depth && ok; ...) {
for (int y = 0; y < outspec.height && ok; ...) {
for (int x = 0; y < outspec.width && ok; ...) {
ok = out->write_tile(...)
I guess I'm superstitious about ignoring the return code, that's what we're trying to be caching. Even though this is a test... what better time to catch a problem then when we're testing?
|
I have a feeling that you did a reformat of code you weren't really trying to change, and you must have a different version of clang-format locally than we are using in CI. |
|
What would you recommend I do to make sure I’m using the same clang-format version as CI? |
I don't, really. We tend to lock down to a clang-format version in CI for a few years at a time to make a stable standard, so that we're not constantly reformatting with every clang-format update. But of course, that means that for those of us who keep our own machines fairly up to date, we can drift from the CI standard. (Of course you COULD install the clang-format 17 we are using in CI but it's probably not worth the trouble.) So first, I never run a clang-format of the full code base on my machine (for this reason -- it will change too many things I wasn't even working on). I use VSCode and so usually I'll just highlight/select the function I altered, or sometimes just the lines I changed, and ask it to reformat that selection only, rather than the whole file or the whole codebase. That at least limits any changes to just the sections I was intending to edit. When my CI fails the clang-format test, I just look at the logs for that run, which in the "clang-format" section, will show the diffs between the actual code and the CI-formatted version, as you can see here. USUALLY it only differs on a couple lines and I just edit those by hand. It's usually easy to see exactly what to do from the diffs in the log. But when it's more extensive or hard to do by hand, I check the downloadable artifacts (click "Summary" on the upper left of the CI dashboard, then scroll all the way to the bottom, where you'll see downloads for each job, and one will be called clang-format). That saved artifact is a zip file of the source code with proper formatting, so you can extract the files you need formatted precisely the way the CI thought it should be done. I'm not sure what tools you have on your end, but what I'd do first if I were you is try to revert all the places in your last commit that reformatted parts of the code you didn't intend to change at all. Then you will only have the small number of differences in the code you really did modify. That should be manageable by hand or by downloading the changed files. Also, if you just can't figure it out, I am happy to fix the formatting for you on my end, and amend your PR with the fixes |
|
Oh, one more thing -- it looks like at least one of your commit did not use |
…rmat Signed-off-by: rose413 <116857309+rose413@users.noreply.github.com>
6b292bb to
e092be1
Compare
Signed-off-by: rose413 <116857309+rose413@users.noreply.github.com>
|
Aha, looks like you got all the formatting fixed! |
| errorfmt("Error closing \"{}\" : {}", out_filename, out->geterror()); | ||
| } |
There was a problem hiding this comment.
I think you should also set ok=false so that the function's return value indicates that something went wrong and that we don't overwrite the real file (at this point we are writing to a temporary file, and will, later i the function, replace the destination file only if everything appeared to go right).
| errorfmt("Error closing \"{}\" : {}", out_filename, out->geterror()); | |
| } | |
| errorfmt("Error closing \"{}\" : {}", out_filename, out->geterror()); | |
| ok = false; | |
| } |
| size_t pixelsize = outspec.nchannels * sizeof(float); | ||
| imagesize_t scanlinesize = outspec.width * pixelsize; | ||
| bool ok = true; | ||
| for (int y = 0; y < outspec.height; ++y) { |
There was a problem hiding this comment.
You assign the result to ok, but ok isn't actually used anywhere. I think that it would be better if you had an OIIO_ASSERT(ok) (or OIIO_CONTRACT_ASSERT, I guess) after the loop. And the loop should probably terminate as soon as there's an error, say:
for (int y = 0; y < outspec.height && ok; ++y)
This file is a bunch of unit tests, so it's not important to issue meaningful error messages with errorfmt or anything like that. But it is a test, so we should at least have an assertion to let us know that it's not really successfully testing the thing that we think it's testing.
I'm only writing this comment here, but I think all of the changes in this file should follow a similar pattern.
lgritz
left a comment
There was a problem hiding this comment.
We are very close. Please see my comments about at least asserting success for the changes to the tests.
Description
Tests
Checklist:
and if I used AI coding assistants, I have an
Assisted-by: TOOL / MODELline in the pull request description above.
behavior.
PR, by pushing the changes to my fork and seeing that the automated CI
passed there. (Exceptions: If most tests pass and you can't figure out why
the remaining ones fail, it's ok to submit the PR and ask for help. Or if
any failures seem entirely unrelated to your change; sometimes things break
on the GitHub runners.)
fixed any problems reported by the clang-format CI test.
corresponding Python bindings. If altering ImageBufAlgo functions, I also
exposed the new functionality as oiiotool options.