From bb747312b2fb50f5be0bde747cfb465071240be2 Mon Sep 17 00:00:00 2001 From: GalB Date: Mon, 7 Sep 2026 10:30:53 +0300 Subject: [PATCH] perf: hoist `import datetime as dt` to module scope in time.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #335 declared `__lazy_modules__` so module-scope imports become lazy on Python 3.15+, but only added the declarations — the function-level `import datetime as dt` statements predating it were left in place, costing a `sys.modules` lookup on every call. Move the import to module scope and add "datetime" to `__lazy_modules__`, the same pattern filesize.py already uses for `math`. The now-redundant `TYPE_CHECKING` import goes with it. --- src/humanize/time.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/humanize/time.py b/src/humanize/time.py index 975cc03c..90a874f2 100644 --- a/src/humanize/time.py +++ b/src/humanize/time.py @@ -5,8 +5,9 @@ from __future__ import annotations -__lazy_modules__ = {"humanize.i18n", "humanize.number"} +__lazy_modules__ = {"datetime", "humanize.i18n", "humanize.number"} +import datetime as dt from enum import Enum from functools import total_ordering @@ -16,7 +17,6 @@ TYPE_CHECKING = False if TYPE_CHECKING: - import datetime as dt from collections.abc import Iterable from typing import Any @@ -47,8 +47,6 @@ def __lt__(self, other: Any) -> Any: def _now() -> dt.datetime: - import datetime as dt - return dt.datetime.now() @@ -74,8 +72,6 @@ def _date_and_delta( If that's not possible, return `(None, value)`. """ - import datetime as dt - if not now: now = _now() if isinstance(value, dt.datetime): @@ -136,8 +132,6 @@ def naturaldelta( ``` """ - import datetime as dt - tmp = Unit[minimum_unit.upper()] if tmp not in (Unit.SECONDS, Unit.MILLISECONDS, Unit.MICROSECONDS): msg = f"Minimum unit '{minimum_unit}' not supported" @@ -286,8 +280,6 @@ def naturaltime( Returns: str: A natural representation of the input in a resolution that makes sense. """ - import datetime as dt - value = _convert_aware_datetime(value) when = _convert_aware_datetime(when) @@ -316,8 +308,6 @@ def _convert_aware_datetime( if value is None: return None - import datetime as dt - if isinstance(value, dt.datetime) and value.tzinfo is not None: value = dt.datetime.fromtimestamp(value.timestamp()) return value @@ -331,8 +321,6 @@ def naturalday(value: dt.date | dt.datetime, format: str = "%b %d") -> str: formatted according to `format`. """ - import datetime as dt - try: # When value is a tz-aware datetime, compute "today" in that timezone # so the comparison uses the correct local date. @@ -363,8 +351,6 @@ def naturalday(value: dt.date | dt.datetime, format: str = "%b %d") -> str: def naturaldate(value: dt.date | dt.datetime) -> str: """Like `naturalday`, but append a year for dates more than ~five months away.""" - import datetime as dt - original_value = value try: if isinstance(value, dt.datetime) and value.tzinfo is not None: