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

(WIP) Update the parameter type annotations for pyqtSignal.__init__ #107

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions PyQt5-stubs/QtCore.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,22 @@ class pyqtBoundSignal:
@typing.overload
def disconnect(self, slot: typing.Union["PYQT_SLOT", "QMetaObject.Connection"]) -> None: ...


_SignalTypesT = typing.TypeVar("_SignalTypesT", type, typing.List[type])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
_SignalTypesT = typing.TypeVar("_SignalTypesT", type, typing.List[type])
_SignalTypesT = typing.TypeVar("_SignalTypesT", typing.Union[type, typing.List[type]])

I can't say I know the reasons for why this works and the separate types don't but... it does. :| Is there something that makes it wrong despite passing?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Err, hold that thought... maybe I didn't test properly here...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, trying again and hoping to be less silly. As is, there is no relationship being created between multiple hints so this can just be an alias instead, I think?

Suggested change
_SignalTypesT = typing.TypeVar("_SignalTypesT", type, typing.List[type])
_SignalTypesT = typing.Union[type, typing.List[type]]

(except with a different variable name changed here and at the use sites)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The issue here is that I need to keep all of the var args of the same type. Using the Union allows for

a = pyqtSignal([int, bool], float)

but this is not allowed by PyQt. You can use only types OR only lists of types

Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, I think my second attempt was less silly... though still not helpful. Humm.

class pyqtSignal:
def __init__(self, *types: typing.Any, name: str = ...) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT, name: str) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT, name: str, revision: int) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT, name: str, revision: int, arguments: typing.List[str]) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT, revision: int) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT, revision: int, arguments: typing.List[str]) -> None: ...
@typing.overload
def __init__(self, *types: _SignalTypesT, arguments: typing.List[str]) -> None: ...

@typing.overload
def __get__(self, instance: None, owner: typing.Type["QObject"]) -> "pyqtSignal": ...
Expand Down
17 changes: 11 additions & 6 deletions tests/pyqtsignal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@


class Class(QtCore.QObject):
signal = QtCore.pyqtSignal([str]) # type: typing.ClassVar[QtCore.pyqtSignal]
signal1 = QtCore.pyqtSignal([str]) # type: typing.ClassVar[QtCore.pyqtSignal]
signal2 = QtCore.pyqtSignal(int)
signal3 = QtCore.pyqtSignal([str, bool], [float])
signal4 = QtCore.pyqtSignal(int, name="cool_signal")
signal5 = QtCore.pyqtSignal(type, revision=2)
signal6 = QtCore.pyqtSignal(bool, arguments=["bool_arg"])


Class.signal.__get__
Class.signal1.__get__

instance = Class()
instance.signal.emit
instance.signal.connect
instance.signal.disconnect
instance.signal[str].emit
instance.signal1.emit
instance.signal1.connect
instance.signal1.disconnect
instance.signal1[str].emit