11import json
2+ import pickle
23
34from os import path
45
1516 Table ,
1617)
1718from Orange .data .io import FileFormat
19+ from Orange .data .io_base import PICKLE_PROTOCOL
1820
1921from Orange .version import short_version as ORANGE_VERSION # noqa N812
2022from orangecontrib .spectroscopy .io import HDF5MetaReader
@@ -38,7 +40,7 @@ def read_domain(sub):
3840 if f'{ sub } _args' in d
3941 else ['{}' ] * len (subdomain )
4042 )
41- for attr , args in zip (subdomain , subdomain_args , strict = False ):
43+ for attr , args in zip (subdomain , subdomain_args ): # noqa B905
4244 yield attr [0 ], attr [1 ], json .loads (args )
4345
4446 def make_var (name , header , args ):
@@ -141,6 +143,48 @@ def parse(attr):
141143 f .create_dataset (f'metas/{ i } ' , data = col_data , dtype = col_type )
142144 cls .write_table_metadata (filename , data )
143145
146+ @classmethod
147+ def write_table_metadata (cls , filename , data ):
148+ dump_dict = {}
149+ for key , value in data .attributes .items ():
150+ if isinstance (value , str ):
151+ dump_dict [key ] = value
152+ else :
153+ try :
154+ dump_dict [key ] = json .dumps (value )
155+ except TypeError :
156+ # value is not JSON serializable, fall back to pickle
157+ dump_dict [key ] = pickle .dumps (value , protocol = PICKLE_PROTOCOL ).hex ()
158+
159+ with h5py .File (filename , 'r+' ) as f :
160+ metadata_group = f .require_group ('metadata' )
161+ str_dtype = h5py .string_dtype ()
162+ for key , value in dump_dict .items ():
163+ metadata_group .create_dataset (key , data = value , dtype = str_dtype )
164+
165+ @classmethod
166+ def set_table_metadata (cls , filename , data ):
167+ with h5py .File (filename , 'r' ) as f :
168+ if 'metadata' in f :
169+ metadata_group = f ['metadata' ]
170+ for key in metadata_group :
171+ value = metadata_group [key ][()]
172+ if isinstance (value , bytes ):
173+ value = value .decode ('utf-8' )
174+ if value .startswith ('{' ) or value .startswith ('[' ):
175+ try :
176+ value = json .loads (value )
177+ except json .JSONDecodeError :
178+ pass
179+ elif value .startswith (f"80{ PICKLE_PROTOCOL :02x} " ):
180+ try :
181+ value = pickle .loads (bytes .fromhex (value ))
182+ except (pickle .UnpicklingError , ValueError ):
183+ pass
184+ data .attributes [key ] = value
185+ else :
186+ super ().set_table_metadata (filename , data )
187+
144188
145189class IRisF1HDF5Reader (FileFormat ):
146190 """Reader for IRsweep IRis-F1 HDF5 _processed_data files"""
0 commit comments