From a0d47808c5191db68e71433bc1e308352b129503 Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Sat, 30 May 2026 05:58:42 -0700 Subject: [PATCH] release: archivebox 0.9.33rc46 --- archivebox/config/collection.py | 23 ++++++++++++++++++++--- etc/package.json | 2 +- pyproject.toml | 8 ++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/archivebox/config/collection.py b/archivebox/config/collection.py index 97f82fc7..bfe2303d 100644 --- a/archivebox/config/collection.py +++ b/archivebox/config/collection.py @@ -1,6 +1,7 @@ __package__ = "archivebox.config" import io +import json import os from typing import Any @@ -43,12 +44,28 @@ def _coerce_to_str_dict(config: Any) -> dict[str, str]: INI files only round-trip strings, so we normalize Machine.config values to strings on the way out and accept the same shape on the way back. Pydantic re-coerces types at read time inside ``get_config``. + + Composite values (``dict`` / ``list`` / ``tuple``) are JSON-encoded so + they round-trip back through pydantic-settings — ``str(some_dict)`` + would produce Python's repr (``{'k': 'v'}`` with single quotes), and + pydantic-settings refuses to parse that as a ``dict`` field, causing + e.g. ``ABX_INSTALL_CACHE`` to crash with ``ValidationError: Input + should be a valid dictionary``. """ if not config: return {} - if hasattr(config, "items"): - return {str(key).upper(): "" if value is None else str(value) for key, value in config.items()} - return {} + if not hasattr(config, "items"): + return {} + flat: dict[str, str] = {} + for key, value in config.items(): + upper_key = str(key).upper() + if value is None: + flat[upper_key] = "" + elif isinstance(value, (dict, list, tuple)): + flat[upper_key] = json.dumps(value, default=str) + else: + flat[upper_key] = str(value) + return flat def _load_file_config_dict() -> tuple[dict[str, str], float | None]: diff --git a/etc/package.json b/etc/package.json index ac542daf..5dd24625 100644 --- a/etc/package.json +++ b/etc/package.json @@ -1,6 +1,6 @@ { "name": "archivebox", - "version": "0.9.33rc45", + "version": "0.9.33rc46", "repository": "github:ArchiveBox/ArchiveBox", "license": "MIT", "dependencies": { diff --git a/pyproject.toml b/pyproject.toml index 55ec99eb..2e51a907 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "archivebox" -version = "0.9.33rc45" +version = "0.9.33rc46" requires-python = ">=3.13" description = "Self-hosted internet archiving solution." authors = [{name = "Nick Sweeting", email = "pyproject.toml@archivebox.io"}] @@ -79,9 +79,9 @@ dependencies = [ ### Extractor dependencies (optional binaries detected at runtime via shutil.which) ### Binary/Package Management "abxbus==2.5.8", # EventBus API - "abxpkg>=1.11.72", # for: detecting, versioning, and installing binaries via apt/brew/pip/npm - "abx-plugins>=1.11.78", # shared ArchiveBox plugin package with Chrome/Puppeteer dependency wiring - "abx-dl>=1.11.78", # shared ArchiveBox downloader package with blocking install preflight + "abxpkg>=1.11.73", # for: detecting, versioning, and installing binaries via apt/brew/pip/npm + "abx-plugins>=1.11.79", # shared ArchiveBox plugin package with Chrome/Puppeteer dependency wiring + "abx-dl>=1.11.79", # shared ArchiveBox downloader package with blocking install preflight ### UUID7 backport for Python <3.14 "uuid7>=0.1.0; python_version < '3.14'", # provides the uuid_extensions module on Python 3.13 ]