Skip to content

New semantic analyzer: crash on assignment to sqlalchemy @hybrid_property #7044

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Deimos opened this issue Jun 22, 2019 · 1 comment · Fixed by #7181
Closed

New semantic analyzer: crash on assignment to sqlalchemy @hybrid_property #7044

Deimos opened this issue Jun 22, 2019 · 1 comment · Fixed by #7181
Labels
crash priority-0-high semantic-analyzer Problems that happen during semantic analysis

Comments

@Deimos
Copy link
Contributor

Deimos commented Jun 22, 2019

I'm testing out the new semantic analyzer, but it crashes on my codebase. Trying to assign to a SQLAlchemy @hybrid_property) results in a Cannot assign to a method error followed by a crash.

Here's a fairly minimal reproduction for it:

from sqlalchemy import Base, Column, String
from sqlalchemy.ext.hybrid import hybrid_property

class FirstNameOnly(Base):
    first_name = Column(String)

    @hybrid_property
    def name(self) -> str:
        return self.first_name

    @name.setter  # type: ignore
    def name(self, value: str) -> None:
        self.first_name = value

    def __init__(self, name: str):
        self.name = name

The # type: ignore comment on the setter is a workaround for this issue I reported last year: #4430

Here's the full output:

(tildes) vagrant@ubuntu-xenial:/opt/tildes$ mypy --new-semantic-analyzer --show-traceback test_mypy.py 
test_mypy.py:16: error: Cannot assign to a method
test_mypy.py:16: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.rtfd.io/en/latest/common_issues.html#using-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.720+dev.48916e63403645730a584d6898fbe925d513a841
Traceback (most recent call last):
  File "/opt/venvs/tildes/bin/mypy", line 10, in <module>
    sys.exit(console_entry())
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/__main__.py", line 8, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/main.py", line 83, in main
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/build.py", line 164, in build
    result = _build(sources, options, alt_lib_path, flush_errors, fscache, stdout, stderr)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/build.py", line 224, in _build
    graph = dispatch(sources, manager, stdout)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/build.py", line 2567, in dispatch
    process_graph(graph, manager)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/build.py", line 2880, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/build.py", line 2987, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/build.py", line 2096, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 281, in check_first_pass
    self.accept(d)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 392, in accept
    stmt.accept(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/nodes.py", line 913, in accept
    return visitor.visit_class_def(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 1596, in visit_class_def
    self.accept(defn.defs)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 392, in accept
    stmt.accept(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/nodes.py", line 978, in accept
    return visitor.visit_block(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 1785, in visit_block
    self.accept(s)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 392, in accept
    stmt.accept(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/nodes.py", line 655, in accept
    return visitor.visit_func_def(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 703, in visit_func_def
    self._visit_func_def(defn)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 707, in _visit_func_def
    self.check_func_item(defn, name=defn.name())
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 769, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 935, in check_func_def
    self.accept(item.body)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 392, in accept
    stmt.accept(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/nodes.py", line 978, in accept
    return visitor.visit_block(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 1785, in visit_block
    self.accept(s)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 392, in accept
    stmt.accept(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/nodes.py", line 1036, in accept
    return visitor.visit_assignment_stmt(self)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 1793, in visit_assignment_stmt
    self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 1834, in check_assignment
    lvalue_type, index_lvalue, inferred = self.check_lvalue(lvalue)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checker.py", line 2479, in check_lvalue
    True)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checkexpr.py", line 1766, in analyze_ordinary_member_access
    in_literal_context=self.is_literal_context())
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checkmember.py", line 103, in analyze_member_access
    result = _analyze_member_access(name, typ, mx, override_info)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checkmember.py", line 117, in _analyze_member_access
    return analyze_instance_member_access(name, typ, mx, override_info)
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/checkmember.py", line 179, in analyze_instance_member_access
    signature = function_type(method, mx.builtin_type('builtins.function'))
  File "/opt/venvs/tildes/lib/python3.7/site-packages/mypy/types.py", line 2188, in function_type
    assert isinstance(func, mypy.nodes.FuncItem), str(func)
AssertionError: OverloadedFuncDef:7(
  Decorator:11(
    Var(name)
    MemberExpr:11(
      NameExpr(name [test_mypy.FirstNameOnly.name])
      setter)
    FuncDef:12(
      name
      Args(
        Var(self)
        Var(value))
      def (self: test_mypy.FirstNameOnly, value: builtins.str)
      Block:12(
        AssignmentStmt:13(
          MemberExpr:13(
            NameExpr(self [l])
            first_name)
          NameExpr(value [l]))))))
@ilevkivskyi
Copy link
Member

This is still crashing. I think this is a release blocker for 0.720

@ilevkivskyi ilevkivskyi added crash semantic-analyzer Problems that happen during semantic analysis priority-0-high labels Jul 9, 2019
ilevkivskyi added a commit that referenced this issue Jul 9, 2019
…7181)

Fixes #7044

The crash is caused by the fact that `.type` for broken overloads can be `None`. There is another example where we deal with this in `analyze_ref_expr()`. The crash doesn't happen on the old analyzer because it doesn't add the broken overload to the symbol table.

I solve the crash by generating a dummy `Overloaded()` type in this case. An alternative solution would be to re-analyze a broken overload as independent (re-)definitions, but I think this is more error-prone to keep an overload in AST, but a bunch of functions in symbol table.

Using this opportunity I also remove a redundant `add_symbol()` call (we always add the overload before even processing it).

Note that the behavior of the new analyzer is still different from the old one, but IMO it is more consistent in some sense.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash priority-0-high semantic-analyzer Problems that happen during semantic analysis
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants