From adbee07133b2cd2017c7adb924ab2c8c8e95e9bd Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Fri, 31 Jul 2026 20:10:50 -0700 Subject: [PATCH] refactor: remove final Base-specific package residue --- CHANGELOG.md | 2 ++ lib/python/base_cli/ide_schema.py | 49 ------------------------------- lib/python/base_cli/logging.py | 4 +-- tests/test_generic_core.py | 7 +++++ tests/test_ide_schema.py | 41 -------------------------- tests/test_logging.py | 4 +-- 6 files changed, 13 insertions(+), 94 deletions(-) delete mode 100644 lib/python/base_cli/ide_schema.py delete mode 100644 tests/test_ide_schema.py diff --git a/CHANGELOG.md b/CHANGELOG.md index f4b00fe..7cf0624 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and versions are tracked in the repo-root `VERSION` file. Base-shaped `UserConfig` types from the public package facade. - Make command-filter normalization consumer-neutral by default. Consumers can provide a normalizer callback for legacy prefixes or aliases. +- Remove the Base-branded logger formatter and IDE schema parser from the + standalone package; those consumer-specific concerns now belong to adapters. - Make command protocol schemas consumer-owned. The generic protocol now ships only framing and validation, with `COMMAND_PROTOCOL_V1` as its default header; consumers can register schemas and preserve a legacy header through diff --git a/lib/python/base_cli/ide_schema.py b/lib/python/base_cli/ide_schema.py deleted file mode 100644 index d42b6b3..0000000 --- a/lib/python/base_cli/ide_schema.py +++ /dev/null @@ -1,49 +0,0 @@ -from __future__ import annotations - -import json -from typing import Any - - -__all__ = [ - "parse_ide_extensions", - "parse_ide_settings", -] - - -def parse_ide_extensions(context: str, extensions_data: Any) -> tuple[str, ...]: - if extensions_data is None: - return () - if not isinstance(extensions_data, list): - raise ValueError(f"{context} must be a list when provided.") - - extensions: list[str] = [] - for index, extension in enumerate(extensions_data, start=1): - if not isinstance(extension, str) or not extension.strip(): - raise ValueError(f"{context}[{index}] must be a non-empty string.") - extensions.append(extension.strip()) - return tuple(extensions) - - -def parse_ide_settings( - context: str, - settings_data: Any, - *, - auto_setting_keys: frozenset[str] | None = None, -) -> dict[str, Any]: - if settings_data is None: - return {} - if not isinstance(settings_data, dict): - raise ValueError(f"{context} must be a mapping when provided.") - - settings: dict[str, Any] = {} - for key, value in settings_data.items(): - if not isinstance(key, str) or not key: - raise ValueError(f"{context} keys must be non-empty strings.") - if auto_setting_keys is not None and value == "auto" and key not in auto_setting_keys: - raise ValueError(f"{context}.{key} does not support the special value 'auto'.") - try: - json.dumps(value) - except TypeError as exc: - raise ValueError(f"{context}.{key} must be JSON-serializable.") from exc - settings[key] = value - return settings diff --git a/lib/python/base_cli/logging.py b/lib/python/base_cli/logging.py index 0809f2d..ece8bdb 100644 --- a/lib/python/base_cli/logging.py +++ b/lib/python/base_cli/logging.py @@ -64,7 +64,7 @@ def _user_stream_level(debug: bool, quiet: bool) -> int: def _handler_formatter(formatter: logging.Formatter | None, *, use_color: bool) -> logging.Formatter: if formatter is not None: return formatter - return BaseCliFormatter(use_color=use_color) + return CliFormatter(use_color=use_color) def _use_color(stream: TextIO) -> bool: @@ -102,7 +102,7 @@ def _secure_log_file_open_flags(mode: str) -> int: return flags | os.O_APPEND | os.O_WRONLY -class BaseCliFormatter(logging.Formatter): +class CliFormatter(logging.Formatter): def __init__(self, *, use_utc: bool | None = None, use_color: bool = False) -> None: self.use_utc = use_utc if use_utc is not None else os.environ.get("LOG_UTC") == "1" self.use_color = use_color diff --git a/tests/test_generic_core.py b/tests/test_generic_core.py index 26a1cbb..b06b54f 100644 --- a/tests/test_generic_core.py +++ b/tests/test_generic_core.py @@ -1,5 +1,6 @@ from __future__ import annotations +import importlib.util import json import logging import tempfile @@ -71,3 +72,9 @@ def test_base_specific_path_helpers_are_not_in_generic_module(self) -> None: self.assertFalse(hasattr(paths, "discover_manifest")) self.assertFalse(hasattr(paths, "normalize_runtime_owner")) self.assertFalse(hasattr(base_cli.CliProfile, "legacy_base")) + + def test_consumer_specific_ide_schema_and_formatter_are_not_in_generic_module(self) -> None: + import base_cli.logging as logging_module + + self.assertIsNone(importlib.util.find_spec("base_cli.ide_schema")) + self.assertFalse(hasattr(logging_module, "BaseCliFormatter")) diff --git a/tests/test_ide_schema.py b/tests/test_ide_schema.py deleted file mode 100644 index 5ddb5d5..0000000 --- a/tests/test_ide_schema.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import annotations - -import unittest - -from base_cli.ide_schema import parse_ide_extensions -from base_cli.ide_schema import parse_ide_settings - - -class IdeSchemaTests(unittest.TestCase): - def test_parse_ide_extensions_trims_and_rejects_empty_values(self) -> None: - self.assertEqual( - parse_ide_extensions("ide.vscode.extensions", [" ms-python.python "]), - ("ms-python.python",), - ) - - with self.assertRaisesRegex(ValueError, r"ide.vscode.extensions\[1\]"): - parse_ide_extensions("ide.vscode.extensions", [""]) - - def test_parse_ide_settings_allows_auto_as_literal_by_default(self) -> None: - self.assertEqual( - parse_ide_settings("ide.vscode.settings", {"editor.defaultFormatter": "auto"}), - {"editor.defaultFormatter": "auto"}, - ) - - def test_parse_ide_settings_can_restrict_consumer_auto_values(self) -> None: - project_auto_setting_keys = frozenset({"python.defaultInterpreterPath"}) - self.assertEqual( - parse_ide_settings( - "ide.vscode.settings", - {"python.defaultInterpreterPath": "auto"}, - auto_setting_keys=project_auto_setting_keys, - ), - {"python.defaultInterpreterPath": "auto"}, - ) - - with self.assertRaisesRegex(ValueError, "does not support the special value 'auto'"): - parse_ide_settings( - "ide.vscode.settings", - {"editor.defaultFormatter": "auto"}, - auto_setting_keys=project_auto_setting_keys, - ) diff --git a/tests/test_logging.py b/tests/test_logging.py index 92ef375..000ca20 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -11,7 +11,7 @@ import base_cli import base_cli.logging as logging_module -from base_cli.logging import BaseCliFormatter +from base_cli.logging import CliFormatter class ConfigureLoggerTests(unittest.TestCase): @@ -45,7 +45,7 @@ def test_configure_logger_defaults_to_stderr_and_base_formatter(self) -> None: logger.info("hello default") handler = logger.handlers[0] - self.assertIsInstance(handler.formatter, BaseCliFormatter) + self.assertIsInstance(handler.formatter, CliFormatter) self.assertIn("INFO", stream.getvalue()) self.assertIn("hello default", stream.getvalue()) self.assertRegex(stream.getvalue(), r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4} INFO")