Calling a function via button but also when saving .blend

Beginner here.
I have a function which is called by an operator which is connected to a UI button.

def actuallyDoIt(caller):
    caller.report({'INFO'}, 'Button clicked.')

class DoThatStuff(bpy.types.Operator):
    bl_idname = 'mything.dothatstuff'
    bl_label = 'Click this'
    def execute(self, context): 
        actuallyDoIt(self)
        return {'FINISHED'}

At least Google taught me that that’s how it’s done. It might be completely wrong.
Next I want to make it so that this function is also called when saving the .blend, so I registered it as follows:

bpy.app.handlers.save_pre.append(actuallyDoIt)

But obviously when the function is not called by the operator, it doesn’t know what the caller is, and instead of it executing the caller.report I am getting this error:

AttributeError: 'NoneType' object has no attribute 'report'

Any kind of advice is welcome.

Okay, after some googling I think that executing a report from outside a class is really not supported by Blender at the moment.
Apparently about a year ago, there was an attempt to add this functionality, but it never actually happened. That’s too bad.
I’ll have to stick with regular print commands then.

You can achieve this by calling the operator from the save_pre handler. Example:


import bpy


def actuallyDoIt(caller):
    caller.report({'INFO'}, 'Button clicked.')


class DoThatStuff(bpy.types.Operator):
    bl_idname = 'mything.dothatstuff'
    bl_label = 'Click this'
    def execute(self, context): 
        actuallyDoIt(self)
        return {'FINISHED'}
    

def CallDoThatStuffOperator(none):
    bpy.ops.mything.dothatstuff()
    

bpy.utils.register_class(DoThatStuff)
bpy.app.handlers.save_pre.append(CallDoThatStuffOperator)

Hope this helps!

Wow, thank you. I didn’t know I could call operators like that. That’s really helpful.

The only issue I’m having now is that my report message is not being displayed as a green line in the Info bar, but only appears in the system console. I wanted some kind of confirmation message for the average user.
So far I’ve only been able to get that via press of a UI button.