Skip to content

Error when checking function conditionally defined in try/except/else clause #1289

Closed
@aiiie

Description

@aiiie

The following code causes mypy to crash:

def fun1():
    pass

try:
    pass
except:
    fun2 = fun1
else:
    def fun2():
        pass

Traceback:

Traceback (most recent call last):
  File "./scripts/mypy", line 6, in <module>
    main(__file__)
  File "mypy/mypy/main.py", line 50, in main
    type_check_only(sources, bin_dir, options)
  File "mypy/mypy/main.py", line 94, in type_check_only
    python_path=options.python_path)
  File "mypy/mypy/build.py", line 210, in build
    result = manager.process(initial_states)
  File "mypy/mypy/build.py", line 425, in process
    next.process()
  File "mypy/mypy/build.py", line 930, in process
    self.type_checker().visit_file(self.tree, self.tree.path)
  File "mypy/mypy/checker.py", line 409, in visit_file
    self.accept(d)
  File "mypy/mypy/checker.py", line 450, in accept
    typ = node.accept(self)
  File "mypy/mypy/nodes.py", line 707, in accept
    return visitor.visit_try_stmt(self)
  File "mypy/mypy/checker.py", line 1732, in visit_try_stmt
    self.accept(s.else_body)
  File "mypy/mypy/checker.py", line 450, in accept
    typ = node.accept(self)
  File "mypy/mypy/nodes.py", line 526, in accept
    return visitor.visit_block(self)
  File "mypy/mypy/checker.py", line 1113, in visit_block
    self.accept(s)
  File "mypy/mypy/checker.py", line 450, in accept
    typ = node.accept(self)
  File "mypy/mypy/nodes.py", line 382, in accept
    return visitor.visit_func_def(self)
  File "mypy/mypy/checker.py", line 594, in visit_func_def
    'redefinition with type')
  File "mypy/mypy/checker.py", line 2117, in check_subtype
    if not is_subtype(subtype, supertype):
  File "mypy/mypy/subtypes.py", line 49, in is_subtype
    return left.accept(SubtypeVisitor(right, type_parameter_checker))
AttributeError: 'NoneType' object has no attribute 'accept'

I'm still trying to understand the code and why it might be crashing. As a side issue, one thing I find odd is that presumably when mypy checks itself, it isn't seeing that TypeChecker.check_subtype() doesn't accept None for the first argument (it accepts Type but doesn't specify it using Optional). When it's called, the first argument is defined like this:

orig_type = defn.original_def.type

Where defn is of the type mypy.nodes.FuncDef. FuncDef.original_def is of the type Union[mypy.nodes.FuncDef, mypy.nodes.Var]. FuncDef.type and Var.type are of the type Optional[mypy.types.Type] (both fields are optional because they're set to None on their respective classes).

Shouldn't the checker, using type inference when orig_type is defined, catch that type mismatch when TypeChecker.check_subtype() is called?

Edit: I suppose my digression above might be invalid if all types are nullable, but while PEP 484 states, "[b]y default, None is an invalid value for any type, unless a default value of None has been provided in the function definition", the mypy docs say, "None is a valid value for every type, which resembles null in Java." Are the mypy docs out of date/incorrect, or is every type nullable?

Metadata

Metadata

Assignees

Labels

bugmypy got something wrong

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions