diff --git a/coolamqp/framing/base.py b/coolamqp/framing/base.py
index 437856508fc6d3561775fc92081a10e2fee83190..eaf24bab3d1f29f47a475f19314c06d7f60803cb 100644
--- a/coolamqp/framing/base.py
+++ b/coolamqp/framing/base.py
@@ -104,6 +104,7 @@ class AMQPContentPropertyList(object):
         # type: (str, str) -> tp.Union[memoryview, bytes]
         """
         Return a particular property, or default if not defined
+
         :param property_name: property name, unicode
         :param default: default value
         :return: memoryview or bytes
@@ -117,6 +118,7 @@ class AMQPContentPropertyList(object):
 
         This leaves us with a canonical representation, that can be used
         in obtaining a particular property list
+
         :param property_flags: binary
         :return: binary
         """
@@ -143,6 +145,7 @@ class AMQPContentPropertyList(object):
     def get_size(self):  # type: () -> int
         """
         How long is property_flags + property_values
+
         :return: int
         """
         raise Exception(u'This is an abstract method')
@@ -157,7 +160,11 @@ class AMQPMethodPayload(AMQPPayload):
         """
         Calculate the size of this frame.
 
+        Needs to be overloaded, unless you're a class with IS_CONTENT_STATIC
+
         :return: int, size of argument section
+        :raises RuntimeError: this class isn't IS_CONTENT_STATIC and this method was called directly.
+            In this case, you should have rather subclassed it.
         """
         if self.IS_CONTENT_STATIC:
             return len(
diff --git a/coolamqp/framing/field_table.py b/coolamqp/framing/field_table.py
index 60cf0dd1ad00800054cebaa6f01c0d5ab8ebf5f7..a728197bdd7a61ca5472bb968ce06e600f7827e4 100644
--- a/coolamqp/framing/field_table.py
+++ b/coolamqp/framing/field_table.py
@@ -163,12 +163,12 @@ def enframe_array(buf, array):
         enframe_field_value(buf, fv)
 
 
-def enframe_table(buf, table):
+def enframe_table(buf, table):  # type (tp.BinaryIO, table) -> None
     """
     Write AMQP table to buffer
-    :param buf:
-    :param table:
-    :return:
+
+    :param buf: target buffer to write to
+    :param table: table to write
     """
     _tobuf(buf, '!I', frame_table_size(table) - 4)
 
diff --git a/coolamqp/framing/frames.py b/coolamqp/framing/frames.py
index 1aa4ea4b117131da1dcf3d93027cd36a8df73c7b..86424233852bb74d6a0e69155a2cb43c24b12362 100644
--- a/coolamqp/framing/frames.py
+++ b/coolamqp/framing/frames.py
@@ -40,8 +40,8 @@ class AMQPMethodFrame(AMQPFrame):
             self.payload.write_arguments(buf)
             buf.write(FRAME_END_BYTE)
 
-    @staticmethod
-    def unserialize(channel, payload_as_buffer):
+    @classmethod
+    def unserialize(cls, channel, payload_as_buffer):
         clsmet = struct.unpack_from('!HH', payload_as_buffer, 0)
 
         try:
@@ -50,7 +50,7 @@ class AMQPMethodFrame(AMQPFrame):
         except KeyError:
             raise ValueError('Invalid class %s method %s' % clsmet)
         else:
-            return AMQPMethodFrame(channel, payload)
+            return cls(channel, payload)
 
     def get_size(self):  # type: () -> int
         # frame_header = (method(1) + channel(2) + length(4) + class(2) + method(2) + payload(N) + frame_end(1))
@@ -58,17 +58,20 @@ class AMQPMethodFrame(AMQPFrame):
 
 
 class AMQPHeaderFrame(AMQPFrame):
+    """
+    A frame containing a message header
+
+    :param channel: channel ID
+    :type channel: int
+    :param class_id: class ID
+    :type class_id: int
+    :param weight: weight (lol wut?)
+    :param body_size: size of the body to follow
+    :param properties: a suitable AMQPContentPropertyList instance
+    """
     FRAME_TYPE = FRAME_HEADER
 
     def __init__(self, channel, class_id, weight, body_size, properties):
-        # type: (int, int, int, int, AMQPContentPropertyList) -> None
-        """
-        :param channel: channel ID
-        :param class_id: class ID
-        :param weight: weight (lol wut?)
-        :param body_size: size of the body to follow
-        :param properties: a suitable AMQPContentPropertyList instance
-        """
         AMQPFrame.__init__(self, channel)
         self.class_id = class_id
         self.weight = weight
@@ -103,14 +106,20 @@ class AMQPHeaderFrame(AMQPFrame):
 
 
 class AMQPBodyFrame(AMQPFrame):
+    """
+    A frame containing message body
+
+    :param channel: Channel ID
+    :type channel: int
+    :param data: body (or a piece of it) of a message
+    :type data: binary
+    """
+
     FRAME_TYPE = FRAME_BODY
 
     FRAME_SIZE_WITHOUT_PAYLOAD = 8
 
     def __init__(self, channel, data):  # type: (int, bytes) -> None
-        """
-        :type data: binary
-        """
         AMQPFrame.__init__(self, channel)
         assert isinstance(data, (six.binary_type, memoryview))
         self.data = data
@@ -121,9 +130,9 @@ class AMQPBodyFrame(AMQPFrame):
         buf.write(self.data)
         buf.write(FRAME_END_BYTE)
 
-    @staticmethod
-    def unserialize(channel, payload_as_buffer):
-        return AMQPBodyFrame(channel, payload_as_buffer)
+    @classmethod
+    def unserialize(cls, channel, payload_as_buffer):
+        return cls(channel, payload_as_buffer)
 
     def get_size(self):  # type: () -> int
         return 8 + len(self.data)