from dataclasses import dataclass, field, _MISSING_TYPE as mt class Event(): def __init__(self,event_type,data,raw_data,outbound=False): self.event_type=event_type self.data=data self.raw_data=raw_data self.outbound=outbound class Listener(): def __init__(self,name,match,function,): self.name=name or function.__name__ self.match=match self._matchstr=isinstance(match,str) self.function=function def __call__(self,*args,**kwargs): self.function(*args,**kwargs) def __eq__(self,other): if isinstance(other,str): if self._matchstr: return self.match==other return self.match(other) # If it's not a string, assume it's a callable. else: return super.__eq__(self,other) def __str__(self): return self.name # I HATE THE TYPEHINTS! I HATE THE TYPEHINTS! # I REALLY fucking hate the typehints. This is the messiest fucking shit. # WHY IS THIS NOT JUST A DEFAULT THING IN DATACLASS # Please tell me as soon as this egregious oversight is corrected. # I hate this function so much, I want to delete it ASAP. def redc(classy): wrapped=dataclass(classy) def from_dict(somedict): # Sure would be nice if we could just ask for a list of required args. count=len(dict(filter(lambda x:isinstance(x[1].default,mt) and isinstance(x[1].default_factory,mt),wrapped.__dataclass_fields__.items()))) p=wrapped(*[None]*count) for k,v in somedict.items(): if k not in p.__dict__: continue t=p.__dataclass_fields__[k].type try: parsed=t(v) except TypeError: for n in t.__args__: try: parsed=n(v) except: continue else: break # Everything failed so just leave it as default. 🤷 # Watch that somehow generate an error one day anyway. else: parsed=p.__dict__[k] p.__dict__[k]=parsed wrapped.from_dict=from_dict return wrapped def get_or_create(needle,haystack,default): """ This is a wrapper for filter that can add stuff. Nothing special. Needle is a function, default isn't. Haystack is a list. I might fix that later. """ f=filter(needle,haystack) try: return next(f) except StopIteration: pass haystack.append(default) return default