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

Add opt-in fuller typing for callables accepting (func, *args, ...) #511

Closed

Conversation

gschaffner
Copy link
Collaborator

this follows up discussion in #491. this uses trio_typing.plugin to add opt-in fuller typing to callables accepting (func, *args, unrelated_kwarg0, ...). see versionhistory.rst for more detailed info.

all of the errors that Mypy currently produces when checking AnyIO with this PR are due to either #510 or python/mypy#14337, I believe.

even with this Mypy bug, this PR is quite useful for typed AnyIO-dependent works as-is, but the Mypy bug does limit its usefulness to (for the most part) only non-generic functions.

if there is interest in this work, I'd be happy to add some typing tests to this PR.

Presently this only changes typing for user-facing callables, but
trio_typing.plugin can also be used to strengthen type checking of
anyio's private callables.
@gschaffner
Copy link
Collaborator Author

the pyright type completion check is failing because it sees mypy_extensions in some public signatures but does not understand that the intent is for pyright to instead use the half of the union that doesn't use mypy_extensions.

one way to fix this is by passing the --ignoreexternal flag during pyright's type completion check. this can have other effects, however. unfortunately it does not look like pyright currently supports setting --ignoreexternal with granularity to ignore only mypy_extensions.

@killjoy1221
Copy link

killjoy1221 commented Jun 29, 2023

I don't like how this is specific to mypy. Using TypeVarTuple from PEP 646 would be a better alternative. Support for it in mypy requires additional flags, but it appears to be fully implemented in pyright and pyre.

A basic implementation would be like this.

from typing import TypeVar, Awaitable, Callable, Any
from typing_extensions import TypeVarTuple, Unpack

T_Ret = TypeVar("T_Ret")
T_Args = TypeVarTuple("T_Args")


def start(
    func: Callable[[Unpack[T_Args]], Awaitable[T_Ret]],
    *args: Unpack[T_Args],
    name: Any = None,
) -> Awaitable[T_Ret]:
    pass

@gschaffner
Copy link
Collaborator Author

yeah, i actually wrote a proper PEP 646 patch a few months ago that would supplant this Mypy-only mess. i got busy with other work and never got around to posting it though. i'll try to get it submitted this weekend :)

@agronholm
Copy link
Owner

Closing in favor of #652.

@agronholm agronholm closed this Dec 14, 2023
@gschaffner
Copy link
Collaborator Author

gschaffner commented Dec 16, 2023

technically #652 didn't supercede this, because the trio_typing Mypy plugin plus mypy_extensions.NamedArg (as used by this PR) can provide some further typing of start and start_task's *args and task_status_value, which some type checkers' PEP 646 implementations currently cannot provide. That said, I completely agree with closing this—nonstandardized, Mypy-specific stuff doesn't sound good.

From my never-posted attempt at using PEP 646 for start, dated June 28, we'd want something like

class Startable(Protocol[Unpack[PosArgsT], T_co, T_Retval]):
    def __call__(
        self, *args: Unpack[PosArgsT], task_status: TaskStatus[T_co]
    ) -> Awaitable[T_Retval]:
        ...

async def start(
    self,
    func: abc.Startable[Unpack[PosArgsT], T_co, Any],
    *args: Unpack[PosArgsT],
    name: object = None,
) -> T_co:
    ...

def start_task(
    self,
    func: Startable[Unpack[PosArgsT], T_co, T_Retval],
    *args: Unpack[PosArgsT],
    name: object = None,
) -> tuple[Future[T_Retval], T_co]:
    ...

For Mypy, at least, this doesn't work currently and the tracking issue is python/mypy#16522.

@gschaffner gschaffner deleted the opt-in-func-posargs-typing branch December 16, 2023 12:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants