Skip to content

Type signature for callbacks does not follow PEP #195

Description

@eosti

In the map function in dispatcher.py (as well as in the docs), the type signature for callbacks is various forms of:

def some_cb(address: str, *osc_args: List[Any]) -> Union[None, AnyStr, Tuple(str, ArgValue)]

According to PEP484, arbitrary argument lists should be typed according to what any one argument could be. This annotation therefore suggests that osc_args is a tuple of lists of Any instead of a list of Any. This means that type checkers stumble when trying to use osc_args. For example:

def my_great_handler(self, addr: str, *osc_args: list[Any]) -> None:
    myvar = int(args[0])

ty will flag this as an invalid argument to int:

error[invalid-argument-type]: Argument to constructor `int.__new__` is incorrect
   --> example.py:7:30
    |
106 |         myvar = int(args[0])
    |                     ^^^^^^^ Expected `str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc`, found `list[Any]`
info: type `list[Any]` is not assignable to any element of the union `str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc`
info: ├── type `list[Any]` is not assignable to protocol `Buffer`
info: │   └── protocol member `__buffer__` is not defined on type `list[Any]`
info: ├── type `list[Any]` is not assignable to protocol `SupportsInt`
info: │   └── protocol member `__int__` is not defined on type `list[Any]`
info: ├── type `list[Any]` is not assignable to protocol `SupportsIndex`
info: │   └── protocol member `__index__` is not defined on type `list[Any]`
info: ├── type `list[Any]` is not assignable to protocol `SupportsTrunc`
info: │   └── protocol member `__trunc__` is not defined on type `list[Any]`
info: └── ... omitted 1 union element without additional context
info: Matching overload defined here
   --> stdlib/builtins.pyi:368:9
    |
368 |     def __new__(cls, x: ConvertibleToInt = 0, /) -> Self: ...
    |         ^^^^^^^      ----------------------- Parameter declared here
info: Non-matching overloads for function `__new__`:
info:   [Self](cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self

I believe the correct fix for this would be annotating *osc_args as some type of union of any type that can be in an OSC message. I suppose you could annotate it as Any again, but ruff complains that Any is basically the same as leaving it unannotated, and I'd argue OSC arguments are well enough constrained that you could do something like OscArg = int | float | bytes | bool | other stuff? and annotate callbacks as *osc_args: OscArg.

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions