dmypy Suggest assertion error in `node_type_from_base`
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Crash Report
Mypy Daemon crashed attempting to generate type suggestions for __reduce__ function in class with nonstandard __new__. (re-creating #15823)
Traceback
dmypy suggest crash.py:64: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.8.0
dmypy suggest crash.py: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.8.0
Daemon crashed!
Traceback (most recent call last):
File "mypy/dmypy_server.py", line 236, in serve
File "mypy/dmypy_server.py", line 285, in run_command
File "mypy/dmypy_server.py", line 972, in cmd_suggest
File "mypy/suggestions.py", line 267, in suggest
File "mypy/suggestions.py", line 502, in get_suggestion
File "mypy/suggestions.py", line 444, in find_best
File "mypy/suggestions.py", line 675, in try_type
File "mypy/server/update.py", line 314, in trigger
File "mypy/server/update.py", line 881, in propagate_changes_using_dependencies
File "mypy/server/update.py", line 1010, in reprocess_nodes
File "mypy/semanal_main.py", line 144, in semantic_analysis_for_targets
File "mypy/semanal_main.py", line 291, in process_top_level_function
File "mypy/semanal_main.py", line 349, in semantic_analyze_target
File "mypy/semanal.py", line 600, in refresh_partial
File "mypy/semanal.py", line 6541, in accept
File "mypy/errors.py", line 1261, in report_internal_error
File "mypy/semanal.py", line 6539, in accept
File "mypy/nodes.py", line 787, in accept
File "mypy/semanal.py", line 833, in visit_func_def
File "mypy/semanal.py", line 865, in analyze_func_def
File "mypy/typeanal.py", line 1031, in visit_callable_type
File "mypy/typeanal.py", line 1684, in anal_type
File "mypy/types.py", line 2400, in accept
File "mypy/typeanal.py", line 1133, in visit_tuple_type
File "mypy/typeanal.py", line 1659, in anal_array
File "mypy/typeanal.py", line 1684, in anal_type
File "mypy/types.py", line 1970, in accept
File "mypy/typeanal.py", line 980, in visit_callable_type
File "mypy/typeanal.py", line 1614, in bind_function_type_variables
AssertionError
To Reproduce
dmypy suggest crash.py:
from __future__ import annotations
from collections.abc import Iterable, Callable
from typing import TYPE_CHECKING, TypeVar, Any, cast
import sys
if sys.version_info < (3, 11):
from exceptiongroup import ExceptionGroup, BaseExceptionGroup
if TYPE_CHECKING:
from types import TracebackType
from typing_extensions import Self
NonBaseMultiError = ExceptionGroup
class MultiError(BaseExceptionGroup[BaseException]):
def __init__(
self, exceptions: list[BaseException], *, _collapse: bool = True
) -> None:
self.collapse = _collapse
# Avoid double initialization when _collapse is True and exceptions[0] returned
# by __new__() happens to be a MultiError and subsequently __init__() is called.
if _collapse and getattr(self, "exceptions", None) is not None:
# This exception was already initialized.
return
super().__init__("multiple tasks failed", exceptions)
def __new__(
cls, exceptions: Iterable[BaseException], *, _collapse: bool = True
) -> MultiError | NonBaseMultiError[Exception] | Self:
exceptions_union: list[BaseException | Exception] = list(exceptions)
for exc in exceptions_union:
if not isinstance(exc, BaseException):
raise TypeError(f"Expected an exception object, not {exc!r}")
class_sub: type[Self | NonBaseMultiError[Exception]] = cls
if _collapse and len(exceptions_union) == 1:
# If this lone object happens to itself be a MultiError, then
# Python will implicitly call our __init__ on it again. See
# special handling in __init__.
single = exceptions_union[0]
assert isinstance(single, MultiError)
return single
else:
# The base class __new__() implicitly invokes our __init__, which
# is what we want.
#
# In an earlier version of the code, we didn't define __init__ and
# simply set the `exceptions` attribute directly on the new object.
# However, linters expect attributes to be initialized in __init__.
if all(isinstance(exc, Exception) for exc in exceptions_union):
exceptions_arg_one = cast("list[Exception]", exceptions_union)
return super().__new__(
NonBaseMultiError, "multiple tasks failed", exceptions_arg_one
)
else:
exceptions_arg_two = cast("list[BaseException]", exceptions_union)
return super().__new__(cls, "multiple tasks failed", exceptions_arg_two)
def __reduce__(self):
return (
self.__new__,
(self.__class__, list(self.exceptions)),
{"collapse": self.collapse},
)
Run:
dmypy --status-file="<user path>/dmypy.json" run --timeout=1800 --log-file="<user path>/log.txt" --export-types "<user path>/dmypy suggest crash.py" -- --no-implicit-reexport --disallow-untyped-defs --show-error-codes --strict --warn-redundant-casts --cache-dir="<user path>" --show-error-end --no-color-output --no-error-summary --show-column-numbers --warn-unreachable --disallow-untyped-calls --warn-unused-ignores --cache-fine-grained --soft-error-limit=-1 --show-traceback --hide-error-context --show-absolute-path
dmypy --status-file="<user path>/dmypy.json" suggest "<user path>/dmypy suggest crash.py:65"
Your Environment
- Mypy version used: dmypy 1.8.0
- Mypy command-line flags: See above
- Mypy configuration options from
mypy.ini(and other config files): See above - Python version used: Python 3.12.0 (main, Oct 4 2023, 06:27:34) [GCC 13.2.0] on linux
- Operating system and version: 64 bit Linux Ubuntu Budgie 10.8 (Ubuntu 23.10) Linux 6.5.0-14-generic
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit der im Issue beschriebenen Reproduktion von dmypy suggest und verfolge dann den gemeldeten Aufrufpfad durch mypy/suggestions.py und mypy/typeanal.py, insbesondere bind_function_type_variables. Bestätige das Verhalten mit der bereitgestellten crash.py und ermittle, wie die Assertion während der Typanalyse erreicht wird. Erledigt ist die Aufgabe, wenn dmypy suggest diesen Fall ohne einen INTERNAL ERROR oder einen Absturz des Daemons verarbeitet.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- devtools
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Ruhig
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 55/100