Skip to content

TypeError: Parameter list cannot be empty for TypeVarTuple #322

Description

@EmmanuelMess

There is a problem with typing_extensions that doesn't happen with typing. Running the program with python3.11 works, but with python3.10 with typing_extensions throws:

Traceback (most recent call last):
  File ".../main.py", line 48, in <module>
    main()
  File ".../main.py", line 40, in main
    signal: Signal[()] = Signal[()]()
  File "/usr/lib/python3.10/typing.py", line 312, in inner
    return func(*args, **kwds)
  File "/usr/lib/python3.10/typing.py", line 1328, in __class_getitem__
    raise TypeError(
TypeError: Parameter list to Signal[...] cannot be empty

from __future__ import annotations

from typing_extensions import Callable, TypeVarTuple, Generic, Unpack, List, TypeVar

VarArgs = TypeVarTuple('VarArgs')


class Signal(Generic[Unpack[VarArgs]]):

    def __init__(self):
        self.functions: List[Callable[..., None]] = []
        """
        Simple mechanism that allows abstracted invocation of callbacks. Multiple callbacks can be attached to a signal
        so that they are all called when the signal is emitted.
        """

    def connect(self, function: Callable[..., None]):
        """
        Add a callback to this Signal
        :param function: callback to call when emited
        """
        self.functions.append(function)

    def emit(self, *args: Unpack[VarArgs]):
        """
        Call all callbacks with the arguments passed
        :param args: arguments for the signal, must be the same type as type parameter
        """
        for function in self.functions:
            if args:
                function(*args)
            else:
                function()


def main():
    def signalEmptyCall():
        print("Hello!")

    signal: Signal[()] = Signal[()]()

    signal.connect(signalEmptyCall)

    signal.emit()


if __name__ == '__main__':
    main()

Activity

  1. Daraan commented on Dec 15, 2024

    @Daraan
    Contributor

    I leave a quick comment here.

    The problem is that in 3.10 typing.Generic(and earlier?) there is a check:

            if not params and cls is not Tuple:
                 raise TypeError(f"Parameter list to {cls}[...] cannot be empty")

    As params is an empty tuple the TypeError is raised. We either need to monkeypatch typing or create a custom version of Generic - as there are multiple is Generic tests in typing I am not sure how easy it is to create a stable alternative version.

    Afaik, the only workaround that can be used before 3.11 is to use the equivalent form of () ≡ Unpack[Tuple[()]]:

    signal: Signal[Unpack[Tuple[()]]]
    
  2. JelleZijlstra commented on Dec 16, 2024

    @JelleZijlstra
    Member

    We could make a typing_extensions.Generic that is different from typing.Generic and fixes this issue.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions