Source code for pythonwrench.json

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
from io import StringIO, TextIOBase
from os import PathLike
from pathlib import Path
from typing import Any, Optional, Union

from pythonwrench._core import _setup_output_fpath
from pythonwrench.cast import as_builtin
from pythonwrench.functools import function_alias

# -- Dump / Save / Serialize content to JSON --


[docs] def dump_json( data: Any, file: Union[str, Path, None, TextIOBase] = None, /, *, overwrite: bool = True, make_parents: bool = True, to_builtins: bool = False, # JSON dump kwargs indent: Optional[int] = 4, ensure_ascii: bool = False, **json_dumps_kwds, ) -> str: r"""Dump content to JSON format into a string and/or file. Args: data: Data to dump to JSON. file: Optional filepath to save dumped data. Not used if None. defaults to None. overwrite: If True, overwrite target filepath. defaults to True. make_parents: Build intermediate directories to filepath. defaults to True. to_builtins: If True, converts data to builtin equivalent before saving. defaults to False. indent: JSON indentation size in spaces. defaults to 4. ensure_ascii: Ensure only ASCII characters. defaults to False. \*\*json_dump_kwds: Other args passed to `json.dumps`. Returns: Dumped content as string. """ content = dumps_json( data, to_builtins=to_builtins, indent=indent, ensure_ascii=ensure_ascii, **json_dumps_kwds, ) if isinstance(file, (str, Path, PathLike)): file = _setup_output_fpath(file, overwrite, make_parents) with open(file, "w") as opened_file: opened_file.write(content) elif isinstance(file, TextIOBase): file.write(content) elif file is None: pass else: msg = f"Invalid argument type {type(file)}. (expected one of str, Path, TextIOBase, None)" raise TypeError(msg) return content
def dumps_json( data: Any, /, *, to_builtins: bool = False, # JSON dump kwargs indent: Optional[int] = 4, ensure_ascii: bool = False, **json_dumps_kwds, ) -> str: with StringIO() as buffer: _serialize_json( data, buffer, to_builtins=to_builtins, indent=indent, ensure_ascii=ensure_ascii, **json_dumps_kwds, ) content = buffer.getvalue() return content def save_json( data: Any, file: Union[str, Path, PathLike, TextIOBase], /, *, overwrite: bool = True, make_parents: bool = True, to_builtins: bool = False, # JSON dump kwargs indent: Optional[int] = 4, ensure_ascii: bool = False, **json_dumps_kwds, ) -> None: if isinstance(file, (str, Path, PathLike)): file = _setup_output_fpath(file, overwrite=overwrite, make_parents=make_parents) file = open(file, "w") close = True elif isinstance(file, TextIOBase): close = False else: msg = f"Invalid argument type {type(file)}. (expected one of str, Path, PathLike, TextIOBase)" raise TypeError(msg) _serialize_json( data, file, to_builtins=to_builtins, indent=indent, ensure_ascii=ensure_ascii, **json_dumps_kwds, ) if close: file.close() def _serialize_json( data: Any, buffer: TextIOBase, /, *, to_builtins: bool = False, **json_dumps_kwds, ) -> None: if to_builtins: data = as_builtin(data) return json.dump(data, buffer, **json_dumps_kwds) # -- Load / Read / Parse JSON content -- def load_json( file: Union[str, Path, PathLike, TextIOBase], /, **json_loads_kwds, ) -> Any: if isinstance(file, (str, Path, PathLike)): file = open(file, "r") close = True else: close = False data = _parse_json(file, **json_loads_kwds) if close: file.close() return data def loads_json(content: str, /, **json_loads_kwds) -> Any: with StringIO(content) as buffer: return _parse_json(buffer, **json_loads_kwds) @function_alias(load_json) def read_json(*args, **kwargs): ... def _parse_json(buffer: TextIOBase, **json_loads_kwds) -> Any: return json.load(buffer, **json_loads_kwds)