code: def _create_py_udf(
      f: Callable[..., Any],
      returnType: "DataTypeOrString",
      useArrow: Optional[bool] = None,
  ) -> "UserDefinedFunctionLike":
      """Create a regular/Arrow-optimized Python UDF."""
      # The following table shows the results when the type coercion in Arrow is needed, that is,
      # when the user-specified return type(SQL Type) of the UDF and the actual instance(Python
      # Value(Type)) that the UDF returns are different.
      # Arrow and Pickle have different type coercion rules, so a UDF might have a different result
      # with/without Arrow optimization. That's the main reason the Arrow optimization for Python
      # UDFs is disabled by default.
      # +-----------------------------+--------------+----------+------+---------------+--------------------+-----------------------------+----------+----------------------+---------+--------------------+----------------------------+------------+--------------+  # noqa
      # |SQL Type \ Python Value(Type)|None(NoneType)|True(bool)|1(int)|         a(str)|    1970-01-01(date)|1970-01-01 00:00:00(datetime)|1.0(float)|array('i', [1])(array)|[1](list)|         (1,)(tuple)|bytearray(b'ABC')(bytearray)|  1(Decimal)|{'a': 1}(dict)|  # noqa
      # +-----------------------------+--------------+----------+------+---------------+--------------------+-----------------------------+----------+----------------------+---------+--------------------+----------------------------+------------+--------------+  # noqa
      # |                      boolean|          None|      True|  None|           None|                None|                         None|      None|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                      tinyint|          None|      None|     1|           None|                None|                         None|      None|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                     smallint|          None|      None|     1|           None|                None|                         None|      None|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                          int|          None|      None|     1|           None|                None|                         None|      None|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                       bigint|          None|      None|     1|           None|                None|                         None|      None|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                       string|          None|    'true'|   '1'|            'a'|'java.util.Gregor...|         'java.util.Gregor...|     '1.0'|         '[I@120d813a'|    '[1]'|'[Ljava.lang.Obje...|               '[B@48571878'|         '1'|       '{a=1}'|  # noqa
      # |                         date|          None|         X|     X|              X|datetime.date(197...|         datetime.date(197...|         X|                     X|        X|                   X|                           X|           X|             X|  # noqa
      # |                    timestamp|          None|         X|     X|              X|                   X|         datetime.datetime...|         X|                     X|        X|                   X|                           X|           X|             X|  # noqa
      # |                        float|          None|      None|  None|           None|                None|                         None|       1.0|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                       double|          None|      None|  None|           None|                None|                         None|       1.0|                  None|     None|                None|                        None|        None|          None|  # noqa
      # |                       binary|          None|      None|  None|bytearray(b'a')|                None|                         None|      None|                  None|     None|                None|           bytearray(b'ABC')|        None|          None|  # noqa
      # |                decimal(10,0)|          None|      None|  None|           None|                None|                         None|      None|                  None|     None|                None|                        None|Decimal('1')|          None|  # noqa
      # +-----------------------------+--------------+----------+------+---------------+--------------------+-----------------------------+----------+----------------------+---------+--------------------+----------------------------+------------+--------------+  # noqa
      # Note: Python 3.9.15, Pandas 1.5.2 and PyArrow 10.0.1 are used.
      # Note: The values of 'SQL Type' are DDL formatted strings, which can be used as `returnType`s.
      # Note: The values inside the table are generated by `repr`. X' means it throws an exception
      # during the conversion.
  
      if useArrow is None:
          from pyspark.sql import SparkSession
  
          session = SparkSession._instantiatedSession
          is_arrow_enabled = (
              False
              if session is None
              else session.conf.get(
                  "spark.sql.execution.pythonUDF.arrow.enabled"
              )
              == "true"
          )
      else:
          is_arrow_enabled = useArrow
  
      eval_type: int = PythonEvalType.SQL_BATCHED_UDF
  
      if is_arrow_enabled:
          try:
              is_func_with_args = len(getfullargspec(f).args) > 0
          except TypeError:
              is_func_with_args = False
          if is_func_with_args:
              require_minimum_pandas_version()
              require_minimum_pyarrow_version()
              eval_type = PythonEvalType.SQL_ARROW_BATCHED_UDF
          else:
              warnings.warn(
                  "Arrow optimization for Python UDFs cannot be enabled.",
                  UserWarning,
              )
  
      return _create_udf(f, returnType, eval_type)
  
imports: from inspect import getfullargspec
  import functools
  import inspect
  import sys
  import warnings
  from typing import Callable, Any, TYPE_CHECKING, Optional, cast, Union
  from py4j.java_gateway import JavaObject
  from pyspark import SparkContext
  from pyspark.rdd import _prepare_for_python_RDD, PythonEvalType
  from pyspark.sql.column import Column, _to_java_expr, _to_seq
  from pyspark.sql.types import DataType, StringType, StructType, _parse_datatype_string
  from pyspark.sql.utils import get_active_spark_context
  from pyspark.sql.pandas.types import to_arrow_type
  from pyspark.sql.pandas.utils import require_minimum_pandas_version, require_minimum_pyarrow_version
  from pyspark.errors import PySparkTypeError, PySparkNotImplementedError, PySparkRuntimeError
label_desc: Use image node_id 3 for calling a global function with example usage: _create_py_udf(f, returnType, useArrow) and returns: _create_udf