I don't think you're going to get a complete script for this, and no the function doesn't exist in Blender by default.
The basic function is easy to design and here it is in pseudocode:
examined = set()
to_examine = [bpy.context.active_object]
object = to_examine
for new_object in EACH_OBJECT_RELATED_TO_OBJECT:
if not new_object in examined:
for object in examined:
This is a common pattern when you are walking a tree but only need to know the names of the nodes. Every time it encounters an object it hasn't seen before, it adds it to the list of objects it needs to process (
to_examine). Whenever it wants to process an object it removes it from that list.
Each time it finishes processing an object it remembers the object by adding it to the
At the end, every object that is related to the original object is in the
The real problem is EACH_OBJECT_RELATED_TO_OBJECT. You need to evaluate every aspect of the original object, like parenting, children, modifiers, et cetera, to see if that aspect turns up an object.
But that code is tedious to write, and very fragile. For instance, here's a tiny fragment of code to find the objects related because they're in a modifier:
if modifier.type == 'BOOLEAN':
if modifier.type == 'MIRROR':
That happens to handle the two modifiers in your object, but to be complete, there needs to be an if for every modifier type, that either does nothing, because the modifier doesn't use another object, or returns the modifier's object, and every modifier that has an object identifies it through a different property.
So the final script would be full of functions to identify modifiers by type, constraints by type, et cetera and return any objects used by those pieces.