Problem
The current type annotation for Tk.report_callback_exception in typeshed, introduced in #2498, causes a regression when subclassing tkinter.Tk and overriding the method.
Issue 1: Incompatible override error in pyright
When subclassing Tk and overriding report_callback_exception with the correct runtime signature, pyright reports an incompatible method override error.
Code:
from tkinter import Tk
from types import TracebackType
from typing import override
class App(Tk):
@override
def report_callback_exception(
self,
exc_type: type[BaseException],
exc_value: BaseException,
exc_traceback: TracebackType | None,
):
pass
pyright output:
(report-callback-exception) PS G:\programming\python\lab\report_callback_exception> pyright
g:\programming\python\lab\report_callback_exception\main.py
g:\programming\python\lab\report_callback_exception\main.py:8:9 - error: Method "report_callback_exception" overrides class "Tk" in an incompatible manner
Positional parameter count mismatch; base method has 3, but override has 4
Parameter 2 type mismatch: base parameter is type "BaseException", override parameter is type "type[BaseException]"
Parameter 3 type mismatch: base parameter is type "TracebackType | None", override parameter is type "BaseException"
Type "BaseException" is not assignable to type "type[BaseException]"
Type "TracebackType | None" is not assignable to type "BaseException"
"TracebackType" is not assignable to "BaseException" (reportIncompatibleMethodOverride)
1 error, 0 warnings, 0 informations
Issue 2: Missing error on invalid manual call
Conversely, pyright does not report an error when manually calling Tk.report_callback_exception with the wrong signature, even though the code fails at runtime.
Code:
from tkinter import Tk
import sys
def main():
try:
print(0 / 0)
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
assert exc_type is not None
assert exc_value is not None
Tk.report_callback_exception(exc_type, exc_value, exc_traceback)
Runtime error:
(report-callback-exception) PS G:\programming\python\lab\report_callback_exception> & g:\programming\python\lab\report_callback_exception\.venv\Scripts\python.exe g:/programming/python/lab/report_callback_exception/main.py
Traceback (most recent call last):
File "g:\programming\python\lab\report_callback_exception\main.py", line 7, in main
0 / 0
~~^~~
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "g:\programming\python\lab\report_callback_exception\main.py", line 16, in <module>
main()
~~~~^^
File "g:\programming\python\lab\report_callback_exception\main.py", line 12, in main
Tk.report_callback_exception(exc_type, exc_value, exc_traceback)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Tk.report_callback_exception() missing 1 required positional argument: 'tb'
pyright output:
(report-callback-exception) PS G:\programming\python\lab\report_callback_exception> pyright
0 errors, 0 warnings, 0 informations
Expected behavior
The type annotation should match the actual runtime signature as used in practice.
Additional context
srittau said in #1767 (comment):
"This looks more like a mypy problem to me. It is somehow expecting an additional self argument here."
If that is indeed the case, I think we should revert the type annotation for report_callback_exception and report the error to mypy instead, because the root cause is not here.
The above statement is irrelevant to this issue.
mypy's error when assigning to a method is intentional, therefore #1767 is not an issue.
Problem
The current type annotation for
Tk.report_callback_exceptionin typeshed, introduced in #2498, causes a regression when subclassingtkinter.Tkand overriding the method.Issue 1: Incompatible override error in pyright
When subclassing
Tkand overridingreport_callback_exceptionwith the correct runtime signature, pyright reports an incompatible method override error.Code:
pyright output:
Issue 2: Missing error on invalid manual call
Conversely, pyright does not report an error when manually calling
Tk.report_callback_exceptionwith the wrong signature, even though the code fails at runtime.Code:
Runtime error:
pyright output:
Expected behavior
The type annotation should match the actual runtime signature as used in practice.
Additional context
srittau said in #1767 (comment):If that is indeed the case, I think we should revert the type annotation forreport_callback_exceptionand report the error to mypy instead, because the root cause is not here.The above statement is irrelevant to this issue.
mypy's error when assigning to a method is intentional, therefore #1767 is not an issue.