PK!ݴG G component_injector/__init__.pyimport contextvars import functools import inspect from types import TracebackType from typing import Any, Callable, Dict, Optional, Type, TypeVar, cast T = TypeVar("T") TypeMap = Dict[Type[T], T] UNSET = object() class Injector: class Context: def __init__(self, injector: "Injector") -> None: self.injector = injector self.registry = injector.registry def __enter__(self) -> None: self.token = self.registry.set(self.registry.get().copy()) def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[Exception], traceback: Optional[TracebackType], ) -> None: self.registry.reset(self.token) registry: contextvars.ContextVar def __init__(self) -> None: self.registry = contextvars.ContextVar("registry", default={}) def register( self, component: Any, *, bases: bool = True, overwrite_bases: bool = True ) -> None: registry: TypeMap = self.registry.get() type_ = type(component) registry[type_] = component if bases: types = type_.mro() for type_ in types: apply = overwrite_bases or type_ not in registry if inspect.isclass(type_) and apply: registry[type_] = component def get_component(self, type_: Type[T]) -> T: registry: TypeMap = self.registry.get() return cast(T, registry[type_]) def scope(self) -> "Injector.Context": return self.Context(self) def inject(self, f: Callable[..., T]) -> Callable[..., T]: sig = inspect.signature(f) @functools.wraps(f) def wrapper(*args: Any, **kwargs: Any) -> T: registry = self.registry.get() bound = sig.bind_partial(*args, **kwargs) for name, param in sig.parameters.items(): if ( name in bound.arguments or param.annotation is inspect.Parameter.empty ): continue component = registry.get(param.annotation, UNSET) if component is not UNSET: bound.arguments[name] = component bound.apply_defaults() return f(*bound.args, **bound.kwargs) return wrapper PK!HڽTU(component_injector-1.0.2.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!Hh: +component_injector-1.0.2.dist-info/METADATAVnF}߯R%M 1: bI iQ"WV.̷C_3K7 @rz̾WAf2Oym͈=AjD-Jk m~SiNtR{n/ 6SάuhH*ɔIkZ)eADrJ?e2a^MJ#Tg⤂Y733CPtJǁ*GԚ:+sԈ^!ɮ8ͥzh4WgtRީ{u@ٙE͌ΥUHOtTœ5^S|}ચÝtzGÃdC[ۻtH@/ .UiRe)D9!J\{āԙ$i Һ@ΌA{060ɩUT=NV2)Ls )1 @)BX&p3Ԕ[ [`-P J7 Tco/~+Ev6HD)S<K{N}TL{9UD!_pJ{KZENX|,4ԜY} Bq,[A>%^s9Ρ2x@p@к $>Od8'ytK l TG-%מ& Ӗ3\>QuI1i+#(ʷvDҺ-> j ˩w2Ѵ;/FiSm &H]oR:3 # >#y3uR =(uɭVEG<:u/2WBC}*|4K Gد4Dt[ $ri}[U"R>WY㎭̓Ԕ'G[;= ҧ}V=_{JV}⡅>mmT!6h;'gRC=6F-7"ķon`#G*}νa j '`sD_ܺ>0On#{^;2M.xsY9l:wpӂZ-(JܔVa*#mUVNHm%cv+F+8и4h/eyr\}9 SQ:53CxюY[౧=CcH*]4[*f.ݧ\!R M{NVmBx]?l4{U62hzR5{{!PgVӤ`R&B% G2a&fn+ufWژil'ts܂fGXsIdt?_МT<5˼_&tgo>\PmMSa ^sj7d@ Kݱ;|Z'"Q_'tr^X!f\L:8ih@JG}qdR4< @}eԨnCyB%Xg/~E-㈼r. )_PK!H?F)component_injector-1.0.2.dist-info/RECORDͽv0@g 0t@"TO A~LO.N]t?ԷF 50nR/'wߚ%ؽ;9a<̊Ř6k/+lH LaDf!L wO(&wj_DZ=E/t?]4ӡ!tnȯ,rp/<ҔaЈض_1R$)` PK!ݴG G component_injector/__init__.pyPK!HڽTU( component_injector-1.0.2.dist-info/WHEELPK!Hh: + component_injector-1.0.2.dist-info/METADATAPK!H?F)Ecomponent_injector-1.0.2.dist-info/RECORDPKRe