Skip to content

Instantly share code, notes, and snippets.

@datavudeja
Forked from mypy-play/main.py
Created September 17, 2025 20:10
Show Gist options
  • Save datavudeja/3d79ba80fa5a1be8265f09aba4c98cda to your computer and use it in GitHub Desktop.
Save datavudeja/3d79ba80fa5a1be8265f09aba4c98cda to your computer and use it in GitHub Desktop.
Shared via mypy Playground
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