Does a vtkMultiBlockDataSet own a copy of its blocks in Python?


I’ve been wondering about the data model of a multiblock dataset using the Python API. Using a simplified version of this example:

import weakref
from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet
from vtkmodules.vtkFiltersSources import vtkSphereSource

# Make a tree.
root = vtkMultiBlockDataSet()

branch = vtkMultiBlockDataSet()
root.SetBlock(0, branch)

# Make some leaves.
leaf1 = vtkSphereSource()
leaf1.SetCenter(0, 0, 0)
branch.SetBlock(0, leaf1.GetOutput())

leaf2 = vtkSphereSource()
leaf2.SetCenter(1.75, 2.5, 0)
branch.SetBlock(1, leaf2.GetOutput())

leaf3 = vtkSphereSource()
leaf3.SetCenter(4, 0, 0)
root.SetBlock(1, leaf3.GetOutput())

# show that leaf1's output can be returned from the multiblock
print(branch.GetBlock(0) is leaf1.GetOutput())  # True

# show that leaf1 can be deallocated none the less
wref = weakref.ref(leaf1)
del leaf1
print(wref() is None)  # True

# show that the vtkMultiBlockDataSet still works
print(repr(branch.GetBlock(0)))  # a perfectly fine vtkPolyData

In the above snippet, we can see

  1. the dataset can return the exact object from which it was created. This suggests that the dataset only holds a reference to the original object.
  2. The original object is deallocated when its name is deleted. This suggests that the dataset does not hold a reference to the original object. (This is also true for a weakref on leaf1.GetOutput().)
  3. After the original object is deallocated, the dataset can return a copy of the original object just fine.

I can’t form a consistent mental model around this behaviour. Is there a simple explanation?