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

Improve lifecycle documentation #5772

Closed
jenstroeger opened this issue Oct 15, 2021 · 5 comments · Fixed by #5773
Closed

Improve lifecycle documentation #5772

jenstroeger opened this issue Oct 15, 2021 · 5 comments · Fixed by #5773

Comments

@jenstroeger
Copy link

The Image lifecycle documentation states that

The lifecycle of a single-frame image is relatively simple. The file must remain open until the load() or close() function is called or the context manager exits.

However, functions like Image.convert()

Returns a converted copy of this image.

It’s unclear whether it’s necessary to call close() on such newly created objects or not, i.e. what’s the lifecycle here? Is the underlying file shared amongst these two objects?

@radarhere radarhere changed the title Improve lifecycle documentation. Improve lifecycle documentation Oct 16, 2021
@radarhere
Copy link
Member

https://pillow.readthedocs.io/en/stable/reference/open_files.html#image-lifecycle

When the pixel data from the image is required, load() is called.

Pixel data is required for convert(). So it calls load() before it does anything else, and the underlying file is closed (for a single-frame image) on the original image. Then convert() reads that data, transforms it appropriately, and places it in a new image instance.

As for improving the documentation, what do you think of #5773?

@jenstroeger
Copy link
Author

As for improving the documentation, what do you think of #5773?

Thank you for the clarification, suggested change helps!

What you say also implies that a context manager is not required for the new Image instance, so…

with Image.open("some.jpg") as img:
    new_img = img.convert("L")
    # Closes the context on `img` but does not affect `new_img`.

print(new_img.format, new_img.mode)  # Safe to do with `img` also?

is safe to do, correct?

@radarhere
Copy link
Member

That is safe to do with new_img, yes.

If you use img after the context manger, you can - it's just that the file association will be gone.

So the following code will work, because load() has already been called by convert().

from PIL import Image
with Image.open("some.jpg") as img:
    if img.fp is not None:
        print("img.fp is not None inside the context manager")
    new_img = img.convert("L")

if img.fp is None:
    print("img.fp is None outside the context manager")
img.save("out.png")

But this code will not work, because load() hasn't been called and the file has been lost.

from PIL import Image
with Image.open("some.jpg") as img:
    pass

img.save("out.png")

@jenstroeger
Copy link
Author

@radarhere, great, I think that too should be mentioned in PR #5773 👍🏼

@radarhere
Copy link
Member

I've added a variation on the passing code I wrote to the PR. The failing code is already explained in https://pillow.readthedocs.io/en/stable/reference/open_files.html#complications

Screen Shot 2021-10-16 at 11 32 30 pm

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

Successfully merging a pull request may close this issue.

2 participants