pyloxi: create inheritance hierarchy

Virtual classes are generated but currently only serve as superclasses.

Somehow this works without topologically sorting the classes.
diff --git a/py_gen/templates/action.py b/py_gen/templates/action.py
index 77a1d9f..2f1d020 100644
--- a/py_gen/templates/action.py
+++ b/py_gen/templates/action.py
@@ -48,12 +48,12 @@
         return parser(reader)
     return loxi.generic_util.unpack_list_tlv16(reader, deserializer)
 
-class Action(object):
-    type = None # override in subclass
-    pass
-
 :: for ofclass in ofclasses:
-:: include('_ofclass.py', ofclass=ofclass, superclass="Action")
+:: if ofclass.virtual:
+:: include('_virtual_ofclass.py', ofclass=ofclass)
+:: else:
+:: include('_ofclass.py', ofclass=ofclass)
+:: #endif
 
 :: #endfor
 
@@ -72,8 +72,9 @@
         raise loxi.ProtocolError("unexpected BSN experimenter subtype %#x" % subtype)
 
 parsers = {
+:: concrete_ofclasses = [x for x in ofclasses if not x.virtual]
 :: sort_key = lambda x: x.member_by_name('type').value
-:: msgtype_groups = itertools.groupby(sorted(ofclasses, key=sort_key), sort_key)
+:: msgtype_groups = itertools.groupby(sorted(concrete_ofclasses, key=sort_key), sort_key)
 :: for (k, v) in msgtype_groups:
 :: k = util.constant_for_value(version, "ofp_action_type", k)
 :: v = list(v)
@@ -85,7 +86,7 @@
 :: #endfor
 }
 
-:: experimenter_ofclasses = [x for x in ofclasses if x.member_by_name('type').value == 0xffff]
+:: experimenter_ofclasses = [x for x in concrete_ofclasses if x.member_by_name('type').value == 0xffff]
 :: sort_key = lambda x: x.member_by_name('experimenter').value
 :: experimenter_ofclasses.sort(key=sort_key)
 :: grouped = itertools.groupby(experimenter_ofclasses, sort_key)