typeshed
typeshed copied to clipboard
`BaseException` lacks `__new__()`
Summary
When overriding __new__()
in a BaseException
subclass, a call of form super().__new__(cls, arg0, [arg1, [arg2, ...]]])
causes type checkers to complain about unused positional argument(s), even though the positional args are both accepted and used by BaseException.__new__()
— they become <BaseException>.args
.
Root cause: type checkers believe super().__new__(...)
in this context is a call to object.__new__()
, rather than BaseException.__new__()
.
Proposed fix: typeshed should include a definition for BaseException.__new__()
analogous to and compatible with to its existing signature for BaseException.__init__()
:
class BaseException:
...
def __init__(self, *args: object) -> None: ...
...
Concrete example
Analyzing the following code....
from __future__ import annotations
class SomeException(Exception):
def __new__(cls, alfa: str, bravo: str) -> SomeException:
msg = f"{alfa} ({bravo})"
return super().__new__(cls, msg) # ᐊ── errors occur here
def __init__(self, alfa: str, bravo: str):
# (preserve these as attributes)
pass
...with mypy causes this report:
bug.py|8| error: Too many arguments for "__new__" of "object" [call-arg]
|| Found 1 error in 1 file (checked 1 source file)
...while pyright (without strict
) says:
|| .../bug.py
bug.py|8| 37 - error: Expected 1 positional argument (reportCallIssue)
|| 1 error, 0 warnings, 0 informations