Deleting TFile from python

Hi,

I have a problem with a script that opens a lot of files and takes forever to shutdown. The following is a simple script to reproduce the issue:

import ROOT

for i in range(0, 100000):
    file = ROOT.TFile.Open("hsimple.root")
    file.Close()

print "done with opening and closing a file"

This script will run about 10 minutes to open and close the same file 100000 times, print the message that it is done, after that it will take more than an hour for python to quit. GDB suggests that this time is spent in the destruction of the gROOT object, more precisely the list of closed objects (gROOT->GetListOfClosedObjects).

From a ROOT (C++) macro I can work around this by calling the destructor of the file after closing it:

#include <iostream>

#include <TFile.h>
#include <TROOT.h>

void test() {
    for (unsigned int i=0; i<100000; ++i) {
        TFile* file = TFile::Open("hsimple.root");
        file->Close();
        delete file;
    }
    std::cout << "done with opening and closing a file" << std::endl;
}

(Without the delete file line, the behavior is the same as for the python example).

I tried ta add file.Delete() or del file to the python example, however, this did not have any effect. So how can I properly call the destructor of a TFile so that the corresponding object is removed from the list of closed objects?

Regards,
Sebastian

Sebastian,

the two scripts are equivalent: PyROOT will call the destructor for you, as Python clearly owns the file. You can call the destructor directly (using the associated TClass), but that will only lead to crashes, as then the destructor is called twice.

The difference, however, is that PyROOT has a callback that does lookups when objects go away. This is exactly to prevent double deletes.

I don’t understand, however, why it is still being called for deleted objects. I’ll so some digging …

Later,
Wim

Sebastian,

sorry, not awake here. I was thinking that this was the TFile constructor, but it is the Open call. The TFile object from an Open call is not owned by python. I’ll change that. In the mean time, set TFile.Open._creates = True.

Thanks,
Wim

Hi Wim,

setting TFile.Open._creates = True seems to indeed fix the problem for me.

Thank you,
Sebastian