# Copyright (c) Facebook, Inc. and its affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. # import os, json from os import path as osp from pathlib import Path from collections import namedtuple support_types = ('str', 'int', 'bool', 'float', 'none') def convert_param(original_lists): assert isinstance(original_lists, list), 'The type is not right : {:}'.format(original_lists) ctype, value = original_lists[0], original_lists[1] assert ctype in support_types, 'Ctype={:}, support={:}'.format(ctype, support_types) is_list = isinstance(value, list) if not is_list: value = [value] outs = [] for x in value: if ctype == 'int': x = int(x) elif ctype == 'str': x = str(x) elif ctype == 'bool': x = bool(int(x)) elif ctype == 'float': x = float(x) elif ctype == 'none': if x.lower() != 'none': raise ValueError('For the none type, the value must be none instead of {:}'.format(x)) x = None else: raise TypeError('Does not know this type : {:}'.format(ctype)) outs.append(x) if not is_list: outs = outs[0] return outs def load_config(path, extra, logger): path = str(path) if hasattr(logger, 'log'): logger.log(path) assert os.path.exists(path), 'Can not find {:}'.format(path) # Reading data back with open(path, 'r') as f: data = json.load(f) content = { k: convert_param(v) for k,v in data.items()} assert extra is None or isinstance(extra, dict), 'invalid type of extra : {:}'.format(extra) if isinstance(extra, dict): content = {**content, **extra} Arguments = namedtuple('Configure', ' '.join(content.keys())) content = Arguments(**content) if hasattr(logger, 'log'): logger.log('{:}'.format(content)) return content def configure2str(config, xpath=None): if not isinstance(config, dict): config = config._asdict() def cstring(x): return "\"{:}\"".format(x) def gtype(x): if isinstance(x, list): x = x[0] if isinstance(x, str) : return 'str' elif isinstance(x, bool) : return 'bool' elif isinstance(x, int): return 'int' elif isinstance(x, float): return 'float' elif x is None : return 'none' else: raise ValueError('invalid : {:}'.format(x)) def cvalue(x, xtype): if isinstance(x, list): is_list = True else: is_list, x = False, [x] temps = [] for temp in x: if xtype == 'bool' : temp = cstring(int(temp)) elif xtype == 'none': temp = cstring('None') else : temp = cstring(temp) temps.append( temp ) if is_list: return "[{:}]".format( ', '.join( temps ) ) else: return temps[0] xstrings = [] for key, value in config.items(): xtype = gtype(value) string = ' {:20s} : [{:8s}, {:}]'.format(cstring(key), cstring(xtype), cvalue(value, xtype)) xstrings.append(string) Fstring = '{\n' + ',\n'.join(xstrings) + '\n}' if xpath is not None: parent = Path(xpath).resolve().parent parent.mkdir(parents=True, exist_ok=True) if osp.isfile(xpath): os.remove(xpath) with open(xpath, "w") as text_file: text_file.write('{:}'.format(Fstring)) return Fstring def dict2config(xdict, logger): assert isinstance(xdict, dict), 'invalid type : {:}'.format( type(xdict) ) Arguments = namedtuple('Configure', ' '.join(xdict.keys())) content = Arguments(**xdict) if hasattr(logger, 'log'): logger.log('{:}'.format(content)) return content