How to know if an operator is registered?

The function hasattr(bpy.ops, “wm23”) always returns True no matter what idname i pass.

So ye the question is, how to detect if an operator exists by idname?

Thanks

Well, you could either do something like

getattr(getattr(bpy.ops, “wm”), “call_menu”)

If no AttributeError is raised, the operator exists. Note that getattr(bpy.ops, “wm.call_menu”) will fail, you need two calls to getattr().

But it’s probably better to do something like:

hasattr(bpy.types, “WM_OT_call_menu”)

Note that the C naming convention for operators is used.

bpy.ops.wm.call_menu.idname() # returns WM_OT_call_menu

but you can also construct it from the py name easily:

idname_py = “wm.call_menu”
module, op = idname.split(".")
idname = module.upper() + “OT” + op

1 Like

Thanks Codemanx, You are helping a lot of people.

Ive also tried getattr but always return True as well.
Im trying to check for invalid operators assignments to the keyconfig but i can’t identify them.


def operator_exists(idname):
    names = idname.split(".")
    print(names)
    a = bpy.ops
    for prop in names:
        a = getattr(a, prop) #it wont fail even if the operator name is invalid
        print(prop, a.__class__.__name__)
    try:
        name = a.idname() #try to raise the exception
    except:
        return False

    return True
        
print(operator_exists("wm.call_menu2")) #True

Ive found a way

Im only able to raise the exception if i try to print the result, i dont want to print in order to check if an operator exists but i solve that by calling repr


import bpy
print(30*"-")

def operator_exists(idname):
    names = idname.split(".")
    print(names)
    a = bpy.ops
    for prop in names:
        a = getattr(a, prop)
        
    try:
        name = a.__repr__()
    except Exception as e:
        print(e)
        return False

    return True
        
print(operator_exists("wm.call_menu23")) #False

Ah, I wasn’t aware that it actually needs to be accessed before an exception is fired. Anyway, hasattr(bpy.types, “…”) is still the better way.

I agree that looking into bpy.types should be better but bpy.types has everything, not just operators, and some custom ones doesnt follow name conventions. Also i dont know the class name as my way to search for unregistered operators is by idname, extracted from the keyconfig.

This way you can also check for anything that “exists”. For example, passing “bpy.ops.wm” also works.

Thanks for the help.

Ive found a cleaner way, here it is:


def operator_exists(idname):
    from bpy.ops import op_as_string
    try:
        op_as_string(idname)
        return True
    except:
        return False