Skip to content

fix: resolve P1 bugs from codebase audit - #1

Merged
thomaspinder merged 5 commits into
mainfrom
fix/p1-bugfixes
Feb 21, 2026
Merged

thomaspinder merged 5 commits into
mainfrom
fix/p1-bugfixes

Conversation

@thomaspinder

Copy link
Copy Markdown
Collaborator

Summary

Fixes the four Priority 1 bugs identified in the codebase audit. These are correctness issues and resource leaks that should be resolved before any feature work.

1. Remove dead dutch_name / display_name from Column model

The Column Pydantic model had a dutch_name field and a display_name computed property intended for bilingual support. However, the CBS OData API returns a single Title field per column — there is no separate Dutch vs English title in one response. _parse_column was setting both name and dutch_name from the same "Title" value, making display_name's fallback logic dead code.

Changes:

  • Removed dutch_name: str field and display_name computed property from Column
  • Removed computed_field import from pydantic
  • Simplified _parse_column in client.py to drop the redundant dutch_name= argument
  • Updated test_models.py — removed tests for the non-functional bilingual behavior

2. Make Client a context manager to prevent connection leaks

When no http_client is passed, Client.__init__ creates an httpx.Client() internally but never closes it. This leaks TCP connections and file descriptors, and httpx emits ResourceWarning on garbage collection.

Changes:

  • Added _owns_http flag to track whether Client created the httpx instance
  • Added close() method that only closes the httpx client if Client owns it
  • Added __enter__ / __exit__ for with statement support
  • Added 4 lifecycle tests covering owned/external clients with both close() and context manager

3. Remove broken Dockerfile

The Dockerfile was a cookiecutter template leftover with CMD ["python", "cbspy/foo.py"] — a file that doesn't exist. The source layout is src/cbspy/, not cbspy/, and this is a library with no application entrypoint.

Changes:

  • Deleted Dockerfile

4. Add retry logic for transient 5xx and network errors

The MVP design doc specifies "retry once with backoff" for 5xx errors, but the implementation had zero retry logic. The CBS API occasionally returns 503s under load.

Changes:

  • Replaced _check_response with _request_with_retry in ODataClient
  • Retries once with 1 second delay on HTTP 5xx status codes
  • Retries once with 1 second delay on httpx.RequestError (connection errors, timeouts)
  • 404 and other 4xx errors raise immediately without retry
  • Added 5 tests covering: retry-then-succeed, retry-exhausted, no-retry-on-404, network-error-retry, network-error-exhausted
  • Removed unused http_client fixture from conftest.py

Test plan

  • All 38 tests pass (uv run python -m pytest tests/ -v)
  • 98% code coverage
  • Ruff lint: zero errors (uv run ruff check src tests)
  • Type checker: zero errors (uv run ty check)
  • Existing behavior preserved for all non-error paths
  • Verify no downstream documentation references dutch_name or display_name

🤖 Generated with Claude Code

thomaspinder and others added 5 commits February 21, 2026 15:40
The CBS API returns a single Title per column. dutch_name was always
set to the same value as name, making display_name fallback dead code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Client now tracks whether it owns the httpx.Client. close() and
__exit__ only close the HTTP client if Client created it internally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Template leftover referencing non-existent cbspy/foo.py. This is a
library — no application entrypoint to containerise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ODataClient now retries once with a 1s delay on 5xx status codes and
httpx.RequestError (timeouts, connection errors). 404 and 4xx errors
are not retried. Also removes unused http_client fixture from conftest.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@thomaspinder
thomaspinder merged commit 14b1fdf into main Feb 21, 2026
7 checks passed
@thomaspinder
thomaspinder deleted the fix/p1-bugfixes branch February 21, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant