KEMBAR78
dataclass inheritance: deeply nested InitVar overrides crash mypy · Issue #8207 · python/mypy · GitHub
Skip to content

dataclass inheritance: deeply nested InitVar overrides crash mypy #8207

@beckjake

Description

@beckjake

This is related to the fix I provided in #8159 - That fix works as long as you don't inherit from the final subclass created there and set init=False on the inheritor.

The issue is that when an InitVar is found in a parent class but isn't present in that parent's __init__ method, mypy should to keep walking the MRO to find the parent's parent (etc...) until it finds the actual definition to add to info before it adds the attribute to the set of known_attrs. Currently it adds the attribute to known_attrs even if it wasn't added to info, which results in an assertion error.

I believe I have a fix for this, I'll open a PR with my fix (and a new test!)

Please provide more information to help us understand the issue:

  • Are you reporting a bug, or opening a feature request?
    bug

  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.

from dataclasses import dataclass, field, InitVar
@dataclass
class A:
    a: InitVar[bool]
    _a: bool = field(init=False)

    def __post_init__(self, a: bool):
        self._a = a

@dataclass(init=False)
class B(A):
    def __init__(self):
        super().__init__(True)

@dataclass(init=False)
class C(B):
    pass
  • What is the actual behavior/output?
    Mypy crashes

  • What is the behavior/output you expect?
    Mypy should not crash (and this should pass type checking)

  • What are the versions of mypy and Python you are using?
    Do you see the same issue after installing mypy from Git master?
    Python 3.6.5
    This is on the current git master of mypy (9101707)

  • What are the mypy flags you are using? (For example --strict-optional)
    None required

  • If mypy crashed with a traceback, please paste
    the full traceback below.

crash_mypy.py:16: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.rtfd.io/en/latest/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.770+dev.c6ebe764da96ec6671c3549f7f513237616898dd
Traceback (most recent call last):
  File "/Users/jake/.pyenv/versions/dbt36/bin/mypy", line 11, in <module>
    load_entry_point('mypy', 'console_scripts', 'mypy')()
  File "/Users/jake/src/fishtown/mypy/mypy/__main__.py", line 8, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "/Users/jake/src/fishtown/mypy/mypy/main.py", line 89, in main
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/Users/jake/src/fishtown/mypy/mypy/build.py", line 167, in build
    sources, options, alt_lib_path, flush_errors, fscache, stdout, stderr, extra_plugins
  File "/Users/jake/src/fishtown/mypy/mypy/build.py", line 235, in _build
    graph = dispatch(sources, manager, stdout)
  File "/Users/jake/src/fishtown/mypy/mypy/build.py", line 2611, in dispatch
    process_graph(graph, manager)
  File "/Users/jake/src/fishtown/mypy/mypy/build.py", line 2918, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/jake/src/fishtown/mypy/mypy/build.py", line 3011, in process_stale_scc
    mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal_main.py", line 77, in semantic_analysis_for_scc
    process_top_levels(graph, scc, patches)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal_main.py", line 202, in process_top_levels
    patches)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal_main.py", line 330, in semantic_analyze_target
    active_type=active_type)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 378, in refresh_partial
    self.refresh_top_level(node)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 389, in refresh_top_level
    self.accept(d)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 4695, in accept
    node.accept(self)
  File "/Users/jake/src/fishtown/mypy/mypy/nodes.py", line 939, in accept
    return visitor.visit_class_def(self)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 1029, in visit_class_def
    self.analyze_class(defn)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 1106, in analyze_class
    self.analyze_class_body_common(defn)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 1115, in analyze_class_body_common
    self.apply_class_plugin_hooks(defn)
  File "/Users/jake/src/fishtown/mypy/mypy/semanal.py", line 1161, in apply_class_plugin_hooks
    hook(ClassDefContext(defn, decorator, self))
  File "/Users/jake/src/fishtown/mypy/mypy/plugins/dataclasses.py", line 383, in dataclass_class_maker_callback
    transformer.transform()
  File "/Users/jake/src/fishtown/mypy/mypy/plugins/dataclasses.py", line 87, in transform
    assert attr.is_init_var and not attr.is_in_init

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions