class_docstr: Thread that is recommended to be used in PySpark when the pinned thread mode is
  enabled. The wrapper function, before calling original thread target, it
  inherits the inheritable properties specific to JVM thread such as
  ``InheritableThreadLocal``, or thread local such as tags
  with Spark Connect.
  
  When the pinned thread mode is off, this works as :class:`threading.Thread`.
  
  .. versionadded:: 3.1.0
  
  .. versionchanged:: 3.5.0
      Supports Spark Connect.
  
  Notes
  -----
  This API is experimental.
code: def __init__(
      self,
      target: Callable,
      *args: Any,
      session: Optional["SparkSession"] = None,
      **kwargs: Any,
  ):
      from pyspark.sql import is_remote
  
      # Spark Connect
      if is_remote():
          assert session is not None, "Spark Connect must be provided."
          self._session = session
  
          def copy_local_properties(*a: Any, **k: Any) -> Any:
              # Set tags in child thread.
              assert hasattr(self, "_tags")
              session.client.thread_local.tags = self._tags  # type: ignore[union-attr, has-type]
              return target(*a, **k)
  
          super(InheritableThread, self).__init__(
              target=copy_local_properties, *args, **kwargs  # type: ignore[misc]
          )
      else:
          # Non Spark Connect
          from pyspark import SparkContext
  
          if isinstance(SparkContext._gateway, ClientServer):
              # Here's when the pinned-thread mode (PYSPARK_PIN_THREAD) is on.
              def copy_local_properties(*a: Any, **k: Any) -> Any:
                  # self._props is set before starting the thread to match the behavior with JVM.
                  assert hasattr(self, "_props")
                  assert SparkContext._active_spark_context is not None
                  SparkContext._active_spark_context._jsc.sc().setLocalProperties(
                      self._props
                  )
                  return target(*a, **k)
  
              super(InheritableThread, self).__init__(
                  target=copy_local_properties, *args, **kwargs  # type: ignore[misc]
              )
          else:
              super(InheritableThread, self).__init__(
                  target=target, *args, **kwargs  # type: ignore[misc]
              )
  
imports: import copy
  import functools
  import itertools
  import os
  import platform
  import re
  import sys
  import threading
  import traceback
  import typing
  from types import TracebackType
  from typing import Any, Callable, IO, Iterator, List, Optional, TextIO, Tuple, Union
  from py4j.clientserver import ClientServer
  from pyspark.errors import PySparkRuntimeError
  from py4j.java_gateway import JavaObject
label_desc: Use image node_id 1 to create a new InheritableThread object from inherited base classes: threading with example: obj = InheritableThread(target)