Tipragot
628be439b8
Cela permet de ne pas avoir de problèmes de compatibilité car python est dans le git.
141 lines
4.9 KiB
Python
141 lines
4.9 KiB
Python
from pathlib import Path
|
|
from json import loads, dumps
|
|
from typing import Any, Callable, Optional, Union
|
|
|
|
from .text import Text
|
|
from .highlighter import JSONHighlighter, NullHighlighter
|
|
|
|
|
|
class JSON:
|
|
"""A renderable which pretty prints JSON.
|
|
|
|
Args:
|
|
json (str): JSON encoded data.
|
|
indent (Union[None, int, str], optional): Number of characters to indent by. Defaults to 2.
|
|
highlight (bool, optional): Enable highlighting. Defaults to True.
|
|
skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False.
|
|
ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False.
|
|
check_circular (bool, optional): Check for circular references. Defaults to True.
|
|
allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True.
|
|
default (Callable, optional): A callable that converts values that can not be encoded
|
|
in to something that can be JSON encoded. Defaults to None.
|
|
sort_keys (bool, optional): Sort dictionary keys. Defaults to False.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
json: str,
|
|
indent: Union[None, int, str] = 2,
|
|
highlight: bool = True,
|
|
skip_keys: bool = False,
|
|
ensure_ascii: bool = False,
|
|
check_circular: bool = True,
|
|
allow_nan: bool = True,
|
|
default: Optional[Callable[[Any], Any]] = None,
|
|
sort_keys: bool = False,
|
|
) -> None:
|
|
data = loads(json)
|
|
json = dumps(
|
|
data,
|
|
indent=indent,
|
|
skipkeys=skip_keys,
|
|
ensure_ascii=ensure_ascii,
|
|
check_circular=check_circular,
|
|
allow_nan=allow_nan,
|
|
default=default,
|
|
sort_keys=sort_keys,
|
|
)
|
|
highlighter = JSONHighlighter() if highlight else NullHighlighter()
|
|
self.text = highlighter(json)
|
|
self.text.no_wrap = True
|
|
self.text.overflow = None
|
|
|
|
@classmethod
|
|
def from_data(
|
|
cls,
|
|
data: Any,
|
|
indent: Union[None, int, str] = 2,
|
|
highlight: bool = True,
|
|
skip_keys: bool = False,
|
|
ensure_ascii: bool = False,
|
|
check_circular: bool = True,
|
|
allow_nan: bool = True,
|
|
default: Optional[Callable[[Any], Any]] = None,
|
|
sort_keys: bool = False,
|
|
) -> "JSON":
|
|
"""Encodes a JSON object from arbitrary data.
|
|
|
|
Args:
|
|
data (Any): An object that may be encoded in to JSON
|
|
indent (Union[None, int, str], optional): Number of characters to indent by. Defaults to 2.
|
|
highlight (bool, optional): Enable highlighting. Defaults to True.
|
|
default (Callable, optional): Optional callable which will be called for objects that cannot be serialized. Defaults to None.
|
|
skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False.
|
|
ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False.
|
|
check_circular (bool, optional): Check for circular references. Defaults to True.
|
|
allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True.
|
|
default (Callable, optional): A callable that converts values that can not be encoded
|
|
in to something that can be JSON encoded. Defaults to None.
|
|
sort_keys (bool, optional): Sort dictionary keys. Defaults to False.
|
|
|
|
Returns:
|
|
JSON: New JSON object from the given data.
|
|
"""
|
|
json_instance: "JSON" = cls.__new__(cls)
|
|
json = dumps(
|
|
data,
|
|
indent=indent,
|
|
skipkeys=skip_keys,
|
|
ensure_ascii=ensure_ascii,
|
|
check_circular=check_circular,
|
|
allow_nan=allow_nan,
|
|
default=default,
|
|
sort_keys=sort_keys,
|
|
)
|
|
highlighter = JSONHighlighter() if highlight else NullHighlighter()
|
|
json_instance.text = highlighter(json)
|
|
json_instance.text.no_wrap = True
|
|
json_instance.text.overflow = None
|
|
return json_instance
|
|
|
|
def __rich__(self) -> Text:
|
|
return self.text
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
import argparse
|
|
import sys
|
|
|
|
parser = argparse.ArgumentParser(description="Pretty print json")
|
|
parser.add_argument(
|
|
"path",
|
|
metavar="PATH",
|
|
help="path to file, or - for stdin",
|
|
)
|
|
parser.add_argument(
|
|
"-i",
|
|
"--indent",
|
|
metavar="SPACES",
|
|
type=int,
|
|
help="Number of spaces in an indent",
|
|
default=2,
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
from pip._vendor.rich.console import Console
|
|
|
|
console = Console()
|
|
error_console = Console(stderr=True)
|
|
|
|
try:
|
|
if args.path == "-":
|
|
json_data = sys.stdin.read()
|
|
else:
|
|
json_data = Path(args.path).read_text()
|
|
except Exception as error:
|
|
error_console.print(f"Unable to read {args.path!r}; {error}")
|
|
sys.exit(-1)
|
|
|
|
console.print(JSON(json_data, indent=args.indent), soft_wrap=True)
|