Description
Crash Report
A dataclass with a field that uses field(...)
call with **
crashes mypy. Find examples after the traceback.
Traceback
I checked on 0.920, main branch, and a few earlier versions, and got the same traceback:
my_file.py:36: 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.920+dev.bc1dc95486edf4f062a38eb7b78affb2268de39d
Traceback (most recent call last):
File "c:\tools\miniconda3\envs\datapackage\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\tools\miniconda3\envs\datapackage\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\tools\miniconda3\envs\datapackage\Scripts\mypy.exe\__main__.py", line 7, in <module>
sys.exit(console_entry())
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\__main__.py", line 11, in console_entry
main(None, sys.stdout, sys.stderr)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\main.py", line 87, in main
res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\main.py", line 165, in run_build
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\build.py", line 179, in build
result = _build(
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\build.py", line 254, in _build
graph = dispatch(sources, manager, stdout)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\build.py", line 2698, in dispatch
process_graph(graph, manager)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\build.py", line 3022, in process_graph
process_stale_scc(graph, scc, manager)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\build.py", line 3114, in process_stale_scc
mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal_main.py", line 78, in semantic_analysis_for_scc
process_top_levels(graph, scc, patches)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal_main.py", line 199, in process_top_levels
deferred, incomplete, progress = semantic_analyze_target(next_id, state,
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal_main.py", line 326, in semantic_analyze_target
analyzer.refresh_partial(refresh_node,
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 402, in refresh_partial
self.refresh_top_level(node)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 413, in refresh_top_level
self.accept(d)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 4919, in accept
node.accept(self)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\nodes.py", line 959, in accept
return visitor.visit_class_def(self)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 1068, in visit_class_def
self.analyze_class(defn)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 1146, in analyze_class
self.analyze_class_body_common(defn)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 1155, in analyze_class_body_common
self.apply_class_plugin_hooks(defn)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\semanal.py", line 1201, in apply_class_plugin_hooks
hook(ClassDefContext(defn, decorator, self))
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\plugins\dataclasses.py", line 384, in dataclass_class_maker_callback
transformer.transform()
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\plugins\dataclasses.py", line 103, in transform
attributes = self.collect_attributes()
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\plugins\dataclasses.py", line 254, in collect_attributes
has_field_call, field_args = _collect_field_args(stmt.rvalue)
File "c:\tools\miniconda3\envs\datapackage\lib\site-packages\mypy\plugins\dataclasses.py", line 400, in _collect_field_args
assert name is not None
AssertionError:
my_file.py:36: : note: use --pdb to drop into pdb```
To Reproduce
Minimal example should be this:
@dataclass
class Foo:
bar: float = field(**{"repr": False})
How it actually came about is the following: i'm having a dataclass where i want to use the metadata
argument of the field
functions to pass extra information about the unit of the field. For convenience, I did it with a helper function, which is where **
came from:
@dataclass
class Results:
voltage: float = field(**unit("mV"))
def unit(u: str) -> Dict[Dict[str, str]]
return {"metadata": {"unit": u}}
Your Environment
- Mypy version used: 0.920, main branch, and a few earlier versions
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini
(and other config files):
[mypy]
strict_optional = True
disallow_untyped_decorators = True
ignore_missing_imports = True
show_column_numbers = True
warn_unused_ignores = True
warn_unused_configs = True
warn_redundant_casts = True
- Python version used: 3.8.10
- Operating system and version: Windows 10
I think the issue is in
https://github.com/python/mypy/blob/f98f78216ba9d6ab68c8e69c19e9f3c7926c5efe/mypy/plugins/dataclasses.py#L387-403
In the case of field(**...)
call, the arguments exists but don't have a name
, hence the assertion fails. I tried to make a workaround locally and ignore the None
argument names, but then mypy
thinks that I'm not using field
in a type-approved way, however i do (right?), it's just more difficult (or impossible?) to statically type-check.
Perhaps, there is a simple way to assume that field(**..)
is equivalent to how Any
works, that would be great as a hotfix, if it takes more time for a proper solution to arrive.
I would've loved to initiate a PR but I am afraid I won't have time, so really relying on your help :)