diff --git a/CHANGELOG.md b/CHANGELOG.md index c851e6b..3a499ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,12 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Ability to specify start and end indices in `ParamDB.commit_history()` - Support for scalar [`astropy.units.Quantity`] objects +- Parameter dataclass bases (`Param` and `Struct`) automatically convert subclasses into + dataclasses `kw_only` as True by default ### Changed - `ParamDict` can be initialized from keyword arguments in addition to dictionaries -- Parameter dataclass bases (`Param` and `Struct`) automatically convert subclasses into - dataclasses, so the `@dataclass` decorator should no longer be used ## [0.2.0] (Mar 8 2023) diff --git a/README.md b/README.md index 1b053e1..a5fcb34 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ poetry source add --secondary paramdb https://painterqubits.github.io/paramdb/re Then the package can be installed like any other (e.g. `poetry add paramdb`). [poetry]: https://python-poetry.org +[astropy]: https://docs.astropy.org/en/stable/index.html +[`astropy.units.quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity @@ -50,8 +52,6 @@ ParamDB has two main components: See the [api reference] for more information. -[astropy]: https://docs.astropy.org/en/stable/install.html -[`astropy.units.quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity [**parameter data**]: https://painterqubits.github.io/paramdb/parameter-data.html [**database**]: https://painterqubits.github.io/paramdb/database.html [api reference]: https://painterqubits.github.io/paramdb/api-reference diff --git a/docs/parameter-data.md b/docs/parameter-data.md index 44706d0..eb7d1d5 100644 --- a/docs/parameter-data.md +++ b/docs/parameter-data.md @@ -53,15 +53,18 @@ param.value The dataclass aspects of the subclass can be customized by passing keyword arguments when defining the custom class (the same arguments that would be passed to the [`@dataclass`] -decorator), and by using the dataclass [`field`] function. For example, +decorator), and by using the dataclass [`field`] function. The class arguments have the +same default values as in [`@dataclass`], except `kw_only` is True by default for +ParamDB dataclasses to facilitate dataclass inheritance with default values. An example of +dataclass customization is shown below. ```{jupyter-execute} from dataclasses import field -class CustomizedDataclassParam(Param, kw_only=True, repr=False): +class CustomizedDataclassParam(Param, kw_only=False, repr=False): values: list[int] = field(default_factory=list) -customized_dataclass_param = CustomizedDataclassParam() +customized_dataclass_param = CustomizedDataclassParam([1, 2, 3]) customized_dataclass_param.values ``` @@ -97,6 +100,12 @@ param_custom_init = ParamCustomInit() ``` ```` +```{tip} +Since the base class of all parameter classes, {py:class}`ParamData`, is an abstract class +that inherits from [`abc.ABC`], you can use abstract decorators in parameter and structure +classes without inheriting from [`abc.ABC`] again. +``` + Parameters track when any of their properties was last updated in the read-only {py:attr}`~Param.last_updated` property. For example: @@ -170,7 +179,7 @@ example, ```{jupyter-execute} from paramdb import ParamList -param_list = ParamList([CustomParam(1), CustomParam(2), CustomParam(3)]) +param_list = ParamList([CustomParam(value=1), CustomParam(value=2), CustomParam(value=3)]) param_list[1].parent == param_list ``` @@ -233,4 +242,5 @@ This does nothing to the functionality, but static type checkers will now know t [`__init__`]: https://docs.python.org/3/reference/datamodel.html#object.__init__ [`@property`]: https://docs.python.org/3/library/functions.html#property [`__post_init__`]: https://docs.python.org/3/library/dataclasses.html#post-init-processing +[`abc.abc`]: https://docs.python.org/3/library/abc.html#abc.ABC [`collections.abc`]: https://docs.python.org/3/library/collections.abc.html diff --git a/paramdb/_param_data/_dataclasses.py b/paramdb/_param_data/_dataclasses.py index e80551e..3057191 100644 --- a/paramdb/_param_data/_dataclasses.py +++ b/paramdb/_param_data/_dataclasses.py @@ -9,14 +9,14 @@ from paramdb._param_data._param_data import ParamData -@dataclass_transform() +@dataclass_transform(kw_only_default=True) class _ParamDataclass(ParamData): """Base class for parameter dataclasses.""" - def __init_subclass__(cls, /, **kwargs: Any) -> None: + def __init_subclass__(cls, /, kw_only: bool = True, **kwargs: Any) -> None: # Convert subclasses into dataclasses super().__init_subclass__() - dataclass(cls, **kwargs) + dataclass(kw_only=kw_only, **kwargs)(cls) def __getitem__(self, name: str) -> Any: # Enable getting attributes via indexing