pytype
pytype copied to clipboard
An asynccontextmanager method breaks __init__ inference for attrs classes
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__.