docs: def extend(self, new_attr_dict):
          """
          *Wrapper of* ``EXTEND``
  
          For each sample in an input dataset, the EXTEND operator builds new metadata attributes,
          assigns their values as the result of arithmetic and/or aggregate functions calculated on 
          sample region attributes, and adds them to the existing metadata attribute-value pairs of 
          the sample. Sample number and their genomic regions, with their attributes and values, 
          remain unchanged in the output dataset.  
          
          :param new_attr_dict: a dictionary of the type {'new_metadata' : AGGREGATE_FUNCTION('field'), ...}
          :return: new GMQLDataset
          
          An example of usage, in which we count the number of regions in each sample and the minimum
          value of the `pValue` field and export it respectively as metadata attributes `regionCount` and `minPValue`::
          
              import gmql as gl
              
              dataset = gl.get_example_dataset("Example_Dataset_1")
              new_dataset = dataset.extend({'regionCount' : gl.COUNT(),
                                            'minPValue' : gl.MIN('pValue')})
          """
          if isinstance(new_attr_dict, dict):
              expBuild = self.pmg.getNewExpressionBuilder(self.__index)
              aggregates = []
              for k in new_attr_dict.keys():
                  if isinstance(k, str):
                      item = new_attr_dict[k]
                      if isinstance(item, Aggregate):
                          op_name = item.get_aggregate_name()
                          op_argument = Some(item.get_argument()) if item.is_unary() else none()
                          regsToMeta = expBuild.getRegionsToMeta(op_name, k, op_argument)
                          aggregates.append(regsToMeta)
                      else:
                          raise TypeError("The items in new_reg_fields must be Aggregates."
                                          " {} was provided".format(type(item)))
                  else:
                      raise TypeError("The key of new_attr_dict must be a string. "
                                      "{} was provided".format(type(k)))
          else:
              raise TypeError("new_attr_dict must be a dictionary. "
                              "{} was provided".format(type(new_attr_dict)))
  
          new_index = self.opmng.extend(self.__index, aggregates)
          return GMQLDataset(index=new_index, location=self.location,
                             local_sources=self._local_sources,
                             remote_sources=self._remote_sources, meta_profile=self.meta_profile)