Blender operators context interaction documentation

There is a reoccurring problem with using Blender operators from Python API and using Context.temp_override - I feel like everyone is doing the same guesswork and it would be great if it was somehow documented.

I tried to report it as a bug to Blender documentation (#137210) but it was expectedly closed as I guess it’s not a documentation bug, but a documentation issue. So I’m posting it now here as it’s probably the best place to discuss Python API.

Issue description from the bug report:

There is a reoccurring issue for every Blender Python API user - you try to use default Blender operators as they are very efficient but you never know what Context attributes to temp_override to make it work (object / active_object / selected_objects / selected_editable_objects) and whether it’s possible at all. Typically user would try to provide all attributes they can possibly guess and if doesn’t work, the solution is to go and check C++ source and identify what context members are used.

And since Blender doesn’t have a requirement to make all operators context overridable from API, so it’s never a bug. Missing context override support may be wasn’t implemented as it wasn’t needed or supporting it may not be trivial or it could be part of design (e.g. code requires accessing selected objects from view layer explicitly). So theoretically any operator user meets may not support temp_override at all and require manual context manipulation.

Could there be a general solution to this?
E.g. I just needed object.make_single_user operator. I’ve investigated the source code and it doesn’t use Context but instead is using FOREACH_OBJECT_FLAG_BEGIN (scene, view_layer, v3d, flag, ob) - so checking selected objects on view layer explicitly.

Is there a place in docs where such thing could be documented? So this kind of information could slowly accumulate by the community contributions and then every Python API user (and myself in the future) wouldn’t need to go and recheck it again themselves.

As I see it, there’s probably no way to fit it in in the current Blender opertors documentation. E.g. object operators page - it’s using operator and properties description from the UI and have no details on how it suppose to/can be used from Python API. UI descriptions shouldn’t be polluted with implementation details, so something new should be added to the documentation. Posting this as an idea on Right-Click Select is probably not very meaningful as it usually end up just hanging there forever.

Maybe just creating another public repository with documentation for operators would make sense? E.g. with small descriptions for default Blender operator like shown below.

Any thoughts?

object.convert:

  • :white_check_mark: support context override
  • can be overridden using selected_editable_objects
  • active object is not affected

object.make_single_user :

  • :x: context override
  • check view layer selected objects explicitly
  • active object is not affected

object.transform_apply:

  • :white_check_mark: support context override
  • can be overridden using selected_editable_objects
  • active object is not affected

Hehe ! This is a very important topic. FWIW some work has already been done, somewhat successfully. You might be interested in the discussion on this BSE page https://blender.stackexchange.com/questions/248274/a-comprehensive-list-of-operator-overrides

In the second answer there is a python script approach that looks promising.

Current operator table
Operator Required context members Q&A’s
ed.lib_id_generate_preview() id - Object reference #1
ed.lib_id_load_custom_preview() id - Object reference #1
file.execute() window - Window reference
area - Area reference
fluid.bake_data() scene - Scene reference
active_object - Object reference
#1
image.save_sequence() area - Area reference #1
info.report_copy() area - Area reference
info.select_all() area - Area reference
mesh.customdata_custom_
splitnormals_clear()
mesh - Mesh reference
object.bake() selected_objects - Sequence of Object references #1
object.delete() selected_objects - Sequence of Object references #1, #2
object.duplicates_make_real() selected_objects - Sequence of Object references
object.empty_image_add() area - Area reference
region - Region reference
#1
object.geometry_nodes_input_
attribute_toggle()
object - Sequence of Object references
selected_editable_objects - Sequence of Object references
object.join() active_object - Object reference
selected_editable_objects - Sequence of Object references
#1, #2, #3
object.make_single_user() selected_objects - Sequence of Object references
object.material_slot_remove() object - Object reference #1, #2, #3
object.modifier_apply() object - Object reference
view_layer - Viewlayer reference (Optional)
scene - Scene reference (Optional)
#1, #2, #3, #4, #5
object.modifier_copy_
to_selected()
object - Object reference
selected_objects - Sequence of Object references
#1, #2
object.modifier_move_down() object - Object reference #1, #2, #3
object.modifier_move_to_index() object - Object reference
object.modifier_move_up() object - Object reference #1, #2, #3
object.origin_set() selected_editable_objects - Sequence of Object references #1, #2
object.parent_clear() selected_editable_objects - Sequence of Object references
object.parent_set() object - Object reference
selected_editable_objects - Sequence of Object references
object.posemode_toggle() active_object - Object reference
object.select_all() area - Area reference
object.shade_smooth() selected_editable_objects - Sequence of Object references #1, #2
object.transform_apply() selected_editable_objects - Sequence of Object references #1
palette.extract_from_image() area - Area reference #1
ptcache.bake() scene - Scene reference
active_object - Object reference
pointcache - Pointcache reference
#1, #2, #3, #4, #5
render.opengl() area - Area reference #1, #2
screen.area_close() area - Area reference #1
screen.area_dupli() area - Area reference #1
screen.area_split() area - Area reference #1
script.execute_preset() window - Window reference
area - Area reference
#1
sequencer.sound_strip_add() area - Area reference #1
text.reload() edit_text - Text reference
text.run_script() edit_text - Text reference #1
view3d.view_axis() area - Area reference
region - Region reference
#1
view3d.walk area - Area reference
region - Region reference
#1, #2
workspace.delete() workspace - Workspace reference

Cheers

That’s super useful, I’ll check it out!

I wonder if we would benefit from having a general Github page for this where it will be easier to fit as many notes for each operator as we need, list all operators, maybe use some code parsing to fill in some notes (e.g. lots of operators reuse same poll methods in Blender source code).

I’ve started this kind of page (before I’ve found it kind of exists on stackexchange) but my page only has info for a couple operators I was investigating recently - https://andrej730.github.io/bpy.ops.context/

PS Don’t even mean as just a compliment, just a fact of life - for the past two years whatever caveat I meet with Blender Python API I find some post of you mentioning it 4 years ago :smile:

But still, there are more than 10000 different poll functions in the whole Blender code… Creating such a list might be a big chunk of work.

Probably better to write a script that looks for the poll call for a specific operator, directly in the source code. (this should be fun to do :sweat_smile: )

Hehe thank you. Turns out we all hit the same roadblocks and milestones on our programming journeys. Kind of what happens in life journeys, too :slight_smile: Yup, a github page parallel to the Blender github would be awesome. Could open up possible integrations with IDEs like VSCode for autocomplete. One can always dream :slight_smile:

@Secrop indeed there are so many operators it’s an extremely time consuming endeavour to try to document them, that’s why I (and other contributors) elected on growing the database empirically. The nice thing is that theoretically the most used operators will be documented and time won’t be spent on never-used operators or operators where it doesn’t make sense to override.

Having parsed a few dozens of operator code in C++ manually I’m not sure if it’s even possible to automate finding out the different properties that can be overriden. Often times there are very intricate relations between these properties and the underlying data blocks, sometimes they are mentioned but never used, sometimes they are fetched from another data structure without explicit calls from outside, sometimes you need an actual core Blender dev to tell you it’s not overridable because of X or Y reason. Might work for some of them, though !