-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Internal error on processing NamedTuple with method and recursive field #8695
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
Comments
I just ran into this, and reduced it to an amusingly identical test case, except for the fact that this also happens with a from __future__ import annotations
from typing import NamedTuple
class ScopeName(NamedTuple):
def somefun(self):
pass
class Scope(NamedTuple):
children: Scope # type: ignore Presumably with this marker mypy is still checking the type and just silencing the warnings. It looks like the only way to avoid this is to remove the annotation completely? Checked on master (781dd69) python 3.7/3.8. |
This may be causing downstream bugs in the django-stubs project, as well, since the django-stubs Mypy plugin crashes when I use |
This might be classed as "not a bug" or a low priority bug by the MyPy due to the impossibility of instantiating the example (i.e. if the recursive attribute of Second is always an instance of Second, you can never actually instantiate Second correctly - you need to have another case to be able to terminate the chain of Second's). However, there does appear to be a bug in the cycle detector because if we change the recursive attribute to be Optional (to make it possible to instantiate), we have the following odd behaviour: from __future__ import annotations
from typing import NamedTuple, Optional
class First(NamedTuple):
def method(self): ...
class Second(NamedTuple):
recursive: Optional[Second] Causes MyPy to crash with "mypy-sample-4.py: error: INTERNAL ERROR: maximum semantic analysis iteration count reached" from __future__ import annotations
from typing import NamedTuple, Optional
class Second(NamedTuple):
recursive: Optional[Second] Causes MyPy to fail with "mypy-sample-4.py:8: error: Cannot resolve name "Second" (possible cyclic definition)". So that means if you have a NamedTuple with a method, it changes the behaviour of the cycle detector on a different, unrelated NamedTuple - that certainly seems wrong! Note that I'd argue both of these behaviours are wrong as a frozen dataclass will handle this just fine (see other issue mentioned above for that bug) |
I have the exact same issue. from typing import Tuple, NamedTuple
class Tree(NamedTuple):
children: Tuple['Tree', ...] = () # type: ignore
class ClassThatDoesSomething(NamedTuple):
def do_something(self) -> None:
return None Took me a while to isolate this... It used to work in earlier versions (don't know exactly when it broke). It's a bit frustrating because we (my team and I) have a huge project that used to be ok, but now fails to be checked by mypy. |
The OP's example still fails on 0.942. Output:
Interestingly it doesn't crash when the |
The original example works on master with |
More specifically, our version of mypy has a known issue regarding processing the type hints for subclasses of NamedTuples which reference themselves. i.e., using the "DeferredScopeUploadTable" type hint in the DeferredScopeUploadTable class For more details, see python/mypy#8695
Checking following code with mypy results in
INTERNAL ERROR: maximum semantic analysis iteration count reached
along withDeferral trace
cycling with lines 7, 7 and -1As far as I've debugged mypy code I think it is caused by
analyze_class_body_common
being called undersave_namedtuple_body
contextmanager which sets empty SymbolTable for class.Then
analyze_class_body_common
processes methods defined in class body, method definition is processed throughSemanticAnalyzer.visit_func_def
which callsadd_function_to_symbol_table
.Ultimately
add_symbol_table_node
upon not seeing that method was already handled (because we've cleared SymbolTable), setsSemanticAnalyzer#progress = True
on every analysis iteration, preventingprocess_top_levels
from settingfinal_iteration
which breaks analysis cycleThe text was updated successfully, but these errors were encountered: