docs: def describe(self, incl_properties=False, incl_details=False, fields=None, default_fields=None, **kwargs):
          """
          :param fields: set of fields to include in the output, for
              example ``{'name', 'modified'}``. The field ``id`` is always
              implicitly included. If ``fields`` is specified, the default
              fields are not included (that is, only the fields specified
              here, and ``id``, are included) unless ``default_fields`` is
              additionally set to True.
          :type fields: set or sequence of str
          :param default_fields: if True, include the default fields in
              addition to fields requested in ``fields``, if any; if
              False, only the fields specified in ``fields``, if any, are
              returned (defaults to False if ``fields`` is specified, True
              otherwise)
          :type default_fields: bool
          :param incl_properties: if true, includes the properties of the
              object in the output (deprecated; use
              ``fields={'properties'}, default_fields=True`` instead)
          :type incl_properties: bool
          :param incl_details: if true, includes the details of the object
              in the output (deprecated; use ``fields={'details'},
              default_fields=True`` instead)
          :type incl_details: bool
          :returns: Description of the remote object
          :rtype: dict
  
          Return a dict with a description of the remote data object.
  
          The result includes the key-value pairs as specified in the API
          documentation for the ``/describe`` method of each data object
          class. The API defines some default set of fields that will be
          included (at a minimum, "id", "class", etc. should be available,
          and there may be additional fields that vary based on the
          class); the set of fields may be customized using ``fields`` and
          ``default_fields``.
  
          Any project-specific metadata fields (name, properties, and
          tags) are obtained from the copy of the object in the project
          associated with the handler, if possible.
  
          """
  
          if self._dxid is None:
              raise DXError('This {handler} handler has not been initialized with a {_class} ID and cannot be described'.format(
                  handler=self.__class__.__name__,
                  _class=self._class)
              )
  
          if (incl_properties or incl_details) and (fields is not None or default_fields is not None):
              raise ValueError('Cannot specify properties or details in conjunction with fields or default_fields')
  
          if incl_properties or incl_details:
              describe_input = dict(properties=incl_properties, details=incl_details)
          else:
              describe_input = {}
              if default_fields is not None:
                  describe_input['defaultFields'] = default_fields
              if fields is not None:
                  describe_input['fields'] = {field_name: True for field_name in fields}
  
          if self._proj is not None:
              describe_input["project"] = self._proj
  
          self._desc = self._describe(self._dxid, describe_input, **kwargs)
  
          return self._desc