From cdf1f527322015ad692630c04813d328f15c9ebd Mon Sep 17 00:00:00 2001 From: Sean N Date: Fri, 17 Apr 2026 20:18:35 +0200 Subject: [PATCH] Added docstrings to all methods --- nitro_datastore/__init__.py | 2 +- nitro_datastore/datastore.py | 48 +++++++++++++++++++++++++++++--- nitro_datastore/query_builder.py | 12 +++++--- pyproject.toml | 2 +- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/nitro_datastore/__init__.py b/nitro_datastore/__init__.py index 26f0903..fa5a9b5 100644 --- a/nitro_datastore/__init__.py +++ b/nitro_datastore/__init__.py @@ -18,5 +18,5 @@ from nitro_datastore.datastore import NitroDataStore from nitro_datastore.query_builder import QueryBuilder -__version__ = "1.0.4" +__version__ = "1.0.5" __all__ = ["NitroDataStore", "QueryBuilder"] diff --git a/nitro_datastore/datastore.py b/nitro_datastore/datastore.py index dca2694..92ab454 100644 --- a/nitro_datastore/datastore.py +++ b/nitro_datastore/datastore.py @@ -362,6 +362,13 @@ def has(self, key: str) -> bool: Raises: ValueError: If key is empty, whitespace-only, or has empty segments + + Example: + >>> data = NitroDataStore({'site': {'name': 'My Site'}}) + >>> data.has('site.name') + True + >>> data.has('site.missing') + False """ self._validate_path(key) @@ -382,8 +389,20 @@ def has(self, key: str) -> bool: def merge(self, other: Union["NitroDataStore", Dict[str, Any]]) -> None: """Deep merge another data store or dictionary into this one. + Mutates this datastore in place. Nested dicts are merged recursively; + non-dict values (including lists) from `other` overwrite existing values. + Args: - other: Another NitroDataStore or dict to merge in + other: Another NitroDataStore or dict to merge in. + + Raises: + ValueError: If a circular reference is detected during merge. + + Example: + >>> data = NitroDataStore({'site': {'name': 'A', 'theme': 'dark'}}) + >>> data.merge({'site': {'theme': 'light', 'url': 'a.com'}}) + >>> data.to_dict() + {'site': {'name': 'A', 'theme': 'light', 'url': 'a.com'}} """ if isinstance(other, NitroDataStore): other_data = other._data @@ -396,17 +415,38 @@ def merge(self, other: Union["NitroDataStore", Dict[str, Any]]) -> None: def to_dict(self) -> Dict[str, Any]: """Export data as a plain dictionary. + Returns a deep copy, so mutations on the result do not affect the + datastore (and vice versa). + Returns: - A deep copy of the internal data dictionary + A deep copy of the internal data dictionary. + + Raises: + ValueError: If a circular reference is detected during the copy. + + Example: + >>> data = NitroDataStore({'site': {'name': 'My Site'}}) + >>> plain = data.to_dict() + >>> plain['site']['name'] = 'Mutated' + >>> data.get('site.name') + 'My Site' """ return self._deep_copy(self._data) def save(self, file_path: Union[str, Path], indent: int = 2) -> None: """Save data to a JSON file. + Creates parent directories if they do not exist. Non-ASCII characters + are written as-is (UTF-8 encoded, not escaped). + Args: - file_path: Path to save JSON file - indent: JSON indentation (default: 2) + file_path: Destination JSON file path. + indent: JSON indentation in spaces. Defaults to 2. + + Example: + >>> data = NitroDataStore({'site': {'name': 'My Site'}}) + >>> data.save('output/config.json') + >>> data.save('output/compact.json', indent=0) """ path = Path(file_path) path.parent.mkdir(parents=True, exist_ok=True) diff --git a/nitro_datastore/query_builder.py b/nitro_datastore/query_builder.py index cfb0acd..dd247c4 100644 --- a/nitro_datastore/query_builder.py +++ b/nitro_datastore/query_builder.py @@ -1,6 +1,6 @@ """Query builder for filtering and transforming collections.""" -from typing import Any, Callable, List, Optional +from typing import Any, Callable, Dict, List, Optional class QueryBuilder: @@ -169,14 +169,18 @@ def pluck(self, key: str) -> List[Any]: results = self.execute() return [item.get(key) if isinstance(item, dict) else None for item in results] - def group_by(self, key: str) -> dict: + def group_by(self, key: str) -> Dict[Any, List[Any]]: """Group results by a field value. + Non-dict items in the result set are skipped. Items missing `key` are + grouped under `None`. + Args: - key: Key to group by + key: Field name to group by. Returns: - Dictionary mapping key values to lists of items + Mapping from each distinct field value to the list of items + that share it. Example: >>> by_category = query.group_by('category') diff --git a/pyproject.toml b/pyproject.toml index 5a07b71..5445bcc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "nitro-datastore" -version = "1.0.4" +version = "1.0.5" description = "Schema-agnostic JSON data store with dot notation, chainable queries, bulk operations, and built-in security features" readme = "README.md" authors = [