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

Replace sys.stdout with sys.stdout.buffer when saving #5437

Merged
merged 5 commits into from
May 3, 2021

Conversation

radarhere
Copy link
Member

Resolves #5436

https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html#example-draw-a-gray-cross-over-an-image

from PIL import Image, ImageDraw

with Image.open("hopper.jpg") as im:

    draw = ImageDraw.Draw(im)
    draw.line((0, 0) + im.size, fill=128)
    draw.line((0, im.size[1], im.size[0], 0), fill=128)

    # write to stdout
    im.save(sys.stdout, "PNG")

However, running this example code gives

Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
  File "PIL/Image.py", line 2172, in save
    save_handler(self, fp, filename)
  File "PIL/PngImagePlugin.py", line 1223, in _save
    fp.write(_MAGIC)
TypeError: write() argument must be str, not bytes

This PR suggests fixing this by changing im.save so that if it is passed sys.stdout (sys.stdout.mode is 'w'), then it is replaced with sys.stdout.buffer (sys.stdout.buffer.mode is 'wb').

It also changes the PSDraw() default from sys.stdout to sys.stdout.buffer, and simplifies EPS saving by abandoning the idea of wrapping fp just so that it can write strings.

@radarhere radarhere added the Bug Any unexpected behavior, until confirmed feature. label Apr 25, 2021
@hugovk
Copy link
Member

hugovk commented May 3, 2021

Looks good, one question:

The docs for sys.stdout includes this:

Note: To write or read binary data from/to the standard streams, use the underlying binary buffer object. For example, to write bytes to stdout, use sys.stdout.buffer.write(b'abc').

OK, good. It continues:

However, if you are writing a library (and do not control in which context its code will be executed), be aware that the standard streams may be replaced with file-like objects like io.StringIO which do not support the buffer attribute.

Is this something we need to accomodate?

@radarhere
Copy link
Member Author

Nice catch. Sure, I've added a commit to allow for that.

@hugovk
Copy link
Member

hugovk commented May 3, 2021

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Any unexpected behavior, until confirmed feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't save PNG to sys.stdout
2 participants