@@ -2342,5 +2342,66 @@ def testScalarHdf5Fields(self):
23422342 series_read_again .close ()
23432343
23442344
2345+ def testKeepaliveComponentExtraction (self ):
2346+ """Test that keepalive specifications guard root objects from garbage collection."""
2347+ for ext in tested_file_extensions :
2348+ self .backend_keepalive_component_extraction (ext )
2349+
2350+ def backend_keepalive_component_extraction (self , file_ending ):
2351+ """Helper function that creates an openPMD Series, extracts a component,
2352+ discards the parent objects, forces garbage collection, and then writes data
2353+ using only the returned component."""
2354+ import gc
2355+
2356+ filename = "../samples/unittest_py_keepalive." + file_ending
2357+ path = filename
2358+
2359+ def get_component_only ():
2360+ """
2361+ Create a Series, access a component, discard the Series and Iteration,
2362+ and return only the component. The keepalive specification should
2363+ guard the root objects from garbage collection.
2364+ """
2365+ series = io .Series (path , io .Access .create )
2366+ backend = series .backend
2367+ iteration = series .iterations [0 ]
2368+ mesh = iteration .meshes ["E" ]
2369+ component = mesh ["x" ]
2370+
2371+ mesh .axis_labels = ["x" , "y" ]
2372+ component .reset_dataset (io .Dataset (np .dtype ("float" ), [10 , 10 ]))
2373+
2374+ del iteration
2375+ del mesh
2376+ del series
2377+ gc .collect ()
2378+
2379+ return component , backend
2380+
2381+ component , backend = get_component_only ()
2382+ gc .collect ()
2383+
2384+ component [:, :] = np .reshape (
2385+ np .arange (100 , dtype = np .dtype ("float" )),
2386+ [10 , 10 ]
2387+ )
2388+
2389+ component .series_flush ()
2390+ if backend == "ADIOS2" :
2391+ # need to close the step for data to become visible in ADIOS2
2392+ # cant close the step since we threw away the Iteration, so we need
2393+ # to trigger the GC here
2394+ del component
2395+ gc .collect ()
2396+
2397+ read = io .Series (path , io .Access .read_only )
2398+ loaded = read .iterations [0 ].meshes ["E" ]["x" ][:]
2399+ read .flush ()
2400+ np .testing .assert_array_equal (
2401+ loaded ,
2402+ np .reshape (np .arange (100 , dtype = np .dtype ("float" )), [10 , 10 ])
2403+ )
2404+
2405+
23452406if __name__ == '__main__' :
23462407 unittest .main ()
0 commit comments