Use TypeAdapter for Json serialization (#4183)
This commit is contained in:
parent
0dddc7308d
commit
1d8352b466
|
|
@ -77,7 +77,7 @@ class ArchConfig:
|
|||
services: list[str] = field(default_factory=list)
|
||||
custom_commands: list[str] = field(default_factory=list)
|
||||
|
||||
def unsafe_json(self) -> dict[str, Any]:
|
||||
def unsafe_config(self) -> dict[str, Any]:
|
||||
config: dict[str, list[UserSerialization] | str | None] = {}
|
||||
|
||||
if self.auth_config:
|
||||
|
|
@ -94,7 +94,7 @@ class ArchConfig:
|
|||
|
||||
return config
|
||||
|
||||
def safe_json(self) -> dict[str, Any]:
|
||||
def safe_config(self) -> dict[str, Any]:
|
||||
config: Any = {
|
||||
'version': self.version,
|
||||
'script': self.script,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ import json
|
|||
import readline
|
||||
import stat
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from pydantic import TypeAdapter
|
||||
|
||||
from archinstall.lib.menu.helpers import Confirmation, Selection
|
||||
from archinstall.lib.translationhandler import tr
|
||||
|
|
@ -10,7 +13,6 @@ from archinstall.tui.ui.result import ResultType
|
|||
|
||||
from .args import ArchConfig
|
||||
from .crypt import encrypt
|
||||
from .general import JSON, UNSAFE_JSON
|
||||
from .output import debug, logger, warn
|
||||
from .utils.util import get_password, prompt_dir
|
||||
|
||||
|
|
@ -40,12 +42,18 @@ class ConfigurationOutput:
|
|||
return self._user_creds_file
|
||||
|
||||
def user_config_to_json(self) -> str:
|
||||
out = self._config.safe_json()
|
||||
return json.dumps(out, indent=4, sort_keys=True, cls=JSON)
|
||||
config = self._config.safe_config()
|
||||
|
||||
adapter = TypeAdapter(dict[str, Any])
|
||||
python_dict = adapter.dump_python(config)
|
||||
return json.dumps(python_dict, indent=4, sort_keys=True)
|
||||
|
||||
def user_credentials_to_json(self) -> str:
|
||||
out = self._config.unsafe_json()
|
||||
return json.dumps(out, indent=4, sort_keys=True, cls=UNSAFE_JSON)
|
||||
config = self._config.unsafe_config()
|
||||
|
||||
adapter = TypeAdapter(dict[str, Any])
|
||||
python_dict = adapter.dump_python(config)
|
||||
return json.dumps(python_dict, indent=4, sort_keys=True)
|
||||
|
||||
def write_debug(self) -> None:
|
||||
debug(' -- Chosen configuration --')
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
import json
|
||||
from datetime import date, datetime
|
||||
from enum import Enum
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Any, override
|
||||
|
||||
from archinstall.lib.packages.packages import check_package_upgrade
|
||||
|
||||
|
|
@ -35,55 +31,3 @@ def running_from_host() -> bool:
|
|||
"""
|
||||
is_host = not Path('/run/archiso').exists()
|
||||
return is_host
|
||||
|
||||
|
||||
def jsonify(obj: Any, safe: bool = True) -> Any:
|
||||
"""
|
||||
Converts objects into json.dumps() compatible nested dictionaries.
|
||||
Setting safe to True skips dictionary keys starting with a bang (!)
|
||||
"""
|
||||
|
||||
compatible_types = str, int, float, bool
|
||||
if isinstance(obj, dict):
|
||||
return {
|
||||
key: jsonify(value, safe)
|
||||
for key, value in obj.items()
|
||||
if isinstance(key, compatible_types) and not (isinstance(key, str) and key.startswith('!') and safe)
|
||||
}
|
||||
if isinstance(obj, Enum):
|
||||
return obj.value
|
||||
if hasattr(obj, 'json'):
|
||||
# json() is a friendly name for json-helper, it should return
|
||||
# a dictionary representation of the object so that it can be
|
||||
# processed by the json library.
|
||||
return jsonify(obj.json(), safe)
|
||||
if isinstance(obj, datetime | date):
|
||||
return obj.isoformat()
|
||||
if isinstance(obj, list | set | tuple):
|
||||
return [jsonify(item, safe) for item in obj]
|
||||
if isinstance(obj, Path):
|
||||
return str(obj)
|
||||
if hasattr(obj, '__dict__'):
|
||||
return vars(obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
class JSON(json.JSONEncoder, json.JSONDecoder):
|
||||
"""
|
||||
A safe JSON encoder that will omit private information in dicts (starting with !)
|
||||
"""
|
||||
|
||||
@override
|
||||
def encode(self, o: Any) -> str:
|
||||
return super().encode(jsonify(o))
|
||||
|
||||
|
||||
class UNSAFE_JSON(json.JSONEncoder, json.JSONDecoder):
|
||||
"""
|
||||
UNSAFE_JSON will call/encode and keep private information in dicts (starting with !)
|
||||
"""
|
||||
|
||||
@override
|
||||
def encode(self, o: Any) -> str:
|
||||
return super().encode(jsonify(o, safe=False))
|
||||
|
|
|
|||
Loading…
Reference in New Issue