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

pyright: Failed to call method "__get__" for descriptor class "LRUAsyncCallable..." #124

Closed
Luffbee opened this issue Jan 24, 2024 · 5 comments
Labels
help wanted Extra attention is needed typing bug Some type hints aren't working

Comments

@Luffbee
Copy link

Luffbee commented Jan 24, 2024

The following code can run, but pyright will report errors.
These errors are annoying, it would be great if they could be eliminated.

Thanks for this great library!

import asyncio

import asyncstdlib as astd


class Test:
    @astd.cache
    async def foo(self, n: int) -> int:
        return n

    async def bar(self) -> int:
        return await self.foo(1)

if __name__ == "__main__":
    a = Test()
    with asyncio.Runner() as r:
        print(r.run(a.bar()))
        print(r.run(a.foo(2)))
$ python aaa.py 
1
2

$ pyright aaa.py 
/liuyifan/aaa.py
  /liuyifan/aaa.py:11:27 - error: Cannot access member "foo" for type "Test*"
    Failed to call method "__get__" for descriptor class "LRUAsyncCallable[(self: Self@Test, n: int) -> Coroutine[Any, Any, int]]" (reportAttributeAccessIssue)
  /liuyifan/aaa.py:17:23 - error: Cannot access member "foo" for type "Test"
    Failed to call method "__get__" for descriptor class "LRUAsyncCallable[(self: Test, n: int) -> Coroutine[Any, Any, int]]" (reportAttributeAccessIssue)
2 errors, 0 warnings, 0 information 

$ python --version
Python 3.12.1

$ pyright --version
pyright 1.1.348
@maxfischer2781
Copy link
Owner

Thanks for the report! I can confirm that I can reproduce this issue, but I still have to figure out what exactly PyRight is complaining about here.

@maxfischer2781 maxfischer2781 added the typing bug Some type hints aren't working label Jan 25, 2024
@maxfischer2781
Copy link
Owner

maxfischer2781 commented Mar 3, 2024

This is going to take a bit longer. I've made some progress on understand __get__ to the point that MyPy now has full parameter support for methods (#129) - but PyRight still chokes. :/

I might have to build an MRE and ask the PyRight maintainers just what the thing complains about. If anyone has capacities to handle this earlier than me, feel free to move ahead.

@maxfischer2781 maxfischer2781 added the help wanted Extra attention is needed label Mar 3, 2024
@maxfischer2781
Copy link
Owner

maxfischer2781 commented Mar 18, 2024

I seem to have tracked this down to an issue with capturing the -> Awaitable[R] part of the wrapped callable; a synchronous setup using -> R seems to work.

My current MRE for the descriptor:

AC = TypeVar("AC", bound=Callable[..., Awaitable[Any]])
R = TypeVar("R")
P = ParamSpec("P")
S = TypeVar("S")


class ADescr(Generic[AC]):
    __call__: AC

    def __init__(self, callable: AC): ...

    @overload
    def __get__(
        self: ADescr[AC], instance: None, owner: type | None = ...
    ) -> ADescr[AC]: ...
    @overload
    def __get__(
        self: ADescr[Callable[Concatenate[S, P], Awaitable[R]]],
        instance: S,
        owner: type | None = ...,
    ) -> Callable[P, Awaitable[R]]: ...

    def __get__(self, instance: object | None, owner: type | None = None) -> Any: ...

Which fails for a simple testcase:

class Test:
    @ADescr
    async def foo(self, a: int) -> int:
        return a

    async def access(self):
        return await self.foo(12)
        # Cannot access member "foo" for type "Test*"
        # Failed to call method "__get__" for descriptor class "ADescr[(self: Self@Test, a: int) -> Coroutine[Any, Any, int]]" Pylance[reportAttributeAccessIssue]

Notably, MyPy accepts this and infers everything correctly.

@maxfischer2781
Copy link
Owner

I've just reported this as microsoft/pyright#7533.

maxfischer2781 added a commit that referenced this issue Mar 21, 2024
maxfischer2781 added a commit that referenced this issue Mar 21, 2024
* add missing get case

* special case to workaround #124
@maxfischer2781
Copy link
Owner

The solution suggested in the PyRight issue doesn't work for the practical case (AC must be invariant since it is also used in __call__). So the workaround is going to stay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed typing bug Some type hints aren't working
Projects
None yet
Development

No branches or pull requests

2 participants