blob: 74a47e9778cb47a3fa4096df6f9a60b609cd339a [file]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Small subset of pyspark.sql.utils needed by the drop-in and vendored modules."""
from typing import Any, Union, TYPE_CHECKING, Sequence
if TYPE_CHECKING:
from pyspark.pandas._typing import IndexOpsLike, SeriesOrIndex
def is_remote() -> bool:
"""This client is always a Spark Connect (remote) client."""
return True
def is_timestamp_ntz_preferred() -> bool:
"""Whether TIMESTAMP_NTZ is the preferred timestamp type.
Best-effort for the Connect drop-in: honor the active session's
spark.sql.timestampType when one is running, else False.
"""
try:
from pyspark.sql import SparkSession
session = SparkSession.getActiveSession()
if session is None:
return False
return session.conf.get("spark.sql.timestampType", None) == "TIMESTAMP_NTZ"
except Exception:
return False
def get_lit_sql_str(val: str) -> str:
"""Get SQL string literal representation.
Equivalent to `lit(val)._jc.expr().sql()` for string typed val.
See `sql` definition in `sql/catalyst/src/main/scala/org/apache/spark/
sql/catalyst/expressions/literals.scala`
"""
return "'" + val.replace("\\", "\\\\").replace("'", "\\'") + "'"
def pyspark_column_op(
func_name: str, left: "IndexOpsLike", right: Any, fillna: Any = None
) -> Union["SeriesOrIndex", None]:
"""Wrapper function for column_op to get proper Column class."""
from pyspark.pandas.base import column_op
from pyspark.sql.column import Column
from pyspark.pandas.data_type_ops.base import _is_extension_dtypes
result = column_op(getattr(Column, func_name))(left, right)
# It works as expected on extension dtype, so we don't need to call `fillna` for this case.
if (fillna is not None) and (_is_extension_dtypes(left) or _is_extension_dtypes(right)):
fillna = None
# TODO(SPARK-43877): Fix behavior difference for compare binary functions.
return result.fillna(fillna) if fillna is not None else result
def require_minimum_plotly_version() -> None:
"""Raise ImportError if plotly is not installed"""
from pyspark.loose_version import LooseVersion
from pyspark.errors import PySparkImportError
minimum_plotly_version = "4.8"
try:
import plotly
have_plotly = True
except ImportError as error:
have_plotly = False
raised_error = error
if not have_plotly:
raise PySparkImportError(
errorClass="PACKAGE_NOT_INSTALLED",
messageParameters={
"package_name": "Plotly",
"minimum_version": str(minimum_plotly_version),
},
) from raised_error
if LooseVersion(plotly.__version__) < LooseVersion(minimum_plotly_version):
raise PySparkImportError(
errorClass="UNSUPPORTED_PACKAGE_VERSION",
messageParameters={
"package_name": "Plotly",
"minimum_version": str(minimum_plotly_version),
"current_version": str(plotly.__version__),
},
)
class NumpyHelper:
@staticmethod
def linspace(start: float, stop: float, num: int) -> Sequence[float]:
if num == 1:
return [float(start)]
step = (float(stop) - float(start)) / (num - 1)
return [start + step * i for i in range(num)]