feat: use tomli-w for config dumps (#103)

This commit is contained in:
banteg
2026-01-12 18:39:54 +04:00
committed by GitHub
parent f638b8c32e
commit 9d3fd1a515
3 changed files with 19 additions and 61 deletions
+1
View File
@@ -18,6 +18,7 @@ dependencies = [
"rich>=14.2.0",
"structlog>=25.5.0",
"sulguk>=0.11.1",
"tomli-w>=1.2.0",
"typer>=0.21.0",
"watchfiles>=0.21.0",
]
+7 -61
View File
@@ -5,6 +5,8 @@ from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
import tomli_w
HOME_CONFIG_PATH = Path.home() / ".takopi" / "takopi.toml"
@@ -92,68 +94,12 @@ class ProjectsConfig:
return tuple(self.chat_map.keys())
def _toml_escape(value: str) -> str:
return value.replace("\\", "\\\\").replace('"', '\\"')
def _format_toml_value(value: Any) -> str:
if isinstance(value, bool):
return "true" if value else "false"
if isinstance(value, int):
return str(value)
if isinstance(value, float):
return repr(value)
if isinstance(value, Path):
return f'"{_toml_escape(str(value))}"'
if isinstance(value, str):
return f'"{_toml_escape(value)}"'
if isinstance(value, (list, tuple)):
inner = ", ".join(_format_toml_value(item) for item in value)
return f"[{inner}]"
raise ConfigError(f"Unsupported config value {value!r}")
def _table_has_scalars(table: dict[str, Any]) -> bool:
return any(not isinstance(value, dict) for value in table.values())
def dump_toml(config: dict[str, Any]) -> str:
lines: list[str] = []
def write_kv(key: str, value: Any) -> None:
lines.append(f"{key} = {_format_toml_value(value)}")
def write_table(name: str, table: dict[str, Any]) -> None:
if lines and lines[-1] != "":
lines.append("")
lines.append(f"[{name}]")
for key, value in table.items():
if isinstance(value, dict):
continue
write_kv(key, value)
for key, value in table.items():
if isinstance(value, dict):
write_table(f"{name}.{key}", value)
for key, value in config.items():
if isinstance(value, dict):
continue
write_kv(key, value)
for key, value in config.items():
if not isinstance(value, dict):
continue
if _table_has_scalars(value):
write_table(key, value)
continue
for subkey, subvalue in value.items():
if isinstance(subvalue, dict):
write_table(f"{key}.{subkey}", subvalue)
else:
write_table(key, value)
break
return "\n".join(lines) + "\n"
try:
dumped = tomli_w.dumps(config)
except (TypeError, ValueError) as e:
raise ConfigError(f"Unsupported config value: {e}") from None
return dumped
def write_config(config: dict[str, Any], path: Path) -> None:
Generated
+11
View File
@@ -581,6 +581,7 @@ dependencies = [
{ name = "rich" },
{ name = "structlog" },
{ name = "sulguk" },
{ name = "tomli-w" },
{ name = "typer" },
{ name = "watchfiles" },
]
@@ -607,6 +608,7 @@ requires-dist = [
{ name = "rich", specifier = ">=14.2.0" },
{ name = "structlog", specifier = ">=25.5.0" },
{ name = "sulguk", specifier = ">=0.11.1" },
{ name = "tomli-w", specifier = ">=1.2.0" },
{ name = "typer", specifier = ">=0.21.0" },
{ name = "watchfiles", specifier = ">=0.21.0" },
]
@@ -620,6 +622,15 @@ dev = [
{ name = "ty", specifier = ">=0.0.8" },
]
[[package]]
name = "tomli-w"
version = "1.2.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" },
]
[[package]]
name = "tqdm"
version = "4.67.1"