diff --git a/src/prompt_toolkit/__init__.py b/src/prompt_toolkit/__init__.py index 7a0c4cee9..dc49c40e3 100644 --- a/src/prompt_toolkit/__init__.py +++ b/src/prompt_toolkit/__init__.py @@ -16,25 +16,56 @@ from __future__ import annotations -import re -from importlib import metadata - -# note: this is a bit more lax than the actual pep 440 to allow for a/b/rc/dev without a number -pep440 = re.compile( - 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*)?)?$", - re.UNICODE, -) +from typing import Any + from .application import Application from .formatted_text import ANSI, HTML from .shortcuts import PromptSession, choice, print_formatted_text, prompt -# Don't forget to update in `docs/conf.py`! -__version__ = metadata.version("prompt_toolkit") +__version__: str +VERSION: tuple[int, int, int] + + +def _load_version() -> None: + """ + Load the package version from importlib.metadata and cache both __version__ + and VERSION in the module globals. + """ + global __version__, VERSION + + import re + from importlib import metadata + + # note: this is a bit more lax than the actual pep 440 to allow for a/b/rc/dev without a number + pep440_pattern = ( + r"^([1-9]\d*!)?(0|[1-9]\d*)(\.(0|[1-9]\d*))*" + r"((a|b|rc)(0|[1-9]\d*)?)?(\.post(0|[1-9]\d*))?(\.dev(0|[1-9]\d*)?)?$" + ) + + version = metadata.version("prompt_toolkit") + assert re.fullmatch(pep440_pattern, version) + + # Don't forget to update in `docs/conf.py`! + __version__ = version + # Version tuple. + VERSION = tuple(int(v.rstrip("abrc")) for v in version.split(".")[:3]) + + +def __getattr__(name: str) -> Any: + if name in {"__version__", "VERSION"}: + _load_version() + return globals()[name] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") -assert pep440.match(__version__) -# Version tuple. -VERSION = tuple(int(v.rstrip("abrc")) for v in __version__.split(".")[:3]) +def __dir__() -> list[str]: + return sorted( + { + *globals().keys(), + "__version__", + "VERSION", + } + ) __all__ = [