8
$\begingroup$

I have the following code which I use for expanding all collections in the outliner

def toggle_collection_collapse(state):
    area = next(a for a in bpy.context.screen.areas if a.type == 'OUTLINER')
    bpy.ops.outliner.show_hierarchy({'area': area}, 'INVOKE_DEFAULT')
    for i in range(state):
        bpy.ops.outliner.expanded_toggle({'area': area})
    area.tag_redraw()

class Expand_All(bpy.types.Operator):
    bl_label = "Expand All"
    bl_idname = "my.expand_all"

    def execute(self, context):
        toggle_collection_collapse(1)
        return {'FINISHED'}

This used to work on Blender 3.6.5 but now in 4.0.1 I get this error

Traceback (most recent call last):
  File "/Users/user/models.blend/Text", line 218, in execute
  File "/Users/user/models.blend/Text", line 195, in toggle_collection_collapse
  File "/Applications/Blender.app/Contents/Resources/4.0/scripts/modules/bpy/ops.py", line 106, in __call__
    C_exec, C_undo = _BPyOpsSubModOp._parse_args(args)
  File "/Applications/Blender.app/Contents/Resources/4.0/scripts/modules/bpy/ops.py", line 60, in _parse_args
    raise ValueError("1-2 args execution context is supported")
ValueError: 1-2 args execution context is supported

Seems like the problem is when calling this line bpy.ops.outliner.show_hierarchy({'area': area}, 'INVOKE_DEFAULT')

How I can fix this?

$\endgroup$
1
  • $\begingroup$ It looks like this method doesn't work with a number of operators. For example, the operator bpy.ops.outliner.select_walk('INVOKE_DEFAULT') causes a critical error in Blender and it closes. And so far unfortunately i have not found any information on how to work around this problem. $\endgroup$
    – Andrew
    Commented Nov 30, 2023 at 8:15

2 Answers 2

12
$\begingroup$

Blender dev team added a new API for overriding context some time ago:

https://docs.blender.org/api/current/bpy.ops.html#overriding-context

Overriding context should be implemented this way, context attribute was deprecated and disabled in 4.0. Info in release notes:

Blender Operators (bpy.ops)
Remove the context override argument to bpy.ops in favor of context.temp_override(..) (ac263a9bce)

bpy.ops.some_ops({"a": a, "b": b}) need change to with bpy.context.temp_override(a=a, b=b): bpy.ops.some_ops()

import bpy

def toggle_collection_collapse(state, context):
    area = next(a for a in bpy.context.screen.areas if a.type == 'OUTLINER')

    with context.temp_override(area=area):
        bpy.ops.outliner.show_hierarchy('INVOKE_DEFAULT')
        for i in range(state):
            bpy.ops.outliner.expanded_toggle()
        area.tag_redraw()

class Expand_All(bpy.types.Operator):
    bl_label = "Expand All"
    bl_idname = "my.expand_all"

    def execute(self, context):
        toggle_collection_collapse(1, context)
        return {'FINISHED'}

if __name__ == "__main__":
    bpy.utils.register_class(Expand_All)

    # test call
    bpy.ops.my.expand_all()
$\endgroup$
0
0
$\begingroup$

The solution provided by @XY is accurate but it is a bit complex for beginners, like me. Here's a simpler version of the code that might be easier to understand:

The Main error is that the Context override works different now

First we need the Context

def get_context(type):
    for screen in bpy.data.screens:
        for area in screen.areas:
            if area.type == type:
                context_override = {"area": area, "screen": screen}
                return context_override

After that we set the Context in temp_override

def sound_to_sample(context, mp3):
    override = get_context("OUTLINER")

    with context.temp_override(**override):
        #context changed
        #add your code here
$\endgroup$

You must log in to answer this question.

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