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 _clean_pieces(self) -> Iterator[range]:
      pieces = self._raw_split_into_pieces(
          self.tree, 1, len(self.lines) + 1
      )
      pieces = [(start, end) for (start, end) in pieces if end > start]
  
      # Combine overlapping pieces, i.e. consecutive pieces where the end of the first
      # is greater than the start of the second.
      # This can happen when two statements are on the same line separated by a semicolon.
      new_pieces = pieces[:1]
      for start, end in pieces[1:]:
          (last_start, last_end) = new_pieces[-1]
          if start < last_end:
              assert start == last_end - 1
              assert ";" in self.lines[start - 1]
              new_pieces[-1] = (last_start, end)
          else:
              new_pieces.append((start, end))
      pieces = new_pieces
  
      starts = [start for start, end in pieces[1:]]
      ends = [end for start, end in pieces[:-1]]
      if starts != ends:
          joins = list(map(set, zip(starts, ends)))
          mismatches = [s for s in joins if len(s) > 1]
          raise AssertionError("Pieces mismatches: %s" % mismatches)
  
      def is_blank(i):
          try:
              return not self.lines[i - 1].strip()
          except IndexError:
              return False
  
      for start, end in pieces:
          while is_blank(start):
              start += 1
          while is_blank(end - 1):
              end -= 1
          if start < end:
              yield range(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 3 for calling the Source obj's underlying member method code with example usage: obj._clean_pieces() and returns: unknown, False