python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.32k stars 2.81k forks source link

Mypy 1.11.0 crashes on typing.NotRequired with `--html-report` #17604

Closed sanderr closed 2 months ago

sanderr commented 2 months ago

Crash Report

Mypy crashes on a Python file that makes use of typing.NotRequired when used with the --html-report option.

Traceback

To Reproduce

I took an example from the typing docs on TypedDict:

from typing import NotRequired, TypedDict

class Point2D(TypedDict):
    x: int
    y: int
    label: NotRequired[str]

Running mypy on it with --html-report causes a crash:

(sandbox-312) sander@bedevere:~/documents/projects/python-sandbox$ mypy --html-report mypy --show-traceback reproduce.py
reproduce.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.11.0
Traceback (most recent call last):
  File "/home/sander/.virtualenvs/sandbox-312/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "mypy/build.py", line 2069, in wrap_context
TypeError: mypy.types.ProperType object expected; got mypy.types.RequiredType
reproduce.py: : note: use --pdb to drop into pdb
Generated HTML report (via XSLT): /home/sander/documents/projects/python-sandbox/mypy/index.html
(sandbox-312) sander@bedevere:~/documents/projects/python-sandbox$ cat mypy/index.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="mypy-html.css">
</head>
<body>
<h1>Mypy Type Check Coverage Summary</h1>
<table class="summary">
<caption>Summary from index</caption>
<thead><tr class="summary">
<th class="summary">File</th>
<th class="summary">Imprecision</th>
<th class="summary">Lines</th>
</tr></thead>
<tfoot><tr class="summary summary-quality-0">
<th class="summary summary-filename">Total</th>
<th class="summary summary-precision">0.00% imprecise</th>
<th class="summary summary-lines">0 LOC</th>
</tr></tfoot>
<tbody></tbody>
</table>
</body>
</html>
(sandbox-312) sander@bedevere:~/documents/projects/python-sandbox$ mypy --version
mypy 1.11.0 (compiled: yes)

When I change the NotRequired[str] to plain str, mypy succeeds. The issue also doesn't occur without the --html-report option.

I failed to reproduce the issue from a source installation, even from a checked out v1.11.0 tag. But I get it consistently with the 1.11.0 version published to PyPi.

Your Environment

nernst commented 2 months ago

I've hit a very similar crash in 1.11 involving Required/NotRequired in a TypedDict as well. In my case, html report is not required:

from typing import NotRequired, Required, TypedDict
from bson.objectid import ObjectId  # type: ignore

class Data(TypedDict, total=False):
    _id: Required[ObjectId]  # or NotRequired, either crashes
    appId: str

I have the type ignore because I don't have stubs for bson. If I remove the import of ObjectId and change the type on _id to be str, the code analyses fine. Traceback looks a little more interesting in my case:

mypy-repro.py:8: 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.11.0
Traceback (most recent call last):
  File "mypy/checker.py", line 591, in accept
  File "mypy/nodes.py", line 1351, in accept
  File "mypy/checker.py", line 2948, in visit_assignment_stmt
  File "mypy/messages.py", line 1768, in unimported_type_becomes_any
  File "mypy/messages.py", line 2805, in format_type
  File "mypy/messages.py", line 2822, in format_type_bare
  File "mypy/messages.py", line 2540, in format_type_inner
  File "mypy/types.py", line 3111, in get_proper_type
TypeError: mypy.types.ProperType object expected; got mypy.types.RequiredType
mypy-repro.py:8: : note: use --pdb to drop into pdb
JelleZijlstra commented 2 months ago

@nernst could you report a separate bug and leave this one limited to the html-report issue?

andersk commented 2 months ago

git bisect says this was introduced by e5b3b563ea3f6d1f83d0fe3552965c8b05ea4c3d (Fix daemon crash on invalid type in TypedDict, #17495).

Note that to reproduce without mypyc, you need to manually insert this assertion that would be enforced automatically by mypyc:

--- a/mypy/types.py
+++ b/mypy/types.py
@@ -3108,7 +3108,8 @@ def get_proper_type(typ: Type | None) -> ProperType | None:
     while isinstance(typ, TypeAliasType):
         typ = typ._expand_once()
     # TODO: store the name of original type alias on this type, so we can show it in errors.
-    return cast(ProperType, typ)
+    assert isinstance(typ, ProperType)
+    return typ

 @overload

(So far this seems similar to @nernst’s #17608.)