282 lines
8.4 KiB
Python
282 lines
8.4 KiB
Python
"""Narwhals-level equivalent of `CompliantNamespace`."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Any, ClassVar, Generic, overload
|
|
|
|
from narwhals._compliant.typing import CompliantNamespaceAny, CompliantNamespaceT_co
|
|
from narwhals._native import (
|
|
NativeAny,
|
|
NativeArrow,
|
|
NativeCuDF,
|
|
NativeDask,
|
|
NativeDuckDB,
|
|
NativeIbis,
|
|
NativeModin,
|
|
NativePandas,
|
|
NativePandasLike,
|
|
NativePolars,
|
|
NativeSparkLike,
|
|
NativeUnknown,
|
|
_CuDFDataFrame,
|
|
_CuDFSeries,
|
|
_ModinDataFrame,
|
|
_ModinSeries,
|
|
is_native_arrow,
|
|
is_native_cudf,
|
|
is_native_dask,
|
|
is_native_duckdb,
|
|
is_native_ibis,
|
|
is_native_modin,
|
|
is_native_pandas,
|
|
is_native_polars,
|
|
is_native_pyspark_connect,
|
|
is_native_spark_like,
|
|
is_native_sqlframe,
|
|
)
|
|
from narwhals._utils import Implementation, Version
|
|
|
|
if TYPE_CHECKING:
|
|
import pandas as pd
|
|
from typing_extensions import TypeAlias
|
|
|
|
from narwhals._arrow.namespace import ArrowNamespace
|
|
from narwhals._dask.namespace import DaskNamespace
|
|
from narwhals._duckdb.namespace import DuckDBNamespace
|
|
from narwhals._ibis.namespace import IbisNamespace
|
|
from narwhals._pandas_like.namespace import PandasLikeNamespace
|
|
from narwhals._polars.namespace import PolarsNamespace
|
|
from narwhals._spark_like.namespace import SparkLikeNamespace
|
|
from narwhals._typing import (
|
|
Arrow,
|
|
Backend,
|
|
Dask,
|
|
DuckDB,
|
|
EagerAllowed,
|
|
Ibis,
|
|
IntoBackend,
|
|
PandasLike,
|
|
Polars,
|
|
SparkLike,
|
|
)
|
|
|
|
EagerAllowedNamespace: TypeAlias = "Namespace[PandasLikeNamespace] | Namespace[ArrowNamespace] | Namespace[PolarsNamespace]"
|
|
|
|
__all__ = ["Namespace"]
|
|
|
|
|
|
class Namespace(Generic[CompliantNamespaceT_co]):
|
|
_compliant_namespace: CompliantNamespaceT_co
|
|
_version: ClassVar[Version] = Version.MAIN
|
|
|
|
def __init__(self, namespace: CompliantNamespaceT_co, /) -> None:
|
|
self._compliant_namespace = namespace
|
|
|
|
def __init_subclass__(cls, *args: Any, version: Version, **kwds: Any) -> None:
|
|
super().__init_subclass__(*args, **kwds)
|
|
|
|
if isinstance(version, Version):
|
|
cls._version = version
|
|
else:
|
|
msg = f"Expected {Version} but got {type(version).__name__!r}"
|
|
raise TypeError(msg)
|
|
|
|
def __repr__(self) -> str:
|
|
return f"Namespace[{type(self.compliant).__name__}]"
|
|
|
|
@property
|
|
def compliant(self) -> CompliantNamespaceT_co:
|
|
return self._compliant_namespace
|
|
|
|
@property
|
|
def implementation(self) -> Implementation:
|
|
return self.compliant._implementation
|
|
|
|
@property
|
|
def version(self) -> Version:
|
|
return self._version
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: PandasLike, /) -> Namespace[PandasLikeNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: Polars, /) -> Namespace[PolarsNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: Arrow, /) -> Namespace[ArrowNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: SparkLike, /) -> Namespace[SparkLikeNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: DuckDB, /) -> Namespace[DuckDBNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: Dask, /) -> Namespace[DaskNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: Ibis, /) -> Namespace[IbisNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(cls, backend: EagerAllowed, /) -> EagerAllowedNamespace: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_backend(
|
|
cls, backend: IntoBackend[Backend], /
|
|
) -> Namespace[CompliantNamespaceAny]: ...
|
|
|
|
@classmethod
|
|
def from_backend(
|
|
cls: type[Namespace[Any]], backend: IntoBackend[Backend], /
|
|
) -> Namespace[Any]:
|
|
"""Instantiate from native namespace module, string, or Implementation.
|
|
|
|
Arguments:
|
|
backend: native namespace module, string, or Implementation.
|
|
|
|
Examples:
|
|
>>> from narwhals._namespace import Namespace
|
|
>>> Namespace.from_backend("polars")
|
|
Namespace[PolarsNamespace]
|
|
"""
|
|
impl = Implementation.from_backend(backend)
|
|
backend_version = impl._backend_version() # noqa: F841
|
|
version = cls._version
|
|
ns: CompliantNamespaceAny
|
|
if impl.is_pandas_like():
|
|
from narwhals._pandas_like.namespace import PandasLikeNamespace
|
|
|
|
ns = PandasLikeNamespace(implementation=impl, version=version)
|
|
|
|
elif impl.is_polars():
|
|
from narwhals._polars.namespace import PolarsNamespace
|
|
|
|
ns = PolarsNamespace(version=version)
|
|
elif impl.is_pyarrow():
|
|
from narwhals._arrow.namespace import ArrowNamespace
|
|
|
|
ns = ArrowNamespace(version=version)
|
|
elif impl.is_spark_like():
|
|
from narwhals._spark_like.namespace import SparkLikeNamespace
|
|
|
|
ns = SparkLikeNamespace(implementation=impl, version=version)
|
|
elif impl.is_duckdb():
|
|
from narwhals._duckdb.namespace import DuckDBNamespace
|
|
|
|
ns = DuckDBNamespace(version=version)
|
|
elif impl.is_dask():
|
|
from narwhals._dask.namespace import DaskNamespace
|
|
|
|
ns = DaskNamespace(version=version)
|
|
elif impl.is_ibis():
|
|
from narwhals._ibis.namespace import IbisNamespace
|
|
|
|
ns = IbisNamespace(version=version)
|
|
else:
|
|
msg = "Not supported Implementation" # pragma: no cover
|
|
raise AssertionError(msg)
|
|
return cls(ns)
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativePolars, /
|
|
) -> Namespace[PolarsNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativePandas, /
|
|
) -> Namespace[PandasLikeNamespace[pd.DataFrame, pd.Series[Any]]]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(cls, native: NativeArrow, /) -> Namespace[ArrowNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativeSparkLike, /
|
|
) -> Namespace[SparkLikeNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativeDuckDB, /
|
|
) -> Namespace[DuckDBNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(cls, native: NativeDask, /) -> Namespace[DaskNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(cls, native: NativeIbis, /) -> Namespace[IbisNamespace]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativeModin, /
|
|
) -> Namespace[PandasLikeNamespace[_ModinDataFrame, _ModinSeries]]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativeCuDF, /
|
|
) -> Namespace[PandasLikeNamespace[_CuDFDataFrame, _CuDFSeries]]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativePandasLike, /
|
|
) -> Namespace[PandasLikeNamespace[Any, Any]]: ...
|
|
|
|
@overload
|
|
@classmethod
|
|
def from_native_object(
|
|
cls, native: NativeUnknown, /
|
|
) -> Namespace[CompliantNamespaceAny]: ...
|
|
|
|
@classmethod
|
|
def from_native_object(
|
|
cls: type[Namespace[Any]], native: NativeAny, /
|
|
) -> Namespace[Any]:
|
|
impl: Backend
|
|
if is_native_polars(native):
|
|
impl = Implementation.POLARS
|
|
elif is_native_pandas(native):
|
|
impl = Implementation.PANDAS
|
|
elif is_native_arrow(native):
|
|
impl = Implementation.PYARROW
|
|
elif is_native_spark_like(native):
|
|
impl = (
|
|
Implementation.SQLFRAME
|
|
if is_native_sqlframe(native)
|
|
else Implementation.PYSPARK_CONNECT
|
|
if is_native_pyspark_connect(native)
|
|
else Implementation.PYSPARK
|
|
)
|
|
elif is_native_dask(native): # pragma: no cover
|
|
impl = Implementation.DASK
|
|
elif is_native_duckdb(native):
|
|
impl = Implementation.DUCKDB
|
|
elif is_native_cudf(native): # pragma: no cover
|
|
impl = Implementation.CUDF
|
|
elif is_native_modin(native): # pragma: no cover
|
|
impl = Implementation.MODIN
|
|
elif is_native_ibis(native):
|
|
impl = Implementation.IBIS
|
|
else:
|
|
msg = f"Unsupported type: {type(native).__qualname__!r}"
|
|
raise TypeError(msg)
|
|
return cls.from_backend(impl)
|