code: def getstatementrange_ast(
      lineno: int,
      source: Source,
      assertion: bool = False,
      astnode: Optional[ast.AST] = None,
  ) -> Tuple[ast.AST, int, int]:
      if astnode is None:
          content = str(source)
          # See #4260:
          # Don't produce duplicate warnings when compiling source to find AST.
          with warnings.catch_warnings():
              warnings.simplefilter("ignore")
              astnode = ast.parse(content, "source", "exec")
  
      start, end = get_statement_startend2(lineno, astnode)
      # We need to correct the end:
      # - ast-parsing strips comments
      # - there might be empty lines
      # - we might have lesser indented code blocks at the end
      if end is None:
          end = len(source.lines)
  
      if end > start + 1:
          # Make sure we don't span differently indented code blocks
          # by using the BlockFinder helper used which inspect.getsource() uses itself.
          block_finder = inspect.BlockFinder()
          # If we start with an indented line, put blockfinder to "started" mode.
          block_finder.started = source.lines[start][0].isspace()
          it = ((x + "\n") for x in source.lines[start:end])
          try:
              for tok in tokenize.generate_tokens(lambda: next(it)):
                  block_finder.tokeneater(*tok)
          except (inspect.EndOfBlock, IndentationError):
              end = block_finder.last + start
          except Exception:
              pass
  
      # The end might still point to a comment or empty line, correct it.
      while end:
          line = source.lines[end - 1].lstrip()
          if line.startswith("#") or not line:
              end -= 1
          else:
              break
      return astnode, start, end
  
imports: import ast
  import inspect
  import textwrap
  import tokenize
  import types
  import warnings
  from bisect import bisect_right
  from typing import Iterable
  from typing import Iterator
  from typing import List
  from typing import Optional
  from typing import overload
  from typing import Tuple
  from typing import Union
label_desc: Use image node_id 5 for calling a global function with example usage: getstatementrange_ast(lineno, source, assertion, astnode) and returns: astnode,  start,  end