Update: Since commit rBfa566157a5c351775d082b05b180c630665b4afc Blender calls unregister on exit in WM_exit_ex through addon_utils.disable_all(). This only calls unregister for the installed and enabled add-ons though, not for scripts run from the text editor.
You can verify this by saving the script below in a .py file, installing and enabling it as an add-on in Edit > Preferences > Add-ons and then closing Blender. The test.txt file will contain the "unregister" line when using Blender 2.91 or later, assuming that you have the required permissions to write the file.
Old answer that applies to versions prior to commit rBfa566157a5c351775d082b05b180c630665b4afc
The unregister() function is only called when you deactivate the add-on in your preferences, while register() is always called when Blender starts in case the add-on is activated in the preferences. You can test this with the following simple add-on that writes into a text file whenever one of the functions is executed. The example also includes how to add a handler that is triggered when Blender is exiting.
This add-on tries to write the test file into Blender's install directory. If that directory requires special permissions, then you should adjust the path to somewhere it can write the file to.
bl_info = {
"name": "Register and unregister test",
"author": "Robert Guetzkow",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "Dummy panel in View3D",
"description": "Check when register and unregister are called",
"warning": "",
"wiki_url": "",
"category": "3D View"}
import bpy
import atexit
class EXAMPLE_PT_panel(bpy.types.Panel):
bl_label = "My own addon"
bl_category = "Name of your tab"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
layout = self.layout
layout.label(text="This is a label")
classes = (EXAMPLE_PT_panel,)
def exit_handler():
with open("test.txt", "a") as myfile:
myfile.write("exiting\n")
def register():
for cls in classes:
bpy.utils.register_class(cls)
with open("test.txt", "a") as myfile:
myfile.write("register\n")
atexit.register(exit_handler)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
with open("test.txt", "a") as myfile:
myfile.write("unregister\n")
if name == "main":
register()
unregister()function is only called when you deactivate the add-on in your preferences, as far as I'm aware. Add-ons that store settings in the preferences commonly remove them whenunregister()is called. It would be very inconvenient if that was the case whenever Blender is closed. For an example see the add-on in this answer https://blender.stackexchange.com/questions/153022/pycharm-remote-debugger/153031 – Robert Gützkow Sep 18 '19 at 13:21register()was a sort of activation area, and 'unregister()' was the exit point of that activation. I just assumed all add-ons would be deactivated before Blender shuts down. I've noticed several add-ons doing this, so it must be a common assumption (unless they were only trying to clean up for add-on toggling). So then it would be unwise to try to initialize inregister()and clean up inunregister()? Such as, for example, to flush some file buffers on exit (random example). Where would be the best place to do this? – Robert Sep 18 '19 at 18:49unregister()function doesn't get called when that happends). If anything needs to run when Blender closes you would useatexit. – Robert Gützkow Sep 18 '19 at 20:09