Coverage for /builds/svesch/cikit/src/cikit/json_utils.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-10-09 14:17 +0000

1# SPDX-License-Identifier: GPL-3.0-or-later 

2"""JSON file helpers for cikit. 

3 

4Author: 

5 Sven Schlender 

6Date: 

7 2026-09-21 

8""" 

9 

10import json 

11from pathlib import Path 

12from typing import Any 

13 

14from cikit.errors import CiToolsError 

15 

16 

17def load_json_file(filepath: Path, *, description: str) -> Any: 

18 """Load JSON data from a file. 

19 

20 Missing files are treated as empty data and return an empty dictionary. 

21 

22 Args: 

23 filepath: Path to the JSON file. 

24 description: Human-readable description used in error messages. 

25 

26 Returns: 

27 Parsed JSON content, or an empty dictionary if the file does not exist. 

28 

29 Raises: 

30 CiToolsError: If the file cannot be read or parsed as JSON. 

31 """ 

32 if not filepath.exists(): 

33 return {} 

34 

35 try: 

36 with filepath.open("r", encoding="utf-8") as file: 

37 return json.load(file) 

38 except (OSError, json.JSONDecodeError) as exp: 

39 raise CiToolsError(f"Failed to read {description} from '{filepath}': {exp}") from exp 

40 

41 

42def save_json_file(filepath: Path, data: Any, *, description: str): 

43 """Write JSON data to a file. 

44 

45 Parent directories are created automatically if required. 

46 

47 Args: 

48 filepath: Path to the JSON file. 

49 data: JSON-serializable data to store. 

50 description: Human-readable description used in error messages. 

51 

52 Raises: 

53 CiToolsError: If the file cannot be written or serialized as JSON. 

54 """ 

55 try: 

56 filepath.parent.mkdir(parents=True, exist_ok=True) 

57 with filepath.open("w", encoding="utf-8") as file: 

58 json.dump(data, file, indent=4) 

59 except (OSError, TypeError, ValueError) as exp: 

60 raise CiToolsError(f"Failed to write {description} to '{filepath}': {exp}") from exp