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
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on:
push:
branches: [master]
pull_request:

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
python-version: "3.12"
- name: Install dependencies
run: uv sync
- name: Lint (ruff)
run: uv run ruff check .
- name: Typecheck (mypy)
run: uv run mypy *.py
- name: Test (pytest)
run: uv run pytest -q
8 changes: 4 additions & 4 deletions analyze_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ def test_load_all():
@click.option("--resample", default="1D")
@click.option("--title")
def main(
column: str = None,
save: str = None,
since: datetime = None,
column: str | None = None,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add postponed annotations for Python 3.9

This project still declares requires-python = ">=3.9", but analyze_stats.py does not use from __future__ import annotations. On Python 3.9 these new str | None/datetime | None parameter annotations are evaluated when the module is imported, raising TypeError: unsupported operand type(s) for | ..., so the analysis script becomes unusable on a supported interpreter. Either postpone annotation evaluation here or raise the minimum Python version.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #24 — raised requires-python to >=3.10 (3.9 is EOL and 3.10 is the lowest we actually run). The PEP 604 str | None annotations are valid natively there, so no __future__ import needed.

save: str | None = None,
since: datetime | None = None,
per_day: bool = False,
per_week: bool = False,
resample: str = "1D",
title: str = None,
title: str | None = None,
):
n_plots = 2 if per_day or per_week else 1

Expand Down
2 changes: 1 addition & 1 deletion collect_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def github_get_all(path: str) -> list:
releases a single request would silently truncate the list.
"""
items: list = []
url = f"https://api.github.com{path}"
url: str | None = f"https://api.github.com{path}"
while url:
response = requests.get(url, headers=_github_headers(), timeout=30)
response.raise_for_status()
Expand Down
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,19 @@ dependencies = [
# trying to install a non-existent "aw-stats" package. uv reads [project] above.
[tool.poetry]
package-mode = false

[dependency-groups]
dev = [
"mypy>=1.19.1",
"pytest>=8.4.2",
"ruff>=0.15.21",
]

[tool.mypy]
# Third-party libs here (pandas, matplotlib, google-auth, …) ship partial or no
# stubs; this repo is scripts, not a typed library — keep the check lightweight.
ignore_missing_imports = true

[tool.pytest.ini_options]
# The smoke tests (test_load*) live inside analyze_stats.py, not a test_*.py file.
python_files = ["test_*.py", "analyze_stats.py"]
Loading
Loading