Skip to content

"UnboundLocalError" on an annotation for a nonlocal variable #7060

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
shirayu opened this issue Jun 25, 2019 · 2 comments · Fixed by #7089
Closed

"UnboundLocalError" on an annotation for a nonlocal variable #7060

shirayu opened this issue Jun 25, 2019 · 2 comments · Fixed by #7089
Labels
crash priority-0-high semantic-analyzer Problems that happen during semantic analysis

Comments

@shirayu
Copy link

shirayu commented Jun 25, 2019

This code causes UnboundLocalError with mypy 0.711 and the latest master sources (Version: 0.720+dev.46aa00d8a8d5c870c6ef24b82261b6b257e2ea03).

#!/usr/bin/env python3

import typing


def main():
    bar = []  # type: typing.List[int]

    def foo():
        nonlocal bar
        bar = []  # type: typing.List[int]


if __name__ == '__main__':
    main()
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/dev/shm/mypy/mypy/__main__.py", line 12, in <module>
    main(None, sys.stdout, sys.stderr)
  File "/dev/shm/mypy/mypy/main.py", line 83, in main
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/dev/shm/mypy/mypy/build.py", line 164, in build
    result = _build(sources, options, alt_lib_path, flush_errors, fscache, stdout, stderr)
  File "/dev/shm/mypy/mypy/build.py", line 224, in _build
    graph = dispatch(sources, manager, stdout)
  File "/dev/shm/mypy/mypy/build.py", line 2567, in dispatch
    process_graph(graph, manager)
  File "/dev/shm/mypy/mypy/build.py", line 2880, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/dev/shm/mypy/mypy/build.py", line 2981, in process_stale_scc
    graph[id].semantic_analysis()
  File "/dev/shm/mypy/mypy/build.py", line 2073, in semantic_analysis
    self.manager.semantic_analyzer.visit_file(self.tree, self.xpath, self.options, patches)
  File "/dev/shm/mypy/mypy/semanal.py", line 321, in visit_file
    self.accept(d)
  File "/dev/shm/mypy/mypy/semanal.py", line 3853, in accept
    node.accept(self)
  File "/dev/shm/mypy/mypy/nodes.py", line 655, in accept
    return visitor.visit_func_def(self)
  File "/dev/shm/mypy/mypy/semanal.py", line 393, in visit_func_def
    self._visit_func_def(defn)
  File "/dev/shm/mypy/mypy/semanal.py", line 484, in _visit_func_def
    self.analyze_function(defn)
  File "/dev/shm/mypy/mypy/semanal.py", line 784, in analyze_function
    postponed.accept(self)
  File "/dev/shm/mypy/mypy/nodes.py", line 655, in accept
    return visitor.visit_func_def(self)
  File "/dev/shm/mypy/mypy/semanal.py", line 393, in visit_func_def
    self._visit_func_def(defn)
  File "/dev/shm/mypy/mypy/semanal.py", line 484, in _visit_func_def
    self.analyze_function(defn)
  File "/dev/shm/mypy/mypy/semanal.py", line 779, in analyze_function
    defn.body.accept(self)
  File "/dev/shm/mypy/mypy/nodes.py", line 978, in accept
    return visitor.visit_block(self)
  File "/dev/shm/mypy/mypy/semanal.py", line 1731, in visit_block
    self.accept(s)
  File "/dev/shm/mypy/mypy/semanal.py", line 3853, in accept
    node.accept(self)
  File "/dev/shm/mypy/mypy/nodes.py", line 1036, in accept
    return visitor.visit_assignment_stmt(self)
  File "/dev/shm/mypy/mypy/semanal.py", line 1792, in visit_assignment_stmt
    self.analyze_lvalues(s)
  File "/dev/shm/mypy/mypy/semanal.py", line 1813, in analyze_lvalues
    is_final=s.is_final_def)
  File "/dev/shm/mypy/mypy/semanal.py", line 2119, in analyze_lvalue
    self.analyze_name_lvalue(lval, add_global, explicit_type, is_final)
  File "/dev/shm/mypy/mypy/semanal.py", line 2198, in analyze_name_lvalue
    self.make_name_lvalue_point_to_existing_def(lval, explicit_type, is_final)
  File "/dev/shm/mypy/mypy/semanal.py", line 2281, in make_name_lvalue_point_to_existing_def
    self.name_already_defined(lval.name, lval, original_def)
  File "/dev/shm/mypy/mypy/semanal.py", line 3817, in name_already_defined
    self.already_defined(name, ctx, original_ctx, noun='Name')
  File "/dev/shm/mypy/mypy/semanal.py", line 3808, in already_defined
    elif node and node.line != -1:
UnboundLocalError: local variable 'node' referenced before assignment
@JelleZijlstra
Copy link
Member

Confirmed on master and 0.711. The code passes with --new-semantic-analyzer though.

@JukkaL JukkaL added the semantic-analyzer Problems that happen during semantic analysis label Jun 25, 2019
@JukkaL
Copy link
Collaborator

JukkaL commented Jun 28, 2019

Since this is not a regression (it also happens with 0.670 at least) and fixed in the new semantic analyzer, this doesn't seem urgent to fix. The only action seems to be adding a test case to prevent a future regression.

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.

3 participants