-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Currently in typeshed, urllib.error.HTTPError is (accurately) annotated as inheriting both URLError and urllib.response.addinfourl. The addinfourl class inherits addbase, which is annotated as inheriting typing.BinaryIO. This appears to be an attempt to deal with the fact that addbase actually inherits the (private) tempfile._TemporaryFileWrapper, which is supposed to wrap a "file-like object", and proxies all attribute access to the wrapped object.
This makes some sense: BinaryIO is supposed to be the typing "definition" of what "file-like object" means (at least in binary mode). And this works OK for type-checking code that accesses "file-like" methods on an HTTPError instance. But it makes it impossible to actually instantiate an HTTPError without a spurious mypy error, because the methods of typing.BinaryIO (and its parent typing.IO) are all decorated as @abstractmethod, and most of them are not overridden by the typeshed annotation of addbase or addinfourl.
So if you type-check this code (which works fine at runtime):
from io import StringIO
from urllib.error import HTTPError
http_error = HTTPError("", 500, "message", dict(), StringIO(''))
mypy gives you:
error: Cannot instantiate abstract class 'HTTPError' with abstract attributes '__enter__', '__exit__', ... and 'writelines' (16 methods suppressed)
I'm filing an issue rather than going straight to pull request because the correct fix here isn't obvious to me, and I'm hoping someone with more typeshed experience can offer a preferred solution. If so, I'm happy to implement it. The obvious solution seems to be repeating all the method definitions from typing.BinaryIO and typing.IO in the typeshed annotation for addbase, without @abstractmethod, but I'm hoping there might be an option that avoids this duplication.