pytype icon indicating copy to clipboard operation
pytype copied to clipboard

An asynccontextmanager method breaks __init__ inference for attrs classes

Open gmacon opened this issue 2 years ago • 0 comments

Pytype 2024.02.13 Python 3.8.18

This file:

from contextlib import asynccontextmanager
from typing import AsyncGenerator

from attrs import define


@define
class Thing:
    instance: int

    @asynccontextmanager
    async def context(self) -> AsyncGenerator[None, None]:
        yield

produces this output from pytype-single --output - repro.py:

import attr
import contextlib
from typing import Annotated, AsyncIterator, Callable, ParamSpec, TypeVar

define: Annotated[Callable, 'pytype_metadata', {'tag': 'attr.s', 'init': True, 'kw_only': False, 'auto_attribs': None}]

_P = ParamSpec('_P')
_T_co = TypeVar('_T_co')

@attr.s
class Thing:
    instance: int
    def __init__(self) -> None: ...
    def context(self) -> contextlib._AsyncGeneratorContextManager[None]: ...

def asynccontextmanager(func: Callable[_P, AsyncIterator[_T_co]]) -> Callable[_P, contextlib._AsyncGeneratorContextManager[_T_co]]: ...

Note __init__(self) -> None: ... is incorrect, should be __init__(self, instance: int) -> None: ...

If you remove `context:

from contextlib import asynccontextmanager
from typing import AsyncGenerator

from attrs import define


@define
class Thing:
    instance: int

this gives:

import attr
import contextlib
from typing import Annotated, AsyncIterator, Callable, ParamSpec, TypeVar

define: Annotated[Callable, 'pytype_metadata', {'tag': 'attr.s', 'init': True, 'kw_only': False, 'auto_attribs': None}]

_P = ParamSpec('_P')
_T_co = TypeVar('_T_co')

@attr.s
class Thing:
    instance: int
    def __init__(self, instance: int) -> None: ...

def asynccontextmanager(func: Callable[_P, AsyncIterator[_T_co]]) -> Callable[_P, contextlib._AsyncGeneratorContextManager[_T_co]]: ...

which has the correct signature for __init__.

gmacon avatar Feb 14 '24 21:02 gmacon