Skip to content

Commit

Permalink
add _GeneratorContextManagerBase.__init__ (#13246)
Browse files Browse the repository at this point in the history
I think that #6676 showed that Paramspec didn't work, but that
wasn't actually the fault of _GeneratorContextManagerBase.
  • Loading branch information
tungol authored Dec 28, 2024
1 parent b29e26a commit 43f637b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 23 deletions.
1 change: 0 additions & 1 deletion stdlib/@tests/stubtest_allowlists/common.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ _collections_abc.AsyncGenerator.ag_running
asyncio.__all__
builtins.dict.get
collections\.ChainMap\.fromkeys # https://github.com/python/mypy/issues/17023
contextlib._GeneratorContextManagerBase.__init__ # skipped in the stubs in favor of its child classes
http.client.HTTPConnection.response_class # the actual type at runtime is abc.ABCMeta
importlib.abc.Loader.exec_module # See Lib/importlib/_abc.py. Might be defined for backwards compatibility
importlib.abc.MetaPathFinder.find_spec # Not defined on the actual class, but expected to exist.
Expand Down
43 changes: 21 additions & 22 deletions stdlib/contextlib.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ _T_co = TypeVar("_T_co", covariant=True)
_T_io = TypeVar("_T_io", bound=IO[str] | None)
_ExitT_co = TypeVar("_ExitT_co", covariant=True, bound=bool | None, default=bool | None)
_F = TypeVar("_F", bound=Callable[..., Any])
_G = TypeVar("_G", bound=Generator[Any, Any, Any] | AsyncGenerator[Any, Any], covariant=True)
_P = ParamSpec("_P")

_SendT_contra = TypeVar("_SendT_contra", contravariant=True, default=None)
_ReturnT_co = TypeVar("_ReturnT_co", covariant=True, default=None)

_ExitFunc: TypeAlias = Callable[[type[BaseException] | None, BaseException | None, TracebackType | None], bool | None]
_CM_EF = TypeVar("_CM_EF", bound=AbstractContextManager[Any, Any] | _ExitFunc)

Expand Down Expand Up @@ -64,16 +68,19 @@ class ContextDecorator:
def _recreate_cm(self) -> Self: ...
def __call__(self, func: _F) -> _F: ...

class _GeneratorContextManagerBase: ...

class _GeneratorContextManager(_GeneratorContextManagerBase, AbstractContextManager[_T_co, bool | None], ContextDecorator):
# __init__ and all instance attributes are actually inherited from _GeneratorContextManagerBase
# adding them there is more trouble than it's worth to include in the stub; see #6676
def __init__(self, func: Callable[..., Iterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ...
gen: Generator[_T_co, Any, Any]
func: Callable[..., Generator[_T_co, Any, Any]]
class _GeneratorContextManagerBase(Generic[_G]):
# Ideally this would use ParamSpec, but that requires (*args, **kwargs), which this isn't. see #6676
def __init__(self, func: Callable[..., _G], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ...
gen: _G
func: Callable[..., _G]
args: tuple[Any, ...]
kwds: dict[str, Any]

class _GeneratorContextManager(
_GeneratorContextManagerBase[Generator[_T_co, _SendT_contra, _ReturnT_co]],
AbstractContextManager[_T_co, bool | None],
ContextDecorator,
):
if sys.version_info >= (3, 9):
def __exit__(
self, typ: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
Expand All @@ -93,26 +100,18 @@ if sys.version_info >= (3, 10):
def __call__(self, func: _AF) -> _AF: ...

class _AsyncGeneratorContextManager(
_GeneratorContextManagerBase, AbstractAsyncContextManager[_T_co, bool | None], AsyncContextDecorator
_GeneratorContextManagerBase[AsyncGenerator[_T_co, _SendT_contra]],
AbstractAsyncContextManager[_T_co, bool | None],
AsyncContextDecorator,
):
# __init__ and these attributes are actually defined in the base class _GeneratorContextManagerBase,
# adding them there is more trouble than it's worth to include in the stub (see #6676)
def __init__(self, func: Callable[..., AsyncIterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ...
gen: AsyncGenerator[_T_co, Any]
func: Callable[..., AsyncGenerator[_T_co, Any]]
args: tuple[Any, ...]
kwds: dict[str, Any]
async def __aexit__(
self, typ: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
) -> bool | None: ...

else:
class _AsyncGeneratorContextManager(_GeneratorContextManagerBase, AbstractAsyncContextManager[_T_co, bool | None]):
def __init__(self, func: Callable[..., AsyncIterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ...
gen: AsyncGenerator[_T_co, Any]
func: Callable[..., AsyncGenerator[_T_co, Any]]
args: tuple[Any, ...]
kwds: dict[str, Any]
class _AsyncGeneratorContextManager(
_GeneratorContextManagerBase[AsyncGenerator[_T_co, _SendT_contra]], AbstractAsyncContextManager[_T_co, bool | None]
):
async def __aexit__(
self, typ: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
) -> bool | None: ...
Expand Down

0 comments on commit 43f637b

Please sign in to comment.