class_docstr: The source code of a single file and associated metadata.
  
  In addition to the attributes from the base class executing.Source,
  if .tree is not None, meaning this is valid Python code, objects have:
      - pieces: a list of Piece objects
      - tokens_by_lineno: a defaultdict(list) mapping line numbers to lists of tokens.
  
  Don't construct this class. Get an instance from frame_info.source.
class_docstr_tok: ["The","source","code","of","a","single","file","and","associated","metadata",".","In","addition","to","the","attributes","from","the","base","class","executing.Source",",","if",".tree","is","not","None",",","meaning","this","is","valid","Python","code",",","objects","have",":","-","pieces",":","a","list","of","Piece","objects","-","tokens_by_lineno",":","a","defaultdict","(","list",")","mapping","line","numbers","to","lists","of","tokens",".","Do","n't","construct","this","class",".","Get","an","instance","from","frame_info.source","."]
code: def _raw_split_into_pieces(
      self,
      stmt: ast.AST,
      start: int,
      end: int,
  ) -> Iterator[Tuple[int, int]]:
      for name, body in ast.iter_fields(stmt):
          if (
              isinstance(body, list)
              and body
              and isinstance(
                  body[0],
                  (
                      ast.stmt,
                      ast.ExceptHandler,
                      getattr(ast, "match_case", ()),
                  ),
              )
          ):
              for rang, group in sorted(
                  group_by_key_func(body, self.line_range).items()
              ):
                  sub_stmt = group[0]
                  for (
                      inner_start,
                      inner_end,
                  ) in self._raw_split_into_pieces(sub_stmt, *rang):
                      if start < inner_start:
                          yield start, inner_start
                      if inner_start < inner_end:
                          yield inner_start, inner_end
                      start = inner_end
  
      yield start, end
  
imports: import ast
  import html
  import os
  import sys
  from collections import defaultdict, Counter
  from enum import Enum
  from textwrap import dedent
  from types import FrameType, CodeType, TracebackType
  from typing import Iterator, List, Tuple, Optional, NamedTuple, Any, Iterable, Callable, Union, Sequence
  from typing import Mapping
  import executing
  from asttokens.util import Token
  from executing import only
  from pure_eval import Evaluator, is_expression_interesting
  from stack_data.utils import truncate, unique_in_order, line_range, frame_and_lineno, iter_stack, collapse_repeated, group_by_key_func, cached_property, is_frame, _pygmented_with_ranges, assert_
label_desc: Use image node_id 4 for calling the Source obj's underlying member method code with example usage: obj._raw_split_into_pieces(stmt, start, end) without return types