How to get render visibility for object?

obj.visible_get() returns object visibility for viewports, but how do I get object visibility for renders?

bpy.types.Object has also hide_render and hide_viewport boolean values but reading those doesn’t seem to always give the correct state for some reason.

Also, visible_get() has optional parameters visible_get(view_layer=None, viewport=None ) where the first is ViewLayer and the second is SpaceView3D.

Maybe in render() those parameters can be obtained and passed to the function to get render visibility?

I found a workaround during rendering, namely if obj is in depsgraph.object_instances then its visible and if not then its invisible.

render_visible_set = {}
for object_instance in depsgraph.object_instances:
    o = object_instance.object
    render_visible_set[o.name_full] = 1

for o in all_objects:
    is_visible = o.name_full in render_visible_set

Someone might wonder why not just iterate over object_instances during rendering and the reason is with bpy.context.scene.render.use_persistent_data == True its required to sync all objects in the scene for the updates to work properly, at least the way I have it setup.

The above workaround didn’t seem take into account all visibility settings from e.g. collections.

What actually worked was recursively parsing Master Collection (scene.collection) to build correct visibility with everything taken into account, including eye icon for collections from view_layer.layer_collection.

It would have made the api easier to use for this if there was a function that returns visibility with everything taken into account that works for both objects and instanced objects.