pygobject-stubs icon indicating copy to clipboard operation
pygobject-stubs copied to clipboard

Possible way to type hint callbacks

Open matperc opened this issue 1 year ago • 13 comments

Right now we hint all the callables that admits variable arguments as Callable[..., T]. Starting from python 3.10 we can use the combination of Concatenate and ParamSpec. Link to documentation.

So for example GAsyncReadyCallback can be typed as

__P__ = ParamSpec("__P__")

Callable[Concatenate[GObject.Object, Gio.AsyncResult, __P__], None]

@lovetox there are any plans to support 3.10?

matperc avatar May 24 '23 07:05 matperc

Its not about supporting 3.10 rather about not supporting everything that was before, except we cover everything with conditionals.

Python 3.10 is now in debian stable i think we could drop everything else.

Type hints are usually only used for CI and development, so i see no reason why people would need to run type checkers with old python versions.

especially because type checkers have the option to specifically test against older python versions anyway

lovetox avatar May 24 '23 17:05 lovetox

Good, I will work on this

matperc avatar May 24 '23 17:05 matperc

While ParamSpec and Concatenate both are added to typing in 3.10, they exist in typing_extensions which is available for all Python versions since 3.7.

demberto avatar May 24 '23 19:05 demberto

While ParamSpec and Concatenate both are added to typing in 3.10, they exist in typing_extensions which is available for all Python versions since 3.7.

Thanks for the info. I will use this then

matperc avatar May 25 '23 04:05 matperc

While with pyright there aren't errors, mypy throw this:

Argument 3 to "read_async" of "File" has incompatible type "Callable[[Optional[Object], AsyncResult], None]"; expected "Optional[Callable[[Optional[Object], AsyncResult, VarArg(<nothing>), KwArg(<nothing>)], None]]"  [arg-type]

The error doesn't make any sense to me, I suppose that it's not correct to use this method for this use case.

matperc avatar May 26 '23 11:05 matperc

Looks correct to me for the most part, the callback argument takes in a Callable or None, hence its optional. I don't understand the VarArg, KwArg part, maybe its the user_data argument.

Also, if you don't care about type hinting for Python < 3.7, you could simply add

from __future__ import annotations

and replace:

Optional[str]

with the newer syntax without breaking compatibility:

str | None

demberto avatar May 27 '23 06:05 demberto

It seems that the problem lays on Optional

from typing import Concatenate, ParamSpec, Callable


P = ParamSpec("P")

def func1(func: Callable[Concatenate[str, P], None], *args):
    pass

def func2(a: str, b: str):
    pass

func1(func2, "hello")

This works

from typing import Concatenate, ParamSpec, Callable, Optional


P = ParamSpec("P")

def func1(func: Optional[Callable[Concatenate[str, P], None]], *args): # Optional func here
    pass

def func2(a: str, b: str):
    pass

func1(func2, "hello")

This not

A bug in mypy?

matperc avatar May 29 '23 07:05 matperc

A bug in mypy?

Yes probably.

demberto avatar May 29 '23 16:05 demberto

did you try other type checkers like for example pyright?

lovetox avatar May 29 '23 16:05 lovetox

did you try other type checkers like for example pyright?

With pyright works fine. In the PR I linked an issue that is similar. I have added some comments, let's see if someone is able to fix it

matperc avatar May 29 '23 16:05 matperc

The question for me is, you wrote the MR is blocked by that mypy issue.

Personally for me thats not blocking, there exist at least one type checker who does it right.

mypy has 2.4 k open issues, what if they never fix that issue?

lovetox avatar May 29 '23 16:05 lovetox

The question for me is, you wrote the MR is blocked by that mypy issue.

Personally for me thats not blocking, there exist at least one type checker who does it right.

mypy has 2.4 k open issues, what if they never fix that issue?

I see your point. Maybe let's wait some time to see if someone came up with a solution

matperc avatar May 29 '23 16:05 matperc

Yeah no hurry, your work, your MR, your decision :) Just wanted to point out that there is more than mypy.

lovetox avatar May 29 '23 16:05 lovetox