Chore/typing#5
Merged
Merged
Conversation
Enable flake8-annotations (ANN) in ruff with ANN401 active so Any is rejected. Add per-file ignores for tests/migrations/manage.py/conftest. Annotate 32 previously untyped sites: - decorators: PEP 695 ParamSpec on login_required_json to preserve wrapped view signatures end-to-end - management commands: handle(*args: object, **options: object) -> None; s3 cached_property typed as S3Client (TYPE_CHECKING) - storage: 3 __init__ return None - tasks: generate_thumbnail self: Task (Celery bind=True) - views: 5 HTML views -> HttpResponse - models: _fmt_ts(dt: datetime | None)
Drop per-file ignores for manage.py, conftest.py, and tests/. Keep migrations ignored — Django regenerates them via makemigrations and would overwrite annotations. - manage.py: main() -> None - conftest.py: fixtures typed with Client, User, tuple[Client, User] - factories.py: post_generation password method fully typed - tests/: 38 test methods get -> None; fixtures typed via DjangoAssertNumQueries and Iterator[None] for yielding mock_s3
Collapse 6 duplicated test methods into 3 parametrized ones using @pytest.mark.parametrize with named ids: - test_login: matrix over (password, expected_status) - test_create (images): matrix over (payload, expected_status) - test_delete (images): matrix over (owned, expected_status, image_remains) - test_create_task: matrix over (payload_kind, expected_status, task_created) - test_get_task: matrix over (owned, expected_status) 18 test methods → 12 methods producing 17 cases. Tests with distinct assertion shapes (cancel_task, list_query_count_constant, unauthenticated) stay separate. ids=[...] keeps failure messages readable.
factory-boy class calls return the factory class to type checkers, breaking IDE attribute resolution on returned model fields. Wrap each factory in a helper that asserts the model return type via typing.cast, restoring IDE/pyrefly visibility on .id, .latest_task, refresh_from_db, etc. Pyrefly errors across tests drop from 40 to 8. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Promote generate_thumbnail max_retries to a module-level constant so tests reference the int directly instead of celery's untyped Task attr. - Wrap celery .apply call in a Callable cast (stubs misreport it as list). - factories.UserFactory.password: cast self to User (factory-boy injects the instance at runtime; pyrefly enforces LSP on self annotations). - test_models: null-check latest_task() before .id access. - pyrefly.toml: drop tests/ and management/ excludes; add manage.py. Result: 0 pyrefly errors across the full project (was 40 with tests included), no new type:ignore lines. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
DELETE /api/tasks/<id>/ let any owner revoke a running Celery task. Task lifecycle should be controlled internally (admin/management), not exposed to end users — removing the verb closes that surface. tasks_detail now accepts GET only; AsyncResult import and the test_cancel_task case are dropped. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- test_tasks: split test_status_outcomes into test_direct_call (success and invalid_image) and test_resilient_to_download_failure (retry outcomes). Each method is now straight-line with no branching; the parametrize matrices align with their actual call mode. - test_views_html: hoist URL names into class-level *_viewname attributes, matching the convention already used in test_api.py. - test_smoke: rename infra-check helpers so each name announces the stack layer it covers (async worker, storage, observability) and drop the redundant docstrings. Add Jaeger query retry loop so the trace assertion no longer relies on a single fixed sleep. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wire a TracerProvider + OTLP gRPC exporter and RequestsInstrumentor in the smoke test process so outbound HTTP calls inject traceparent and emit client spans. Web/worker spans become children under a single trace, enabling end-to-end visibility in Jaeger. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move Jaeger HTTP polling, response schemas, and helpers into a single test-only module (images/tests/jaeger.py) with a JaegerClient singleton mirroring the storage.py pattern. Response shapes are typed via TypedDict, with a shared KeyedValue covering process/span/log fields and NotRequired warnings to reflect Jaeger's optional payloads. Switch smoke process to SimpleSpanProcessor so spans export synchronously on end, removing the need for force_flush() before the events assertion. The smoke root span now runs inline in the test method via tracer.start_as_current_span, with trace_id read from the span context. The trace is verified in two passes: service presence inside the active span, then events on the root span after it ends. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.