docs: def normalize_datum(self, datum):
          """
          Convert `datum` into something that umsgpack likes.
  
          :param datum: something that we want to process with umsgpack
          :return: a packable version of `datum`
          :raises TypeError: if `datum` cannot be packed
  
          This message is called by :meth:`.packb` to recursively normalize
          an input value before passing it to :func:`umsgpack.packb`.  Values
          are normalized according to the following table.
  
          +-------------------------------+-------------------------------+
          | **Value**                     | **MsgPack Family**            |
          +-------------------------------+-------------------------------+
          | :data:`None`                  | `nil byte`_ (0xC0)            |
          +-------------------------------+-------------------------------+
          | :data:`True`                  | `true byte`_ (0xC3)           |
          +-------------------------------+-------------------------------+
          | :data:`False`                 | `false byte`_ (0xC2)          |
          +-------------------------------+-------------------------------+
          | :class:`int`                  | `integer family`_             |
          +-------------------------------+-------------------------------+
          | :class:`float`                | `float family`_               |
          +-------------------------------+-------------------------------+
          | String                        | `str family`_                 |
          +-------------------------------+-------------------------------+
          | :class:`bytes`                | `bin family`_                 |
          +-------------------------------+-------------------------------+
          | :class:`bytearray`            | `bin family`_                 |
          +-------------------------------+-------------------------------+
          | :class:`memoryview`           | `bin family`_                 |
          +-------------------------------+-------------------------------+
          | :class:`collections.Sequence` | `array family`_               |
          +-------------------------------+-------------------------------+
          | :class:`collections.Set`      | `array family`_               |
          +-------------------------------+-------------------------------+
          | :class:`collections.Mapping`  | `map family`_                 |
          +-------------------------------+-------------------------------+
          | :class:`uuid.UUID`            | Converted to String           |
          +-------------------------------+-------------------------------+
  
          .. _nil byte: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#formats-nil
          .. _true byte: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#bool-format-family
          .. _false byte: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#bool-format-family
          .. _integer family: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#int-format-family
          .. _float family: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#float-format-family
          .. _str family: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#str-format-family
          .. _array family: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#array-format-family
          .. _map family: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md
             #mapping-format-family
          .. _bin family: https://github.com/msgpack/msgpack/blob/
             0b8f5ac67cdd130f4d4d4fe6afb839b989fdb86a/spec.md#bin-format-family
  
          """
          if datum is None:
              return datum
  
          if isinstance(datum, self.PACKABLE_TYPES):
              return datum
  
          if isinstance(datum, uuid.UUID):
              datum = str(datum)
  
          if isinstance(datum, bytearray):
              datum = bytes(datum)
  
          if isinstance(datum, memoryview):
              datum = datum.tobytes()
  
          if hasattr(datum, 'isoformat'):
              datum = datum.isoformat()
  
          if isinstance(datum, (bytes, str)):
              return datum
  
          if isinstance(datum, (collections.Sequence, collections.Set)):
              return [self.normalize_datum(item) for item in datum]
  
          if isinstance(datum, collections.Mapping):
              out = {}
              for k, v in datum.items():
                  out[k] = self.normalize_datum(v)
              return out
  
          raise TypeError(
              '{} is not msgpackable'.format(datum.__class__.__name__))