code: def field(type=PFIELD_NO_TYPE, invariant=PFIELD_NO_INVARIANT, initial=PFIELD_NO_INITIAL,
            mandatory=False, factory=PFIELD_NO_FACTORY, serializer=PFIELD_NO_SERIALIZER):
      
  
      # NB: We have to check this predicate separately from the predicates in
      # `maybe_parse_user_type` et al. because this one is related to supporting
      # the argspec for `field`, while those are related to supporting the valid
      # ways to specify types.
  
      # Multiple types must be passed in one of the following containers. Note
      # that a type that is a subclass of one of these containers, like a
      # `collections.namedtuple`, will work as expected, since we check
      # `isinstance` and not `issubclass`.
      if isinstance(type, (list, set, tuple)):
          types = set(maybe_parse_many_user_types(type))
      else:
          types = set(maybe_parse_user_type(type))
  
      invariant_function = wrap_invariant(invariant) if invariant != PFIELD_NO_INVARIANT and callable(invariant) else invariant
      field = _PField(type=types, invariant=invariant_function, initial=initial,
                      mandatory=mandatory, factory=factory, serializer=serializer)
  
      _check_field_parameters(field)
  
      return field
docs: Field specification factory for :py:class:`PRecord`.
  
      :param type: a type or iterable with types that are allowed for this field
      :param invariant: a function specifying an invariant that must hold for the field
      :param initial: value of field if not specified when instantiating the record
      :param mandatory: boolean specifying if the field is mandatory or not
      :param factory: function called when field is set.
      :param serializer: function that returns a serialized version of the field