docs: def _filter(self, text, context, encoding):
          """Retrieve the Python docstrings."""
  
          docstrings = []
          strings = []
          comments = []
          prev_token_type = tokenize.NEWLINE
          indent = ''
          name = None
          stack = [(context, 0, self.MODULE)]
          last_comment = False
          possible_fmt_str = None
  
          src = io.StringIO(text)
  
          for token in tokenizer(src.readline):
              token_type = token[0]
              value = token[1]
              line = str(token[2][0])
              line_num = token[2][0]
  
              value = token[1]
              line = str(token[2][0])
  
              # Track function and class ancestry
              if token_type == tokenize.NAME:
                  possible_fmt_str = None
                  if value in ('def', 'class'):
                      name = value
                  elif name:
                      parent = stack[-1][2]
                      prefix = ''
                      if parent != self.MODULE:
                          prefix = '.' if parent == self.CLASS else ', '
                      if name == 'class':
                          stack.append(('%s%s' % (prefix, value), len(indent), self.CLASS))
                      elif name == 'def':
                          stack.append(('%s%s()' % (prefix, value), len(indent), self.FUNCTION))
                      name = None
                  elif not F_SUPPORT and value in FMT_STR:
                      possible_fmt_str = (prev_token_type, value)
              elif token_type != tokenize.STRING:
                  possible_fmt_str = None
  
              if token_type == tokenize.COMMENT and self.comments:
                  # Capture comments
                  if (
                      self.group_comments and
                      last_comment and
                      comments and (comments[-1][2] + 1) == line_num
                  ):
                      # Group multiple consecutive comments
                      comments[-1][0] += '\n' + value[1:]
                      comments[-1][2] = line_num
                  else:
                      if len(stack) > 1:
                          loc = "%s(%s): %s" % (stack[0][0], line, ''.join([crumb[0] for crumb in stack[1:]]))
                      else:
                          loc = "%s(%s)" % (stack[0][0], line)
                      comments.append([value[1:], loc, line_num])
              if token_type == tokenize.STRING:
                  # Capture docstrings.
                  # If we captured an `INDENT` or `NEWLINE` previously we probably have a docstring.
                  # `NL` means end of line, but not the end of the Python code line (line continuation).
                  if (
                      (prev_token_type in PREV_DOC_TOKENS) or
                      (possible_fmt_str and possible_fmt_str[0] in PREV_DOC_TOKENS)
                  ):
                      if self.docstrings:
                          value = value.strip()
                          if possible_fmt_str and value.startswith(("'", "\"")):
                              value = possible_fmt_str[1] + value
                          string, is_bytes = self.process_strings(value, docstrings=True)
                          if string:
                              loc = "%s(%s): %s" % (stack[0][0], line, ''.join([crumb[0] for crumb in stack[1:]]))
                              docstrings.append(
                                  filters.SourceText(string, loc, 'utf-8', 'py-docstring')
                              )
                  elif self.strings:
                      value = value.strip()
                      if possible_fmt_str and value.startswith(("'", "\"")):
                          value = possible_fmt_str[1] + value
                      string, is_bytes = self.process_strings(value)
                      if string:
                          loc = "%s(%s): %s" % (stack[0][0], line, ''.join([crumb[0] for crumb in stack[1:]]))
                          strings.append(filters.SourceText(string, loc, 'utf-8', 'py-string'))
  
              if token_type == tokenize.INDENT:
                  indent = value
              elif token_type == tokenize.DEDENT:
                  indent = indent[:-4]
                  if len(stack) > 1 and len(indent) <= stack[-1][1]:
                      stack.pop()
  
              # We purposefully avoid storing comments as comments can come before docstrings,
              # and that can mess up our logic. So if the token is a comment we won't track it,
              # and comments are always followed with `NL` so we ignore that as well.
              # We only care that docstrings are preceded by `NEWLINE`.
              if token_type != tokenize.COMMENT and not (last_comment and token_type == tokenize.NL):
                  prev_token_type = token_type
                  last_comment = False
              else:
                  last_comment = True
  
          final_comments = []
          for comment in comments:
              final_comments.append(filters.SourceText(textwrap.dedent(comment[0]), comment[1], encoding, 'py-comment'))
  
          return docstrings + final_comments + strings