|
|
from types import StringTypes |
from types import StringTypes |
|
|
|
__all__ = [ |
|
'structType', 'struct', 'makeStructType' |
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class structType(type): |
class structType(type): |
|
|
"""Sets up __fieldmap__ and field properties""" |
"""Sets up __fieldmap__ and field properties""" |
|
|
|
classmethods = ( |
|
'fromArgs', 'fromOther', 'fromString', |
|
'fromMapping', 'extractFromMapping', |
|
) |
|
|
def __new__(klass, name, bases, cdict): |
def __new__(klass, name, bases, cdict): |
|
|
cdict = cdict.copy() |
cdict = cdict.copy() |
cdict['__slots__']=[] |
cdict['__slots__']=[] |
|
|
|
for cm in klass.classmethods: |
|
if cm in cdict: |
|
cdict[cm] = classmethod(cdict[cm]) |
|
|
return super(structType,klass).__new__(klass, name, bases, cdict) |
return super(structType,klass).__new__(klass, name, bases, cdict) |
|
|
|
|
setattr(klass, fieldName, makeFieldProperty(fieldName, fieldNum)) |
setattr(klass, fieldName, makeFieldProperty(fieldName, fieldNum)) |
|
|
|
|
|
|
|
|
|
|
|
|
def addField(klass, fieldName): |
def addField(klass, fieldName): |
|
|
"""Add field 'fieldName' to an existing struct class""" |
"""Add field 'fieldName' to an existing struct class""" |
Note: if you define custom properties, they only determine the *attributes* |
Note: if you define custom properties, they only determine the *attributes* |
of the instance. All other behaviors including string representation, |
of the instance. All other behaviors including string representation, |
iteration, item retrieval, etc., will be unaffected. It's probably best |
iteration, item retrieval, etc., will be unaffected. It's probably best |
to define a 'defaultCreate' classmethod to manage the initial construction |
to redefine the 'fromArgs' classmethod to manage the initial construction |
of the fields instead.""" |
of the fields instead.""" |
|
|
__metaclass__ = structType |
__metaclass__ = structType |
return klass.fromArgs(*__args, **__kw) |
return klass.fromArgs(*__args, **__kw) |
|
|
|
|
|
def fromString(klass, arg): |
|
|
|
"""Override this classmethod to enable parsing from a string""" |
|
|
|
raise NotImplementedError |
|
|
|
|
|
|
|
|
|
|
|
|
return tuple.__new__(klass, __args) |
return tuple.__new__(klass, __args) |
|
|
fromArgs = classmethod(fromArgs) |
|
|
|
|
|
|
|
""" |
""" |
return klass.fromArgs(arg) |
return klass.fromArgs(arg) |
|
|
fromOther = classmethod(fromOther) |
|
|
|
|
|
def fromString(klass, arg): |
|
"""Override this classmethod to enable parsing from a string""" |
|
raise NotImplementedError |
|
|
|
fromString = classmethod(fromString) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fromMapping(klass, arg): |
def fromMapping(klass, arg): |
|
|
|
|
return klass.fromArgs(*tuple(map(arg.get, klass.__fields__))) |
return klass.fromArgs(*tuple(map(arg.get, klass.__fields__))) |
|
|
fromMapping = classmethod(fromMapping) |
|
|
|
|
|
def extractFromMapping(klass, arg): |
def extractFromMapping(klass, arg): |
"""Fast extraction from a mapping; ignores undefined fields""" |
"""Fast extraction from a mapping; ignores undefined fields""" |
return klass.fromArgs(*tuple(map(arg.get, klass.__fields__))) |
return klass.fromArgs(*tuple(map(arg.get, klass.__fields__))) |
|
|
extractFromMapping = classmethod(extractFromMapping) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getitem__(self, key): |
def __getitem__(self, key): |
|
|
except (KeyError,IndexError): |
except (KeyError,IndexError): |
return default |
return default |
|
|
|
|
def copy(self): return dict(self.items()) |
def copy(self): return dict(self.items()) |
def keys(self): return list(self.__fields__[:len(self)]) |
def keys(self): return list(self.__fields__[:len(self)]) |
def iterkeys(self): return iter(self.__fields__[:len(self)]) |
def iterkeys(self): return iter(self.__fields__[:len(self)]) |
def values(self): return list(self) |
def values(self): return list(self) |
def itervalues(self): return iter(self) |
def itervalues(self): return iter(self) |
|
|
|
|
|
|
|
|
|
|
__safe_for_unpickling__ = True |
__safe_for_unpickling__ = True |
|
|
def __reduce__(self): return self.__class__, (tuple(self),) |
def __reduce__(self): return self.__class__, (tuple(self),) |
|
|
has_key = __contains__ |
has_key = __contains__ |
|
|
|
|
|
|
def makeFieldProperty(fieldName, fieldNum): |
def makeFieldProperty(fieldName, fieldNum): |
|
|
def get(self): |
def get(self): |
|
|
return property(get) |
return property(get) |
|
|
|
|
def makeStructType(name, fields, baseType=struct, **kw): |
def makeStructType(name, fields, baseType=struct, **kw): |
kw['__fields__'] = fields |
kw['__fields__'] = fields |
return structType(name or 'anonymous_struct', (baseType,), kw) |
return structType(name or 'anonymous_struct', (baseType,), kw) |