5
$\begingroup$

A recent question / answer involves what looks like an overridden operator:

bpy.ops.object.align()

Differing from the documented default, how do we find which addon(s) have registered the operator.

Method 1:

Edit to match operator id.

op_name = "import_scene.obj"

Script:

import addon_utils
from bpy.types import Operator
from importlib import import_module
import inspect

op_name = "import_scene.obj"

for m in addon_utils.modules():
    name = m.__name__
    default, loaded = addon_utils.check(name)
    if loaded:
        mod = import_module(name)
        classes = getattr(mod, "classes", [])
        for c in classes:
            if (
                issubclass(c, Operator) 
                and  
                getattr(c, "bl_idname", "").startswith(op_name)
                ):
                print(name)
        
        if not classes:
            for k in dir(mod):
                cls = getattr(mod, k, None)
                if inspect.isclass(cls) and issubclass(cls, Operator):
                    id = getattr(cls, "bl_idname", "")
                    if id.startswith(op_name):
                        print(name)

By either looking at the addons classes or inspecting all objects of enabled addons. How do I run an existing add-on via the python API?

Method 2:

This approach disable, check op is still registered, re-enable...

Edit your operator of interest into

op_id = bpy.ops.import_scene.obj.idname()

Script:

import addon_utils
import bpy

op_id = bpy.ops.import_scene.obj.idname()

for m in addon_utils.modules():
    name = m.__name__
    default, loaded = addon_utils.check(name)
    if loaded:
        addon_utils.disable(name)
        if not hasattr(bpy.types, op_id):
            print(name)
            #addon_utils.enable(name)
            #break
        addon_utils.enable(name)

How would you approach finding an operators registering addon(s) from its id name?.

Note: don't save preferences after running this, as addon preferences could be lost after disable.

$\endgroup$
4
  • $\begingroup$ for me, on script 1: line 15: AttributeError: 'tuple' object has no attribute 'startswith' $\endgroup$
    – james_t
    Commented Mar 23, 2021 at 15:18
  • 1
    $\begingroup$ Have put in fix for that, prob could flag it since it is "usual practice" to have a tuple for a "bl_idname" $\endgroup$
    – batFINGER
    Commented Mar 23, 2021 at 15:31
  • $\begingroup$ super! thanks, unfortunately op_name = "bpy.ops.object.align" returns nothing for me, nor does op_name = "bpy" ! $\endgroup$
    – james_t
    Commented Mar 23, 2021 at 16:10
  • $\begingroup$ ah i changed to op_name in getattr(c, "bl_idname", "") and now op_name = "align" returned "space_view3d_align_tools", so this is getting me what I need to know. Perhaps I would disable this add-on to help solve my problem. thanks again!!! $\endgroup$
    – james_t
    Commented Mar 23, 2021 at 16:18

1 Answer 1

0
$\begingroup$
Operator to top module map
import bpy
import sys
import inspect

module_name_to_op_reprs = {}
op_to_module = {}

for cls in bpy.types.Operator.__subclasses__():

    try:
        op_section, op_name = cls.bl_idname.split('.', 1)
        op = getattr(getattr(bpy.ops, op_section), op_name)
        op_repr = repr(op)
        assert op.idname() == getattr(cls, 'bl_rna').name, str(cls)
    except Exception as e:
        print("Not registered:", e)
        continue

    op_module = inspect.getmodule(cls)
    if op_module is None:
        print("No module:", cls)
        continue

    try:
        top_module_name = op_module.__spec__.parent
    except AttributeError:
        top_module_name = op_module.__package__

    if not top_module_name:
        top_module_name = op_module.__name__

    op_to_module[op] = sys.modules[top_module_name]

    try:
        module_name_to_op_reprs[top_module_name].append(op_repr)
    except Exception:
        module_name_to_op_reprs[top_module_name] = [op_repr]


print(op_to_module)

import json
print(json.dumps(module_name_to_op_reprs, indent = 4))
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .