Open ippeiukai opened 1 year ago
The best I came up with was using @contextmanager
within if TYPE_CHECKING
block and trusting type checkers to infer the type of foo
. This isn't the same as explicitly annotating foo
's return type.
if TYPE_CHECKING:
@contextmanager
def foo() -> Iterator[Never]:
...
else:
def foo():
...
return _hoge()
The correct return type for foo
is _GeneratorContextManager
(imported from contextlib
).
from contextlib import _GeneratorContextManager
def foo() -> _GeneratorContextManager:
...
return _hoge()
_GeneratorContextManager
is the actual class used at runtime, and this class subclasses from both AbstractContextManager
and ContextDecorator
.
The fact that it's named with an underscore means that it's private, so you might be reluctant to use this type in a type annotation. I'm not sure why the authors of contextlib
decided not to expose this type publicly. If you're using pyright, you don't need to supply a return type for foo
because it infers the proper return type. Mypy doesn't do this currently.
The fact that it's named with an underscore means that it's private, so you might be reluctant to use this type in a type annotation.
Yap, exactly that. It is clearly not meant to be exported from contextlib. https://github.com/python/cpython/blob/a24e25d74bb5d30775a61853d34e0bb5a7e12c64/Lib/contextlib.py#L10-L14 https://github.com/python/typeshed/blob/a079b0de6e703fcb615a1169a32bc2186efee9bd/stdlib/contextlib.pyi#L10-L23
I'm not sure why the authors of contextlib decided not to expose this type publicly.
I think not exposing such implementation detail is good. That way, we can later swap the implementation _hoge
with our own AbstractContextManager subclass with ContextDecorator mixed in.
I want to contribute a real life use case that we encountered which may justify the needs of Intersection types.
Can anyone suggest an alternative without using Intersection?
NOTE: the spec of
@contextmanager
is here: https://docs.python.org/3/library/contextlib.html#contextlib.contextmanagerEssentially, what the decorated function returns is a ContextManager that uses ContextDecorator mixin.