Skip to content

shared-clock-mock

Preview (since 0.17.3) · Related issues · View source

This rule is unstable and in preview. The --preview flag is required for use.

What it does

Checks for patches, assignments, and deletions of shared clock and sleep functions in time and asyncio.

Why is this bad?

If worker uses import time, then worker.time and time refer to the same module. Patching worker.time.sleep can make an assert_called_once() check fail when another thread calls time.sleep. The same can happen when another task calls a patched asyncio.sleep.

To keep the patch local to worker, replace worker.time or worker.asyncio with an object that provides the functions worker uses.

Example

from unittest.mock import Mock, patch

from example import worker

sleep = Mock()
with patch.object(worker.time, "sleep", sleep):
    worker.retry()

Use instead:

from types import SimpleNamespace
from unittest.mock import Mock, patch

from example import worker

sleep = Mock()
with patch.object(worker, "time", SimpleNamespace(sleep=sleep)):
    worker.retry()

Known problems

Ruff can flag a patch to worker.time.sleep even if a fixture has replaced worker.time with a private clock. It can miss a patch when the target is a dynamically built string or when the test assigns clock = worker.time and then patches clock.sleep.

References