1
$\begingroup$

I am developing some custom nodes and have a question about the development lifecycle. Can I reload AN classes without restarting Blender? Or, do I need to reload blender after each change to the class’s source file? I have tried a few things using importLib and nothing works. Thanks!

$\endgroup$
2
$\begingroup$

If you can reload your changes without closing Blender depends on what you changed. First of all: you don't have to write any reloading code yourself, everything is handled automatically in the developer_utils.py file.

The problem with reloading when you have so many modules is that you can't reload the whole addon at once (please correct me if I'm wrong). Instead each module is reloaded individually.

Here is an example that shows the problem that can happen:

# file_a.py
def my_func():
    return 0

# file_b.py
from file_a import my_func
print(my_func())

When file_b is executed everything looks normal and the console output will be 0. Now imagine you change my_func so that it returns 1. After this change the reloading order is important.

There are two different scenarios:

  1. file_a.py and then file_b.py: In this case everything works as expected, my_func will be updated at first, then the updated function is imported into file_b and the output will be 1.

  2. file_b.py and then file_a.py: Now file_b imports the old function again (the one that returns 0) because file_a has not been reloaded yet. Then output will still be 0.

In general you can simply try to reload all addons by hitting F8. Sometimes it helps to reload twice to make sure that all modules use the updated functions. There is still a good chance that two modules which depend on the same module will have different versions of the same function but in most cases you don't need to care about that.

Currently there is only one module in AN that needs to be reloaded before all the others: https://github.com/JacquesLucke/animation_nodes/blob/master/utils/handlers.py#L6

Summary

Reloading should definitly work when you only changed a single file. Maybe you have to reload twice (I hit F8 twice all the time..).

Reloading does not work (only if you are lucky) when you added/removed a function from a module that is imported into other modules.

Most of the time I just try it and when it doesn't work I restart Blender. Take a look into the console if any exception is raised (also note that not all exceptions have to come from AN; other actived addons might not support reloading)

$\endgroup$
2
$\begingroup$

try hitting F8 to reload scripts, or, if you're just running your script from a text editor, just run it again.

$\endgroup$
1
$\begingroup$

The best way to apply changes made to an addon is to disable then re-enable the addon. If the addon has been made right this will un-register any classes, properties and other changes that have been made by the addon, allowing the new adjusted code to be used without conflicts.

When you create an addon, or add to another addon, any classes need to be registered in the addons register() function with a matching unregister added to the unregister() function. Other steps can be added to these functions, as in the following example an item is added and removed from the import menu. Custom properties may also be added in register and then deleted in unregister. There is also a register_module() available that can make things easy for some addons.

When you disable the addon, the code that was read when you enabled the addon is used (which is the old unregister()), then when you re-enable it, the modifications are noticed and the file is re-read so that the new version is in use. If you look in the console when you re-enable the addon after you make changes you will see something like -

module changed on disk: /path/to/scripts/addons_contrib/test1.py reloading...

Here is a trimmed down copy of the import template included with blender showing the use of register and unregister.

import bpy

class ImportSomeData(Operator, ImportHelper):
    """This appears in the tooltip of the operator and in the generated docs"""
    bl_idname = "import_test.some_data"
    bl_label = "Import Some Data"

    #class methods here

def menu_func_import(self, context):
    self.layout.operator(ImportSomeData.bl_idname, text="Text Import Operator")

def register():
    bpy.utils.register_class(ImportSomeData)
    bpy.types.INFO_MT_file_import.append(menu_func_import)

def unregister():
    bpy.utils.unregister_class(ImportSomeData)
    bpy.types.INFO_MT_file_import.remove(menu_func_import)

if __name__ == "__main__":
    register()
$\endgroup$
  • $\begingroup$ this is right for smaller addons but in Animation Nodes all registration is handled automatically because it would be a pain to register hundreds of classes manually. It is true that you can also just deactivate and activate AN again to reload changes. $\endgroup$ – Jacques Lucke May 15 '16 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.