Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssertionError when analyzing recursive TypedDict #3674

Closed
ilinum opened this issue Jul 7, 2017 · 2 comments · Fixed by #3952
Closed

AssertionError when analyzing recursive TypedDict #3674

ilinum opened this issue Jul 7, 2017 · 2 comments · Fixed by #3952

Comments

@ilinum
Copy link
Collaborator

ilinum commented Jul 7, 2017

$ cat n.py 
from mypy_extensions import TypedDict

class MovieBase(TypedDict):
    name: str
    year: int

class Movie(MovieBase):
    director: 'Movie'
$ mypy n.py 
Traceback (most recent call last):
  File "/usr/local/bin/mypy", line 11, in <module>
    load_entry_point('mypy===0.520-dev-6c61c66641d46682e24341e624d4a8fd6ac32e11', 'console_scripts', 'mypy')()
  File "/usr/local/lib/python3.6/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/usr/local/lib/python3.6/site-packages/mypy/main.py", line 50, in main
    res = type_check_only(sources, bin_dir, options)
  File "/usr/local/lib/python3.6/site-packages/mypy/main.py", line 97, in type_check_only
    options=options)
  File "/usr/local/lib/python3.6/site-packages/mypy/build.py", line 196, in build
    graph = dispatch(sources, manager)
  File "/usr/local/lib/python3.6/site-packages/mypy/build.py", line 1769, in dispatch
    process_graph(graph, manager)
  File "/usr/local/lib/python3.6/site-packages/mypy/build.py", line 2012, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/usr/local/lib/python3.6/site-packages/mypy/build.py", line 2113, in process_stale_scc
    graph[id].semantic_analysis_apply_patches()
  File "/usr/local/lib/python3.6/site-packages/mypy/build.py", line 1675, in semantic_analysis_apply_patches
    patch_func()
  File "/usr/local/lib/python3.6/site-packages/mypy/semanal.py", line 2468, in patch
    fallback.args[1] = join.join_type_list(types)
  File "/usr/local/lib/python3.6/site-packages/mypy/join.py", line 392, in join_type_list
    joined = join_types(joined, t)
  File "/usr/local/lib/python3.6/site-packages/mypy/join.py", line 88, in join_types
    return t.accept(TypeJoinVisitor(s))
  File "/usr/local/lib/python3.6/site-packages/mypy/types.py", line 427, in accept
    return visitor.visit_instance(self)
  File "/usr/local/lib/python3.6/site-packages/mypy/join.py", line 141, in visit_instance
    return join_instances(t, self.s)
  File "/usr/local/lib/python3.6/site-packages/mypy/join.py", line 299, in join_instances
    return join_instances_via_supertype(s, t)
  File "/usr/local/lib/python3.6/site-packages/mypy/join.py", line 318, in join_instances_via_supertype
    assert best is not None
AssertionError
@ilinum
Copy link
Collaborator Author

ilinum commented Jul 7, 2017

Actually, it doesn't have to be a recursive definition, just a nested TypedDict.

The following code causes the same crash:

from mypy_extensions import TypedDict


class A(TypedDict):
    name: 'B'
    year: int


class B(TypedDict):
    director: str

@ilevkivskyi
Copy link
Member

ilevkivskyi commented Jul 7, 2017

I think this is closely related to (almost a duplicate of) #3340 modulo NamedTuple -> TypedDict. The recent PR #3560 added the necessary infrastructure, so that this will be easier to fix now.

@JukkaL JukkaL self-assigned this Jul 10, 2017
@JukkaL JukkaL removed their assignment Sep 18, 2017
JukkaL pushed a commit that referenced this issue Sep 27, 2017
Forward references didn't work with anything apart from classes, for example 
this didn't work:

```
x: A
A = NamedTuple('A', [('x', int)])
```

The same situation was with `TypedDict`, `NewType`, and type aliases. The 
root problem is that these synthetic types are neither detected in first pass, 
nor fixed in third pass. In certain cases this can lead to crashes (first six issues 
below are various crash scenarios). This fixes these crashes by applying some 
additional patches after third pass.

Here is the summary of the PR:

* New simple wrapper type `ForwardRef` with only one field `link` is introduced 
  (with updates to type visitors)
* When an unknown type is found in second pass, the corresponding 
  `UnboundType` is wrapped in `ForwardRef`, it is given a "second chance" in 
  third pass.
* After third pass I record the "suspicious" nodes, where forward references and 
  synthetic types have been encountered and append patches (callbacks) to fix 
  them after third pass. Patches use the new visitor `TypeReplacer` (which is the 
  core of this PR).

Fixes #3340
Fixes #3419
Fixes #3674
Fixes #3685
Fixes #3799
Fixes #3836
Fixes #3881
Fixes #867
Fixes #2241
Fixes #2399
Fixes #1701
Fixes #3016
Fixes #3054
Fixes #2762
Fixes #3575
Fixes #3990
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants