docs: def _assign_field(self, assigned_bits, identifier, field_values):
          """For internal use only.  Assign a length and position to a field
          which may have either one of these values missing.
  
          Parameters
          ----------
          assigned_bits : int
              A bit mask of bits already in use by other fields
          identifier : str
              The identifier of the field to assign
          field_values : {identifier: value, ...}
              The values held by various fields (used to access the correct
              identifier)
  
          Returns
          -------
          int
              Mask of which bits which are assigned to fields after this field
              has been assigned.
          """
          field = self.fields.get_field(identifier, field_values)
  
          length = field.length
          if length is None:
              # Assign lengths based on values
              length = int(log(field.max_value, 2)) + 1
  
          start_at = field.start_at
          if start_at is None:
              # Force a failure if no better space is found
              start_at = self.length
  
              # Try every position until a space is found
              for bit in range(0, self.length - length):
                  field_bits = ((1 << length) - 1) << bit
                  if not (assigned_bits & field_bits):
                      start_at = bit
                      assigned_bits |= field_bits
                      break
          else:
              # A start position has been forced, ensure that it can be fulfilled
              field_bits = ((1 << length) - 1) << start_at
  
              if assigned_bits & field_bits:
                  raise ValueError(
                      "{}-bit field {} with fixed position does not fit in "
                      "{}.".format(
                          field.length,
                          self.fields.get_field_human_readable(identifier,
                                                               field_values),
                          type(self).__name__
                      )
                  )
  
              # Mark these bits as assigned
              assigned_bits |= field_bits
  
          # Check that the calculated field is within the bit field
          if start_at + length <= self.length:
              field.length = length
              field.start_at = start_at
          else:
              raise ValueError(
                  "{}-bit field {} does not fit in {}.".format(
                      field.length,
                      self.fields.get_field_human_readable(identifier,
                                                           field_values),
                      type(self).__name__
                  )
              )
  
          return assigned_bits