class_docstr: Process code blocks. 
class_docstr_tok: ["Process","code","blocks","."]
code: def run(self, parent: etree.Element, blocks: list[str]) -> None:
      sibling = self.lastChild(parent)
      block = blocks.pop(0)
      theRest = ""
      if (
          sibling is not None
          and sibling.tag == "pre"
          and len(sibling)
          and sibling[0].tag == "code"
      ):
          # The previous block was a code block. As blank lines do not start
          # new code blocks, append this block to the previous, adding back
          # line breaks removed from the split into a list.
          code = sibling[0]
          block, theRest = self.detab(block)
          code.text = util.AtomicString(
              "{}\n{}\n".format(
                  code.text, util.code_escape(block.rstrip())
              )
          )
      else:
          # This is a new code block. Create the elements and insert text.
          pre = etree.SubElement(parent, "pre")
          code = etree.SubElement(pre, "code")
          block, theRest = self.detab(block)
          code.text = util.AtomicString(
              "%s\n" % util.code_escape(block.rstrip())
          )
      if theRest:
          # This block contained unindented line(s) after the first indented
          # line. Insert these lines as the first block of the master blocks
          # list for future processing.
          blocks.insert(0, theRest)
  
imports: from __future__ import annotations
  import logging
  import re
  import xml.etree.ElementTree
  from typing import TYPE_CHECKING, Any
  from .None import util
  from .blockparser import BlockParser
label_desc: Use image node_id 2 for calling the CodeBlockProcessor obj's underlying member method code with example usage: obj.run(parent, blocks) without return types