mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[chore] clear all 64 pre-existing mypy errors in tests/ (no type:ignore)
Convention: no type:ignore/noqa, and pre-existing violations still violate. The make-quality gate runs 'mypy roboco/ tests/', but the prior commits' gates only ran mypy on production files, masking 64 type errors across 15 test files (method-assign, unused-ignore, no-untyped-def, attr-defined, union-attr, has-type, index, misc). Fixed without any type:ignore: - method-assign (svc.session.X = / svc.method = AsyncMock()): hold a local 'session: MagicMock'/'AsyncMock' and assert on it, or stub via object.__setattr__ / monkeypatch / a typed '_bind' helper returning Any, or alias 'cc: Any = c' (the pattern the file already used). - unused 'type: ignore[assignment]' (real code was method-assign): removed; replaced with the no-suppression patterns above. - 'Callable[...] has no attribute assert_*': keep a typed local ref to the AsyncMock and assert on the local, not the method-typed attr. - no-untyped-def: annotate helper params (Any / pytest.MonkeyPatch). - attr-defined / index / union-attr: type the helper as Any, narrow with an 'is not None' assert, or add the missing attr to a fake. - has-type / return-value: fix the declared return type to the tuple the function actually returns. - PLC0415 inline imports: hoisted to top-level. test_pr_gate_notifies_pm._stub_gate_path converted fully to the 'cc: Any = c' alias (it already used it for one attr) so its five '# type: ignore[method-assign]' suppressions are gone. mypy tests/: 64 errors -> 0 (538 files). ruff check tests/: clean. All 84 tests in the touched files pass.
This commit is contained in:
@@ -25,6 +25,15 @@ _SLUG = "backend-cell"
|
||||
_LOOKUPS_BEFORE_AND_AFTER_RACE = 2
|
||||
|
||||
|
||||
def _bind(svc: object, name: str, value: object) -> Any:
|
||||
"""Stub `name` on `svc` without tripping mypy's method-assign check.
|
||||
Returns the value (typed ``Any``) so the caller can keep a reference for
|
||||
assertions — ``object.__setattr__`` does not narrow the attribute type, so
|
||||
assert on the returned local, not ``svc.<name>``."""
|
||||
object.__setattr__(svc, name, value)
|
||||
return value
|
||||
|
||||
|
||||
def _integrity_error() -> IntegrityError:
|
||||
return IntegrityError(
|
||||
"INSERT INTO channels ...",
|
||||
@@ -55,14 +64,16 @@ async def test_race_lost_refetches_existing_channel() -> None:
|
||||
re-fetches the winner's channel and returns it (no crash)."""
|
||||
existing = MagicMock(name="existing-channel", slug=_SLUG)
|
||||
svc, session = _svc(flush_side_effect=_integrity_error())
|
||||
svc.get_channel_by_slug = AsyncMock(side_effect=[None, existing])
|
||||
get_channel_by_slug = _bind(
|
||||
svc, "get_channel_by_slug", AsyncMock(side_effect=[None, existing])
|
||||
)
|
||||
|
||||
result = await svc.get_or_create_channel_by_slug(_SLUG)
|
||||
|
||||
assert result is existing
|
||||
# Savepoint isolated the failed insert; re-fetch was the recovery.
|
||||
session.begin_nested.assert_called_once()
|
||||
assert svc.get_channel_by_slug.await_count == _LOOKUPS_BEFORE_AND_AFTER_RACE
|
||||
assert get_channel_by_slug.await_count == _LOOKUPS_BEFORE_AND_AFTER_RACE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -70,7 +81,7 @@ async def test_race_lost_but_re_fetch_empty_reraises() -> None:
|
||||
"""If the conflict did NOT produce a row on re-fetch (a real failure, not a
|
||||
race), the IntegrityError is re-raised — never masked as a silent None."""
|
||||
svc, _session = _svc(flush_side_effect=_integrity_error())
|
||||
svc.get_channel_by_slug = AsyncMock(side_effect=[None, None])
|
||||
_bind(svc, "get_channel_by_slug", AsyncMock(side_effect=[None, None]))
|
||||
|
||||
with pytest.raises(IntegrityError):
|
||||
await svc.get_or_create_channel_by_slug(_SLUG)
|
||||
@@ -82,8 +93,8 @@ async def test_normal_auto_create_unaffected_by_savepoint() -> None:
|
||||
newly-created channel is returned (regression guard — the savepoint must
|
||||
not break the happy path)."""
|
||||
svc, session = _svc() # flush succeeds
|
||||
svc.get_channel_by_slug = AsyncMock(
|
||||
side_effect=[None]
|
||||
get_channel_by_slug = _bind(
|
||||
svc, "get_channel_by_slug", AsyncMock(side_effect=[None])
|
||||
) # not present, then never re-called
|
||||
|
||||
result = await svc.get_or_create_channel_by_slug(_SLUG)
|
||||
@@ -93,4 +104,4 @@ async def test_normal_auto_create_unaffected_by_savepoint() -> None:
|
||||
session.begin_nested.assert_called_once()
|
||||
session.add.assert_called_once()
|
||||
assert session.flush.await_count == 1
|
||||
assert svc.get_channel_by_slug.await_count == 1 # no recovery re-fetch
|
||||
assert get_channel_by_slug.await_count == 1 # no recovery re-fetch
|
||||
|
||||
Reference in New Issue
Block a user