""" .. codeauthor:: Tsuyoshi Hombashi """ import enum import platform import re import string from pathlib import Path from typing import Any, List, Optional, Union, cast _re_whitespaces = re.compile(r"^[\s]+$") @enum.unique class Platform(enum.Enum): POSIX = "POSIX" UNIVERSAL = "universal" LINUX = "Linux" WINDOWS = "Windows" MACOS = "macOS" PathType = Union[str, Path] PlatformType = Union[str, Platform, None] def is_pathlike_obj(value: PathType) -> bool: return isinstance(value, Path) def validate_pathtype( text: PathType, allow_whitespaces: bool = False, error_msg: Optional[str] = None ) -> None: from .error import ErrorReason, ValidationError if _is_not_null_string(text) or is_pathlike_obj(text): return if allow_whitespaces and _re_whitespaces.search(str(text)): return if is_null_string(text): if not error_msg: error_msg = "the value must be a not empty" raise ValidationError( description=error_msg, reason=ErrorReason.NULL_NAME, ) raise TypeError("text must be a string: actual={}".format(type(text))) def validate_null_string(text: PathType, error_msg: Optional[str] = None) -> None: # Deprecated: alias to validate_pathtype validate_pathtype(text, False, error_msg) def preprocess(name: PathType) -> str: if is_pathlike_obj(name): name = str(name) return cast(str, name) def is_null_string(value: Any) -> bool: if value is None: return True try: return len(value.strip()) == 0 except AttributeError: return False def _is_not_null_string(value: Any) -> bool: try: return len(value.strip()) > 0 except AttributeError: return False def _get_unprintable_ascii_chars() -> List[str]: return [chr(c) for c in range(128) if chr(c) not in string.printable] unprintable_ascii_chars = tuple(_get_unprintable_ascii_chars()) def _get_ascii_symbols() -> List[str]: symbol_list = [] # type: List[str] for i in range(128): c = chr(i) if c in unprintable_ascii_chars or c in string.digits + string.ascii_letters: continue symbol_list.append(c) return symbol_list ascii_symbols = tuple(_get_ascii_symbols()) __RE_UNPRINTABLE_CHARS = re.compile( "[{}]".format(re.escape("".join(unprintable_ascii_chars))), re.UNICODE ) def replace_unprintable_char(text: str, replacement_text: str = "") -> str: try: return __RE_UNPRINTABLE_CHARS.sub(replacement_text, text) except (TypeError, AttributeError): raise TypeError("text must be a string") def normalize_platform(name: PlatformType) -> Platform: if isinstance(name, Platform): return name if name: name = name.strip().lower() if name == "posix": return Platform.POSIX if name == "auto": name = platform.system().lower() if name in ["linux"]: return Platform.LINUX if name and name.startswith("win"): return Platform.WINDOWS if name in ["mac", "macos", "darwin"]: return Platform.MACOS return Platform.UNIVERSAL def findall_to_str(match: List[Any]) -> str: return ", ".join([repr(text) for text in match])