From 62cdb7a20f8fe49e29e0232e7d390d39d610feca Mon Sep 17 00:00:00 2001 From: Enno Hermann Date: Tue, 12 Nov 2024 00:31:55 +0100 Subject: [PATCH 1/5] docs(readme): add badges --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4b0dea8..acf97e6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # 👩‍✈️ Coqpit +[![PyPI - License](https://img.shields.io/pypi/l/coqpit-config)](https://github.com/idiap/coqui-ai-coqpit/blob/main/LICENSE.txt) +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/coqpit-config) +[![PyPI - Version](https://img.shields.io/pypi/v/coqpit-config)](https://pypi.org/project/coqpit-config) [![CI](https://github.com/idiap/coqui-ai-coqpit/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/idiap/coqui-ai-coqpit/actions/workflows/main.yml) Simple, light-weight and no dependency config handling through python data From 26d600620ceebbbf84c1db902c09cf806096f230 Mon Sep 17 00:00:00 2001 From: Enno Hermann Date: Tue, 12 Nov 2024 00:34:22 +0100 Subject: [PATCH 2/5] ci: update uv and move into composite action --- .github/actions/setup-uv/action.yml | 10 ++++++++++ .github/workflows/main.yml | 8 ++------ .github/workflows/pypi-release.yml | 8 ++------ 3 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 .github/actions/setup-uv/action.yml diff --git a/.github/actions/setup-uv/action.yml b/.github/actions/setup-uv/action.yml new file mode 100644 index 0000000..a4f3f6d --- /dev/null +++ b/.github/actions/setup-uv/action.yml @@ -0,0 +1,10 @@ +name: Setup uv +runs: + using: 'composite' + steps: + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + version: "0.5.1" + enable-cache: true + cache-dependency-glob: "**/pyproject.toml" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ed1e0ee..31b799e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,12 +16,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install uv - uses: astral-sh/setup-uv@v3 - with: - version: "0.4.27" - enable-cache: true - cache-dependency-glob: "**/pyproject.toml" + - name: Setup uv + uses: ./.github/actions/setup-uv - name: Set up Python ${{ matrix.python-version }} run: uv python install ${{ matrix.python-version }} - name: Lint check diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index 29e9038..23622f6 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -19,12 +19,8 @@ jobs: if [[ "v$version" != "$tag" ]]; then exit 1 fi - - name: Install uv - uses: astral-sh/setup-uv@v3 - with: - version: "0.4.27" - enable-cache: true - cache-dependency-glob: "**/pyproject.toml" + - name: Setup uv + uses: ./.github/actions/setup-uv - name: Set up Python run: uv python install - name: Build sdist and wheel From 13c2b7941081bbdafb0cb314c299a0f1b3d67318 Mon Sep 17 00:00:00 2001 From: Enno Hermann Date: Tue, 12 Nov 2024 00:46:08 +0100 Subject: [PATCH 3/5] fix(parse_known_args): pass on arg_prefix The default in both functions is the same, so the behaviour doesn't change when it's left at the default. --- coqpit/coqpit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coqpit/coqpit.py b/coqpit/coqpit.py index 73d34f6..60bd5b0 100644 --- a/coqpit/coqpit.py +++ b/coqpit/coqpit.py @@ -937,6 +937,7 @@ def parse_known_args( Returns: List of unknown parameters. """ + unknown: list[str] = [] if not args: # If args was not specified, parse from sys.argv parser = self.init_argparse(instance=self, arg_prefix=arg_prefix, relaxed_parser=relaxed_parser) @@ -948,7 +949,7 @@ def parse_known_args( parser = self.init_argparse(instance=self, arg_prefix=arg_prefix, relaxed_parser=relaxed_parser) args, unknown = parser.parse_known_args(args) - self.parse_args(args) + self.parse_args(args, arg_prefix=arg_prefix) return unknown @classmethod From c34c93cce7cdcefb20e9bad4c5fe1001153f01b8 Mon Sep 17 00:00:00 2001 From: Enno Hermann Date: Tue, 12 Nov 2024 10:34:44 +0100 Subject: [PATCH 4/5] test: add test cases for helper functions --- tests/test_serialization.py | 39 ++++++++++++++++++++++++++++++-- tests/test_utils.py | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 tests/test_utils.py diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 557d261..9cd7d2b 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -1,8 +1,10 @@ from dataclasses import dataclass, field from pathlib import Path -from typing import Optional +from typing import Optional, Union -from coqpit.coqpit import Coqpit, _deserialize_list +import pytest + +from coqpit.coqpit import Coqpit, _deserialize_list, _deserialize_primitive_types @dataclass @@ -66,3 +68,36 @@ def test_deserialize_list() -> None: assert _deserialize_list([1, 2, 3], list[int]) == [1, 2, 3] assert _deserialize_list([1, 2, 3], list[float]) == [1.0, 2.0, 3.0] assert _deserialize_list([1, 2, 3], list[str]) == ["1", "2", "3"] + + +# TODO: `type: ignore` can probably be removed when switching to Python 3.10 +# Union syntax (e.g. str | int) +def test_deserialize_primitive_type() -> None: + cases = ( + (True, bool, True), + (False, bool, False), + ("a", str, "a"), + ("3", str, "3"), + (3, int, 3), + (3, float, 3.0), + (3, str, "3"), + (3.0, str, "3.0"), + (3, bool, True), + ("a", Union[str, None], "a"), + ("3", Union[str, None], "3"), + (3, Union[int, None], 3), + (3, Union[float, None], 3.0), + (None, Union[str, None], None), + (None, Union[int, None], None), + (None, Union[float, None], None), + (None, Union[str, None], None), + (float("inf"), float, float("inf")), + (float("inf"), int, float("inf")), + (float("-inf"), float, float("-inf")), + (float("-inf"), int, float("-inf")), + ) + for value, field_type, expected in cases: + assert _deserialize_primitive_types(value, field_type) == expected # type: ignore[arg-type] + + with pytest.raises(TypeError): + _deserialize_primitive_types(3, Coqpit) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..7d7de34 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,44 @@ +from typing import Union + +from coqpit.coqpit import _is_optional_field, _is_union, _is_union_and_not_simple_optional + +# TODO: `type: ignore` can probably be removed when switching to Python 3.10 +# Union syntax (e.g. str | int) + + +def test_is_union() -> None: + cases = ( + (Union[str, int], True), + (Union[str, None], True), + (int, False), + (list[int], False), + (list[Union[str, int]], False), + ) + for item, expected in cases: + assert _is_union(item) == expected # type: ignore[arg-type] + + +def test_is_union_and_not_simple_optional() -> None: + cases = ( + (Union[str, int], True), + (Union[str, None], False), + (Union[list[int], None], False), + (int, False), + (list[int], False), + (list[Union[str, int]], False), + ) + for item, expected in cases: + assert _is_union_and_not_simple_optional(item) == expected # type: ignore[arg-type] + + +def test_is_optional_field() -> None: + cases = ( + (Union[str, int], False), + (Union[str, None], True), + (Union[list[int], None], True), + (int, False), + (list[int], False), + (list[Union[str, int]], False), + ) + for item, expected in cases: + assert _is_optional_field(item) == expected # type: ignore[arg-type] From ef27e892bb5aded5c4b36f394ff6662d3783b22e Mon Sep 17 00:00:00 2001 From: Enno Hermann Date: Wed, 20 Nov 2024 13:48:52 +0100 Subject: [PATCH 5/5] chore: bump version to 0.1.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 122e1e0..479f7eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "coqpit-config" -version = "0.1.0" +version = "0.1.1" description = "Simple (maybe too simple), light-weight config management through python data-classes." readme = "README.md" requires-python = ">=3.9"