Multi-File Packages need to unregister all classes from files Blender (2.70a) is crashing with segmentation faults when I enable/disable/reenable my addon. I've inherited a project with a multi-file package design. I'm suspect that some classes are not unregistering since they aren't being called when the addon's unregister gets called. 

I've reviewed this cookbook. And in both examples there are no bpy.type.Operators except in the __init__.py file. But in my project some files have Operators and Panels and some don't.

Does anyone know if reregistering classes can cause a crash?
What's the point of calling bpy.utils.unregister_module(__name__) if it doesn't unregister. Here is my __init__.py

bl_info = {
   'name': 'MyTools',
   'author': 'Me',
   'version': (0, 3),
   'blender': (2, 69, 0),
   'location': 'bpy.ops.mytools',
   'description': 'MyTools',
   'warning': '',
   'wiki_url': '',
   'category': 'user'}

import os
import sys
import importlib


# import/reload all .py files dynamically
for file_name in os.listdir(os.path.dirname(__file__)):
  if file_name      == '__init__.py' or \
     file_name[-3:] != '.py'         or \
     file_name[0]   == '.'           or \
     file_name[0]   == '#':
       continue

  module_name = 'mytool.' + file_name[:-3]
  __import__(module_name, locals(), globals())

  module = sys.modules[module_name]
if 'bpy' in locals():
    print(module.__name__)
    importlib.reload(module)

if 'bpy' in locals():
  print('Reloaded Mytool AddOn')
else:
  print('Imported Mytool AddOn')

import bpy

def register():
  bpy.utils.register_module(__name__)


def unregister():
  bpy.utils.unregister_module(__name__)

if __name__ == '__main__':
  register()


And mock up of one of the other files. foo.py

from . import myUtils

import bpy

class myOp(bpy.types.Operator):
   bl_idname = "mytools.myop"
   bl_label = "my operator"
   def execute(self,context):
       self.report({'INFO'}, "awesome")
       return {'FINISHED'}

bpy.utils.register_class(myOp)


Is this as simple as adding register and unregister methods to all of my other .py files.
If there are any custom PropertyGroup classes in the submodules, they have to be loaded in the correct order. You also need to "unregister" the submodules.

This is a pattern in the main file

def register():
    #register operators and propertyGroups explicitly
    bpy.utils.register_class(myPGClass1)
    #and/or run a helper function that finds all the classes and registers them

    bpy.utils.register_module(__name__)

    #add to the schema
    bpy.types.Scene.myTool = bpy.props.PointProperty(type=myPGClass1)


def unregister():

    #important: delete custom schema
    del bpy.types.Scene.myTool
    #unregister_classes, or use helper
    bpy.utils.unregister_class(myPGClass1)
    bpy.utils.unregister_module(__name__)

if __name__ == '__main__':
    register()


The this should work find if everything is in the __init__.py file. But since this is not the case, then these are the issues I discovered.


register_module() just finds the bpy.types.* classes in the module and runs register_class which looks to be a python call into C. So this doesn't look in the other files. So one has to call register_class on anything defined there.
enabling and disabling scripts will find the register and unregister functions by duck-typing. But only the __init__.py file will be in the list that gets checked. So anything in unregister() will not get called. This is the del types.myType line.
even though registering and unregistering is not working. Reloading will import the submodules, thus causing erratic behavior and classes will be reregistering, and the schema will try to update from a dereferenced raw pointer.
disabling/enabling addons has more to do with marking modules with a flag than with loading and unloading modules. Loading happens on first load and reload(f8).