"""Implementation helper: a struct that looks like a tuple. See timemoduleand posixmodule for example uses."""classstructseqfield(object):"""Definition of field of a structseq. The 'index' is for positional tuple-like indexing. Fields whose index is after a gap in the numbers cannot be accessed like this, but only by name. """def__init__(self,index,doc=None,default=lambdaself:None):self.__name__='?'self.index=index# patched to None if not positionalself._index=indexself.__doc__=docself._default=defaultdef__repr__(self):return'<field %s (%s)>'%(self.__name__,self.__doc__or'undocumented')def__get__(self,obj,typ=None):ifobjisNone:returnselfifself.indexisNone:returnobj.__dict__[self.__name__]else:returnobj[self.index]def__set__(self,obj,value):raiseTypeError("readonly attribute")classstructseqtype(type):def__new__(metacls,classname,bases,dict):assertnotbasesfields_by_index={}forname,fieldindict.items():ifisinstance(field,structseqfield):assertfield._indexnotinfields_by_indexfields_by_index[field._index]=fieldfield.__name__=namedict['n_fields']=len(fields_by_index)extra_fields=fields_by_index.items()extra_fields.sort()n_sequence_fields=0whileextra_fieldsandextra_fields[0][0]==n_sequence_fields:extra_fields.pop(0)n_sequence_fields+=1dict['n_sequence_fields']=n_sequence_fieldsdict['n_unnamed_fields']=0# no fully anonymous fields in PyPyextra_fields=[fieldforindex,fieldinextra_fields]forfieldinextra_fields:field.index=None# no longer relevantassert'__new__'notindictdict['_extra_fields']=tuple(extra_fields)dict['__new__']=structseq_newdict['__reduce__']=structseq_reducedict['__setattr__']=structseq_setattrdict['__repr__']=structseq_reprdict['_name']=dict.get('name','')returntype.__new__(metacls,classname,(tuple,),dict)builtin_dict=dictdefstructseq_new(cls,sequence,dict={}):sequence=tuple(sequence)dict=builtin_dict(dict)N=cls.n_sequence_fieldsiflen(sequence)<N:ifN<cls.n_fields:msg="at least"else:msg="exactly"raiseTypeError("expected a sequence with %s%d items"%(msg,N))iflen(sequence)>N:iflen(sequence)>cls.n_fields:ifN<cls.n_fields:msg="at most"else:msg="exactly"raiseTypeError("expected a sequence with %s%d items"%(msg,cls.n_fields))forfield,valueinzip(cls._extra_fields,sequence[N:]):name=field.__name__ifnameindict:raiseTypeError("duplicate value for %r"%(name,))dict[name]=valuesequence=sequence[:N]result=tuple.__new__(cls,sequence)object.__setattr__(result,'__dict__',dict)forfieldincls._extra_fields:name=field.__name__ifnamenotindict:dict[name]=field._default(result)returnresultdefstructseq_reduce(self):returntype(self),(tuple(self),self.__dict__)defstructseq_setattr(self,attr,value):raiseAttributeError("%r object has no attribute %r"%(self.__class__.__name__,attr))defstructseq_repr(self):fields={}forfieldintype(self).__dict__.values():ifisinstance(field,structseqfield):fields[field._index]=fieldparts=["%s=%r"%(fields[index].__name__,value)forindex,valueinenumerate(self)]return"%s(%s)"%(self._name,", ".join(parts))