from typing import List, Protocol, Tuple, Union def MakeAttrs(css:str|Tuple[str, ...]|None, id:str|None, attributes: dict[str, str | None]) -> str: if css: attributes['class'] = " ".join(css) if isinstance(css, (list, tuple)) else css if id: attributes['id'] = id attrList: List[str] = [] for key, value in attributes.items(): if value: attrList.append(f'{key}="{value}"') return " ".join(attrList) class ComplexProxyLeaf(dict): name:str = "" attrs:str = "" def __init__(self, name:str): self.name = name def __call__(self, css:str|None = None, id:str|None = None): clone = ComplexProxyLeaf(self.name) clone.attrs = MakeAttrs(css, id, {}) return clone def __repr__(self) -> str: return f'<{self.name} {self.attrs}/>' class ComplexProxyBranch(ComplexProxyLeaf): name:str = "" attrs:str = "" def __init__(self, name:str): self.name = name def __call__(self, css:str|None = None, id:str|None = None): clone = ComplexProxyBranch(self.name) clone.attrs = MakeAttrs(css, id, {}) return clone def __repr__(self) -> str: print("dump", self.attrs) copy = self.attrs self.attrs = "" return f'<{self.name} {copy}>' def __getitem__(self, key:Union[str, 'ComplexProxyBranch', ComplexProxyLeaf, Tuple[Union[str, 'ComplexProxyBranch', ComplexProxyLeaf], ...]]) -> str: if isinstance(key, tuple): children = "".join(str(k) for k in key) else: children = key print("child", self.attrs) return f'<{self.name} {self.attrs}>{children}' IMG = ComplexProxyLeaf("img") BR = ComplexProxyLeaf("br") A = ComplexProxyBranch("a") print( A [ "click here", BR, A(css="test"), A(css="www.site.com") [ IMG(id="image.png") ] ] )