Trouble unregistering classes

When trying to unregister a previously registered class, I get the error:
RuntimeError: unregister_class(…):, missing bl_rna attribute from ‘_RNAMeta’ instance (may not be registered)

However, it seems it is registered, because if I try to register it again, I get this:
Info: Registering operator class: ‘SimpleOperator’, bl_idname ‘object.my_operator’ has been registered before, unregistering previous

Here’s the code:

import bpy

class SimpleOperator(bpy.types.Operator):
    bl_idname = "object.my_operator"
    bl_label = "My Custom Operator"
    
    def execute(self, context):
        return {'FINISHED'}

def register():
    bpy.utils.register_class(SimpleOperator)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()
    #unregister()

Another oddity: if I call register() and then immediately unregister(), no errors are issued. It’s only when I call only register() on the first run, then call only unregister() on the subsequent run that I get the error.

The code is a boiled down version of the blender template “Operator File Export”, btw. I’ve tried blender 4.2.3 and 4.3.1.

How can I avoid this error message?

I assume you unregistering by running the same script in the Scripting text editor but uncommenting unregister() and commenting register(). Each time you run the script it creates new Python namespace and it creates new SimpleOperator class. So unregistering it fails as it was never registered - it was another SimpleOperator that was registered when script was executed first time.

So, to avoid the error SimpleOperator must be stored somewhere, so unregister will pick up actually registered class. E.g. you can find your registered class it in bpy.types. But typically you wouldn’t get this error if your script is an addon as module executed just once and register and unregister are accessing the same class.

Info: Registering operator class: ‘SimpleOperator’, bl_idname ‘object.my_operator’ has been registered before, unregistering previous

It’s just an error suggesting that you’re trying to use already used bl_idname.

Thank you for replying!

I see what you’re saying – and given that register_class() is able to unregister the class if a second attempt at registering it is made without unregistering it first, it’s obviously possible to get at it via bl_idname.

Well, almost. It turns out that the solution is to look up the class via getattr() thus:

def unregister():
    op_class = getattr(bpy.types, 'OBJECT_OT_my_operator')
    bpy.utils.unregister_class(op_class)

The twist in the plot is of course that you have to use ‘OBJECT_OT_my_operator’ rather than ‘object.my_operator’ to reference it.

Interestingly, the blender ‘Operator File Export’ makes no attempt at this; it merely calls unregister_class() as in my original post.

Anyway, problem solved – thanks again :slight_smile:

Because it’s an example how you would do it in the addon, not in a separate script.

Yes, I eventually figured this out. This has been an enlightening problem but I will definitely load my script as a module when it’s finished.