diff options
| author | Ben Sima <ben@bsima.me> | 2025-11-13 14:47:07 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bsima.me> | 2025-11-13 14:53:55 -0500 |
| commit | 7884d54baa5387ceb89071c831245273cf42521a (patch) | |
| tree | be92ae097a8b545699c2838565043e2a01c1a8de | |
| parent | bbb1e56e97ee5e899fc6deae497f06b3f13595d3 (diff) | |
Improve type safety in Billing module
- Add explicit type annotations to TIER_LIMITS dict - Add type
annotation to tier_info dict in get_tier_info - Remove unnecessary
type: ignore comments - Use .get() consistently for dict access
Improves type safety and removes 3 type: ignore suppressions.
Amp-Thread-ID:
https://ampcode.com/threads/T-8edacbeb-b343-49ca-b524-1c999272acb6
Co-authored-by: Amp <amp@ampcode.com>
| -rw-r--r-- | .tasks/tasks.jsonl | 8 | ||||
| -rw-r--r-- | Biz/PodcastItLater/Billing.py | 16 |
2 files changed, 13 insertions, 11 deletions
diff --git a/.tasks/tasks.jsonl b/.tasks/tasks.jsonl index f2e2f4a..338188a 100644 --- a/.tasks/tasks.jsonl +++ b/.tasks/tasks.jsonl @@ -51,10 +51,10 @@ {"taskCreatedAt":"2025-11-13T19:38:08.37344762Z","taskDependencies":[],"taskId":"t-1f9Td4U","taskNamespace":null,"taskParent":null,"taskStatus":"Open","taskTitle":"Navbar Styling Cleanup","taskType":"Epic","taskUpdatedAt":"2025-11-13T19:38:08.37344762Z"} {"taskCreatedAt":"2025-11-13T19:38:32.95559213Z","taskDependencies":[],"taskId":"t-1fbym1M","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Remove BLE001 noqa for bare Exception catches - use specific exceptions","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:43:29.049855419Z"} {"taskCreatedAt":"2025-11-13T19:38:33.139120541Z","taskDependencies":[],"taskId":"t-1fbz7LV","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Fix PLR0913 violations - refactor functions with too many parameters","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:44:09.820023426Z"} -{"taskCreatedAt":"2025-11-13T19:38:33.309222802Z","taskDependencies":[],"taskId":"t-1fbzQ1v","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"InProgress","taskTitle":"Extract format_duration utility to shared UI or Core module (used only in Web.py)","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:44:13.950088651Z"} -{"taskCreatedAt":"2025-11-13T19:38:33.491331064Z","taskDependencies":[],"taskId":"t-1fbABoD","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Open","taskTitle":"Extract extract_og_metadata and send_magic_link to Core module for reusability","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:33.491331064Z"} -{"taskCreatedAt":"2025-11-13T19:38:33.674140035Z","taskDependencies":[],"taskId":"t-1fbBmXa","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Open","taskTitle":"Review and fix type: ignore comments - improve type safety","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:33.674140035Z"} -{"taskCreatedAt":"2025-11-13T19:38:33.85804778Z","taskDependencies":[],"taskId":"t-1fbC8Nq","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Open","taskTitle":"Remove PLR2004 magic number - use constant for month check","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:33.85804778Z"} +{"taskCreatedAt":"2025-11-13T19:38:33.309222802Z","taskDependencies":[],"taskId":"t-1fbzQ1v","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Extract format_duration utility to shared UI or Core module (used only in Web.py)","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:45:49.402934404Z"} +{"taskCreatedAt":"2025-11-13T19:38:33.491331064Z","taskDependencies":[],"taskId":"t-1fbABoD","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Extract extract_og_metadata and send_magic_link to Core module for reusability","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:46:04.679290775Z"} +{"taskCreatedAt":"2025-11-13T19:38:33.674140035Z","taskDependencies":[],"taskId":"t-1fbBmXa","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Review and fix type: ignore comments - improve type safety","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:47:09.583640045Z"} +{"taskCreatedAt":"2025-11-13T19:38:33.85804778Z","taskDependencies":[],"taskId":"t-1fbC8Nq","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Remove PLR2004 magic number - use constant for month check","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:47:45.120428021Z"} {"taskCreatedAt":"2025-11-13T19:38:34.035597081Z","taskDependencies":[],"taskId":"t-1fbCSZd","taskNamespace":null,"taskParent":"t-1f9RIzd","taskStatus":"Open","taskTitle":"Implement cancel subscription functionality","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.035597081Z"} {"taskCreatedAt":"2025-11-13T19:38:34.194926176Z","taskDependencies":[],"taskId":"t-1fbDyr2","taskNamespace":null,"taskParent":"t-1f9RIzd","taskStatus":"Open","taskTitle":"Implement delete account functionality","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.194926176Z"} {"taskCreatedAt":"2025-11-13T19:38:34.384489707Z","taskDependencies":[],"taskId":"t-1fbElKv","taskNamespace":null,"taskParent":"t-1f9RIzd","taskStatus":"Open","taskTitle":"Implement change email address functionality","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.384489707Z"} diff --git a/Biz/PodcastItLater/Billing.py b/Biz/PodcastItLater/Billing.py index 4996607..0e2537a 100644 --- a/Biz/PodcastItLater/Billing.py +++ b/Biz/PodcastItLater/Billing.py @@ -37,7 +37,7 @@ PRICE_TO_TIER = { } # Tier limits (None = unlimited) -TIER_LIMITS = { +TIER_LIMITS: dict[str, dict[str, int | None]] = { "free": { "articles_per_period": 10, "minutes_per_period": None, @@ -112,7 +112,7 @@ def can_submit(user_id: int) -> tuple[bool, str, dict[str, int]]: usage = get_usage(user_id, period_start, period_end) # Check article limit - article_limit = limits["articles_per_period"] # type: ignore[index] + article_limit = limits.get("articles_per_period") if article_limit is not None and usage["articles"] >= article_limit: msg = ( f"You've reached your limit of {article_limit} articles " @@ -121,7 +121,7 @@ def can_submit(user_id: int) -> tuple[bool, str, dict[str, int]]: return (False, msg, usage) # Check minutes limit (if implemented) - minute_limit = limits.get("minutes_per_period") # type: ignore[attr-defined] + minute_limit = limits.get("minutes_per_period") if minute_limit is not None and usage.get("minutes", 0) >= minute_limit: return ( False, @@ -391,11 +391,13 @@ def _update_subscription_state(subscription: dict[str, typing.Any]) -> None: period_start = datetime.fromtimestamp(period_start_ts, tz=timezone.utc) # Calculate period end if not provided (assume monthly) + december = 12 + january = 1 if not period_end_ts: - if period_start.month == 12: # noqa: PLR2004 + if period_start.month == december: period_end = period_start.replace( year=period_start.year + 1, - month=1, + month=january, ) else: period_end = period_start.replace(month=period_start.month + 1) @@ -447,7 +449,7 @@ def get_tier_info(tier: str) -> dict[str, typing.Any]: Returns: dict with keys: name, articles_limit, price, description """ - tier_info = { + tier_info: dict[str, dict[str, typing.Any]] = { "free": { "name": "Free", "articles_limit": 10, @@ -461,7 +463,7 @@ def get_tier_info(tier: str) -> dict[str, typing.Any]: "description": "Unlimited articles", }, } - return tier_info.get(tier, tier_info["free"]) # type: ignore[return-value] + return tier_info.get(tier, tier_info["free"]) # Tests |
