from typing import Generic, Iterable, Optional, TypeVar from bs4 import Tag T = TypeVar("T") class WidgetParser: def parse_widget(self, tag: Tag) -> Tag: raise NotImplementedError class BaseWidgetParser(WidgetParser): SELECT: str def __init__(self, select: Optional[str] = None): super().__init__() self._select = select or self.SELECT def parse_widget(self, tag: Tag) -> Tag: widget = tag.select_one(self._select) if widget is None: raise ValueError(self._select) return widget class RowParser(Generic[T]): KEY: str def parse_row(self, tag: Tag) -> Iterable[T]: raise NotImplementedError