Skip to content

Instantly share code, notes, and snippets.

@harvimt
Last active December 19, 2015 14:49
Show Gist options
  • Save harvimt/5972099 to your computer and use it in GitHub Desktop.
Save harvimt/5972099 to your computer and use it in GitHub Desktop.
Example metaclass implementation for Python 3 for the construct3 library
class CustomCollection():
def __init__(self):
super().__init__()
self.items = []
def __setitem__(self, key, value):
if key == '_':
self.items.append(value)
else:
self.items.append((key, value))
def __getitem__(self, key):
if key == '_':
raise KeyError('_')
return dict(self.items)[key]
class _MetaStruct(type):
""" metaclass for use by magic struct"""
@classmethod
def __prepare__(metacls, name, bases):
return CustomCollection()
def __new__(cls, name, bases, classdict):
if bases:
return Struct(*classdict.items())
else:
return super().__new__(name, bases, classdict.items())
class MagicStruct(metaclass=_MetaStruct):
""" syntactic sugar for making Structs"""
pass
class ExampleStruct(MagicStruct)
named = uint64l
_ = Embedded(Flags(uint64l,
flag1=0x01,
flag2=0x20,
))
@harvimt
Copy link
Author

harvimt commented Jul 14, 2013

How about:

next = Switch(this.type)
next[0x1234] = IPHeader

@next.condition(0x2345)
class next(MagicStruct):
pass

next[Switch.default] = uint64l

that could be made to work (w/o macros), but now there's machinery to do Switch inside the Struct metaclass, which I suppose isn't composable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment