codekingpro/portable-devtools
115k
1from __future__ import annotations2 3import bisect4import os5import sys6 7if sys.version_info[:2] >= (3, 9):8 from functools import cache9else:10 from functools import lru_cache as cache # pragma: no cover11 12from importlib import import_module13from typing import TYPE_CHECKING, cast14 15from rich._unicode_data._versions import VERSIONS16 17if TYPE_CHECKING:18 from rich.cells import CellTable19 20VERSION_ORDER = sorted(21 [22 tuple(23 map(int, version.split(".")),24 )25 for version in VERSIONS26 ]27)28VERSION_SET = frozenset(VERSIONS)29 30 31def _parse_version(version: str) -> tuple[int, int, int]:32 """Parse a version string into a tuple of 3 integers.33 34 Args:35 version: A version string.36 37 Raises:38 ValueError: If the version string is invalid.39 40 Returns:41 A tuple of 3 integers.42 """43 version_integers: tuple[int, ...]44 try:45 version_integers = tuple(46 map(int, version.split(".")),47 )48 except ValueError:49 raise ValueError(50 f"unicode version string {version!r} is badly formatted"51 ) from None52 while len(version_integers) < 3:53 version_integers = version_integers + (0,)54 triple = cast("tuple[int, int, int]", version_integers[:3])55 return triple56 57 58@cache59def load(unicode_version: str = "auto") -> CellTable:60 """Load a cell table for the given unicode version.61 62 Args:63 unicode_version: Unicode version, or `None` to auto-detect.64 65 """66 if unicode_version == "auto":67 unicode_version = os.environ.get("UNICODE_VERSION", "latest")68 try:69 _parse_version(unicode_version)70 except ValueError:71 # The environment variable is invalid72 # Fallback to using the latest version seems reasonable73 unicode_version = "latest"74 75 if unicode_version == "latest":76 version = VERSIONS[-1]77 else:78 try:79 version_numbers = _parse_version(unicode_version)80 except ValueError:81 version_numbers = _parse_version(VERSIONS[-1])82 major, minor, patch = version_numbers83 version = f"{major}.{minor}.{patch}"84 if version not in VERSION_SET:85 insert_position = bisect.bisect_left(VERSION_ORDER, version_numbers)86 version = VERSIONS[max(0, insert_position - 1)]87 88 version_path_component = version.replace(".", "-")89 module_name = f".unicode{version_path_component}"90 module = import_module(module_name, "rich._unicode_data")91 if TYPE_CHECKING:92 assert isinstance(module.cell_table, CellTable)93 return module.cell_table94 