Skip to content

"RuntimeWarning: assigning None to unbound local": an inscrutable error #124118

Description

@wyattscarpenter

Documentation

RuntimeWarning: assigning None to unbound local ← I get this periodically since upgrading to python 3.12, for various lines of library code somewhere deep in my project's dependencies, and it seems like there's no documentation for it online? It's not even clear to me from the error message why this would be a bad thing to happen. These warnings generally seem to show up in list comprehensions. I don't know how to fix them or what they indicate. Maybe it's even a bug in python! I'm using Python 3.12.6 on Windows 10.

Here's an example from today:

C:\[...]\.venv\Lib\site-packages\asttokens\util.py:173: RuntimeWarning: assigning None to unbound local 'n'
  if isinstance(c, type) and issubclass(c, ast.expr)} |
C:\[...]\.venv\Lib\site-packages\asttokens\util.py:173: RuntimeWarning: assigning None to unbound local 'c'
  if isinstance(c, type) and issubclass(c, ast.expr)} |

Here's the line it's complaining about: https://github.com/gristlabs/asttokens/blob/2ff0e8d157fa89c22fe16839ab060b33f4c888bd/asttokens/util.py#L173

Here's another:

C:\[...]\.venv\Lib\site-packages\scipy\sparse\__init__.py:315: RuntimeWarning: assigning None to unbound local 's'
  __all__ = [s for s in dir() if not s.startswith('_')]

