Repository: python/mypy
Pull request: Fix crash involving explicit any flag and Required
### Description

Fixes #12038. This adds an accept method to Required that delegates to the inner type. @davidfstr 

## Test Plan

I ran the tests locally and they passed. I added two small test cases to check-typeddict.test that correspond to fixed crash.

Problem statement:
Explicit Any Crashes With Required for Functional TypedDict
**Crash Report**

Required does not define accept as a Type so when check_for_explicit_any runs it crashes with an error of not implement. Reproducing code example,

```python
from typing import TypedDict

from typing_extensions import Required

Foo = TypedDict("Foo", {"a.x": Required[int]})
```
run with mypy --disallow-any-explicit.

Strangely class form of typeddict works. Only functional form fails. I need functional form for one usage due to some of the keys being invalid variable names.

**Traceback**

```
version: 0.931
Traceback (most recent call last):
  File "mypy/semanal.py", line 5142, in accept
  File "mypy/nodes.py", line 1140, in accept
  File "mypy/semanal.py", line 2090, in visit_assignment_stmt
  File "mypy/semanal.py", line 2336, in analyze_typeddict_assign
  File "mypy/semanal_typeddict.py", line 224, in check_typeddict
  File "mypy/semanal_typeddict.py", line 305, in parse_typeddict_args
  File "mypy/typeanal.py", line 1313, in check_for_explicit_any
  File "mypy/typeanal.py", line 1321, in has_explicit_any
  File "mypy/types.py", line 155, in accept
RuntimeError: Not implemented
```


**Your Environment**

mypy 0.931 and mypy master both crash in same way. I'm using python 3.8.

I'll make a small pr to fix this. The fix looks small and hopefully I can just have accept be run on the inner type.

Hints from issue discussion:

Commit message: fix unit test.

Patch to review:
diff --git a/mypy/types.py b/mypy/types.py
index d3987897995e..1d7ab669a2d4 100644
--- a/mypy/types.py
+++ b/mypy/types.py
@@ -360,6 +360,9 @@ def __repr__(self) -> str:
         else:
             return "NotRequired[{}]".format(self.item)
 
+    def accept(self, visitor: 'TypeVisitor[T]') -> T:
+        return self.item.accept(visitor)
+
 
 class ProperType(Type):
     """Not a type alias.
diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test
index 921d2ab5c46e..a9321826b3ba 100644
--- a/test-data/unit/check-typeddict.test
+++ b/test-data/unit/check-typeddict.test
@@ -2208,6 +2208,12 @@ class Movie(TypedDict, total=False):
     year: int
 [typing fixtures/typing-typeddict.pyi]
 
+[case testRequiredExplicitAny]
+# flags: --disallow-any-explicit
+from typing import TypedDict
+from typing import Required
+Foo = TypedDict("Foo", {"a.x": Required[int]})
+[typing fixtures/typing-typeddict.pyi]
 
 -- NotRequired[]
 
@@ -2271,6 +2277,13 @@ class Movie(TypedDict):
     year: int
 [typing fixtures/typing-typeddict.pyi]
 
+[case testNotRequiredExplicitAny]
+# flags: --disallow-any-explicit
+from typing import TypedDict
+from typing import NotRequired
+Foo = TypedDict("Foo", {"a.x": NotRequired[int]})
+[typing fixtures/typing-typeddict.pyi]
+
 -- Union dunders
 
 [case testTypedDictUnionGetItem]
diff --git a/test-data/unit/fixtures/typing-typeddict.pyi b/test-data/unit/fixtures/typing-typeddict.pyi
index 72f500707094..5c509bd82c66 100644
--- a/test-data/unit/fixtures/typing-typeddict.pyi
+++ b/test-data/unit/fixtures/typing-typeddict.pyi
@@ -43,7 +43,7 @@ class Iterator(Iterable[T_co], Protocol):
     def __next__(self) -> T_co: pass
 
 class Sequence(Iterable[T_co]):
-    def __getitem__(self, n: Any) -> T_co: pass
+    def __getitem__(self, n: Any) -> T_co: pass # type: ignore
 
 class Mapping(Iterable[T], Generic[T, T_co], metaclass=ABCMeta):
     def __getitem__(self, key: T) -> T_co: pass


Code review comments:
diff_hunk: @@ -43,7 +43,7 @@ class Iterator(Iterable[T_co], Protocol):
     def __next__(self) -> T_co: pass
 
 class Sequence(Iterable[T_co]):
-    def __getitem__(self, n: Any) -> T_co: pass
+    def __getitem__(self, n: Any) -> T_co: pass # type: ignore
path: test-data/unit/fixtures/typing-typeddict.pyi
text: @user1:
Why is this `# type ignore`d? Perhaps leave a note for future viewers?

@author:
It has an Any and my new test case checks for explicit Any with typeddict stubs. Alternatively I could add silent import flag to the test case.

@user1:
What you now makes sense then, I suppose putting a specific code on the `type: ignore` (like, if you run with `--show-error-codes` it will tell you what code to put) would be appreciated. But I don't know if that's the style tests normally take so...

@user2:
> I suppose putting a specific code on the type: ignore [...] would be appreciated

+1

@author:
I've added the error code. The code is vague [misc] so I included a comment too on which error it was.