Skip to content

Conversation

@rchen152
Copy link
Collaborator

I'm in the process of pulling a newer version of typeshed into Google
and have come across new type errors in code that passes
PIL.ImageTk.PhotoImage objects to tkinter.Label.configure().
Changing the method to instead accept a protocol fixes this.

I created the protocol by checking what attributes and methods are
shared between tkinter.Image and PIL.ImageTk.PhotoImage
(https://github.com/python-pillow/Pillow/blob/0bb6a19cbf250867e708c3c09aa68e857621d272/src/PIL/ImageTk.py#L65).

I'm in the process of pulling a newer version of typeshed into Google
and have come across some code that passes PIL.ImageTk.PhotoImage
objects to tkinter.Label.configure(). This causes pytype to complain
that configure expects tkinter.Image. Changing the method to instead
accept a protocol fixes this.

I created the protocol by checking what attributes and methods are
shared between tkinter.Image and PIL.ImageTk.PhotoImage
(https://github.com/python-pillow/Pillow/blob/0bb6a19cbf250867e708c3c09aa68e857621d272/src/PIL/ImageTk.py#L65).
Copy link
Collaborator

@srittau srittau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for using a protocol, LGTM as is, but I'd appreciate it if you could add return types to the protocol.

@srittau srittau merged commit 8c20938 into master Nov 13, 2020
@srittau srittau deleted the pil branch November 13, 2020 19:59

class _Image(Protocol):
tk: _tkinter.TkappType
def __del__(self) -> None: ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__del__ being part of a protocol seems odd, does tk really require it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I...don't really know. If there's documentation anywhere on what an image class should define to be tkinter-compatible, I haven't been able to find it. I just included all the methods that are present on both tkinter.Image and PIL.ImageTk.PhotoImage (except __str__).

@Akuli
Copy link
Collaborator

Akuli commented Jan 1, 2021

I think __del__ is not necessary. Tkinter uses it to delete the underlying Tcl image, but there's no reason to require every tkinter-compatible image to have it.

Every tkinter image has to have a meaningful __str__, which gets used in the Tcl call that configure() does. But I don't know what including __str__ in a protocol would do. For this purpose, it would be best to reject any objects that don't have a custom __str__, because that's very likely a programming error.

@srittau
Copy link
Collaborator

srittau commented Jan 1, 2021

I assume that it wouldn't do anything, since every class has a __str__ inherited from object.

@rchen152
Copy link
Collaborator Author

rchen152 commented Jan 5, 2021

Sounds like I should remove __del__ from the protocol then, thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants