@log_calls
  def get_tags(self, scope, srev_start=None, srev_end=None, filter=None):
    '''
    Return the list of all tags at this scope, each in the form (tag, rev).
    Output is ordered historically, based on srev_start and srev_end. Multiple tags
    may be returned for a single revision. Returns empty if expect is false and
    scope is not valid.
    '''
    tags_file = self._store_path_tags(scope)
    if not self.store.exists(tags_file):
      log.debug("get_tags: tags file not present: %s", tags_file)
      # TODO should change so we always make empty tags file, and use this to raise exception only if invalid scope 
      return

    # Find all tags in the desired range (if supplied) that also match the filter (if supplied).
    # The range implies the direction.
    all_tags = self._parse_tags(self.store.read_string(self._store_path_tags(scope)))
    tag_dict = group_pairs((rev, name) for (name, rev) in all_tags)
    revs = self._rev_range(scope, srev_start, srev_end)
    for rev in revs:
      if rev in tag_dict:
        for tag in sorted(tag_dict[rev]):
          if not filter or filter(self.get_manifest(scope, rev)):
            yield (tag, rev)
dataset/ETHPy150Open bloomreach/zinc/zinc.py/Repo.get_tags/original