Description
Crash Report
See the traceback.
Traceback
Traceback (most recent call last):
File "D:\dro\bin\WPy64-31090\python-3.10.9.amd64\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "D:\dro\bin\WPy64-31090\python-3.10.9.amd64\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "D:\dro\bin\WPy64-31090\python-3.10.9.amd64\scripts\mypy.exe\__main__.py", line 7, in <module>
File "D:\dro\bin\WPy64-31090\python-3.10.9.amd64\lib\site-packages\mypy\__main__.py", line 15, in console_entry
main()
File "mypy\main.py", line 95, in main
File "mypy\main.py", line 174, in run_build
File "mypy\build.py", line 194, in build
File "mypy\build.py", line 277, in _build
File "mypy\build.py", line 2923, in dispatch
File "mypy\build.py", line 3320, in process_graph
File "mypy\build.py", line 3415, in process_stale_scc
File "mypy\semanal_main.py", line 99, in semantic_analysis_for_scc
File "mypy\semanal_main.py", line 429, in apply_class_plugin_hooks
AssertionError: Internal error: too many class plugin hook passes
To Reproduce
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
from __future__ import annotations
from dataclasses import asdict, dataclass, field
from decimal import Context, Decimal, Inexact
from typing import ClassVar, Protocol
DecimalPlus = Decimal | str | int | float
@dataclass
class TargetSettings(Protocol):
max: DecimalPlus
min: DecimalPlus
inc: DecimalPlus
precision: int
PLACES: Decimal = field(init=False, repr=False)
INEXACT: ClassVar[Context] = Context(traps=[Inexact])
def __post_init__(self) -> None:
self.PLACES = PLACES = Decimal(10) ** -self.precision
self.min = Decimal(self.min).quantize(PLACES)
self.max = Decimal(self.max).quantize(PLACES)
self.inc = Decimal(self.inc).quantize(PLACES)
def is_valid(self, val: DecimalPlus) -> bool:
try:
val = Decimal(val).quantize(self.PLACES, context=self.INEXACT)
except Inexact:
return False # more decimal places than allowed
# mypy does not know attributes are Decimals at this stage
if not (self.min <= val <= self.max): # type: ignore
return False
return True # all checks passed
Your Environment
- Mypy version used: 1.1.1
- Mypy command-line flags:
None
- Mypy configuration options from
mypy.ini
(and other config files):None
- Python version used:
3.10.9
- Operating system and version:
Windows 11 22621.1413
Additional Comment
Let me say that I do believe that the concept of static type checking of Union
is broken (again: the concept). In my very humble opinion as user, if I do declare something as a Union
(either with the keyword or the |
operator), mypy
must believe that when the time comes, the variable/attribute declared as a Union, will contain one of the types.
Reporting errors like
error: Unsupported operand types for <= ("Decimal" and "str") [operator]
when the Union
contains Union[Decimal, str, int, float]
is in my very humble opinion: wrong. Such an error can be reported during runtime, but not during static analysis, because mypy
has no way of knowing what the type at that stage contains. Reporting a "warning" would be ok. Reporting an "error" is an error itself.
No, as a user I am not in the mood of adding cast
here and there and here-there to pollute the code, hence the need to add a # type: ignore
to silence mypy
.