Skip to content

Commit 3b3078d

Browse files
authored
Implement lazy loading of __version__ (#2031)
1 parent 2aec820 commit 3b3078d

File tree

1 file changed

+44
-13
lines changed

1 file changed

+44
-13
lines changed

src/prompt_toolkit/__init__.py

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,56 @@
1616

1717
from __future__ import annotations
1818

19-
import re
20-
from importlib import metadata
21-
22-
# note: this is a bit more lax than the actual pep 440 to allow for a/b/rc/dev without a number
23-
pep440 = re.compile(
24-
r"^([1-9]\d*!)?(0|[1-9]\d*)(\.(0|[1-9]\d*))*((a|b|rc)(0|[1-9]\d*)?)?(\.post(0|[1-9]\d*))?(\.dev(0|[1-9]\d*)?)?$",
25-
re.UNICODE,
26-
)
19+
from typing import Any
20+
2721
from .application import Application
2822
from .formatted_text import ANSI, HTML
2923
from .shortcuts import PromptSession, choice, print_formatted_text, prompt
3024

31-
# Don't forget to update in `docs/conf.py`!
32-
__version__ = metadata.version("prompt_toolkit")
25+
__version__: str
26+
VERSION: tuple[int, int, int]
27+
28+
29+
def _load_version() -> None:
30+
"""
31+
Load the package version from importlib.metadata and cache both __version__
32+
and VERSION in the module globals.
33+
"""
34+
global __version__, VERSION
35+
36+
import re
37+
from importlib import metadata
38+
39+
# note: this is a bit more lax than the actual pep 440 to allow for a/b/rc/dev without a number
40+
pep440_pattern = (
41+
r"^([1-9]\d*!)?(0|[1-9]\d*)(\.(0|[1-9]\d*))*"
42+
r"((a|b|rc)(0|[1-9]\d*)?)?(\.post(0|[1-9]\d*))?(\.dev(0|[1-9]\d*)?)?$"
43+
)
44+
45+
version = metadata.version("prompt_toolkit")
46+
assert re.fullmatch(pep440_pattern, version)
47+
48+
# Don't forget to update in `docs/conf.py`!
49+
__version__ = version
50+
# Version tuple.
51+
VERSION = tuple(int(v.rstrip("abrc")) for v in version.split(".")[:3])
52+
53+
54+
def __getattr__(name: str) -> Any:
55+
if name in {"__version__", "VERSION"}:
56+
_load_version()
57+
return globals()[name]
58+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
3359

34-
assert pep440.match(__version__)
3560

36-
# Version tuple.
37-
VERSION = tuple(int(v.rstrip("abrc")) for v in __version__.split(".")[:3])
61+
def __dir__() -> list[str]:
62+
return sorted(
63+
{
64+
*globals().keys(),
65+
"__version__",
66+
"VERSION",
67+
}
68+
)
3869

3970

4071
__all__ = [

0 commit comments

Comments
 (0)