code: def run(self) -> None:
      lgr.log(5, "%s (%s) started", self.identifier, self)
  
      # Copy data from source queue to destination queue
      # until exit is requested. If timeouts arise, signal
      # them to the receiver via the signal queue.
      data: Optional[bytes] = b""
      while not self.exit_requested:
          data = self.read()
          # If the source sends None-data it wants
          # us to exit the thread. Signal this to
          # the downstream queues (which might or might
          # not be contain the output queue),
          # and exit the thread.
          if data is None:
              break
  
          if self.exit_requested:
              break
  
          succeeded = self.write(data)
          if not succeeded:
              break
  
      self.signal_event(IOState.ok, None)
      lgr.log(
          5,
          "%s (%s) exiting (exit_requested: %s, last data: %s)",
          self.identifier,
          self,
          self.exit_requested,
          data,
      )
  
imports: from __future__ import annotations
  import logging
  import os
  import threading
  from abc import ABCMeta, abstractmethod
  from enum import Enum
  from queue import Full, Queue
  from subprocess import Popen
  from typing import IO, Any, Optional
  from datalad.utils import COPY_BUFSIZE
label_desc: Use image node_id 7 for calling the TransportThread obj's underlying member method code with example usage: obj.run() without return types