def_dump_tuple(t:tuple)->bytes:cnt=b""foritemint:ifitemisnotNone:type_=type(item)iftype_in_DUMP_BY_TYPE:cnt+=_DUMP_BY_TYPE[type_](item)else:# for TaggedObjects, hash(item) is stable# other types of items may show up, such as pyvex.expr.CCall and Dirty. they will be removed some day.cnt+=struct.pack("<Q",hash(item)&0xFFFF_FFFF_FFFF_FFFF)cnt+=b"\xf0"returncntdef_dump_str(t:str)->bytes:returnt.encode("ascii")def_dump_int(t:int)->bytes:prefix=b""ift>=0elseb"-"t=abs(t)ift<=0xFFFF:returnprefix+struct.pack("<H",t)elift<=0xFFFF_FFFF:returnprefix+struct.pack("<I",t)elift<=0xFFFF_FFFF_FFFF_FFFF:returnprefix+struct.pack("<Q",t)else:cnt=b""whilet>0:cnt+=_dump_int(t&0xFFFF_FFFF_FFFF_FFFF)t>>=64returnprefix+cntdef_dump_type(t:type)->bytes:returnt.__name__.encode("ascii")_DUMP_BY_TYPE={tuple:_dump_tuple,str:_dump_str,int:_dump_int,type:_dump_type,}
[docs]defis_none_or_likeable(arg1,arg2,is_list=False):""" Returns whether two things are both None or can like each other """from.expressionimportExpressionifarg1isNoneorarg2isNone:ifarg1==arg2:returnTruereturnFalseifis_list:returnlen(arg1)==len(arg2)andall(is_none_or_likeable(a1,a2)fora1,a2inzip(arg1,arg2))ifisinstance(arg1,Expression):returnarg1.likes(arg2)returnarg1==arg2