mypy
mypy copied to clipboard
AttributeError: attribute '_fullname' of 'TypeInfo' undefined
Crash Report
I'm running mypy on my code but it fails with an INTERNAL ERROR.
Traceback
$ mypy src/mt_devops tests --show-traceback
src/mt_devops/cli/tasks/test.py:167: 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: 0.991
Traceback (most recent call last):
File "mypy/checkexpr.py", line 4665, in accept
File "mypy/nodes.py", line 2121, in accept
File "mypy/checkexpr.py", line 3903, in visit_list_expr
File "mypy/checkexpr.py", line 3944, in check_lst_expr
File "mypy/checkexpr.py", line 3934, in fast_container_type
File "mypy/join.py", line 674, in join_type_list
File "mypy/join.py", line 252, in join_types
File "mypy/types.py", line 1283, in accept
File "mypy/join.py", line 327, in visit_instance
File "mypy/join.py", line 104, in join_instances
File "mypy/subtypes.py", line 179, in is_subtype
File "mypy/subtypes.py", line 329, in _is_subtype
File "mypy/types.py", line 1283, in accept
File "mypy/subtypes.py", line 466, in visit_instance
File "mypy/nodes.py", line 2898, in fullname
AttributeError: attribute '_fullname' of 'TypeInfo' undefined
src/mt_devops/cli/tasks/test.py:167: : note: use --pdb to drop into pd
To Reproduce
I run mypy again.
Please note if I delete the .mypy_cache the problem goes away. But some time later it comes back.
The code of the current module is
"""Module of test tasks to check CODE QUALITY.
"""
import pathlib
from typing import Optional, Union
from invoke import task
from ...api.shared import FILES, PACKAGE_FOLDER, run_in_context
from . import autoformat
from . import docs as _docs
TEST_FOLDERS = "tests"
TEST_RESULTS_FOLDER = "test_results"
ON_LAPTOP = not pathlib.Path("/home/jovyan/shared").exists()
def _create_test_results_folder(
cwd: Optional[Union[str, pathlib.Path]] = None, name=TEST_RESULTS_FOLDER
):
"""Creates a subfolder with the specific name in the cwd folder"""
if not cwd:
cwd = pathlib.Path.cwd()
else:
cwd = pathlib.Path(cwd)
pathlib.Path(cwd / name).mkdir(exist_ok=True)
@task(name="bandit")
def _bandit(context, report=False):
"""Runs Bandit the security linter from PyCQA.
Args:
report (bool, optional): If True an xml report will be created. Defaults to False.
"""
print(
"""
Running Bandit the Python Security Linter
to identify common security issues in Python code
=================================================
"""
)
command = "bandit -r ./ -c pyproject.toml --severity-level=medium"
if report:
command += " -f xml -o test_results/bandit-results.xml"
run_in_context(command=command, context=context)
@task(name="pytest")
def _pytest(
context,
test_files=TEST_FOLDERS,
fast=False,
test_results=False,
show_test_results=False,
report=False,
):
"""Runs pytest to identify failing tests
Keyword Arguments:
root_dir {str} -- The directory from which to run the tests
test_files {str} -- A space separated list of folders and files to test. (default: {'tests})
fast {bool} -- If True tests marked slow will not be
run. (default: False)
test_results {bool} -- If True test reports will be generated in the test_results
folder. (default: False)
show_test_results {bool} -- If True test results will be generated in the test_results
folder and opened in a browser. (default: False)
report (bool, optional): If True an xml report will be created. Defaults to False.
"""
print(
"""
Running pytest the test framework
=================================
"""
)
# Build the command_string
command = f"pytest {test_files}"
if fast:
command += ' -m "not slow"'
if test_results or show_test_results:
_create_test_results_folder()
command += f" --cov=src --cov-report html:{TEST_RESULTS_FOLDER}/cov_html"
if report:
command += (
""" -m "not skip_in_azure_pipelines" """
"--junitxml=test_results/pytest-results.xml "
f"--cov={PACKAGE_FOLDER} --cov-report xml:test_results/coverage.xml"
""
)
# Run the command_string
run_in_context(command=command, context=context)
# Open the test coverage report in a browser
if show_test_results:
command = "start test_results/cov_html/index.html"
run_in_context(command=command, context=context)
@task(name="pylint")
def _pylint(context, files=FILES, report=False):
"""Runs pylint (linter) on all .py files recursively to identify coding errors
Arguments:
files {string} -- A space separated list of files and folders to lint
report (bool, optional): If True an xml report will be created. Defaults to False.
"""
# https://stackoverflow.com/questions/22241435/pylint-discard-cached-file-state
# from astroid import MANAGER
# MANAGER.astroid_cache.clear()
print(
"""
Running pylint.
Pylint looks for programming errors, helps enforcing a coding standard,
sniffs for code smells and offers simple refactoring suggestions.
=======================================================================
"""
)
command = f"pylint {files} -f text"
if report:
_create_test_results_folder()
command += (
" --output-format=pylint2junit.JunitReporter 2>&1 > test_results/pylint-results.xml"
)
run_in_context(command=command, context=context)
@task(name="mypy")
def _mypy(context, files=FILES, report=False):
"""Runs mypy (static type checker) on all .py files recursively
Arguments:
files {string} -- A space separated list of files and folders to lint
report (bool, optional): If True an xml report will be created. Defaults to False.
"""
print(
"""
Running mypy for identifying python type errors
===============================================
"""
)
command = f"mypy {files}"
if report:
_create_test_results_folder()
command += " --junit-xml test_results/mypy-results.xml"
run_in_context(command=command, context=context)
@task(pre=[_docs.build])
def docs(context):
"""Checks for broken internal and external links and runs the doc8 .rst linter to identify
problems.
Runs
- the Sphinx 'dummy' builder to identify internal problems.
- the Sphinx 'linkcheck' build to identify broken external links.
- doc8 linter to identify .rst syntax errors
"""
_docs._test(context) # pylint: disable=protected-access
@task(
pre=[autoformat._all, _pylint, _mypy, _bandit, docs], # pylint: disable=protected-access
name="all",
)
def _all(context, fast=False, test_results=True, show_test_results=True):
"""Runs all tests, i.e. isort, autoflake, black, pylint, mypy, pytest and bandit
Arguments:
fast {bool} -- If True tests marked slow will not be
run. (default: False)
test_results {bool} -- If True test reports will be generated in the test_results
folder. (default: False)
show_test_results {bool} -- If True test results will be generated in the test_results
folder and opened in a browser. (default: False)
"""
show_test_results = show_test_results and ON_LAPTOP
_pytest(context, fast=fast, test_results=test_results, show_test_results=show_test_results)
# If we get to this point all tests listed in 'pre' have passed
# unless we have run the task with the --warn flag
if not context.config.run.warn:
print(
"""
All Tests Passed Successfully
=============================
"""
)
Your Environment
- Mypy version used: 0.991
- Mypy command-line flags:
mypy src/mt_devops tests --show-traceback - Mypy configuration options from
pyproject.toml:
[tool.mypy]
python_version = "3.9"
namespace_packages = true
explicit_package_bases = true
mypy_path = "src"
exclude = ["src/mt_devops/templates"]
[[tool.mypy.overrides]]
module = [
"cookiecutter.main",
"pyparsing",
]
ignore_missing_imports = true
- Python version used: 3.10.6
- Operating system and version: Ubuntu 22.04.1 LTS
I'm not able to reproduce from the file you've shared. The expected directory structure was a little confusing to me too, so possibly I messed that up. Maybe you could provide a link to a git repo (or possible a script that constructs the directory structure you expect)?