Repository: pytest-dev/pytest
File: src/_pytest/timing.py (Python)

Code before:


if TYPE_CHECKING:
    from pytest import MonkeyPatch


@dataclasses.dataclass(frozen=True)
class Instant:
    """
    Represents an instant in time, used to both get the timestamp value and to measure
    the duration of a time span.

    Inspired by Rust's `std::time::Instant`.
    """

    # Creation time of this instant, using time.time(), to measure actual time.
    # Use a `lambda` to initialize the default to correctly get the mocked time via `MockTiming`.
    time: float = dataclasses.field(default_factory=lambda: time(), init=False)

    # Performance counter tick of the instant, used to measure precise elapsed time.
    # Use a `lambda` to initialize the default to correctly get the mocked time via `MockTiming`.
    perf_count: float = dataclasses.field(
        default_factory=lambda: perf_counter(), init=False
    )

    def duration(self) -> Duration:
        """Measure the duration since `Instant` was created."""
        return Duration(start=self, stop=Instant())

    def as_utc(self) -> datetime:
        """Instant as UTC datetime."""
        return datetime.fromtimestamp(self.time, timezone.utc)


@dataclasses.dataclass(frozen=True)
class Duration:
    """A span of time as measured by `Instant.duration()`."""

    start: Instant
    stop: Instant

    @property
    def elapsed_s(self) -> float:
        """Elapsed time of the duration, in seconds, measured using a performance counter for precise timing."""
        return self.stop.perf_count - self.start.perf_count


@dataclasses.dataclass
class MockTiming:
    """Mocks _pytest.timing with a known object that can be used to control timing in tests
    deterministically.

Review comment (suggestion):
```suggestion
    def until_current(self) -> Duration:
```

Code after:


if TYPE_CHECKING:
    from pytest import MonkeyPatch


@dataclasses.dataclass(frozen=True)
class Instant:
    """
    Represents an instant in time, used to both get the timestamp value and to measure
    the duration of a time span.

    Inspired by Rust's `std::time::Instant`.
    """

    # Creation time of this instant, using time.time(), to measure actual time.
    # Note: using a `lambda` to correctly get the mocked time via `MockTiming`.
    time: float = dataclasses.field(default_factory=lambda: time(), init=False)

    # Performance counter tick of the instant, used to measure precise elapsed time.
    # Note: using a `lambda` to correctly get the mocked time via `MockTiming`.
    perf_count: float = dataclasses.field(
        default_factory=lambda: perf_counter(), init=False
    )

    def elapsed(self) -> Duration:
        """Measure the duration since `Instant` was created."""
        return Duration(start=self, stop=Instant())

    def as_utc(self) -> datetime:
        """Instant as UTC datetime."""
        return datetime.fromtimestamp(self.time, timezone.utc)


@dataclasses.dataclass(frozen=True)
class Duration:
    """A span of time as measured by `Instant.elapsed()`."""

    start: Instant
    stop: Instant

    @property
    def seconds(self) -> float:
        """Elapsed time of the duration in seconds, measured using a performance counter for precise timing."""
        return self.stop.perf_count - self.start.perf_count


@dataclasses.dataclass
class MockTiming:
    """Mocks _pytest.timing with a known object that can be used to control timing in tests
    deterministically.