from __future__ import annotations from typing import ( List, Literal, Optional, NamedTuple, NewType, ) Maintainer = NewType('Maintainer', str) def annotate_maints( pkg: str, maints: List[Maintainer], ) -> str: maints_str = ', '.join(f'@{m}' for m in maints) return f'{pkg} ({maints_str})' class Dependent(NamedTuple): pkgbase: str maintainers: List[Maintainer] class OrphanResult: _lit_created = False def __new__( cls, ty: Literal['Removed', 'NotFound', 'Depended'], dependents: Optional[List[Dependent]] = None, ) -> OrphanResult: if ty in ['Removed', 'NotFound'] and \ cls._lit_created: return getattr(cls, ty) inst = super().__new__(cls) inst.__init__(ty, dependents) # type: ignore return inst def __init__( self, ty: Literal['Removed', 'NotFound', 'Depended'], dependents: Optional[List[Dependent]] = None, ) -> None: self.ty = ty if ty == 'Depended': if dependents is None: raise ValueError('dependents not given') self.dependents = dependents @classmethod def Depended( cls, dependents: List[Dependent], ) -> OrphanResult: return cls('Depended', dependents) def __repr__(self) -> str: name = self.__class__.__name__ if self.ty == 'Depended': s = f'<{name}: Depended({self.dependents!r})>' else: s = f'<{name}: {self.ty}>' return s Removed: OrphanResult NotFound: OrphanResult OrphanResult.Removed = OrphanResult('Removed') OrphanResult.NotFound = OrphanResult('NotFound') OrphanResult._lit_created = True