Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ body:
- Module utilities (part:module)
- Logging utilities (part:logging)
- Type hints and typing (part:typing)
- Warnings and deprecation utilities (part:warnings)
- Unit, integration and performance tests (part:tests)
validations:
required: true
Expand Down
1 change: 1 addition & 0 deletions .github/keylabeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ labelMappings:
"part:tests": "part:tests"
"part:tooling": "part:tooling"
"part:typing": "part:typing"
"part:warnings": "part:warnings"
"part:❓": "part:❓"
8 changes: 8 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,11 @@
- "src/frequenz/core/typing/**"
- "tests/test_typing.py"
- "tests/typing/**"

"part:warnings":
- changed-files:
- any-glob-to-any-file:
- "src/frequenz/core/warnings.py"
- "src/frequenz/core/warnings/**"
- "tests/test_warnings.py"
- "tests/warnings/**"
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ from frequenz.core.enum import Enum, deprecated_member, unique
class TaskStatus(Enum):
OPEN = 1
IN_PROGRESS = 2
# Duplicate values are fine with `@unique` as long as they are deprecated
PENDING = deprecated_member(1, "PENDING is deprecated, use OPEN instead")
DONE = deprecated_member(3, "DONE is deprecated, use FINISHED instead")
FINISHED = 4
# Duplicate values are fine with `@unique` as long as they are deprecated.
# `since` is for the documentation.
PENDING = deprecated_member(1, new_name="OPEN", since="v1.2.0")

status1 = TaskStatus.PENDING # Warns: "PENDING is deprecated, use OPEN instead"
# Warns "<module>.TaskStatus.PENDING is deprecated. Use
# <module>.TaskStatus.OPEN instead."
status1 = TaskStatus.PENDING
assert status1 is TaskStatus.OPEN
```

Expand Down Expand Up @@ -209,8 +210,8 @@ else:
# imports included.
__getattr__ = deprecated_aliases(
__name__,
# Warns "<module>.Decimal is deprecated since v1.2.0. Use
# decimal.Decimal instead."
# Warns "<module>.Decimal is deprecated. Use decimal.Decimal instead.",
# `since` is for the documentation.
DeprecatedAlias("Decimal", new_module="decimal", since="v1.2.0"),
# Renamed on the way out
DeprecatedAlias(
Expand Down
23 changes: 18 additions & 5 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,31 @@

## Summary

<!-- Here goes a general summary of what this release is about -->
This release introduces a better way to deprecate enum members.

## Upgrading

<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
Even when this is a minor release, it ships with 2 potential breaking changes for users of `DeprecatedAlias` and `DeprecatedMember`:

- The standard warning of a `DeprecatedAlias` with `since` no longer includes the version: it is now `<old> is deprecated. Use <new> instead.` `since` is only used for the documentation now, following the Frequenz deprecation guide. Update tests matching the old wording.
- `DeprecatedMember.message` is now `str | None`, since a member declared with only `new_name` has its warning generated when the enum class is created. `DeprecatedMember` is not meant to be used directly, `deprecated_member()` is.

## New Features

<!-- Here goes the main new features and examples or instructions on how to use them -->
- `DeprecatedAlias` now accepts `since` and `message` together, or neither: `since` is only for the documentation, and `message` only replaces the warning. This lets an alias with a custom warning still say since which version it is deprecated in its documentation.
- `deprecated_member()` takes the replacement and version as structured, keyword-only arguments, like `DeprecatedAlias`: `new_name`, the member to use instead in the same enum, and `since`, the version it is deprecated since, for the documentation only. With `new_name` the `message` can be omitted, and the warning is generated with fully qualified names:

## Bug Fixes
```python
class TaskStatus(Enum):
OPEN = 1
# Warns "mypkg.TaskStatus.PENDING is deprecated. Use mypkg.TaskStatus.OPEN instead."
PENDING = deprecated_member(1, new_name="OPEN", since="v1.2.0")
```

The enum class checks that `new_name` is one of its members and is not deprecated itself. Existing calls passing a `message` keep working unchanged.

<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
[`griffe-frequenz-core`](https://github.com/frequenz-floss/griffe-frequenz-core) will read `since` and `new_name` to generate the documentation notice of these members.

## Bug Fixes

- Docstrings now use absolute cross-references to public paths instead of relative ones. Relative cross-references are expanded from the module where an object is defined since mkdocstrings-python 2.0.9, which broke some links, and projects rendering docstrings inherited from this library needed `relative_crossrefs: true` for them to work at all. See [frequenz-repo-config-python#655](https://github.com/frequenz-floss/frequenz-repo-config-python/issues/655) for details.
Loading