Created
December 31, 2024 09:48
-
-
Save mypy-play/2d95cc2c5e14fdf0776cc3418c189c8c to your computer and use it in GitHub Desktop.
Shared via mypy Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from enum import Enum, unique, auto | |
| from dataclasses import dataclass | |
| from typing import List, TypeVar, Type | |
| from pathlib import Path | |
| import os | |
| I = TypeVar('I', bound='Input') | |
| @unique | |
| class InputType(Enum): | |
| FILE = auto() | |
| STRING = auto() | |
| @dataclass(frozen=True) | |
| class Input: | |
| input_type: InputType | |
| input_value: str | |
| def __post_init__(self): | |
| if not isinstance(self.input_type, InputType): | |
| raise TypeError(f"Type must be InputType, got {type(self.input_type)}") | |
| if not isinstance(self.input_value, str): | |
| raise TypeError(f"Value must be string, got {type(self.input_value)}") | |
| match self.input_type: | |
| case InputType.FILE: | |
| self._validate_file_path(self.input_value) | |
| case InputType.STRING: | |
| self._validate_str(self.input_value) | |
| case _: | |
| raise ValueError(f"Unsupported input type: {self.input_type}") | |
| def get_lines(self) -> List[str]: | |
| match self.input_type: | |
| case InputType.FILE: | |
| with open(self.input_value) as file: | |
| return file.readlines() | |
| case InputType.STRING: | |
| return self.input_value.splitlines() | |
| case _: | |
| raise ValueError(f"Unsupported input type: {self.input_type}") | |
| @classmethod | |
| def from_file(cls: Type[I], file_path: str) -> I: | |
| return cls(input_type=InputType.FILE, input_value=file_path) | |
| @classmethod | |
| def from_string(cls: Type[I], raw_string: str) -> I: | |
| return cls(input_type=InputType.STRING, input_value=raw_string) | |
| @staticmethod | |
| def _validate_str(s: str | bytes) -> None: | |
| try: | |
| if isinstance(s, str): | |
| s.encode('utf-8') | |
| elif isinstance(s, bytes): | |
| s.decode('utf-8') | |
| except UnicodeError: | |
| raise ValueError(f"Input data must be valid utf-8.") | |
| @staticmethod | |
| def _validate_file_path(file_path: str) -> None: | |
| path = Path(file_path) | |
| try: | |
| path = path.resolve(strict=True) | |
| except (FileNotFoundError, RuntimeError): | |
| raise ValueError(f"Invalid file path: {file_path}") | |
| if not path.is_file(): | |
| raise ValueError(f"Path is not a file: {file_path}") | |
| if not os.access(path, os.R_OK): | |
| raise ValueError(f"File is not readable: {file_path}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment