diff --git a/pyproject.toml b/pyproject.toml index 8eec1943..acdaf82b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ only-binary = [":all:"] [tool.ruff] line-length = 200 +src = ["website"] [tool.ty.environment] python-version = "3.14" diff --git a/website/build.py b/website/build.py old mode 100644 new mode 100755 index e3dd66b4..bb268ac3 --- a/website/build.py +++ b/website/build.py @@ -12,10 +12,11 @@ from datetime import UTC, datetime from pathlib import Path from typing import TypedDict -from fetch_pypi_downloads_via_clickpy import OVERRIDES_FILE, normalize from jinja2 import Environment, FileSystemLoader from markdown_it import MarkdownIt from markdown_it.tree import SyntaxTreeNode + +from fetch_pypi_downloads_via_clickpy import OVERRIDES_FILE, normalize from readme_parser import AlsoSee, ParsedGroup, ParsedSection, parse_readme, parse_sponsors, render_inline_text, slugify GITHUB_REPO_URL_RE = re.compile(r"^https?://github\.com/([^/]+/[^/]+?)(?:\.git)?/?$") @@ -405,7 +406,7 @@ def synthetic_category(name: str, slug: str) -> SyntheticCategory: def git_last_change_date(repo_root: Path, *log_args: str) -> str: """Return the date of the last commit matching `git log` args, or "" without git history.""" - result = subprocess.run(["git", "log", "-1", "--format=%cs", "--no-patch", *log_args], cwd=repo_root, capture_output=True, text=True) + result = subprocess.run(["git", "log", "-1", "--format=%cs", "--no-patch", *log_args], cwd=repo_root, capture_output=True, text=True, check=False) return result.stdout.strip() diff --git a/website/fetch_github_stars.py b/website/fetch_github_stars.py old mode 100644 new mode 100755 index 3f451885..52d65dc1 --- a/website/fetch_github_stars.py +++ b/website/fetch_github_stars.py @@ -16,6 +16,7 @@ from itertools import batched from pathlib import Path import httpx + from build import extract_github_repo, load_stars CACHE_MAX_AGE_HOURS = 12 diff --git a/website/fetch_pypi_downloads_via_bigquery.py b/website/fetch_pypi_downloads_via_bigquery.py old mode 100644 new mode 100755 index e8b5bbfc..87099c69 --- a/website/fetch_pypi_downloads_via_bigquery.py +++ b/website/fetch_pypi_downloads_via_bigquery.py @@ -47,7 +47,7 @@ def fetch_bigquery(names: list[str], dry_run: bool) -> dict[str, int]: if dry_run: cmd.append("--dry_run") cmd.append(query) - result = subprocess.run(cmd, capture_output=True, text=True) + result = subprocess.run(cmd, capture_output=True, text=True, check=False) if result.returncode != 0: print(result.stderr, file=sys.stderr) sys.exit(1) diff --git a/website/fetch_pypi_downloads_via_clickpy.py b/website/fetch_pypi_downloads_via_clickpy.py old mode 100644 new mode 100755 index 0cbc89d3..dded71bc --- a/website/fetch_pypi_downloads_via_clickpy.py +++ b/website/fetch_pypi_downloads_via_clickpy.py @@ -33,10 +33,11 @@ Usage: python fetch_pypi_downloads_via_clickpy.py import json import re -from datetime import date +from datetime import UTC, datetime from pathlib import Path import httpx + from readme_parser import parse_readme DATA_DIR = Path(__file__).parent / "data" @@ -97,7 +98,7 @@ def main() -> None: query_names = sorted({pkg for pkg in packages.values() if pkg}) print(f"Querying {len(query_names)} package names...") counts = fetch_clickpy(query_names) - fetched_at = date.today().isoformat() + fetched_at = datetime.now(UTC).date().isoformat() rows = "\n".join(f"{name}\t{pkg or '-'}\t{counts.get(pkg, 'NOT_FOUND') if pkg else 'NOT_FOUND'}\t{fetched_at}" for name, pkg in packages.items()) OUT_FILE.write_text(f"name\tpackage\tdownloads\tfetched_at\n{rows}\n") print(f"Done. {len(counts)}/{len(query_names)} names found on PyPI. Cached to {OUT_FILE}") diff --git a/website/fetch_pypi_downloads_via_pepy.py b/website/fetch_pypi_downloads_via_pepy.py old mode 100644 new mode 100755 index 55eb7593..2a2c4dbe --- a/website/fetch_pypi_downloads_via_pepy.py +++ b/website/fetch_pypi_downloads_via_pepy.py @@ -23,6 +23,7 @@ import time from pathlib import Path import httpx + from fetch_pypi_downloads_via_clickpy import resolve ENV_FILE = Path(__file__).parent.parent / ".env" diff --git a/website/tests/test_build.py b/website/tests/test_build.py index 16af7aa4..4c66c9f6 100644 --- a/website/tests/test_build.py +++ b/website/tests/test_build.py @@ -12,6 +12,7 @@ from html.parser import HTMLParser from pathlib import Path import pytest + from build import ( TemplateEntry, annotate_entries_with_stats, diff --git a/website/tests/test_fetch_github_stars.py b/website/tests/test_fetch_github_stars.py index 6f0297b6..7b694e51 100644 --- a/website/tests/test_fetch_github_stars.py +++ b/website/tests/test_fetch_github_stars.py @@ -1,6 +1,7 @@ """Tests for fetch_github_stars module.""" import json +from datetime import UTC from fetch_github_stars import ( build_graphql_query, @@ -161,7 +162,7 @@ class TestMainSkipsFreshCache: """Verify that main() skips fetching when all cache entries are fresh.""" def test_skips_fetch_when_cache_is_fresh(self, tmp_path, monkeypatch, capsys): - from datetime import datetime, timedelta, timezone + from datetime import datetime, timedelta from fetch_github_stars import main @@ -174,7 +175,7 @@ class TestMainSkipsFreshCache: data_dir = tmp_path / "data" data_dir.mkdir() cache_file = data_dir / "github_stars.json" - now = datetime.now(timezone.utc) + now = datetime.now(UTC) fresh_cache = { "psf/requests": { "stars": 52000, @@ -201,7 +202,7 @@ class TestMainSkipsFreshCache: assert "Cache is up to date" in output def test_fetches_when_cache_is_stale(self, tmp_path, monkeypatch, capsys): - from datetime import datetime, timedelta, timezone + from datetime import datetime, timedelta from unittest.mock import MagicMock from fetch_github_stars import main @@ -215,7 +216,7 @@ class TestMainSkipsFreshCache: data_dir = tmp_path / "data" data_dir.mkdir() cache_file = data_dir / "github_stars.json" - now = datetime.now(timezone.utc) + now = datetime.now(UTC) stale_cache = { "psf/requests": { "stars": 52000, diff --git a/website/tests/test_readme_parser.py b/website/tests/test_readme_parser.py index 707134ed..eb596cde 100644 --- a/website/tests/test_readme_parser.py +++ b/website/tests/test_readme_parser.py @@ -5,6 +5,8 @@ import textwrap from pathlib import Path import pytest +from markdown_it import MarkdownIt +from markdown_it.tree import SyntaxTreeNode from fetch_pypi_downloads_via_clickpy import PYPI_NAME_RE, load_overrides, normalize from readme_parser import ( @@ -15,9 +17,6 @@ from readme_parser import ( render_inline_text, ) -from markdown_it import MarkdownIt -from markdown_it.tree import SyntaxTreeNode - def _parse_inline(md_text: str) -> list[SyntaxTreeNode]: """Helper: parse a single paragraph and return its inline children."""