{"record":{"id":"89a84ba10298627c","repo":"microsoft/qlib","slug":"only-py-yml-yaml-json-type-are-supported-now","errorCode":null,"errorMessage":"Only py/yml/yaml/json type are supported now!","messagePattern":"Only py/yml/yaml/json type are supported now!","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"error","filePath":"qlib/rl/contrib/naive_config_parser.py","lineNumber":37,"sourceCode":"            v.pop(DELETE_KEY, False)\n            b[k] = merge_a_into_b(v, b[k])\n        else:\n            b[k] = v\n    return b\n\n\ndef check_file_exist(filename: str, msg_tmpl: str = 'file \"{}\" does not exist') -> None:\n    if not os.path.isfile(filename):\n        raise FileNotFoundError(msg_tmpl.format(filename))\n\n\ndef parse_backtest_config(path: str) -> dict:\n    abs_path = os.path.abspath(path)\n    check_file_exist(abs_path)\n\n    file_ext_name = os.path.splitext(abs_path)[1]\n    if file_ext_name not in (\".py\", \".json\", \".yaml\", \".yml\"):\n        raise IOError(\"Only py/yml/yaml/json type are supported now!\")\n\n    with tempfile.TemporaryDirectory() as tmp_config_dir:\n        with tempfile.NamedTemporaryFile(dir=tmp_config_dir, suffix=file_ext_name) as tmp_config_file:\n            if platform.system() == \"Windows\":\n                tmp_config_file.close()\n\n            tmp_config_name = os.path.basename(tmp_config_file.name)\n            shutil.copyfile(abs_path, tmp_config_file.name)\n\n            if abs_path.endswith(\".py\"):\n                tmp_module_name = os.path.splitext(tmp_config_name)[0]\n                sys.path.insert(0, tmp_config_dir)\n                module = import_module(tmp_module_name)\n                sys.path.pop(0)\n\n                config = {k: v for k, v in module.__dict__.items() if not k.startswith(\"__\")}\n\n                del sys.modules[tmp_module_name]","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/rl/contrib/naive_config_parser.py#L19-L55","documentation":"parse_backtest_config (qlib/rl/contrib/naive_config_parser.py:37) dispatches on the file extension and only supports .py, .json, .yaml, and .yml backtest configs (py configs are imported as a temp module; json/yaml are parsed). Any other extension (.yml.bak, .toml, .ini, .txt, no extension) raises IOError(\"Only py/yml/yaml/json type are supported now!\").","triggerScenarios":"Calling parse_backtest_config on files with extensions outside (.py, .json, .yaml, .yml), e.g. 'config.toml', 'config.yml.bak', 'config.txt', or extensionless files.","commonSituations":"Renaming configs (leaving .bak or ~ suffixes); trying to use TOML/INI configs with the RL backtest entry point; editor temp files being picked up by glob patterns.","solutions":["Rename the config to end in .py, .json, .yaml, or .yml","Convert TOML/INI configs to YAML before passing them to parse_backtest_config","Filter globbed file lists by allowed suffixes before parsing"],"exampleFix":"# before\nconfig = parse_backtest_config('backtest_config.toml')  # IOError\n\n# after\n# convert to yaml, then\nconfig = parse_backtest_config('backtest_config.yaml')","handlingStrategy":"validation","validationCode":"from pathlib import Path\next = Path(path).suffix.lower()\nassert ext in ('.py', '.json', '.yaml', '.yml'), f'unsupported config extension: {ext}'","typeGuard":"def is_supported_config(path) -> bool:\n    return Path(path).suffix.lower() in ('.py', '.json', '.yaml', '.yml')","tryCatchPattern":"try:\n    cfg = parse_backtest_config(path)\nexcept IOError as e:\n    raise ValueError('convert config to .py/.json/.yaml/.yml') from e","preventionTips":["Standardize team configs on YAML","Strip .bak/~ editor suffixes before passing files to parsers"],"tags":["qlib","rl","backtest","config","file-format","io-error"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}