From 00aaf4ed4eae8d4439b4f55d40bd570ebd1d15b6 Mon Sep 17 00:00:00 2001 From: Jirka Date: Fri, 3 Feb 2023 16:03:52 +0100 Subject: [PATCH 1/6] chlog - new section --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c162e2f..db0ebb9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - CI: Checking schem in both yaml & yml + verbose ([#84](https://github.com/Lightning-AI/utilities/pull/84)) +## [UnReleased] - 2023-MM-DD + +### Added + +- + + +### Changed + +- CI/docs: allow passing env. variables ([#96](https://github.com/Lightning-AI/utilities/pull/96)) + + +### Fixed + +- + + ## [0.5.0] - 2022-12-21 ### Added From f84c4435bba5cb778f297be53ea99c62683d9843 Mon Sep 17 00:00:00 2001 From: Jirka Date: Tue, 7 Feb 2023 04:24:09 +0100 Subject: [PATCH 2/6] fix & extend StrEnum.from_str --- src/lightning_utilities/core/enums.py | 70 ++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/src/lightning_utilities/core/enums.py b/src/lightning_utilities/core/enums.py index 71d00741..78d50901 100644 --- a/src/lightning_utilities/core/enums.py +++ b/src/lightning_utilities/core/enums.py @@ -16,18 +16,72 @@ class StrEnum(str, Enum): ... t2 = "T-2" >>> MySE("T-1") == MySE.t1 True - >>> MySE.from_str("t-2") == MySE.t2 + >>> MySE.from_str("t-2", source="value") == MySE.t2 True """ @classmethod - def from_str(cls, value: str, source: Literal["key", "value", "any"] = "key") -> Optional["StrEnum"]: - for st, val in cls.__members__.items(): - if source in ("key", "any") and st.lower() == value.lower(): - return cls[st] - if source in ("value", "any") and val.lower() == value.lower(): - return cls[st] - return None + def from_str(cls, value: str, source: Literal["key", "value", "any"] = "key", strict: bool = False) -> Optional["StrEnum"]: + """Create StrEnum from a sting matching the key or value. + + Args: + value: matching string + source: compare with: + + - ``"key"``: validates only with Enum keys, typical alphanumeric with "_" + - ``"value"``: validates only with Enum values, could be any string + - ``"key"``: validates with any key or value, but key has priority + + strict: allow not matching string and returns None; if false raises exceptions + + Raises: + ValueError: + if requested string does not match any option based on selected source and use ``"strict=True"`` + UserWarning: + if requested string does not match any option based on selected source and use ``"strict=False"`` + + Example: + >>> class MySE(StrEnum): + ... t1 = "T-1" + ... t2 = "T-2" + >>> MySE.from_str("t-1", source="key") + Traceback (most recent call last): + ... + UserWarning: Invalid string: expected one of ['t1', 't2'], but got t-1. + >>> MySE.from_str("t-2", source="value") + + >>> MySE.from_str("t-3", source="any", strict=True) + Traceback (most recent call last): + ... + ValueError: Invalid match: expected one of ['t1', 't2', 'T-1', 'T-2'], but got t-3. + + """ + allowed = cls._allowed_matches(source) + if strict and not any(enum_.lower() == value.lower() for enum_ in allowed): + raise ValueError(f"Invalid match: expected one of {allowed}, but got {value}.") + + if source in ("key", "any"): + for enum_key in cls.__members__.keys(): + if enum_key.lower() == value.lower(): + return cls[enum_key] + if source in ("value", "any"): + for enum_key, enum_val in cls.__members__.items(): + if enum_val == value: + return cls[enum_key] + + raise UserWarning(f"Invalid string: expected one of {allowed}, but got {value}.") + + @classmethod + def _allowed_matches(cls, source) -> list: + keys, vals = [], [] + for enum_key, enum_val in cls.__members__.items(): + keys.append(enum_key) + vals.append(enum_val.value) + if source == "key": + return keys + if source == "value": + return vals + return keys + vals def __eq__(self, other: object) -> bool: if isinstance(other, Enum): From 157c36252ad10dc0579e8c1ba8950ca3e5bb6e74 Mon Sep 17 00:00:00 2001 From: Jirka Date: Tue, 7 Feb 2023 04:37:26 +0100 Subject: [PATCH 3/6] chlog & warning --- CHANGELOG.md | 21 ++------------------- src/lightning_utilities/core/enums.py | 6 ++---- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db0ebb9c..9f158a3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- +- Extended `StrEnum.from_str` with optional raising ValueError ([#99](https://github.com/Lightning-AI/utilities/pull/99)) ### Changed @@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- +- fixed `StrEnum.from_str` with source as key ([#99](https://github.com/Lightning-AI/utilities/pull/99)) ## [0.6.0] - 2023-01-23 @@ -40,23 +40,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - CI: Checking schem in both yaml & yml + verbose ([#84](https://github.com/Lightning-AI/utilities/pull/84)) -## [UnReleased] - 2023-MM-DD - -### Added - -- - - -### Changed - -- CI/docs: allow passing env. variables ([#96](https://github.com/Lightning-AI/utilities/pull/96)) - - -### Fixed - -- - - ## [0.5.0] - 2022-12-21 ### Added diff --git a/src/lightning_utilities/core/enums.py b/src/lightning_utilities/core/enums.py index 78d50901..1b4a6bc8 100644 --- a/src/lightning_utilities/core/enums.py +++ b/src/lightning_utilities/core/enums.py @@ -2,6 +2,7 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # http://www.apache.org/licenses/LICENSE-2.0 # +import warnings from enum import Enum from typing import Optional @@ -45,9 +46,6 @@ def from_str(cls, value: str, source: Literal["key", "value", "any"] = "key", st ... t1 = "T-1" ... t2 = "T-2" >>> MySE.from_str("t-1", source="key") - Traceback (most recent call last): - ... - UserWarning: Invalid string: expected one of ['t1', 't2'], but got t-1. >>> MySE.from_str("t-2", source="value") >>> MySE.from_str("t-3", source="any", strict=True) @@ -69,7 +67,7 @@ def from_str(cls, value: str, source: Literal["key", "value", "any"] = "key", st if enum_val == value: return cls[enum_key] - raise UserWarning(f"Invalid string: expected one of {allowed}, but got {value}.") + warnings.warn(UserWarning(f"Invalid string: expected one of {allowed}, but got {value}.")) @classmethod def _allowed_matches(cls, source) -> list: From d883b7cd00d246d148dcb0191a405dbd29c7d89f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 03:37:38 +0000 Subject: [PATCH 4/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/lightning_utilities/core/enums.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lightning_utilities/core/enums.py b/src/lightning_utilities/core/enums.py index 1b4a6bc8..0ce60587 100644 --- a/src/lightning_utilities/core/enums.py +++ b/src/lightning_utilities/core/enums.py @@ -22,7 +22,9 @@ class StrEnum(str, Enum): """ @classmethod - def from_str(cls, value: str, source: Literal["key", "value", "any"] = "key", strict: bool = False) -> Optional["StrEnum"]: + def from_str( + cls, value: str, source: Literal["key", "value", "any"] = "key", strict: bool = False + ) -> Optional["StrEnum"]: """Create StrEnum from a sting matching the key or value. Args: @@ -52,7 +54,6 @@ def from_str(cls, value: str, source: Literal["key", "value", "any"] = "key", st Traceback (most recent call last): ... ValueError: Invalid match: expected one of ['t1', 't2', 'T-1', 'T-2'], but got t-3. - """ allowed = cls._allowed_matches(source) if strict and not any(enum_.lower() == value.lower() for enum_ in allowed): From 9de3ac713a5efc8dcb76e36428e33f4352ce642e Mon Sep 17 00:00:00 2001 From: Jirka Date: Tue, 7 Feb 2023 07:48:48 +0100 Subject: [PATCH 5/6] mypy --- src/lightning_utilities/core/enums.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lightning_utilities/core/enums.py b/src/lightning_utilities/core/enums.py index 0ce60587..6c0953fa 100644 --- a/src/lightning_utilities/core/enums.py +++ b/src/lightning_utilities/core/enums.py @@ -69,9 +69,10 @@ def from_str( return cls[enum_key] warnings.warn(UserWarning(f"Invalid string: expected one of {allowed}, but got {value}.")) + return None @classmethod - def _allowed_matches(cls, source) -> list: + def _allowed_matches(cls, source: str) -> list: keys, vals = [], [] for enum_key, enum_val in cls.__members__.items(): keys.append(enum_key) From 31f3b2993d3c123f29730f329c584c2ad7e9912a Mon Sep 17 00:00:00 2001 From: Akihiro Nitta Date: Tue, 7 Feb 2023 11:08:14 +0000 Subject: [PATCH 6/6] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3240921..c9596e72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- fixed `StrEnum.from_str` with source as key ([#99](https://github.com/Lightning-AI/utilities/pull/99)) +- Fixed `StrEnum.from_str` with source as key ([#99](https://github.com/Lightning-AI/utilities/pull/99)) ## [0.6.0] - 2023-01-23