Support a way to temporarily override the context from Python.
- Added method Context.temp_override context manager.
- Special support for windowing variables "window", "area" and "region", other context members such as "active_object".
- Nesting context overrides is supported.
- Previous windowing members are restored when the context exists unless they have been removed.
- Overriding context members by passing a dictionary into operators in bpy.ops has been deprecated and warns when used.
This allows the window in a newly loaded file to be used, see: T92464
Motivation for this Patch
The initial motivation was to let script authors select a window after loading a file to continue operations after a file is loaded and the context's window is cleared.
However this has wider implications we should consider, one is that script authors will be able to run operators in contexts that currently don't use an active window - Python timers for example.
This can be seen as a benefit but also allows for operators being executed outside the main event loop - which we might want to avoid.
If there are contexts where this shouldn't be possible we could explicitly prevent it too.
This patch is a test for overriding some of the context members, it could be extended on as needed.
Notes:
- bpy.context.temp_override name could change.
- This could be extended to override other kinds of data, although screen/scene are tried to the window internally.
- pyrna_struct_as_ptr and related API's should be committed separately.
This example script adds a cube in the non-active window (which may have a different scene).
import bpy
from bpy import context
wm = context.window_manager
win_active = context.window
win_other = None
for win_iter in wm.windows:
if win_iter != win_active:
win_other = win_iter
break
# Add cube in the other window.
with context.temp_override(window=win_other):
bpy.ops.mesh.primitive_cube_add()