From ac4e3b86624996888b2b96a7ec69fa45a3de3bed Mon Sep 17 00:00:00 2001 From: Abby Austin <38941820+spidertyler2005@users.noreply.github.com> Date: Mon, 18 May 2026 13:03:42 -0400 Subject: [PATCH] Add Missing Boolean Fields --- comprehensiveconfig/json.py | 2 +- comprehensiveconfig/spec.py | 43 +++++++++++++++++----------------- comprehensiveconfig/toml.py | 2 ++ comprehensiveconfig/utility.py | 1 + pyproject.toml | 2 +- tests/test_fields.py | 1 + 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/comprehensiveconfig/json.py b/comprehensiveconfig/json.py index e061341..0c617c2 100644 --- a/comprehensiveconfig/json.py +++ b/comprehensiveconfig/json.py @@ -31,7 +31,7 @@ def dump_value(cls, node: spec.AnyConfigField, value): return value.name case spec.ConfigEnum(_, False): return value.value - case str() | int() | float() | datetime() | dict() | None: + case str() | int() | float() | bool() | datetime() | dict() | None: return value case _: # magic method to make writing new field types possible diff --git a/comprehensiveconfig/spec.py b/comprehensiveconfig/spec.py index eb04311..8ad5c37 100644 --- a/comprehensiveconfig/spec.py +++ b/comprehensiveconfig/spec.py @@ -321,27 +321,6 @@ def nullable(self): return False -class Float(ConfigurationField): - """Floating point field""" - - __slots__ = () - - _holds: float - - def __get__(self, instance, owner) -> float: - return super().__get__(instance, owner) - - def __set__(self, instance, value: float): - super().__set__(instance, value) - - def _validate_value(self, value: Any, name: str | None = None, /): - super()._validate_value(value) - if not isinstance(value, (float, int)): - raise ValueError( - f"Field: {name or self._name}\nValue was not a valid number: {repr(value)}" - ) - - class List[T](ConfigurationField): """List field""" @@ -583,6 +562,27 @@ def _validate_value(self, value: Any, name: str | None = None, /): self.inner_type._validate_value(item, f"{name or self._name}[{c}]") +class Boolean(ConfigurationField): + """Boolean (true/false) field""" + + __slots__ = () + + _holds: bool + + def __get__(self, instance, owner) -> bool: + return super().__get__(instance, owner) + + def __set__(self, instance, value: bool): + super().__set__(instance, value) + + def _validate_value(self, value: Any, name: str | None = None, /): + super()._validate_value(value) + if not isinstance(value, bool): + raise ValueError( + f"Field: {name or self._name}\nValue was not a valid boolean: {repr(value)}" + ) + + class Float(ConfigurationField): """Floating point field""" @@ -840,6 +840,7 @@ def _validate_value(self, value: Any, name: str | None = None, /): "NoDefaultValue", "_NoDefaultValueT", "Section", + "Boolean", "Float", "Integer", "Number", diff --git a/comprehensiveconfig/toml.py b/comprehensiveconfig/toml.py index ada0aed..b607b28 100644 --- a/comprehensiveconfig/toml.py +++ b/comprehensiveconfig/toml.py @@ -74,6 +74,8 @@ def format_value(cls, field, value) -> str: match value: case int() | float(): return str(value) + case bool(): + return "true" if value else "false" case str(): return f'"{escape(value)}"' case list(): diff --git a/comprehensiveconfig/utility.py b/comprehensiveconfig/utility.py index ec5cda4..4e66a8a 100644 --- a/comprehensiveconfig/utility.py +++ b/comprehensiveconfig/utility.py @@ -26,6 +26,7 @@ class Bar(comprehensiveconfig.spec.Section, name="burger"): ) test_int = comprehensiveconfig.spec.Integer(20) test_float = comprehensiveconfig.spec.Float(20.20) + test_bool = comprehensiveconfig.spec.Boolean(True) test_dict = comprehensiveconfig.spec.Table( {10: "burgers"}, key_type=comprehensiveconfig.spec.Integer(), diff --git a/pyproject.toml b/pyproject.toml index b9b9251..f87a137 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "comprehensiveconfig" -version = "1.0.1" +version = "1.1.1" description = "A library to create ergonomic, auto-validated configuration models with great support for static type annotations." readme = "readme.md" requires-python = ">=3.12" diff --git a/tests/test_fields.py b/tests/test_fields.py index 8c9973b..c210129 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -398,6 +398,7 @@ class Bar(comprehensiveconfig.spec.Section, name="burger"): ) test_int = comprehensiveconfig.spec.Integer(20) test_float = comprehensiveconfig.spec.Float(20.20) + test_bool = comprehensiveconfig.spec.Boolean(True) test_dict = comprehensiveconfig.spec.Table( {10: "burgers"}, key_type=comprehensiveconfig.spec.Integer(),