Skip to content

Commit 13f71a3

Browse files
authored
Defer imports for faster overall import time: 19 ms -> 5 ms (#234)
2 parents c6455cf + 147cbbc commit 13f71a3

8 files changed

Lines changed: 33 additions & 25 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ repos:
2222
- id: debug-statements
2323
- id: end-of-file-fixer
2424
- id: forbid-submodules
25+
- id: requirements-txt-fixer
2526
- id: trailing-whitespace
2627
exclude: \.github/ISSUE_TEMPLATE\.md|\.github/PULL_REQUEST_TEMPLATE\.md
2728

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
mkdocs==1.6.1
2+
mkdocs-include-markdown-plugin
23
mkdocs-material
34
mkdocstrings[python]==0.27.0
4-
mkdocs-include-markdown-plugin
55
pygments
66
pymdown-extensions==10.14.3

requirements-mypy.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
mypy==1.15.0
2+
pytest
3+
types-freezegun
4+
types-setuptools

src/humanize/i18n.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import gettext as gettext_module
66
from threading import local
7-
from typing import TYPE_CHECKING
87

8+
TYPE_CHECKING = False
99
if TYPE_CHECKING:
1010
import os
1111
import pathlib

src/humanize/lists.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
from __future__ import annotations
44

5-
from typing import Any
5+
TYPE_CHECKING = False
6+
if TYPE_CHECKING:
7+
from typing import Any
68

79
__all__ = ["natural_list"]
810

src/humanize/number.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
from __future__ import annotations
44

55
import math
6-
import re
7-
import sys
8-
from typing import TYPE_CHECKING
96

107
from .i18n import _gettext as _
118
from .i18n import _ngettext, decimal_separator, thousands_separator
129
from .i18n import _ngettext_noop as NS_
1310
from .i18n import _pgettext as P_
1411

12+
TYPE_CHECKING = False
1513
if TYPE_CHECKING:
14+
import sys
15+
1616
if sys.version_info >= (3, 10):
1717
from typing import TypeAlias
1818
else:
1919
from typing_extensions import TypeAlias
2020

21-
# This type can be better defined by typing.SupportsInt, typing.SupportsFloat
22-
# but that's a Python 3.8 only typing option.
23-
NumberOrString: TypeAlias = "float | str"
21+
# This type can be better defined by typing.SupportsFloat
22+
# but that's a Python 3.8 only typing option.
23+
NumberOrString: TypeAlias = float | str
2424

2525

2626
def _format_not_finite(value: float) -> str:
@@ -165,6 +165,8 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:
165165
else:
166166
orig = str(value)
167167
orig = orig.replace(".", decimal_sep)
168+
import re
169+
168170
while True:
169171
new = re.sub(r"^(-?\d+)(\d{3})", rf"\g<1>{thousands_sep}\g<2>", orig)
170172
if orig == new:
@@ -429,6 +431,8 @@ def scientific(value: NumberOrString, precision: int = 2) -> str:
429431
n = fmt.format(value)
430432
part1, part2 = n.split("e")
431433
# Remove redundant leading '+' or '0's (preserving the last '0' for 10⁰).
434+
import re
435+
432436
part2 = re.sub(r"^\+?(\-?)0*(.+)$", r"\1\2", part2)
433437

434438
new_part2 = []

src/humanize/time.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55

66
from __future__ import annotations
77

8-
import collections.abc
98
import datetime as dt
109
import math
11-
import typing
1210
from enum import Enum
1311
from functools import total_ordering
14-
from typing import Any
1512

1613
from .i18n import _gettext as _
1714
from .i18n import _ngettext
1815
from .number import intcomma
1916

17+
TYPE_CHECKING = False
18+
if TYPE_CHECKING:
19+
from collections.abc import Iterable
20+
from typing import Any
21+
2022
__all__ = [
2123
"naturaldate",
2224
"naturalday",
@@ -37,7 +39,7 @@ class Unit(Enum):
3739
MONTHS = 6
3840
YEARS = 7
3941

40-
def __lt__(self, other: typing.Any) -> typing.Any:
42+
def __lt__(self, other: Any) -> Any:
4143
if self.__class__ is other.__class__:
4244
return self.value < other.value
4345
return NotImplemented
@@ -62,9 +64,7 @@ def _abs_timedelta(delta: dt.timedelta) -> dt.timedelta:
6264
return delta
6365

6466

65-
def _date_and_delta(
66-
value: typing.Any, *, now: dt.datetime | None = None
67-
) -> tuple[typing.Any, typing.Any]:
67+
def _date_and_delta(value: Any, *, now: dt.datetime | None = None) -> tuple[Any, Any]:
6868
"""Turn a value into a date and a timedelta which represents how long ago it was.
6969
7070
If that's not possible, return `(None, value)`.
@@ -327,7 +327,7 @@ def _quotient_and_remainder(
327327
divisor: float,
328328
unit: Unit,
329329
minimum_unit: Unit,
330-
suppress: collections.abc.Iterable[Unit],
330+
suppress: Iterable[Unit],
331331
) -> tuple[float, float]:
332332
"""Divide `value` by `divisor` returning the quotient and remainder.
333333
@@ -368,7 +368,7 @@ def _carry(
368368
ratio: float,
369369
unit: Unit,
370370
min_unit: Unit,
371-
suppress: typing.Iterable[Unit],
371+
suppress: Iterable[Unit],
372372
) -> tuple[float, float]:
373373
"""Return a tuple with two values.
374374
@@ -401,7 +401,7 @@ def _carry(
401401
return value1, value2
402402

403403

404-
def _suitable_minimum_unit(min_unit: Unit, suppress: typing.Iterable[Unit]) -> Unit:
404+
def _suitable_minimum_unit(min_unit: Unit, suppress: Iterable[Unit]) -> Unit:
405405
"""Return a minimum unit suitable that is not suppressed.
406406
407407
If not suppressed, return the same unit:
@@ -430,7 +430,7 @@ def _suitable_minimum_unit(min_unit: Unit, suppress: typing.Iterable[Unit]) -> U
430430
return min_unit
431431

432432

433-
def _suppress_lower_units(min_unit: Unit, suppress: typing.Iterable[Unit]) -> set[Unit]:
433+
def _suppress_lower_units(min_unit: Unit, suppress: Iterable[Unit]) -> set[Unit]:
434434
"""Extend suppressed units (if any) with all units lower than the minimum unit.
435435
436436
>>> from humanize.time import _suppress_lower_units, Unit
@@ -449,7 +449,7 @@ def _suppress_lower_units(min_unit: Unit, suppress: typing.Iterable[Unit]) -> se
449449
def precisedelta(
450450
value: dt.timedelta | int | None,
451451
minimum_unit: str = "seconds",
452-
suppress: typing.Iterable[str] = (),
452+
suppress: Iterable[str] = (),
453453
format: str = "%0.2f",
454454
) -> str:
455455
"""Return a precise representation of a timedelta.

tox.ini

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ commands =
4040

4141
[testenv:mypy]
4242
deps =
43-
mypy==1.12
44-
pytest
45-
types-freezegun
46-
types-setuptools
43+
-r requirements-mypy.txt
4744
commands =
4845
mypy . {posargs}
4946

0 commit comments

Comments
 (0)