You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello! I'm working on a mocking library that aims to bring type-safety to Python mocking, and I'm running into an issue with the typeshed types for contextlib.contextmanager.
Current behavior
A function decorated with @contextlib.contextmanager has the following signature:
Callable[_P, _GeneratorContextManager[_T]]
I think this is difficult to work with in general, because _GeneratorContextManager is a "private" implementation detail of contextlib. In my specific case, I find it difficult to work with because I would like to mock return values from a @contextmanager decorated method.
Returning a value wrapped in a contextlib.nullcontext from the mock works perfectly at runtime. However, a nullcontext[_T] does not satisfy the typing requirement of _GeneratorContextManager[_T],resulting in the following typing error from mypy:
Argument 1 to "then_return" of "Stub" has incompatible type "ContextManager[_ValueReader]";
expected "_GeneratorContextManager[_ValueReader]" [arg-type]
Expected behavior
A function decorated with @contextlib.contextmanager should have the signature:
Callable[_P, AbstractContextManager[_T]]
contextlib.AbstractContextManager is a "public" interface, and in my opinion better communicates the intent of the decorator.
Additional thoughts
@contextlib.asynccontextmanager is already typed in the manner proposed above This was changed to support Python 3.10
The text was updated successfully, but these errors were encountered:
It's probably worth noting that this is no longer true 😕 — I changed the return type of asynccontextmanager in #6634 to fix an issue caused by the return type not being callable.
After seeing #6521 I think this is not a typeshed issue. The __call__ methods added to the generator context managers are very much public interfaces to support usage as a decorator, while _GeneratorContextManager and _AsyncGeneratorContextManager are "private" in actual contextlib source (underscore named, not included in __all__). Typeshed can't (and shouldn't) do anything about this discrepancy.
Gonna close this issue because the answer to my question is "no" 🙃
Overview
Hello! I'm working on a mocking library that aims to bring type-safety to Python mocking, and I'm running into an issue with the typeshed types for
contextlib.contextmanager
.Current behavior
A function decorated with
@contextlib.contextmanager
has the following signature:I think this is difficult to work with in general, because
_GeneratorContextManager
is a "private" implementation detail ofcontextlib
. In my specific case, I find it difficult to work with because I would like to mock return values from a@contextmanager
decorated method.Returning a value wrapped in a
contextlib.nullcontext
from the mock works perfectly at runtime. However, anullcontext[_T]
does not satisfy the typing requirement of_GeneratorContextManager[_T]
,resulting in the following typing error from mypy:Expected behavior
A function decorated with
@contextlib.contextmanager
should have the signature:contextlib.AbstractContextManager
is a "public" interface, and in my opinion better communicates the intent of the decorator.Additional thoughts
This was changed to support Python 3.10@contextlib.asynccontextmanager
is already typed in the manner proposed aboveThe text was updated successfully, but these errors were encountered: