Skip to content

Commit d69f331

Browse files
Add usethis-python-enum agent skill and dict comprehensiveness test (#1492)
* Initial plan * Add usethis-python-enum skill and dict comprehensiveness test for _STATUS_TO_CLASSIFIER_MAP Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/8b73af53-8aa9-4d64-903e-93112ce1ac5d --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com>
1 parent e0fa033 commit d69f331

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
name: usethis-python-enum
3+
description: Style and testing conventions for working with Python enums
4+
compatibility: usethis, Python, pytest, enums
5+
license: MIT
6+
metadata:
7+
version: "1.0"
8+
---
9+
10+
# Working with Enums
11+
12+
## Exhaustiveness via `assert_never`
13+
14+
When handling all cases of an enum in `if`/`elif` chains, always include a final `else` branch that calls `assert_never` from `typing_extensions`. This ensures the type checker will flag any unhandled enum members if the enum is extended in the future.
15+
16+
```python
17+
from typing_extensions import assert_never
18+
19+
from usethis._types.backend import BackendEnum
20+
21+
def handle_backend(backend: BackendEnum) -> str:
22+
if backend is BackendEnum.uv:
23+
return "uv"
24+
elif backend is BackendEnum.none:
25+
return "none"
26+
else:
27+
assert_never(backend)
28+
```
29+
30+
## Dicts with enum keys must have comprehensiveness tests
31+
32+
When a module-level dict uses an enum's members as its keys, add a unit test that asserts the dict's keys exactly match the set of all enum members. This prevents the dict from silently becoming incomplete when new members are added to the enum.
33+
34+
### Example test
35+
36+
```python
37+
from usethis._core.status import _STATUS_TO_CLASSIFIER_MAP
38+
from usethis._types.status import DevelopmentStatusEnum
39+
40+
class TestStatusToClassifierMap:
41+
def test_keys_match_enum(self):
42+
assert set(_STATUS_TO_CLASSIFIER_MAP.keys()) == set(DevelopmentStatusEnum)
43+
```
44+
45+
### Why this matters
46+
47+
Type checkers can catch missing cases in `if`/`elif` chains when `assert_never` is used, but they **cannot** catch missing keys in a dict literal. A dedicated unit test is the only reliable way to ensure that all enum members are represented.

tests/usethis/_core/test_status.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
import pytest
44
from pydantic import TypeAdapter
55

6-
from usethis._core.status import use_development_status
6+
from usethis._core.status import _STATUS_TO_CLASSIFIER_MAP, use_development_status
77
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
88
from usethis._test import change_cwd
99
from usethis._types.status import DevelopmentStatusEnum
1010

1111

12+
class TestStatusToClassifierMap:
13+
def test_keys_match_enum(self):
14+
assert set(_STATUS_TO_CLASSIFIER_MAP.keys()) == set(DevelopmentStatusEnum)
15+
16+
1217
class TestUseDevelopmentStatus:
1318
def test_planning(self, uv_init_dir: Path, capfd: pytest.CaptureFixture[str]):
1419
# Arrange

0 commit comments

Comments
 (0)