typing: graduate tests.permissioning.* subpackage out of the mypy baseline#1768
Conversation
…eline Continues the mypy baseline drain tracked in #1738 (the #1331 → #1335 → #1447 cadence). After the config tail (#1748), this is the next cohesive batch called out in the issue: the 18-module ``opencontractserver.tests.permissioning.*`` subpackage. Removes all 18 ``[mypy-…]`` ``ignore_errors`` blocks from ``mypy.ini``, prunes the corresponding 313 lines from ``docs/typing/mypy_baseline.txt`` (5592 → 5279), and fixes the 162 errors that surface. Most errors were the standard Django ``setUpTestData(cls)`` class-attribute pattern flagged by mypy (recommended fix from #1479: annotate the assigned names as class-level attributes before the ``@classmethod`` body). One real production-code gap surfaced: - ``CoreAgent`` Protocol was missing its public ``config: AgentConfig`` attribute (``opencontractserver/llms/agents/core_agents.py``). Five tests read ``agent.config.tools`` / ``agent.config._approval_bypass_allowed`` directly off agents handed back by ``llm_agents.for_corpus(...)`` / ``for_document(...)``. The factory returns the ``CoreAgent`` Protocol; the concrete ``CoreAgentBase`` initialises ``self.config = config`` in ``__init__``, but the Protocol never declared it. Added ``config: AgentConfig`` to the Protocol body — captures the existing public API contract without a behaviour change. Per-file test fixes: - ``test_query_optimizer_methods.py`` (108 errors): added class-level annotations to ``AnalysisServicePermissionTestCase`` and ``DocumentPermissionFilterQueryCountTestCase`` covering every ``cls.<attr> = ...`` assignment inside ``setUpTestData``; switched ``User = get_user_model()`` to ``from opencontractserver.users.models import User`` so the name is usable as a type annotation; replaced three ``qs.first().<attr>`` accesses with ``qs[0].<attr>`` after the pre-existing ``qs.count() == 1`` guard. - ``test_metadata_query_optimizer.py`` (15 errors): added ``assert status is not None`` narrowings before indexing into the ``dict | None`` return of ``MetadataService.get_metadata_completion_status``; one ``column is not None`` narrowing in ``test_validate_column_valid``. - ``test_permissioning.py`` (10 errors): same ``setUpTestData`` annotation pattern on ``SetPermissionsIsNewTests``; same ``get_user_model()`` → direct import switch. - ``test_permissioned_querysets.py`` (8 errors): narrowed ``qs.query.select_related`` (``dict | bool``) via ``assert isinstance(..., dict)`` before three ``assertIn`` calls; gave two ``PermissionQuerySet`` constructions explicit type annotations. - ``test_public_and_permissions.py`` (7 errors): removed six unused ``# type: ignore[attr-defined]`` comments on ``Model.objects.acount()`` calls (django-stubs now ships proper async-manager typing). - ``test_version_aware_query_optimizer.py`` (7 errors): replaced six ``result.first().id`` accesses with ``result[0].id`` after the pre-existing ``result.count() == 1`` guard. - ``test_custom_permission_filters.py`` (4 errors): replaced two ``assertIsNotNone`` calls with ``assert`` narrowings. - ``test_creator_based_permissions.py`` (2 errors): narrow ``# type: ignore[arg-type]`` on the two ``get_users_permissions_for_obj (instance=mock_instance, ...)`` calls (the test deliberately passes a non-``Model`` mock to exercise the no-guardian-tables fallback). - ``test_comment_permission.py`` (1 error): replaced one ``assertIsNotNone`` with ``assert`` for narrowing. Pre-commit ``mypy`` continues to pass on the full project surface (``mypy --config-file mypy.ini opencontractserver config`` → "Success: no issues found in 1157 source files"). Refs #1738
Code Review — PR #1768:
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…eline (#1776) Continues issue #1738's drain (the #1331 → #1335 → #1447 cadence). The `annotation` domain chunk from the issue's tests.* leaf-files batching plan, following the tests.permissioning.* subpackage in PR #1768. Removes all 6 [mypy-opencontractserver.tests.test_annotation_*] ignore_errors blocks from mypy.ini, prunes the corresponding 138 lines from docs/typing/mypy_baseline.txt (5279 → 5141), and fixes the errors that surface under the current mypy / django-stubs pins. Per-file changes: - test_annotation_admin.py: class-level annotations on TestAnnotationAdmin for every cls.<attr> in setUpTestData; get_user_model() → direct User import. - test_annotation_images_api.py: class-level annotations on AnnotationImagesAPITestCase; same User import switch (also clears the valid-type error on the `owner: User` parameter). - test_annotation_permission_mutations.py: no code change; the historical set_permissions_for_obj_to_user arg-type errors no longer reproduce. - test_annotation_privacy.py: same as above. - test_annotation_tree.py: rename self.client → self.graphene_client on AnnotationTreeTestCase so the graphene Client no longer shadows the inherited django.test.TestCase.client (mypy resolved .execute through Django's Client); replace one assertIsNotNone with `assert ... is not None` narrowing; same User import switch. - test_annotation_utils.py: class-level annotations on the two TestCases; scoped # type: ignore[arg-type] on the two compute_content_modalities calls that deliberately pass mixed/invalid items to exercise defensive skipping; same User import switch. Refs #1738 Signed-off-by: JSIV <5049984+JSv4@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
Continues the mypy baseline drain (issue Open-Source-Legal#1738, the Open-Source-Legal#1331 -> Open-Source-Legal#1335 -> Open-Source-Legal#1447 cadence). After the config tail (Open-Source-Legal#1748), tests.permissioning.* (Open-Source-Legal#1768), and the annotation (Open-Source-Legal#1776) / document (Open-Source-Legal#1851) / corpus (Open-Source-Legal#1866) / agent (Open-Source-Legal#1877) leaf-file chunks, this is the next cohesive batch from the issue's tests.* batching plan: the extract domain. Removes the 6 [mypy-opencontractserver.tests.test_*] ignore_errors blocks for the structured-data-extraction feature -- Extracts plus their Fieldsets/Columns, Datacells, and metadata columns (all in opencontractserver/extracts/models.py): test_extract_mutations, test_extract_queries, test_extract_tasks, test_datacell_mutations, test_column_mutations, test_metadata_columns_graphql. Prunes the corresponding 57 lines from docs/typing/mypy_baseline.txt (3648 -> 3591) and fixes the 42 errors that surface. Every surfaced error was the same: a graphene.test.Client assigned to self.client shadows django.test.TestCase.client (which has no .execute()). Renamed self.client -> self.graphene_client in the 5 GraphQL test modules -- a behaviour-equivalent rename, since the assignment already shadowed the Django client at runtime and every read was .execute(). test_extract_tasks needed no code change: its historical set_permissions_for_obj_to_user arg-type errors no longer reproduce under django-stubs==6.0.5. Full project surface (mypy --config-file mypy.ini opencontractserver config) stays clean under both the pre-commit pin (mypy==2.0.0) and CI's pin (mypy==2.1.0). Refs Open-Source-Legal#1738
Summary
Continues the mypy baseline drain tracked in #1738 (the
#1331 → #1335 → #1447cadence). After the config tail (PR #1748), this is the next cohesive batch called out in the issue's batching plan: the 18-moduleopencontractserver.tests.permissioning.*subpackage.Removes all 18
[mypy-…]ignore_errorsblocks frommypy.ini, prunes the corresponding 313 lines fromdocs/typing/mypy_baseline.txt(5592 → 5279), and fixes the 162 errors that surface.After this PR:
opencontractserver.mcp.tests.test_mcpand theopencontractserver.tests.*leaf-file modules remain on the baseline, per the issue's batching plan.Production-code finding
One real type-correctness gap surfaced — the kind of thing #1738 explicitly invites graduation passes to look for:
CoreAgentProtocol was missing its publicconfig: AgentConfigattribute (opencontractserver/llms/agents/core_agents.py:383). Five tests readagent.config.tools/agent.config._approval_bypass_alloweddirectly off agents handed back byllm_agents.for_corpus(...)/for_document(...). The factory returns theCoreAgentProtocol; the concreteCoreAgentBaseinitializesself.config = configin__init__, but the Protocol never declared it. Tests worked at runtime (the attribute exists on every concrete agent) but failed type-checking. Addedconfig: AgentConfigto the Protocol body — captures the existing public API contract without a behaviour change.Per-file test fixes
Most errors were the standard Django
setUpTestData(cls)class-attribute pattern flagged by mypy (recommended fix from #1479: annotate the assigned names as class-level attributes before the@classmethodbody). The breakdown:test_query_optimizer_methods.pyAnalysisServicePermissionTestCase+DocumentPermissionFilterQueryCountTestCase; switchedUser = get_user_model()to directfrom opencontractserver.users.models import User; replaced threeqs.first().<attr>withqs[0].<attr>after the existingqs.count() == 1guard.test_metadata_query_optimizer.pyassert status is not Nonenarrowings before indexing into thedict | Nonereturn ofMetadataService.get_metadata_completion_status; onecolumn is not Nonenarrowing intest_validate_column_valid.test_permissioning.pysetUpTestDataannotation pattern onSetPermissionsIsNewTests; sameget_user_model()→ direct import switch.test_permissioned_querysets.pyqs.query.select_related(dict | bool) viaassert isinstance(..., dict)before threeassertIncalls; gave twoPermissionQuerySetconstructions explicit type annotations.test_public_and_permissions.py# type: ignore[attr-defined]comments onModel.objects.acount()calls (django-stubs now ships proper async-manager typing); one real fix onCoreAgent.config(covered above).test_version_aware_query_optimizer.pyresult.first().idaccesses withresult[0].idafter the pre-existingresult.count() == 1guard.test_custom_permission_filters.pyassertIsNotNonecalls withassertnarrowings.test_creator_based_permissions.py# type: ignore[arg-type]on twoget_users_permissions_for_obj(instance=mock_instance, ...)calls (the test deliberately passes a non-Modelmock to exercise the no-guardian-tables fallback).test_comment_permission.pyassertIsNotNonewithassertfor narrowing.All test behaviour is preserved — the changes are either no-ops at runtime (class-level annotations,
assertvsassertIsNotNone) or behaviour-equivalent refactors (.first().idafter acount() == 1guard →[0].id).Test plan
mypy --config-file mypy.ini opencontractserver config→Success: no issues found in 1157 source files(the acceptance gate per Continue draining the mypy baseline established in #1331 — test suite + config tail #1738)black/isort/flake8/pyupgradeclean on all changed filesbackend.ymllinter + test jobs) — the authoritative runtime checkRefs #1738