TRIQS / h5

A high-level C++ interface to the hdf5 library
https://triqs.github.io/h5
Other
3 stars 7 forks source link

print (__repr__) partially broken in some cases in python #27

Open the-hampel opened 3 months ago

the-hampel commented 3 months ago

When creating an h5 archive in python and trying to check the variable pointing to the archive after it was used gives an error:

from h5 import HDFArchive
import sys
from triqs.gf import MeshImFreq

mesh = MeshImFreq(beta=40, statistic='Fermion',n_iw=401)
with HDFArchive('test.h5', 'w') as ar:
    ar['mesh'] = mesh

print(sys.getrefcount(ar))
print(ar)

the last line will show the error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[10], line 12
      9     mesh = ar['mesh']
     11 print(sys.getrefcount(ar))
---> 12 print(ar)
     13 gc.collect()
     14 # gc.get_objects()

File [~/git/ccq-software-build/triqs/3_unst_nix2.3_llvm/installation/lib/python3.11/site-packages/h5/archive.py:264](http://127.0.0.1:7777/lab/tree/Dropbox/work/LiV2O4/~/git/ccq-software-build/triqs/3_unst_nix2.3_llvm/installation/lib/python3.11/site-packages/h5/archive.py#line=263), in HDFArchiveGroup.__str__(self)
    261         raise ValueError("oopps %s"%name)
    263 s= "HDFArchive%s with the following content:\n"%(" (partial view)" if self.is_top_level else '')
--> 264 s+='\n'.join([ '  '+ pr(n) for n in list(self.keys()) ])
    265 return s

File ~/git/ccq-software-build/triqs/3_unst_nix2.3_llvm/installation/lib/python3.11/site-packages/h5/archive.py:264, in <listcomp>(.0)
    261         raise ValueError("oopps %s"%name)
    263 s= "HDFArchive%s with the following content:\n"%(" (partial view)" if self.is_top_level else '')
--> 264 s+='\n'.join([ '  '+ pr(n) for n in list(self.keys()) ])
    265 return s

File ~/git/ccq-software-build/triqs/3_unst_nix2.3_llvm/installation/lib/python3.11/site-packages/h5/archive.py:256, in HDFArchiveGroup.__str__.<locals>.pr(name)
    255 def pr(name) :
--> 256     if self.is_group(name) :
    257         return "%s : subgroup"%name
    258     elif self.is_data(name) : # can be an array of a number

File [~/git/ccq-software-build/triqs/3_unst_nix2.3_llvm/installation/lib/python3.11/site-packages/h5/archive_basic_layer.py:66](http://127.0.0.1:7777/lab/tree/Dropbox/work/LiV2O4/~/git/ccq-software-build/triqs/3_unst_nix2.3_llvm/installation/lib/python3.11/site-packages/h5/archive_basic_layer.py#line=65), in HDFArchiveGroupBasicLayer.is_group(self, p)
     64 """Is p a subgroup ?"""
     65 assert len(p)>0 and p[0]!='/'
---> 66 return p in self.cached_keys and self._group.has_subgroup(p)

AttributeError: 'HDFArchive' object has no attribute '_group'

Such scenario is interesting in cases where one wants to debug a script. For example after these lines a print(globals()) will fail with the error shown above. The problem is somehow that ar still points to the archive to some degree. Is it properly closed at this point? I think not really. Consider the above written h5 archive is present and one starts a new python script, now reading the mesh without loading the module:

from h5 import HDFArchive
import sys
import gc

with HDFArchive('test.h5', 'r') as ar:
    mesh = ar['mesh']

print(sys.getrefcount(ar))
gc.collect()
print(ar)

prinat(ar) still shows an existing h5 archive, with the same error, even though the garbage collector was run ar is still present.

Or maybe this is intended behavior of Python let me know.