diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56613b2..4918df1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - python_version: ["3.12", "3.11", "3.10", "3.9", "3.8"] + python_version: ["3.12", "3.11", "3.10", "3.9"] steps: - name: Checkout Code diff --git a/README.md b/README.md index 6a1eafa..d59220a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,53 @@ # Simple-File-Settings -This is a package intended to easily load and save simple configuration data -transparently through a class. +[![Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit) +[![GitHub license](https://img.shields.io/github/license/NathanVaughn/simple-file-settings)](https://github.com/NathanVaughn/simple-file-settings/blob/main/LICENSE) +[![PyPi versions](https://img.shields.io/pypi/pyversions/simple-file-settings)](https://pypi.org/project/simple-file-settings) +[![PyPi downloads](https://img.shields.io/pypi/dm/simple-file-settings)](https://pypi.org/project/simple-file-settings) + +--- + +Sometimes, you just need to save and retain a few settings for your desktop program, +like a theme preference, or last viewed directory. This is a library intended to easily +load and save simple configuration data to and from disk through a +type-checked data class. ## Usage +First, a basic use case: + +```bash +pip install simple-file-settings +``` + +```python +import os +from simplefilesettings.json import JSONClass + +class _Settings(JSONClass): + class Config: + json_file = os.path.join(os.path.expanduser("~"), "config.json") + + mqtt_host: str = "mqtt" + mqtt_port: int = 1883 + serial_port: str = "COM1" + serial_baud_rate: int = 115200 + log_file_directory: str = os.path.join(os.getcwd(), "logs") + force_light_mode: bool = False + joystick_inverted: bool = False + max_moving_map_tracks: int = 5000 + takeoff_height: float = 3 + +Settings = _Settings() + +# this will attempt to load the value from the file on disk, or revert to the default +print(Settings.serial_port) + +# this will save the change to the config file +Settings.serial_port = "/dev/tty1" +``` + Inherit `simplefilesettings.json.JSONClass` and add class attributes with type hints and default values. Attributes without type hints will not be loaded or saved. Attributes without a default value, or starting with an @@ -34,12 +77,12 @@ class _Settings(JSONClass): name: str = "John" ``` -Nested classes are not supported. +Data types not JSON serializable (objects, datetimes, etc.) are not supported. -By default, when any attribute is accessed, the configured file will be read. If the file -does not exist, the default value will be used. If the file is not valid JSON, -it will be deleted automatically. To only read the file one time, set the `Config` -value `always_read` to `False`. +By default, when any attribute is accessed, the configured file will be read. +If the file does not exist, the default value will be used. +If the file is not valid JSON, it will be deleted automatically. +To only read the file one time, set the `Config` value `always_read` to `False`. When any attribute has its value set, that will be written to the configured file. @@ -83,7 +126,7 @@ class _YSettings(YAMLClass): python -m pip install pipx --upgrade pipx ensurepath pipx install poetry -pipx install vscode-task-runner +pipx install simple-file-settings # (Optionally) Add pre-commit plugin poetry self add poetry-pre-commit-plugin ``` diff --git a/poetry.lock b/poetry.lock index f079d58..dd58b9b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -249,13 +249,13 @@ virtualenv = ">=20.10.0" [[package]] name = "pytest" -version = "7.4.4" +version = "8.1.1" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, + {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] @@ -263,21 +263,21 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.4,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" -version = "4.1.0" +version = "5.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, ] [package.dependencies] @@ -285,7 +285,7 @@ coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pyyaml" @@ -457,4 +457,4 @@ yaml = ["pyyaml"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "bda8ab491caa06310e5bf852c7d891beb93a137330c734029ae642d14789cf60" +content-hash = "f0f08ea9a3a4ae279a6ce2781dce13171a24bcfdaa7c2e981d2dd55e9ff9700c" diff --git a/pyproject.toml b/pyproject.toml index d42b551..aa11e6b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,8 +21,8 @@ tomli = { version = "^2.0.1", python = "<3.11", optional = true } # not needed in 3.11 [tool.poetry.group.dev.dependencies] - pytest = "^7.4.3" - pytest-cov = "^4.1.0" + pytest = "^8.1.1" + pytest-cov = "^5.0.0" pre-commit = "^3.7.0" [tool.poetry.extras] diff --git a/simplefilesettings/toml.py b/simplefilesettings/toml.py index bc6607e..95477f2 100644 --- a/simplefilesettings/toml.py +++ b/simplefilesettings/toml.py @@ -4,7 +4,7 @@ import tomli_w try: - import tomllib + import tomllib # type: ignore except ImportError: # pragma: no cover import tomli as tomllib # type: ignore