Description
Summary
The following code causes Pyright (the type checker used by Pylance, default type checker for Python in VSCode) to emit an error:
import matplotlib.pyplot as plt
with plt.ioff():
fig, ax = plt.subplots()
ax.plot([...], [...]) # <-- Pyright error: "ax" is possibly unbound
The root cause of the issue seems to be that ioff
and ion
return contextlib.ExitStack
, which can in theory supress excpetions, as indicated by the return type of ErrorStack.__exit__
being bool
rather than Literal[False]
or None
. (See microsoft/pyright#7009)
In practice though, the way matplotlib uses ExitStack
, it can't swallow exceptions. It would be convenient for typed codebases if the return type of ion
and ioff
reflected that.
Proposed fix
A simple context manager like this could be used instead to make it clear to type checkers that exceptions will never be supressed (note that the return type of __exit__
is None
):
class _InteractiveContextManager(contextlib.AbstractContextManager):
def __init__(self, callback: Callable):
self._callback = callback
def __enter__(self) -> None:
return None
def __exit__(self, __exc_type, __exc_value, __traceback) -> None:
self._callback()
This also has the added benefit that by returning None
from __enter__
we can better enforce that the context manager is not stored or accessed by the user.