|
16 | 16 |
|
17 | 17 | from __future__ import annotations |
18 | 18 |
|
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 | + |
27 | 21 | from .application import Application |
28 | 22 | from .formatted_text import ANSI, HTML |
29 | 23 | from .shortcuts import PromptSession, choice, print_formatted_text, prompt |
30 | 24 |
|
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}") |
33 | 59 |
|
34 | | -assert pep440.match(__version__) |
35 | 60 |
|
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 | + ) |
38 | 69 |
|
39 | 70 |
|
40 | 71 | __all__ = [ |
|
0 commit comments