Activity

  1. rruuaanng commented on Sep 16, 2024

    @rruuaanng
    Contributor

    Documentation

    RuntimeWarning: assigning None to unbound local ← I get this periodically since upgrading to python 3.12, for various lines of library code somewhere deep in my project's dependencies, and it seems like there's no documentation for it online? It's not even clear to me from the error message why this would be a bad thing to happen. These warnings generally seem to show up in list comprehensions. I don't know how to fix them or what they indicate. Maybe it's even a bug in python! I'm using Python 3.12.6 on Windows 10.

    Here's an example from today:

    C:\[...]\.venv\Lib\site-packages\asttokens\util.py:173: RuntimeWarning: assigning None to unbound local 'n'
      if isinstance(c, type) and issubclass(c, ast.expr)} |
    C:\[...]\.venv\Lib\site-packages\asttokens\util.py:173: RuntimeWarning: assigning None to unbound local 'c'
      if isinstance(c, type) and issubclass(c, ast.expr)} |

    Here's the line it's complaining about: https://github.com/gristlabs/asttokens/blob/2ff0e8d157fa89c22fe16839ab060b33f4c888bd/asttokens/util.py#L173

    Here's another:

    C:\[...]\.venv\Lib\site-packages\scipy\sparse\__init__.py:315: RuntimeWarning: assigning None to unbound local 's'
      __all__ = [s for s in dir() if not s.startswith('_')]

    Can you show the code that triggers the error?

  2. wyattscarpenter commented on Sep 16, 2024

    @wyattscarpenter
    Author

    I would like to, but I don't really know where in the program it comes from, nor do I have an minimal repro.

  3. rruuaanng commented on Sep 16, 2024

    @rruuaanng
    Contributor

    I would like to, but I don't really know where in the program it comes from, nor do I have an minimal repro.

    Oh, that's really sad.

  4. rruuaanng commented on Sep 16, 2024

    @rruuaanng
    Contributor

    I would like to, but I don't really know where in the program it comes from, nor do I have an minimal repro.

    Can you run the code on your machine?

    import ast
    
    expr_class_names = ({n for n, c in ast.__dict__.items()
                        if isinstance(c, type) and issubclass(c, ast.expr)} |
                        {'AssignName', 'DelName', 'Const', 'AssignAttr', 'DelAttr'})
    
    print(expr_class_names)
    

    Of course, Put the running results here.

  5. added
    type-bugAn unexpected behavior, bug, or error
    and removed
    docsDocumentation in the Doc dir
    on Sep 16, 2024
  6. picnixz commented on Sep 16, 2024

    @picnixz
  7. added
    pendingThe issue will be closed if no feedback is provided
    on Sep 16, 2024
  8. JelleZijlstra commented on Sep 16, 2024

    @JelleZijlstra
    Member

    This error is from here in _PyFrame_LocalsToFast. It was added in #99075 (cc @brandtbucher). In 3.13 this check is gone again, so it's only in 3.12.

    I'm not very familiar with this code, but it seems to interact with code paths that only trigger if you have a trace function enabled. For example, Brandt added a unit test that triggers this warning by doing del frame.f_locals["x"] in a trace function. Are you running with any trace function?

    I was able to reproduce this with just Python 3.12 (but only in the REPL for some reason, not when I put the same code in a file):

    % python3.12
    Python 3.12.5 (main, Aug  6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def trace(frame, event, arg):
    ...     if "s" in frame.f_locals:
    ...         del frame.f_locals["s"]
    ...     return trace
    ... 
    >>> import sys
    >>> sys.settrace(trace)
    >>> [s for s in dir() if s]
    <stdin>:1: RuntimeWarning: assigning None to unbound local 's'
    

    However, if you have a trace function that deletes locals, it seems reasonable that we raise warnings. I'd be curious what is causing the issue in the OP's code.

  9. added
    3.12only security fixes
    and removed
    pendingThe issue will be closed if no feedback is provided
    on Sep 16, 2024
  10. gaogaotiantian commented on Sep 16, 2024

    @gaogaotiantian
    Member

    Did you attach any debugger when you run this code? How did you run the code?

    This warning happens when you try to write/delete a local variable in a trace function. The reason @JelleZijlstra's code only repros in REPL is because when [s for s in dir() if s] is in module-level, its f_locals will be a real dict same as f_globals. Changing it won't matter to the actual locals.

    And yes, there are module level locals - hidden locals, introduced by PEP 709. They are basically comprehension locals when they are inlined (also in 3.12).

    This may or may not be a bug in CPython. I still need more info to figure out what's the trigger. You can, probably, do something crazy in your debugger/trace function to trigger this, but this also could be a corner that's forgotten when implementing PEP 709.

    Both cases listed are a global comprehension - they are comprehensions at module level so I can imagine there are some dark corners when trying to work with fast locals in module level.

    Maybe @carljm has a better insight than I do.

  11. wyattscarpenter commented on Sep 16, 2024

    @wyattscarpenter
    Author

    @rruuaanng
    I get this result, with no error:

    {'Dict', 'YieldFrom', 'Starred', 'UnaryOp', 'NamedExpr', 'BoolOp', '_ast_Ellipsis', 'Constant', 'IfExp', 'Set', 'Await', 'Tuple', 'AssignAttr', 'Const', 'ListComp', 'DelName', 'DictComp', 'Yield', 'DelAttr', 'Name', 'SetComp', 'Subscript', 'BinOp', 'Call', 'FormattedValue', 'JoinedStr', 'Compare', 'expr', 'GeneratorExp', 'Lambda', 'Attribute', 'List', 'AssignName', 'Slice'}

    This happens whether I'm in the repl or executing it from a file.

    @picnixz I agree that it seems to me likely to be a problem in third-party packages. But today I had resolved to investigate those errors, and ran into the difficulty that the RuntimeWarning here isn't documented anywhere, leaving me at a bit of a loss.

    @JelleZijlstra I was also able to reproduce using this code, but only in the repl, not when run from a file. I don't think I'm using a trace function directly, but come to think of it my code does use (an old version of) pyinstrument; so that might have a trace function. My code is also running inside of streamlit, which could also conceivably have a trace in it somewhere. I will try running it various ways...

  12. wyattscarpenter commented on Sep 16, 2024

    @wyattscarpenter
    Author

    Yep, OK, removing the profiler meant I couldn't get any of these errors, and adding the profiler back in made one happen. So I think it's safe to say it's my profiler. And, looking into it, it seems the author of the profiler noticed this problem and fixed it about 3 weeks ago!

  13. wyattscarpenter commented on Sep 16, 2024

    @wyattscarpenter
    Author

    So, not a bug in CPython. Perhaps the warning could use documentation somewhere... although, on the other hand, it seems like the actual author of the profiler was able to figure it out well enough.

  14. gaogaotiantian commented on Sep 16, 2024

    @gaogaotiantian
    Member

    The warning should not really happen for common users. This is some dark zone that users need to explore with their own flashlights. I'm glad the author of pyinstrument has figured it out. From the issue listed it seems like this is indeed a third party bug. So I'll close this one for now.

  15. wyattscarpenter commented on Sep 16, 2024

    @wyattscarpenter
    Author

    Thanks everyone!

  16. added a commit that references this issue on Jan 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.12only security fixestype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions