Page MenuHome

context.scene not updated when context.screen.scene changed in an operator called from a panel.
Closed, ArchivedPublic

Description

System Information
Windows 7 64bit

Blender Version
Broken: 2.71
Worked: 2.70

Short description of error
In a python script, if a panel calls an operator, and that operator changes the scene by setting 'bpy.context.screen.scene', bpy.context.scene is not updated. This causes operators to run on the previous scene.

Exact steps for others to reproduce the error
The following script is as simple as I could make it, also see http://www.pasteall.org/53521/python
(sorry, couldn't get attached files to work)

	import bpy
	
	class TestPanel(bpy.types.Panel):
	    bl_label = "Test Panel"
	    bl_space_type = 'PROPERTIES'
	    bl_region_type = 'WINDOW'
	    bl_context = "scene"
	    def draw(self, context):
	        layout = self.layout
	        row = layout.row()
	        row.operator('test.operator')
	
	class TestOperator(bpy.types.Operator):
	    bl_label = "Test Operator"
	    bl_idname = 'test.operator'
	    def execute(self, context):
	        scene = bpy.data.scenes.new('test')
	        bpy.context.screen.scene = scene
	        print(bpy.context.scene)
	        return{'FINISHED'}
	        
	def register():
	    bpy.utils.register_module(__name__)
	    
	if __name__ == "__main__":
	    register()

Details

Type
Bug

Event Timeline

hudson barkley (snuq) set Type to Bug.
hudson barkley (snuq) created this task.
hudson barkley (snuq) raised the priority of this task from to Needs Triage by Developer.

This is a quirk of how the API works, switching the scene is handled by a notifier, so the result isn't available immediately. Realize this can be problematic.

We could add some way for Python to handle notifiers while the script runs. (wrap wm_event_do_notifiers, eg context.window_manager.handle_notifiers()) .

But this is more an API limit then a bug.

If it's an api limitation, why did it work in 2.70? Also if that same operator is called from the console, it behaves as expected, it's only doing this when called from a panel

Update, this example can be made to work by adding row.operator_context = 'INVOKE_SCREEN' before row.operator('test.operator')

This works because using INVOKE_SCREEN bypasses the buttons context which is default for panels, The buttons context doesn't get updated when assigning a variable to the screen. But the screen context does.