Fix mypy warning "Missing return statement" by EliahKagan · Pull Request #1789 · gitpython-developers/GitPython (original) (raw)
In git.index.base.IndexFile.from_tree
, control was never able to fall off the end, but mypy
reported a "Missing return statement" because it could not infer that the context manager didn't suppress any exceptions.
This was for two reasons. An ExitStack
context manager suppresses exceptions in some uses and not others, depending on the context manager objects its enter_context
method is called with. In this case, that was sufficient to produce the mypy
warning regardless of other changes, so I converted it to nested with
-statements. The nesting depth is only 2, so this is not really any worse. (I also reworded the comments for clarity and adjusted their spacing.)
The more important cause, however, could also produce this warning in code that uses GitPython, as git.index.util.TemporaryFileSwap
is public. Its __exit__
method was annotated to return bool
. This was itself reported by mypy
as an error, because a context manager __exit__
method that never suppresses exceptions should either always (implicitly) return None
and be annotated as such, or it can return False
as this implementation does but should then have its return type annotated as Literal[False]
.
So this also changes TemporaryFileSwap.__exit__
's return type annotation from bool
to Literal[False]
. If this were nonpublic or being newly designed, it may be better for it to instead return None
implicitly, but I think that would technically be a breaking change (though it would be very unusual, and not a good idea, for any code to ever rely on the distinction).
With both these changes made, both those mypy
warnings go away, and code using GitPython will not get a warning if it makes similar direct use of TemporaryFileSwap
.
(An alternative might be to dedent the return statement out of the with
-statement in IndexFile.from_tree
, but this would make less clear to readers that it does not suppress exceptions. Furthermore, the change to TemporaryFileSwap.__exit__
would still have to be made for mypy
to consider it correctly typed.)