Skip to content

Crash when overriding partially typed attribute with partially typed property #11686

Closed
@jakelishman

Description

@jakelishman

Crash Report

I've been seeing mypy crashes with the released 0.910 and the current state of the dev branch. It appears to occur when a child class overrides a partially type instance attribute in its parent with a property that's also partially typed, but it also seems to matter that there's a second property in the parent that has at least a setter method.

I've cut it down as far as I could to the reproducer below the traceback.

Traceback

partial_list.py:15: 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.01e6aba30c787c664ac88d849b45f7d303316951
Traceback (most recent call last):
  File "/Users/jake/.miniconda3/envs/tmp/bin/mypy", line 33, in <module>
    sys.exit(load_entry_point('mypy', 'console_scripts', 'mypy')())
  File "/Users/jake/code/mypy/mypy/__main__.py", line 12, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "/Users/jake/code/mypy/mypy/main.py", line 96, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "/Users/jake/code/mypy/mypy/main.py", line 173, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/Users/jake/code/mypy/mypy/build.py", line 180, in build
    result = _build(
  File "/Users/jake/code/mypy/mypy/build.py", line 256, in _build
    graph = dispatch(sources, manager, stdout)
  File "/Users/jake/code/mypy/mypy/build.py", line 2715, in dispatch
    process_graph(graph, manager)
  File "/Users/jake/code/mypy/mypy/build.py", line 3046, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/jake/code/mypy/mypy/build.py", line 3144, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/Users/jake/code/mypy/mypy/build.py", line 2180, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/Users/jake/code/mypy/mypy/checker.py", line 319, in check_first_pass
    self.accept(d)
  File "/Users/jake/code/mypy/mypy/checker.py", line 425, in accept
    stmt.accept(self)
  File "/Users/jake/code/mypy/mypy/nodes.py", line 1000, in accept
    return visitor.visit_class_def(self)
  File "/Users/jake/code/mypy/mypy/checker.py", line 1790, in visit_class_def
    self.accept(defn.defs)
  File "/Users/jake/code/mypy/mypy/checker.py", line 425, in accept
    stmt.accept(self)
  File "/Users/jake/code/mypy/mypy/nodes.py", line 1069, in accept
    return visitor.visit_block(self)
  File "/Users/jake/code/mypy/mypy/checker.py", line 2052, in visit_block
    self.accept(s)
  File "/Users/jake/code/mypy/mypy/checker.py", line 425, in accept
    stmt.accept(self)
  File "/Users/jake/code/mypy/mypy/nodes.py", line 561, in accept
    return visitor.visit_overloaded_func_def(self)
  File "/Users/jake/code/mypy/mypy/checker.py", line 458, in visit_overloaded_func_def
    self._visit_overloaded_func_def(defn)
  File "/Users/jake/code/mypy/mypy/checker.py", line 482, in _visit_overloaded_func_def
    self.check_method_override(defn)
  File "/Users/jake/code/mypy/mypy/checker.py", line 1474, in check_method_override
    if self.check_method_or_accessor_override_for_base(defn, base):
  File "/Users/jake/code/mypy/mypy/checker.py", line 1502, in check_method_or_accessor_override_for_base
    if self.check_method_override_for_base_with_name(defn, name, base):
  File "/Users/jake/code/mypy/mypy/checker.py", line 1596, in check_method_override_for_base_with_name
    elif is_equivalent(original_type, typ):
  File "/Users/jake/code/mypy/mypy/subtypes.py", line 164, in is_equivalent
    is_subtype(a, b, ignore_type_params=ignore_type_params,
  File "/Users/jake/code/mypy/mypy/subtypes.py", line 93, in is_subtype
    return _is_subtype(left, right,
  File "/Users/jake/code/mypy/mypy/subtypes.py", line 147, in _is_subtype
    return left.accept(SubtypeVisitor(orig_right,
  File "/Users/jake/code/mypy/mypy/types.py", line 1967, in accept
    return visitor.visit_partial_type(self)
  File "/Users/jake/code/mypy/mypy/subtypes.py", line 515, in visit_partial_type
    raise RuntimeError(f'Partial type "{left}" cannot be checked with "issubtype()"')
RuntimeError: Partial type "<partial list[?]>" cannot be checked with "issubtype()"
partial_list.py:15: : note: use --pdb to drop into pdb

To Reproduce

The traceback above was generated by the file partial_list.py:

class Parent:
    # No error if there's no type hint in the constructor (type unimportant)
    def __init__(self, args: int):
        # The next line succeeds if it's a tuple, but fails on list.
        self.var_a = []
        # The type of this variable doesn't seem to matter at all, but it needs
        # to exist and be trying to set a property.
        self.var_b = None

    # This needs to be a property, but the getter doesn't affect anything.
    var_b = property(fset=lambda self, value: None)


class Child(Parent):
    @property  # Error reported on this line.
    def var_a(self):
        return self._var_a

    @var_a.setter
    def var_a(self, value):
        self._var_a = []

This was run with mypy --show-traceback partial_list.py in an empty venv, after deleting the .mypy-cache directory, and I don't think there's any other configuration being pulled from anywhere.

This was as small a reproducer as I could find. It seems to matter that there are two properties (although one of them only needs a setter), and the child class seems to need to be overriding a partially typed instance variable with a getter property that's also partially typed.

Your Environment

  • Mypy version used: master: 0.920.dev @ 01e6aba
  • Mypy command-line flags: --show-traceback
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.9 and 3.10
  • Operating system and version: macOS 11.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions