Description
I've encountered something really weird which is quite close to all issues related to AttributeError: attribute '_fullname' of 'TypeInfo' undefined
but where I could reproduce the bug.
More precisely, the following crashes
from typing import Generic, TypeVar
NT = TypeVar('NT', int, float)
class Foo(Generic[NT]):
def bar(self) -> None:
p, q = 1, 2.0 # type: (int, float)
with a "AttributeError: attribute '_fullname' of 'TypeInfo' undefined". Obviously, the following succeeds:
from typing import Generic, TypeVar
NT = TypeVar('NT', int, float)
class Foo(Generic[NT]):
def bar(self) -> None:
p, q = 1, 2.0 # no type comment
So I thought that the issue was because of the type comment. However (!), I was surprised to see that the following also doesn't crash:
from typing import Generic, TypeVar
NT = TypeVar('NT', bound=int) # here I have a bound and not a constraint !
class Foo(Generic[NT]):
def bar(self) -> None:
p, q = 1, 2.0 # type: (int, float)
Or even the following is fine:
from typing import Generic, TypeVar
NT = TypeVar('NT', int, float) # here I have a constraint
class Foo(Generic[NT]):
def bar(self) -> None:
# but here I only have a single annotated object and not two on the same line
p = 1 # type: int
Now, we could have thought that the issue stems from "constrained TypeVar
" + "type comment with more than 2 objects". But actually, it's not entirely the case because the following actually works (!!):
from typing import Generic, TypeVar
NT = TypeVar('NT', int, float)
class Foo(Generic[NT]):
p, q = 1, 2.0 # type: (int, float)
Also, if I do not inherit from Generic
, then the original bug disappears. So I think the issue stems from the fact that I inherit from Generic
, uses a constrainted TypeVar
(although I don't understand why the type comment outside a method wouldn't produce a bug as well) and a type comment for two objects (note that this is allowed according to PEP 484).
Full traceback
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "mypy/checker.py", line 591, in accept
File "mypy/nodes.py", line 785, in accept
File "mypy/checker.py", line 1000, in visit_func_def
File "mypy/checker.py", line 1004, in _visit_func_def
File "mypy/checker.py", line 1077, in check_func_item
File "mypy/checker.py", line 1104, in check_func_def
File "mypy/checker.py", line 1867, in expand_typevars
File "mypy/checker.py", line 7628, in expand_func
File "mypy/treetransform.py", line 696, in node
File "mypy/nodes.py", line 785, in accept
File "mypy/treetransform.py", line 194, in visit_func_def
File "mypy/treetransform.py", line 735, in block
File "mypy/treetransform.py", line 279, in visit_block
File "mypy/treetransform.py", line 746, in statements
File "mypy/treetransform.py", line 713, in stmt
File "mypy/nodes.py", line 1402, in accept
File "mypy/treetransform.py", line 344, in visit_for_stmt
File "mypy/treetransform.py", line 777, in optional_type
File "mypy/checker.py", line 7639, in type
File "mypy/expandtype.py", line 71, in expand_type
File "mypy/types.py", line 2394, in accept
File "mypy/expandtype.py", line 413, in visit_tuple_type
File "mypy/types.py", line 1429, in accept
File "mypy/expandtype.py", line 215, in visit_instance
File "mypy/nodes.py", line 3099, in fullname
AttributeError: attribute '_fullname' of 'TypeInfo' undefined
Environment
Platform: linux; (Linux-5.3.18-lp152.106-default-x86_64-with-glibc2.26)
Python version: 3.11.6 (main, Nov 29 2023, 14:46:32) [GCC 7.5.0])
Python implementation: CPython
MyPy version: 1.7.1 (compiled: yes)
Command: python3.11 -m mypy -c "$code" --no-incremental
Here "$code" is a string containing any of the above programs, e.g.,
$ read -r -d '' code <<EOF
from typing import Generic, TypeVar
NT = TypeVar('NT', int, float)
class Foo(Generic[NT]):
def bar(self) -> None:
p, q = 1, 2.0 # type: (int, float)
EOF
$ python3.11 -m mypy -c "$code" --no-incremental --show-traceback
Traceback (most recent call last):
...
AttributeError: attribute '_fullname' of 'TypeInfo' undefined