mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 05:37:44 +00:00
Small speed up to frequently called datetime functions (#85399)
This commit is contained in:
parent
45eb1efc6f
commit
d81febd3f4
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
import bisect
|
||||
from contextlib import suppress
|
||||
import datetime as dt
|
||||
from functools import partial
|
||||
import platform
|
||||
import re
|
||||
import time
|
||||
@ -98,9 +99,10 @@ def get_time_zone(time_zone_str: str) -> dt.tzinfo | None:
|
||||
return None
|
||||
|
||||
|
||||
def utcnow() -> dt.datetime:
|
||||
"""Get now in UTC time."""
|
||||
return dt.datetime.now(UTC)
|
||||
# We use a partial here since it is implemented in native code
|
||||
# and avoids the global lookup of UTC
|
||||
utcnow: partial[dt.datetime] = partial(dt.datetime.now, UTC)
|
||||
utcnow.__doc__ = "Get now in UTC time."
|
||||
|
||||
|
||||
def now(time_zone: dt.tzinfo | None = None) -> dt.datetime:
|
||||
@ -466,8 +468,8 @@ def _datetime_ambiguous(dattim: dt.datetime) -> bool:
|
||||
return _datetime_exists(dattim) and dattim.utcoffset() != opposite_fold.utcoffset()
|
||||
|
||||
|
||||
def __monotonic_time_coarse() -> float:
|
||||
"""Return a monotonic time in seconds.
|
||||
def __gen_monotonic_time_coarse() -> partial[float]:
|
||||
"""Return a function that provides monotonic time in seconds.
|
||||
|
||||
This is the coarse version of time_monotonic, which is faster but less accurate.
|
||||
|
||||
@ -477,13 +479,16 @@ def __monotonic_time_coarse() -> float:
|
||||
|
||||
https://lore.kernel.org/lkml/20170404171826.25030-1-marc.zyngier@arm.com/
|
||||
"""
|
||||
return time.clock_gettime(CLOCK_MONOTONIC_COARSE)
|
||||
# We use a partial here since its implementation is in native code
|
||||
# which allows us to avoid the overhead of the global lookup
|
||||
# of CLOCK_MONOTONIC_COARSE.
|
||||
return partial(time.clock_gettime, CLOCK_MONOTONIC_COARSE)
|
||||
|
||||
|
||||
monotonic_time_coarse = time.monotonic
|
||||
with suppress(Exception):
|
||||
if (
|
||||
platform.system() == "Linux"
|
||||
and abs(time.monotonic() - __monotonic_time_coarse()) < 1
|
||||
and abs(time.monotonic() - __gen_monotonic_time_coarse()()) < 1
|
||||
):
|
||||
monotonic_time_coarse = __monotonic_time_coarse
|
||||
monotonic_time_coarse = __gen_monotonic_time_coarse()
|
||||
|
@ -5,7 +5,7 @@ import asyncio
|
||||
from collections import OrderedDict
|
||||
from collections.abc import Awaitable, Callable, Collection
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
import functools as ft
|
||||
from io import StringIO
|
||||
import json
|
||||
@ -396,7 +396,7 @@ def async_fire_time_changed_exact(
|
||||
approach, as this is only for testing.
|
||||
"""
|
||||
if datetime_ is None:
|
||||
utc_datetime = date_util.utcnow()
|
||||
utc_datetime = datetime.now(timezone.utc)
|
||||
else:
|
||||
utc_datetime = date_util.as_utc(datetime_)
|
||||
|
||||
@ -418,7 +418,7 @@ def async_fire_time_changed(
|
||||
for an exact microsecond, use async_fire_time_changed_exact.
|
||||
"""
|
||||
if datetime_ is None:
|
||||
utc_datetime = date_util.utcnow()
|
||||
utc_datetime = datetime.now(timezone.utc)
|
||||
else:
|
||||
utc_datetime = date_util.as_utc(datetime_)
|
||||
|
||||
|
@ -7,7 +7,6 @@ from datetime import datetime, timedelta
|
||||
import json
|
||||
from unittest.mock import patch, sentinel
|
||||
|
||||
from freezegun import freeze_time
|
||||
import pytest
|
||||
from sqlalchemy import text
|
||||
|
||||
@ -973,6 +972,7 @@ def test_state_changes_during_period_multiple_entities_single_test(hass_recorder
|
||||
hist[entity_id][0].state == value
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2039-01-19 03:14:07.555555-00:00")
|
||||
async def test_get_full_significant_states_past_year_2038(
|
||||
async_setup_recorder_instance: SetupRecorderInstanceT,
|
||||
hass: ha.HomeAssistant,
|
||||
@ -980,13 +980,13 @@ async def test_get_full_significant_states_past_year_2038(
|
||||
"""Test we can store times past year 2038."""
|
||||
await async_setup_recorder_instance(hass, {})
|
||||
past_2038_time = dt_util.parse_datetime("2039-01-19 03:14:07.555555-00:00")
|
||||
|
||||
with freeze_time(past_2038_time):
|
||||
hass.states.async_set("sensor.one", "on", {"attr": "original"})
|
||||
state0 = hass.states.get("sensor.one")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
hass.states.async_set("sensor.one", "on", {"attr": "new"})
|
||||
state1 = hass.states.get("sensor.one")
|
||||
|
||||
await async_wait_recording_done(hass)
|
||||
|
||||
def _get_entries():
|
||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
from collections.abc import AsyncGenerator, Callable, Generator
|
||||
from contextlib import asynccontextmanager
|
||||
import datetime
|
||||
import functools
|
||||
import gc
|
||||
import itertools
|
||||
@ -78,6 +79,14 @@ asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False))
|
||||
asyncio.set_event_loop_policy = lambda policy: None
|
||||
|
||||
|
||||
def _utcnow():
|
||||
"""Make utcnow patchable by freezegun."""
|
||||
return datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
|
||||
dt_util.utcnow = _utcnow
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
"""Register custom pytest options."""
|
||||
parser.addoption("--dburl", action="store", default="sqlite://")
|
||||
|
Loading…
x
Reference in New Issue
Block a user