pyloxi: parse unknown subclasses as the superclass

Previously we would throw an exception if we encountered a (for example)
experimenter action subclass that we didn't know existed. This was fine for
OFTest but causes problems for other tools that use pyloxi.

This change generates a full set of pack/unpack/pretty_print functions for
virtual classes. If a discriminator field contains a subtype we don't know
about, the virtual class is instantiated instead.

This also removes the special cases around unknown hello elements.
diff --git a/py_gen/tests/of10.py b/py_gen/tests/of10.py
index 250000f..7e10335 100644
--- a/py_gen/tests/of10.py
+++ b/py_gen/tests/of10.py
@@ -112,10 +112,10 @@
         with self.assertRaisesRegexp(ofp.ProtocolError, 'Buffer too short'):
             loxi.generic_util.unpack_list(OFReader(buf), ofp.action.action.unpack)
 
-    def test_invalid_action_type(self):
+    def test_unknown_action_type(self):
         buf = '\xff\xfe\x00\x08\x00\x00\x00\x00'
-        with self.assertRaisesRegexp(ofp.ProtocolError, 'unknown action subtype'):
-            loxi.generic_util.unpack_list(OFReader(buf), ofp.action.action.unpack)
+        result = loxi.generic_util.unpack_list(OFReader(buf), ofp.action.action.unpack)
+        self.assertEquals(result, [ofp.action.action(type=0xfffe)])
 
 class TestConstants(unittest.TestCase):
     def test_ports(self):
@@ -200,11 +200,19 @@
         test_klasses = [x for x in ofp.message.__dict__.values()
                         if type(x) == type
                            and issubclass(x, ofp.message.message)
-                           and hasattr(x, 'pack')]
+                           and not hasattr(x, 'subtypes')]
 
         for klass in test_klasses:
             self.assertIsInstance(ofp.message.parse_message(klass(xid=1).pack()), klass)
 
+    def test_parse_unknown_message(self):
+        import loxi
+        import loxi.of10 as ofp
+
+        buf = "\x01\xfe\x00\x08\x12\x34\x56\x78"
+        msg = ofp.message.parse_message(buf)
+        self.assertIsInstance(msg, ofp.message.message)
+
 class TestUtils(unittest.TestCase):
     def test_pretty_wildcards(self):
         self.assertEquals("OFPFW_ALL", ofp.util.pretty_wildcards(ofp.OFPFW_ALL))
@@ -231,7 +239,7 @@
                               for klass in mod.__dict__.values()
                               if isinstance(klass, type) and
                                  issubclass(klass, loxi.OFObject) and
-                                 hasattr(klass, 'pack')]
+                                 not hasattr(klass, 'subtypes')]
         self.klasses.sort(key=lambda x: str(x))
 
     def test_serialization(self):