Uh oh!
There was an error while loading. Please reload this page.
Explain why we subclass ImageQt with Any - #9461
Conversation
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
hauntsaninja
left a comment
There was a problem hiding this comment.
Maybe this should be a protocol?
Avasam
commented
Jan 5, 2023
I thought about it, but Protocol could probably be simplified by using Any when it starts referencing other types (so at least we have all methods and members). But would a protocol still work as a return type? |
AlexWaygood
commented
Jan 5, 2023
Protocols can be used as a return type! I agree with @hauntsaninja that we can probably at least try to roughly describe the shape of the superclass here. |
I meant that I'm concerned about the variance: fromtypingimportProtocolclassAbc:
foo: strclassAbcProtocol(Abc, Protocol): ... # type: ignore[misc]reveal_type(AbcProtocol().foo). # strclassAbcd:
foo: strabcd: Abcdabcd=AbcProtocol() # Incompatible types in assignment (abcproto: AbcProtocol=Abcd() |
hauntsaninja
commented
Jan 7, 2023
I'm not sure I follow, wouldn't users just use the |
Here's a minimal example in PyQt6. This is what we need to support (without actually having to install PyQt6, PyQt5, PySide6 or PySide2 when installing types-pillow). Would using a protocol for ImageQt's base work thanks to duck typing? And how complex would that protocol have to be? (QImages have lots of methods, members and bases). fromPyQt6importQtGuifromPILimportImage, ImageQtdata: memoryview# Some graphics data from elsewhere in the codepil_image: Image.Image# Some pillow image from elsewhere in the codedefshow_qimage(image: QtGui.QImage):
# Show the image someplace in the GUIpass# With PyQt directlyqimage=QtGui.QImage(data, 640, 480, 640*4, QtGui.QImage.Format.Format_RGBA8888)
show_qimage(qimage)
# using the pillow wrapper insteadqimage=ImageQt.ImageQt(pil_image)
show_qimage(qimage) # Argument of type "ImageQt" cannot be assigned to parameter "image" of type "QImage" in function "show_qimage" "ImageQt" is incompatible with "QImage"
Edit: Don't think so classA:
deftest(self, foo: str) ->int: ...
classProtocolA(Protocol):
deftest(self, foo: str) ->int: ...
protoA=cast(ProtocolA, A())
a: A=protoA# Expression of type "ProtocolA" cannot be assigned to declared type "A" "ProtocolA" is incompatible with "A" |
Avasam
commented
Jan 11, 2023
@AlexWaygood , I don't see an "easy" solution for this (or any good solution at all). Since type-checkers can't have a conditional type based on if a module exists or not. (without having to check for a full ImportError, which can't be done statically, I feel like checking for a module's existence could be a beneficial proposition) Can I move this to #9491 ? |
AlexWaygood
commented
Jan 11, 2023
I'm fine with that. It's not like we're introducing a regression here, after all -- we're already sbuclassing |
Avasam
commented
Jan 12, 2023
Closing in favor of #9491 |
These are way too complex, with 4 different possible sources (2 deprecated)
And we don't want to force the user to install PyQt or Pyside when they may not even use it.
Fixes 6 subclassing errors (the same error in Pillow, D3DShot, python-xlib, fpdf2, PyScreeze, and PyAutoGUI stubs)
Ref: #9491