Utility function for reloading addon in text editor

Hi everyone :slight_smile:

I’d like to add a bpy.utils function for reloading a single addon snippet in text editor, but not sure how should I proceed.

What I like to do and solve (assuming that is a problem), is that I find most addon or operator example snippets end with these lines:

def register():
    ...

def unregister():
    ...

if __name__ == "__main__":
    register()

Usually one would try those snippets via copy paste it into blender text editor and test it.

But then, you cannot unregister it by simply changing the last line into unregister() and rerun, unless you reload everything with bpy.ops.script.reload(), a.k.a. Press F3 > Reload Scripts.

If we could just press Alt + P in text editor to rerun the snippet and get a reloaded result, that would be wonderful.

So here’s what I’d like to do instead:


def register():
    ...


def unregister():
    ...


def reload_snippet():
    # For testing in blender text editor. Maybe bpy.utils.reload_snippet()?

    # Identifier of the script to reload
    #   You can use current text name (__file__, but may not work if renamed),
    #   or use your addon name.
    key = __file__

    # Setup registry
    if not hasattr(bpy, "_snippets"):
        bpy._snippets = {}
        # this can survive through importlib.reload,
        # but who would reload bpy anyway?
    registry = bpy._snippets

    # Unregister previous session
    prev_globals = registry.pop(key, None)
    if prev_globals:
        eval("unregister()", prev_globals)

    # Register and save session
    register()
    registry[key] = globals()


if __name__ == "__main__":
    reload_snippet()

What that reload_snippet() does is:

  1. Save snippet globals() when registering
  2. When rerun, it calls the unregister() funtion in that globals dict
  3. Then call register in new session.
  4. Save new globals() for next rerun.

What do you think?

Would this worth be part of bpy.utils?

1 Like